texlive[47398] trunk: make4ht (9apr18)

commits+karl at tug.org commits+karl at tug.org
Mon Apr 9 23:09:52 CEST 2018


Revision: 47398
          http://tug.org/svn/texlive?view=revision&revision=47398
Author:   karl
Date:     2018-04-09 23:09:51 +0200 (Mon, 09 Apr 2018)
Log Message:
-----------
make4ht (9apr18)

Modified Paths:
--------------
    trunk/Build/source/texk/texlive/linked_scripts/make4ht/make4ht
    trunk/Master/texmf-dist/doc/support/make4ht/README
    trunk/Master/texmf-dist/doc/support/make4ht/changelog.tex
    trunk/Master/texmf-dist/doc/support/make4ht/make4ht-doc.pdf
    trunk/Master/texmf-dist/doc/support/make4ht/make4ht-doc.tex
    trunk/Master/texmf-dist/doc/support/make4ht/readme.tex
    trunk/Master/texmf-dist/scripts/make4ht/filters/make4ht-filter.lua
    trunk/Master/texmf-dist/scripts/make4ht/make4ht
    trunk/Master/texmf-dist/scripts/make4ht/mkparams.lua
    trunk/Master/texmf-dist/scripts/make4ht/mkutils.lua

Added Paths:
-----------
    trunk/Master/texmf-dist/doc/support/make4ht/extensions/
    trunk/Master/texmf-dist/doc/support/make4ht/extensions/common_domfilters.lua
    trunk/Master/texmf-dist/doc/support/make4ht/extensions/common_filters.lua
    trunk/Master/texmf-dist/doc/support/make4ht/extensions/latexmk.lua
    trunk/Master/texmf-dist/doc/support/make4ht/extensions/mathjaxnode.lua
    trunk/Master/texmf-dist/doc/support/make4ht/extensions/tidy.lua
    trunk/Master/texmf-dist/doc/support/make4ht/formats/
    trunk/Master/texmf-dist/doc/support/make4ht/formats/html5.lua
    trunk/Master/texmf-dist/doc/support/make4ht/formats/odt.lua
    trunk/Master/texmf-dist/doc/support/make4ht/formats/xhtml.lua
    trunk/Master/texmf-dist/scripts/make4ht/domfilters/
    trunk/Master/texmf-dist/scripts/make4ht/domfilters/make4ht-aeneas.lua
    trunk/Master/texmf-dist/scripts/make4ht/domfilters/make4ht-fixinlines.lua
    trunk/Master/texmf-dist/scripts/make4ht/domfilters/make4ht-idcolons.lua
    trunk/Master/texmf-dist/scripts/make4ht/domfilters/make4ht-joincharacters.lua
    trunk/Master/texmf-dist/scripts/make4ht/filters/make4ht-domfilter.lua
    trunk/Master/texmf-dist/scripts/make4ht/filters/make4ht-mathjaxnode.lua
    trunk/Master/texmf-dist/scripts/make4ht/filters/make4ht-svg-height.lua
    trunk/Master/texmf-dist/scripts/make4ht/make4ht-aeneas-config.lua
    trunk/Master/texmf-dist/scripts/make4ht/make4ht-config.lua
    trunk/Master/texmf-dist/scripts/make4ht/make4ht-filterlib.lua

Removed Paths:
-------------
    trunk/Master/texmf-dist/scripts/make4ht/make4ht-dom.lua

Modified: trunk/Build/source/texk/texlive/linked_scripts/make4ht/make4ht
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/make4ht/make4ht	2018-04-09 21:09:18 UTC (rev 47397)
+++ trunk/Build/source/texk/texlive/linked_scripts/make4ht/make4ht	2018-04-09 21:09:51 UTC (rev 47398)
@@ -9,6 +9,7 @@
 local lapp    = require("lapp-mk4")
 local mkutils = require("mkutils")
 local mkparams = require("mkparams")
