texlive[44079] trunk: make4ht (27apr17)

commits+karl at tug.org commits+karl at tug.org
Thu Apr 27 18:43:40 CEST 2017


Revision: 44079
          http://tug.org/svn/texlive?view=revision&revision=44079
Author:   karl
Date:     2017-04-27 18:43:40 +0200 (Thu, 27 Apr 2017)
Log Message:
-----------
make4ht (27apr17)

Modified Paths:
--------------
    trunk/Build/source/texk/texlive/linked_scripts/make4ht/make4ht
    trunk/Build/source/texk/texlive/linked_scripts/texlive/tlmgr.pl
    trunk/Build/source/texk/texlive/linked_scripts/texlive/updmap.pl
    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/make4ht
    trunk/Master/texmf-dist/scripts/make4ht/make4ht-lib.lua
    trunk/Master/texmf-dist/scripts/make4ht/mkparams.lua
    trunk/Master/texmf-dist/scripts/make4ht/mkutils.lua

Added Paths:
-----------
    trunk/Master/texmf-dist/scripts/make4ht/filters/make4ht-fix-links.lua
    trunk/Master/texmf-dist/scripts/make4ht/make4ht-dom.lua
    trunk/Master/texmf-dist/scripts/make4ht/mathnode.lua

Modified: trunk/Build/source/texk/texlive/linked_scripts/make4ht/make4ht
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/make4ht/make4ht	2017-04-27 15:13:02 UTC (rev 44078)
+++ trunk/Build/source/texk/texlive/linked_scripts/make4ht/make4ht	2017-04-27 16:43:40 UTC (rev 44079)
@@ -24,6 +24,11 @@
 <filename> (string) Input file name
 ]]
 
+-- set version number. the template should be replaced by the
+-- actual version number by the build script
+local version = "v0.1c"
+mkparams.version_number = version
+
 local args = mkparams.get_args()
 
 local parameters = mkparams.process_args(args) 

Modified: trunk/Build/source/texk/texlive/linked_scripts/texlive/tlmgr.pl
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/texlive/tlmgr.pl	2017-04-27 15:13:02 UTC (rev 44078)
+++ trunk/Build/source/texk/texlive/linked_scripts/texlive/tlmgr.pl	2017-04-27 16:43:40 UTC (rev 44079)
@@ -1,5 +1,5 @@
 #!/usr/bin/env perl
-# $Id: tlmgr.pl 43940 2017-04-20 14:47:49Z preining $
+# $Id: tlmgr.pl 43990 2017-04-23 13:21:28Z preining $
 #
 # Copyright 2008-2017 Norbert Preining
 # This file is licensed under the GNU General Public License version 2
@@ -6,8 +6,8 @@
 # or any later version.
 #
 
-my $svnrev = '$Revision: 43940 $';
-my $datrev = '$Date: 2017-04-20 16:47:49 +0200 (Thu, 20 Apr 2017) $';
+my $svnrev = '$Revision: 43990 $';
+my $datrev = '$Date: 2017-04-23 15:21:28 +0200 (Sun, 23 Apr 2017) $';
 my $tlmgrrevision;
 my $prg;
 if ($svnrev =~ m/: ([0-9]+) /) {
@@ -6689,6 +6689,11 @@
       } else {
         print "OK\n";
       }
