diff options
author | Karl Berry <karl@freefriends.org> | 2019-01-10 22:21:14 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2019-01-10 22:21:14 +0000 |
commit | 8368bb1a1e80c128b441a121a8fda08f0e32d5ae (patch) | |
tree | fb96d623f66cd3bd555c48c0874af9c5ec85fc07 /Master | |
parent | 59da7b9e7d480f0bc7e89000998103cd707436e7 (diff) |
make4ht (10jan19)
git-svn-id: svn://tug.org/texlive/trunk@49664 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master')
19 files changed, 552 insertions, 120 deletions
diff --git a/Master/texmf-dist/doc/support/make4ht/README b/Master/texmf-dist/doc/support/make4ht/README index c878fdb1db4..46b22e5b14f 100644 --- a/Master/texmf-dist/doc/support/make4ht/README +++ b/Master/texmf-dist/doc/support/make4ht/README @@ -17,7 +17,7 @@ ePub and other e-book formats. `tex4ht` system supports several output formats, most notably `XHTML`, `HTML 5` and `ODT`. The conversion can be invoked using several commands. These commands invoke LaTeX\ or Plain TeX with special instructions to load `tex4ht.sty` package. The \TeX\ run produces special `DVI` file -which contains the code for desired output format. The `DVI` file is then processed and +which contains the code for desired output format. Produced `DVI` file is then processed and desired output files are created. The basic command provided by `tex4ht` is named `htlatex`. It compiles \LaTeX\ @@ -71,8 +71,6 @@ should copy all output files to the correct destinations. make4ht -d outputdir filename.tex - - The image conversion is configured in the [env file](http://www.tug.org/applications/tex4ht/mn35.html#index35-73001), which has really strange syntax based and the rules are @@ -96,6 +94,8 @@ format can be requested using the `--format` option. Supported formats are: - `xhtml` - `html5` - `odt` + - `tei` + - `docbook` The `--format` option can be also used for extension loading. @@ -130,7 +130,7 @@ common\_filters common\_domfilters -: Clean the HTML file using DOM filters. It is more powerful than +: clean the HTML file using DOM filters. It is more powerful than `common_filters`. Used DOM filters are `fixinlines`, `idcolons` and `joincharacters`. @@ -140,6 +140,10 @@ mathjaxnode convert from MathML code to HTML + CSS or SVG. See [the available settings](#mathjaxsettings). +odttemplate + +: automatically load the `odttemplate` filter. + staticsite : build the document in form suitable for static site generators like [Jekyll](https://jekyllrb.com/). @@ -375,9 +379,15 @@ mathjaxnode convert from MathML code to HTML + CSS or SVG. See [the available settings](#mathjaxsettings). +odttemplate + +: use styles from another `ODT` file serving as a template in the current + document. It works for the `styles.xml` file in the `ODT` file. During + the compilation, this file is named as `\jobname.4oy`. + staticsite -: create HTML file in format suitable for static site generators such as [Jekyll](https://jekyllrb.com/) +: create HTML files in format suitable for static site generators such as [Jekyll](https://jekyllrb.com/) svg-height @@ -431,6 +441,14 @@ joincharacters : join consecutive `<span>` or `<mn>` elements. +odtimagesize + +: set correct dimensions for images in the ODT format. It is loaded by default for the ODT output. + +t4htlinks + +: fix hyperlinks in the ODT format. + ### make4ht-aeneas-config package Companion for the `aeneas` DOM filter is the `make4ht-aeneas-config` plugin. It @@ -517,10 +535,10 @@ Table keys are the configured file names. It is necessary to insert them as `["filename.html"]`, because of Lua syntax rules. This example maps audio file `sample.mp3` to a section subpage. The main HTML -file, which may contain title and table of contents doesn't have an +file, which may contain title and table of contents doesn't have a corresponding audio file. -The filenames of sub files corresponds to chapter numbers, so they are not +Filenames of the sub files corresponds to the chapter numbers, so they are not stable when a new chapter is added. It is possible to request file names interfered from the chapter titles using the `sec-filename` option or `tex4ht`. @@ -796,6 +814,22 @@ parallel_size : number of pages used in each Dvisvgm call. The extension detects changed pages in the DVI file and construct multiple calls to Dvisvgm with only changed pages. +scale + +: SVG scaling. + +### The `odttemplate` filter and extension + +template + +: filename of the template `ODT` file + + +`odttemplate` can also get the template filename from the `odttemplate` option from `tex4ht_sty_par` parameter. It can be set useing following command line call, for example: + + make4ht -f odt+odttemplate filename.tex "odttemplate=template.odt" + + # Configuration file {#configfile} diff --git a/Master/texmf-dist/doc/support/make4ht/changelog.tex b/Master/texmf-dist/doc/support/make4ht/changelog.tex index ec2c521110f..1467115b2c5 100644 --- a/Master/texmf-dist/doc/support/make4ht/changelog.tex +++ b/Master/texmf-dist/doc/support/make4ht/changelog.tex @@ -3,6 +3,143 @@ \begin{itemize} \item + 2019/01/10 + + \begin{itemize} + \tightlist + \item + version 0.2d released + \end{itemize} +\item + 2019/01/05 + + \begin{itemize} + \tightlist + \item + added \texttt{docbook} and \texttt{tei} output formats. + \end{itemize} +\item + 2018/12/19 + + \begin{itemize} + \tightlist + \item + new library: \texttt{make4ht-xtpipes.lua}. It contains code for + xtpipes handling. + \item + moved Xtpipes handling code from \texttt{formats/odt.lua}. + \end{itemize} +\item + 2018/12/18 + + \begin{itemize} + \tightlist + \item + new filter: \texttt{odttemplate}. It can be used for replacing style + in a generated \texttt{ODT} file by a style from another existing + \texttt{ODT} file. + \item + new extension: \texttt{odttemplate}. Companioning extension for + filter with the same name. + \item + fixed bug in \texttt{make4ht-filters.lua}: the parameters table + haven't been passed to filters. + \end{itemize} +\item + 2018/12/17 + + \begin{itemize} + \tightlist + \item + fixed extension handling. The disabling from the command line didn't + take precedence over extensions enabled in the config file. + Extensions also could be executed multiple times. + \end{itemize} +\item + 2018/11/08 + + \begin{itemize} + \tightlist + \item + removed replacing newlines by blank strings in the + \texttt{joincharacters} domfilter. The issue it fixed doesn't seem + to exist anymore, and it ate spaces sometimes. + \end{itemize} +\item + 2018/11/01 + + \begin{itemize} + \tightlist + \item + added \texttt{t4htlinks} domfilter + \item + fixed the \texttt{xtpipes} and \texttt{filters} execution order in + the \texttt{ODT} format + \end{itemize} +\item + 2018/10/26 + + \begin{itemize} + \tightlist + \item + fixed ODT generation for files that contains special characters for + Lua string patterns + \item + replace non-breaking spaces with entities. It caused issues in LO + \end{itemize} +\item + 2018/10/18 + + \begin{itemize} + \tightlist + \item + fixed the executable installation + \end{itemize} +\item + 2018/09/16 + + \begin{itemize} + \tightlist + \item + added the \texttt{scale} option for \texttt{dvisvgm\_hashes} + extension + \end{itemize} +\item + 2018/09/14 + + \begin{itemize} + \tightlist + \item + require the \texttt{-dvi} option with \texttt{latexmk\_build} + extension + \end{itemize} +\item + 2018/09/12 + + \begin{itemize} + \tightlist + \item + added \texttt{xindy} command for the build file + \end{itemize} +\item + 2018/09/03 + + \begin{itemize} + \tightlist + \item + expanded the \texttt{-\/-help} option + \end{itemize} +\item + 2018/08/27 + + \begin{itemize} + \tightlist + \item + added \texttt{odtimagesize} domfilter + \item + load \texttt{odtimagesize} by default in the ODT format + \end{itemize} +\item 2018/08/23 \begin{itemize} diff --git a/Master/texmf-dist/doc/support/make4ht/make4ht-doc.pdf b/Master/texmf-dist/doc/support/make4ht/make4ht-doc.pdf Binary files differindex d25efb855d9..e05e081ad12 100644 --- a/Master/texmf-dist/doc/support/make4ht/make4ht-doc.pdf +++ b/Master/texmf-dist/doc/support/make4ht/make4ht-doc.pdf diff --git a/Master/texmf-dist/doc/support/make4ht/readme.tex b/Master/texmf-dist/doc/support/make4ht/readme.tex index 20bf33575d1..bb4fa0e7803 100644 --- a/Master/texmf-dist/doc/support/make4ht/readme.tex +++ b/Master/texmf-dist/doc/support/make4ht/readme.tex @@ -21,7 +21,7 @@ commands}{The issues with default tex4ht conversion commands}}\label{the-issues- invoked using several commands. These commands invoke LaTeX~or Plain TeX with special instructions to load \texttt{tex4ht.sty} package. The \TeX~run produces special \texttt{DVI} file which contains the code for -desired output format. The \texttt{DVI} file is then processed and +desired output format. Produced \texttt{DVI} file is then processed and desired output files are created. The basic command provided by \texttt{tex4ht} is named \texttt{htlatex}. @@ -130,6 +130,10 @@ Supported formats are: \texttt{html5} \item \texttt{odt} +\item + \texttt{tei} +\item + \texttt{docbook} \end{itemize} The \texttt{-\/-format} option can be also used for extension loading. @@ -161,13 +165,15 @@ multiple processor cores and generates only changed images. \item[common\_filters] clean the output HTML files using filters. \item[common\_domfilters] -Clean the HTML file using DOM filters. It is more powerful than +clean the HTML file using DOM filters. It is more powerful than \texttt{common\_filters}. Used DOM filters are \texttt{fixinlines}, \texttt{idcolons} and \texttt{joincharacters}. \item[mathjaxnode] use \href{https://github.com/pkra/mathjax-node-page/}{mathjax-node-page} to convert from MathML code to HTML + CSS or SVG. See \protect\hyperlink{mathjaxsettings}{the available settings}. +\item[odttemplate] +automatically load the \texttt{odttemplate} filter. \item[staticsite] build the document in form suitable for static site generators like \href{https://jekyllrb.com/}{Jekyll}. @@ -395,8 +401,13 @@ internal links, which results in validation error. use \href{https://github.com/pkra/mathjax-node-page/}{mathjax-node-page} to convert from MathML code to HTML + CSS or SVG. See \protect\hyperlink{mathjaxsettings}{the available settings}. +\item[odttemplate] +use styles from another \texttt{ODT} file serving as a template in the +current document. It works for the \texttt{styles.xml} file in the +\texttt{ODT} file. During the compilation, this file is named as +\texttt{\textbackslash{}jobname.4oy}. \item[staticsite] -create HTML file in format suitable for static site generators such as +create HTML files in format suitable for static site generators such as \href{https://jekyllrb.com/}{Jekyll} \item[svg-height] some SVG images produced by \texttt{dvisvgm} seem to have wrong @@ -452,6 +463,11 @@ replace the colon (\texttt{:}) character in internal links and \item[joincharacters] join consecutive \texttt{\textless{}span\textgreater{}} or \texttt{\textless{}mn\textgreater{}} elements. +\item[odtimagesize] +set correct dimensions for images in the ODT format. It is loaded by +default for the ODT output. +\item[t4htlinks] +fix hyperlinks in the ODT format. \end{description} \hypertarget{make4ht-aeneas-config-package}{% @@ -538,12 +554,12 @@ as \texttt{{[}"filename.html"{]}}, because of Lua syntax rules. This example maps audio file \texttt{sample.mp3} to a section subpage. The main HTML file, which may contain title and table of contents -doesn't have an corresponding audio file. +doesn't have a corresponding audio file. -The filenames of sub files corresponds to chapter numbers, so they are -not stable when a new chapter is added. It is possible to request file -names interfered from the chapter titles using the \texttt{sec-filename} -option or \texttt{tex4ht}. +Filenames of the sub files corresponds to the chapter numbers, so they +are not stable when a new chapter is added. It is possible to request +file names interfered from the chapter titles using the +\texttt{sec-filename} option or \texttt{tex4ht}. Available \texttt{map} options: @@ -881,8 +897,27 @@ detect the available cores automatically by default. number of pages used in each Dvisvgm call. The extension detects changed pages in the DVI file and construct multiple calls to Dvisvgm with only changed pages. +\item[scale] +SVG scaling. +\end{description} + +\hypertarget{the-odttemplate-filter-and-extension}{% +\subsubsection{\texorpdfstring{The \texttt{odttemplate} filter and +extension}{The odttemplate filter and extension}}\label{the-odttemplate-filter-and-extension}} + +\begin{description} +\item[template] +filename of the template \texttt{ODT} file \end{description} +\texttt{odttemplate} can also get the template filename from the +\texttt{odttemplate} option from \texttt{tex4ht\_sty\_par} parameter. It +can be set useing following command line call, for example: + +\begin{verbatim} + make4ht -f odt+odttemplate filename.tex "odttemplate=template.odt" +\end{verbatim} + \hypertarget{configfile}{% \section{Configuration file}\label{configfile}} diff --git a/Master/texmf-dist/scripts/make4ht/domfilters/make4ht-joincharacters.lua b/Master/texmf-dist/scripts/make4ht/domfilters/make4ht-joincharacters.lua index 8116a970da0..99d3058d7dd 100644 --- a/Master/texmf-dist/scripts/make4ht/domfilters/make4ht-joincharacters.lua +++ b/Master/texmf-dist/scripts/make4ht/domfilters/make4ht-joincharacters.lua @@ -27,9 +27,9 @@ local function join_characters(obj,par) return next_el -- if the next node is space followed by a matching element, we should add this space elseif next_el and next_el:is_text() and get_next(next_el, class) then - local text = next_el._text + local text = next_el._text -- match only text containing just whitespace - if text:match("^%s+$") then return next_el end + if text:match("^%s+$") then return next_el end end end -- loop over all elements and test if the current element is in a list of @@ -51,8 +51,6 @@ local function join_characters(obj,par) -- add the whitespace elseif next_el:is_text() then local s = next_el._text - -- this is needed to fix newlines inserted by Tidy - s = s:gsub("\n", "") -- we must create a new node el:add_child_node(el:create_text_node(s)) next_el:remove_node() diff --git a/Master/texmf-dist/scripts/make4ht/domfilters/make4ht-odtimagesize.lua b/Master/texmf-dist/scripts/make4ht/domfilters/make4ht-odtimagesize.lua new file mode 100644 index 00000000000..92ce68dee4c --- /dev/null +++ b/Master/texmf-dist/scripts/make4ht/domfilters/make4ht-odtimagesize.lua @@ -0,0 +1,16 @@ +-- set correct dimensions to frames around images +return function(dom) + local frames = dom:query_selector("draw|frame") + for _, frame in ipairs(frames) do + local images = frame:query_selector("draw|image") + if #images > 0 then + local image = images[1] + local width = image:get_attribute("svg:width") + local height = image:get_attribute("svg:height") + frame:set_attribute("svg:width", width) + frame:set_attribute("svg:height", height) + print("image dimensions", width, height) + end + end + return dom +end diff --git a/Master/texmf-dist/scripts/make4ht/domfilters/make4ht-t4htlinks.lua b/Master/texmf-dist/scripts/make4ht/domfilters/make4ht-t4htlinks.lua new file mode 100644 index 00000000000..9a4efb97395 --- /dev/null +++ b/Master/texmf-dist/scripts/make4ht/domfilters/make4ht-t4htlinks.lua @@ -0,0 +1,27 @@ +-- This filter is used by the ODT output format to fix links +return function(dom) + for _, link in ipairs(dom:query_selector("t4htlink")) do + local name = link:get_attribute("name") + local href = link:get_attribute("href") + local children = link:get_children() + -- print("link", name, href, #link._children, link:get_text()) + -- add a link if it contains any subnodes and has href attribute + if #children > 0 and href then + link._name = "text:a" + link._attr = {["xlink:type"]="simple", ["xlink:href"]=href} + -- if the link is named, add a bookmark + if name then + local bookmark = link:create_element("text:bookmark", {["text:name"] = name}) + link:add_child_node(bookmark) + end + -- add bookmark if element has name + elseif name then + link._name = "text:bookmark" + link._attr = {["text:name"] = name} + else + -- just remove the link in other cases + link:remove_node() + end + end + return dom +end diff --git a/Master/texmf-dist/scripts/make4ht/extensions/dvisvgm_hashes.lua b/Master/texmf-dist/scripts/make4ht/extensions/dvisvgm_hashes.lua index ac25e10cf5d..aae3e4bba96 100644 --- a/Master/texmf-dist/scripts/make4ht/extensions/dvisvgm_hashes.lua +++ b/Master/texmf-dist/scripts/make4ht/extensions/dvisvgm_hashes.lua @@ -3,10 +3,12 @@ local mkutils = require "mkutils" local filter = require "make4ht-filter" +local dvisvgm_par = {} + local M = {} -- mapping between tex4ht image names and hashed image names local output_map = {} -local dvisvgm_options = "-n --exact -c 1.15,1.15" +local dvisvgm_options = "-n --exact -c ${scale},${scale}" local parallel_size = 64 -- local parallel_size = 3 @@ -165,6 +167,8 @@ local function get_dvi_pages(arg) dvisvgm_options = arg.options or extoptions.options or dvisvgm_options parallel_size = arg.parallel_size or extoptions.parallel_size or parallel_size cpu_cnt = arg.cpu_cnt or extoptions.cpu_cnt or cpu_cnt + dvisvgm_par.scale = arg.scale or extoptions.scale or 1.15 + dvisvgm_options = dvisvgm_options % dvisvgm_par local f = io.open(idv_file, "r") if not f then return nil, "Cannot open idv file: " .. idv_file end local content = f:read("*all") diff --git a/Master/texmf-dist/scripts/make4ht/extensions/odttemplate.lua b/Master/texmf-dist/scripts/make4ht/extensions/odttemplate.lua new file mode 100644 index 00000000000..3b0af2a6999 --- /dev/null +++ b/Master/texmf-dist/scripts/make4ht/extensions/odttemplate.lua @@ -0,0 +1,16 @@ +local M = {} + +local filter = require "make4ht-filter" + +-- this extension only works for the ODT format +M.test = function(format) + return format=="odt" +end + +M.modify_build = function(make) + local process = filter {"odttemplate"} + make:match("4oy$", process) + return make +end + +return M diff --git a/Master/texmf-dist/scripts/make4ht/filters/make4ht-entities-to-unicode.lua b/Master/texmf-dist/scripts/make4ht/filters/make4ht-entities-to-unicode.lua index f93e776717f..fb921a631a3 100644 --- a/Master/texmf-dist/scripts/make4ht/filters/make4ht-entities-to-unicode.lua +++ b/Master/texmf-dist/scripts/make4ht/filters/make4ht-entities-to-unicode.lua @@ -1,13 +1,15 @@ -- convert Unicode characters encoded as XML entities back to Unicode --- list of disabled characters -local disabled = { ["&"] = "&", ["<"] = "<", [">"] = ">" } local utfchar = unicode.utf8.char +-- list of disabled characters +local disabled = { ["&"] = "&", ["<"] = "<", [">"] = ">"} return function(content) - return content:gsub("%&%#x([A-Fa-f0-9]+);", function(entity) + local content = content:gsub("%&%#x([A-Fa-f0-9]+);", function(entity) -- convert hexadecimal entity to Unicode local newchar = utfchar(tonumber(entity, 16)) -- we don't want to break XML validity with forbidden characters return disabled[newchar] or newchar end) + -- the non-breaking space character cause issues in the ODT opening + return content:gsub(string.char(160), " ") end diff --git a/Master/texmf-dist/scripts/make4ht/filters/make4ht-filter.lua b/Master/texmf-dist/scripts/make4ht/filters/make4ht-filter.lua index bef44f585b5..41804aea39d 100644 --- a/Master/texmf-dist/scripts/make4ht/filters/make4ht-filter.lua +++ b/Master/texmf-dist/scripts/make4ht/filters/make4ht-filter.lua @@ -4,9 +4,9 @@ local function load_filter(filtername) return require("filters.make4ht-"..filtername) end -function filter(filters,parameters) +function filter(filters) local sequence = filter_lib.load_filters(filters, load_filter) - return function(filename) + return function(filename, parameters) if not filename then return false, "filters: no filename" end local input = filter_lib.load_input_file(filename) if not input then return nil, "Cannot load the input file" end diff --git a/Master/texmf-dist/scripts/make4ht/filters/make4ht-odttemplate.lua b/Master/texmf-dist/scripts/make4ht/filters/make4ht-odttemplate.lua new file mode 100644 index 00000000000..cadcbfcd478 --- /dev/null +++ b/Master/texmf-dist/scripts/make4ht/filters/make4ht-odttemplate.lua @@ -0,0 +1,30 @@ +local mkutils = require "mkutils" +local zip = require "zip" + + +local function get_template_filename(settings) + -- either get the template odt filename from tex4ht.sty options (make4ht filename.tex "odttemplate=test.odt") + local tex4ht_settings = settings.tex4ht_sty_par + local templatefile = tex4ht_settings:match("odttemplate=([^%,]+)") + if templatefile then return templatefile end + -- read the template odt filename from settings + local filtersettings = get_filter_settings "odttemplate" + return settings.template or filtersettings.template +end + +return function(content, settings) + -- use settings added from the Make:match, or default settings saved in Make object + local templatefile = get_template_filename(settings) + -- don't do anything if the template file doesn't exist + if not templatefile or not mkutils.file_exists(templatefile) then return content end + local odtfile = zip.open(templatefile) + if odtfile then + local stylesfile = odtfile:open("styles.xml") + -- just break if the styles cannot be found + if not stylesfile then return content end + local styles = stylesfile:read("*all") + return styles + end + -- just return content in the case of problems + return content +end diff --git a/Master/texmf-dist/scripts/make4ht/formats/docbook.lua b/Master/texmf-dist/scripts/make4ht/formats/docbook.lua new file mode 100644 index 00000000000..9e5ffe9488b --- /dev/null +++ b/Master/texmf-dist/scripts/make4ht/formats/docbook.lua @@ -0,0 +1,38 @@ +local M = {} +local mkutils = require "mkutils" +local lfs = require "lfs" +local os = require "os" +local kpse = require "kpse" +local filter = require "make4ht-filter" +local domfilter = require "make4ht-domfilter" +local xtpipeslib = require "make4ht-xtpipes" + +function M.prepare_parameters(settings, extensions) + settings.tex4ht_sty_par = settings.tex4ht_sty_par ..",docbook" + settings = mkutils.extensions_prepare_parameters(extensions, settings) + return settings +end + +local move_matches = xtpipeslib.move_matches + +-- call xtpipes from Lua +local function call_xtpipes(make) + -- we must find root of the TeX distribution + local selfautoparent = xtpipeslib.get_selfautoparent() + + if selfautoparent then + local matchfunction = xtpipeslib.get_xtpipes(selfautoparent) + make:match("xml$", matchfunction) + move_matches(make) + else + print "Cannot locate xtpipes. Try to set TEXMFROOT variable to a root directory of your TeX distribution" + end +end + +function M.modify_build(make) + -- use xtpipes to fix some common docbook issues + call_xtpipes(make) + return make +end + +return M diff --git a/Master/texmf-dist/scripts/make4ht/formats/odt.lua b/Master/texmf-dist/scripts/make4ht/formats/odt.lua index d5a6b0c9ba5..453c46aff5e 100644 --- a/Master/texmf-dist/scripts/make4ht/formats/odt.lua +++ b/Master/texmf-dist/scripts/make4ht/formats/odt.lua @@ -4,6 +4,8 @@ local lfs = require "lfs" local os = require "os" local kpse = require "kpse" local filter = require "make4ht-filter" +local domfilter = require "make4ht-domfilter" +local xtpipeslib = require "make4ht-xtpipes" function M.prepare_parameters(settings, extensions) @@ -75,82 +77,27 @@ function Odtfile:pack() mkutils.delete_dir(self.archivelocation) end --- find if tex4ht.jar exists in a path -local function find_tex4ht_jar(path) - local jar_file = path .. "/tex4ht/bin/tex4ht.jar" - return mkutils.file_exists(jar_file) +-- escape string to be used in the gsub search +local function escape_file(filename) + local quotepattern = '(['..("%^$().[]*+-?"):gsub("(.)", "%%%1")..'])' + return filename:gsub(quotepattern, "%%%1") end --- return value of TEXMFROOT variable if it exists and if tex4ht.jar can be located inside -local function get_texmfroot() - -- user can set TEXMFROOT environmental variable as the last resort - local root_directories = {kpse.var_value("TEXMFROOT"), kpse.var_value("TEXMFDIST"), os.getenv("TEXMFROOT")} - for _, root in ipairs(root_directories) do - if root then - if find_tex4ht_jar(root) then return root end - -- TeX live locates files in texmf-dist subdirectory, but Miktex doesn't - local path = root .. "/texmf-dist" - if find_tex4ht_jar(path) then return path end - end - end -end - --- Miktex doesn't seem to set TeX variables such as TEXMFROOT --- we will try to find the TeX root using trick with locating package in TeX root --- there is a danger that this file is located in TEXMFHOME, the location will fail then -local function find_texmfroot() - local tex4ht_path = kpse.find_file("tex4ht.sty") - if tex4ht_path then - local path = tex4ht_path:gsub("/tex/generic/tex4ht/tex4ht.sty$","") - if find_tex4ht_jar(path) then return path end - end - return nil -end +local move_matches = xtpipeslib.move_matches -- call xtpipes from Lua local function call_xtpipes(make) -- we must find root of the TeX distribution - local selfautoparent = get_texmfroot() or find_texmfroot() + local selfautoparent = xtpipeslib.get_selfautoparent() + if selfautoparent then - -- make pattern using TeX distro path - local pattern = string.format("java -classpath %s/tex4ht/bin/tex4ht.jar xtpipes -i %s/tex4ht/xtpipes/ -o ${outputfile} ${filename}", selfautoparent, selfautoparent) - -- call xtpipes on a temporary file - local matchfunction = function(filename) - -- move the matched file to a temporary file, xtpipes will write it back to the original file - local basename = mkutils.remove_extension(filename) - local tmpfile = basename ..".tmp" - mkutils.mv(filename, tmpfile) - local command = pattern % {filename = tmpfile, outputfile = filename} - print(command) - local status = os.execute(command) - if status > 0 then - -- if xtpipes failed to process the file, it may mean that it was bad-formed xml - -- we can try to make it well-formed using Tidy - local tidy_command = "tidy -utf8 -xml -asxml -q -o ${filename} ${tmpfile}" % {tmpfile = tmpfile, filename = filename} - print("xtpipes failed trying tidy") - print(tidy_command) - local status = os.execute(tidy_command) - if status > 0 then - -- if tidy failed as well, just use the original file - -- it will probably produce corrupted ODT file though - print("Tidy failed as well") - mkutils.mv(tmpfile, filename) - end - end - end + local matchfunction = xtpipeslib.get_xtpipes(selfautoparent) make:match("4oo", matchfunction) make:match("4om", matchfunction) - -- is is necessary to execute the above matches as first in the build file - local matches = make.matches -- move last match to a first place - local function move_matches() - local last = matches[#matches] - table.insert(matches, 1, last) - matches[#matches] = nil - end -- we need to move last two matches, for 4oo and 4om files - move_matches() - move_matches() + move_matches(make) + move_matches(make) else print "Cannot locate xtpipes. Try to set TEXMFROOT variable to a root directory of your TeX distribution" end @@ -182,10 +129,19 @@ function M.modify_build(make) -- execute xtpipes from the build file, instead of t4ht. this fixes issues with wrong paths -- expanded in tex4ht.env in Miktex or Debian call_xtpipes(make) - -- convert XML entities for Unicoe characters produced by Xtpipes to characters + -- fix the image dimensions wrongly set by xtpipes + local domfilters = domfilter {"t4htlinks","odtimagesize"} + make:match("4oo$", domfilters) + -- execute it before xtpipes, because we don't want xtpipes to mess with t4htlink elements + move_matches(make) + -- convert XML entities for Unicode characters produced by Xtpipes to characters local fixentities = filter {"entities-to-unicode"} make:match("4oo", fixentities) make:match("4om", fixentities) + -- execute fixentities as first + move_matches(make) + move_matches(make) + -- build the ODT file. This match must be executed as a last one -- this will be executed as a first match, just to find the last filename -- in the lgfile @@ -194,8 +150,9 @@ function M.modify_build(make) if not executed then -- this is list of processed files local lgfiles = make.lgfile.files - -- find the last one - local lastfile = lgfiles[#lgfiles] .."$" + -- find the last file and escape it so it can be used + -- in filename match + local lastfile = escape_file(lgfiles[#lgfiles]) .."$" -- make match for the last file -- odt packing will be done here make:match(lastfile, function() diff --git a/Master/texmf-dist/scripts/make4ht/formats/tei.lua b/Master/texmf-dist/scripts/make4ht/formats/tei.lua new file mode 100644 index 00000000000..f81953a8b31 --- /dev/null +++ b/Master/texmf-dist/scripts/make4ht/formats/tei.lua @@ -0,0 +1,14 @@ +local M = {} +local xtpipeslib = require "make4ht-xtpipes" + +function M.prepare_parameters(settings, extensions) + settings.tex4ht_sty_par = settings.tex4ht_sty_par ..",tei" + settings = mkutils.extensions_prepare_parameters(extensions, settings) + return settings +end + +function M.prepare_extensions(extensions) + return extensions +end + +return M diff --git a/Master/texmf-dist/scripts/make4ht/make4ht b/Master/texmf-dist/scripts/make4ht/make4ht index c72fe69ece2..1d558e59579 100755 --- a/Master/texmf-dist/scripts/make4ht/make4ht +++ b/Master/texmf-dist/scripts/make4ht/make4ht @@ -27,7 +27,7 @@ make4ht [options] filename ["tex4ht.sty op." "tex4ht op." "t4ht op" "latex op"] -- set version number. the template should be replaced by the -- actual version number by the build script -local version = "v0.2c" +local version = "v0.2d" mkparams.version_number = version local args = mkparams.get_args() @@ -38,7 +38,7 @@ local mode = parameters.mode local build_file = parameters.build_file -- handle output formats -local allowed_output_formats = {xhtml = true, html5=true, odt = true} +local allowed_output_formats = {xhtml = true, html5=true, odt = true, docbook=true, tei=true} -- formatter is Lua library which must provide at least prepare_parameters -- and process_build_sequence functions local formatter diff --git a/Master/texmf-dist/scripts/make4ht/make4ht-xtpipes.lua b/Master/texmf-dist/scripts/make4ht/make4ht-xtpipes.lua new file mode 100755 index 00000000000..78014baff1c --- /dev/null +++ b/Master/texmf-dist/scripts/make4ht/make4ht-xtpipes.lua @@ -0,0 +1,82 @@ +local M = {} + +-- find if tex4ht.jar exists in a path +local function find_tex4ht_jar(path) + local jar_file = path .. "/tex4ht/bin/tex4ht.jar" + return mkutils.file_exists(jar_file) +end + +-- return value of TEXMFROOT variable if it exists and if tex4ht.jar can be located inside +local function get_texmfroot() + -- user can set TEXMFROOT environmental variable as the last resort + local root_directories = {kpse.var_value("TEXMFROOT"), kpse.var_value("TEXMFDIST"), os.getenv("TEXMFROOT")} + for _, root in ipairs(root_directories) do + if root then + if find_tex4ht_jar(root) then return root end + -- TeX live locates files in texmf-dist subdirectory, but Miktex doesn't + local path = root .. "/texmf-dist" + if find_tex4ht_jar(path) then return path end + end + end +end + +-- Miktex doesn't seem to set TeX variables such as TEXMFROOT +-- we will try to find the TeX root using trick with locating package in TeX root +-- there is a danger that this file is located in TEXMFHOME, the location will fail then +local function find_texmfroot() + local tex4ht_path = kpse.find_file("tex4ht.sty") + if tex4ht_path then + local path = tex4ht_path:gsub("/tex/generic/tex4ht/tex4ht.sty$","") + if find_tex4ht_jar(path) then return path end + end + return nil +end + +function M.get_selfautoparent() + return get_texmfroot() or find_texmfroot() +end + +function M.get_xtpipes(selfautoparent) + -- make pattern using TeX distro path + local pattern = string.format("java -classpath %s/tex4ht/bin/tex4ht.jar xtpipes -i %s/tex4ht/xtpipes/ -o ${outputfile} ${filename}", selfautoparent, selfautoparent) + -- call xtpipes on a temporary file + local matchfunction = function(filename) + -- move the matched file to a temporary file, xtpipes will write it back to the original file + local basename = mkutils.remove_extension(filename) + local tmpfile = basename ..".tmp" + mkutils.mv(filename, tmpfile) + local command = pattern % {filename = tmpfile, outputfile = filename} + print(command) + local status = os.execute(command) + if status > 0 then + -- if xtpipes failed to process the file, it may mean that it was bad-formed xml + -- we can try to make it well-formed using Tidy + local tidy_command = "tidy -utf8 -xml -asxml -q -o ${filename} ${tmpfile}" % {tmpfile = tmpfile, filename = filename} + print("xtpipes failed trying tidy") + print(tidy_command) + local status = os.execute(tidy_command) + if status > 0 then + -- if tidy failed as well, just use the original file + -- it will probably produce corrupted ODT file though + print("Tidy failed as well") + mkutils.mv(tmpfile, filename) + end + end + end + return matchfunction +end + +-- This function moves the last added file matching function to the first place +-- in the execution order. This ensures that filters are executed in the +-- correct order. +function M.move_matches(make) + local matches = make.matches + local last = matches[#matches] + table.insert(matches, 1, last) + matches[#matches] = nil +end + +M.get_texmfroot = get_texmfroot +M.find_texmfroot = find_texmfroot +M.find_tex4ht_jar = find_tex4ht_jar +return M diff --git a/Master/texmf-dist/scripts/make4ht/mkparams.lua b/Master/texmf-dist/scripts/make4ht/mkparams.lua index 6f293c8862e..4db967f2706 100755 --- a/Master/texmf-dist/scripts/make4ht/mkparams.lua +++ b/Master/texmf-dist/scripts/make4ht/mkparams.lua @@ -11,21 +11,23 @@ m.version_number = "v0.1" m.optiontext = [[ ${progname} - build system for tex4ht Usage: -${progname} [options] filename ["tex4ht.sty op." "tex4ht op." "t4ht op" "latex op"] --b,--backend (default tex4ht) Backend used for xml generation. - possible values: tex4ht or lua4ht --c,--config (default xhtml) Custom config file --d,--output-dir (default nil) Output directory --e,--build-file (default nil) If build file is different than `filename`.mk4 --f,--format (default html5) Output file format --h,-- help Display this message --l,--lua Use lualatex for document compilation --m,--mode (default default) Switch which can be used in the makefile --n,--no-tex4ht Disable dvi file processing with tex4ht command --s,--shell-escape Enables running external programs from LaTeX --u,--utf8 For output documents in utf8 encoding --x,--xetex Use xelatex for document compilation --v,--version Display version number +${progname} [options] filename ["tex4ht.sty op."] ["tex4ht op."] ["t4ht op"] ["latex op"] + +Available options: + -b,--backend (default tex4ht) Backend used for xml generation. + possible values: tex4ht or lua4ht + -c,--config (default xhtml) Custom config file + -d,--output-dir (default nil) Output directory + -e,--build-file (default nil) If build file is different than `filename`.mk4 + -f,--format (default html5) Output file format + -h,-- help Display this message + -l,--lua Use lualatex for document compilation + -m,--mode (default default) Switch which can be used in the makefile + -n,--no-tex4ht Disable dvi file processing with tex4ht command + -s,--shell-escape Enables running external programs from LaTeX + -u,--utf8 For output documents in utf8 encoding + -x,--xetex Use xelatex for document compilation + -v,--version Display version number ]] -- test if the current command line argument should be passed to tex4ht, t4ht or latex @@ -42,7 +44,18 @@ local function get_args(parameters, optiontext) parameters.postparams = parameters.postparams or "" local optiontext = optiontext or m.optiontext parameters.postfile = parameters.postfile or "" - optiontext = optiontext .. parameters.postparams .."<filename> (string) Input file name\n" .. parameters.postfile + optiontext = optiontext .. parameters.postparams ..[[ <filename> (string) Input file name + +Positional optional argumens: + ["tex4ht.sty op."] Additional parameters for tex4ht.sty + ["tex4ht op."] Options for tex4ht command + ["t4ht op"] Options for t4ht command + ["latex op"] Additional options for LaTeX + +Documentation: https://tug.org/applications/tex4ht/mn.html +Issue tracker for tex4ht bugs: https://puszcza.gnu.org.ua/bugs/?group=tex4ht +Issue tracker for make4ht bugs: https://github.com/michal-h21/make4ht/issues + ]] .. parameters.postfile -- we can pass arguments for tex4ht and t4ht after filename, but it will confuse lapp, thinking that these -- options are for make4ht. this may result in execution error or wrong option parsing -- as fix, add a space before options at the end (we need to stop to add spaces as soon as we find diff --git a/Master/texmf-dist/scripts/make4ht/mkutils.lua b/Master/texmf-dist/scripts/make4ht/mkutils.lua index 63924eeb50e..fd32c91e087 100755 --- a/Master/texmf-dist/scripts/make4ht/mkutils.lua +++ b/Master/texmf-dist/scripts/make4ht/mkutils.lua @@ -372,7 +372,7 @@ env.Make:add("latexmk", function(par) par.expanded = command % par -- quotes in latex_command must be escaped, they cause Latexmk error par.expanded = par.expanded:gsub('"', '\\"') - local newcommand = 'latexmk -latex="${expanded}" ${tex_file}' % par + local newcommand = 'latexmk -latex="${expanded}" -dvi ${tex_file}' % par os.execute(newcommand) return Make.testlogfile(par) end, {correct_exit= 0}) @@ -396,6 +396,10 @@ end function load_config(settings, config_name) local settings = settings or main_settings + -- the extensions requested from the command line should take precedence over + -- extensions enabled in the config file + local saved_extensions = settings.extensions + settings.extensions = {} env.settings = settings env.mode = settings.mode if config_name and not file_exists(config_name) then @@ -411,9 +415,28 @@ function load_config(settings, config_name) local fn, msg = run(code,env) if not fn then print(msg) end assert(fn) + -- reload extensions from command line arguments for the "format" parameter + for _,v in ipairs(saved_extensions) do + table.insert(settings.extensions, v) + end return env end +env.Make:add("xindy", function(par) + -- par.encoding = par.encoding or "utf8" + -- par.language = par.language or "english" + par.idxfile = par.idxfile or par.input .. ".idx" + local modules = par.modules or {par.input} + local t = {} + for k,v in ipairs(modules) do + t[#t+1] = "-M ".. v + end + par.moduleopt = table.concat(t, " ") + local xindy_call = "xindy -L ${language} -C ${encoding} ${moduleopt} ${idxfile}" % par + print(xindy_call) + return os.execute(xindy_call) +end, { language = "english", encoding = "utf8"}) + local function find_lua_file(name) local extension_path = name:gsub("%.", "/") .. ".lua" return kpse.find_file(extension_path, "lua") @@ -495,19 +518,25 @@ function load_extensions(extensions, format) -- diable the extension for _, v in ipairs(extensions) do local enable = v.type == "+" and true or nil + -- load extenisons in a correct order -- don't load extensions multiple times - if not module_names[v.name] then - module_names[v.name] = enable - -- load extenisons in a correct order + if enable and not module_names[v.name] then table.insert(extension_sequence, v.name) end + -- the last extension request can disable it + module_names[v.name] = enable end for _, name in ipairs(extension_sequence) do - local extension = load_extension(name,format) - if extension then - table.insert(extension_table, extension) - else - print("Cannot load extension: ".. name) + -- the extension can be inserted into the extension_sequence, but disabled + -- later. + if module_names[name] == true then + local extension = load_extension(name,format) + if extension then + print("Load extension", name) + table.insert(extension_table, extension) + else + print("Cannot load extension: ".. name) + end end end return extension_table |