diff --git a/.github/workflows/docker-image-latest.yml b/.github/workflows/docker-image-latest.yml index ed9fd64..750e3be 100644 --- a/.github/workflows/docker-image-latest.yml +++ b/.github/workflows/docker-image-latest.yml @@ -47,7 +47,7 @@ jobs: --cache-from=type=local,src=/tmp/.buildx-cache \ --cache-to=type=local,dest=/tmp/.buildx-cache,mode=max \ --tag ghcr.io/ximeraproject/ximeralatex:latest \ - --file docker/Dockerfile \ + --file docker/Dockerfile.full \ --push . # - name: Build and Push full Docker image diff --git a/docker/Dockerfile b/docker/Dockerfile index cf0c264..179005d 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,9 +1,9 @@ -FROM registry.gitlab.com/islandoftex/images/texlive:TL2025-2025-06-15-medium -# FROM registry.gitlab.com/islandoftex/images/texlive:TL2024-2024-11-17-medium +# FROM registry.gitlab.com/islandoftex/images/texlive:TL2025-2025-06-15-medium +FROM registry.gitlab.com/islandoftex/images/texlive:TL2024-2024-11-17-medium RUN apt-get update -y; \ apt-get install -y \ - git git-restore-mtime \ + git \ # mupdf-tools \ pdf2svg \ gnupg \ @@ -12,15 +12,20 @@ RUN apt-get update -y; \ wget \ dos2unix \ vim-tiny strace less \ - nano file + nano file \ + mupdf-tools lsof # hashcash needed for setting up communication to ximeraServer; seems unfortunately not (easily?) installable with apt.. ADD docker/hashcash_1.22-1_amd64.deb . RUN dpkg -i hashcash_1.22-1_amd64.deb +# Install git restore-mtime (version in apt is too old ...) +RUN cd /root; \ + git clone https://github.com/MestreLion/git-tools.git; \ + echo 'PATH=$PATH:~/git-tools' >> ~/.profile # Extra packages (on top of 'medium') -# RUN tlmgr option repository http://ftp.math.utah.edu/pub/tex/historic/systems/texlive/2024/tlnet-final; \ +RUN tlmgr option repository http://ftp.math.utah.edu/pub/tex/historic/systems/texlive/2024/tlnet-final; RUN tlmgr update --self; \ tlmgr install \ # afterpage \ @@ -118,10 +123,16 @@ RUN tlmgr update --self; \ gillius \ pagecolor \ tabularray \ - ninecolors + mdframed \ + zref \ + needspace \ + ninecolors \ + supertabular import boxedminipage chapterfolder sectsty tocbibind sfmath + + # make4ht is not in /usr/local/bin if installed with tlmgr!!! -ENV PATH="$PATH:/usr/local/texlive/2024/bin/x86_64-linux" +ENV PATH="$PATH:/usr/local/texlive/2024/bin/x86_64-linux:/root/git-tools" # Add this complete ximeraLatex repo (is overkill, but allows bugfixing/editing inside the docker image! # It automatically adds the luaxake and xmlatex scripts @@ -133,4 +144,4 @@ RUN ln -s /root/texmf/tex/latex/ximeraLatex/luaxake/luaxake /usr/local/bin/luaxa ln -s /root/texmf/tex/latex/ximeraLatex/xmScripts/xmlatex /usr/local/bin/xmlatex; \ git config --global --add safe.directory /code -WORKDIR /code \ No newline at end of file +WORKDIR /code diff --git a/docker/Dockerfile.full b/docker/Dockerfile.full index b797d2a..6f5f04d 100644 --- a/docker/Dockerfile.full +++ b/docker/Dockerfile.full @@ -4,13 +4,15 @@ FROM registry.gitlab.com/islandoftex/images/texlive:TL2024-2024-11-17-full RUN apt-get update -y; \ apt-get install -y \ curl \ - git git-restore-mtime \ + git \ + # git-restore-mtime \ ## TOO OLD !!! mupdf-tools pdf2svg imagemagick \ gnupg \ jq \ dos2unix \ vim wget strace less \ - nano file + nano file \ + lsof # RUN apt-get install -u hashcash @@ -18,6 +20,15 @@ RUN apt-get update -y; \ ADD docker/hashcash_1.22-1_amd64.deb . RUN dpkg -i hashcash_1.22-1_amd64.deb +# Install git restore-mtime (version in apt is too old ...) +RUN cd /root; \ + git clone https://github.com/MestreLion/git-tools.git; \ + echo 'PATH=$PATH:~/git-tools' >> ~/.profile + +# +ENV PATH="$PATH:/root/git-tools" + + # Add this complete ximeraLatex repo (is overkill, but allows bugfixing/editing inside the docker image! # It automatically adds the luaxake and xmlatex scripts RUN mkdir -p /root/texmf/tex/latex diff --git a/luaxake/luaxake b/luaxake/luaxake index f7e5b15..1c01c97 100755 --- a/luaxake/luaxake +++ b/luaxake/luaxake @@ -43,7 +43,8 @@ Options: --compile (default none) Compile sequence (default 'pdf,html', or as set in settings) --settingsfile (default none) Luaxake settings script --configfile (default none) TeX4ht config file --j,--jobs (optional 1..1000) Number of compile jobs to run in parallel +-j,--jobs (optional 1..1000) Number of compile jobs to run in parallel +--img_format (default svg) Either svg or png for image-format in HTML Possible commands: bake @@ -171,6 +172,16 @@ config = { output_format = "html", infix = "draft" , }, + ["htmlexport"] = { -- NEW, TEST + -- command = 'pdflatex -interaction=nonstopmode -file-line-error -shell-escape -jobname @{basename}.handout "\\PassOptionsToClass{handout}{ximera}\\PassOptionsToClass{handout}{xourse}\\input{@{filename}}"', + command = "make4ht -l -c @{configfile} -f html5 -m draft -d build -j @{basename} -s @{make4ht_extraoptions} @{filename} 'svg,htex4ht,mathjax,-css' '' '' '--interaction=nonstopmode -shell-escape -file-line-error'", + check_log = true, -- check log + status = 0, -- check that the latex command return 0 + post_command = 'post_process_html', + extension = "html", + output_format = "html", + infix = "" , + }, ["make4ht.html"] = { command = "make4ht -l -c @{configfile} -f html5+dvisvgm_hashes -j @{basename}.make4ht -s @{make4ht_extraoptions} @{filename} 'svg,htex4ht,mathjax,-css' '' '' '--interaction=nonstopmode -shell-escape -file-line-error'", check_log = true, -- check log @@ -188,7 +199,7 @@ config = { post_command = 'post_process_html', extension = "html", output_format = "html", - infix = "draft" , + infix = "tikz" , }, ["test.html"] = { -- command = "make4ht -f html5+dvisvgm_hashes -c @{configfile} -sm draft @{filename}", @@ -201,7 +212,6 @@ config = { output_format = "html", infix = "make4ht" , }, - -- sage not tested/implemented !!!! ["sagetex.sage"] = { command = "sage @{output_file}", @@ -210,6 +220,20 @@ config = { status = 0, -- check that the latex command return 0 extension = "sage", -- ? }, + ["pdfexport"] = { -- NEW, TEST + -- this doesn't work well + command = 'pdflatex -j @{basename} -interaction=nonstopmode -file-line-error -shell-escape "\\PassOptionsToClass{tikzexport}{ximera}\\PassOptionsToClass{tikzexport}{ximera}\\PassOptionsToClass{tikzexport}{xourse}\\nonstopmode\\input{@{filename}}"', + -- command = 'pdflatex -interaction=nonstopmode -file-line-error -shell-escape "\\PassOptionsToClass{xake}{ximera}\\PassOptionsToClass{xake}{xourse}\\input{@{filename}}"', + check_log = true, -- check log + status = 0, -- check that the latex command return 0 + infix = "" , -- used for .handout, and .make4k4 + extension = "pdf", -- not used ???? + output_format = "pdf",-- the extension of the 'final' output file, that is eg checked for uptodate-ness + post_command = 'post_process_pdf', + download_folder = 'ximera-downloads/pdfexport', + -- post_command = 'post_process_pdf', + -- download_folder = 'ximera-downloads/with-answers', + }, -- a dummy test: create .ddd files that contain the date .. ddd = { command = 'date >@{basename}.ddd', @@ -276,6 +300,7 @@ config = { -- number of lines in tex files where we should look for \documentclass -- dump_fileinfo = "aFirstXourse.tex", jobs = 2, + img_format = "svg", } @@ -326,6 +351,7 @@ config.noclean = args.noclean or os.getenv("XM_NOCLEAN") or co config.nodependencies = args.nodependencies or os.getenv("XM_NODEPENDENCIES") or config.nodependencies config.force = args.force or os.getenv("XM_FORCE") or config.force config.jobs = args.jobs or os.getenv("XM_JOBS") or config.jobs +config.img_format = args.img_format or os.getenv("XM_IMG_FORMAT") or config.img_format if args.configfile ~= "none" then config.configfile = args.configfile @@ -345,7 +371,7 @@ end -- set/add potential default dependencies if not config.default_dependencies and path.exists("xmPreamble.tex") then - log:info("Adding default dependency xmPreamble.tex") + log:debug("Adding default dependency xmPreamble.tex") config.default_dependencies = { "xmPreamble.tex" } else config.default_dependencies = {} @@ -415,8 +441,10 @@ log:infof("Set compile_sequence=%s (and output_formats=%s)", table.concat(config -- local tex_fileinfos = {} +local first_file_arg = "" + for i,nextarg in ipairs(config.dirs) do - log:infof("Processing argument %d: %s", i,nextarg) + log:debugf("Processing argument %d: %s", i,nextarg) nextarg = nextarg:gsub("^.//*", "") -- remove potential leading './' -- vscode-settings sometimes even add .//myfile.tex; it also might confuse skipping hidden .xxx files/folders --if path.isdir(nextarg) or path.isfile(nextarg) then @@ -424,14 +452,22 @@ for i,nextarg in ipairs(config.dirs) do if not path.isdir(nextarg) then local ext = nextarg:match(("%.([^%.]+)$")) if ext ~= "tex" and path.isfile(nextarg..".tex") then - log:trace("Adding .tex to " .. nextarg) + log:debug("Adding .tex to " .. nextarg) nextarg = nextarg..".tex" elseif ext ~= "tex" then - log:warningf("Argument %s not folder nor tex-file (%s): SKIPPING", nextarg, ext) + log:errorf("Argument %s not folder nor tex-file (%s)", nextarg, ext) + os.exit(1) goto nextarg -- continue ... end end - + + if first_file_arg == "" -- HACK: save to append to url at serve + then + log:debugf("Set first file to %s", nextarg) + first_file_arg = "/" .. nextarg:gsub("%.tex",".html") + end + + -- some files might need compilation even if they are not in the args, e.g. _pdf.tex files, or other dependent .tex files local all_involved_texfiles = files.get_tex_files_with_status(nextarg, config.output_formats, config.compile_sequence) @@ -503,7 +539,7 @@ elseif #to_be_compiled > 0 then log:infof("%3d %s",i,file.relative_path) end else - log:status("No files need compiling") + log:info("No files need compiling") end -- @@ -553,25 +589,24 @@ end -- TODO: fix commands (cfr xmlatex/xmlatex/lua) if command == "bake" or command == "compilePdf" or command == "compile" then - log:status("Start "..command) - + local ret, msg if #to_be_compiled == 0 then - ret, msg = 0, "Nothing to be baked" + log:debug("Nothing to be baked") else + log:status("Start "..command) ret, msg = bake.bake(to_be_compiled, config.jobs) - end -- end baking - - if ret > 0 then - log:error("Bake failed: " .. msg) - os.exit(ret) - else - log:statusf("Bake succeeded: " .. msg) + if ret > 0 then + log:error("Bake failed: " .. msg) + os.exit(ret) + else + log:statusf("Bake succeeded: " .. msg) + end end end if command == "frost" then - log:status("Start " .. command) + log:info("Start " .. command) local ret, msg = frost.frost(tex_files, to_be_compiled) if ret > 0 then log:error("Frost failed: " .. msg) @@ -582,13 +617,13 @@ if command == "frost" then end if command == "serve" then - log:status("Start " .. command) + log:info("Start " .. command) local ret, msg = frost.serve(config.force) if ret > 0 then log:error("Serve failed: " .. msg) os.exit(ret) else - log:statusf("Serve succeeded: " .. msg) + log:statusf("Serve succeeded: " .. msg .. first_file_arg) end end @@ -596,10 +631,10 @@ if command == "ghaction" then local ret, msg if #to_be_compiled == 0 then - log:status("Nothing to be baked") + log:info("Nothing to be baked") msg={} else - log:status("Start bake") + log:info("Start bake") ret, msg = bake.bake(to_be_compiled, config.jobs) if ret > 0 then @@ -626,7 +661,7 @@ if command == "ghaction" then to_be_compiled = still_to_be_compiled -- end-of-hack to_be_compiled - log:status("Start frost") + log:info("Start frost") local ret, msg = frost.frost(tex_files, to_be_compiled) if ret > 0 then log:error("Frost failed: " .. msg) @@ -634,13 +669,13 @@ if command == "ghaction" then else log:statusf("Frost succeeded: " .. msg) end - log:status("Start serve") - local ret, msg = frost.serve(true) -- WITH FORCE (until push/depth issue fixed) + log:info("Start serve") + local ret, msg = frost.serve(false) -- NO FORCE (since push/depth issue fixed ?) if ret > 0 then log:error("Serve failed: " .. msg) os.exit(ret) else - log:statusf("Serve succeeded: " .. msg) + log:statusf("Serve succeeded: " .. msg .. first_file_arg) end end @@ -663,4 +698,4 @@ if command == "extrainfo" then log:infof("Potentially duplicate labels:") require 'pl.pretty'.dump(all_labels) end -end \ No newline at end of file +end diff --git a/luaxake/luaxake-bake.lua b/luaxake/luaxake-bake.lua index 68ba83d..7e86bb0 100644 --- a/luaxake/luaxake-bake.lua +++ b/luaxake/luaxake-bake.lua @@ -136,9 +136,12 @@ local function get_commands_to_run(file, compilers, compile_sequence, only_check end - -- HACK: _pdf.tex and _beamer.tex files should by convention NOT generate HTML (as they typically would contain non-TeX4ht-compatible constructs) - if extension:match("html$") and ( file.relative_path:match("_pdf.tex$") or file.relative_path:match("_beamer.tex$") ) then - log:infof("Skipping HTML compilation of pdf-only file %s",file.relative_path) + -- HACK: _pdf.tex and _beamer.tex files should by convention NOT generate HTML (as they typically would contain non-TeX4ht-compatible constructs) + if ( extension:match("html$") or extension:match("export$") ) + and + ( file.relative_path:match("_pdf.tex$") or file.relative_path:match("_beamer.tex$") ) then + + log:infof("Skipping %s compilation of pdf-only file %s",extension, file.relative_path) -- create/update a dummy outputfile to mark this file 'uptodate' local filename = file.absolute_path:gsub(".tex$",".html") diff --git a/luaxake/luaxake-domobject.lua b/luaxake/luaxake-domobject.lua new file mode 100644 index 0000000..59aad5a --- /dev/null +++ b/luaxake/luaxake-domobject.lua @@ -0,0 +1,800 @@ +--- DOM module for LuaXML +-- @module luaxml-domobject +-- @author Michal Hoftich "] = ">", + ["<"] = "<", + ["&"] = "&", + ['"'] = """, + ["'"] = "'", + ["`"] = "`" +} + +-- declarations of local functions +local html_to_dom +local html_parse +local parse + + + +local function escape(search, text) + return text:gsub(search, function(ch) + return escapes[ch] or "" + end) +end + +local function escape_element(text) + return escape("([<>&])", text) +end + +local function escape_attr(text) + return escape("([<>&\"'`])", text) +end + +local actions = { + TEXT = {text = "%s"}, + COMMENT = {start = ""}, + ELEMENT = {start = "<%s%s>", stop = "", void = "<%s%s />"}, + DECL = {start = ""}, + PI = {start = ""}, + DTD = {start = ""}, + CDATA = {start = ""} + +} + +--- It serializes the DOM object back to the XML. +-- This function is mainly used for internal purposes, it is better to +-- use the `DOM_Object:serialize()`. +-- @param parser DOM object +-- @param current Element which should be serialized +-- @param level +-- @param output +-- @return table Table with XML strings. It can be concenated using table.concat() function to get XML string corresponding to the DOM_Object. +local function serialize_dom(parser, current,level, output) + local output = output or {} + local function get_action(typ, action) + local ac = actions[typ] or {} + local format = ac[action] or "" + return format + end + local function insert(format, ...) + table.insert(output, string.format(format, ...)) + end + local function prepare_attributes(attr) + local t = {} + local attr = attr or {} + for k, v in pairs(attr) do + t[#t+1] = string.format("%s='%s'", k, escape_attr(v)) + end + -- sort attributes alphabetically. this will ensure that + -- their order will not change between several executions of dom:serialize() + table.sort(t) + if #t == 0 then return "" end + -- add space before attributes + return " " .. table.concat(t, " ") + end + local function start(typ, el, attr) + local format = get_action(typ, "start") + insert(format, el, prepare_attributes(attr)) + end + local function text(typ, text, parent) + local parent = parent or {} + local format = get_action(typ, "text") + if parent.verbatim then + insert(format, text) + else + insert(format, escape_element(text)) + end + end + local function stop(typ, el) + local format = get_action(typ, "stop") + insert(format,el) + end + local level = level or 0 + local spaces = string.rep(" ",level) + local root= current or parser._handler.root + local name = root._name or "unnamed" + local xtype = root._type or "untyped" + local text_content = root._text or "" + local attributes = root._attr or {} + -- if xtype == "TEXT" then + -- print(spaces .."TEXT : " .. root._text) + -- elseif xtype == "COMMENT" then + -- print(spaces .. "Comment : ".. root._text) + -- else + -- print(spaces .. xtype .. " : " .. name) + -- end + -- for k, v in pairs(attributes) do + -- print(spaces .. " ".. k.."="..v) + -- end + if xtype == "DTD" then + text_content = string.format('%s %s "%s" "%s"', name, attributes["_type"] or "", attributes._name, attributes._uri ) + -- remove unused fields + text_content = text_content:gsub('"nil"','') + text_content = text_content:gsub('%s*$','') + attributes = {} + elseif xtype == "ELEMENT" and void[name] and #current._children < 1 then + local format = get_action(xtype, "void") + insert(format, name, prepare_attributes(attributes)) + return output + elseif xtype == "PI" then + -- it contains spurious _text attribute + attributes["_text"] = nil + elseif xtype == "DECL" and name =="xml" then + -- the xml declaration attributes must be in a correct order + local encoding = attributes.encoding or "utf-8" + insert("", attributes.version, encoding) + return output + elseif xtype == "CDATA" then + -- return content unescaped + insert("", text_content) + return output + end + + start(xtype, name, attributes) + text(xtype,text_content, (current or {})._parent) + local children = root._children or {} + for _, child in ipairs(children) do + output = serialize_dom(parser,child, level + 1, output) + end + stop(xtype, name) + return output +end + +--- XML parsing function +-- Parse the XML text and create the DOM object. +-- @return DOM_Object +parse = function( + xmltext --- String to be parsed + ,voidElements --- hash table with void elements + ) + local domHandler = handler.domHandler() + --- @type DOM_Object + local DOM_Object = xml.xmlParser(domHandler) + -- preserve whitespace + DOM_Object.options.stripWS = nil + -- don't try to expand entities + DOM_Object.options.expandEntities = nil + local voidElements = voidElements or void + DOM_Object._handler.options.voidElements = voidElements + DOM_Object:parse(xmltext) + DOM_Object.current = DOM_Object._handler.root + DOM_Object.__index = DOM_Object + DOM_Object.css_query = css_query() + + local function save_methods(element) + setmetatable(element,DOM_Object) + local children = element._children or {} + for _, x in ipairs(children) do + save_methods(x) + end + end + local parser = setmetatable({}, DOM_Object) + + --- Returns root element of the DOM_Object + -- @return DOM_Object + function DOM_Object:root_node() + return self._handler.root + end + + + --- Get current node type + -- @param el [optional] node to get the type of + function DOM_Object:get_node_type( + el --- [optional] element to test + ) + local el = el or self + return el._type + end + + --- Test if the current node is an element. + -- You can pass different element as parameter + -- @return boolean + function DOM_Object:is_element( + el --- [optional] element to test + ) + local el = el or self + return self:get_node_type(el) == "ELEMENT" -- @bool + end + + + --- Test if current node is text + -- @return boolean + function DOM_Object:is_text( + el --- [optional] element to test + ) + local el = el or self + return self:get_node_type(el) == "TEXT" + end + + local lower = string.lower + + --- Return name of the current element + -- @return string + function DOM_Object:get_element_name( + el --- [optional] element to test + ) + local el = el or self + return el._name or "unnamed" + end + + --- Get value of an attribute + -- @return string + function DOM_Object:get_attribute( + name --- Attribute name + ) + local el = self + if self:is_element(el) then + local attr = el._attr or {} + return attr[name] + end + end + + --- Set value of an attribute + -- @return boolean + function DOM_Object:set_attribute( + name --- Attribute name + , value --- Value to be set + ) + local el = self + if self:is_element(el) then + el._attr = el._attr or {} + el._attr[name] = value + return true + end + end + + + --- Serialize the current node back to XML + -- @return string + function DOM_Object:serialize( + current --- [optional] element to be serialized + ) + local current = current + -- if no current element is added and self is not plain parser object + -- (_type is then nil), use the current object as serialized root + if not current and self._type then + current = self + end + return table.concat(serialize_dom(self, current)) + end + + --- Get text content from the node and all of it's children + -- @return string + function DOM_Object:get_text( + current --- [optional] element which should be converted to text + ) + local current = current or self + local text = {} + if current:is_text() then return current._text or "" end + for _, el in ipairs(current:get_children()) do + if el:is_text() then + text[#text+1] = el._text or "" + elseif el._type == "CDATA" then + text[#text+1] = el._text or "" + elseif el:is_element() then + text[#text+1] = el:get_text() + end + end + return table.concat(text) + end + + + + --- Retrieve elements from the given path. + -- The path is list of elements separated by space, + -- starting from the top element of the current element + -- @return table of elements which match the path + function DOM_Object:get_path( + path --- path to be traversed + , current --- [optional] element which should be traversed. Default element is the root element of the DOM_Object + ) + local function traverse_path(path_elements, current, t) + local t = t or {} + if #path_elements == 0 then + -- for _, x in ipairs(current._children or {}) do + -- table.insert(t,x) + -- end + table.insert(t,current) + return t + end + local current_path = table.remove(path_elements, 1) + for _, x in ipairs(self:get_children(current)) do + if self:is_element(x) then + local name = string.lower(self:get_element_name(x)) + if name == current_path then + t = traverse_path(path_elements, x, t) + end + end + end + return t + end + local current = current or self:root_node() -- self._handler.root + local path_elements = {} + local path = string.lower(path) + for el in path:gmatch("([^%s]+)") do table.insert(path_elements, el) end + return traverse_path(path_elements, current) + end + + --- Select elements chidlren using CSS selector syntax + -- @return table with elements matching the selector. + function DOM_Object:query_selector( + selector --- String using the CSS selector syntax + ) + local css_query = self.css_query + local css_parts = css_query:prepare_selector(selector) + return css_query:get_selector_path(self, css_parts) + end + + --- Get table with children of the current element + -- @return table with children of the selected element + function DOM_Object:get_children( + el --- [optional] element to be selected + ) + local el = el or self + local children = el._children or {} + return children + end + + --- Get the parent element + -- @return DOM_Object parent element + function DOM_Object:get_parent( + el --- [optional] element to be selected + ) + local el = el or self + return el._parent + end + + --- Execute function on the current element and all it's children nodes. + -- The differenct to DOM_Object:traverse_elements() is that it executes the function + -- also on text nodes and all other kinds of XML nodes. + -- The traversing of child elements of a given node can be disabled when the executed + -- function returns false. + function DOM_Object:traverse( + fn, --- function which will be executed on the current element and all it's children + current --- [optional] element to be selected + ) + local current = current or self -- + -- Following situation may happen when this method is called directly on the parsed object + if not current:get_node_type() then + current = self:root_node() + end + local status = true + local status = fn(current) + if current:is_element() or current:get_node_type() == "ROOT" then + -- don't traverse child nodes when the user function return false + if status ~= false then + for _, child in ipairs(current:get_children()) do + self:traverse(fn, child) + end + end + end + end + + --- Execute function on the current element and all it's children elements. + --- The traversing of child elements of a given node can be disabled when the executed + -- function returns false. + -- @return nothing + function DOM_Object:traverse_elements( + fn, --- function which will be executed on the current element and all it's children + current --- [optional] element to be selected + ) + local current = current or self -- + current:traverse(function(node) + if node:is_element() or node:get_node_type() == "ROOT" then + fn(node) + end + end) + end + + --- Get table with the inner text of an element, every text node is a separate table item. + --- @return table + function DOM_Object:strings( + current --- [optional] element to be selected + ) + local strings = {} + local current = current or self + current:traverse(function(node) + if node:get_node_type() == "TEXT" then + table.insert(strings, node._text or "") + end + end) + return strings + end + + --- Get table with the inner text of an element - leading and trailing spaces are removed and elements that contain only white space are ignored. + -- @return table + function DOM_Object:stripped_strings( + current --- [optional] element to be selected + ) + local current = current or self + local strings = current:strings() + local cleaned = {} + for k,v in ipairs(strings) do + v = v:gsub("^%s*", ""):gsub("%s*$", "") + if v ~= "" then + table.insert(cleaned, v) + end + end + return cleaned + end + + + + + --- Execute function on list of elements returned by DOM_Object:get_path() + function DOM_Object:traverse_node_list( + nodelist --- table with nodes selected by DOM_Object:get_path() + , fn --- function to be executed + ) + local nodelist = nodelist or {} + for _, node in ipairs(nodelist) do + for _, element in ipairs(node._children) do + fn(element) + end + end + end + + --- Replace the current node with new one + -- @return boolean, message + function DOM_Object:replace_node( + new --- element which should replace the current element + ) + local old = self + local parent = self:get_parent(old) + local id,msg = self:find_element_pos( old) + if id then + parent._children[id] = new + return true + end + return false, msg + end + + -- restore correct links to parent elements + local function fix_parents(el) + for k,v in ipairs(el._children or {}) do + if v:is_element() then + v._parent = el + fix_parents(v) + end + end + end + + + --- Add child node to the current node + function DOM_Object:add_child_node( + child, --- element to be inserted as a current node child + position --- [optional] position at which should the node be inserted + ) + local parent = self + child._parent = parent + fix_parents(child) + if position then + table.insert(parent._children, position, child) + else + table.insert(parent._children, child) + end + end + + + --- Create copy of the current node + -- @return DOM_Object element + function DOM_Object:copy_node( + element --- [optional] element to be copied + ) + local element = element or self + local t = {} + for k, v in pairs(element) do + if type(v) == "table" and k~="_parent" then + t[k] = self:copy_node(v) + else + t[k] = v + end + end + save_methods(t) + return t + end + + + --- Create a new element + -- @return DOM_Object element + function DOM_Object:create_element( + name, -- New tag name + attributes, -- Table with attributes + parent -- [optional] element which should be saved as the element's parent + ) + local parent = parent or self + local new = {} + new._type = "ELEMENT" + new._name = name + new._attr = attributes or {} + new._children = {} + new._parent = parent + save_methods(new) + return new + end + + --- Create new text node + -- @return DOM_Object text object + function DOM_Object:create_text_node( + text, -- string + parent -- [optional] element which should be saved as the element's parent + ) + local parent = parent or self + local new = {} + new._type = "TEXT" + new._parent = parent + new._text = text + save_methods(new) + return new + end + + --- Delete current node + function DOM_Object:remove_node( + element -- [optional] element to be removed + ) + local element = element or self + local parent = self:get_parent(element) + local pos = self:find_element_pos(element) + -- if pos then table.remove(parent._children, pos) end + if pos then + -- table.remove(parent._children, pos) + parent._children[pos] = setmetatable({_type = "removed"}, DOM_Object) + end + end + + --- Find the element position in the current node list + -- @return integer position of the current element in the element table + function DOM_Object:find_element_pos( + el -- [optional] element which should be looked up + ) + local el = el or self + local parent = self:get_parent(el) + if not self:is_element(parent) and self:get_node_type(parent) ~= "ROOT" then return nil, "The parent isn't element" end + for i, x in ipairs(parent._children) do + if x == el then return i end + end + return false, "Cannot find element" + end + + --- Get node list which current node is part of + -- @return table with elements + function DOM_Object:get_siblings( + el -- [optional] element for which the sibling element list should be retrieved + ) + local el = el or self + local parent = el:get_parent() + if parent:is_element() then + return parent:get_children() + end + end + + --- Get sibling node of the current node + -- @param change Distance from the current node + -- @return DOM_Object node + function DOM_Object:get_sibling_node( change) + local el = self + local pos = el:find_element_pos() + local siblings = el:get_siblings() + if pos and siblings then + return siblings[pos + change] + end + end + + --- Get next node + -- @return DOM_Object node + function DOM_Object:get_next_node( + el --- [optional] node to be used + ) + local el = el or self + return el:get_sibling_node(1) + end + + --- Get previous node + -- @return DOM_Object node + function DOM_Object:get_prev_node( + el -- [optional] node to be used + ) + local el = el or self + return el:get_sibling_node(-1) + end + + --- parse string as HTML or XML and return created elements + --- @return table elements + function DOM_Object:create_template( + str, + is_xml + ) + -- Wim Obbels: changed 20250927, to allow '<' in ",false) + -- local scrpt_text = scrpt:create_text_node(filtered_cmds) + -- scrpt:add_child_node(scrpt_text) + -- preamble:add_child_node(scrpt) + end + + -- 2025-09: experimantal CSS feature + log:trace("Process .xmcss file if present") + local css_file = src:gsub(".html$", ".xmcss") + if not path.exists(css_file) then + log:debugf("No .xmcss file %s present",css_file) + css_file = nil + end + + if css_file and path.getsize(css_file) == 0 then + log:debug("Removing empty .xmcss file %s", css_file) + pl.file.delete(css_file) + css_file = nil + end + + if css_file then + + local preambles = dom:query_selector("div.preamble") + + if #preambles == 0 then + -- Should not happen ... + log:error("No div.preamble in html : please add one") + end + + local preamble = preambles[1] + local scrpt = preamble:create_element("style") + scrpt:set_attribute("type", "text/css") + + + local f = io.open(css_file, "r") + local csslines = f:read("*a") + f:close() + + + csslines= csslines:gsub("\\%%", "%%") -- remove all 'exotic' characters; _ must be kept... + + -- local _, n_cmds = cmds:gsub("\n","") + -- local _, n_filtered_cmds = filtered_cmds:gsub("\n","") + + log:infof("Adding CSS style : \n %s", csslines) + + local style_text = scrpt:create_text_node(csslines) + scrpt:add_child_node(style_text) preamble:add_child_node(scrpt) end diff --git a/pgfsys-dvisvgm4ht.def b/pgfsys-dvisvgm4ht.def index 4465cb0..1bc1435 100644 --- a/pgfsys-dvisvgm4ht.def +++ b/pgfsys-dvisvgm4ht.def @@ -54,8 +54,8 @@ \HLet\pgfsys@endpicture\:tempa % start picture around TikZ and PGF environments - \ConfigureEnv{tikzpicture}{\texfourht@tikz@begin}{\texfourht@tikz@end}{}{}% - \ConfigureEnv{pgfpicture}{\texfourht@tikz@begin}{\texfourht@tikz@end}{}{}% + \ConfigureEnv{tikzpicture}{\begingroup\texfourht@tikz@begin}{\texfourht@tikz@end\endgroup}{}{}% + \ConfigureEnv{pgfpicture}{\begingroup\texfourht@tikz@begin}{\texfourht@tikz@end\endgroup}{}{}% } \def\texfourht@tikz@begin{ diff --git a/src/css.dtx b/src/css.dtx new file mode 100644 index 0000000..c82f436 --- /dev/null +++ b/src/css.dtx @@ -0,0 +1,69 @@ +% \subsubsection{CSS support} +% This section documents an experimental feature to generate CSS for some LateX environments +% +% Tex4ht (sometimes) creates a |.xmcss| file, and luaxake integrates it into the .html + +% Write adhoc css, currently only used/tested for minipage sizing (Wim Obbels, 2025-09-05) +% \begin{macrocode} +%<*cfgXimera> + +\makeatletter + +%--- open output file for collected CSS +\newwrite\xmcss@out +\immediate\openout\xmcss@out=\jobname.xmcss + +% \xmCSS{ ... } : appends a line to \jobname.xmcss +% Important: we temporarily make % an ordinary character so "50%" is preserved. +\def\xmCSS{\begingroup\catcode`\%=12 \xmcss@grab} + +\long\def\xmcss@grab#1{% + \begingroup + \immediate\write\xmcss@out{#1}% + \endgroup + \endgroup +} + +% we must refer to minipage from the css file, because tags are being +% written *before* dimensions ar known +\newcount\mini@count +\ExplSyntaxOn +% save original minipage +\let\oldiimini\@iiiminipage +% redefine minipage +\def\@iiiminipage#1#2[#3]#4{% + % calculate minipage dimensions and save it to the CSS file + \xmCSS{\#minipage\the\mini@count{width:\fp_eval:n{#4/\textwidth*100}\%;}}% + \global\advance\mini@count by 1\relax% + \oldiimini{#1}{#2}[#3]{#4}% +} + +\ExplSyntaxOff + +%% Should be in image.dtx !! +%%%\ConfigureEnv{image}{% +%%% \ifvmode \IgnorePar\fi \EndP% +%%% \HCode{}}{}{} + +\ConfigureEnv{minipage}{\ifvmode\IgnorePar\fi\EndP\HCode{
}} +{\ifvmode\IgnorePar\fi\EndP\HCode{
\Hnewline}% +}{}{} + +\makeatother + +\Css{div.minipage { + float: left; + } +} + +\Css{div.minipage:last-child { + clear: none; + float: right; + } +} + +\Css{ div.minipage + :not(.minipage) {clear:both;overflow:auto;width:100\%;}} + +% +% \end{macrocode} diff --git a/src/enumerate.dtx b/src/enumerate.dtx index 7c37e97..bda0d4c 100644 --- a/src/enumerate.dtx +++ b/src/enumerate.dtx @@ -8,3 +8,47 @@ \renewcommand{\labelenumii}{\theenumii} % % \end{macrocode} +% \begin{macrocode} +%<*cfgXimera> +\catcode`\:=11 +% Insert
around thebibliography +\ConfigureEnv{thebibliography}{\ifvmode\IgnorePar\fi \EndP \HCode{
}}{\ifvmode\IgnorePar\fi \EndP \HCode{
}}{}{} +% now configure thebibliography to produce a description list +% \en:bib insertes delimiters for particular bibitems. at the beginning, it is empty, as there is no need to insert the delimiter +% it is then defined to insert the delimiter after the first bibitem +\ConfigureList{thebibliography}% + {\ifvmode\IgnorePar\fi\EndP\HCode{
}\let\en:bib=\empty}% opening tags + {\ifvmode\IgnorePar\fi\EndP\HCode{
}} % closing tags + {\en:bib\def\en:bib{\ifvmode\IgnorePar\fi\HCode{
}}}% at the bibitem + {\HCode{
}}% after biblabel +\catcode`\:=12 +\Css{.thebibliography dl { + display: grid; + grid-auto-columns: min-content 1fr; + grid-auto-flow: column; +}} +\Css{.thebibliography dt { + grid-column: 1; + margin-bottom: 0.5em; +}} +\catcode`\:=11 +\ConfigureList{enumerate}% + {\EndP\HCode{
    }\PushMacro\end:itm +\global\let\end:itm=\empty +} + {\PopMacro\end:itm \global\let\end:itm \end:itm +% +\EndP\HCode{
}\ShowPar +} + {\end:itm \gdef\end:itm{\EndP\Tg}\DeleteMark +} + {{\Configure{Link}{li}{}{ class="enumerate" id=}{}% + \let\EndLink=\empty\par\ShowPar +\AnchorLabel }% +} +\catcode`\:=12 +% +% \end{macrocode} diff --git a/src/feedback.dtx b/src/feedback.dtx index c545078..02618bd 100644 --- a/src/feedback.dtx +++ b/src/feedback.dtx @@ -1,7 +1,7 @@ % \subsubsection{Feedback} % \DescribeEnv{feedback}{An initially hidden environment that uncovers itself at an appropriate time.} % New Validator rewrite code added by Jason Nowell. Original code -% orovided by Jim Fowler Validator is an environment designed to run a +% provided by Jim Fowler. Validator is an environment designed to run a % custom check on answers (usually) using javascript code. % % Define a placeholder command for validator and feedback. diff --git a/src/freeresponse.dtx b/src/freeresponse.dtx index 7eec441..2216a1f 100644 --- a/src/freeresponse.dtx +++ b/src/freeresponse.dtx @@ -54,7 +54,7 @@ %<*htXimera> \renewenvironment{freeResponse}{\refstepcounter{problem}}{}% -\ConfigureEnv{freeResponse}{\stepcounter{identification}\ifvmode \IgnorePar\fi \EndP\HCode{
}}{\HCode{
}\IgnoreIndent}{}{}% +\ConfigureEnv{freeResponse}{\stepcounter{identification}\ifvmode \IgnorePar\fi \EndP\HCode{
}}{\EndP\HCode{
}\IgnoreIndent}{}{}% % -% \end{macrocode} \ No newline at end of file +% \end{macrocode} diff --git a/src/hints.dtx b/src/hints.dtx index df14fc9..6e51978 100644 --- a/src/hints.dtx +++ b/src/hints.dtx @@ -22,7 +22,7 @@ \ifhandout \setbox0\vbox\bgroup \else - \begin{trivlist}\item[\hskip \labelsep\small\slshape\bfseries \GetTranslation{hint}:\hspace{2ex}] + \begin{trivlist}\item[\hskip \labelsep\small\slshape\bfseries \GetTranslation{Hint}:\hspace{2ex}] \small\slshape \fi \stepcounter{hintLevel} @@ -38,7 +38,7 @@ \ifhints \renewenvironment{hint}{ - \begin{trivlist}\item[\hskip \labelsep\small\slshape\bfseries \GetTranslation{hint}:\hspace{2ex}] + \begin{trivlist}\item[\hskip \labelsep\small\slshape\bfseries \GetTranslation{Hint}:\hspace{2ex}] \small\slshape } { diff --git a/src/image.dtx b/src/image.dtx index 48dba1e..c4dd914 100644 --- a/src/image.dtx +++ b/src/image.dtx @@ -21,9 +21,18 @@ % % \end{macrocode} % \DescribeMacro{\alt}{Inside an |image| environment, |\alt| provides alt-text for assistive technology like screenreaders.} +% \DescribeMacro{\xmalt}{Generic command to provide alt-text for assistive technology like screenreaders, via the HTML
tag.} % \begin{macrocode} %<*classXimera> -\newcommand{\alt}[1]{} +\newcommand{\alt}[1]{} %% Deprecated + +\providecommand\xmaltprint{} +%% use \undef\xmaltprint to NOT have \xmalt output in the PDF +\newcommand{\xmalt}[1]{% %% see infra for HTML implementation; 2026, J. Kuan + \ifdefined\xmaltprint% + {\footnotesize\color{gray}Alt text: #1}% + \fi% +} % % \end{macrocode} % The |image| environment doesn't actually work in tex4ht as defined @@ -39,6 +48,10 @@ \HCode{}} \renewcommand{\alt}[1]{\HCode{}} +\renewcommand{\xmalt}[1]{% %% implementation 2026, J. Kuan + \ifvmode \IgnorePar\fi \EndP% + \HCode{
Show Alt Text} #1 \HCode{
}% +} % %<*cfgXimera> %% Although we accept many formats, SVG is preferred on the web. diff --git a/src/interactives/doenet.dtx b/src/interactives/doenet.dtx new file mode 100644 index 0000000..87a274b --- /dev/null +++ b/src/interactives/doenet.dtx @@ -0,0 +1,16 @@ +% \subsubsection{Doenet} +% \DescribeMacro{\doenet}{Doenet command. Requires id and width, and height as arguments.} +% \begin{macrocode} +%<*classXimera> +%Doenet link +\newcommand{\doenet}[3]{Doenet link: \url{https://beta.doenet.org/activityViewer/#1}}% +% +% \end{macrocode} +% \begin{macrocode} +%<*htXimera> +%command definition +\renewcommand{\doenet}[3]{% + \HCode{} +} +% +% \end{macrocode} \ No newline at end of file diff --git a/src/packages.dtx b/src/packages.dtx index f1aa14a..84e8347 100644 --- a/src/packages.dtx +++ b/src/packages.dtx @@ -51,5 +51,37 @@ \RequirePackage{gettitlestring} \RequirePackage{nameref} \RequirePackage{epstopdf} -% % \end{macrocode} +% \subsection{Blocking conflicting packages} +% The following packages conflict with Ximera's own page layout, +% header/footer, author, and spacing handling (set up in +% |src/pagesetup.dtx| and |src/title.dtx|). If a contributor's +% document tries to load one of these, we make |\usepackage| a +% no-op instead of erroring, and warn in the compile log. +% \begin{macrocode} +\newcommand{\ximera@blockpkg}[1]{% + \@namedef{ver@#1.sty}{9999/99/99}% + \@namedef{opt@#1.sty}{}% + \PackageWarningNoLine{ximera}{% + The `#1' package conflicts with Ximera's page layout and has + been disabled. Loading it here was ignored% + }% +} + +\ximera@blockpkg{geometry} +\ximera@blockpkg{fullpage} +\ximera@blockpkg{authblk} +\ximera@blockpkg{setspace} +\ximera@blockpkg{fancyhdr} +\ximera@blockpkg{multicol} +\ximera@blockpkg{ragged2e} + +\let\ximera@old@pagenumbering\pagenumbering +\renewcommand{\pagenumbering}[1]{% + \PackageWarningNoLine{ximera}{% + \string\pagenumbering\space conflicts with Ximera's page + numbering and was ignored (argument: #1)% + }% +} +% +% \end{macrocode} \ No newline at end of file diff --git a/src/pagesetup.dtx b/src/pagesetup.dtx index a54dc02..1d567c6 100644 --- a/src/pagesetup.dtx +++ b/src/pagesetup.dtx @@ -18,7 +18,7 @@ % On the HTML side, there is more complicated page setup to perform. % \begin{macrocode} %<*cfgXimera> -\Preamble{xhtml,mathjax} +\Preamble{xhtml,mathjax,minipage-width} % We don't want to translate font suggestions with ugly wrappers like % for italic text diff --git a/src/validators/equalMatrix.dtx b/src/validators/equalMatrix.dtx index 4700f04..b55c1e2 100644 --- a/src/validators/equalMatrix.dtx +++ b/src/validators/equalMatrix.dtx @@ -18,6 +18,7 @@ %%% Apend code via \appendtoverbtoks \appendtoverbtoks? +// ? % % \end{macrocode} diff --git a/src/validators/factorCheck.dtx b/src/validators/factorCheck.dtx index 86ad8f5..9d0dd75 100644 --- a/src/validators/factorCheck.dtx +++ b/src/validators/factorCheck.dtx @@ -25,6 +25,7 @@ %%% Apend code via \appendtoverbtoks \appendtoverbtoks? +// ? % % \end{macrocode} diff --git a/src/validators/multiAns.dtx b/src/validators/multiAns.dtx index 874db9a..2a59656 100644 --- a/src/validators/multiAns.dtx +++ b/src/validators/multiAns.dtx @@ -11,6 +11,7 @@ %%% Apend code via \appendtoverbtoks \appendtoverbtoks? +// ? % % \end{macrocode} diff --git a/src/validators/sameDerivative.dtx b/src/validators/sameDerivative.dtx index 3e880e3..2a93f41 100644 --- a/src/validators/sameDerivative.dtx +++ b/src/validators/sameDerivative.dtx @@ -9,6 +9,7 @@ %%% Apend code via \@addToValidators \appendtoverbtoks? +// ? % % \end{macrocode} diff --git a/src/validators/supplementalCommands.dtx b/src/validators/supplementalCommands.dtx index be60d29..048b68e 100644 --- a/src/validators/supplementalCommands.dtx +++ b/src/validators/supplementalCommands.dtx @@ -7,8 +7,15 @@ % \begin{macrocode} %<*classXimera> \appendtoverbtoks? +// ? % % \end{macrocode} diff --git a/src/validators/unactivatedValidators.dtx b/src/validators/unactivatedValidators.dtx index c5f4c9e..0f2acf5 100644 --- a/src/validators/unactivatedValidators.dtx +++ b/src/validators/unactivatedValidators.dtx @@ -20,12 +20,14 @@ %%% Apend code via \verb|\appendtoverbtoks| %\appendtoverbtoks? +%// %? % % @@ -44,11 +46,13 @@ %%% Apend code via \verb|\appendtoverbtoks| %\appendtoverbtoks? +%// 0; % }; +%//]]> %? % % @@ -71,12 +75,14 @@ %%% Apend code via \verb|\appendtoverbtoks| %\appendtoverbtoks? +%// %? % % diff --git a/ximera.4ht b/ximera.4ht index 91c6446..be81de1 100644 --- a/ximera.4ht +++ b/ximera.4ht @@ -25,6 +25,7 @@ %% src/interactives/javascript.dtx (with options: `htXimera') %% src/interactives/include.dtx (with options: `htXimera') %% src/interactives/geogebra.dtx (with options: `htXimera') +%% src/interactives/doenet.dtx (with options: `htXimera') %% src/interactives/desmos.dtx (with options: `htXimera') %% src/interactives/google.dtx (with options: `htXimera') %% src/feedback.dtx (with options: `htXimera') @@ -173,6 +174,10 @@ \HCode{}} \renewcommand{\alt}[1]{\HCode{}} +\renewcommand{\xmalt}[1]{% %% implementation 2026, J. Kuan + \ifvmode \IgnorePar\fi \EndP% + \HCode{
Show Alt Text} #1 \HCode{
}% +} \providecommand{\pgfsyspdfmark}[3]{} \renewenvironment{dialogue}{\begin{description}}{\end{description}} @@ -241,7 +246,7 @@ \renewenvironment{freeResponse}{\refstepcounter{problem}}{}% -\ConfigureEnv{freeResponse}{\stepcounter{identification}\ifvmode \IgnorePar\fi \EndP\HCode{
}}{\HCode{
}\IgnoreIndent}{}{}% +\ConfigureEnv{freeResponse}{\stepcounter{identification}\ifvmode \IgnorePar\fi \EndP\HCode{
}}{\EndP\HCode{
}\IgnoreIndent}{}{}% @@ -265,6 +270,9 @@ \renewcommand{\geogebra}[4][]{% \setkeys{geogebra}{#1}% Set new keys \HCode{}} +\renewcommand{\doenet}[3]{% + \HCode{} +} \catcode`\%=11 \renewcommand{\desmos}[3]{\HCode{}} \catcode`\%=14 diff --git a/ximera.cfg b/ximera.cfg index 45f4b20..b93ed99 100644 --- a/ximera.cfg +++ b/ximera.cfg @@ -8,7 +8,9 @@ %% src/pagesetup.dtx (with options: `cfgXimera') %% src/packages.dtx (with options: `cfgXimera') %% src/jax.dtx (with options: `cfgXimera') +%% src/css.dtx (with options: `cfgXimera') %% src/sectioning.dtx (with options: `cfgXimera') +%% src/enumerate.dtx (with options: `cfgXimera') %% src/title.dtx (with options: `cfgXimera') %% src/abstract.dtx (with options: `cfgXimera') %% src/image.dtx (with options: `cfgXimera') @@ -16,6 +18,7 @@ %% src/textcolor.dtx (with options: `cfgXimera') %% src/verbatim.dtx (with options: `cfgXimera') %% src/html.dtx (with options: `cfgXimera') +%% src/interactives/doenet.dtx (with options: `cfgXimera') %% src/ending.dtx (with options: `cfgXimera') %% ------------:| ------------------------------------------------------------ %% ximera:| Simultaneously writing print and online interactive materials @@ -32,7 +35,7 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\Preamble{xhtml,mathjax} +\Preamble{xhtml,mathjax,minipage-width} \NoFonts @@ -87,6 +90,59 @@ \ScriptEnv{matlabEquation}{\ifvmode \IgnorePar\fi \EndP\HCode{}} + + +\makeatletter + +\newwrite\xmcss@out +\immediate\openout\xmcss@out=\jobname.xmcss + +\def\xmCSS{\begingroup\catcode`\%=12 \xmcss@grab} + +\long\def\xmcss@grab#1{% + \begingroup + \immediate\write\xmcss@out{#1}% + \endgroup + \endgroup +} + +\newcount\mini@count +\ExplSyntaxOn +\let\oldiimini\@iiiminipage +\def\@iiiminipage#1#2[#3]#4{% + % calculate minipage dimensions and save it to the CSS file + \xmCSS{\#minipage\the\mini@count{width:\fp_eval:n{#4/\textwidth*100}\%;}}% + \global\advance\mini@count by 1\relax% + \oldiimini{#1}{#2}[#3]{#4}% +} + +\ExplSyntaxOff + +%% Should be in image.dtx !! +%%%\ConfigureEnv{image}{% +%%% \ifvmode \IgnorePar\fi \EndP% +%%% \HCode{}}{}{} + +\ConfigureEnv{minipage}{\ifvmode\IgnorePar\fi\EndP\HCode{
}} +{\ifvmode\IgnorePar\fi\EndP\HCode{
\Hnewline}% +}{}{} + +\makeatother + +\Css{div.minipage { + float: left; + } +} + +\Css{div.minipage:last-child { + clear: none; + float: right; + } +} + +\Css{ div.minipage + :not(.minipage) {clear:both;overflow:auto;width:100\%;}} + \renewcommand{\paragraph}[1]{% \HCode{}% #1% @@ -95,6 +151,41 @@ \HCode{}% #1% \HCode{}\par\IgnorePar} +\catcode`\:=11 +\ConfigureEnv{thebibliography}{\ifvmode\IgnorePar\fi \EndP \HCode{
}}{\ifvmode\IgnorePar\fi \EndP \HCode{
}}{}{} +\ConfigureList{thebibliography}% + {\ifvmode\IgnorePar\fi\EndP\HCode{
}\let\en:bib=\empty}% opening tags + {\ifvmode\IgnorePar\fi\EndP\HCode{
}} % closing tags + {\en:bib\def\en:bib{\ifvmode\IgnorePar\fi\HCode{
}}}% at the bibitem + {\HCode{
}}% after biblabel +\catcode`\:=12 +\Css{.thebibliography dl { + display: grid; + grid-auto-columns: min-content 1fr; + grid-auto-flow: column; +}} +\Css{.thebibliography dt { + grid-column: 1; + margin-bottom: 0.5em; +}} +\catcode`\:=11 +\ConfigureList{enumerate}% + {\EndP\HCode{
    }\PushMacro\end:itm +\global\let\end:itm=\empty +} + {\PopMacro\end:itm \global\let\end:itm \end:itm +\EndP\HCode{
}\ShowPar +} + {\end:itm \gdef\end:itm{\EndP\Tg}\DeleteMark +} + {{\Configure{Link}{li}{}{ class="enumerate" id=}{}% + \let\EndLink=\empty\par\ShowPar +\AnchorLabel }% +} +\catcode`\:=12 \ifvmode\IgnorePar\fi\EndP \ConfigureEnv{abstract}{\ifvmode\IgnorePar\fi\EndP\HCode{\Hnewline
}\par}{\ifvmode\IgnorePar\fi\EndP\HCode{\Hnewline
}\par}{}{} diff --git a/ximera.cls b/ximera.cls index a834d53..bc796de 100644 --- a/ximera.cls +++ b/ximera.cls @@ -28,6 +28,7 @@ %% src/interactives/javascript.dtx (with options: `classXimera') %% src/interactives/include.dtx (with options: `classXimera') %% src/interactives/geogebra.dtx (with options: `classXimera') +%% src/interactives/doenet.dtx (with options: `classXimera') %% src/interactives/desmos.dtx (with options: `classXimera') %% src/interactives/google.dtx (with options: `classXimera') %% src/interactives/graph.dtx (with options: `classXimera') @@ -522,7 +523,7 @@ \ifhandout \setbox0\vbox\bgroup \else -\begin{trivlist}\item[\hskip \labelsep\small\slshape\bfseries \GetTranslation{hint}:\hspace{2ex}] +\begin{trivlist}\item[\hskip \labelsep\small\slshape\bfseries \GetTranslation{Hint}:\hspace{2ex}] \small\slshape \fi \stepcounter{hintLevel} @@ -538,7 +539,7 @@ \ifhints \renewenvironment{hint}{ -\begin{trivlist}\item[\hskip \labelsep\small\slshape\bfseries \GetTranslation{hint}:\hspace{2ex}] +\begin{trivlist}\item[\hskip \labelsep\small\slshape\bfseries \GetTranslation{Hint}:\hspace{2ex}] \small\slshape } { @@ -645,7 +646,15 @@ \NewEnviron{image}[1][3in]{% \begin{center}\resizebox{#1}{!}{\BODY}\end{center}% resize and center } -\newcommand{\alt}[1]{} +\newcommand{\alt}[1]{} %% Deprecated + +\providecommand\xmaltprint{} +%% use \undef\xmaltprint to NOT have \xmalt output in the PDF +\newcommand{\xmalt}[1]{% %% see infra for HTML implementation; 2026, J. Kuan + \ifdefined\xmaltprint% + {\footnotesize\color{gray}Alt text: #1}% + \fi% +} \DefineVerbatimEnvironment{javascript}{Verbatim}{numbers=left,frame=lines,label=JavaScript,labelposition=topline} @@ -663,6 +672,7 @@ Interactive } \newcommand{\geogebra}[3]{GeoGebra link: \url{https://www.geogebra.org/m/#1}} +\newcommand{\doenet}[3]{Doenet link: \url{https://beta.doenet.org/activityViewer/#1}}% \newcommand{\desmos}[3]{Desmos link: \url{https://www.desmos.com/calculator/#1}} \newcommand{\desmosThreeD}[3]{Desmos3D link: \url{https://www.desmos.com/3d/#1}} \newcommand{\googleSheet}[5]{% diff --git a/ximera.dtx b/ximera.dtx index 2609cd2..53ca750 100644 --- a/ximera.dtx +++ b/ximera.dtx @@ -107,6 +107,7 @@ Running "make install" installs the files in the local TeX tree. \from{src/interactives/javascript.dtx}{classXimera} \from{src/interactives/include.dtx}{classXimera} \from{src/interactives/geogebra.dtx}{classXimera} + \from{src/interactives/doenet.dtx}{classXimera} \from{src/interactives/desmos.dtx}{classXimera} \from{src/interactives/google.dtx}{classXimera} \from{src/interactives/graph.dtx}{classXimera} @@ -155,7 +156,9 @@ Running "make install" installs the files in the local TeX tree. \from{src/pagesetup.dtx}{cfgXimera} \from{src/packages.dtx}{cfgXimera} \from{src/jax.dtx}{cfgXimera} + \from{src/css.dtx}{cfgXimera} %% added 2025-09; experimental \from{src/sectioning.dtx}{cfgXimera} + \from{src/enumerate.dtx}{cfgXimera} %% for lists \from{src/title.dtx}{cfgXimera} \from{src/abstract.dtx}{cfgXimera} \from{src/image.dtx}{cfgXimera} @@ -163,6 +166,7 @@ Running "make install" installs the files in the local TeX tree. \from{src/textcolor.dtx}{cfgXimera} \from{src/verbatim.dtx}{cfgXimera} \from{src/html.dtx}{cfgXimera} + \from{src/interactives/doenet.dtx}{cfgXimera} \from{src/ending.dtx}{cfgXimera} } } @@ -189,6 +193,7 @@ Running "make install" installs the files in the local TeX tree. \from{src/interactives/javascript.dtx}{htXimera} \from{src/interactives/include.dtx}{htXimera} \from{src/interactives/geogebra.dtx}{htXimera} + \from{src/interactives/doenet.dtx}{htXimera} \from{src/interactives/desmos.dtx}{htXimera} \from{src/interactives/google.dtx}{htXimera} \from{src/feedback.dtx}{htXimera} @@ -288,6 +293,7 @@ Running "make install" installs the files in the local TeX tree. \DocInput{src/interactives/include.dtx} \DocInput{src/interactives/google.dtx} \DocInput{src/interactives/geogebra.dtx} +\DocInput{src/interactives/doenet.dtx} \DocInput{src/interactives/desmos.dtx} \DocInput{src/interactives/graph.dtx} \DocInput{src/interactives/video.dtx} diff --git a/ximera.fls b/ximera.fls deleted file mode 100644 index 960e96a..0000000 --- a/ximera.fls +++ /dev/null @@ -1,850 +0,0 @@ -PWD /home/snapp/ximeraProject/bartOutcomesFootnote/.ximera_latex -INPUT /etc/texmf/web2c/texmf.cnf -INPUT /usr/share/texmf/web2c/texmf.cnf -INPUT /usr/share/texlive/texmf-dist/web2c/texmf.cnf -INPUT /var/lib/texmf/web2c/pdftex/pdflatex.fmt -INPUT ximera.dtx -OUTPUT ximera.log -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/docstrip.tex -INPUT ximera.dtx -OUTPUT ./ximera.cls -INPUT src/banner.dtx -INPUT src/options.dtx -INPUT src/packages.dtx -INPUT src/tikzexport.dtx -INPUT src/hyperref.dtx -INPUT src/suppress.dtx -INPUT src/makeCounter.dtx -INPUT src/pagesetup.dtx -INPUT src/metadata.dtx -INPUT src/macros.dtx -INPUT src/theorems.dtx -INPUT src/enumerate.dtx -INPUT src/proof.dtx -INPUT src/only.dtx -INPUT src/outcomes.dtx -INPUT src/problem.dtx -INPUT src/hints.dtx -INPUT src/abstract.dtx -INPUT src/title.dtx -INPUT src/image.dtx -INPUT src/interactives/javascript.dtx -INPUT src/interactives/include.dtx -INPUT src/interactives/geogebra.dtx -INPUT src/interactives/desmos.dtx -INPUT src/interactives/google.dtx -INPUT src/interactives/graph.dtx -INPUT src/link.dtx -INPUT src/interactives/video.dtx -INPUT src/answer.dtx -INPUT src/choice.dtx -INPUT src/solution.dtx -INPUT src/feedback.dtx -INPUT src/freeresponse.dtx -INPUT src/verbatim.dtx -INPUT src/dialogue.dtx -INPUT src/instructornotes.dtx -INPUT src/xkcd.dtx -INPUT src/foldable.dtx -INPUT src/leash.dtx -INPUT src/interactives/sagemath.dtx -INPUT src/jax.dtx -INPUT src/accordion.dtx -INPUT src/ungraded.dtx -INPUT src/clearEnv.dtx -INPUT src/hideEnv.dtx -INPUT src/localization.dtx -INPUT src/preamble.dtx -INPUT ximera.dtx -OUTPUT ./xourse.cls -INPUT src/optionsxourse.dtx -INPUT src/activity.dtx -INPUT src/sectioning.dtx -INPUT src/logo.dtx -INPUT src/graded.dtx -INPUT ximera.dtx -OUTPUT ./ximera.cfg -INPUT src/pagesetup.dtx -INPUT src/packages.dtx -INPUT src/jax.dtx -INPUT src/sectioning.dtx -INPUT src/title.dtx -INPUT src/abstract.dtx -INPUT src/image.dtx -INPUT src/outcomes.dtx -INPUT src/textcolor.dtx -INPUT src/verbatim.dtx -INPUT src/html.dtx -INPUT src/ending.dtx -INPUT ximera.dtx -OUTPUT ./ximera.4ht -INPUT src/pagesetup.dtx -INPUT src/abstract.dtx -INPUT src/title.dtx -INPUT src/problem.dtx -INPUT src/macros.dtx -INPUT src/theorems.dtx -INPUT src/proof.dtx -INPUT src/image.dtx -INPUT src/dialogue.dtx -INPUT src/foldable.dtx -INPUT src/interactives/video.dtx -INPUT src/xkcd.dtx -INPUT src/link.dtx -INPUT src/interactives/graph.dtx -INPUT src/answer.dtx -INPUT src/choice.dtx -INPUT src/freeresponse.dtx -INPUT src/interactives/javascript.dtx -INPUT src/interactives/include.dtx -INPUT src/interactives/geogebra.dtx -INPUT src/interactives/desmos.dtx -INPUT src/interactives/google.dtx -INPUT src/feedback.dtx -INPUT src/leash.dtx -INPUT src/labels.dtx -INPUT src/interactives/sagemath.dtx -INPUT src/ungraded.dtx -INPUT src/footnotes.dtx -INPUT src/accordion.dtx -INPUT src/ending.dtx -INPUT ximera.dtx -OUTPUT ./xourse.4ht -INPUT src/logo.dtx -INPUT src/metadata.dtx -INPUT src/activity.dtx -INPUT src/sectioning.dtx -INPUT src/graded.dtx -INPUT src/interactives/video.dtx -INPUT src/ending.dtx -INPUT ximera.dtx -OUTPUT ./ximera.ins -INPUT ximera.dtx -OUTPUT ./README.txt -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/ltxdoc.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/ltxdoc.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/ltxdoc.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/ltxdoc.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/ltxdoc.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/ltxdoc.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/ltxdoc.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/ltxdoc.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/ltxdoc.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/ltxdoc.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/ltxdoc.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex-dev/base/ltxdoc.cfg -INPUT /usr/share/texlive/texmf-dist/tex/latex-dev/base/ltxdoc.cfg -INPUT /usr/share/texlive/texmf-dist/tex/latex-dev/base/ltxdoc.cfg -INPUT /usr/share/texlive/texmf-dist/tex/latex-dev/base/ltxdoc.cfg -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/article.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/article.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/article.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/article.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/article.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/article.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/article.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/article.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/article.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/article.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/article.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/article.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/article.cls -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/size10.clo -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/size10.clo -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/size10.clo -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/size10.clo -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/doc.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/doc.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/doc.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/doc.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/doc.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/doc.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/doc.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/doc.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/doc.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/doc.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/doc.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/tools/multicol.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/tools/multicol.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/tools/multicol.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/tools/multicol.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/tools/multicol.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/tools/multicol.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/tools/multicol.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/tools/multicol.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/tools/multicol.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/tools/multicol.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/tools/multicol.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/tools/multicol.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/tools/multicol.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/geometry/geometry.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/geometry/geometry.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/geometry/geometry.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/geometry/geometry.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/geometry/geometry.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/geometry/geometry.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/geometry/geometry.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/geometry/geometry.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/geometry/geometry.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/geometry/geometry.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/geometry/geometry.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/iftex/ifvtex.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/iftex/ifvtex.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/iftex/ifvtex.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/iftex/ifvtex.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/iftex/ifvtex.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/iftex/ifvtex.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/iftex/ifvtex.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/iftex/ifvtex.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/iftex/ifvtex.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/iftex/ifvtex.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/iftex/ifvtex.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/iftex/iftex.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/iftex/iftex.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/iftex/iftex.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/iftex/iftex.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/iftex/iftex.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/iftex/iftex.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/iftex/iftex.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/iftex/iftex.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/iftex/iftex.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/iftex/iftex.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/iftex/iftex.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hypdoc/hypdoc.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hypdoc/hypdoc.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hypdoc/hypdoc.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hypdoc/hypdoc.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hypdoc/hypdoc.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hypdoc/hypdoc.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hypdoc/hypdoc.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hypdoc/hypdoc.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hypdoc/hypdoc.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hypdoc/hypdoc.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hypdoc/hypdoc.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/atveryend/atveryend.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/atveryend/atveryend.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/atveryend/atveryend.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/atveryend-ltx.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/atveryend/atveryend.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/atveryend/atveryend.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/atveryend-ltx.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/atveryend/atveryend.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/atveryend-ltx.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/atveryend-ltx.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/atveryend/atveryend.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/atveryend/atveryend.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/atveryend-ltx.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/atveryend-ltx.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/atveryend/atveryend.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/atveryend-ltx.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/doc.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/hyperref.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/hyperref.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/hyperref.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/hyperref.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/hyperref.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/hyperref.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/hyperref.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/hyperref.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/hyperref.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/hyperref.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/hyperref.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/ltxcmds/ltxcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/ltxcmds/ltxcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/ltxcmds/ltxcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/ltxcmds/ltxcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/ltxcmds/ltxcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/ltxcmds/ltxcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/ltxcmds/ltxcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/ltxcmds/ltxcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/ltxcmds/ltxcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/ltxcmds/ltxcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/ltxcmds/ltxcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/iftex/iftex.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/pdftexcmds/pdftexcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/pdftexcmds/pdftexcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/pdftexcmds/pdftexcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/pdftexcmds/pdftexcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/pdftexcmds/pdftexcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/pdftexcmds/pdftexcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/pdftexcmds/pdftexcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/pdftexcmds/pdftexcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/pdftexcmds/pdftexcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/pdftexcmds/pdftexcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/pdftexcmds/pdftexcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/infwarerr/infwarerr.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/infwarerr/infwarerr.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/infwarerr/infwarerr.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/infwarerr/infwarerr.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/infwarerr/infwarerr.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/infwarerr/infwarerr.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/infwarerr/infwarerr.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/infwarerr/infwarerr.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/infwarerr/infwarerr.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/infwarerr/infwarerr.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/infwarerr/infwarerr.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/iftex/iftex.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/ltxcmds/ltxcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/infwarerr/infwarerr.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/kvsetkeys/kvsetkeys.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/kvsetkeys/kvsetkeys.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/kvsetkeys/kvsetkeys.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/kvsetkeys/kvsetkeys.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/kvsetkeys/kvsetkeys.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/kvsetkeys/kvsetkeys.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/kvsetkeys/kvsetkeys.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/kvsetkeys/kvsetkeys.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/kvsetkeys/kvsetkeys.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/kvsetkeys/kvsetkeys.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/kvsetkeys/kvsetkeys.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/kvdefinekeys/kvdefinekeys.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/kvdefinekeys/kvdefinekeys.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/kvdefinekeys/kvdefinekeys.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/kvdefinekeys/kvdefinekeys.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/kvdefinekeys/kvdefinekeys.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/kvdefinekeys/kvdefinekeys.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/kvdefinekeys/kvdefinekeys.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/kvdefinekeys/kvdefinekeys.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/kvdefinekeys/kvdefinekeys.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/kvdefinekeys/kvdefinekeys.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/kvdefinekeys/kvdefinekeys.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/pdfescape/pdfescape.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/pdfescape/pdfescape.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/pdfescape/pdfescape.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/pdfescape/pdfescape.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/pdfescape/pdfescape.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/pdfescape/pdfescape.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/pdfescape/pdfescape.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/pdfescape/pdfescape.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/pdfescape/pdfescape.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/pdfescape/pdfescape.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/pdfescape/pdfescape.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/ltxcmds/ltxcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/pdftexcmds/pdftexcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hycolor/hycolor.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hycolor/hycolor.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hycolor/hycolor.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hycolor/hycolor.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hycolor/hycolor.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hycolor/hycolor.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hycolor/hycolor.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hycolor/hycolor.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hycolor/hycolor.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hycolor/hycolor.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hycolor/hycolor.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/letltxmacro/letltxmacro.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/letltxmacro/letltxmacro.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/letltxmacro/letltxmacro.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/letltxmacro/letltxmacro.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/letltxmacro/letltxmacro.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/letltxmacro/letltxmacro.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/letltxmacro/letltxmacro.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/letltxmacro/letltxmacro.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/letltxmacro/letltxmacro.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/letltxmacro/letltxmacro.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/letltxmacro/letltxmacro.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/auxhook/auxhook.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/auxhook/auxhook.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/auxhook/auxhook.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/auxhook/auxhook.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/auxhook/auxhook.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/auxhook/auxhook.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/auxhook/auxhook.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/auxhook/auxhook.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/auxhook/auxhook.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/auxhook/auxhook.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/auxhook/auxhook.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/kvoptions/kvoptions.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/kvoptions/kvoptions.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/kvoptions/kvoptions.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/kvoptions/kvoptions.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/kvoptions/kvoptions.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/kvoptions/kvoptions.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/kvoptions/kvoptions.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/kvoptions/kvoptions.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/kvoptions/kvoptions.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/kvoptions/kvoptions.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/kvoptions/kvoptions.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/ltxcmds/ltxcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/kvsetkeys/kvsetkeys.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/pd1enc.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/pd1enc.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/pd1enc.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/pd1enc.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/hyperref-langpatches.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/hyperref-langpatches.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/hyperref-langpatches.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/hyperref-langpatches.def -INPUT /usr/share/texlive/texmf-dist/tex/generic/intcalc/intcalc.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/intcalc/intcalc.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/intcalc/intcalc.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/intcalc/intcalc.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/intcalc/intcalc.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/intcalc/intcalc.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/intcalc/intcalc.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/intcalc/intcalc.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/intcalc/intcalc.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/intcalc/intcalc.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/intcalc/intcalc.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/etexcmds/etexcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/etexcmds/etexcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/etexcmds/etexcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/etexcmds/etexcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/etexcmds/etexcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/etexcmds/etexcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/etexcmds/etexcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/etexcmds/etexcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/etexcmds/etexcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/etexcmds/etexcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/etexcmds/etexcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/infwarerr/infwarerr.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/iftex/iftex.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/puenc.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/puenc.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/puenc.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/puenc.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/url/url.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/url/url.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/url/url.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/url/url.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/url/url.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/url/url.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/url/url.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/url/url.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/url/url.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/url/url.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/url/url.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/bitset/bitset.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/bitset/bitset.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/bitset/bitset.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/bitset/bitset.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/bitset/bitset.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/bitset/bitset.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/bitset/bitset.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/bitset/bitset.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/bitset/bitset.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/bitset/bitset.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/bitset/bitset.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/infwarerr/infwarerr.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/intcalc/intcalc.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/bigintcalc/bigintcalc.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/bigintcalc/bigintcalc.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/bigintcalc/bigintcalc.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/bigintcalc/bigintcalc.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/bigintcalc/bigintcalc.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/bigintcalc/bigintcalc.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/bigintcalc/bigintcalc.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/bigintcalc/bigintcalc.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/bigintcalc/bigintcalc.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/bigintcalc/bigintcalc.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/bigintcalc/bigintcalc.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/pdftexcmds/pdftexcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/atbegshi/atbegshi.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/atbegshi/atbegshi.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/atbegshi/atbegshi.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/atbegshi-ltx.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/atbegshi/atbegshi.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/atbegshi/atbegshi.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/atbegshi-ltx.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/atbegshi/atbegshi.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/atbegshi-ltx.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/atbegshi-ltx.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/atbegshi/atbegshi.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/atbegshi/atbegshi.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/atbegshi-ltx.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/atbegshi-ltx.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/atbegshi/atbegshi.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/base/atbegshi-ltx.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/hpdftex.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/hpdftex.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/hpdftex.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/hpdftex.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/atveryend/atveryend.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/rerunfilecheck/rerunfilecheck.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/rerunfilecheck/rerunfilecheck.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/rerunfilecheck/rerunfilecheck.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/rerunfilecheck/rerunfilecheck.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/rerunfilecheck/rerunfilecheck.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/rerunfilecheck/rerunfilecheck.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/rerunfilecheck/rerunfilecheck.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/rerunfilecheck/rerunfilecheck.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/rerunfilecheck/rerunfilecheck.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/rerunfilecheck/rerunfilecheck.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/rerunfilecheck/rerunfilecheck.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/kvoptions/kvoptions.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/infwarerr/infwarerr.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/pdftexcmds/pdftexcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/atveryend/atveryend.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/uniquecounter/uniquecounter.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/uniquecounter/uniquecounter.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/uniquecounter/uniquecounter.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/uniquecounter/uniquecounter.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/uniquecounter/uniquecounter.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/uniquecounter/uniquecounter.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/uniquecounter/uniquecounter.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/uniquecounter/uniquecounter.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/uniquecounter/uniquecounter.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/uniquecounter/uniquecounter.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/uniquecounter/uniquecounter.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/bigintcalc/bigintcalc.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/infwarerr/infwarerr.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/pdftexcmds/pdftexcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/rerunfilecheck/rerunfilecheck.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/hyperref.sty -OUTPUT ximera.idx -OUTPUT ximera.glo -INPUT /usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def -INPUT ./ximera.aux -INPUT ximera.aux -INPUT ximera.aux -OUTPUT ximera.aux -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/color.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/color.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/color.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/color.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/color.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/color.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/color.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/color.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/color.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/color.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics/color.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics-cfg/color.cfg -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics-cfg/color.cfg -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics-cfg/color.cfg -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics-cfg/color.cfg -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics-def/pdftex.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics-def/pdftex.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics-def/pdftex.def -INPUT /usr/share/texlive/texmf-dist/tex/latex/graphics-def/pdftex.def -INPUT /usr/share/texlive/texmf-dist/tex/context/base/mkii/supp-pdf.mkii -INPUT /usr/share/texlive/texmf-dist/tex/context/base/mkii/supp-pdf.mkii -INPUT /usr/share/texlive/texmf-dist/tex/context/base/mkii/supp-pdf.mkii -INPUT /usr/share/texlive/texmf-dist/tex/context/base/mkii/supp-pdf.mkii -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/nameref.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/nameref.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/nameref.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/nameref.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/nameref.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/nameref.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/nameref.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/nameref.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/nameref.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/nameref.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/hyperref/nameref.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/refcount/refcount.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/refcount/refcount.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/refcount/refcount.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/refcount/refcount.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/refcount/refcount.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/refcount/refcount.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/refcount/refcount.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/refcount/refcount.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/refcount/refcount.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/refcount/refcount.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/refcount/refcount.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/ltxcmds/ltxcmds.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/infwarerr/infwarerr.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/gettitlestring/gettitlestring.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/gettitlestring/gettitlestring.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/gettitlestring/gettitlestring.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/gettitlestring/gettitlestring.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/gettitlestring/gettitlestring.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/gettitlestring/gettitlestring.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/gettitlestring/gettitlestring.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/gettitlestring/gettitlestring.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/gettitlestring/gettitlestring.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/gettitlestring/gettitlestring.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/gettitlestring/gettitlestring.sty -INPUT /usr/share/texlive/texmf-dist/tex/latex/kvoptions/kvoptions.sty -INPUT /usr/share/texlive/texmf-dist/tex/generic/ltxcmds/ltxcmds.sty -INPUT ./ximera.out -INPUT ximera.out -INPUT ./ximera.out -INPUT ximera.out -INPUT ./ximera.out -INPUT ximera.out -INPUT ./ximera.out -INPUT ximera.out -OUTPUT ximera.pdf -INPUT ./ximera.out -INPUT ./ximera.out -OUTPUT ximera.out -INPUT ./ximera.hd -INPUT ximera.hd -INPUT ./ximera.hd -INPUT ximera.hd -INPUT ./ximera.hd -INPUT ./ximera.hd -OUTPUT ximera.hd -INPUT ./ximera.dtx -INPUT ximera.dtx -INPUT ./ximera.dtx -INPUT ximera.dtx -INPUT /usr/share/texlive/texmf-dist/fonts/map/fontname/texfonts.map -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmr17.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmss17.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmr12.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmmi12.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmmi12.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmsy10.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmsy10.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmr8.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmr6.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmmi8.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmmi6.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmsy8.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmsy6.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmr9.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmbx9.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmss9.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmtt9.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmr12.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmbx12.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmbx10.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmtt10.tfm -INPUT ./src/options.dtx -INPUT src/options.dtx -INPUT ./src/options.dtx -INPUT src/options.dtx -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmmi9.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmsy9.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmss8.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmss8.tfm -INPUT /var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmbx12.tfm -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmss10.tfm -INPUT ./src/packages.dtx -INPUT src/packages.dtx -INPUT ./src/packages.dtx -INPUT src/packages.dtx -INPUT ./src/pagesetup.dtx -INPUT src/pagesetup.dtx -INPUT ./src/pagesetup.dtx -INPUT src/pagesetup.dtx -INPUT ./src/macros.dtx -INPUT src/macros.dtx -INPUT ./src/macros.dtx -INPUT src/macros.dtx -INPUT ./src/theorems.dtx -INPUT src/theorems.dtx -INPUT ./src/theorems.dtx -INPUT src/theorems.dtx -INPUT ./src/enumerate.dtx -INPUT src/enumerate.dtx -INPUT ./src/enumerate.dtx -INPUT src/enumerate.dtx -INPUT ./src/proof.dtx -INPUT src/proof.dtx -INPUT ./src/proof.dtx -INPUT src/proof.dtx -INPUT ./src/problem.dtx -INPUT src/problem.dtx -INPUT ./src/problem.dtx -INPUT src/problem.dtx -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmss8.tfm -INPUT ./src/hints.dtx -INPUT src/hints.dtx -INPUT ./src/hints.dtx -INPUT src/hints.dtx -INPUT ./src/solution.dtx -INPUT src/solution.dtx -INPUT ./src/solution.dtx -INPUT src/solution.dtx -INPUT ./src/verbatim.dtx -INPUT src/verbatim.dtx -INPUT ./src/verbatim.dtx -INPUT src/verbatim.dtx -INPUT ./src/dialogue.dtx -INPUT src/dialogue.dtx -INPUT ./src/dialogue.dtx -INPUT src/dialogue.dtx -INPUT ./src/instructornotes.dtx -INPUT src/instructornotes.dtx -INPUT ./src/instructornotes.dtx -INPUT src/instructornotes.dtx -INPUT ./src/foldable.dtx -INPUT src/foldable.dtx -INPUT ./src/foldable.dtx -INPUT src/foldable.dtx -INPUT ./src/leash.dtx -INPUT src/leash.dtx -INPUT ./src/leash.dtx -INPUT src/leash.dtx -INPUT ./src/metadata.dtx -INPUT src/metadata.dtx -INPUT ./src/metadata.dtx -INPUT src/metadata.dtx -INPUT ./src/abstract.dtx -INPUT src/abstract.dtx -INPUT ./src/abstract.dtx -INPUT src/abstract.dtx -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmsltt10.tfm -INPUT ./src/title.dtx -INPUT src/title.dtx -INPUT ./src/title.dtx -INPUT src/title.dtx -INPUT ./src/only.dtx -INPUT src/only.dtx -INPUT ./src/only.dtx -INPUT src/only.dtx -INPUT ./src/outcomes.dtx -INPUT src/outcomes.dtx -INPUT ./src/outcomes.dtx -INPUT src/outcomes.dtx -INPUT ./src/labels.dtx -INPUT src/labels.dtx -INPUT ./src/labels.dtx -INPUT src/labels.dtx -INPUT ./src/image.dtx -INPUT src/image.dtx -INPUT ./src/image.dtx -INPUT src/image.dtx -INPUT ./src/tikzexport.dtx -INPUT src/tikzexport.dtx -INPUT ./src/tikzexport.dtx -INPUT src/tikzexport.dtx -INPUT ./src/xkcd.dtx -INPUT src/xkcd.dtx -INPUT ./src/xkcd.dtx -INPUT src/xkcd.dtx -INPUT ./src/hyperref.dtx -INPUT src/hyperref.dtx -INPUT ./src/hyperref.dtx -INPUT src/hyperref.dtx -INPUT ./src/interactives/include.dtx -INPUT src/interactives/include.dtx -INPUT ./src/interactives/include.dtx -INPUT src/interactives/include.dtx -INPUT ./src/interactives/google.dtx -INPUT src/interactives/google.dtx -INPUT ./src/interactives/google.dtx -INPUT src/interactives/google.dtx -INPUT ./src/interactives/geogebra.dtx -INPUT src/interactives/geogebra.dtx -INPUT ./src/interactives/geogebra.dtx -INPUT src/interactives/geogebra.dtx -INPUT ./src/interactives/desmos.dtx -INPUT src/interactives/desmos.dtx -INPUT ./src/interactives/desmos.dtx -INPUT src/interactives/desmos.dtx -INPUT ./src/interactives/graph.dtx -INPUT src/interactives/graph.dtx -INPUT ./src/interactives/graph.dtx -INPUT src/interactives/graph.dtx -INPUT ./src/interactives/video.dtx -INPUT src/interactives/video.dtx -INPUT ./src/interactives/video.dtx -INPUT src/interactives/video.dtx -INPUT ./src/interactives/javascript.dtx -INPUT src/interactives/javascript.dtx -INPUT ./src/interactives/javascript.dtx -INPUT src/interactives/javascript.dtx -INPUT ./src/interactives/sagemath.dtx -INPUT src/interactives/sagemath.dtx -INPUT ./src/interactives/sagemath.dtx -INPUT src/interactives/sagemath.dtx -INPUT ./src/answer.dtx -INPUT src/answer.dtx -INPUT ./src/answer.dtx -INPUT src/answer.dtx -INPUT ./src/choice.dtx -INPUT src/choice.dtx -INPUT ./src/choice.dtx -INPUT src/choice.dtx -INPUT ./src/freeresponse.dtx -INPUT src/freeresponse.dtx -INPUT ./src/freeresponse.dtx -INPUT src/freeresponse.dtx -INPUT ./src/feedback.dtx -INPUT src/feedback.dtx -INPUT ./src/feedback.dtx -INPUT src/feedback.dtx -INPUT ./src/ungraded.dtx -INPUT src/ungraded.dtx -INPUT ./src/ungraded.dtx -INPUT src/ungraded.dtx -INPUT ./src/jax.dtx -INPUT src/jax.dtx -INPUT ./src/jax.dtx -INPUT src/jax.dtx -INPUT ./src/html.dtx -INPUT src/html.dtx -INPUT ./src/html.dtx -INPUT src/html.dtx -INPUT ./src/suppress.dtx -INPUT src/suppress.dtx -INPUT ./src/suppress.dtx -INPUT src/suppress.dtx -INPUT ./src/ending.dtx -INPUT src/ending.dtx -INPUT ./src/ending.dtx -INPUT src/ending.dtx -INPUT ./src/optionsxourse.dtx -INPUT src/optionsxourse.dtx -INPUT ./src/optionsxourse.dtx -INPUT src/optionsxourse.dtx -INPUT ./src/activity.dtx -INPUT src/activity.dtx -INPUT ./src/activity.dtx -INPUT src/activity.dtx -INPUT /usr/share/texlive/texmf-dist/fonts/tfm/public/cm/cmti10.tfm -INPUT ./src/sectioning.dtx -INPUT src/sectioning.dtx -INPUT ./src/sectioning.dtx -INPUT src/sectioning.dtx -INPUT ./src/graded.dtx -INPUT src/graded.dtx -INPUT ./src/graded.dtx -INPUT src/graded.dtx -INPUT ./src/logo.dtx -INPUT src/logo.dtx -INPUT ./src/logo.dtx -INPUT src/logo.dtx -INPUT ximera.aux -INPUT ./ximera.out -INPUT ./ximera.out -INPUT ./ximera.hd -INPUT ./ximera.hd -INPUT /usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmbx10.pfb -INPUT /usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmbx12.pfb -INPUT /usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmbx9.pfb -INPUT /usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmmi9.pfb -INPUT /usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmr10.pfb -INPUT /usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmr12.pfb -INPUT /usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmr17.pfb -INPUT /usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmr7.pfb -INPUT /usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmr8.pfb -INPUT /usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmr9.pfb -INPUT /usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmsltt10.pfb -INPUT /usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmss10.pfb -INPUT /usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmss17.pfb -INPUT /usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmss9.pfb -INPUT /usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy10.pfb -INPUT /usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy6.pfb -INPUT /usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy9.pfb -INPUT /usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmti10.pfb -INPUT /usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmtt10.pfb -INPUT /usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmtt9.pfb diff --git a/ximera.glo b/ximera.glo deleted file mode 100644 index 7faf0f0..0000000 --- a/ximera.glo +++ /dev/null @@ -1,3 +0,0 @@ -\glossaryentry{v1.0.0> =General:>First public release|hdpindex{}}{1} -\glossaryentry{v1.5.0> =General:>Submitting to CTAN|hdpindex{}}{1} -\glossaryentry{v1.5.1> =General:>Fixed date bug|hdpindex{}}{1} diff --git a/ximera.ins b/ximera.ins index fba0056..e46dabc 100644 --- a/ximera.ins +++ b/ximera.ins @@ -80,6 +80,7 @@ Running "make install" installs the files in the local TeX tree. \from{src/interactives/javascript.dtx}{classXimera} \from{src/interactives/include.dtx}{classXimera} \from{src/interactives/geogebra.dtx}{classXimera} + \from{src/interactives/doenet.dtx}{classXimera} \from{src/interactives/desmos.dtx}{classXimera} \from{src/interactives/google.dtx}{classXimera} \from{src/interactives/graph.dtx}{classXimera} @@ -122,7 +123,9 @@ Running "make install" installs the files in the local TeX tree. \from{src/pagesetup.dtx}{cfgXimera} \from{src/packages.dtx}{cfgXimera} \from{src/jax.dtx}{cfgXimera} + \from{src/css.dtx}{cfgXimera} %% added 2025-09; experimental \from{src/sectioning.dtx}{cfgXimera} + \from{src/enumerate.dtx}{cfgXimera} %% for lists \from{src/title.dtx}{cfgXimera} \from{src/abstract.dtx}{cfgXimera} \from{src/image.dtx}{cfgXimera} @@ -130,6 +133,7 @@ Running "make install" installs the files in the local TeX tree. \from{src/textcolor.dtx}{cfgXimera} \from{src/verbatim.dtx}{cfgXimera} \from{src/html.dtx}{cfgXimera} + \from{src/interactives/doenet.dtx}{cfgXimera} \from{src/ending.dtx}{cfgXimera} } } @@ -156,6 +160,7 @@ Running "make install" installs the files in the local TeX tree. \from{src/interactives/javascript.dtx}{htXimera} \from{src/interactives/include.dtx}{htXimera} \from{src/interactives/geogebra.dtx}{htXimera} + \from{src/interactives/doenet.dtx}{htXimera} \from{src/interactives/desmos.dtx}{htXimera} \from{src/interactives/google.dtx}{htXimera} \from{src/feedback.dtx}{htXimera} diff --git a/ximera.pdf b/ximera.pdf index d7fae5e..ef81ca4 100644 Binary files a/ximera.pdf and b/ximera.pdf differ diff --git a/xmScripts/xmlatex b/xmScripts/xmlatex index 2adc27b..6e35b6f 100755 --- a/xmScripts/xmlatex +++ b/xmScripts/xmlatex @@ -46,9 +46,7 @@ fi # # default docker image to run; overwrite with 'export XAKE_IMAGE=myxake:0.1' : "${XAKE_BASE:=ximeralatex}" -: "${XAKE_VERSION:=v2.6.1}" -# : "${XAKE_BASE:=xake2019}" -# : "${XAKE_VERSION:=v2.1.1}" +: "${XAKE_VERSION:=v2.7.3}" : "${XAKE_CONTAINER:=$XAKE_BASE:$XAKE_VERSION}" : "${DOCKER_REPO:=ghcr.io/ximeraproject/}" @@ -56,6 +54,7 @@ fi : "${XAKE_IMAGE:=$DOCKER_REPO$XAKE_CONTAINER}" # TO BE OBSOLETED : "${DOCKER_IMAGE:=$XAKE_IMAGE}" : "${DOCKER_DEFAULT_PLATFORM:=linux/amd64}" # needed for MacOS ? +export DOCKER_DEFAULT_PLATFORM : "${SERVER_PORT:=2000}" : "${SERVER_NAME:=ximeraserver}" @@ -82,6 +81,15 @@ fi if [[ -f /.dockerenv ]] then [[ -n "$DEBUG" ]] && echo "Running in docker container (with local hostname $HOSTNAME)" +elif [[ -f /.containerenv ]] +then + [[ -n "$DEBUG" ]] && echo "Running in podman container (with local hostname $HOSTNAME)" +elif [[ "$container" == "podman" ]] +then + [[ -n "$DEBUG" ]] && echo "Running in podman container (with local hostname $HOSTNAME)" +elif [[ -n "$container" ]] +then + [[ -n "$DEBUG" ]] && echo "Running in container '$container' (with local hostname $HOSTNAME)" elif [[ -n "$KUBERNETES_SERVICE_HOST" ]] then echo "Running in kubernetes container ($KUBERNETES_SERVICE_HOST)" @@ -108,17 +116,39 @@ else [[ -n "$DEBUG" ]] && echo "Setting LOCAL_IP=$LOCAL_IP" fi + # Determine program to start the docker container (unless already set) + if [[ -z "$DOCKER" ]] + then + if type podman >/dev/null 2>&1 + then + [[ -n "$DEBUG" ]] && echo "Using podman ($(type podman))" + DOCKER=podman + # elif type podman.exe >/dev/null 2>&1 ### WON'T WORK because of mounting current folder? + # then + # [[ -n "$DEBUG" ]] && echo "Using podman ($(type podman))" + # DOCKER=podman.exe + elif type docker >/dev/null 2>&1 + then + [[ -n "$DEBUG" ]] && echo "Using docker ($(type docker))" + DOCKER=docker + else + error "No docker or podman executable found..." + fi + fi + if [[ "$1" == "ximeraserver" ]] then echo "Starting ximera $SERVER_NAME from $SERVER_IMAGE on port $SERVER_PORT" - docker run --rm --name $SERVER_NAME -p 2000:$SERVER_PORT $SERVER_IMAGE + $DOCKER run --rm --name $SERVER_NAME -p 2000:$SERVER_PORT $SERVER_IMAGE exit fi echo "Restarting myself in docker (from image $DOCKER_IMAGE)" + tty >/dev/null && INTERACTIVE="-it" # HACK: in terminal run with -it, to process interrupts with CTRL-C + [[ -n "$DEBUG" ]] && echo \ - docker run --env LOCAL_IP --env XIMERA_URL --env XIMERA_NAME --env GPG_KEY --env GPG_KEY_ID --env DEBUG --network host --rm $INTERACTIVE --mount --platform linux/amd64 type=bind,source=$MOUNTDIR,target=/code $DOCKER_IMAGE $COMMAND $* - docker run --env LOCAL_IP --env XIMERA_URL --env XIMERA_NAME --env GPG_KEY --env GPG_KEY_ID --env DEBUG --network host --rm $INTERACTIVE --mount type=bind,source=$MOUNTDIR,target=/code $DOCKER_IMAGE $COMMAND $* + $DOCKER run --env LOCAL_IP --env XIMERA_URL --env XIMERA_NAME --env GPG_KEY --env GPG_KEY_ID --env DEBUG --network host --rm $INTERACTIVE --mount type=bind,source=$MOUNTDIR,target=/code $DOCKER_IMAGE $COMMAND $* + $DOCKER run --env LOCAL_IP --env XIMERA_URL --env XIMERA_NAME --env GPG_KEY --env GPG_KEY_ID --env DEBUG --network host --rm $INTERACTIVE --mount type=bind,source=$MOUNTDIR,target=/code $DOCKER_IMAGE $COMMAND $* exit fi @@ -179,7 +209,7 @@ fi if [[ -d .texmf ]]; then echo "USING .texmf etc from local repo" [[ -d "/root/texmf/tex/generic" ]] || mkdir /root/texmf/tex/generic - ln -s /code/.texmf /root/texmf/tex/generic/local + ln -s $(pwd)/.texmf /root/texmf/tex/generic/local # cp -r .texmf/* /root/texmf/tex/generic/ fi @@ -189,10 +219,11 @@ if [[ -d .ximera_local ]]; then echo "USING .ximera_local from local repo" mv /root/texmf/tex/latex/ximeraLatex /root/ximeraLatex.ORI # mkdir /root/texmf/tex/latex/ximeraLatex - ln -s /code/.ximera_local/ /root/texmf/tex/latex/ximeraLatex + ln -s $(pwd)/.ximera_local/ /root/texmf/tex/latex/ximeraLatex if [[ -f .ximera_local/xmScripts/xmlatex ]]; then PATH=.ximera_local/xmScripts/:$PATH echo "USING local xmlatex script ($(type xmlatex))" + # THIS CAN NOT POSSIBLY WORK for xmLatex itself: the script is running already !!! fi fi @@ -281,7 +312,7 @@ COMMAND=$1 debug "COMMAND=$COMMAND" # Should not occur ... -[[ -z "$LUAXAKE" ]] && error "Mmm, luaxake command not found: $(type luaxake); $(type kpsewhich)" +[[ -z "$LUAXAKE" ]] && error "Mmm, luaxake command ($LUAXAKE) not found: $(type luaxake); $(type kpsewhich)" if [[ "$XIMERA_NAME" =~ [^a-z0-9] ]]; then @@ -309,6 +340,13 @@ reset_file_times() { # Even aftre a 'cache restore, this would cause re-compile of everything # therefore: restore all modif-dates echo "Resetting file modif times (this prevents some unneeded recompilations after a recent git checkout ...)" + +# if [ -f "/usr/lib/git-core/git-restore-mtime" ] +# then +# echo "Patching git restore-mtime" ### +# sed -i 's/whatchanged --pretty/whatchanged --i-still-use-this --pretty/' /usr/lib/git-core/git-restore-mtime +# fi + # # Construct a git restore-mtime command with proper 'verbosity' (AND allow to overwrite everything by setting a GIT_RESTORE variable!) # TODO: is -f really needed/wanted ...? @@ -625,6 +663,10 @@ EOF echo "I created a .xmKeyFile with a newly generated key for $KEY_UID." echo "This is convenient for quick testing, or in some cases while developing on your local PC." # echo "*** Do NEVER publish this key (eg by commit/push) ***" + + echo "Using settings from .xmkeyfile" + source .xmkeyfile + echo "Using key_id $GPG_KEY_ID (with key ${GPG_KEY:0:5}...)" fi @@ -813,11 +855,27 @@ then echo "Starting name (from bash script $0)" xake_name ## TODO?: get rid of these combinations, and put them in luaxake ... ? -elif [[ "$COMMAND" == "all" ]] +elif [[ "$COMMAND" == "htmltask" ]] # OPTION USED FOR TIKZEXPORT compilation +then + echo "Starting all (bake pdfexport/bake htmlexport/name/frost/serve; no ximera-downloads)" + shift + # HACK: split + $LUAXAKE bake --compile pdfexport $* || error "Problem with 'bake'; Exiting..." + $LUAXAKE bake --compile htmlexport $* || error "Problem with 'bake'; Exiting..." + + xake_name || error "Problem with 'name'; Exiting ..." + + $LUAXAKE frost $* || error "Problem with 'frost'; Exiting..." + $LUAXAKE serve $* || error "Problem with 'serve'; Exiting..." +elif [[ "$COMMAND" == "all" ]] # OPTION USED FOR ADHOC CALCULUS DEPLOYMENT 2025/09/02 then - echo "Starting all (bake/name/frost/serve)" + echo "Starting all (bake pdfexport/bake htmlexport/name/frost/serve; no ximera-downloads)" shift - $LUAXAKE bake $* || error "Problem with 'bake'; Exiting..." + # HACK: split + $LUAXAKE bake --compile pdfexport $* || error "Problem with 'bake'; Exiting..." + $LUAXAKE bake --compile htmlexport $* || error "Problem with 'bake'; Exiting..." + + rm -rf ximera-downloads/pdfexport # 20250905: contains pdfexport versions # git remote show ximera 2>/dev/null || xake_name @@ -853,13 +911,32 @@ then # Unfortunately, 'name' and 'genKey' can not (yet?) be integrated into luaxake ... [[ -z "$GPG_KEY_ID" ]] && xake_findKey # If no key present, try to find and set one - [[ -z "$GPG_KEY_ID" ]] && xake_genKey # If still no key present, try genKey to generate one) + # [[ -z "$GPG_KEY_ID" ]] && xake_genKey # If still no key present, try genKey to generate one) # git remote show ximera >/dev/null 2>&1 || xake_name xake_name # set the name (should only be needed if not-yet-set, OR CHANGED) $LUAXAKE ghaction $* || error "Exiting..." +elif [[ "$COMMAND" == "servetask" ]] +then + echo "Starting full build (name; bake/frost/serve)" + shift + + $LUAXAKE bake --compile pdfexport $* || error "Problem with 'bake'; Exiting..." + $LUAXAKE bake --compile htmlexport $* || error "Problem with 'bake'; Exiting..." + + # Unfortunately, 'name' and 'genKey' can not (yet?) be integrated into luaxake ... + [[ -z "$GPG_KEY_ID" ]] && xake_findKey # If no key present, try to find and set one + [[ -z "$GPG_KEY_ID" ]] && xake_genKey # If still no key present, try genKey to generate one) + + xake_name || error "Problem with 'name'; Exiting ..." + + $LUAXAKE frost $* || error "Problem with 'frost'; Exiting..." + $LUAXAKE serve $* || error "Problem with 'serve'; Exiting..." + + else $LUAXAKE $* fi + diff --git a/xmScripts/xmlatex.base b/xmScripts/xmlatex.base index 4373a8f..ce9aa3d 100755 --- a/xmScripts/xmlatex.base +++ b/xmScripts/xmlatex.base @@ -30,6 +30,9 @@ # # +# exit if we receive INT signal +trap 'exit 130' INT + : "${CONFIG_FILE:=./xmScripts/config.txt}" if [[ -f "$CONFIG_FILE" ]] @@ -43,9 +46,7 @@ fi # # default docker image to run; overwrite with 'export XAKE_IMAGE=myxake:0.1' : "${XAKE_BASE:=ximeralatex}" -: "${XAKE_VERSION:=v2.6.1}" -# : "${XAKE_BASE:=xake2019}" -# : "${XAKE_VERSION:=v2.1.1}" +: "${XAKE_VERSION:=v2.7.3}" : "${XAKE_CONTAINER:=$XAKE_BASE:$XAKE_VERSION}" : "${DOCKER_REPO:=ghcr.io/ximeraproject/}" @@ -53,6 +54,7 @@ fi : "${XAKE_IMAGE:=$DOCKER_REPO$XAKE_CONTAINER}" # TO BE OBSOLETED : "${DOCKER_IMAGE:=$XAKE_IMAGE}" : "${DOCKER_DEFAULT_PLATFORM:=linux/amd64}" # needed for MacOS ? +export DOCKER_DEFAULT_PLATFORM : "${SERVER_PORT:=2000}" : "${SERVER_NAME:=ximeraserver}" @@ -79,6 +81,15 @@ fi if [[ -f /.dockerenv ]] then [[ -n "$DEBUG" ]] && echo "Running in docker container (with local hostname $HOSTNAME)" +elif [[ -f /.containerenv ]] +then + [[ -n "$DEBUG" ]] && echo "Running in podman container (with local hostname $HOSTNAME)" +elif [[ "$container" == "podman" ]] +then + [[ -n "$DEBUG" ]] && echo "Running in podman container (with local hostname $HOSTNAME)" +elif [[ -n "$container" ]] +then + [[ -n "$DEBUG" ]] && echo "Running in container '$container' (with local hostname $HOSTNAME)" elif [[ -n "$KUBERNETES_SERVICE_HOST" ]] then echo "Running in kubernetes container ($KUBERNETES_SERVICE_HOST)" @@ -105,17 +116,39 @@ else [[ -n "$DEBUG" ]] && echo "Setting LOCAL_IP=$LOCAL_IP" fi + # Determine program to start the docker container (unless already set) + if [[ -z "$DOCKER" ]] + then + if type podman >/dev/null 2>&1 + then + [[ -n "$DEBUG" ]] && echo "Using podman ($(type podman))" + DOCKER=podman + # elif type podman.exe >/dev/null 2>&1 ### WON'T WORK because of mounting current folder? + # then + # [[ -n "$DEBUG" ]] && echo "Using podman ($(type podman))" + # DOCKER=podman.exe + elif type docker >/dev/null 2>&1 + then + [[ -n "$DEBUG" ]] && echo "Using docker ($(type docker))" + DOCKER=docker + else + error "No docker or podman executable found..." + fi + fi + if [[ "$1" == "ximeraserver" ]] then echo "Starting ximera $SERVER_NAME from $SERVER_IMAGE on port $SERVER_PORT" - docker run --rm --name $SERVER_NAME -p 2000:$SERVER_PORT $SERVER_IMAGE + $DOCKER run --rm --name $SERVER_NAME -p 2000:$SERVER_PORT $SERVER_IMAGE exit fi echo "Restarting myself in docker (from image $DOCKER_IMAGE)" + tty >/dev/null && INTERACTIVE="-it" # HACK: in terminal run with -it, to process interrupts with CTRL-C + [[ -n "$DEBUG" ]] && echo \ - docker run --env LOCAL_IP --env XIMERA_URL --env XIMERA_NAME --env GPG_KEY --env GPG_KEY_ID --env DEBUG --network host --rm $INTERACTIVE --mount type=bind,source=$MOUNTDIR,target=/code $DOCKER_IMAGE $COMMAND $* - docker run --env LOCAL_IP --env XIMERA_URL --env XIMERA_NAME --env GPG_KEY --env GPG_KEY_ID --env DEBUG --network host --rm $INTERACTIVE --mount type=bind,source=$MOUNTDIR,target=/code $DOCKER_IMAGE $COMMAND $* + $DOCKER run --env LOCAL_IP --env XIMERA_URL --env XIMERA_NAME --env GPG_KEY --env GPG_KEY_ID --env DEBUG --network host --rm $INTERACTIVE --mount type=bind,source=$MOUNTDIR,target=/code $DOCKER_IMAGE $COMMAND $* + $DOCKER run --env LOCAL_IP --env XIMERA_URL --env XIMERA_NAME --env GPG_KEY --env GPG_KEY_ID --env DEBUG --network host --rm $INTERACTIVE --mount type=bind,source=$MOUNTDIR,target=/code $DOCKER_IMAGE $COMMAND $* exit fi