+      # make sure that we restart after having called update --self!
+      if (($cmd eq 'update') && $opts{'self'}) {
+        print "tlmgr has been updated, restarting!\n";
+        exec("tlmgr", @::SAVEDARGV);
+      }
       %opts = %savedopts;
     } else {
       print "ERROR unknown command\n";

Modified: trunk/Build/source/texk/texlive/linked_scripts/texlive/updmap.pl
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/texlive/updmap.pl	2017-04-27 15:13:02 UTC (rev 44078)
+++ trunk/Build/source/texk/texlive/linked_scripts/texlive/updmap.pl	2017-04-27 16:43:40 UTC (rev 44079)
@@ -1,5 +1,5 @@
 #!/usr/bin/env perl
-# $Id: updmap.pl 43794 2017-04-15 00:12:54Z preining $
+# $Id: updmap.pl 44056 2017-04-26 08:14:28Z preining $
 # updmap - maintain map files for outline fonts.
 # (Maintained in TeX Live:Master/texmf-dist/scripts/texlive.)
 # 
@@ -14,7 +14,7 @@
 # the original versions were licensed under the following agreement:
 # Anyone may freely use, modify, and/or distribute this file, without
 
-my $svnid = '$Id: updmap.pl 43794 2017-04-15 00:12:54Z preining $';
+my $svnid = '$Id: updmap.pl 44056 2017-04-26 08:14:28Z preining $';
 
 my $TEXMFROOT;
 BEGIN {
@@ -27,10 +27,10 @@
   unshift(@INC, "$TEXMFROOT/tlpkg");
 }
 
-my $lastchdate = '$Date: 2017-04-15 02:12:54 +0200 (Sat, 15 Apr 2017) $';
+my $lastchdate = '$Date: 2017-04-26 10:14:28 +0200 (Wed, 26 Apr 2017) $';
 $lastchdate =~ s/^\$Date:\s*//;
 $lastchdate =~ s/ \(.*$//;
-my $svnrev = '$Revision: 43794 $';
+my $svnrev = '$Revision: 44056 $';
 $svnrev =~ s/^\$Revision:\s*//;
 $svnrev =~ s/\s*\$$//;
 my $version = "r$svnrev ($lastchdate)";
@@ -1476,6 +1476,11 @@
     if ($w =~ m/=/) {
       # this is --enable MapType=MapName
       my ($type, $map) = split ('=', $w);
+      # allow for all lowercase map types (map/mixedmap/kanjimap)
+      $type =~ s/map$/Map/;
+      $type = ucfirst($type);
+      # don't allow for map names containing /
+      die "$prg: map files cannot be relative/absolute paths: $map\n" if ($map =~ m{/})
       enable_map($tc, $type, $map);
     } else {
       # this is --disable MapName

Modified: trunk/Master/texmf-dist/doc/support/make4ht/README
===================================================================
--- trunk/Master/texmf-dist/doc/support/make4ht/README	2017-04-27 15:13:02 UTC (rev 44078)
+++ trunk/Master/texmf-dist/doc/support/make4ht/README	2017-04-27 16:43:40 UTC (rev 44079)
@@ -60,9 +60,12 @@
     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.
+`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.
 
-Note that you don't have to call `tex4ht` and `t4ht` commands explicitly in the build file, they are called automatically. 
+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 
 
@@ -76,7 +79,11 @@
 `command` can be text template, or function:
 
     Make:add("text", "hello, input file: ${input}")
-    Make:add("function", function(params) for k, v in pairs(params) do print(k..": "..v) end)
+    Make:add("function", function(params) 
+      for k, v in pairs(params) do 
+        print(k..": "..v) 
+      end
+    )
 
 `parameters` is a table or `nil` value.
 
@@ -101,7 +108,7 @@
 packages
 
 :    insert additionl LaTeX code which is inserted before `\documentclass`.
-     useful for passing options to packages or additional packages loading
+     Useful for passing options to packages or additional packages loading
 
 tex4ht_sty_par 
 
@@ -125,7 +132,8 @@
 
 correct_exit 
 
-:     expected `exit code` from the command.
+:    expected `exit code` from the command. The compilation will be terminted
+     when the command `exit code` is different.
 
 
 You may add your own parameters, they will be accessible in templates and
@@ -138,9 +146,9 @@
 called also by `make4ht`. With `repetition`, second execution is blocked.
 
 You can set expected exit code from a command with `correct_exit`. Compilation
-is stopped when command returns different exit code. Situation is little bit
-difficult with LaTeX (all engines and formats in fact), because it doesn't 
-differentiate between fatal and non fatal errors and returns same exit code
+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.
 
@@ -193,11 +201,19 @@
 
 :   `\hrule` commands are translated to series of underscore characters
     by `tex4ht`, this filter translate these underscores to `<hr>` elements
+
 entites 
 
-:    convert prohibited named entities to numeric entities (currently, only ` `, as it causes validation errors, and `tex4ht` is producing it sometimes
+:    convert prohibited named entities to numeric entities (currently, only
+     ` `, as it causes validation errors, and `tex4ht` is producing it
+     sometimes
 
+fix-links
 
+:    replace colons in local links and `id` attributes with underscores. Some
+     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.
 
@@ -222,7 +238,7 @@
 commands are called. 
 
 This conversion is normally configured in the `env file`, 
-which is system dependent and which has a little bit unintuitive syntax.
+which is system dependent and which has a bit unintuitive syntax.
 This configuration is processed by `t4ht` application and conversion
 commands are called for all pictures.
 
@@ -243,9 +259,9 @@
   - source - `dvi` file with the pictures
   - page   - page number of the converted image
 
-## `mode` variable
+## The `mode` variable
 
-Variable `mode` contains contents of `-mode` command line option. 
+The `mode` variable contains contents of `--mode` command line option. 
 It can be used to run some commands conditionally. For example:
 
      if mode == "draft" then
@@ -256,12 +272,23 @@
        Make:htlatex{}
      end
 
-In this example (which is default configuration used by `make4ht`),
-LaTeX is called only once when `make4ht` is called with
+In this example (which is the default configuration used by `make4ht`),
+LaTeX is called only once when `make4ht` is called with `draft` mode:
     
     make4ht -m draft filename
 
+## 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 `OpenDocument Format`, you can use the following settings, based on `oolatex`
+command:
+
+    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 "
+
+
 # Command line options
 
     make4ht - build system for tex4ht

Modified: trunk/Master/texmf-dist/doc/support/make4ht/changelog.tex
===================================================================
--- trunk/Master/texmf-dist/doc/support/make4ht/changelog.tex	2017-04-27 15:13:02 UTC (rev 44078)
+++ trunk/Master/texmf-dist/doc/support/make4ht/changelog.tex	2017-04-27 16:43:40 UTC (rev 44079)
@@ -2,6 +2,61 @@
 
 \begin{itemize}
 \item
+  2017/04/26
+
+  \begin{itemize}
+  \itemsep1pt\parskip0pt\parsep0pt
+  \item
+    Released version \texttt{v0.1c}
+  \end{itemize}
+\item
+  2017/03/16
+
+  \begin{itemize}
+  \itemsep1pt\parskip0pt\parsep0pt
+  \item
+    check for \texttt{TeX capacity exceeded} error in the \LaTeX~run.
+  \end{itemize}
+\item
+  2016/12/19
+
+  \begin{itemize}
+  \itemsep1pt\parskip0pt\parsep0pt
+  \item
+    use full input name in \texttt{tex\_file} variable. This should
+    enable use of files without \texttt{.tex} extension.
+  \end{itemize}
+\item
+  2016/10/22
+
+  \begin{itemize}
+  \itemsep1pt\parskip0pt\parsep0pt
+  \item
+    new command available in the build file:
+    \texttt{Make:add\_file(filename)}. This enables filters and commands
+    to register files to the output.
+  \item
+    use ipairs instead of pairs for traversing files and executing
+    filters. This should ensure correct order of executions.
+  \end{itemize}
+\item
+  2016/10/18
+
+  \begin{itemize}
+  \itemsep1pt\parskip0pt\parsep0pt
+  \item
+    new filter: replace colons in \texttt{id} and \texttt{href}
+    attributes with underscores
+  \end{itemize}
+\item
+  2016/01/11
+
+  \begin{itemize}
+  \itemsep1pt\parskip0pt\parsep0pt
+  \item
+    fixed bug in loading documents with full path specified
+  \end{itemize}
+\item
   2015/12/06 version 0.1b
 
   \begin{itemize}

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	2017-04-27 15:13:02 UTC (rev 44078)
+++ trunk/Master/texmf-dist/doc/support/make4ht/make4ht-doc.tex	2017-04-27 16:43:40 UTC (rev 44079)
@@ -11,10 +11,11 @@
 \setmainfont{TeX Gyre Schola}
 \fi
 \usepackage{microtype}
+\providecommand\tightlist{\relax}
 
 \title{The \texttt{make4ht} build system}
 \author{Michal Hoftich\footnote{\url{michal.h21 at gmail.com}}}
-\date{Version 0.1b\\12/11/2015}
+\date{Version \version\\\gitdate}
 \begin{document}
 \maketitle
 \tableofcontents

Modified: trunk/Master/texmf-dist/doc/support/make4ht/readme.tex
===================================================================
--- trunk/Master/texmf-dist/doc/support/make4ht/readme.tex	2017-04-27 15:13:02 UTC (rev 44078)
+++ trunk/Master/texmf-dist/doc/support/make4ht/readme.tex	2017-04-27 16:43:40 UTC (rev 44079)
@@ -93,7 +93,11 @@
 
 \begin{verbatim}
 Make:add("text", "hello, input file: ${input}")
-Make:add("function", function(params) for k, v in pairs(params) do print(k..": "..v) end)
+Make:add("function", function(params) 
+  for k, v in pairs(params) do 
+    print(k..": "..v) 
+  end
+)
 \end{verbatim}
 
 \texttt{parameters} is a table or \texttt{nil} value.
@@ -111,7 +115,7 @@
 parameters to \texttt{latex}
 \item[packages]
 insert additionl LaTeX code which is inserted before
-\texttt{\textbackslash{}documentclass}. useful for passing options to
+\texttt{\textbackslash{}documentclass}. Useful for passing options to
 packages or additional packages loading
 \item[tex4ht\_sty\_par]
 parameters to \texttt{tex4ht.sty}
@@ -124,7 +128,8 @@
 \item[repetition]
 limit number of command execution.
 \item[correct\_exit]
-expected \texttt{exit code} from the command.
+expected \texttt{exit code} from the command. The compilation will be
+terminted when the command \texttt{exit code} is different.
 \end{description}
 
 You may add your own parameters, they will be accessible in templates
@@ -139,11 +144,11 @@
 
 You can set expected exit code from a command with
 \texttt{correct\_exit}. Compilation is stopped when command returns
-different exit code. Situation is little bit difficult with LaTeX (all
-engines and formats in fact), because it doesn't differentiate between
-fatal and non fatal errors and returns 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.
+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.
 
 \subsection{File matches}\label{file-matches}
 
@@ -197,6 +202,10 @@
 convert prohibited named entities to numeric entities (currently, only
 \texttt{\ }, as it causes validation errors, and \texttt{tex4ht} is
 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.
 \end{description}
 
 Function \texttt{filter} accepts also function arguments, in this case
@@ -226,7 +235,7 @@
 \texttt{dvi to image} commands are called.
 
 This conversion is normally configured in the \texttt{env file}, which
-is system dependent and which has a little bit unintuitive syntax. This
+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.
 
@@ -254,10 +263,11 @@
   page - page number of the converted image
 \end{itemize}
 
-\subsection{\texttt{mode} variable}\label{mode-variable}
+\subsection{The \texttt{mode} variable}\label{the-mode-variable}
 
-Variable \texttt{mode} contains contents of \texttt{-mode} command line
-option. It can be used to run some commands conditionally. For example:
+The \texttt{mode} variable contains contents of \texttt{-{}-mode}
+command line option. It can be used to run some commands conditionally.
+For example:
 
 \begin{verbatim}
  if mode == "draft" then
@@ -269,14 +279,27 @@
  end
 \end{verbatim}
 
-In this example (which is default configuration used by
+In this example (which is the default configuration used by
 \texttt{make4ht}), LaTeX is called only once when \texttt{make4ht} is
-called with
+called with \texttt{draft} mode:
 
 \begin{verbatim}
 make4ht -m draft filename
 \end{verbatim}
 
+\subsection{The \texttt{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:
+
+\begin{verbatim}
+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 "
+\end{verbatim}
+
 \section{Command line options}\label{command-line-options}
 
 \begin{verbatim}

Added: trunk/Master/texmf-dist/scripts/make4ht/filters/make4ht-fix-links.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/make4ht/filters/make4ht-fix-links.lua	                        (rev 0)
+++ trunk/Master/texmf-dist/scripts/make4ht/filters/make4ht-fix-links.lua	2017-04-27 16:43:40 UTC (rev 44079)
@@ -0,0 +1,19 @@
+-- replace colons in `id` or `href` attributes for local links with underscores
+--
+
+local function fix_href_colons(s)
+  return s:gsub('(href=".-")', function(a)
+    if a:match("[a-z]%://") then return a end
+    return a:gsub(":","_")
+  end)
+end
+
+local function fix_id_colons(s)
+  return s:gsub('(id=".-")', function(a)
+    return a:gsub(":", "_")
+  end)
+end
+
+return function(s)
+  return fix_id_colons(fix_href_colons(s))
+end


Property changes on: trunk/Master/texmf-dist/scripts/make4ht/filters/make4ht-fix-links.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	2017-04-27 15:13:02 UTC (rev 44078)
+++ trunk/Master/texmf-dist/scripts/make4ht/make4ht	2017-04-27 16:43:40 UTC (rev 44079)
@@ -24,6 +24,11 @@
 <filename> (string) Input file name
 ]]
 
+-- set version number. the template should be replaced by the
+-- actual version number by the build script
+local version = "v0.1c"
+mkparams.version_number = version
+
 local args = mkparams.get_args()
 
 local parameters = mkparams.process_args(args) 

Added: trunk/Master/texmf-dist/scripts/make4ht/make4ht-dom.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/make4ht/make4ht-dom.lua	                        (rev 0)
+++ trunk/Master/texmf-dist/scripts/make4ht/make4ht-dom.lua	2017-04-27 16:43:40 UTC (rev 44079)
@@ -0,0 +1,448 @@
+--- 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


Property changes on: trunk/Master/texmf-dist/scripts/make4ht/make4ht-dom.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/make4ht-lib.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/make4ht/make4ht-lib.lua	2017-04-27 15:13:02 UTC (rev 44078)
+++ trunk/Master/texmf-dist/scripts/make4ht/make4ht-lib.lua	2017-04-27 16:43:40 UTC (rev 44079)
@@ -116,9 +116,9 @@
 		self.matches[k].params = v
 	end
 	-- Loop over files, run command on matched
-	for _, file in pairs(files)do
+	for _, file in ipairs(files)do
 		statuses[file] = {}
-		for _, s in pairs(self.matches) do
+		for _, s in ipairs(self.matches) do
 			local pattern= s.pattern
 			if file:match(pattern) then 
 				local status, msg = self:run_command(file,s)
@@ -134,6 +134,27 @@
 	return statuses
 end
 
+-- add files from the mk4 file
+-- we must add them to the table generated from the lg file, so they can be processed later
+--
+Make.add_file = function(self, filename)
+  -- self.lgfile should be present, as it is created once the lg_file was parsed for the first time
+  local lg = self.lgfile or {}
+  local files = lg.files or {}
+  -- run filters on the file
+  local filtertable = {filename}
+  -- should we care about return status?
+  self:file_matches(filtertable)
+  -- break if the file is present already 
+  -- start at the end, it it was added by a build file, the file will be likely at the end
+  for i = #files,1,-1  do 
+    if files[i] == filename then return false, "File was already added" end
+  end
+  -- save the added file to the lg_file
+  table.insert(lg.files, filename)
+  self.lg = lg
+end
+
 Make.run = function(self) 
 	local return_codes = {}
   local params = self.params or {}
@@ -174,12 +195,13 @@
 	end
 	local lgfile = params.input and params.input .. ".lg" or nil 
 	if lgfile then
-   	local lg = mkutils.parse_lg(lgfile)
+   	self.lgfile = self.lgfile or mkutils.parse_lg(lgfile)
+    local lg = self.lgfile
 		-- First convert images from lg files
 		self:image_convert(lg["images"])
 		-- Then run file matchers on lg files and converted images
 		local files = lg["files"]
-		for _,v in pairs(lg["images"]) do 
+		for _,v in ipairs(lg["images"]) do 
 			local v = v.output
 			-- print(v)
 			table.insert(files,v) 

Added: trunk/Master/texmf-dist/scripts/make4ht/mathnode.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/make4ht/mathnode.lua	                        (rev 0)
+++ trunk/Master/texmf-dist/scripts/make4ht/mathnode.lua	2017-04-27 16:43:40 UTC (rev 44079)
@@ -0,0 +1,87 @@
+-- local mathnodepath = os.getenv "mathjaxnodepath"
+-- 
+-- print("mathnode", mathnodepath)
+local mkutils = require "mkutils"
+-- other possible value is page2svg
+local mathnodepath = "page2html"
+-- options for MathJax command
+local options = "--format MathML"
+-- math fonts position
+-- don't alter fonts if not set
+local fontdir = nil
+-- if we copy fonts 
+local fontdest = nil
+local fontformat = "otf"
+
+local function compile(src)
+  local tmpfile = os.tmpname()
+  local filename = src
+  print("Compile using MathJax")
+  local command =  mathnodepath .. " ".. options .. " < " .. filename .. " > " .. tmpfile
+  print(command)
+  local status = os.execute(command) 
+  print("Result written to: ".. tmpfile)
+  mkutils.cp(tmpfile, src)
+  os.remove(tmpfile)
+end
+
+local function extract_css(file)
+  local f = io.open(file, "r")
+  local contents = f:read("*all")
+  f:close()
+  local css = ""
+  local filename = ""
+  contents = contents:gsub('<style id="(MathJax.-)">(.+)</style>', function(name, style)
+    css = style
+    filename = (name or "") .. ".css"
+    return '<link rel="stylesheet" type="text/css" href="'..filename ..'" />'
+  end)
+  local x = assert(io.open(file, "w"))
+  x:write(contents)
+  x:close()
+  return filename, css
+end
+
+-- 
+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
+    if not face:match("url%(") then return "" 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
+  mathnodepath = arguments.prg or mathnodepath
+  options      = arguments.options or options
+  fontdir      = arguments.fontdir or fontdir
+  fontdest     = arguments.fontdest or fontdest
+  fontformat   = arguments.fontformat or fontformat
+  compile(text)
+  filename, css = extract_css(text)
+  if fontdir then
+    css = use_fonts(css)
+  end
+  save_css(filename, css)
+  Make:add_file(filename)
+  -- print(css)
+  print(filename)
+end


Property changes on: trunk/Master/texmf-dist/scripts/make4ht/mathnode.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	2017-04-27 15:13:02 UTC (rev 44078)
+++ trunk/Master/texmf-dist/scripts/make4ht/mkparams.lua	2017-04-27 16:43:40 UTC (rev 44079)
@@ -2,6 +2,12 @@
 local mkutils = require "mkutils"
 local m = {} -- use ugly module system for new lua versions support
 
+-- these two variables will be used in the version number
+-- progname will be set in get_args
+m.progname = "make4ht"
+-- set the version number before call to process_args()
+m.version_number = "v0.1"
+
 m.optiontext =  [[
 ${progname} - build system for tex4ht
 Usage:
@@ -43,7 +49,7 @@
 	end
 
   if args.version ==true then
-    print "make4ht version 0.1b"
+    print(string.format("%s version %s", m.progname, m.version_number))
     os.exit()
   end
 
@@ -66,14 +72,15 @@
 
 
 	local compiler = args.lua and "dvilualatex" or args.xetex and "xelatex --no-pdf" or "latex"
+  local tex_file = args.filename
 	local input = mkutils.remove_extension(args.filename)
-
 	local latex_params = {}
-  local tex_file = input
 	local insert_latex = get_inserter(args,latex_params)
 	insert_latex("shell-escape","-shell-escape")
   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("([^%/]+)$")
     table.insert(latex_params,"-jobname="..input)
   else
     -- when user specifies -jobname, we must change name of the input file,
@@ -117,12 +124,13 @@
 	--end
 
 	local tex4ht = ""
+  local dvi= args.xetex and "xdv" or "dvi"
 	if args[2] and args[2] ~="" then
 		tex4ht = args[2]
 	else
 		tex4ht = args.utf8 and " -cmozhtf -utf8" or ""
-		local xdv = args.xetex and " -.xdv" or ""
-		tex4ht = tex4ht .. xdv
+    if args.xetex then tex4ht = tex4ht .. " -.xdv" end
+		-- tex4ht = tex4ht .. xdv
 	end
 
 	local t4ht = args[3] or ""
@@ -146,6 +154,7 @@
 		,tex4ht_par=tex4ht
 		,t4ht_par=t4ht
 		,mode = mode
+    ,dvi = dvi
     ,build_file = build_file
 		--,t4ht_dir_format=t4ht_dir_format
 	}

Modified: trunk/Master/texmf-dist/scripts/make4ht/mkutils.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/make4ht/mkutils.lua	2017-04-27 15:13:02 UTC (rev 44078)
+++ trunk/Master/texmf-dist/scripts/make4ht/mkutils.lua	2017-04-27 16:43:40 UTC (rev 44079)
@@ -92,9 +92,13 @@
 end
 
 
+-- 
 local cp_func = os.type == "unix" and "cp" or "copy"
+-- maybe it would be better to actually move the files
+-- in reality it isn't.
+-- local cp_func = os.type == "unix" and "mv" or "move"
 function cp(src,dest)
-	local command = string.format('%s %s %s', cp_func, src, dest)
+	local command = string.format('%s "%s" "%s"', cp_func, src, dest)
 	if cp_func == "copy" then command = command:gsub("/",'\\') end
 	print("Copy: "..command)
 	os.execute(command)
@@ -262,15 +266,14 @@
 		return 1
 	end
 	local len = f:seek("end")
-
-	f:seek("set", len - 256)
+	f:seek("set", len - 1256)
 	local text = f:read("*a")
 	f:close()
-	if text:match("No pages of output") then return 1 end
+	if text:match("No pages of output") or text:match("TeX capacity exceeded, sorry") then return 1 end
 	return 0 
 end
 ,{correct_exit=0})
-env.Make:add("tex4ht","tex4ht ${tex4ht_par} \"${input}\"", nil, 1)
+env.Make:add("tex4ht","tex4ht ${tex4ht_par} \"${input}.${dvi}\"", nil, 1)
 env.Make:add("t4ht","t4ht ${t4ht_par} \"${input}.${ext}\"",{ext="dvi"},1)
 
 function load_config(settings, config_name)



More information about the tex-live-commits mailing list