+local mk_config = require("make4ht-config")
 -- args string is here just as sample, we dont pass it it to 
 -- mkparams.get_args() so default args string is used
 local args    =  [[
@@ -26,7 +27,7 @@
 
 -- set version number. the template should be replaced by the
 -- actual version number by the build script
-local version = "v0.1c"
+local version = "v0.2"
 mkparams.version_number = version
 
 local args = mkparams.get_args()
@@ -36,6 +37,35 @@
 local mode = parameters.mode
 local build_file = parameters.build_file 
 
+-- handle output formats
+local allowed_output_formats = {xhtml = true, html5=true, odt = true}
+-- formatter is Lua library which must provide at least prepare_parameters
+-- and process_build_sequence functions
+local formatter
+local output_format = parameters.output_format
+if allowed_output_formats[ output_format ] then
+  formatter = mkutils.load_output_format(output_format)
+else
+  -- load html5 as default output format
+  if output_format then 
+    print("Cannot load output format: ".. output_format)
+  end
+  formatter = mkutils.load_output_format("html5")
+end
+-- find make4ht configuration file
+local configname = "make4ht"
+local conffile = mk_config.find_config(configname) or mk_config.find_xdg_config(configname)
+if conffile then
+  print("Using configuration file: " .. conffile)
+  mkutils.load_config(parameters, conffile)
+end
+local extensions = formatter.prepare_extensions(parameters.extensions)
+extensions = mkutils.load_extensions(extensions, output_format)
+
+
+
+-- run extensions with prepare_parameters function
+parameters = formatter.prepare_parameters(parameters,extensions)
 local make = mkutils.load_config(parameters, build_file)["Make"]
 make.params = parameters
 if make:length() < 1 then
@@ -58,6 +88,10 @@
   make.params.t4ht_par = make.params.t4ht_par .. " -p"
 end
 make:t4ht {ext = ext}
+-- run extensions which modify the build sequence
+if #extensions > 0 then
+  make = mkutils.extensions_modify_build(extensions, make)
+end
 make:match("tmp$", function() return false,"tmp file" end)
 make:match(".*",function(filename,par)
 	local outdir =  '' --par["outdir"] and par["outdir"] .."/" or ''
@@ -67,4 +101,5 @@
 	mkutils.copy(filename,outfilename)
 	return true
 end)
+
 make:run()

Modified: trunk/Master/texmf-dist/doc/support/make4ht/README
===================================================================
--- trunk/Master/texmf-dist/doc/support/make4ht/README	2018-04-09 21:09:18 UTC (rev 47397)
+++ trunk/Master/texmf-dist/doc/support/make4ht/README	2018-04-09 21:09:51 UTC (rev 47398)
@@ -1,175 +1,320 @@
+% [![Build Status](https://travis-ci.org/michal-h21/make4ht.svg?branch=master)](https://travis-ci.org/michal-h21/make4ht)
+
 # Introduction
 
-`make4ht` is a simple build system for tex4ht. It is both executable which
-simplifies `tex4ht` execution and a library which can be used to create
-customized conversion programs. An example of such conversion program is [tex4ebook](https://github.com/michal-h21/tex4ebook)
+`make4ht` is a simple build system for `tex4ht`, \TeX\ to XML converter. It provides a command line tool
+that drive the conversion process. It also provides a library which can be used to create
+customized conversion tools. An example of such conversion tool is
+[tex4ebook](https://github.com/michal-h21/tex4ebook) for conversion of \TeX\ to
+ePub and other e-book formats.
 
-## License
 
-Permission is granted to copy, distribute and/or modify this software
-under the terms of the LaTeX Project Public License, version 1.3.
+## How it works
 
-How it works
-------------
+### The issues with default `tex4ht` conversion commands
 
-Default compilation script for `tex4ht`, named `htlatex`  compiles LaTeX files to `HTML` with this command  sequence:
 
+`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 
+desired output files are created.
+
+The basic command provided by `tex4ht` is named `htlatex`. It  compiles \LaTeX\  
+files to `HTML` with this command sequence:
+
     latex $latex_options 'code for loading tex4ht.sty \input{filename}'
     latex $latex_options 'code for loading tex4ht.sty \input{filename}'
     latex $latex_options 'code for loading tex4ht.sty \input{filename}'
-    tex4ht options filename
-    t4ht options filename
+    tex4ht $tex4ht_options filename
+    t4ht $t4ht_options filename
 
-The problem is that this is inefficient when  you need to run program which
-interact with LaTeX, such as `Makeindex` or `Bibtex`. In that case, you need to
-create new script based on the default one, or run `htlatex` twice, which means
-six LaTeX runs. 
+The options for various parts of the system can be passed on the command line:
 
-Another problem is with `t4ht` application. It reads file `filename.lg`,
-generated by `tex4ht`, where are instructions about generated files, `CSS`
-instructions, calls to external applications, instructions for image
-conversions etc. It can be instructed to copy generated files to some output
-directory, but it doesn't preserve directory structure, so when you
-have images in some subdirectory, they will be copied to the output directory,
-but links will be pointing to non existing subdirectory.
+    htlatex filename "tex4ht.sty options" "tex4ht_options" "t4ht_options" "latex_options"
 
-Image conversion is directed with the 
-[env file](http://www.tug.org/applications/tex4ht/mn35.html#index35-73001), 
-with really strange syntax based on whitespace and 
+For basic `HTML` conversion it is possible to use the most basic invocation:
+
+    htlatex filename.tex
+
+It can be much more involved for `HTML 5` output in `UTF-8` encoding:
+
+    htlatex filename.tex "xhtml,html5,charset=utf-8" "-cmozhtf -utf8"
+
+`make4ht` can simplify it:
+
+    make4ht -uf html5 filename.tex
+
+Another issue is the fixed compilation order and hard-coded number of LaTeX invocations.
+
+When you need to run a program which interact with LaTeX, such as `Makeindex`
+or `Bibtex`, you need to create a new script based on `htlatex`, or run
+`htlatex` twice, which means that LaTeX will be invoked six times. 
+This can lead to significantly long compilation times. `make4ht` provides build files and
+extensions, which can be used for interaction with external tools.
+
+It is also possible to have several compilation modes. When you just add new text to a document, 
+which doesn't contain cross-references, don't add new stuff to the table of contents, etc., 
+it is possible to use the `draft` mode which will invoke LaTeX only once. It
+can save quite a lot of the compilation time:
+
+    make4ht -um draft -f html5 filename.tex
+
+There are also issues with a behaviour of the `t4ht` application. It reads file
+`filename.lg`, generated by `tex4ht`, where are instructions about generated
+files, `CSS` instructions, calls to external applications, instructions for
+image conversions etc. It can be instructed to copy generated files to some
+output directory, but it doesn't preserve directory structure, so when you
+have images in a subdirectory, they will be copied to the output directory.
+Links will be pointing to a non-existing subdirectory. The following command
+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 
 [os dependent](http://www.tug.org/applications/tex4ht/mn-unix.html#index27-69005).
+`make4ht` provides simpler means for the image conversion in the build files.
+
 With `make4ht` build files, we have simple mean to fix these issues. We can
-change image conversion parameters without need to modify the `env file`,
-and call actions on the output files. These actions can be either external
+change image conversion parameters without the need to modify the `env file`,
+or execute actions on the output files. These actions can be either external
 programs such as `xslt` processors or `HTML tidy` or `Lua` functions.
 
 The idea is to make system controlled by a build file. Because `Lua`
 interpreter is included in modern TeX distributions and `Lua` is ideal language
-for such task, it was chosen as language in which build script are written.
+for such task, it was chosen as language in which the build scripts are written.
 
+# Output file formats and extensions
 
+The default output format used by `make4ht` is `html5`. Different
+format can be requested using the `--format` option. Supported formats are:
+
+ - `xhtml`
+ - `html5`
+ - `odt`
+
+The `--format` option can be also used for extension loading.
+
+## Extensions
+
+Extensions can be used to modify the build process without the need to use a build file. They
+may post-process the output files or request additional commands for the compilation.
+
+The extensions can be enabled or disabled by appending `+EXTENSION` or `-EXTENSION` after
+the output format name:
+
+     make4ht -uf html5+tidy filename.tex
+
+Available extensions:
+
+latexmk
+
+:    use `Latexmk` for \LaTeX\ compilation.
+
+tidy
+
+:    clean the `HTML` files using the `tidy` command.
+
+common\_filters
+
+:    clean the output HTML files using filters.
+
+common\_domfilters
+
+:    Clean the HTML file using DOM filters. It is more powerful than
+`common_filters`. Used DOM filters are `fixinlines`, `idcolons` and
+`joincharacters`.
+
+mathjaxnode
+
+:    use [mathjax-node-page](https://github.com/pkra/mathjax-node-page/) to
+     convert from MathML code to HTML + CSS or SVG. See [the available
+     settings](#mathjaxsettings).
+
 # Build files
 
-## Commands
+`make4ht` supports build files. These are `Lua` scripts which can adjust
+the build process. You can request external applications like `bibtex` or `makeindex`,
+pass options to the commands, modify the image conversion process, or post-process the
+generated files.
 
-By default, build file is saved in file named `filename + .mk4 extension`.
+`make4ht` tries to load default build file named as `filename + .mk4 extension`.
 You can choose different build file with `-e` or `--build-file` command line
 option.
 
-Sample:
+Sample build file:
 
     Make:htlatex()
     Make:match("html$", "tidy -m -xml -utf8 -q -i ${filename}")
 
 `Make:htlatex()` is preconfigured command for calling LaTeX with `tex4ht`
-loaded on the input file. In this case it will be called  one time. After
-compilation, `tidy` command is executed on the output `html` file.
+loaded on the input file. In this case, it will be called  one time. After
+compilation, the `tidy` command is executed on the output `HTML` file.
 
 Note that you don't have to call `tex4ht` and `t4ht` commands explicitly in the
 build file, they are called automatically. 
 
-You can add more commands like `Make:htlatex` with 
+## User commands
 
+You can add more commands like `Make:htlatex` using `Make:add` command:
+
     Make:add("name", "command", {parameters}, repetition)
 
+The `name` and `command` parameters are required, rest of the parameters are optional.
 
-it can be called with
+This defines `name` command, which can be then executed as `Make:name()` command.
 
-    Make:name()
+### Provided commands
 
-`command` can be text template, or function:
+`Make:htlatex`
 
-    Make:add("text", "hello, input file: ${input}")
+:    One call to TeX engine with special configuration for `tex4ht` loading.
+
+`Make:latexmk`
+
+:    Use `Latexmk` for the document compilation. `tex4ht` will be loaded automatically.
+
+`Make:tex4ht`
+
+:    Process the `DVI` file and creates the output files.
+
+`Make:t4ht`
+
+:    Creates the CSS file.
+
+
+### Command function
+
+The `command` parameter can be either string template or function:
+
+    Make:add("text", "echo hello, input file: ${input}")
     Make:add("function", function(params) 
       for k, v in pairs(params) do 
         print(k..": "..v) 
-      end
+      end, {custom="Hello world"}
     )
 
-`parameters` is a table or `nil` value.
+The template can get variable value from the parameters table using a
+`${var_name}` placeholder. Templates are executed using operating system, so
+they should invoke existing OS commands. Function commands may execute system
+commands using `os.execute` function.
 
-Default parameters are:
 
-htlatex 
+### Parameters table
 
+`parameters` parameter is optional, it can be table or `nil` value, which
+should be used if you want to use the `repetition` parameter, but don't want to
+modify the parameters table. 
+
+The table with default parameters is passed to all commands, they can be accessed from command functions
+or templates. When you specify your own parameters in the command definition, these additional
+parameters are added to the default parameters table for this particular
+command. You can override the default parameters in the parameters table.
+
+
+
+The default parameters are following:
+
+`htlatex`
+
 :     used compiler
 
-input 
+`input`
 
 :    it is output file name in fact
 
-tex_file
+`tex_file`
 
 :    input TeX file
 
-latex_par 
+`latex_par`
 
 :    parameters to `latex`
 
-packages
+`packages`
 
-:    insert additionl LaTeX code which is inserted before `\documentclass`.
+:    insert additional LaTeX code which is inserted before `\documentclass`.
      Useful for passing options to packages or additional packages loading
 
-tex4ht_sty_par 
+`tex4ht_sty_par`
 
 :    parameters to `tex4ht.sty`
 
-tex4ht_par 
+`tex4ht_par`
 
-:     parameters to `tex4ht` application
+:     parameters to the `tex4ht` application
 
-t4ht_par 
+`t4ht_par`
 
-:    parameters to `t4ht` application
+:    parameters to the `t4ht` application
 
-outdir 
+`outdir`
 
-:     output directory
+:    the output directory
 
-repetition 
+`repetition`
 
 :    limit number of command execution.
 
-correct_exit 
+`correct_exit`
 
-:    expected `exit code` from the command. The compilation will be terminted
-     when the command `exit code` is different.
+:    expected `exit code` from the command. The compilation will be terminated
+     if the command `exit code` is different.
 
 
-You may add your own parameters, they will be accessible in templates and
-functions.
+### Repetition
 
-With `repetition`, you can limit number of command executions.  Its value
-should be number or `nil`.  This is used in the case of `tex4ht` and `t4ht`
-commands, as they should be executed only once and they would be executed
-multiple times if you include them in the build file, because they would be
-called also by `make4ht`. With `repetition`, second execution is blocked.
+Repetition is number which specifies a maximal number of executions of the
+particular command.  This is used for instance for `tex4ht` and `t4ht`
+commands, as they should be executed only once in the compilation. They would
+be executed multiple times if you include them in the build file because they
+are called by `make4ht` by default. Because these commands allow only one
+`repetition`, the second execution will be blocked.
 
-You can set expected exit code from a command with `correct_exit`. Compilation
-is stopped when command returns different exit code. The situation is 
-different for LaTeX (for all TeX engines and formats, in fact), because it doesn't 
-differentiate between fatal and non fatal errors, and it returns the same exit code
-in all cases. Log parsing is used because of that, error code `1` is returned 
-in the case of fatal error, `0` is used otherwise.
+### Expected exit code
 
+You can set the expected exit code from a command with a `correct_exit` key in the
+parameters table. The compilation will be stopped when the command returns a
+different exit code. 
+
+This mechanism isn't used for LaTeX (for all TeX engines and formats, in
+fact), because it doesn't differentiate between fatal and non-fatal errors, and
+it returns the same exit code in all cases. Log parsing is used because of
+that, error code `1` is returned in the case of fatal error, `0` is used
+otherwise. The `Make.testlogfile` function can be used in the build file to
+detect compilation errors in the TeX log file.
+
 ## File matches
 
-Other type of action which can be specified in the build file are
-matches  which may be called  on the generated files:
+Another type of action which can be specified in the build file is
+`match`.  It can be called on the generated files:
 
     Make:match("html$", "tidy -m -xml -utf8 -q -i ${filename}")
 
-It tests filenames with `Lua` pattern matching and on matched items will
-execute command or function, specified in the second argument. For functions,
-two arguments are passed, first one is the current filename, the second one
-table with parameters. These parameters are the same as in previous section,
-except for `filename`, which contains generated output name.
+It tests output file names with `Lua` pattern matching and on matched items will
+execute a command or a function, specified in the second argument. Commands may be
+specified as strings, the templates will be expanded, `${var_name}` placeholders
+will be replaced with corresponding variables from the `parameters` table,
+described in the previous subsection. One additional variable is available:
+`filename`. It contains the name of the current output file.
 
+The above example will clean all output `HTML` files using the `tidy` command.
+
+If function is used instead, it will get two parameters.
+The first one is a current filename, the second one
+table with parameters. 
+
+
+
 ### Filters
 
-Some default match actions which you can use are in the `filter` module.  It
-contains some functions which ares useful for fixing some `tex4ht` bugs or
-shortcomings.
+Some default `match` actions which can be used are available from  the
+`make4ht-filter` module.  It contains some functions which are useful for
+fixing some `tex4ht` bugs or shortcomings.
 
 Example:
 
@@ -179,34 +324,35 @@
     Make:htlatex()
     Make:match("html$",process)
 
+The `make4ht-filter` module return a function which can be used for the filter
+chain building. Multiple filters can be chained, each of them can modify the string
+which was modified by the previous filters. The changes are then saved to the
+processed file.
 
-Filter module is located in `make4ht-filter`. Function is returned, 
-which is used for building filter chains then. 
-
 Built-in filters are:
 
-cleanspan 
+cleanspan
 
 :    clean spurious span elements when accented characters are used
 
-cleanspan-nat 
+cleanspan-nat
 
 :    alternative clean span filter, provided by Nat Kuhn
 
-fixligatures 
+fixligatures
 
 :    decompose ligatures to base characters
 
-hruletohr 
+hruletohr
 
 :   `\hrule` commands are translated to series of underscore characters
     by `tex4ht`, this filter translate these underscores to `<hr>` elements
 
-entites 
+entites
 
 :    convert prohibited named entities to numeric entities (currently, only
      ` `, as it causes validation errors, and `tex4ht` is producing it
-     sometimes
+     sometimes)
 
 fix-links
 
@@ -214,55 +360,239 @@
      cross-reference commands may produce colons in internal links, which results in
      validation error.
 
-Function `filter` accepts also function arguments, in this case this function 
-takes file contents as parameter and modified contents are returned.
+mathjaxnode
 
+:    use [mathjax-node-page](https://github.com/pkra/mathjax-node-page/) to
+     convert from MathML code to HTML + CSS or SVG. See [the available
+     settings](#mathjaxsettings).
+
+svg-height
+
+:    some  SVG images produced by `dvisvgm` seem to have wrong dimensions. This filter
+     tries to set the correct image size.
+
+Function `filter` accepts also function arguments, in this case this function
+takes file contents as a parameter and modified contents are returned.
+
 Example:
 
-    local filter  = require "make4ht-filter"                                    
+    local filter  = require "make4ht-filter"
     local changea = function(s) return s:gsub("a","z") end
-    local process = filter{"cleanspan", "fixligatures", changea}            
-    Make:htlatex()                                                              
+    local process = filter{"cleanspan", "fixligatures", changea}
     Make:htlatex()
-    Make:match("html$",process) 
+    Make:htlatex()
+    Make:match("html$",process)
 
-In this case, spurious span elements are joined, ligatures are decomposed,
+In this example, spurious span elements are joined, ligatures are decomposed,
 and then all letters 'a' are replaced with 'z' letters.
 
+### DOM filters
+
+DOM filters use the [`LuaXML`](https://ctan.org/pkg/luaxml) library to modify
+directly the XML object. This enables more powerful
+operations than the regex based filters from the previous section. 
+
+Example:
+
+    local domfilter = require "make4ht-domfilter"
+    local process = domfilter {"joincharacters"}
+    Make:match("html$", process)
+
+
+Available DOM filters:
+
+aeneas
+
+:  [Aeneas](https://www.readbeyond.it/aeneas/) is a tool for automagical synchronization of text and audio.
+   This filter modifies the HTML code to support the synchronization.
+
+fixinlines
+
+:  put all inline elements which are direct children of the `<body>` elements to a paragraph.
+
+idcolons
+
+:  replace the colon (`:`) character in internal links and `id` attributes. They cause validation issues.
+
+joincharacters
+
+:  join consecutive `<span>` or `<mn>` elements.
+
+### make4ht-aeneas-config package
+
+Companion for the `aeneas` DOM filter is the `make4ht-aeneas-config` plugin. It
+can be used to write Aeneas configuration file or execute Aeneas on the
+generated HTML files.
+
+Available functions:
+
+write\_job(parameters)
+
+:  write Aenas job configuration to `config.xml` file. See the [Aeneas
+   documentation](https://www.readbeyond.it/aeneas/docs/clitutorial.html#processing-jobs)
+   for more information about jobs.
+
+execute(parameters)
+
+:  execute Aeneas.
+
+process\_files(parameters)
+
+:  process the audio and generated subtitle files.
+
+
+By default, the `smil` file is created. It is assumed that there is audio file
+in `mp3` format named as the TeX file. It is possible to use different formats
+and file names using mapping.
+
+The configuration options can be passed directly to the functions or set using
+`filter_settings "aeneas-config" {parameters}` function.
+
+
+Available parameters:
+
+
+lang 
+
+:  document language. It is interfered from the HTML file, so it is not necessary to set it. 
+
+map 
+
+:  mapping between HTML, audio and subtitle files. More info bellow. 
+
+text\_type 
+
+:  type of the input. The `aeneas` DOM filter produces `unparsed` text type.
+
+id\_sort 
+
+:  sorting of id attributes. Default value is `numeric`.
+
+id\_regex 
+
+:  regular expression to parse the id attributes.
+
+sub\_format 
+
+:  generated subtitle format. Default `smil`.
+
+
+Additional parameters for the job configuration file:
+
+- description 
+- prefix 
+- config\_name 
+- keep\_config 
+
+
+
+It is possible to generate multiple HTML files from the LaTeX source. For
+example, `tex4ebook` generates separate file for each chapter or section. It is
+possible to set options for each HTML file, in particular names of the
+corresponding audio files. This mapping is done using `map` parameter. 
+
+Example:
+
+    filter_settings "aeneas-config" {
+      map = {
+        ["sampleli1.html"] = {audio_file="sample.mp3"}, 
+        ["sample.html"] = false
+      }
+    }
+
+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
+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 `sec-filename` option or `tex4ht`.
+
+Available `map` options:
+
+
+audio\_file 
+
+:  the corresponding audio file 
+
+sub\_file 
+
+:  name of the generated subtitle file
+
+The following options are same as their counter-parts from the main parameters table and generally don't need to be set:
+
+- prefix 
+- file\_desc 
+- file\_id 
+- text\_type 
+- id\_sort
+- id\_prefix 
+- sub\_format 
+
+
+Full example:
+
+
+    local domfilter = require "make4ht-domfilter"
+    local aeneas_config = require "make4ht-aeneas-config"
+    
+    filter_settings "aeneas-config" {
+      map = {
+        ["krecekli1.xhtml"] = {audio_file="krecek.mp3"}, 
+        ["krecek.xhtml"] = false
+      }
+    }
+    
+    local process = domfilter {"aeneas"}
+    Make:match("html$", process)
+
+    if mode == "draft" then
+      aeneas_config.process_files {}
+    else
+      aeneas_config.execute {}
+    end
+
+
+
+
 ## Image conversion
 
-It is possible to convert parts of LaTeX input to pictures, it is used 
+It is possible to convert parts of LaTeX input to pictures, it is used
 for example for math or diagrams in `tex4ht`. 
 
-These pictures are stored in special `dvi` file, on which `dvi to image` 
-commands are called. 
+These pictures are stored in a special `dvi` file, which can be processed by
+the `dvi to image` commands. 
 
-This conversion is normally configured in the `env file`, 
+This conversion is normally configured in the `env file`,
 which is system dependent and which has a bit unintuitive syntax.
-This configuration is processed by `t4ht` application and conversion
+This configuration is processed by the `t4ht` application and conversion
 commands are called for all pictures.
 
-It is possible to disable `t4ht` image processing and configure image 
-conversion in the make file:
+It is possible to disable `t4ht` image processing and configure image
+conversion in the build file:
 
     Make:image("png$",
-    "dvipng -bg Transparent -T tight -o ${output}  -pp ${page} ${source}")                                                       
+    "dvipng -bg Transparent -T tight -o ${output}  -pp ${page} ${source}")
 
 
 `Make:image` takes two parameters, pattern to match image name and action.
-Action can be either string template with conversion command, 
-or function which takes table with parameters as argument.
+Action can be either string template with conversion command,
+or function which takes a table with parameters as an argument.
 
 There are three parameters:
 
-  - output - output image file name
-  - source - `dvi` file with the pictures
-  - page   - page number of the converted image
+  - `output` - output image file name
+  - `source` - `dvi` file with the pictures
+  - `page`   - page number of the converted image
 
 ## The `mode` variable
 
-The `mode` variable contains contents of `--mode` command line option. 
-It can be used to run some commands conditionally. For example:
+There is global `mode` variable available in the build file. It contains
+contents of the `--mode` command line option.  It can be used to run some commands
+conditionally. For example:
 
      if mode == "draft" then
        Make:htlatex{} 
@@ -281,7 +611,7 @@
 
 You may want to access to the parameters also outside commands, file matches
 and image conversion functions. For example, if you want to convert your file to
-the `OpenDocument Format`, you can use the following settings, based on `oolatex`
+the `OpenDocument Format (ODT)`, you can use the following settings, based on the `oolatex`
 command:
 
     settings.tex4ht_sty_par = settings.tex4ht_sty_par ..",ooffice"
@@ -288,7 +618,157 @@
     settings.tex4ht_par = settings.tex4ht_par .. " ooffice/! -cmozhtf"
     settings.t4ht_par = settings.t4ht_par .. " -cooxtpipes -coo "
 
+There are some functions to ease access to the settings:
 
+`set_settings{parameters}`
+
+:   overwrite settings with values from a passed table
+
+`settings_add{parameters}`
+
+:   add values to the current settings 
+
+`filter_settings "filter name" {parameters}`
+
+:   set settings for a filter
+
+`get_filter_settings(name)`
+
+:   get settings for a filter
+
+
+Using these functions, it is possible to simplify the settings for the `ODT` format:
+
+    settings_add {
+      tex4ht_sty_par =",ooffice",
+      tex4ht_par = " ooffice/! -cmozhtf",
+      t4ht_par = " -cooxtpipes -coo "
+    }
+
+Settings for filters and extensions can be set using `filter_settings`:
+
+    
+    filter_settings "test" {
+      hello = "world"
+    }
+
+These settings can be read in the extensions and filters using `get_filter_settings`:
+
+    function test(input)
+       local options = get_filter_settings("test")
+       print(options.hello)
+       return input
+    end
+       
+## List of available settings for filters and extensions.
+
+These settings may be set using `filter_settings` function.
+
+### The `tidy` extension
+
+options
+
+:  command line options for the `tidy` command. Default value is `-m -utf8 -w 512 -q`.
+
+### The `fixinlines` dom filter 
+
+inline\_elements
+
+:  table of inline elements which shouldn't be direct descendants of the `body` element. The element names should be table keys, the values should be true.
+
+Example
+
+    filter_settings "fixinlines" {inline_elements = {a = true, b = true}}
+
+### The `joincharacters` dom filter
+
+charelements 
+
+:  table of elements which should be joined if several instances with the same value of `class` attribute are side by side.
+
+Example
+
+    filter_settings "joincharacters" { charclases = { span=true, mn = true}}
+
+### The `mathjaxnode` filter {#mathjaxsettings}
+
+options
+
+:  command line options for the `mjpage` command. Default value is `--output CommonHTML`
+
+Example
+
+    filter_settings "mathjaxnode" {
+      options="--output SVG --font Neo-Euler"
+    }
+
+cssfilename  
+
+:  `mjpage` puts some CSS code into the HTML pages. `mathjaxnode` extracts this information and saves it to a standalone CSS file. Default CSS filename is `mathjax-chtml.css`
+
+fontdir
+
+:  directory with MathJax font files. This option enables use of local fonts, which
+   is usefull in Epub conversion, for example. The font directory should be
+   sub-directory of the current directory. Only TeX font is supported at the moment.
+
+Example
+
+
+    filter_settings "mathjaxnode" {
+      fontdir="fonts/TeX/woff/" 
+    }
+
+### The `aeneas` filter
+
+skip\_elements
+
+:  List of CSS selectors that match elements which shouldn't be processed. Default value: `{ "math", "svg"}`.
+
+id\_prefix 
+
+:  prefix used in the ID attribute forming.
+
+sentence\_match 
+
+:  Lua pattern used to match a sentence. Default value: `"([^%.^%?^!]*)([%.%?!]?)"`.
+
+# Configuration file {#configfile}
+
+It is possible to globally modify the build settings using the configuration
+file. New compilation commands can be added, extensions can be loaded or
+disabled and settings can be set.
+
+## Location 
+
+The configuration file can be saved either in
+`$HOME/.config/make4ht/config.lua` or in `.make4ht` in the current directory or
+it's parents (up to `$HOME`).
+
+## Additional commands
+
+There are two additional commands:
+
+`Make:enable_extension(name)`
+
+:  require extension
+
+`Make:disable_extension(name)`
+
+:  disable extension
+
+## Example
+
+The following configuration add support for the `biber` command, requires
+`common_domfilters` extension and requires MathML
+output for math.
+
+    Make:add("biber", "biber ${input}")
+    Make:enable_extension "common_domfilters"
+    settings_add {
+      tex4ht_sty_par =",mathml"
+    }
+
 # Command line options
 
     make4ht - build system for tex4ht
@@ -301,6 +781,7 @@
     -d,--output-dir (default "")  Output directory
     -e,--build-file (default nil)  If build file name is different 
          than `filename`.mk4
+    -f,--format  (default nil)  Output file format
     -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
@@ -311,16 +792,16 @@
     <filename> (string) Input file name
 
 
-You can still use `make4ht` in same way as `htlatex`
+You can still invoke `make4ht` in the same way as `htlatex`:
 
-    make4ht filename "customcfg, charset=utf-8" " -cunihtf -utf8" " -dfoo"
+    make4ht filename "customcfg, charset=utf-8" "-cunihtf -utf8" "-dfoo"
 
-Note that this will not use `make4ht` routines for output dir making and
-copying If you want to use them, change the line above to:
+Note that this will not use `make4ht` routines for output directory making and
+copying. If you want to use them, change the line above to:
 
-    make4ht filename "customcfg, charset=utf-8" " -cunihtf -utf8"  -d foo
+    make4ht -d foo filename "customcfg, charset=utf-8" "-cunihtf -utf8"
 
-This call has the same effect as following:
+This call has the same effect as the following:
 
     make4ht -u -c customcfg -d foo filename
 
@@ -332,4 +813,32 @@
     make4ht -d ~/gotohomedir filename
     make4ht -d c:\documents\windowspathsareworkingtoo filename
 
+# Troubleshooting 
 
+## Incorrect handling of command line arguments for `tex4ht`, `t4ht` or `latex`
+
+Sometimes, you may get a similar error:
+
+    make4ht:unrecognized parameter: i
+
+It may be caused by a following `make4ht` invocation:
+
+    make4ht hello.tex "customcfg,charset=utf-8" "-cunihtf -utf8" -d foo
+
+The command line option parser is confused by mixing options for `make4ht` and
+`tex4ht` in this case and tries to interpret the `-cunihtf -utf8`, which are
+options for `tex4ht` command as `make4ht` options. To fix that, you can either
+move the `-d foo` directly after `make4ht` command:
+
+    make4ht -d foo hello.tex "customcfg,charset=utf-8" "-cunihtf -utf8"
+
+Another option is to add a space before `tex4ht` options:
+
+    make4ht hello.tex "customcfg,charset=utf-8" " -cunihtf -utf8" -d foo
+
+The former way is preferable, though.
+
+# License
+
+Permission is granted to copy, distribute and/or modify this software
+under the terms of the LaTeX Project Public License, version 1.3.

Modified: trunk/Master/texmf-dist/doc/support/make4ht/changelog.tex
===================================================================
--- trunk/Master/texmf-dist/doc/support/make4ht/changelog.tex	2018-04-09 21:09:18 UTC (rev 47397)
+++ trunk/Master/texmf-dist/doc/support/make4ht/changelog.tex	2018-04-09 21:09:51 UTC (rev 47398)
@@ -1,11 +1,253 @@
-\section{Changelog}\label{changelog}
+\hypertarget{changelog}{%
+\section{Changelog}\label{changelog}}
 
 \begin{itemize}
 \item
+  2018/04/09
+
+  \begin{itemize}
+  \tightlist
+  \item
+    released version \texttt{0.2}
+  \item
+    disabled default loading of \texttt{common\_domfilters} extension
+  \end{itemize}
+\item
+  2018/04/06
+
+  \begin{itemize}
+  \tightlist
+  \item
+    added \texttt{Make:enable\_extension} and
+    \texttt{Make:disable\_extension} functions
+  \item
+    documented the configuration file
+  \end{itemize}
+\item
+  2018/03/09
+
+  \begin{itemize}
+  \tightlist
+  \item
+    load the configuration file before extensions
+  \end{itemize}
+\item
+  2018/03/02
+
+  \begin{itemize}
+  \tightlist
+  \item
+    Aeneas execution works
+  \item
+    Aeneas documentation
+  \item
+    added support for \texttt{.make4ht} configuration file
+  \end{itemize}
+\item
+  2018/02/28
+
+  \begin{itemize}
+  \tightlist
+  \item
+    Aeneas configuration file creation works
+  \end{itemize}
+\item
+  2018/02/22
+
+  \begin{itemize}
+  \tightlist
+  \item
+    fixed bug in \texttt{fixinlines} DOM filter
+  \end{itemize}
+\item
+  2018/02/21
+
+  \begin{itemize}
+  \tightlist
+  \item
+    added Aeneas domfilter
+  \item
+    fixed bugs in \texttt{joincharacters} DOM filter
+  \end{itemize}
+\item
+  2018/02/20
+
+  \begin{itemize}
+  \tightlist
+  \item
+    fixed bug in \texttt{joincharacters} DOM filter
+  \item
+    make \texttt{woff} default font format for \texttt{mathjaxnode}
+  \item
+    added documentation for \texttt{mathjaxnode} settings
+  \end{itemize}
+\item
+  2018/02/19
+
+  \begin{itemize}
+  \tightlist
+  \item
+    fixed bug in filter loading
+  \item
+    added \texttt{mathjaxnode} extension
+  \end{itemize}
+\item
+  2018/02/15
+
+  \begin{itemize}
+  \tightlist
+  \item
+    use HTML5 as a default format
+  \item
+    use \texttt{common\_domfilters} implicitly for the XHTML and HTML5
+    formats
+  \end{itemize}
+\item
+  2018/02/12
+
+  \begin{itemize}
+  \tightlist
+  \item
+    added \texttt{common\_domfilters} extension
+  \item
+    documented DOM filters
+  \end{itemize}
+\item
+  2018/02/12
+
+  \begin{itemize}
+  \tightlist
+  \item
+    handle XML parsing errors in the DOM handler
+  \item
+    enable extension loading in Formatters
+  \end{itemize}
+\item
+  2018/02/11
+
+  \begin{itemize}
+  \tightlist
+  \item
+    fixed Tidy extension output to support LuaXML
+  \item
+    fixed white space issues with \texttt{joincharacters} DOM filter
+  \end{itemize}
+\item
+  2018/02/09
+
+  \begin{itemize}
+  \tightlist
+  \item
+    fixed issues with the Mathjax filter
+  \item
+    documented basic info about thd DOM filters
+  \item
+    DOM filter optimalizations
+  \end{itemize}
+\item
+  2018/02/08
+
+  \begin{itemize}
+  \tightlist
+  \item
+    make Tidy extension configurable
+  \item
+    documented filter settings
+  \end{itemize}
+\item
+  2018/02/07
+
+  \begin{itemize}
+  \tightlist
+  \item
+    added filter for Mathjax-node
+  \end{itemize}
+\item
+  2018/02/06
+
+  \begin{itemize}
+  \tightlist
+  \item
+    created DOM filter function
+  \item
+    added DOM filter for spurious inlinine elements
+  \end{itemize}
+\item
+  2018/02/03
+
+  \begin{itemize}
+  \tightlist
+  \item
+    added settings handling functions
+  \item
+    settings made available for extensions and filters
+  \end{itemize}
+\item
+  2017/12/08
+
+  \begin{itemize}
+  \tightlist
+  \item
+    fixed the \texttt{mk4} build file loading when it is placed in the
+    current working dir and another one with same filename somewhere in
+    the TEXMF tree.
+  \end{itemize}
+\item
+  2017/11/10
+
+  \begin{itemize}
+  \tightlist
+  \item
+    Added new filter: \texttt{svg-height}. It tries to fix height of
+    some of the images produced by \texttt{dvisvgm}
+  \end{itemize}
+\item
+  2017/10/06
+
+  \begin{itemize}
+  \tightlist
+  \item
+    Added support for output format selection. Supported formats are
+    \texttt{xhtml}, \texttt{html5} and \texttt{odt}
+  \item
+    Added support for extensions
+  \end{itemize}
+\item
+  2017/09/10
+
+  \begin{itemize}
+  \tightlist
+  \item
+    Added support for Latexmk
+  \item
+    Added support of \texttt{math} library and \texttt{tonumber}
+    function in the build files
+  \end{itemize}
+\item
+  2017/09/04
+
+  \begin{itemize}
+  \tightlist
+  \item
+    fixed bug caused by the previous change -- the --help and --version
+    didn't work
+  \end{itemize}
+\item
+  2017/08/22
+
+  \begin{itemize}
+  \tightlist
+  \item
+    fixed the command line option parsing for \texttt{tex4ht},
+    \texttt{t4ht} and \texttt{latex} commands
+  \item
+    various grammar and factual fixes in the documentation
+  \end{itemize}
+\item
   2017/04/26
 
   \begin{itemize}
-  \itemsep1pt\parskip0pt\parsep0pt
+  \tightlist
   \item
     Released version \texttt{v0.1c}
   \end{itemize}
@@ -13,15 +255,15 @@
   2017/03/16
 
   \begin{itemize}
-  \itemsep1pt\parskip0pt\parsep0pt
+  \tightlist
   \item
-    check for \texttt{TeX capacity exceeded} error in the \LaTeX~run.
+    check for \texttt{TeX\ capacity\ exceeded} error in the \LaTeX~run.
   \end{itemize}
 \item
   2016/12/19
 
   \begin{itemize}
-  \itemsep1pt\parskip0pt\parsep0pt
+  \tightlist
   \item
     use full input name in \texttt{tex\_file} variable. This should
     enable use of files without \texttt{.tex} extension.
@@ -30,7 +272,7 @@
   2016/10/22
 
   \begin{itemize}
-  \itemsep1pt\parskip0pt\parsep0pt
+  \tightlist
   \item
     new command available in the build file:
     \texttt{Make:add\_file(filename)}. This enables filters and commands
@@ -43,7 +285,7 @@
   2016/10/18
 
   \begin{itemize}
-  \itemsep1pt\parskip0pt\parsep0pt
+  \tightlist
   \item
     new filter: replace colons in \texttt{id} and \texttt{href}
     attributes with underscores
@@ -52,7 +294,7 @@
   2016/01/11
 
   \begin{itemize}
-  \itemsep1pt\parskip0pt\parsep0pt
+  \tightlist
   \item
     fixed bug in loading documents with full path specified
   \end{itemize}
@@ -60,11 +302,11 @@
   2015/12/06 version 0.1b
 
   \begin{itemize}
-  \itemsep1pt\parskip0pt\parsep0pt
+  \tightlist
   \item
-    modifed lapp library to recognize \texttt{-{}-version} and
+    modifed lapp library to recognize \texttt{-\/-version} and
   \item
-    added \texttt{-{}-help} and \texttt{-{}-version} command line
+    added \texttt{-\/-help} and \texttt{-\/-version} command line
     options
   \end{itemize}
 \item
@@ -71,7 +313,7 @@
   2015/11/30
 
   \begin{itemize}
-  \itemsep1pt\parskip0pt\parsep0pt
+  \tightlist
   \item
     use \texttt{kpse} library for build file locating
   \end{itemize}
@@ -79,7 +321,7 @@
   2015/11/17
 
   \begin{itemize}
-  \itemsep1pt\parskip0pt\parsep0pt
+  \tightlist
   \item
     better \texttt{-jobname} handling
   \end{itemize}
@@ -87,18 +329,18 @@
   2015/09/23 version 0.1a
 
   \begin{itemize}
-  \itemsep1pt\parskip0pt\parsep0pt
+  \tightlist
   \item
     various documentation updates
+  \item
+    \texttt{mozhtf} profile for unicode output is used, this should
+    prevent ligatures in the output files
   \end{itemize}
 \item
-  \texttt{mozhtf} profile for unicode output is used, this should
-  prevent ligatures in the output files
-\item
   2015/06/29 version 0.1
 
   \begin{itemize}
-  \itemsep1pt\parskip0pt\parsep0pt
+  \tightlist
   \item
     major README file update
   \end{itemize}
@@ -106,7 +348,7 @@
   2015/06/26
 
   \begin{itemize}
-  \itemsep1pt\parskip0pt\parsep0pt
+  \tightlist
   \item
     added Makefile
   \item

Added: trunk/Master/texmf-dist/doc/support/make4ht/extensions/common_domfilters.lua
===================================================================
--- trunk/Master/texmf-dist/doc/support/make4ht/extensions/common_domfilters.lua	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/support/make4ht/extensions/common_domfilters.lua	2018-04-09 21:09:51 UTC (rev 47398)
@@ -0,0 +1,27 @@
+local M = {}
+
+
+local filter = require "make4ht-domfilter"
+-- local process = filter {"fixinlines", "idcolons", "joincharacters" }
+
+-- filters support only html formats
+function M.test(format)
+  if format == "odt" then return false end
+  return true
+end
+
+function M.modify_build(make)
+  local process = filter {"fixinlines", "idcolons", "joincharacters"}
+  make:match("html$", process)
+  local matches = make.matches
+  -- the filters should be first match to be executed, especially if tidy
+  -- should be executed as well
+  if #matches > 1 then
+    local last = matches[#matches]
+    table.insert(matches, 1, last)
+    matches[#matches] = nil
+  end
+  return make
+end
+
+return M


Property changes on: trunk/Master/texmf-dist/doc/support/make4ht/extensions/common_domfilters.lua
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/support/make4ht/extensions/common_filters.lua
===================================================================
--- trunk/Master/texmf-dist/doc/support/make4ht/extensions/common_filters.lua	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/support/make4ht/extensions/common_filters.lua	2018-04-09 21:09:51 UTC (rev 47398)
@@ -0,0 +1,26 @@
+local M = {}
+
+
+local filter = require "make4ht-filter"
+local process = filter {"cleanspan-nat", "fixligatures", "hruletohr", "entities", "fix-links"}
+
+-- filters support only html formats
+function M.test(format)
+  if format == "odt" then return false end
+  return true
+end
+
+function M.modify_build(make)
+  make:match("html$", process)
+  local matches = make.matches
+  -- the filters should be first match to be executed, especially if tidy
+  -- should be executed as well
+  if #matches > 1 then
+    local last = matches[#matches]
+    table.insert(matches, 1, last)
+    matches[#matches] = nil
+  end
+  return make
+end
+
+return M


Property changes on: trunk/Master/texmf-dist/doc/support/make4ht/extensions/common_filters.lua
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/support/make4ht/extensions/latexmk.lua
===================================================================
--- trunk/Master/texmf-dist/doc/support/make4ht/extensions/latexmk.lua	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/support/make4ht/extensions/latexmk.lua	2018-04-09 21:09:51 UTC (rev 47398)
@@ -0,0 +1,31 @@
+-- use Latexmk in first LaTeX call
+-- only in the first call, because we don't need to execute  biber, etc. in the subsequent
+-- LaTeX calls, these are only for resolving the cross-references
+local M = {}
+function M.modify_build(make)
+  local used = false
+  local first 
+  local build_seq = make.build_seq
+  -- find first htlatex call in the build sequence
+  for pos,v in ipairs(build_seq) do
+    if v.name == "htlatex" and not first then
+      first = pos
+    end
+  end
+  -- if htlatex was found
+  if first then
+    -- add dummy latexmk call to the build sequence
+    make:latexmk {}
+    -- replace name, command and type in the first htlatex
+    -- call with values from the dummy latexmk call
+    local replaced = build_seq[first]
+    local latexmk = build_seq[#build_seq]
+    replaced.name = latexmk.name
+    replaced.command = latexmk.command
+    replaced.type = latexmk.type
+    -- remove the dummy latexmk
+    table.remove(build_seq)
+  end
+  return make
+end
+return M


Property changes on: trunk/Master/texmf-dist/doc/support/make4ht/extensions/latexmk.lua
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/support/make4ht/extensions/mathjaxnode.lua
===================================================================
--- trunk/Master/texmf-dist/doc/support/make4ht/extensions/mathjaxnode.lua	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/support/make4ht/extensions/mathjaxnode.lua	2018-04-09 21:09:51 UTC (rev 47398)
@@ -0,0 +1,16 @@
+local M = {}
+
+
+local filter = require "make4ht-filter"
+function M.test(format)
+  if format == "odt" then return false end
+  return true
+end
+
+function M.modify_build(make)
+  local mathjax = filter { "mathjaxnode"}
+  make:match("html$",mathjax)
+  return make
+end
+
+return M


Property changes on: trunk/Master/texmf-dist/doc/support/make4ht/extensions/mathjaxnode.lua
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/support/make4ht/extensions/tidy.lua
===================================================================
--- trunk/Master/texmf-dist/doc/support/make4ht/extensions/tidy.lua	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/support/make4ht/extensions/tidy.lua	2018-04-09 21:09:51 UTC (rev 47398)
@@ -0,0 +1,57 @@
+local M = {}
+
+function M.test(format)
+  if format == "odt" then return false end
+  return true
+end
+
+local empty_elements = {
+  area=true,
+  base=true,
+  br=true,
+  col=true,
+  embed=true,
+  hr=true,
+  img=true,
+  input=true,
+  keygen=true,
+  link=true,
+  meta=true,
+  param=true,
+  source=true,
+  track=true,
+  wbr=true,
+}
+
+-- LuaXML cannot read HTML with unclosed tags (like <meta name="hello" content="world">)
+-- Tidy removes end slashes in the HTML output, so
+-- this function will add them back
+local function close_tags(s)
+  return s:gsub("<(%w+)([^>]-)>", function(tag, rest)
+    local endslash = ""
+    if empty_elements[tag] then endslash = " /" end
+    return string.format("<%s%s%s>", tag, rest, endslash)
+  end)
+end
+    
+
+
+function M.modify_build(make)
+  make:match("html$", function(filename, par)
+    local settings = get_filter_settings "tidy" or {}
+    par.options = par.options or settings.options or "-utf8 -w 512 -ashtml -q"
+    local command = "tidy ${options}  ${filename}" % par
+    print("execute: ".. command)
+    -- os.execute(command)
+    local run = io.popen(command, "r")
+    local result = run:read("*all")
+    run:close()
+    result = close_tags(result)
+    local f = io.open(filename, "w")
+    f:write(result)
+    f:close()
+  end)
+  return make
+end
+
+return M


Property changes on: trunk/Master/texmf-dist/doc/support/make4ht/extensions/tidy.lua
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/support/make4ht/formats/html5.lua
===================================================================
--- trunk/Master/texmf-dist/doc/support/make4ht/formats/html5.lua	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/support/make4ht/formats/html5.lua	2018-04-09 21:09:51 UTC (rev 47398)
@@ -0,0 +1,17 @@
+local M = {}
+
+local mkutils = require "mkutils"
+
+function M.prepare_extensions(extensions)
+  -- return mkutils.add_extensions("+common_domfilters", extensions)
+  return extensions --mkutils.add_extensions("+tidy", extensions)
+end
+
+function M.prepare_parameters(parameters,extensions)
+  parameters.tex4ht_sty_par  = parameters.tex4ht_sty_par .. ",html5"
+  parameters = mkutils.extensions_prepare_parameters(extensions,parameters)
+  return parameters
+end
+
+
+return M


Property changes on: trunk/Master/texmf-dist/doc/support/make4ht/formats/html5.lua
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/support/make4ht/formats/odt.lua
===================================================================
--- trunk/Master/texmf-dist/doc/support/make4ht/formats/odt.lua	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/support/make4ht/formats/odt.lua	2018-04-09 21:09:51 UTC (rev 47398)
@@ -0,0 +1,11 @@
+local M = {}
+local mkutils = require "mkutils"
+
+function M.prepare_parameters(settings, extensions)
+  settings.tex4ht_sty_par = settings.tex4ht_sty_par ..",ooffice"
+  settings.tex4ht_par = settings.tex4ht_par .. " ooffice/! -cmozhtf"
+  settings.t4ht_par = settings.t4ht_par .. " -cooxtpipes -coo "
+  settings = mkutils.extensions_prepare_parameters(extensions, settings)
+  return settings
+end
+return M


Property changes on: trunk/Master/texmf-dist/doc/support/make4ht/formats/odt.lua
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/support/make4ht/formats/xhtml.lua
===================================================================
--- trunk/Master/texmf-dist/doc/support/make4ht/formats/xhtml.lua	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/support/make4ht/formats/xhtml.lua	2018-04-09 21:09:51 UTC (rev 47398)
@@ -0,0 +1,16 @@
+local M = {}
+
+local mkutils = require "mkutils"
+
+function M.prepare_extensions(extensions)
+  -- return mkutils.add_extensions("+common_domfilters", extensions)
+  return extensions
+end
+
+function M.prepare_parameters(parameters,extensions)
+  parameters = mkutils.extensions_prepare_parameters(extensions,parameters)
+  return parameters
+end
+
+
+return M


Property changes on: trunk/Master/texmf-dist/doc/support/make4ht/formats/xhtml.lua
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/doc/support/make4ht/make4ht-doc.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/support/make4ht/make4ht-doc.tex
===================================================================
--- trunk/Master/texmf-dist/doc/support/make4ht/make4ht-doc.tex	2018-04-09 21:09:18 UTC (rev 47397)
+++ trunk/Master/texmf-dist/doc/support/make4ht/make4ht-doc.tex	2018-04-09 21:09:51 UTC (rev 47398)
@@ -9,6 +9,7 @@
 \else
 \usepackage{fontspec}
 \setmainfont{TeX Gyre Schola}
+\setmonofont[Scale=MatchLowercase]{Inconsolatazi4}
 \fi
 \usepackage{microtype}
 \providecommand\tightlist{\relax}

Modified: trunk/Master/texmf-dist/doc/support/make4ht/readme.tex
===================================================================
--- trunk/Master/texmf-dist/doc/support/make4ht/readme.tex	2018-04-09 21:09:18 UTC (rev 47397)
+++ trunk/Master/texmf-dist/doc/support/make4ht/readme.tex	2018-04-09 21:09:51 UTC (rev 47398)
@@ -1,177 +1,354 @@
-\section{Introduction}\label{introduction}
+\hypertarget{introduction}{%
+\section{Introduction}\label{introduction}}
 
-\texttt{make4ht} is a simple build system for tex4ht. It is both
-executable which simplifies \texttt{tex4ht} execution and a library
-which can be used to create customized conversion programs. An example
-of such conversion program is
-\href{https://github.com/michal-h21/tex4ebook}{tex4ebook}
+\texttt{make4ht} is a simple build system for \texttt{tex4ht}, \TeX~to
+XML converter. It provides a command line tool that drive the conversion
+process. It also provides a library which can be used to create
+customized conversion tools. An example of such conversion tool is
+\href{https://github.com/michal-h21/tex4ebook}{tex4ebook} for conversion
+of \TeX~to ePub and other e-book formats.
 
-\subsection{License}\label{license}
+\hypertarget{how-it-works}{%
+\subsection{How it works}\label{how-it-works}}
 
-Permission is granted to copy, distribute and/or modify this software
-under the terms of the LaTeX Project Public License, version 1.3.
+\hypertarget{the-issues-with-default-tex4ht-conversion-commands}{%
+\subsubsection{\texorpdfstring{The issues with default \texttt{tex4ht}
+conversion
+commands}{The issues with default tex4ht conversion commands}}\label{the-issues-with-default-tex4ht-conversion-commands}}
 
-\subsection{How it works}\label{how-it-works}
+\texttt{tex4ht} system supports several output formats, most notably
+\texttt{XHTML}, \texttt{HTML\ 5} and \texttt{ODT}. The conversion can be
+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 files are created.
 
-Default compilation script for \texttt{tex4ht}, named \texttt{htlatex}
-compiles LaTeX files to \texttt{HTML} with this command sequence:
+The basic command provided by \texttt{tex4ht} is named \texttt{htlatex}.
+It compiles \LaTeX~ files to \texttt{HTML} with this command sequence:
 
 \begin{verbatim}
 latex $latex_options 'code for loading tex4ht.sty \input{filename}'
 latex $latex_options 'code for loading tex4ht.sty \input{filename}'
 latex $latex_options 'code for loading tex4ht.sty \input{filename}'
-tex4ht options filename
-t4ht options filename
+tex4ht $tex4ht_options filename
+t4ht $t4ht_options filename
 \end{verbatim}
 
-The problem is that this is inefficient when you need to run program
-which interact with LaTeX, such as \texttt{Makeindex} or
-\texttt{Bibtex}. In that case, you need to create new script based on
-the default one, or run \texttt{htlatex} twice, which means six LaTeX
-runs.
+The options for various parts of the system can be passed on the command
+line:
 
-Another problem is with \texttt{t4ht} application. It reads file
-\texttt{filename.lg}, generated by \texttt{tex4ht}, where are
-instructions about generated files, \texttt{CSS} instructions, calls to
-external applications, instructions for image conversions etc. It can be
-instructed to copy generated files to some output directory, but it
-doesn't preserve directory structure, so when you have images in some
-subdirectory, they will be copied to the output directory, but links
-will be pointing to non existing subdirectory.
+\begin{verbatim}
+htlatex filename "tex4ht.sty options" "tex4ht_options" "t4ht_options" "latex_options"
+\end{verbatim}
 
-Image conversion is directed with the
+For basic \texttt{HTML} conversion it is possible to use the most basic
+invocation:
+
+\begin{verbatim}
+htlatex filename.tex
+\end{verbatim}
+
+It can be much more involved for \texttt{HTML\ 5} output in
+\texttt{UTF-8} encoding:
+
+\begin{verbatim}
+htlatex filename.tex "xhtml,html5,charset=utf-8" "-cmozhtf -utf8"
+\end{verbatim}
+
+\texttt{make4ht} can simplify it:
+
+\begin{verbatim}
+make4ht -uf html5 filename.tex
+\end{verbatim}
+
+Another issue is the fixed compilation order and hard-coded number of
+LaTeX invocations.
+
+When you need to run a program which interact with LaTeX, such as
+\texttt{Makeindex} or \texttt{Bibtex}, you need to create a new script
+based on \texttt{htlatex}, or run \texttt{htlatex} twice, which means
+that LaTeX will be invoked six times. This can lead to significantly
+long compilation times. \texttt{make4ht} provides build files and
+extensions, which can be used for interaction with external tools.
+
+It is also possible to have several compilation modes. When you just add
+new text to a document, which doesn't contain cross-references, don't
+add new stuff to the table of contents, etc., it is possible to use the
+\texttt{draft} mode which will invoke LaTeX only once. It can save quite
+a lot of the compilation time:
+
+\begin{verbatim}
+make4ht -um draft -f html5 filename.tex
+\end{verbatim}
+
+There are also issues with a behaviour of the \texttt{t4ht} application.
+It reads file \texttt{filename.lg}, generated by \texttt{tex4ht}, where
+are instructions about generated files, \texttt{CSS} instructions, calls
+to external applications, instructions for image conversions etc. It can
+be instructed to copy generated files to some output directory, but it
+doesn't preserve directory structure, so when you have images in a
+subdirectory, they will be copied to the output directory. Links will be
+pointing to a non-existing subdirectory. The following command should
+copy all output files to the correct destinations.
+
+\begin{verbatim}
+make4ht -d outputdir filename.tex
+\end{verbatim}
+
+The image conversion is configured in the
 \href{http://www.tug.org/applications/tex4ht/mn35.html\#index35-73001}{env
-file}, with really strange syntax based on whitespace and
+file}, which has really strange syntax based and the rules are
 \href{http://www.tug.org/applications/tex4ht/mn-unix.html\#index27-69005}{os
-dependent}. With \texttt{make4ht} build files, we have simple mean to
-fix these issues. We can change image conversion parameters without need
-to modify the \texttt{env file}, and call actions on the output files.
+dependent}. \texttt{make4ht} provides simpler means for the image
+conversion in the build files.
+
+With \texttt{make4ht} build files, we have simple mean to fix these
+issues. We can change image conversion parameters without the need to
+modify the \texttt{env\ file}, or execute actions on the output files.
 These actions can be either external programs such as \texttt{xslt}
-processors or \texttt{HTML tidy} or \texttt{Lua} functions.
+processors or \texttt{HTML\ tidy} or \texttt{Lua} functions.
 
 The idea is to make system controlled by a build file. Because
 \texttt{Lua} interpreter is included in modern TeX distributions and
 \texttt{Lua} is ideal language for such task, it was chosen as language
-in which build script are written.
+in which the build scripts are written.
 
-\section{Build files}\label{build-files}
+\hypertarget{output-file-formats-and-extensions}{%
+\section{Output file formats and
+extensions}\label{output-file-formats-and-extensions}}
 
-\subsection{Commands}\label{commands}
+The default output format used by \texttt{make4ht} is \texttt{html5}.
+Different format can be requested using the \texttt{-\/-format} option.
+Supported formats are:
 
-By default, build file is saved in file named
-\texttt{filename + .mk4 extension}. You can choose different build file
-with \texttt{-e} or \texttt{-{}-build-file} command line option.
+\begin{itemize}
+\tightlist
+\item
+  \texttt{xhtml}
+\item
+  \texttt{html5}
+\item
+  \texttt{odt}
+\end{itemize}
 
-Sample:
+The \texttt{-\/-format} option can be also used for extension loading.
 
+\hypertarget{extensions}{%
+\subsection{Extensions}\label{extensions}}
+
+Extensions can be used to modify the build process without the need to
+use a build file. They may post-process the output files or request
+additional commands for the compilation.
+
+The extensions can be enabled or disabled by appending
+\texttt{+EXTENSION} or \texttt{-EXTENSION} after the output format name:
+
 \begin{verbatim}
+ make4ht -uf html5+tidy filename.tex
+\end{verbatim}
+
+Available extensions:
+
+\begin{description}
+\item[latexmk]
+use \texttt{Latexmk} for \LaTeX~compilation.
+\item[tidy]
+clean the \texttt{HTML} files using the \texttt{tidy} command.
+\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
+\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}.
+\end{description}
+
+\hypertarget{build-files}{%
+\section{Build files}\label{build-files}}
+
+\texttt{make4ht} supports build files. These are \texttt{Lua} scripts
+which can adjust the build process. You can request external
+applications like \texttt{bibtex} or \texttt{makeindex}, pass options to
+the commands, modify the image conversion process, or post-process the
+generated files.
+
+\texttt{make4ht} tries to load default build file named as
+\texttt{filename\ +\ .mk4\ extension}. You can choose different build
+file with \texttt{-e} or \texttt{-\/-build-file} command line option.
+
+Sample build file:
+
+\begin{verbatim}
 Make:htlatex()
 Make:match("html$", "tidy -m -xml -utf8 -q -i ${filename}")
 \end{verbatim}
 
 \texttt{Make:htlatex()} is preconfigured command for calling LaTeX with
-\texttt{tex4ht} loaded on the input file. In this case it will be called
-one time. After compilation, \texttt{tidy} command is executed on the
-output \texttt{html} file.
+\texttt{tex4ht} loaded on the input file. In this case, it will be
+called one time. After compilation, the \texttt{tidy} command is
+executed on the output \texttt{HTML} file.
 
 Note that you don't have to call \texttt{tex4ht} and \texttt{t4ht}
 commands explicitly in the build file, they are called automatically.
 
-You can add more commands like \texttt{Make:htlatex} with
+\hypertarget{user-commands}{%
+\subsection{User commands}\label{user-commands}}
 
+You can add more commands like \texttt{Make:htlatex} using
+\texttt{Make:add} command:
+
 \begin{verbatim}
 Make:add("name", "command", {parameters}, repetition)
 \end{verbatim}
 
-it can be called with
+The \texttt{name} and \texttt{command} parameters are required, rest of
+the parameters are optional.
 
-\begin{verbatim}
-Make:name()
-\end{verbatim}
+This defines \texttt{name} command, which can be then executed as
+\texttt{Make:name()} command.
 
-\texttt{command} can be text template, or function:
+\hypertarget{provided-commands}{%
+\subsubsection{Provided commands}\label{provided-commands}}
 
+\begin{description}
+\item[\texttt{Make:htlatex}]
+One call to TeX engine with special configuration for \texttt{tex4ht}
+loading.
+\item[\texttt{Make:latexmk}]
+Use \texttt{Latexmk} for the document compilation. \texttt{tex4ht} will
+be loaded automatically.
+\item[\texttt{Make:tex4ht}]
+Process the \texttt{DVI} file and creates the output files.
+\item[\texttt{Make:t4ht}]
+Creates the CSS file.
+\end{description}
+
+\hypertarget{command-function}{%
+\subsubsection{Command function}\label{command-function}}
+
+The \texttt{command} parameter can be either string template or
+function:
+
 \begin{verbatim}
-Make:add("text", "hello, input file: ${input}")
+Make:add("text", "echo hello, input file: ${input}")
 Make:add("function", function(params) 
   for k, v in pairs(params) do 
     print(k..": "..v) 
-  end
+  end, {custom="Hello world"}
 )
 \end{verbatim}
 
-\texttt{parameters} is a table or \texttt{nil} value.
+The template can get variable value from the parameters table using a
+\texttt{\$\{var\_name\}} placeholder. Templates are executed using
+operating system, so they should invoke existing OS commands. Function
+commands may execute system commands using \texttt{os.execute} function.
 
-Default parameters are:
+\hypertarget{parameters-table}{%
+\subsubsection{Parameters table}\label{parameters-table}}
 
+\texttt{parameters} parameter is optional, it can be table or
+\texttt{nil} value, which should be used if you want to use the
+\texttt{repetition} parameter, but don't want to modify the parameters
+table.
+
+The table with default parameters is passed to all commands, they can be
+accessed from command functions or templates. When you specify your own
+parameters in the command definition, these additional parameters are
+added to the default parameters table for this particular command. You
+can override the default parameters in the parameters table.
+
+The default parameters are following:
+
 \begin{description}
-\item[htlatex]
+\item[\texttt{htlatex}]
 used compiler
-\item[input]
+\item[\texttt{input}]
 it is output file name in fact
-\item[tex\_file]
+\item[\texttt{tex\_file}]
 input TeX file
-\item[latex\_par]
+\item[\texttt{latex\_par}]
 parameters to \texttt{latex}
-\item[packages]
-insert additionl LaTeX code which is inserted before
+\item[\texttt{packages}]
+insert additional LaTeX code which is inserted before
 \texttt{\textbackslash{}documentclass}. Useful for passing options to
 packages or additional packages loading
-\item[tex4ht\_sty\_par]
+\item[\texttt{tex4ht\_sty\_par}]
 parameters to \texttt{tex4ht.sty}
-\item[tex4ht\_par]
-parameters to \texttt{tex4ht} application
-\item[t4ht\_par]
-parameters to \texttt{t4ht} application
-\item[outdir]
-output directory
-\item[repetition]
+\item[\texttt{tex4ht\_par}]
+parameters to the \texttt{tex4ht} application
+\item[\texttt{t4ht\_par}]
+parameters to the \texttt{t4ht} application
+\item[\texttt{outdir}]
+the output directory
+\item[\texttt{repetition}]
 limit number of command execution.
-\item[correct\_exit]
-expected \texttt{exit code} from the command. The compilation will be
-terminted when the command \texttt{exit code} is different.
+\item[\texttt{correct\_exit}]
+expected \texttt{exit\ code} from the command. The compilation will be
+terminated if the command \texttt{exit\ code} is different.
 \end{description}
 
-You may add your own parameters, they will be accessible in templates
-and functions.
+\hypertarget{repetition}{%
+\subsubsection{Repetition}\label{repetition}}
 
-With \texttt{repetition}, you can limit number of command executions.
-Its value should be number or \texttt{nil}. This is used in the case of
-\texttt{tex4ht} and \texttt{t4ht} commands, as they should be executed
-only once and they would be executed multiple times if you include them
-in the build file, because they would be called also by
-\texttt{make4ht}. With \texttt{repetition}, second execution is blocked.
+Repetition is number which specifies a maximal number of executions of
+the particular command. This is used for instance for \texttt{tex4ht}
+and \texttt{t4ht} commands, as they should be executed only once in the
+compilation. They would be executed multiple times if you include them
+in the build file because they are called by \texttt{make4ht} by
+default. Because these commands allow only one \texttt{repetition}, the
+second execution will be blocked.
 
-You can set expected exit code from a command with
-\texttt{correct\_exit}. Compilation is stopped when command returns
-different exit code. The situation is different for LaTeX (for all TeX
-engines and formats, in fact), because it doesn't differentiate between
-fatal and non fatal errors, and it returns the same exit code in all
-cases. Log parsing is used because of that, error code \texttt{1} is
-returned in the case of fatal error, \texttt{0} is used otherwise.
+\hypertarget{expected-exit-code}{%
+\subsubsection{Expected exit code}\label{expected-exit-code}}
 
-\subsection{File matches}\label{file-matches}
+You can set the expected exit code from a command with a
+\texttt{correct\_exit} key in the parameters table. The compilation will
+be stopped when the command returns a different exit code.
 
-Other type of action which can be specified in the build file are
-matches which may be called on the generated files:
+This mechanism isn't used for LaTeX (for all TeX engines and formats, in
+fact), because it doesn't differentiate between fatal and non-fatal
+errors, and it returns the same exit code in all cases. Log parsing is
+used because of that, error code \texttt{1} is returned in the case of
+fatal error, \texttt{0} is used otherwise. The \texttt{Make.testlogfile}
+function can be used in the build file to detect compilation errors in
+the TeX log file.
 
+\hypertarget{file-matches}{%
+\subsection{File matches}\label{file-matches}}
+
+Another type of action which can be specified in the build file is
+\texttt{match}. It can be called on the generated files:
+
 \begin{verbatim}
 Make:match("html$", "tidy -m -xml -utf8 -q -i ${filename}")
 \end{verbatim}
 
-It tests filenames with \texttt{Lua} pattern matching and on matched
-items will execute command or function, specified in the second
-argument. For functions, two arguments are passed, first one is the
-current filename, the second one table with parameters. These parameters
-are the same as in previous section, except for \texttt{filename}, which
-contains generated output name.
+It tests output file names with \texttt{Lua} pattern matching and on
+matched items will execute a command or a function, specified in the
+second argument. Commands may be specified as strings, the templates
+will be expanded, \texttt{\$\{var\_name\}} placeholders will be replaced
+with corresponding variables from the \texttt{parameters} table,
+described in the previous subsection. One additional variable is
+available: \texttt{filename}. It contains the name of the current output
+file.
 
-\subsubsection{Filters}\label{filters}
+The above example will clean all output \texttt{HTML} files using the
+\texttt{tidy} command.
 
-Some default match actions which you can use are in the \texttt{filter}
-module. It contains some functions which ares useful for fixing some
-\texttt{tex4ht} bugs or shortcomings.
+If function is used instead, it will get two parameters. The first one
+is a current filename, the second one table with parameters.
 
+\hypertarget{filters}{%
+\subsubsection{Filters}\label{filters}}
+
+Some default \texttt{match} actions which can be used are available from
+the \texttt{make4ht-filter} module. It contains some functions which are
+useful for fixing some \texttt{tex4ht} bugs or shortcomings.
+
 Example:
 
 \begin{verbatim}
@@ -182,8 +359,10 @@
 Make:match("html$",process)
 \end{verbatim}
 
-Filter module is located in \texttt{make4ht-filter}. Function is
-returned, which is used for building filter chains then.
+The \texttt{make4ht-filter} module return a function which can be used
+for the filter chain building. Multiple filters can be chained, each of
+them can modify the string which was modified by the previous filters.
+The changes are then saved to the processed file.
 
 Built-in filters are:
 
@@ -201,73 +380,260 @@
 \item[entites]
 convert prohibited named entities to numeric entities (currently, only
 \texttt{\ }, as it causes validation errors, and \texttt{tex4ht} is
-producing it sometimes
+producing it sometimes)
 \item[fix-links]
 replace colons in local links and \texttt{id} attributes with
 underscores. Some cross-reference commands may produce colons in
 internal links, which results in validation error.
+\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[svg-height]
+some SVG images produced by \texttt{dvisvgm} seem to have wrong
+dimensions. This filter tries to set the correct image size.
 \end{description}
 
 Function \texttt{filter} accepts also function arguments, in this case
-this function takes file contents as parameter and modified contents are
-returned.
+this function takes file contents as a parameter and modified contents
+are returned.
 
 Example:
 
 \begin{verbatim}
-local filter  = require "make4ht-filter"                                    
+local filter  = require "make4ht-filter"
 local changea = function(s) return s:gsub("a","z") end
-local process = filter{"cleanspan", "fixligatures", changea}            
-Make:htlatex()                                                              
+local process = filter{"cleanspan", "fixligatures", changea}
 Make:htlatex()
-Make:match("html$",process) 
+Make:htlatex()
+Make:match("html$",process)
 \end{verbatim}
 
-In this case, spurious span elements are joined, ligatures are
+In this example, spurious span elements are joined, ligatures are
 decomposed, and then all letters `a' are replaced with `z' letters.
 
-\subsection{Image conversion}\label{image-conversion}
+\hypertarget{dom-filters}{%
+\subsubsection{DOM filters}\label{dom-filters}}
 
+DOM filters use the \href{https://ctan.org/pkg/luaxml}{\texttt{LuaXML}}
+library to modify directly the XML object. This enables more powerful
+operations than the regex based filters from the previous section.
+
+Example:
+
+\begin{verbatim}
+local domfilter = require "make4ht-domfilter"
+local process = domfilter {"joincharacters"}
+Make:match("html$", process)
+\end{verbatim}
+
+Available DOM filters:
+
+\begin{description}
+\item[aeneas]
+\href{https://www.readbeyond.it/aeneas/}{Aeneas} is a tool for
+automagical synchronization of text and audio. This filter modifies the
+HTML code to support the synchronization.
+\item[fixinlines]
+put all inline elements which are direct children of the
+\texttt{\textless{}body\textgreater{}} elements to a paragraph.
+\item[idcolons]
+replace the colon (\texttt{:}) character in internal links and
+\texttt{id} attributes. They cause validation issues.
+\item[joincharacters]
+join consecutive \texttt{\textless{}span\textgreater{}} or
+\texttt{\textless{}mn\textgreater{}} elements.
+\end{description}
+
+\hypertarget{make4ht-aeneas-config-package}{%
+\subsubsection{make4ht-aeneas-config
+package}\label{make4ht-aeneas-config-package}}
+
+Companion for the \texttt{aeneas} DOM filter is the
+\texttt{make4ht-aeneas-config} plugin. It can be used to write Aeneas
+configuration file or execute Aeneas on the generated HTML files.
+
+Available functions:
+
+\begin{description}
+\item[write\_job(parameters)]
+write Aenas job configuration to \texttt{config.xml} file. See the
+\href{https://www.readbeyond.it/aeneas/docs/clitutorial.html\#processing-jobs}{Aeneas
+documentation} for more information about jobs.
+\item[execute(parameters)]
+execute Aeneas.
+\item[process\_files(parameters)]
+process the audio and generated subtitle files.
+\end{description}
+
+By default, the \texttt{smil} file is created. It is assumed that there
+is audio file in \texttt{mp3} format named as the TeX file. It is
+possible to use different formats and file names using mapping.
+
+The configuration options can be passed directly to the functions or set
+using \texttt{filter\_settings\ "aeneas-config"\ \{parameters\}}
+function.
+
+Available parameters:
+
+\begin{description}
+\item[lang]
+document language. It is interfered from the HTML file, so it is not
+necessary to set it.
+\item[map]
+mapping between HTML, audio and subtitle files. More info bellow.
+\item[text\_type]
+type of the input. The \texttt{aeneas} DOM filter produces
+\texttt{unparsed} text type.
+\item[id\_sort]
+sorting of id attributes. Default value is \texttt{numeric}.
+\item[id\_regex]
+regular expression to parse the id attributes.
+\item[sub\_format]
+generated subtitle format. Default \texttt{smil}.
+\end{description}
+
+Additional parameters for the job configuration file:
+
+\begin{itemize}
+\tightlist
+\item
+  description
+\item
+  prefix
+\item
+  config\_name
+\item
+  keep\_config
+\end{itemize}
+
+It is possible to generate multiple HTML files from the LaTeX source.
+For example, \texttt{tex4ebook} generates separate file for each chapter
+or section. It is possible to set options for each HTML file, in
+particular names of the corresponding audio files. This mapping is done
+using \texttt{map} parameter.
+
+Example:
+
+\begin{verbatim}
+filter_settings "aeneas-config" {
+  map = {
+    ["sampleli1.html"] = {audio_file="sample.mp3"}, 
+    ["sample.html"] = false
+  }
+}
+\end{verbatim}
+
+Table keys are the configured file names. It is necessary to insert them
+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.
+
+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}.
+
+Available \texttt{map} options:
+
+\begin{description}
+\item[audio\_file]
+the corresponding audio file
+\item[sub\_file]
+name of the generated subtitle file
+\end{description}
+
+The following options are same as their counter-parts from the main
+parameters table and generally don't need to be set:
+
+\begin{itemize}
+\tightlist
+\item
+  prefix
+\item
+  file\_desc
+\item
+  file\_id
+\item
+  text\_type
+\item
+  id\_sort
+\item
+  id\_prefix
+\item
+  sub\_format
+\end{itemize}
+
+Full example:
+
+\begin{verbatim}
+local domfilter = require "make4ht-domfilter"
+local aeneas_config = require "make4ht-aeneas-config"
+
+filter_settings "aeneas-config" {
+  map = {
+    ["krecekli1.xhtml"] = {audio_file="krecek.mp3"}, 
+    ["krecek.xhtml"] = false
+  }
+}
+
+local process = domfilter {"aeneas"}
+Make:match("html$", process)
+
+if mode == "draft" then
+  aeneas_config.process_files {}
+else
+  aeneas_config.execute {}
+end
+\end{verbatim}
+
+\hypertarget{image-conversion}{%
+\subsection{Image conversion}\label{image-conversion}}
+
 It is possible to convert parts of LaTeX input to pictures, it is used
 for example for math or diagrams in \texttt{tex4ht}.
 
-These pictures are stored in special \texttt{dvi} file, on which
-\texttt{dvi to image} commands are called.
+These pictures are stored in a special \texttt{dvi} file, which can be
+processed by the \texttt{dvi\ to\ image} commands.
 
-This conversion is normally configured in the \texttt{env file}, which
+This conversion is normally configured in the \texttt{env\ file}, which
 is system dependent and which has a bit unintuitive syntax. This
-configuration is processed by \texttt{t4ht} application and conversion
-commands are called for all pictures.
+configuration is processed by the \texttt{t4ht} application and
+conversion commands are called for all pictures.
 
 It is possible to disable \texttt{t4ht} image processing and configure
-image conversion in the make file:
+image conversion in the build file:
 
 \begin{verbatim}
 Make:image("png$",
-"dvipng -bg Transparent -T tight -o ${output}  -pp ${page} ${source}")                                                       
+"dvipng -bg Transparent -T tight -o ${output}  -pp ${page} ${source}")
 \end{verbatim}
 
 \texttt{Make:image} takes two parameters, pattern to match image name
 and action. Action can be either string template with conversion
-command, or function which takes table with parameters as argument.
+command, or function which takes a table with parameters as an argument.
 
 There are three parameters:
 
 \begin{itemize}
-\itemsep1pt\parskip0pt\parsep0pt
+\tightlist
 \item
-  output - output image file name
+  \texttt{output} - output image file name
 \item
-  source - \texttt{dvi} file with the pictures
+  \texttt{source} - \texttt{dvi} file with the pictures
 \item
-  page - page number of the converted image
+  \texttt{page} - page number of the converted image
 \end{itemize}
 
-\subsection{The \texttt{mode} variable}\label{the-mode-variable}
+\hypertarget{the-mode-variable}{%
+\subsection{\texorpdfstring{The \texttt{mode}
+variable}{The mode variable}}\label{the-mode-variable}}
 
-The \texttt{mode} variable contains contents of \texttt{-{}-mode}
-command line option. It can be used to run some commands conditionally.
-For example:
+There is global \texttt{mode} variable available in the build file. It
+contains contents of the \texttt{-\/-mode} command line option. It can
+be used to run some commands conditionally. For example:
 
 \begin{verbatim}
  if mode == "draft" then
@@ -287,12 +653,14 @@
 make4ht -m draft filename
 \end{verbatim}
 
-\subsection{The \texttt{settings} table}\label{the-settings-table}
+\hypertarget{the-settings-table}{%
+\subsection{\texorpdfstring{The \texttt{settings}
+table}{The settings table}}\label{the-settings-table}}
 
 You may want to access to the parameters also outside commands, file
 matches and image conversion functions. For example, if you want to
-convert your file to the \texttt{OpenDocument Format}, you can use the
-following settings, based on \texttt{oolatex} command:
+convert your file to the \texttt{OpenDocument\ Format\ (ODT)}, you can
+use the following settings, based on the \texttt{oolatex} command:
 
 \begin{verbatim}
 settings.tex4ht_sty_par = settings.tex4ht_sty_par ..",ooffice"
@@ -300,9 +668,198 @@
 settings.t4ht_par = settings.t4ht_par .. " -cooxtpipes -coo "
 \end{verbatim}
 
-\section{Command line options}\label{command-line-options}
+There are some functions to ease access to the settings:
 
+\begin{description}
+\item[\texttt{set\_settings\{parameters\}}]
+overwrite settings with values from a passed table
+\item[\texttt{settings\_add\{parameters\}}]
+add values to the current settings
+\item[\texttt{filter\_settings\ "filter\ name"\ \{parameters\}}]
+set settings for a filter
+\item[\texttt{get\_filter\_settings(name)}]
+get settings for a filter
+\end{description}
+
+Using these functions, it is possible to simplify the settings for the
+\texttt{ODT} format:
+
 \begin{verbatim}
+settings_add {
+  tex4ht_sty_par =",ooffice",
+  tex4ht_par = " ooffice/! -cmozhtf",
+  t4ht_par = " -cooxtpipes -coo "
+}
+\end{verbatim}
+
+Settings for filters and extensions can be set using
+\texttt{filter\_settings}:
+
+\begin{verbatim}
+filter_settings "test" {
+  hello = "world"
+}
+\end{verbatim}
+
+These settings can be read in the extensions and filters using
+\texttt{get\_filter\_settings}:
+
+\begin{verbatim}
+function test(input)
+   local options = get_filter_settings("test")
+   print(options.hello)
+   return input
+end
+   
+\end{verbatim}
+
+\hypertarget{list-of-available-settings-for-filters-and-extensions.}{%
+\subsection{List of available settings for filters and
+extensions.}\label{list-of-available-settings-for-filters-and-extensions.}}
+
+These settings may be set using \texttt{filter\_settings} function.
+
+\hypertarget{the-tidy-extension}{%
+\subsubsection{\texorpdfstring{The \texttt{tidy}
+extension}{The tidy extension}}\label{the-tidy-extension}}
+
+\begin{description}
+\item[options]
+command line options for the \texttt{tidy} command. Default value is
+\texttt{-m\ -utf8\ -w\ 512\ -q}.
+\end{description}
+
+\hypertarget{the-fixinlines-dom-filter}{%
+\subsubsection{\texorpdfstring{The \texttt{fixinlines} dom
+filter}{The fixinlines dom filter}}\label{the-fixinlines-dom-filter}}
+
+\begin{description}
+\item[inline\_elements]
+table of inline elements which shouldn't be direct descendants of the
+\texttt{body} element. The element names should be table keys, the
+values should be true.
+\end{description}
+
+Example
+
+\begin{verbatim}
+filter_settings "fixinlines" {inline_elements = {a = true, b = true}}
+\end{verbatim}
+
+\hypertarget{the-joincharacters-dom-filter}{%
+\subsubsection{\texorpdfstring{The \texttt{joincharacters} dom
+filter}{The joincharacters dom filter}}\label{the-joincharacters-dom-filter}}
+
+\begin{description}
+\item[charelements]
+table of elements which should be joined if several instances with the
+same value of \texttt{class} attribute are side by side.
+\end{description}
+
+Example
+
+\begin{verbatim}
+filter_settings "joincharacters" { charclases = { span=true, mn = true}}
+\end{verbatim}
+
+\hypertarget{mathjaxsettings}{%
+\subsubsection{\texorpdfstring{The \texttt{mathjaxnode}
+filter}{The mathjaxnode filter}}\label{mathjaxsettings}}
+
+\begin{description}
+\item[options]
+command line options for the \texttt{mjpage} command. Default value is
+\texttt{-\/-output\ CommonHTML}
+\end{description}
+
+Example
+
+\begin{verbatim}
+filter_settings "mathjaxnode" {
+  options="--output SVG --font Neo-Euler"
+}
+\end{verbatim}
+
+\begin{description}
+\item[cssfilename]
+\texttt{mjpage} puts some CSS code into the HTML pages.
+\texttt{mathjaxnode} extracts this information and saves it to a
+standalone CSS file. Default CSS filename is \texttt{mathjax-chtml.css}
+\item[fontdir]
+directory with MathJax font files. This option enables use of local
+fonts, which is usefull in Epub conversion, for example. The font
+directory should be sub-directory of the current directory. Only TeX
+font is supported at the moment.
+\end{description}
+
+Example
+
+\begin{verbatim}
+filter_settings "mathjaxnode" {
+  fontdir="fonts/TeX/woff/" 
+}
+\end{verbatim}
+
+\hypertarget{the-aeneas-filter}{%
+\subsubsection{\texorpdfstring{The \texttt{aeneas}
+filter}{The aeneas filter}}\label{the-aeneas-filter}}
+
+\begin{description}
+\item[skip\_elements]
+List of CSS selectors that match elements which shouldn't be processed.
+Default value: \texttt{\{\ "math",\ "svg"\}}.
+\item[id\_prefix]
+prefix used in the ID attribute forming.
+\item[sentence\_match]
+Lua pattern used to match a sentence. Default value:
+\texttt{"({[}\^{}\%.\^{}\%?\^{}!{]}*)({[}\%.\%?!{]}?)"}.
+\end{description}
+
+\hypertarget{configfile}{%
+\section{Configuration file}\label{configfile}}
+
+It is possible to globally modify the build settings using the
+configuration file. New compilation commands can be added, extensions
+can be loaded or disabled and settings can be set.
+
+\hypertarget{location}{%
+\subsection{Location}\label{location}}
+
+The configuration file can be saved either in
+\texttt{\$HOME/.config/make4ht/config.lua} or in \texttt{.make4ht} in
+the current directory or it's parents (up to \texttt{\$HOME}).
+
+\hypertarget{additional-commands}{%
+\subsection{Additional commands}\label{additional-commands}}
+
+There are two additional commands:
+
+\begin{description}
+\item[\texttt{Make:enable\_extension(name)}]
+require extension
+\item[\texttt{Make:disable\_extension(name)}]
+disable extension
+\end{description}
+
+\hypertarget{example}{%
+\subsection{Example}\label{example}}
+
+The following configuration add support for the \texttt{biber} command,
+requires \texttt{common\_domfilters} extension and requires MathML
+output for math.
+
+\begin{verbatim}
+Make:add("biber", "biber ${input}")
+Make:enable_extension "common_domfilters"
+settings_add {
+  tex4ht_sty_par =",mathml"
+}
+\end{verbatim}
+
+\hypertarget{command-line-options}{%
+\section{Command line options}\label{command-line-options}}
+
+\begin{verbatim}
 make4ht - build system for tex4ht
 Usage:
 make4ht [options] filename ["tex4ht.sty op." "tex4ht op." 
@@ -313,6 +870,7 @@
 -d,--output-dir (default "")  Output directory
 -e,--build-file (default nil)  If build file name is different 
      than `filename`.mk4
+-f,--format  (default nil)  Output file format
 -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
@@ -323,20 +881,22 @@
 <filename> (string) Input file name
 \end{verbatim}
 
-You can still use \texttt{make4ht} in same way as \texttt{htlatex}
+You can still invoke \texttt{make4ht} in the same way as
+\texttt{htlatex}:
 
 \begin{verbatim}
-make4ht filename "customcfg, charset=utf-8" " -cunihtf -utf8" " -dfoo"
+make4ht filename "customcfg, charset=utf-8" "-cunihtf -utf8" "-dfoo"
 \end{verbatim}
 
-Note that this will not use \texttt{make4ht} routines for output dir
-making and copying If you want to use them, change the line above to:
+Note that this will not use \texttt{make4ht} routines for output
+directory making and copying. If you want to use them, change the line
+above to:
 
 \begin{verbatim}
-make4ht filename "customcfg, charset=utf-8" " -cunihtf -utf8"  -d foo
+make4ht -d foo filename "customcfg, charset=utf-8" "-cunihtf -utf8"
 \end{verbatim}
 
-This call has the same effect as following:
+This call has the same effect as the following:
 
 \begin{verbatim}
 make4ht -u -c customcfg -d foo filename
@@ -352,3 +912,47 @@
 make4ht -d ~/gotohomedir filename
 make4ht -d c:\documents\windowspathsareworkingtoo filename
 \end{verbatim}
+
+\hypertarget{troubleshooting}{%
+\section{Troubleshooting}\label{troubleshooting}}
+
+\hypertarget{incorrect-handling-of-command-line-arguments-for-tex4ht-t4ht-or-latex}{%
+\subsection{\texorpdfstring{Incorrect handling of command line arguments
+for \texttt{tex4ht}, \texttt{t4ht} or
+\texttt{latex}}{Incorrect handling of command line arguments for tex4ht, t4ht or latex}}\label{incorrect-handling-of-command-line-arguments-for-tex4ht-t4ht-or-latex}}
+
+Sometimes, you may get a similar error:
+
+\begin{verbatim}
+make4ht:unrecognized parameter: i
+\end{verbatim}
+
+It may be caused by a following \texttt{make4ht} invocation:
+
+\begin{verbatim}
+make4ht hello.tex "customcfg,charset=utf-8" "-cunihtf -utf8" -d foo
+\end{verbatim}
+
+The command line option parser is confused by mixing options for
+\texttt{make4ht} and \texttt{tex4ht} in this case and tries to interpret
+the \texttt{-cunihtf\ -utf8}, which are options for \texttt{tex4ht}
+command as \texttt{make4ht} options. To fix that, you can either move
+the \texttt{-d\ foo} directly after \texttt{make4ht} command:
+
+\begin{verbatim}
+make4ht -d foo hello.tex "customcfg,charset=utf-8" "-cunihtf -utf8"
+\end{verbatim}
+
+Another option is to add a space before \texttt{tex4ht} options:
+
+\begin{verbatim}
+make4ht hello.tex "customcfg,charset=utf-8" " -cunihtf -utf8" -d foo
+\end{verbatim}
+
+The former way is preferable, though.
+
+\hypertarget{license}{%
+\section{License}\label{license}}
+
+Permission is granted to copy, distribute and/or modify this software
+under the terms of the LaTeX Project Public License, version 1.3.

Added: trunk/Master/texmf-dist/scripts/make4ht/domfilters/make4ht-aeneas.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/make4ht/domfilters/make4ht-aeneas.lua	                        (rev 0)
+++ trunk/Master/texmf-dist/scripts/make4ht/domfilters/make4ht-aeneas.lua	2018-04-09 21:09:51 UTC (rev 47398)
@@ -0,0 +1,144 @@
+-- DOM filter for Aeneas, tool for automatical text and audio synchronization
+-- https://github.com/readbeyond/aeneas
+-- It adds elements with id attributes for text chunks, in sentence length.
+--
+--
+local cssquery = require "luaxml-cssquery"
+local mkutils  = require "mkutils"
+
+-- Table of CSS selectors to be skipped.
+local skip_elements = { "math", "svg"}
+
+-- The id attribute format is configurable
+-- Aeneas must be told to search for the ID pattern using is_text_unparsed_id_regex
+-- option in Aneas configuration file
+local id_prefix = "ast"
+
+-- Pattern to mach a sentence. It should match two groups, first is actual
+-- sentence, the second optional interpunction mark.
+local sentence_match = "([^%.^%?^!]*)([%.%?!]?)"
+
+-- convert table with selectors to a query list
+local function prepare_selectors(skips)
+  local css = cssquery()
+  for _, selector in ipairs(skips) do
+    css:add_selector(selector)
+  end
+  return css
+end
+
+-- save the HTML language 
+local function save_config(dom, saves)
+  local get_lang = function(d)
+    local html = d:query_selector("html")[1] or {}
+    return html:get_attribute("lang")
+  end
+  local saves = saves or {}
+  local config = get_filter_settings "aeneas_config"
+  if config.language then return end
+  saves.lang = get_lang(dom)
+  filter_settings "aeneas-config" (saves)
+end
+-- make span element with unique id for a sentence
+local function make_span(id,parent, text)
+  local newobj = parent:create_element("span", {id=id }) 
+  newobj.processed = true -- to disable multiple processing of the node
+  local text_node = newobj:create_text_node(text)
+  newobj:add_child_node(text_node)
+  return newobj
+end
+
+-- make the id attribute and update the id value
+local function make_id(lastid, id_prefix)
+  local id = id_prefix .. lastid
+  lastid = lastid + 1
+  return id, lastid
+end
+
+-- parse text for sentences and add spans 
+local function make_ids(parent, text, lastid, id_prefix)
+  local t = {}
+  local id
+  for chunk, punct in text:gmatch(sentence_match) do
+    id, lastid = make_id(lastid, id_prefix)
+    local newtext = chunk..punct
+    -- the newtext is empty string sometimes. we can skipt it then.
+    if newtext~="" then
+      table.insert(t, make_span(id, parent, newtext))
+    end
+  end
+  return t, lastid
+end
+
+
+
+-- test if the DOM element is in list of skipped CSS selectors
+local function is_skipped(el, css)
+  local matched = css:match_querylist(el)
+  return #matched > 0
+end
+
+local function aeneas(dom, par)
+  local par = par or {}
+  local id = 1
+  local options = get_filter_settings "aeneas"
+  local skip_elements = options.skip_elements or par.skip_elements or skip_elements
+  local id_prefix = options.id_prefix or par.id_prefix or id_prefix
+  local skip_object = prepare_selectors(skip_elements)
+  sentence_match = options.sentence_match or par.sentence_match or sentence_match
+
+  local body = dom:query_selector("body")[1]
+  -- process only the document body
+  if not body then return dom end
+  -- save information for aeneas_config
+  save_config(dom, {id_prefix = id_prefix})
+  body:traverse_elements(function(el)
+    -- skip disabled elements
+    if(is_skipped(el, skip_object)) then return false end
+    -- skip already processed elements
+    if el.processed then return false end
+    local newchildren = {} -- this will contain the new elements
+    local children = el:get_children()
+    local first_child = children[1]
+
+    -- if the element contains only text, doesn't already have an id attribute and the text is short,
+    -- the id is set directly on that element.
+    if #children == 1
+      and first_child:is_text()
+      and not el:get_attribute("id")
+      and string.len(first_child._text) < 20
+      and el._attr
+    then
+      local idtitle
+      idtitle, id = make_id(id, id_prefix)
+      print(el._name, first_child._text)
+      el:set_attribute("id", idtitle)
+      return el
+    end
+
+    for _, child in ipairs(children) do
+      -- process only non-empty text
+      if child:is_text() and child._text:match("%a+") then
+        local newnodes
+        newnodes, id = make_ids(child, child._text, id, id_prefix)
+        for _, node in ipairs(newnodes) do
+          table.insert(newchildren, node or {})
+        end
+      else
+        -- insert the current processing element to the new element list
+        -- if it isn't only text
+        table.insert(newchildren, child or {})
+      end
+    end
+    -- replace element children with the new ones
+    if #newchildren > 0 then
+      el._children = {}
+      for _, c in ipairs(newchildren) do
+        el:add_child_node(c)
+      end
+    end
+  end)
+  return dom
+end
+
+return aeneas


Property changes on: trunk/Master/texmf-dist/scripts/make4ht/domfilters/make4ht-aeneas.lua
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/scripts/make4ht/domfilters/make4ht-fixinlines.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/make4ht/domfilters/make4ht-fixinlines.lua	                        (rev 0)
+++ trunk/Master/texmf-dist/scripts/make4ht/domfilters/make4ht-fixinlines.lua	2018-04-09 21:09:51 UTC (rev 47398)
@@ -0,0 +1,57 @@
+local inline_elements = {
+  b=true,
+  big=true,
+  i=true,
+  small=true,
+  tt=true,
+  abbr=true,
+  acronym=true,
+  cite=true,
+  code=true,
+  dfn=true,
+  em=true,
+  kbd=true,
+  strong=true,
+  samp=true,
+  time=true,
+  var=true,
+  a=true,
+  bdo=true,
+  br=true,
+  img=true,
+  map=true,
+  object=true,
+  q=true,
+  script=true,
+  span=true,
+  sub=true,
+  sup=true,
+  button=true,
+  input=true,
+  label=true,
+  select=true,
+  textarea=true,
+  mn=true,
+  mi=true
+}
+
+
+local function fix_inlines(obj)
+  local settings = get_filter_settings "fixinlines"
+  local inline_elements = settings.inline_elements or inline_elements
+  local nodes = obj:get_path("html body")
+  obj:traverse_node_list(nodes, function(jej) 
+    if jej._type == "ELEMENT" then
+      local name = string.lower(jej._name)
+      -- local parent = jej:get_parent_node()
+      if inline_elements[name] then
+        local new = obj:create_element("p" )
+        new:add_child_node(obj:copy_node(jej))
+        jej:replace_node(new)
+      end
+    end
+  end)
+  return obj
+end
+
+return fix_inlines


Property changes on: trunk/Master/texmf-dist/scripts/make4ht/domfilters/make4ht-fixinlines.lua
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/scripts/make4ht/domfilters/make4ht-idcolons.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/make4ht/domfilters/make4ht-idcolons.lua	                        (rev 0)
+++ trunk/Master/texmf-dist/scripts/make4ht/domfilters/make4ht-idcolons.lua	2018-04-09 21:09:51 UTC (rev 47398)
@@ -0,0 +1,20 @@
+local function id_colons(obj)
+  -- replace : characters in links and ids with unserscores
+  obj:traverse_elements(function(el) 
+    local name = string.lower(obj:get_element_name(el))
+    if name == "a" then
+      local href = obj:get_attribute(el, "href")
+      if href and not href:match("[a-z]%://") then
+        obj:set_attribute(el, "href", href:gsub(":", "_"))
+      end
+    end
+    local id  = obj:get_attribute( el , "id")
+    if id then
+      obj:set_attribute(el, "id", id:gsub(":", "_"))
+    end
+    -- local id = obj:get_attribute(el, "id")
+  end)
+  return obj
+end
+
+return id_colons


Property changes on: trunk/Master/texmf-dist/scripts/make4ht/domfilters/make4ht-idcolons.lua
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/scripts/make4ht/domfilters/make4ht-joincharacters.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/make4ht/domfilters/make4ht-joincharacters.lua	                        (rev 0)
+++ trunk/Master/texmf-dist/scripts/make4ht/domfilters/make4ht-joincharacters.lua	2018-04-09 21:09:51 UTC (rev 47398)
@@ -0,0 +1,87 @@
+local charclases = {
+  span=true,
+  mn = true,
+}
+
+local function join_characters(obj,par)
+  -- join adjanced span and similar elements inserted by 
+  -- tex4ht to just one object.
+  local par = par or {}
+  local options = get_filter_settings "joincharacters"
+  local charclases = options.charclases or par.charclases or charclases
+
+  obj:traverse_elements(function(el)
+    local get_name = function(curr) 
+      return string.lower(curr:get_element_name())
+    end
+    local get_class = function(next_el)
+      return next_el:get_attribute("class")
+    end
+    local is_span = function(next_el)
+      return charclases[get_name(next_el)]
+    end
+
+    local function get_next(curr, class)
+      local next_el = curr:get_next_node()
+      if next_el and next_el:is_element() and is_span(next_el) then
+        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
+        -- match only text containing just whitespace
+        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
+    -- processed elements (charclases)
+    if is_span(el) then
+      local next_el = get_next(el)
+      -- loop over the following elements and test whether they are of the same type
+      -- as the current one
+      while  next_el do
+        -- save the next element because we will remove it later
+        local real_next = get_next(next_el)
+        if get_name(el) == get_name(next_el) and get_class(el) == get_class(next_el) and not el:get_attribute("id") then
+          -- it the following element match, copy it's children to the current element
+          for _, child in ipairs(next_el:get_children()) do
+            el:add_child_node(child)
+          end
+          -- remove the next element
+          next_el:remove_node()
+          -- 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()
+          real_next = nil
+        else
+          real_next = nil
+        end
+        -- use the saved element as a next object
+        next_el = real_next
+      end
+    end
+
+  end)
+  -- join text nodes in an element into one
+  obj:traverse_elements(function(el)
+    -- save the text
+    local t = {}
+    local children = el:get_children()
+    for _, x in ipairs(children) do
+      if x:is_text() then
+        t[#t+1] = x._text
+      else
+        return nil
+      end
+    end
+    el._text = table.concat(t)
+    return el
+  end)
+  return obj
+end
+
+return join_characters


Property changes on: trunk/Master/texmf-dist/scripts/make4ht/domfilters/make4ht-joincharacters.lua
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/scripts/make4ht/filters/make4ht-domfilter.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/make4ht/filters/make4ht-domfilter.lua	                        (rev 0)
+++ trunk/Master/texmf-dist/scripts/make4ht/filters/make4ht-domfilter.lua	2018-04-09 21:09:51 UTC (rev 47398)
@@ -0,0 +1,63 @@
+local filter_lib = require "make4ht-filterlib"
+local dom    = require "luaxml-domobject"
+local mkutils    = require "mkutils"
+
+local function load_filter(filtername)
+	return require("domfilters.make4ht-"..filtername)
+end
+
+-- save processed names, in order to block multiple executions of the filter
+-- sequence on a same file
+local processed = {}
+
+local function filter(filters, name)
+  -- because XML parsing to DOM is potentially expensive operation
+  -- this filter will use cache for it's sequence
+  -- all requests to the domfilter will add new filters to the
+  -- one sequence, which will be executed on one DOM object.
+  -- it is possible to request a different sequence using
+  -- unique name parameter
+  local name = name or "domfilter"
+  local settings = mkutils.get_filter_settings(name) or {}
+  local sequence = settings.sequence or {}
+  local local_sequence = filter_lib.load_filters(filters, load_filter)
+  for _, filter in ipairs(local_sequence) do
+    table.insert(sequence, filter)
+  end
+  settings.sequence = sequence
+  mkutils.filter_settings (name) (settings)
+
+	return function(filename, parameters)
+    -- load processed files for the current filter name
+    local processed_files = processed[name] or {}
+    -- don't process the file again
+    if processed_files[filename] then
+      return nil
+    end
+    local input = filter_lib.load_input_file(filename)
+    if not input  then return nil, "Cannot load the input file" end
+    -- we need to use pcall, because XML error would break the whole build process
+    -- domobject will be error object if DOM parsing failed
+    local status, domobject = pcall(function()
+      return dom.parse(input)
+    end)
+    if not status then
+      print("DOM parsing of " .. filename .. " failed:")
+      print(domobject)
+      return nil, "DOM parsing failed"
+    end
+		for _,f in pairs(sequence) do
+			domobject = f(domobject,parameters)
+		end
+    local output = domobject:serialize()
+    if output then
+      filter_lib.save_input_file(filename, output)
+    else
+      print("DOM filter failed on ".. filename)
+    end
+    -- mark the filename as processed
+    processed_files[filename] = true
+    processed[name] = processed_files
+	end
+end
+return filter


Property changes on: trunk/Master/texmf-dist/scripts/make4ht/filters/make4ht-domfilter.lua
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/scripts/make4ht/filters/make4ht-filter.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/make4ht/filters/make4ht-filter.lua	2018-04-09 21:09:18 UTC (rev 47397)
+++ trunk/Master/texmf-dist/scripts/make4ht/filters/make4ht-filter.lua	2018-04-09 21:09:51 UTC (rev 47398)
@@ -1,41 +1,19 @@
-local filters = {}
+local filter_lib = require "make4ht-filterlib"
 
 local function load_filter(filtername)
 	return require("filters.make4ht-"..filtername)
 end
 
-function filter(filters)
-	local sequence = {}
-	if type(filters) == "string" then
-		table.insert(sequence,load_filter(filters))
-	elseif type(filters) == "table" then
-		for _,n in pairs(filters) do
-			if type(n) == "string" then
-				table.insert(sequence,load_filter(n))
-			elseif type(n) == "function" then
-				table.insert(sequence, n)
-			end
-		end
-	elseif type(filters) == "function" then
-		table.insert(sequence, filters)
-	else
-		return false, "Argument to filter must be either\ntable with filter names, or single filter name"
-	end
+function filter(filters,parameters)
+  local sequence = filter_lib.load_filters(filters, load_filter)
 	return function(filename)
 		if not filename then return false, "filters: no filename" end
-		local input = nil
-
-		if filename then
-			local file = io.open(filename,"r")
-			input = file:read("*all")
-			file:close()
-		end
+    local input = filter_lib.load_input_file(filename)
+    if not input  then return nil, "Cannot load the input file" end
 		for _,f in pairs(sequence) do
-			input = f(input)
+			input = f(input,parameters)
 		end
-		local file = io.open(filename,"w")
-		file:write(input)
-		file:close()
+    filter_lib.save_input_file(filename, input)
 	end
 end
 return filter

Added: trunk/Master/texmf-dist/scripts/make4ht/filters/make4ht-mathjaxnode.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/make4ht/filters/make4ht-mathjaxnode.lua	                        (rev 0)
+++ trunk/Master/texmf-dist/scripts/make4ht/filters/make4ht-mathjaxnode.lua	2018-04-09 21:09:51 UTC (rev 47398)
@@ -0,0 +1,94 @@
+local mkutils = require "mkutils"
+-- other possible value is page2svg
+local mathnodepath = "mjpage"
+-- options for MathJax command
+local options = "--output CommonHTML"
+-- math fonts position
+-- don't alter fonts if not set
+local fontdir = nil
+-- if we copy fonts 
+local fontdest = nil
+local fontformat = "woff"
+local cssfilename =  "mathjax-chtml.css"
+
+local function compile(text)
+  local tmpfile = os.tmpname()
+  print("Compile using MathJax")
+  local command =  mathnodepath .. " ".. options .. " > " .. tmpfile
+  print(command)
+  local commandhandle = io.popen(command,"w") 
+  commandhandle:write(text)
+  commandhandle:close()
+  print("Result written to: ".. tmpfile)
+  local f = io.open(tmpfile)
+  local content = f:read("*all")
+  f:close()
+  os.remove(tmpfile)
+  return content
+end
+
+-- save the css code from the html page generated by MathJax
+local function extract_css(contents)
+  local css = ""
+  local filename = cssfilename
+  contents = contents:gsub('<style [^>]+>(.-)</style>', function(style)
+    -- replace only the style for mathjax
+    if style:match "%.mjx%-math" then
+      css = style
+      return '<link rel="stylesheet" type="text/css" href="'..filename ..'" />'
+    end
+  end)
+  -- local x = assert(io.open(file, "w"))
+  -- x:write(contents)
+  -- x:close()
+  return filename, contents, css
+end
+
+-- Update the paths to fonts to use the local versions
+local function use_fonts(css)
+  local family_pattern = "font%-family:%s*(.-);.-%/([^%/]+)%.".. fontformat
+  local family_build = "@font-face {font-family: %s; src: url('%s/%s.%s') format('%s')}"
+  local fontdir = fontdir:gsub("/$","")
+  css = css:gsub("(@font%-face%s*{.-})", function(face)
+    if not face:match("url%(") then return face end
+    -- print(face)
+    local family, filename = face:match(family_pattern)
+    print(family, filename)
+    local newfile = string.format("%s/%s.%s", fontdir, filename, fontformat)
+    Make:add_file(newfile)
+    return family_build:format(family, fontdir, filename, fontformat, fontformat)
+    -- return face
+  end)
+  return css
+end
+
+
+local function save_css(filename, css)
+  local f = io.open(filename, "w")
+  f:write(css)
+  f:close()
+end
+
+return function(text, arguments)
+  -- if arguments.prg then mathnodepath = arguments.prg end
+  local extoptions = mkutils.get_filter_settings "mathjaxnode" or {}
+  local arguments = arguments or {}
+  mathnodepath = arguments.prg or extoptions.prg or  mathnodepath
+  options      = arguments.options or extoptions.options or options
+  fontdir      = arguments.fontdir or extoptions.fontdir or fontdir
+  -- the following ne is unused ATM
+  fontdest     = arguments.fontdest or extoptions.fontdest or fontdest
+  fontformat   = arguments.fontformat or extoptions.fontformat or fontformat
+  cssfilename  = arguments.cssfilename or extoptions.cssfilename or cssfilename
+  local newtext = compile(text)
+  local cssfile, newtext,  css = extract_css(newtext)
+  -- use local font files if fontdir is present
+  if fontdir then
+    css = use_fonts(css)
+  end
+  save_css(cssfile, css)
+  Make:add_file(cssfile)
+  -- print(css)
+  print(cssfile)
+  return newtext
+end


Property changes on: trunk/Master/texmf-dist/scripts/make4ht/filters/make4ht-mathjaxnode.lua
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/scripts/make4ht/filters/make4ht-svg-height.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/make4ht/filters/make4ht-svg-height.lua	                        (rev 0)
+++ trunk/Master/texmf-dist/scripts/make4ht/filters/make4ht-svg-height.lua	2018-04-09 21:09:51 UTC (rev 47398)
@@ -0,0 +1,43 @@
+
+-- Make:image("svg$", "dvisvgm -n -a -p ${page} -b preview -c 1.4,1.4 -s ${source} > ${output}")
+
+local max = function(a,b)
+  return a > b and a or b
+end
+
+local function get_height(svg)
+  local height = svg:match("height='([0-9%.]+)pt'")
+  return tonumber(height)
+end
+
+local function get_max_height(path,max_number)
+  local coordinates = {}
+  for number in path:gmatch("(%-?[0-9%.]+)") do
+    table.insert(coordinates, tonumber(number))
+  end
+  for i = 2, #coordinates, 2 do
+    max_number = max(max_number, coordinates[i])
+  end
+  return max_number
+end
+
+local function update_height(svg, height)
+  return svg:gsub("height='.-pt'", "height='"..height .."pt'")
+end
+
+-- we need to fix the svg height
+return function(svg)
+  local max_height = 0
+  local height = get_height(svg)
+  for path in svg:gmatch("path d='([^']+)'") do
+    -- find highest height in all paths in the svg file
+    max_height = get_max_height(path, max_height)
+  end
+  -- update the height only if the max_height is larger than height set in the SVG file
+  print(max_height, height)
+  if max_height > height then
+    svg = update_height(svg, max_height)
+  end
+  return svg
+end
+


Property changes on: trunk/Master/texmf-dist/scripts/make4ht/filters/make4ht-svg-height.lua
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/scripts/make4ht/make4ht
===================================================================
--- trunk/Master/texmf-dist/scripts/make4ht/make4ht	2018-04-09 21:09:18 UTC (rev 47397)
+++ trunk/Master/texmf-dist/scripts/make4ht/make4ht	2018-04-09 21:09:51 UTC (rev 47398)
@@ -9,6 +9,7 @@
 local lapp    = require("lapp-mk4")
 local mkutils = require("mkutils")
 local mkparams = require("mkparams")
+local mk_config = require("make4ht-config")
 -- args string is here just as sample, we dont pass it it to 
 -- mkparams.get_args() so default args string is used
 local args    =  [[
@@ -26,7 +27,7 @@
 
 -- set version number. the template should be replaced by the
 -- actual version number by the build script
-local version = "v0.1c"
+local version = "v0.2"
 mkparams.version_number = version
 
 local args = mkparams.get_args()
@@ -36,6 +37,35 @@
 local mode = parameters.mode
 local build_file = parameters.build_file 
 
+-- handle output formats
+local allowed_output_formats = {xhtml = true, html5=true, odt = true}
+-- formatter is Lua library which must provide at least prepare_parameters
+-- and process_build_sequence functions
+local formatter
+local output_format = parameters.output_format
+if allowed_output_formats[ output_format ] then
+  formatter = mkutils.load_output_format(output_format)
+else
+  -- load html5 as default output format
+  if output_format then 
+    print("Cannot load output format: ".. output_format)
+  end
+  formatter = mkutils.load_output_format("html5")
+end
+-- find make4ht configuration file
+local configname = "make4ht"
+local conffile = mk_config.find_config(configname) or mk_config.find_xdg_config(configname)
+if conffile then
+  print("Using configuration file: " .. conffile)
+  mkutils.load_config(parameters, conffile)
+end
+local extensions = formatter.prepare_extensions(parameters.extensions)
+extensions = mkutils.load_extensions(extensions, output_format)
+
+
+
+-- run extensions with prepare_parameters function
+parameters = formatter.prepare_parameters(parameters,extensions)
 local make = mkutils.load_config(parameters, build_file)["Make"]
 make.params = parameters
 if make:length() < 1 then
@@ -58,6 +88,10 @@
   make.params.t4ht_par = make.params.t4ht_par .. " -p"
 end
 make:t4ht {ext = ext}
+-- run extensions which modify the build sequence
+if #extensions > 0 then
+  make = mkutils.extensions_modify_build(extensions, make)
+end
 make:match("tmp$", function() return false,"tmp file" end)
 make:match(".*",function(filename,par)
 	local outdir =  '' --par["outdir"] and par["outdir"] .."/" or ''
@@ -67,4 +101,5 @@
 	mkutils.copy(filename,outfilename)
 	return true
 end)
+
 make:run()

Added: trunk/Master/texmf-dist/scripts/make4ht/make4ht-aeneas-config.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/make4ht/make4ht-aeneas-config.lua	                        (rev 0)
+++ trunk/Master/texmf-dist/scripts/make4ht/make4ht-aeneas-config.lua	2018-04-09 21:09:51 UTC (rev 47398)
@@ -0,0 +1,215 @@
+local M = {}
+
+local mkutils = require "mkutils"
+
+local task_template = [[
+<task>
+    <task_language>${lang}</task_language>
+    <task_description>${file_desc}</task_description>
+    <task_custom_id>${file_id}</task_custom_id>
+    <is_text_file>${prefix}${html_file}</is_text_file>
+    <is_text_type>${text_type}</is_text_type>
+    <is_audio_file>${prefix}${audio_file}</is_audio_file>
+    <is_text_unparsed_id_sort>${id_sort}</is_text_unparsed_id_sort>
+    <is_text_unparsed_id_regex>${id_regex}</is_text_unparsed_id_regex>
+    <os_task_file_name>${sub_file}</os_task_file_name>
+    <os_task_file_format>${sub_format}</os_task_file_format>
+    <os_task_file_smil_page_ref>${html_file}</os_task_file_smil_page_ref>
+    <os_task_file_smil_audio_ref>${audio_file}</os_task_file_smil_audio_ref>
+</task>
+]]
+
+-- get html files
+local function get_html_files(config)
+  local config = config or {}
+  local files = {}
+  local filematch = config.file_match or  "html$"
+  -- this is a trick to get list of files from the LG file
+  for _, file in ipairs(Make.lgfile.files) do
+    if file:match(filematch) then table.insert(files, file) end
+  end
+  return files
+end
+
+-- prepare filename for the audio
+local function get_audio_file(filename, config)
+  local extension = config.audio_extension or "mp3"
+  local base = mkutils.remove_extension(filename)
+  return base .. "." .. extension
+end
+
+local function get_sub_file(filename, config)
+  local extension = config.sub_format or "smil"
+  local base = mkutils.remove_extension(filename)
+  return base .. "." .. extension
+end
+
+
+-- create task record for each HTML file
+local function prepare_tasks(files, configuration)
+  local tasks = {}
+  --  the map can contain info for particular files, otherwise we will interfere default values
+  local map = configuration.map or {}
+  -- task_template should be configurable
+  local task_template = configuration.task_template or task_template
+  for i, filename in ipairs(files) do
+    local filemap = map[filename] 
+    if filemap ~= false then
+      filemap = filemap or {}
+      local taskconfig = configuration
+      taskconfig.html_file = filename
+      taskconfig.prefix = filemap.prefix or configuration.prefix
+      taskconfig.file_desc = filemap.description or configuration.description .. " " .. i
+      taskconfig.file_id = filemap.id or filename:gsub("[%/%.]", "_")
+      taskconfig.text_type = filemap.text_type or configuration.text_type
+      taskconfig.audio_file = filemap.audio_file or get_audio_file(filename, configuration)
+      taskconfig.sub_file = filemap.sub_file or get_sub_file(filename, configuration)
+      taskconfig.id_sort= filemap.id_sort  or configuration.id_sort
+      taskconfig.id_prefix = filemap.id_regex or configuration.id_regex
+      taskconfig.sub_format = filemap.sub_format or configuration.sub_format
+      tasks[#tasks+1] = task_template % taskconfig
+      Make:add_file(taskconfig.audio_file)
+      Make:add_file(taskconfig.sub_file)
+    end
+  end
+  return tasks --table.concat(tasks, "\n")
+end
+-- from https://www.readbeyond.it/aeneas/docs/clitutorial.html#xml-config-file-config-xml
+local config_template = [[
+<job>
+    <job_language>${lang}</job_language>
+    <job_description>${description}</job_description>
+    <tasks>
+    ${tasks}
+    </tasks>
+    <os_job_file_name>output_example4</os_job_file_name>
+    <os_job_file_container>zip</os_job_file_container>
+    <os_job_file_hierarchy_type>flat</os_job_file_hierarchy_type>
+    <os_job_file_hierarchy_prefix>${prefix}</os_job_file_hierarchy_prefix>
+</job>
+]]
+
+-- check if the config file exists
+local function is_config(filename)
+  return mkutils.file_exists(filename)
+end
+
+-- prepare Aeneas configuration
+local function prepare_configuration(parameters)
+  local config = parameters or {}
+  config.lang = parameters.lang 
+  config.tasks = table.concat(prepare_tasks(parameters.files, config), "\n")
+  return config
+end
+
+-- write Aeneeas configuration file in the XML format
+local function write_config(filename, configuration)
+  local cfg = config_template % configuration
+  print(cfg)
+  local f = io.open(filename, "w")
+  f:write(cfg)
+  f:close()
+end
+
+
+local function make_default_options(options)
+  local configuration = {}
+  local par = get_filter_settings "aeneas-config"
+  configuration.lang = options.lang or par.lang or "en"
+  configuration.description = options.description or par.description or "Aeneas job"
+  configuration.map = options.map or par.map or {}
+  configuration.text_type = options.text_type or par.text_type or "unparsed"
+  configuration.id_sort = options.id_sort or par.id_sort or "numeric"
+  configuration.id_regex = options.id_regex or par.id_regex or par.id_prefix .. "[0-9]+"
+  configuration.sub_format = options.sub_format or par.sub_format or "smil"
+  configuration.prefix = options.prefix or par.prefix or "./"
+  configuration.config_name = options.config_name or par.config_name or "config.xml"
+  configuration.keep_config = options.keep_config or par.keep_config
+  return configuration
+end
+
+
+local function configure_job(options)
+  local configuration = make_default_options(options)
+  local config_name = configuration.config_name
+  -- prepare the configuration in every case
+  configuration.files = get_html_files()
+  local configuration = prepare_configuration(configuration)
+  -- write the configuration only if the config file doesn't exist
+  -- and keep_config option is set to true
+  if is_config(config_name) and configuration.keep_config==true then
+  else
+    write_config(config_name, configuration)
+  end
+end
+
+local function execute_job(options)
+  local par = get_filter_settings "aeneas-config"
+  local configuration = make_default_options(options)
+  configuration.files = get_html_files()
+  -- we need to configure prepare_tasks to return calls to aeneas task convertor
+  configuration.python = options.python or par.python or "python3"
+  configuration.module = options.module or par.module or "aeneas.tools.execute_task"
+  configuration.task_template = '${python} -m "${module}" "${audio_file}" "${html_file}" "is_text_type=${text_type}|os_task_file_smil_audio_ref=${audio_file}|os_task_file_smil_page_ref=${html_file}|task_language=${lang}|is_text_unparsed_id_sort=${id_sort}|is_text_unparsed_id_regex=${id_regex}|os_task_file_format=${sub_format}" "${sub_file}"'
+  local tasks = prepare_tasks(configuration.files, configuration)
+  -- execute the tasks
+  for _, v in ipairs(tasks) do
+    print("task", v)
+    local proc = io.popen(v, "r")
+    local result = proc:read("*all")
+    proc:close()
+    print(result)
+  end
+end
+
+-- the aeneas configuration must be executed at last processed file, after all filters
+-- have been executed
+local function get_last_lg_file()
+  local t = Make.lgfile.files
+  for i = #t, 1, -1 do
+    --  find last html file or the tmp file
+    local x = t[i]
+    if x:match "html$" or x:match "tmp$" then 
+      return x 
+    end
+  end
+  return t[#t]
+end
+
+-- write Aeneas job configuration file
+-- it doesn't execute Aeneas
+function M.write_job(par)
+  -- configuration table for Aeneas job
+  Make:match("tmp$", function()
+    configure_job(par)
+  end)
+end
+
+-- execute Aeneas directly
+function M.execute(par)
+  Make:match("tmp$", function(current_name)
+    -- there may be html files after the .tmp file
+    -- the aeneas must be executed after the Aeneas filter inserts the id
+    -- attributes, so it is necessary to execute this code as very last one
+    local last = get_last_lg_file()
+    -- execute the job if there are no HTML files after the tmp file
+    if current_name == last then
+      execute_job(par)
+    end
+    Make:match(last, function()
+      execute_job(par)
+    end)
+  end)
+end
+
+-- only register the audio and smil files as processed files
+function M.process_files(par)
+  Make:match("tmp$", function()
+    local configuration = make_default_options(par)
+    local files = get_html_files()
+    prepare_tasks(files, configuration)
+  end)
+end
+
+
+return M


Property changes on: trunk/Master/texmf-dist/scripts/make4ht/make4ht-aeneas-config.lua
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: trunk/Master/texmf-dist/scripts/make4ht/make4ht-config.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/make4ht/make4ht-config.lua	                        (rev 0)
+++ trunk/Master/texmf-dist/scripts/make4ht/make4ht-config.lua	2018-04-09 21:09:51 UTC (rev 47398)
@@ -0,0 +1,92 @@
+local m = {}
+
+local mkutils = require "mkutils"
+
+local file_exists = mkutils.file_exists
+-- function file_exists(name)
+-- 	local f=io.open(name,"r")
+-- 	if f~=nil then io.close(f) return true else return false end
+-- end
+
+
+local make_name = function(name)
+  return table.concat(name, "/")
+  -- return name:gsub("//","/")
+end
+
+-- find the config file in XDG_CONFIG_HOME  or in the HOME directry
+-- the XDG tree is looked up first, the $HOME is used only when it cannot be
+-- find in the former
+local xdg_config  = function(filename, xdg_config_name)
+  local dotfilename = "." .. filename
+  local xdg_config_name = xdg_config_name or "config.lua"
+  local xdg = os.getenv("XDG_CONFIG_HOME") or ((os.getenv("HOME") or "") ..  "/.config")
+  local home = os.getenv("HOME")
+  if xdg then
+    -- filename like ~/.config/make4ht/config.lua
+    local fn = make_name{ xdg ,filename , xdg_config_name }
+    if file_exists(fn) then
+      return fn
+    end
+  end
+  if home then
+    -- ~/.make4ht
+    local fn = make_name{ home, dotfilename }
+    if file_exists(fn) then
+      return fn
+    end
+  end
+end
+
+local find_config = function(filename)
+  local filename = "." .. filename
+	local current =  lfs.currentdir()
+	local path = {}
+	current:gsub("([^/]+)", function(s) table.insert(path,s) end)
+	local begin = os.type == "windows" and "" or "/"
+	for i = #path, 1, -1 do
+		local fn =begin .. table.concat(path,"/") .. "/".. filename
+		-- print("testing",fn)
+		if file_exists(fn) then return fn end
+		table.remove(path)
+	end
+	return false
+end
+
+local function load_config(filename, default)
+  local default = default or {}
+  default.table = table
+  default.string = string
+  default.io = io
+  default.os = os
+  default.math = math
+  default.print = print
+  default.ipairs = ipairs
+  default.pairs = pairs
+  local f = io.open(filename, "r")
+  local contents = f:read("*all")
+  f:close()
+  load(contents,"sandbox config","bt", default)()
+  return default
+end
+
+--[[
+local function load_config(filename, default)
+	local default = default or {}
+	if ~file_exists(filename) then 
+		return nil, "Cannot load config file "..filename 
+	end
+	local section = "default"
+	local file  = io.open(filename,  "r")
+	if ~file then return nil, "Error opening config file"..filename end
+	for line in file:lines() do
+		local ts = line:match("")
+	end
+	file:close()
+end
+--]]
+
+m.find_config     = find_config
+m.find_xdg_config = xdg_config
+m.load_config     = load_config
+return m


Property changes on: trunk/Master/texmf-dist/scripts/make4ht/make4ht-config.lua
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Deleted: trunk/Master/texmf-dist/scripts/make4ht/make4ht-dom.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/make4ht/make4ht-dom.lua	2018-04-09 21:09:18 UTC (rev 47397)
+++ trunk/Master/texmf-dist/scripts/make4ht/make4ht-dom.lua	2018-04-09 21:09:51 UTC (rev 47398)
@@ -1,448 +0,0 @@
---- DOM module for LuaXML
--- @module make4ht-dom
-local dom = {}
-local xml = require("luaxml-mod-xml")
-local handler = require("luaxml-mod-handler")
-local query = require("make4ht-parse-query")
-
-
-local void = {area = true, base = true, br = true, col = true, hr = true, img = true, input = true, link = true, meta = true, param = true}
-
-local actions = {
-  TEXT = {text = "%s"},
-  COMMENT = {start = "<!-- ", text = "%s", stop = " -->"},
-  ELEMENT = {start = "<%s%s>", stop = "</%s>", void = "<%s%s />"},
-  DECL = {start = "<?%s %s?>"},
-  DTD = {start = "<!DOCTYPE ", text = "%s" , stop=">"}
-}
-
---- It serializes the DOM object back to XML 
--- @function serialize_dom
--- @param parser DOM object
--- @param current 
--- @param level
--- @param output
--- @return table
-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, v)
-    end
-    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)
-    local format = get_action(typ, "text")
-    insert(format, text)
-  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"],  attributes._name, attributes._uri )
-    attributes = {}
-  elseif xtype == "ELEMENT" and void[name] then
-    local format = get_action(xtype, "void")
-    insert(format, name, prepare_attributes(attributes))
-    return output
-  end
-
-  start(xtype, name, attributes)
-  text(xtype,text_content) 
-  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
-
-local parse = function(x)
-  local domHandler = handler.domHandler()
-  local Parser = xml.xmlParser(domHandler)
-  -- preserve whitespace
-  Parser.options.stripWS = nil
-  Parser:parse(x)
-  Parser.current = Parser._handler.root
-  Parser.__index = Parser
-
-  local function save_methods(element)
-    setmetatable(element,Parser)
-    local children = element._children or {}
-    for _, x in ipairs(children) do
-      save_methods(x)
-    end
-  end
-  local parser = setmetatable({}, Parser)
-
-  --- @class Parser
-  function Parser.root_node(self)
-    return self._handler.root
-  end
-
-
-  function Parser.get_element_type(self, el)
-    local el = el or self
-    return el._type
-  end
-  function Parser.is_element(self, el)
-    local el = el or self
-    return self:get_element_type(el) == "ELEMENT" 
-  end
-
-  function Parser.is_text(self, el)
-    local el = el or self
-    return self:get_element_type(el) == "TEXT"
-  end
-
-  local lower = string.lower
-
-  function Parser.get_element_name(self, el)
-    local el = el or self
-    return el._name or "unnamed"
-  end
-
-  function Parser.get_attribute(self, name)
-    local el = self
-    if self:is_element(el) then
-      local attr = el._attr or {}
-      return attr[name]
-    end
-  end
-
-  function Parser.set_attribute(self, name, value)
-    local el = self
-    if self:is_element(el) then
-      el._attr[name] = value
-      return true
-    end
-  end
-  
-
-  function Parser.serialize(self, current)
-    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
-
-  function Parser.get_path(self,path, current)
-    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
-
-  function Parser.calculate_specificity(self, query)
-    local query = query or {}
-    local specificity = 0
-    for _, item in ipairs(query.query or {}) do
-      for key, value in pairs(item) do
-        if key == "id" then
-          specificity = specificity + 100
-        elseif key == "tag" then
-          specificity = specificity + 1
-        else
-          specificity = specificity + 10
-        end
-      end
-    end
-    return specificity
-  end
-
-  function Parser.match_querylist(self, querylist)
-    local matches = {}
-    local querylist = querylist
-
-    local function test_part(key, value, el)
-      -- print("testing", key, value, el:get_element_name())
-      if key == "tag" then 
-        return el:get_element_name() == value
-      elseif key == "id" then
-        local id = el:get_attribute "id"
-        return id and id == value
-      elseif key == "class" then 
-        local class = el:get_attribute "class"
-        if not class then return false end
-        local c = {}
-        for part in class:gmatch "([^%s]+)" do
-          c[part] = true
-        end
-        return c[value] == true
-      end
-      -- TODO: Add more cases
-      -- just return true for not supported selectors
-      return true
-    end
-
-    local function test_object(query, el)
-      -- test one object in CSS selector
-      local matched = {}
-      for key, value in pairs(query) do
-        matched[#matched+1] = test_part(key, value, el)
-      end
-      if #matched == 0 then return false end
-      for k, v in ipairs(matched) do
-        if v ~= true then return false end
-      end
-      return true
-    end
-        
-    local function match_query(query, el)
-      local query = query or {}
-      local object = table.remove(query) -- get current object from the query stack
-      if not object then return true end -- if the query stack is empty, then we can be sure that it matched previous items
-      if not el:is_element() then return false end -- if there is object to test, but current node isn't element, test failed
-      local result = test_object(object, el)
-      if result then
-        return match_query(query, el:get_parent())
-      end
-      return false
-    end
-    for _,element in ipairs(querylist) do
-      local query =  {}
-      for k,v in ipairs(element.query) do query[k] = v end
-      if #query > 0 then -- don't try to match empty query
-        local result = match_query(query, self)
-        if result then matches[#matches+1] = element end
-      end
-    end
-    return matches
-  end
-
-  function Parser.get_selector_path(self, selectorlist)
-    local nodelist = {}
-    self:traverse_elements(function(el)
-      local matches = el:match_querylist(selectorlist)
-      print("Matching", el:get_element_name(), #matches)
-      if #matches > 0 then nodelist[#nodelist+1] = el
-      end
-    end)
-    return nodelist
-  end
-
-  --- Parse CSS selector to match table
-  function Parser.prepare_selector(self, selector)
-    local querylist = {}
-    local function parse_selector(item)
-      local query = {}
-      -- for i = #item, 1, -1 do
-        -- local part = item[i]
-      for _, part in ipairs(item) do
-        local t = {}
-        for _, atom in ipairs(part) do
-          local key = atom[1]
-          local value = atom[2]
-          t[key] =  value
-        end
-        query[#query + 1] = t
-      end
-      return query
-    end
-    -- for item in selector:gmatch("([^%s]+)") do
-    -- elements[#elements+1] = parse_selector(item)
-    -- end
-    local parts = query.parse_query(selector) or {}
-    -- several selectors may be separated using ",", we must process them separately
-    for _, part in ipairs(parts) do
-      querylist[#querylist+1] = {query =  parse_selector(part)}
-    end
-    return querylist
-  end
-
-  function Parser.get_children(self, el)
-    local el  = el or self
-    local children = el._children or {}
-    return children
-  end
-
-  function Parser.get_parent(self, el)
-    local el = el or self
-    return el._parent
-  end
-
-  function Parser.traverse_elements(self, fn, current)
-    local current = current or self:root_node()
-    local status = true
-    if self:is_element(current) or self:get_element_type(current) == "ROOT"then
-      local status = fn(current)
-      -- don't traverse child nodes when the user function return false
-      if status ~= false then
-        for _, child in ipairs(self:get_children(current)) do
-          self:traverse_elements(fn, child)
-        end
-      end
-    end
-  end
-
-  function Parser.traverse_node_list(self, nodelist, fn)
-    local nodelist = nodelist or {}
-    for _, node in ipairs(nodelist) do
-      for _, element in ipairs(node._children) do
-        fn(element)
-      end
-    end
-  end
-
-  function Parser.replace_node(self,  new)
-    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
-
-  function Parser.add_child_node(self, child)
-    local parent = self
-    child._parent = parent
-    table.insert(parent._children, child)
-  end
-
-
-  function Parser.copy_node(self, element)
-    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
-
-  function Parser.create_element(self, name, attributes, 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
-
-  function Parser.remove_node(self, element)
-    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"}, Parser)
-    end
-  end
-
-  function Parser.find_element_pos(self, el)
-    local el = el or self
-    local parent = self:get_parent(el)
-    if not self:is_element(parent) and self:get_element_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
-
-  function Parser.get_siblibgs(self, el)
-    local el = el or self
-    local parent = el:get_parent()
-    if parent:is_element() then
-      return parent:get_children()
-    end
-  end
-
-  function Parser.get_sibling_node(self, change)
-    local el = self
-    local pos = el:find_element_pos()
-    local siblings = el:get_siblibgs()
-    if pos and siblings then
-      return siblings[pos + change]
-    end
-  end
-
-  function Parser.get_next_node(self, el)
-    local el = el or self
-    return el:get_sibling_node(1)
-  end
-
-  function Parser.get_prev_node(self, el)
-    local el = el or self
-    return el:get_sibling_node(-1)
-  end
-
-
-  -- include the methods to all xml nodes
-  save_methods(parser._handler.root)
-  -- parser:
-  return parser
-end
-
-
-local M = {}
-M.parse = parse
-M.serialize= serialize_dom
-return M

Added: trunk/Master/texmf-dist/scripts/make4ht/make4ht-filterlib.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/make4ht/make4ht-filterlib.lua	                        (rev 0)
+++ trunk/Master/texmf-dist/scripts/make4ht/make4ht-filterlib.lua	2018-04-09 21:09:51 UTC (rev 47398)
@@ -0,0 +1,42 @@
+local M = {}
+
+-- the filter module  must implement the load_filter function
+function M.load_filters(filters, load_filter)
+	local sequence = {}
+	if type(filters) == "string" then
+		table.insert(sequence,load_filter(filters))
+	elseif type(filters) == "table" then
+		for _,n in pairs(filters) do
+			if type(n) == "string" then
+				table.insert(sequence,load_filter(n))
+			elseif type(n) == "function" then
+				table.insert(sequence, n)
+			end
+		end
+	elseif type(filters) == "function" then
+		table.insert(sequence, filters)
+	else
+		return false, "Argument to filter must be either\ntable with filter names, or single filter name"
+	end
+  return sequence
+end
+
+function M.load_input_file(filename)
+  if not filename then return false, "filters: no filename" end
+  local input = nil
+
+  if filename then
+    local file = io.open(filename,"r")
+    input = file:read("*all")
+    file:close()
+  end
+  return input
+end
+
+function M.save_input_file(filename, input)
+  local file = io.open(filename,"w")
+  file:write(input)
+  file:close()
+end
+
+return M


Property changes on: trunk/Master/texmf-dist/scripts/make4ht/make4ht-filterlib.lua
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Modified: trunk/Master/texmf-dist/scripts/make4ht/mkparams.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/make4ht/mkparams.lua	2018-04-09 21:09:18 UTC (rev 47397)
+++ trunk/Master/texmf-dist/scripts/make4ht/mkparams.lua	2018-04-09 21:09:51 UTC (rev 47398)
@@ -17,6 +17,7 @@
 -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 
@@ -26,6 +27,15 @@
 -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
+local function is_escapedargument(arg)
+  -- we need to ignore make4ht options which can be used without filename, ie --version and --help
+  local ignored_options = {["-h"]=true, ["--help"]=true, ["-v"] = true, ["--version"]=true}
+  if ignored_options[arg] then return false end
+  -- in other cases, match if the argument starts with "-" character
+  return arg:match("^%-")
+end
 local function get_args(parameters, optiontext)
 	local parameters = parameters or {}
 	parameters.progname = parameters.progname or "make4ht"
@@ -33,10 +43,37 @@
 	local optiontext = optiontext or m.optiontext
 	parameters.postfile = parameters.postfile or ""
 	optiontext = optiontext .. parameters.postparams .."<filename> (string) Input file name\n" .. 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
+  -- nonempty string which doesn't start with - it will be filename or tex4ht.sty options
+  if #arg > 1 then -- do this only if more than one argument is used
+    for i=#arg,1,-1 do
+      local current = arg[i]
+      if is_escapedargument(arg[i]) then
+        arg[i] = " ".. arg[i]
+      -- empty parameter
+      elseif current == "" then
+      else
+        break
+      end
+    end
+  end
 	--print("--------------\n" .. optiontext .."--------------\n")
 	return lapp(optiontext % parameters)
 end
 
+--- get outptut file format and list of extensions from --format option string
+local function get_format_extensions(format_string)
+  local format, rest = format_string:match("^([a-zA-Z0-9]+)(.*)")
+  local extensions = {}
+  -- it is possible to pass only the extensions
+  rest = rest or format_string
+  rest:gsub("([%+%-])([^%+^%-]+)",function(typ, name)
+    table.insert(extensions, {type = typ, name = name})
+  end)
+  return format, extensions
+end
 
 local function process_args(args)
 	local function get_inserter(args,tb)
@@ -80,7 +117,7 @@
   local latex_cli_params = args[4] or ""
   if not latex_cli_params:match("%-jobname") then
     -- we must strip out directories from jobname when full path to document is given
-    input = input:match("([^%/]+)$")
+    input = input:match("([^%/^%\\]+)$")
     table.insert(latex_params,"-jobname="..input)
   else
     -- when user specifies -jobname, we must change name of the input file,
@@ -140,9 +177,14 @@
 	local build_file = input.. ".mk4"
 
 	if args["build-file"] and args["build-file"] ~= "nil" then
-		build_file = args["build-file"] 
+		build_file = args["build-file"]
 	end
 
+  local outformat, extensions
+  if args["format"] and arg["format"] ~= "nil" then
+    outformat, extensions = get_format_extensions(args["format"])
+  end
+
 	local parameters = {
 		htlatex = compiler
 		,input=input
@@ -156,6 +198,8 @@
 		,mode = mode
     ,dvi = dvi
     ,build_file = build_file
+    ,output_format = outformat
+    ,extensions = extensions
 		--,t4ht_dir_format=t4ht_dir_format
 	}
 	if outdir then parameters.outdir = outdir end
@@ -165,8 +209,15 @@
 	print("tex4ht.sty :",t4sty)
 	print("tex4ht",tex4ht)
 	print("build_file", build_file)
+  if outformat~="nil" then
+    print("Output format", outformat) 
+    for _, ex in ipairs(extensions) do
+      print("Extension", ex.type .. ex.name)
+    end
+  end
 	return parameters
 end
 m.get_args = get_args
+m.get_format_extensions = get_format_extensions
 m.process_args = process_args
 return m

Modified: trunk/Master/texmf-dist/scripts/make4ht/mkutils.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/make4ht/mkutils.lua	2018-04-09 21:09:18 UTC (rev 47397)
+++ trunk/Master/texmf-dist/scripts/make4ht/mkutils.lua	2018-04-09 21:09:51 UTC (rev 47398)
@@ -1,6 +1,7 @@
 module(...,package.seeall)
 
 local make4ht = require("make4ht-lib")
+local mkparams = require("mkparams")
 --template engine
 function interp(s, tab)
 	local tab = tab or {}
@@ -223,6 +224,8 @@
 env.string = string
 env.table  = table
 env.copy   = copy
+env.tonumber = tonumber
+env.tostring = tostring
 env.mkdirectories = mkdirectories
 env.require = require
 env.texio  = texio
@@ -230,7 +233,49 @@
 env.lfs    = lfs
 env.os     = os
 env.io     = io
+env.math   = math
 env.unicode = unicode
+
+
+-- it is necessary to use the settings table
+-- set in the Make environment by mkutils
+function env.set_settings(par)
+  local settings = env.settings
+  for k,v in pairs(par) do
+    settings[k] = v
+  end
+end
+
+-- Add a value to the current settings
+function env.settings_add(par)
+  local settings = env.settings
+  for k,v in pairs(par) do
+    local oldval = settings[k] or ""
+    settings[k] = oldval .. v
+  end
+end
+
+function env.get_filter_settings(name)
+  local settings = env.settings
+  -- local settings = self.params
+  local filters = settings.filter or {}
+  local filter_options = filters[name] or {}
+  return filter_options
+end
+
+function env.filter_settings(name)
+  -- local settings = Make.params
+  local settings = env.settings
+  local filters = settings.filter or {}
+  local filter_options = filters[name] or {}
+  return function(par)
+    for k,v in pairs(par) do
+      filter_options[k] = v
+    end
+    filters[name] = filter_options
+    settings.filter = filters
+  end
+end
 env.Font   = function(s)
 	local font_name = s["name"]
 	if not font_name then return nil, "Cannot find font name" end
@@ -239,11 +284,35 @@
 
 env.Make   = make4ht.Make
 env.Make.params = env.settings
-env.Make:add("test","no takže ${tex4ht_sty_par} ${htlatex} ${input} ${config}")
+env.Make:add("test","test the variables:  ${tex4ht_sty_par} ${htlatex} ${input} ${config}")
+
+-- this function reads the LaTeX log file and tries to detect fatal errors in the compilation
+local function testlogfile(par)
+	local logfile = par.input .. ".log"
+	local f = io.open(logfile,"r")
+	if not f then
+		print("Make4ht: cannot open log file "..logfile)
+		return 1
+	end
+	local len = f:seek("end")
+  -- test only the end of the log file, no need to run search functions on everything
+  local newlen = len - 1256
+  -- but the value to seek must be greater than 0
+  newlen = (newlen > 0) and newlen or 0
+	f:seek("set", newlen)
+	local text = f:read("*a")
+	f:close()
+	if text:match("No pages of output") or text:match("TeX capacity exceeded, sorry") then return 1 end
+	return 0
+end
+
+
+-- Make this function available in the build files
+Make.testlogfile = testlogfile
 --env.Make:add("htlatex", "${htlatex} ${latex_par} '\\\makeatletter\\def\\HCode{\\futurelet\\HCode\\HChar}\\def\\HChar{\\ifx\"\\HCode\\def\\HCode\"##1\"{\\Link##1}\\expandafter\\HCode\\else\\expandafter\\Link\\fi}\\def\\Link#1.a.b.c.{\\g at addto@macro\\@documentclasshook{\\RequirePackage[#1,html]{tex4ht}\\let\\HCode\\documentstyle\\def\\documentstyle{\\let\\documentstyle\\HCode\\expandafter\\def\\csname tex4ht\\endcsname{#1,html}\\def\\HCode####1{\\documentstyle[tex4ht,}\\@ifnextchar[{\\HCode}{\\documentstyle[tex4ht]}}}\\makeatother\\HCode '${config}${tex4ht_sty_par}'.a.b.c.\\input ' ${input}")
-env.Make:add("htlatex",function(par) 
-	local command = 
-"${htlatex} ${latex_par} '\\makeatletter"..
+
+-- template for calling LaTeX with tex4ht loaded
+Make.latex_command = "${htlatex} ${latex_par} '\\makeatletter"..
 "\\def\\HCode{\\futurelet\\HCode\\HChar}\\def\\HChar{\\ifx\"\\HCode"..
 "\\def\\HCode\"##1\"{\\Link##1}\\expandafter\\HCode\\else"..
 "\\expandafter\\Link\\fi}\\def\\Link#1.a.b.c.{\\g at addto@macro"..
@@ -252,7 +321,10 @@
 "\\HCode\\expandafter\\def\\csname tex4ht\\endcsname{#1,html}\\def"..
 "\\HCode####1{\\documentstyle[tex4ht,}\\@ifnextchar[{\\HCode}{"..
 "\\documentstyle[tex4ht]}}}\\makeatother\\HCode ${tex4ht_sty_par}.a.b.c."..
-"\\input ${tex_file}'" 
+"\\input ${tex_file}'"
+
+env.Make:add("htlatex",function(par)
+  local command = Make.latex_command
   if os.type == "windows" then
     command = command:gsub("'",'')
   end
@@ -259,39 +331,160 @@
   command = command % par
   print("LaTeX call: "..command)
   os.execute(command)
-	local logfile = par.input .. ".log"
-	local f = io.open(logfile,"r")
-	if not f then 
-		print("Make4ht: cannot open log file "..logfile)
-		return 1
-	end
-	local len = f:seek("end")
-	f:seek("set", len - 1256)
-	local text = f:read("*a")
-	f:close()
-	if text:match("No pages of output") or text:match("TeX capacity exceeded, sorry") then return 1 end
-	return 0 
+  return testlogfile(par)
 end
 ,{correct_exit=0})
+
+
+env.Make:add("latexmk", function(par)
+  local command = Make.latex_command
+  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
+  os.execute(newcommand)
+  return Make.testlogfile(par)
+end, {correct_exit= 0})
+
+
+
 env.Make:add("tex4ht","tex4ht ${tex4ht_par} \"${input}.${dvi}\"", nil, 1)
 env.Make:add("t4ht","t4ht ${t4ht_par} \"${input}.${ext}\"",{ext="dvi"},1)
 
+-- enable extension in the config file
+-- the following two functions must be here and not in make4ht-lib.lua
+-- because of the access to env.settings
+env.Make.enable_extension = function(self,name)
+  table.insert(env.settings.extensions, {type="+", name=name})
+end
+
+-- disable extension in the config file
+env.Make.disable_extension = function(self,name)
+  table.insert(env.settings.extensions, {type="-", name=name})
+end
+
 function load_config(settings, config_name)
-	local settings = settings or main_settings
-	env.settings = settings
-	env.mode = settings.mode
-	local config_name = kpse.find_file(config_name, 'texmfscripts') or config_name
-	local f = io.open(config_name,"r")
-	if not f then 
+  local settings = settings or main_settings
+  env.settings = settings
+  env.mode = settings.mode
+  if config_name and not file_exists(config_name) then
+    config_name = kpse.find_file(config_name, 'texmfscripts') or config_name
+  end
+  local f = io.open(config_name,"r")
+  if not f then 
     print("Cannot open config file", config_name)
     return  env
   end
   print("Using build file", config_name)
-	local code = f:read("*all")
-	local fn, msg = run(code,env)
-	if not fn then print(msg) end
-	assert(fn)
-	return env
+  local code = f:read("*all")
+  local fn, msg = run(code,env)
+  if not fn then print(msg) end
+  assert(fn)
+  return env
 end
 
+local function find_lua_file(name)
+  local extension_path = name:gsub("%.", "/") .. ".lua"
+  return kpse.find_file(extension_path, "lua")
+end
 
+--- load the output format plugins
+function load_output_format(format_name)
+  local format_library =  "make4ht.formats."..format_name
+  local is_format_file = find_lua_file(format_library)
+  if is_format_file then 
+    local format = assert(require(format_library))
+    if format then
+      format.prepare_extensions = format.prepare_extensions or function(extensions) return extensions end
+    end
+    return format
+  end
+end
+
+--- Execute the prepare_parameters function in list of extensions
+function extensions_prepare_parameters(extensions, parameters)
+  for _, ext in ipairs(extensions) do
+    -- execute the extension only if it contains prepare_parameters function
+    local fn = ext.prepare_parameters
+    if fn then
+      parameters = fn(parameters)
+    end
+  end
+  return parameters
+end
+
+--- Modify the build sequence using extensions
+-- @param extensions list of extensions 
+-- @make  Make object
+function extensions_modify_build(extensions, make)
+  for _, ext in ipairs(extensions) do
+    local fn = ext.modify_build
+    if fn then
+      make = fn(make)
+    end
+  end
+  return make
+end
+
+
+--- load one extension
+-- @param name  extension name
+-- @param format current output format
+function load_extension(name,format)
+  -- first test if the extension exists
+  local extension_library = "make4ht.extensions." .. name
+  local is_extension_file = find_lua_file(extension_library)
+  -- don't try to load the extension if it doesn't exist
+  if not is_extension_file then return nil end
+  local extension = require("make4ht.extensions.".. name)
+  -- extensions can test if the current output format is supported
+  local test = extension.test
+  if test then
+    if test(format) then 
+      return extension
+    end
+    -- if the test fail return nil
+    return nil
+  end
+  -- if the extension doesn't provide the test function, we will assume that
+  -- it supports every output format
+  return extension
+end
+
+--- load extensions
+-- @param extensions table created by mkparams.get_format_extensions function
+-- @param format  output type format. extensions may support only certain file
+-- formats
+function load_extensions(extensions, format)
+  local module_names = {}
+  local extension_table = {}
+  -- process the extension table. it contains type field, which can enable or
+  -- diable the extension
+  for _, v in ipairs(extensions) do
+    local enable = v.type == "+" and true or nil
+    module_names[v.name] = enable
+  end
+  for name, _ in pairs(module_names) do
+    local extension = load_extension(name,format)
+    if extension then
+      table.insert(extension_table, extension)
+    else
+      print("Cannot load extension: ".. name)
+    end
+  end
+  return extension_table
+end
+
+--- add new extensions to a list of loaded extensions
+-- @param added  string with extensions to be added in the form +ext1+ext2
+function add_extensions(added, extensions)
+  local _, newextensions = mkparams.get_format_extensions("dummyfmt" .. added)
+  -- insert new extension at the beginning, in order to support disabling using
+  -- the -f option
+  for _, x in ipairs(extensions or {}) do table.insert(newextensions, x) end
+  return newextensions
+end
+
+-- I don't know if this is clean, but settings functions won't be available
+-- for filters and extensions otherwise
+for k,v in pairs(env) do _G[k] = v end



More information about the tex-live-commits mailing list