summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2012-08-13 22:41:51 +0000
committerKarl Berry <karl@freefriends.org>2012-08-13 22:41:51 +0000
commit891d790aa1dafff5340c181e3dce3332526e4834 (patch)
tree049abb04059bc666a0ffa9c585547f5fee297a4c
parent99f6ebc940e504927ea38d6600f8ca9f893667bb (diff)
new luatex package luaxml (13aug12)
git-svn-id: svn://tug.org/texlive/trunk@27394 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r--Master/texmf-dist/doc/luatex/luaxml/README27
-rw-r--r--Master/texmf-dist/doc/luatex/luaxml/luaxml.pdfbin0 -> 111453 bytes
-rw-r--r--Master/texmf-dist/doc/luatex/luaxml/luaxml.tex355
-rw-r--r--Master/texmf-dist/tex/luatex/luaxml/luaxml-mod-handler.lua338
-rw-r--r--Master/texmf-dist/tex/luatex/luaxml/luaxml-mod-xml.lua547
-rw-r--r--Master/texmf-dist/tex/luatex/luaxml/luaxml-selectors.lua42
-rw-r--r--Master/texmf-dist/tex/luatex/luaxml/luaxml-stack.lua63
-rwxr-xr-xMaster/tlpkg/bin/tlpkg-ctan-check2
-rwxr-xr-xMaster/tlpkg/libexec/ctan2tds1
-rw-r--r--Master/tlpkg/tlpsrc/collection-luatex.tlpsrc1
-rw-r--r--Master/tlpkg/tlpsrc/luaxml.tlpsrc0
11 files changed, 1375 insertions, 1 deletions
diff --git a/Master/texmf-dist/doc/luatex/luaxml/README b/Master/texmf-dist/doc/luatex/luaxml/README
new file mode 100644
index 00000000000..cb48cbab9bd
--- /dev/null
+++ b/Master/texmf-dist/doc/luatex/luaxml/README
@@ -0,0 +1,27 @@
+Introduction
+============
+
+LuaXML is pure lua library for reading and serializing of the XML files. Current release is aimed mainly as support
+for the odsfile package. The documentation was created by automatic conversion of original documentation in the source code.
+In this version, some files not useful for luaTeX were droped. Original files can be found at
+
+ http://manoelcampos.com/files/LuaXML--0.0.0-lua5.1.tgz
+
+
+License:
+========
+
+This code is freely distributable under the terms of the Lua license
+ (http://www.lua.org/copyright.html)
+
+
+Author
+------
+Michal Hoftich
+Email: michal.h21@gmail.com
+
+Original authors: Paul Chakravarti and Manoel Campos (http://manoelcampos.com)
+
+If you are interested in the process of development you may observe
+
+ https://github.com/michal-h21/LuaXML \ No newline at end of file
diff --git a/Master/texmf-dist/doc/luatex/luaxml/luaxml.pdf b/Master/texmf-dist/doc/luatex/luaxml/luaxml.pdf
new file mode 100644
index 00000000000..cddfdcdf5d9
--- /dev/null
+++ b/Master/texmf-dist/doc/luatex/luaxml/luaxml.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/luatex/luaxml/luaxml.tex b/Master/texmf-dist/doc/luatex/luaxml/luaxml.tex
new file mode 100644
index 00000000000..34363fbcf04
--- /dev/null
+++ b/Master/texmf-dist/doc/luatex/luaxml/luaxml.tex
@@ -0,0 +1,355 @@
+\documentclass{ltxdoc}
+\usepackage{tgschola,url}
+\usepackage[english]{babel}
+\begin{document}
+ \title{The \textsc{LuaXML} library}
+ \author{Paul Chakravarti \and Michal Hoftich}
+ \maketitle
+\tableofcontents
+\section*{Introduction}
+
+|LuaXML| is pure lua library for reading and serializing of the |xml| files.
+Current release is aimed mainly as support for the odsfile package.
+In first release it was included with the odsfile package,
+but as it is general library which can be used also with other packages,
+I decided to distribute it as separate library.
+
+\noindent Example of usage:
+
+\begin{verbatim}
+xml = require('luaxml-mod-xml')
+handler = require('luaxml-mod-handler')
+\end{verbatim}
+
+First load the libraries. In |luaxml-mod-xml|, there is xml parser and also serializer. In |luaxml-mod-handler|, there are various handlers for dealing with xml data. Handlers are objects with callback functions which are invoked for every type of content in the |xml| file. More information about handlers can be found in the original documentation, section \ref{sec:handlers}.
+\begin{verbatim}
+sample = [[
+<a>
+ <d>hello</d>
+ <b>world.</b>
+ <b at="Hi">another</b>
+</a>]]
+treehandler = handler.simpleTreeHandler()
+x = xml.xmlParser(treehandler)
+x:parse(sample)
+\end{verbatim}
+
+You have to create handler object, using |handler.simpleTreeHandler()| and xml parser object using |xml.xmlParser(handler object)|. |simpleTreehandler| creates simple table hierarchy, with top root node in |treehandler.root|
+\begin{verbatim}
+-- pretty printing function
+function printable(tb, level)
+ level = level or 1
+ local spaces = string.rep(' ', level*2)
+ for k,v in pairs(tb) do
+ if type(v) ~= "table" then
+ print(spaces .. k..'='..v)
+ else
+ print(spaces .. k)
+ level = level + 1
+ printable(v, level)
+ end
+ end
+end
+
+-- print table
+printable(treehandler.root)
+-- print xml serialization of table
+print(xml.serialize(treehandler.root))
+-- direct access to the element
+print(treehandler.root["a"]["b"][1])
+
+-- output:
+-- a
+-- d=hello
+-- b
+-- 1=world.
+-- 2
+-- 1=another
+-- _attr
+-- at=Hi
+-- <?xml version="1.0" encoding="UTF-8"?>
+-- <a>
+-- <d>hello</d>
+-- <b>world.</b>
+-- <b at="Hi">
+-- another
+-- </b>
+-- </a>
+--
+-- world.
+\end{verbatim}
+
+Note that |simpleTreeHandler| creates tables that can be easily accessed using standard lua functions, but in case of mixed content, like
+\begin{verbatim}
+<a>hello
+ <b>world</b>
+</a>
+\end{verbatim}
+it produces wrong results. It is useful mostly for data |xml| files, not for text formats like |xhtml|.
+
+Because at the moment it is intended mainly as support for the odsfile package, there is little documentation,
+what follows is the original documentation of |LuaXML|, which may be little bit obsolete now.
+
+\clearpage
+\noindent{\Huge Original documentation}
+\medskip
+
+\noindent This document was created automatically from original source code comments using Pandoc\footnote{\url{http://johnmacfarlane.net/pandoc/}}
+
+\section{Overview}
+
+
+This module provides a non-validating XML stream parser in Lua.
+\section{Features}
+
+\begin{itemize}
+\item
+ Tokenises well-formed XML (relatively robustly)
+\item
+ Flexible handler based event api (see below)
+\item
+ Parses all XML Infoset elements - ie.
+ \begin{itemize}
+ \item
+ Tags
+ \item
+ Text
+ \item
+ Comments
+ \item
+ CDATA
+ \item
+ XML Decl
+ \item
+ Processing Instructions
+ \item
+ DOCTYPE declarations
+ \end{itemize}
+\item
+ Provides limited well-formedness checking (checks for basic syntax \&
+ balanced tags only)
+\item
+ Flexible whitespace handling (selectable)
+\item
+ Entity Handling (selectable)
+\end{itemize}
+\section{Limitations}
+
+\begin{itemize}
+\item
+ Non-validating
+\item
+ No charset handling
+\item
+ No namespace support
+\item
+ Shallow well-formedness checking only (fails to detect most semantic
+ errors)
+\end{itemize}
+\section{API}
+
+The parser provides a partially object-oriented API with functionality
+split into tokeniser and hanlder components.
+
+The handler instance is passed to the tokeniser and receives callbacks
+for each XML element processed (if a suitable handler function is
+defined). The API is conceptually similar to the SAX API but implemented
+differently.
+
+The following events are generated by the tokeniser
+
+\begin{verbatim}
+handler:start - Start Tag
+handler:end - End Tag
+handler:text - Text
+handler:decl - XML Declaration
+handler:pi - Processing Instruction
+handler:comment - Comment
+handler:dtd - DOCTYPE definition
+handler:cdata - CDATA
+\end{verbatim}
+The function prototype for all the callback functions is
+
+\begin{verbatim}
+callback(val,attrs,start,end)
+\end{verbatim}
+where attrs is a table and val/attrs are overloaded for specific
+callbacks - ie.
+
+\begin{tabular}{llp{5cm}}
+Callback & val & attrs (table)\\
+\hline
+start & name & |{ attributes (name=val).. }|\\
+end & name & nil\\
+text & |<text>| & nil\\
+cdata & |<text> | & nil\\
+decl & "xml" & |{ attributes (name=val).. }|\\
+pi & pi name & \begin{verbatim}{ attributes (if present)..
+ _text = <PI Text>
+}\end{verbatim}\\
+comment & |<text>| & nil\\
+dtd & root element & \begin{verbatim}{ _root = <Root Element>,
+ _type = SYSTEM|PUBLIC,
+ _name = <name>,
+ _uri = <uri>,
+ _internal = <internal dtd>
+}\end{verbatim}\\
+\end{tabular}
+
+(start \& end provide the character positions of the start/end of the
+element)
+
+XML data is passed to the parser instance through the `parse' method
+(Nore: must be passed a single string currently)
+
+\section{Options}
+
+Parser options are controlled through the `self.options' table.
+Available options are -
+
+\begin{itemize}
+\item
+ stripWS
+
+ Strip non-significant whitespace (leading/trailing) and do not
+ generate events for empty text elements
+\item
+ expandEntities
+
+ Expand entities (standard entities + single char numeric entities only
+ currently - could be extended at runtime if suitable DTD parser added
+ elements to table (see obj.\_ENTITIES). May also be possible to expand
+ multibyre entities for UTF--8 only
+\item
+ errorHandler
+
+ Custom error handler function
+\end{itemize}
+NOTE: Boolean options must be set to `nil' not `0'
+
+\section{Usage}
+
+Create a handler instance -
+
+\begin{verbatim}
+h = { start = function(t,a,s,e) .... end,
+ end = function(t,a,s,e) .... end,
+ text = function(t,a,s,e) .... end,
+ cdata = text }
+\end{verbatim}
+(or use predefined handler - see luaxml-mod-handler.lua)
+
+Create parser instance -
+
+\begin{verbatim}
+p = xmlParser(h)
+\end{verbatim}
+Set options -
+
+\begin{verbatim}
+p.options.xxxx = nil
+\end{verbatim}
+Parse XML data -
+
+\begin{verbatim}
+xmlParser:parse("<?xml... ")
+\end{verbatim}
+\section{Handlers}\label{sec:handlers}
+
+\subsection{Overview}
+
+Standard XML event handler(s) for XML parser module (luaxml-mod-xml.lua)
+
+\subsection{Features}
+
+\begin{verbatim}
+printHandler - Generate XML event trace
+domHandler - Generate DOM-like node tree
+simpleTreeHandler - Generate 'simple' node tree
+simpleTeXhandler - SAX like handler with support for CSS selectros
+\end{verbatim}
+\subsection{API}
+
+Must be called as handler function from xmlParser and implement XML
+event callbacks (see xmlParser.lua for callback API definition)
+
+\subsubsection{printHandler}
+
+printHandler prints event trace for debugging
+
+\subsubsection{domHandler}
+
+domHandler generates a DOM-like node tree structure with
+a single ROOT node parent - each node is a table comprising
+fields below.
+
+\begin{verbatim}
+node = { _name = <Element Name>,
+ _type = ROOT|ELEMENT|TEXT|COMMENT|PI|DECL|DTD,
+ _attr = { Node attributes - see callback API },
+ _parent = <Parent Node>
+ _children = { List of child nodes - ROOT/NODE only }
+ }
+
+\end{verbatim}
+The dom structure is capable of representing any valid XML document
+\subsubsection{simpleTreeHandler}
+
+simpleTreeHandler is a simplified handler which attempts to generate a
+more `natural' table based structure which supports many common XML
+formats.
+
+The XML tree structure is mapped directly into a recursive table
+structure with node names as keys and child elements as either a table
+of values or directly as a string value for text. Where there is only a
+single child element this is inserted as a named key - if there are
+multiple elements these are inserted as a vector (in some cases it may
+be preferable to always insert elements as a vector which can be
+specified on a per element basis in the options). Attributes are
+inserted as a child element with a key of `\_attr'.
+
+Only Tag/Text \& CDATA elements are processed - all others are ignored.
+
+This format has some limitations - primarily
+
+\begin{itemize}
+\item Mixed-Content behaves unpredictably - the relationship between text
+ elements and embedded tags is lost and multiple levels of mixed
+ content does not work
+\item If a leaf element has both a text element and attributes then the text
+ must be accessed through a vector (to provide a container for the
+ attribute)
+\end{itemize}
+In general however this format is relatively useful.
+
+
+\subsection{Options}
+
+\begin{verbatim}
+simpleTreeHandler.options.noReduce = { <tag> = bool,.. }
+
+ - Nodes not to reduce children vector even if only
+ one child
+
+domHandler.options.(comment|pi|dtd|decl)Node = bool
+
+ - Include/exclude given node types
+\end{verbatim}
+\subsection{Usage}
+
+Pased as delegate in xmlParser constructor and called as callback by
+xmlParser:parse(xml) method.
+
+\section{History}
+
+This library is fork of LuaXML library originaly created by Paul
+Chakravarti. Its original version can be found at
+\url{http://manoelcampos.com/files/LuaXML--0.0.0-lua5.1.tgz}. Some files not
+needed for use with luatex were droped from the distribution.
+Documentation was converted from original comments in the source code.
+
+\section{License}
+
+This code is freely distributable under the terms of the Lua license
+(\url{http://www.lua.org/copyright.html})
+\end{document}
diff --git a/Master/texmf-dist/tex/luatex/luaxml/luaxml-mod-handler.lua b/Master/texmf-dist/tex/luatex/luaxml/luaxml-mod-handler.lua
new file mode 100644
index 00000000000..bc4d8ea9120
--- /dev/null
+++ b/Master/texmf-dist/tex/luatex/luaxml/luaxml-mod-handler.lua
@@ -0,0 +1,338 @@
+module(...,package.seeall)
+--
+-- Overview:
+-- =========
+-- Standard XML event handler(s) for XML parser module (xml.lua)
+--
+-- Features:
+-- =========
+-- printHandler - Generate XML event trace
+-- domHandler - Generate DOM-like node tree
+-- simpleTreeHandler - Generate 'simple' node tree
+-- simpleTeXhandler - SAX like handler with support for CSS selectros
+--
+-- API:
+-- ====
+-- Must be called as handler function from xmlParser
+-- and implement XML event callbacks (see xmlParser.lua
+-- for callback API definition)
+--
+-- printHandler:
+-- -------------
+--
+-- printHandler prints event trace for debugging
+--
+-- domHandler:
+-- -----------
+--
+-- domHandler generates a DOM-like node tree structure with
+-- a single ROOT node parent - each node is a table comprising
+-- fields below.
+--
+-- node = { _name = <Element Name>,
+-- _type = ROOT|ELEMENT|TEXT|COMMENT|PI|DECL|DTD,
+-- _attr = { Node attributes - see callback API },
+-- _parent = <Parent Node>
+-- _children = { List of child nodes - ROOT/NODE only }
+-- }
+--
+-- The dom structure is capable of representing any valid XML document
+--
+-- simpleTreeHandler
+-- -----------------
+--
+-- simpleTreeHandler is a simplified handler which attempts
+-- to generate a more 'natural' table based structure which
+-- supports many common XML formats.
+--
+-- The XML tree structure is mapped directly into a recursive
+-- table structure with node names as keys and child elements
+-- as either a table of values or directly as a string value
+-- for text. Where there is only a single child element this
+-- is inserted as a named key - if there are multiple
+-- elements these are inserted as a vector (in some cases it
+-- may be preferable to always insert elements as a vector
+-- which can be specified on a per element basis in the
+-- options). Attributes are inserted as a child element with
+-- a key of '_attr'.
+--
+-- Only Tag/Text & CDATA elements are processed - all others
+-- are ignored.
+--
+-- This format has some limitations - primarily
+--
+-- * Mixed-Content behaves unpredictably - the relationship
+-- between text elements and embedded tags is lost and
+-- multiple levels of mixed content does not work
+-- * If a leaf element has both a text element and attributes
+-- then the text must be accessed through a vector (to
+-- provide a container for the attribute)
+--
+-- In general however this format is relatively useful.
+--
+-- It is much easier to understand by running some test
+-- data through 'textxml.lua -simpletree' than to read this)
+--
+-- Options
+-- =======
+-- simpleTreeHandler.options.noReduce = { <tag> = bool,.. }
+--
+-- - Nodes not to reduce children vector even if only
+-- one child
+--
+-- domHandler.options.(comment|pi|dtd|decl)Node = bool
+--
+-- - Include/exclude given node types
+--
+-- Usage
+-- =====
+-- Pased as delegate in xmlParser constructor and called
+-- as callback by xmlParser:parse(xml) method.
+--
+-- See textxml.lua for examples
+-- License:
+-- ========
+--
+-- This code is freely distributable under the terms of the Lua license
+-- (<a href="http://www.lua.org/copyright.html">http://www.lua.org/copyright.html</a>)
+--
+-- History
+-- =======
+-- $Id: handler.lua,v 1.1.1.1 2001/11/28 06:11:33 paulc Exp $
+--
+-- $Log: handler.lua,v $
+-- Revision 1.1.1.1 2001/11/28 06:11:33 paulc
+-- Initial Import
+--@author Paul Chakravarti (paulc@passtheaardvark.com)<p/>
+
+
+---Handler to generate a string prepresentation of a table
+--Convenience function for printHandler (Does not support recursive tables).
+--@param t Table to be parsed
+--@returns Returns a string representation of table
+
+local stack = require("luaxml-stack")
+
+function showTable(t)
+ local sep = ''
+ local res = ''
+ if type(t) ~= 'table' then
+ return t
+ end
+ for k,v in pairs(t) do
+ if type(v) == 'table' then
+ v = showTable(v)
+ end
+ res = res .. sep .. string.format("%s=%s",k,v)
+ sep = ','
+ end
+ res = '{'..res..'}'
+ return res
+end
+
+---Handler to generate a simple event trace
+printHandler = function()
+ local obj = {}
+ obj.starttag = function(self,t,a,s,e)
+ io.write("Start : "..t.."\n")
+ if a then
+ for k,v in pairs(a) do
+ io.write(string.format(" + %s='%s'\n",k,v))
+ end
+ end
+ end
+ obj.endtag = function(self,t,s,e)
+ io.write("End : "..t.."\n")
+ end
+ obj.text = function(self,t,s,e)
+ io.write("Text : "..t.."\n")
+ end
+ obj.cdata = function(self,t,s,e)
+ io.write("CDATA : "..t.."\n")
+ end
+ obj.comment = function(self,t,s,e)
+ io.write("Comment : "..t.."\n")
+ end
+ obj.dtd = function(self,t,a,s,e)
+ io.write("DTD : "..t.."\n")
+ if a then
+ for k,v in pairs(a) do
+ io.write(string.format(" + %s='%s'\n",k,v))
+ end
+ end
+ end
+ obj.pi = function(self,t,a,s,e)
+ io.write("PI : "..t.."\n")
+ if a then
+ for k,v in pairs(a) do
+ io. write(string.format(" + %s='%s'\n",k,v))
+ end
+ end
+ end
+ obj.decl = function(self,t,a,s,e)
+ io.write("XML Decl : "..t.."\n")
+ if a then
+ for k,v in pairs(a) do
+ io.write(string.format(" + %s='%s'\n",k,v))
+ end
+ end
+ end
+ return obj
+end
+
+---Handler to generate a lua table from a XML content string
+function simpleTreeHandler()
+ local obj = {}
+
+ obj.root = {}
+ obj.stack = {obj.root;n=1}
+ obj.options = {noreduce = {}}
+
+ obj.reduce = function(self,node,key,parent)
+ -- Recursively remove redundant vectors for nodes
+ -- with single child elements
+ for k,v in pairs(node) do
+ if type(v) == 'table' then
+ self:reduce(v,k,node)
+ end
+ end
+ if table.getn(node) == 1 and not self.options.noreduce[key] and
+ node._attr == nil then
+ parent[key] = node[1]
+ else
+ node.n = nil
+ end
+ end
+
+ obj.starttag = function(self,t,a)
+ local node = {}
+ if self.parseAttributes == true then
+ node._attr=a
+ end
+
+ local current = self.stack[table.getn(self.stack)]
+ if current[t] then
+ table.insert(current[t],node)
+ else
+ current[t] = {node;n=1}
+ end
+ table.insert(self.stack,node)
+ end
+
+ obj.endtag = function(self,t,s)
+ local current = self.stack[table.getn(self.stack)]
+ local prev = self.stack[table.getn(self.stack)-1]
+ if not prev[t] then
+ error("XML Error - Unmatched Tag ["..s..":"..t.."]\n")
+ end
+ if prev == self.root then
+ -- Once parsing complete recursively reduce tree
+ self:reduce(prev,nil,nil)
+ end
+ table.remove(self.stack)
+ end
+
+ obj.text = function(self,t)
+ local current = self.stack[table.getn(self.stack)]
+ table.insert(current,t)
+ end
+
+ obj.cdata = obj.text
+
+ return obj
+end
+
+
+
+--- domHandler
+function domHandler()
+ local obj = {}
+ obj.options = {commentNode=1,piNode=1,dtdNode=1,declNode=1}
+ obj.root = { _children = {n=0}, _type = "ROOT" }
+ obj.current = obj.root
+ obj.starttag = function(self,t,a)
+ local node = { _type = 'ELEMENT',
+ _name = t,
+ _attr = a,
+ _parent = self.current,
+ _children = {n=0} }
+ table.insert(self.current._children,node)
+ self.current = node
+ end
+ obj.endtag = function(self,t,s)
+ if t ~= self.current._name then
+ error("XML Error - Unmatched Tag ["..s..":"..t.."]\n")
+ end
+ self.current = self.current._parent
+ end
+ obj.text = function(self,t)
+ local node = { _type = "TEXT",
+ _parent = self.current,
+ _text = t }
+ table.insert(self.current._children,node)
+ end
+ obj.comment = function(self,t)
+ if self.options.commentNode then
+ local node = { _type = "COMMENT",
+ _parent = self.current,
+ _text = t }
+ table.insert(self.current._children,node)
+ end
+ end
+ obj.pi = function(self,t,a)
+ if self.options.piNode then
+ local node = { _type = "PI",
+ _name = t,
+ _attr = a,
+ _parent = self.current }
+ table.insert(self.current._children,node)
+ end
+ end
+ obj.decl = function(self,t,a)
+ if self.options.declNode then
+ local node = { _type = "DECL",
+ _name = t,
+ _attr = a,
+ _parent = self.current }
+ table.insert(self.current._children,node)
+ end
+ end
+ obj.dtd = function(self,t,a)
+ if self.options.dtdNode then
+ local node = { _type = "DTD",
+ _name = t,
+ _attr = a,
+ _parent = self.current }
+ table.insert(self.current._children,node)
+ end
+ end
+ obj.cdata = obj.text
+ return obj
+end
+
+--
+simpleTeXhandler=function()
+ local obj={}
+ local _stack=stack.Stack:Create()
+ obj.starttag = function(self,t,a,s,e)
+ local tag = {t}
+ local getAtt = function(att)
+ if a[att] then
+ return att.."="..a[att]
+ end
+ return nil
+ end
+ if type(a) == "table" then
+ table.insert(tag,getAtt("id"))
+ table.insert(tag,getAtt("class"))
+ end
+ _stack:push("<"..table.concat(tag," ")..">")
+ io.write(_stack:join("").."\n")
+-- io.write("Start "..t.."\n" )
+ end
+ obj.endtag = function(self,t,s,e)
+ _stack:pop()
+ -- io.write("End : "..t.."\n")
+ end
+ return obj
+end
diff --git a/Master/texmf-dist/tex/luatex/luaxml/luaxml-mod-xml.lua b/Master/texmf-dist/tex/luatex/luaxml/luaxml-mod-xml.lua
new file mode 100644
index 00000000000..f3ebb0445e8
--- /dev/null
+++ b/Master/texmf-dist/tex/luatex/luaxml/luaxml-mod-xml.lua
@@ -0,0 +1,547 @@
+module(...,package.seeall)
+---
+-- Overview:
+-- =========
+--
+-- This module provides a non-validating XML stream parser in Lua.
+--
+-- Features:
+-- =========
+--
+-- * Tokenises well-formed XML (relatively robustly)
+-- * Flexible handler based event api (see below)
+-- * Parses all XML Infoset elements - ie.
+-- - Tags
+-- - Text
+-- - Comments
+-- - CDATA
+-- - XML Decl
+-- - Processing Instructions
+-- - DOCTYPE declarations
+-- * Provides limited well-formedness checking
+-- (checks for basic syntax & balanced tags only)
+-- * Flexible whitespace handling (selectable)
+-- * Entity Handling (selectable)
+--
+-- Limitations:
+-- ============
+--
+-- * Non-validating
+-- * No charset handling
+-- * No namespace support
+-- * Shallow well-formedness checking only (fails
+-- to detect most semantic errors)
+--
+-- API:
+-- ====
+--
+-- The parser provides a partially object-oriented API with
+-- functionality split into tokeniser and hanlder components.
+--
+-- The handler instance is passed to the tokeniser and receives
+-- callbacks for each XML element processed (if a suitable handler
+-- function is defined). The API is conceptually similar to the
+-- SAX API but implemented differently.
+--
+-- The following events are generated by the tokeniser
+--
+-- handler:start - Start Tag
+-- handler:end - End Tag
+-- handler:text - Text
+-- handler:decl - XML Declaration
+-- handler:pi - Processing Instruction
+-- handler:comment - Comment
+-- handler:dtd - DOCTYPE definition
+-- handler:cdata - CDATA
+--
+-- The function prototype for all the callback functions is
+--
+-- callback(val,attrs,start,end)
+--
+-- where attrs is a table and val/attrs are overloaded for
+-- specific callbacks - ie.
+--
+-- Callback val attrs (table)
+-- -------- --- -------------
+-- start name { attributes (name=val).. }
+-- end name nil
+-- text <text> nil
+-- cdata <text> nil
+-- decl "xml" { attributes (name=val).. }
+-- pi pi name { attributes (if present)..
+-- _text = <PI Text>
+-- }
+-- comment <text> nil
+-- dtd root element { _root = <Root Element>,
+-- _type = SYSTEM|PUBLIC,
+-- _name = <name>,
+-- _uri = <uri>,
+-- _internal = <internal dtd>
+-- }
+--
+-- (start & end provide the character positions of the start/end
+-- of the element)
+--
+-- XML data is passed to the parser instance through the 'parse'
+-- method (Nore: must be passed a single string currently)
+--
+-- Options
+-- =======
+--
+-- Parser options are controlled through the 'self.options' table.
+-- Available options are -
+--
+-- * stripWS
+--
+-- Strip non-significant whitespace (leading/trailing)
+-- and do not generate events for empty text elements
+--
+-- * expandEntities
+--
+-- Expand entities (standard entities + single char
+-- numeric entities only currently - could be extended
+-- at runtime if suitable DTD parser added elements
+-- to table (see obj._ENTITIES). May also be possible
+-- to expand multibyre entities for UTF-8 only
+--
+-- * errorHandler
+--
+-- Custom error handler function
+--
+-- NOTE: Boolean options must be set to 'nil' not '0'
+--
+-- Usage
+-- =====
+--
+-- Create a handler instance -
+--
+-- h = { start = function(t,a,s,e) .... end,
+-- end = function(t,a,s,e) .... end,
+-- text = function(t,a,s,e) .... end,
+-- cdata = text }
+--
+-- (or use predefined handler - see handler.lua)
+--
+-- Create parser instance -
+--
+-- p = xmlParser(h)
+--
+-- Set options -
+--
+-- p.options.xxxx = nil
+--
+-- Parse XML data -
+--
+-- xmlParser:parse("<?xml... ")
+-- License:
+-- ========
+--
+-- This code is freely distributable under the terms of the Lua license
+-- (http://www.lua.org/copyright.html)
+--
+-- History
+-- =======
+-- Fixed some errors in DTD matching
+-- Added functions serialize and xmlEscape
+-- by Michal Hoftich
+-- 2012/07/26
+--
+-- Added parameter parseAttributes (boolean) in xmlParser.parse method
+-- If true, tag attributtes are parsed. The default value is true.
+-- by Manoel Campos (http://manoelcampos.com)
+--
+-- $Id: xml.lua,v 1.1.1.1 2001/11/28 06:11:33 paulc Exp $
+--
+-- $Log: xml.lua,v $
+-- Revision 1.1.1.1 2001/11/28 06:11:33 paulc
+-- Initial Import
+--
+--@author Paul Chakravarti (paulc@passtheaardvark.com)<p/>
+
+local format= string.format
+---Parses a XML string
+--@param handler Handler object to be used to convert the XML string
+--to another formats. @see handler.lua
+xmlParser = function(handler)
+ local obj = {}
+ -- Public attributes
+
+ obj.options = {
+ stripWS = 1,
+ expandEntities = 1,
+ errorHandler = function(err,pos)
+ error(format("%s [char=%d]\n",
+ err or "Parse Error",pos))
+ end,
+ }
+
+ -- Public methods
+
+ obj.parse = function(self, str, parseAttributes)
+ if parseAttributes == nil then
+ parseAttributes = true
+ end
+ self._handler.parseAttributes = parseAttributes
+
+ local match,endmatch,pos = 0,0,1
+ local text,endt1,endt2,tagstr,tagname,attrs,starttext,endtext
+ local errstart,errend,extstart,extend
+ while match do
+ -- Get next tag (first pass - fix exceptions below)
+ match,endmatch,text,endt1,tagstr,endt2 = string.find(str,self._XML,pos)
+ if not match then
+ if string.find(str,self._WS,pos) then
+ -- No more text - check document complete
+ if table.getn(self._stack) ~= 0 then
+ self:_err(self._errstr.incompleteXmlErr,pos)
+ else
+ break
+ end
+ else
+ -- Unparsable text
+ self:_err(self._errstr.xmlErr,pos)
+ end
+ end
+ -- Handle leading text
+ starttext = match
+ endtext = match + string.len(text) - 1
+ match = match + string.len(text)
+ text = self:_parseEntities(self:_stripWS(text))
+ if text ~= "" and self._handler.text then
+ self._handler:text(text,nil,match,endtext)
+ end
+ -- Test for tag type
+ if string.find(string.sub(tagstr,1,5),"?xml%s") then
+ -- XML Declaration
+ match,endmatch,text = string.find(str,self._PI,pos)
+ if not match then
+ self:_err(self._errstr.declErr,pos)
+ end
+ if match ~= 1 then
+ -- Must be at start of doc if present
+ self:_err(self._errstr.declStartErr,pos)
+ end
+ tagname,attrs = self:_parseTag(text)
+ -- TODO: Check attributes are valid
+ -- Check for version (mandatory)
+ if attrs.version == nil then
+ self:_err(self._errstr.declAttrErr,pos)
+ end
+ if self._handler.decl then
+ self._handler:decl(tagname,attrs,match,endmatch)
+ end
+ elseif string.sub(tagstr,1,1) == "?" then
+ -- Processing Instruction
+ match,endmatch,text = string.find(str,self._PI,pos)
+ if not match then
+ self:_err(self._errstr.piErr,pos)
+ end
+ if self._handler.pi then
+ -- Parse PI attributes & text
+ tagname,attrs = self:_parseTag(text)
+ local pi = string.sub(text,string.len(tagname)+1)
+ if pi ~= "" then
+ if attrs then
+ attrs._text = pi
+ else
+ attrs = { _text = pi }
+ end
+ end
+ self._handler:pi(tagname,attrs,match,endmatch)
+ end
+ elseif string.sub(tagstr,1,3) == "!--" then
+ -- Comment
+ match,endmatch,text = string.find(str,self._COMMENT,pos)
+ if not match then
+ self:_err(self._errstr.commentErr,pos)
+ end
+ if self._handler.comment then
+ text = self:_parseEntities(self:_stripWS(text))
+ self._handler:comment(text,next,match,endmatch)
+ end
+ elseif string.sub(tagstr,1,8) == "!DOCTYPE" then
+ -- DTD
+ --match,endmatch,attrs = self:_parseDTD(string,pos)
+ match,endmatch,attrs = self:_parseDTD(str,pos)
+ if not match then
+ self:_err(self._errstr.dtdErr,pos)
+ end
+ if self._handler.dtd then
+ self._handler:dtd(attrs._root,attrs,match,endmatch)
+ end
+ elseif string.sub(tagstr,1,8) == "![CDATA[" then
+ -- CDATA
+ match,endmatch,text = string.find(str,self._CDATA,pos)
+ if not match then
+ self:_err(self._errstr.cdataErr,pos)
+ end
+ if self._handler.cdata then
+ self._handler:cdata(text,nil,match,endmatch)
+ end
+ else
+ -- Normal tag
+
+ -- Need theck for embedded '>' in attribute value and extend
+ -- match recursively if necessary eg. <tag attr="123>456">
+
+ while 1 do
+ errstart,errend = string.find(tagstr,self._ATTRERR1)
+ if errend == nil then
+ errstart,errend = string.find(tagstr,self._ATTRERR2)
+ if errend == nil then
+ break
+ end
+ end
+ extstart,extend,endt2 = string.find(str,self._TAGEXT,endmatch+1)
+ tagstr = tagstr .. string.sub(string,endmatch,extend-1)
+ if not match then
+ self:_err(self._errstr.xmlErr,pos)
+ end
+ endmatch = extend
+ end
+
+ -- Extract tagname/attrs
+
+ tagname,attrs = self:_parseTag(tagstr)
+
+ if (endt1=="/") then
+ -- End tag
+ if self._handler.endtag then
+ if attrs then
+ -- Shouldnt have any attributes in endtag
+ self:_err(format("%s (/%s)",
+ self._errstr.endTagErr,
+ tagname)
+ ,pos)
+ end
+ if table.remove(self._stack) ~= tagname then
+ self:_err(format("%s (/%s)",
+ self._errstr.unmatchedTagErr,
+ tagname)
+ ,pos)
+ end
+ self._handler:endtag(tagname,nil,match,endmatch)
+ end
+ else
+ -- Start Tag
+ table.insert(self._stack,tagname)
+ if self._handler.starttag then
+ self._handler:starttag(tagname,attrs,match,endmatch)
+ end
+ -- Self-Closing Tag
+ if (endt2=="/") then
+ table.remove(self._stack)
+ if self._handler.endtag then
+ self._handler:endtag(tagname,nil,match,endmatch)
+ end
+ end
+ end
+ end
+ pos = endmatch + 1
+ end
+ end
+
+ -- Private attrobures/functions
+
+ obj._handler = handler
+ obj._stack = {}
+
+ obj._XML = '^([^<]*)<(%/?)([^>]-)(%/?)>'
+ obj._ATTR1 = '([%w-:_]+)%s*=%s*"(.-)"'
+ obj._ATTR2 = '([%w-:_]+)%s*=%s*\'(.-)\''
+ obj._CDATA = '<%!%[CDATA%[(.-)%]%]>'
+ obj._PI = '<%?(.-)%?>'
+ obj._COMMENT = '<!%-%-(.-)%-%->'
+ obj._TAG = '^(.-)%s.*'
+ obj._LEADINGWS = '^%s+'
+ obj._TRAILINGWS = '%s+$'
+ obj._WS = '^%s*$'
+ obj._DTD1 = '<!DOCTYPE%s+(.-)%s+(SYSTEM)%s+["\'](.-)["\']%s*(%b[])%s*>'
+ obj._DTD2 = '<!DOCTYPE%s+(.-)%s+(PUBLIC)%s+["\'](.-)["\']%s+["\'](.-)["\']%s*(%b[])%s*>'
+ obj._DTD3 = '<!DOCTYPE%s+(.-)%s*(%b[])%s*>'
+ obj._DTD4 = '<!DOCTYPE%s+(.-)%s+(SYSTEM)%s+["\'](.-)["\']%s*>'
+ obj._DTD5 = '<!DOCTYPE%s+(.-)%s+(PUBLIC)%s+["\'](.-)["\']%s+["\'](.-)["\']%s*>'
+ --obj._DTD6 = "<!DOCTYPE%s+(.-)%s+(PUBLIC)%s+[\"'](.-)[\"']%s+[\"'](.-)[\"']%s*>"
+
+ obj._ATTRERR1 = '=%s*"[^"]*$'
+ obj._ATTRERR2 = '=%s*\'[^\']*$'
+ obj._TAGEXT = '(%/?)>'
+
+ obj._ENTITIES = { ["&lt;"] = "<",
+ ["&gt;"] = ">",
+ ["&amp;"] = "&",
+ ["&quot;"] = '"',
+ ["&apos;"] = "'",
+ ["&#(%d+);"] = function (x)
+ local d = tonumber(x)
+ if d >= 0 and d < 256 then
+ return string.char(d)
+ else
+ return "&#"..d..";"
+ end
+ end,
+ ["&#x(%x+);"] = function (x)
+ local d = tonumber(x,16)
+ if d >= 0 and d < 256 then
+ return string.char(d)
+ else
+ return "&#x"..x..";"
+ end
+ end,
+ }
+
+ obj._err = function(self,err,pos)
+ if self.options.errorHandler then
+ self.options.errorHandler(err,pos)
+ end
+ end
+
+ obj._errstr = { xmlErr = "Error Parsing XML",
+ declErr = "Error Parsing XMLDecl",
+ declStartErr = "XMLDecl not at start of document",
+ declAttrErr = "Invalid XMLDecl attributes",
+ piErr = "Error Parsing Processing Instruction",
+ commentErr = "Error Parsing Comment",
+ cdataErr = "Error Parsing CDATA",
+ dtdErr = "Error Parsing DTD",
+ endTagErr = "End Tag Attributes Invalid",
+ unmatchedTagErr = "Unbalanced Tag",
+ incompleteXmlErr = "Incomplete XML Document",
+ }
+
+ obj._stripWS = function(self,s)
+ if self.options.stripWS then
+ s = string.gsub(s,'^%s+','')
+ s = string.gsub(s,'%s+$','')
+ end
+ return s
+ end
+
+ obj._parseEntities = function(self,s)
+ if self.options.expandEntities then
+ --for k,v in self._ENTITIES do
+ for k,v in pairs(self._ENTITIES) do
+ --print (k, v)
+ s = string.gsub(s,k,v)
+ end
+ end
+ return s
+ end
+
+ obj._parseDTD = function(self,s,pos)
+ -- match,endmatch,root,type,name,uri,internal
+ --print(s.." : "..pos)
+ local m,e,r,t,n,u,i
+ m,e,r,t,n,u = string.find(s,self._DTD5,pos)
+ if m then
+ return m,e,{_root=r,_type=t,_name=n,_uri=u}
+ end
+ m,e,r,t,u,i = string.find(s,self._DTD1,pos)
+ if m then
+ return m,e,{_root=r,_type=t,_uri=u,_internal=i}
+ end
+ m,e,r,t,n,u,i = string.find(s,self._DTD2,pos)
+ if m then
+ return m,e,{_root=r,_type=t,_name=n,_uri=u,_internal=i}
+ end
+ m,e,r,i = string.find(s,self._DTD3,pos)
+ if m then
+ return m,e,{_root=r,_internal=i}
+ end
+ m,e,r,t,u = string.find(s,self._DTD4,pos)
+ if m then
+ return m,e,{_root=r,_type=t,_uri=u}
+ end
+ return nil
+ end
+
+ obj._parseTag = function(self,s)
+ local attrs = {}
+ local tagname = string.gsub(s,self._TAG,'%1')
+ string.gsub(s,self._ATTR1,function (k,v)
+ attrs[string.lower(k)]=self:_parseEntities(v)
+ attrs._ = 1
+ end)
+ string.gsub(s,self._ATTR2,function (k,v)
+ attrs[string.lower(k)]=self:_parseEntities(v)
+ attrs._ = 1
+ end)
+ if attrs._ then
+ attrs._ = nil
+ else
+ attrs = nil
+ end
+ return tagname,attrs
+ end
+
+ return obj
+
+end
+
+function xmlEscape(s)
+ local t = {['"']="&quot;",["'"]="&apos;",["&"]="&amp;",["<"]="&lt;",[">"]="&gt;"}
+ return string.gsub(s,"([\"'<>&])",t)
+end
+
+
+
+function serialize(tb)
+local function getAttributes(k,v)
+ local i = ""
+ if(type(v["_attr"])=="table") then
+ -- texio.write_nl("attr")
+ for p,n in pairs(v["_attr"]) do
+ i = i ..' '.. p .. '="'..xmlEscape(n)..'"'
+ end
+ --table.remove(v,"_attr")
+ end
+ return i
+end
+ local function printable(tb, level,currTag)
+ local r ={}
+ local currTag = currTag or ""
+ level = level or 0
+ local spaces = string.rep(' ', level*2)
+ for k,v in pairs(tb) do
+ if type(v) ~= "table" then
+ local ct = k
+ if type(k)=="number" then
+ ct = currTag
+ end
+ if ct == "" then
+ table.insert(r,spaces .. xmlEscape(v).."\n")
+ else
+ local i = getAttributes(k,v)
+ table.insert(r,spaces .. '<'..ct..i..'>'..xmlEscape(v)..'</'..ct..'>'.."\n")
+ end
+ else
+ if k == "_attr" then
+ --table.insert(r,printable(v, level))
+ else
+ if type(k)=="string" then
+ --currTag = k
+ if type(k)=="numeric" then
+ k = currTag
+ end
+ if #v > 1 then
+ table.insert(r,printable(v, level+1,k))
+ else
+ local i = getAttributes(k,v)
+ table.insert(r,spaces.."<"..k..i..">\n")
+ table.insert(r,printable(v, level+1,k))
+ table.insert(r,spaces.."</"..k..">\n")
+ end
+ else
+ local i = getAttributes(k,v)
+ table.insert(r,spaces .. "<"..currTag..i..">\n")
+ --level = level + 1
+ table.insert(r,printable(v, level+1))
+ table.insert(r,spaces .. "</"..currTag..">\n")
+ end
+ end
+ end
+ end
+ return table.concat(r,"")
+ end
+ return table.concat({'<?xml version="1.0" encoding="UTF-8"?>',printable(tb)},"\n")
+end
diff --git a/Master/texmf-dist/tex/luatex/luaxml/luaxml-selectors.lua b/Master/texmf-dist/tex/luatex/luaxml/luaxml-selectors.lua
new file mode 100644
index 00000000000..921f971eb2e
--- /dev/null
+++ b/Master/texmf-dist/tex/luatex/luaxml/luaxml-selectors.lua
@@ -0,0 +1,42 @@
+module(...,package.seeall)
+
+
+function makeTag(s)
+ return "<"..s.."[^>]*>"
+end
+function matchTag(tg)
+ return makeTag(tg)
+end
+
+function matchDescendand(a,b)
+ return makeTag(a)..makeTag(b)
+end
+
+function matchChild(a,b)
+ return makeTag(a)..".*"..makeTag(b)
+end
+
+function matchSibling(a,b)
+ return makeTag(a .. "[^>]*".."@%("..b.."[^>]*%)")
+end
+
+function matchClass(tg,class)
+ return makeTag(tg.."[^>]*class=[|]*[^>]*|"..class.."[^>]*|")
+end
+matcher = {}
+function matcher.new()
+ local self = {}
+ local selectors={}
+ function self:addSelector(sel,val)
+ selectors[sel.."$"] = val
+ end
+ function self:testPath(path,fn)
+ for k, v in pairs(selectors) do
+ if path:match(k) then
+ fn(v)
+ end
+ end
+ end
+ return self
+end
+
diff --git a/Master/texmf-dist/tex/luatex/luaxml/luaxml-stack.lua b/Master/texmf-dist/tex/luatex/luaxml/luaxml-stack.lua
new file mode 100644
index 00000000000..54386ff84d3
--- /dev/null
+++ b/Master/texmf-dist/tex/luatex/luaxml/luaxml-stack.lua
@@ -0,0 +1,63 @@
+-- Code from http://lua-users.org/wiki/SimpleStack
+module(...,package.seeall)
+Stack = {}
+
+-- Create a Table with stack functions
+function Stack:Create()
+
+ -- stack table
+ local t = {}
+ -- entry table
+ t._et = {}
+
+ -- push a value on to the stack
+ function t:push(...)
+ if ... then
+ local targs = {...}
+ -- add values
+ for _,v in pairs(targs) do
+ table.insert(self._et, v)
+ end
+ end
+ end
+
+ -- pop a value from the stack
+ function t:pop(num)
+
+ -- get num values from stack
+ local num = num or 1
+
+ -- return table
+ local entries = {}
+
+ -- get values into entries
+ for i = 1, num do
+ -- get last entry
+ if #self._et ~= 0 then
+ table.insert(entries, self._et[#self._et])
+ -- remove last value
+ table.remove(self._et)
+ else
+ break
+ end
+ end
+ -- return unpacked entries
+ return unpack(entries)
+ end
+
+ -- get entries
+ function t:getn()
+ return #self._et
+ end
+
+ -- list values
+ function t:list()
+ for i,v in pairs(self._et) do
+ print(i, v)
+ end
+ end
+ function t:join(s)
+ return table.concat(self._et,s)
+ end
+ return t
+end
diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check
index 54e6a93a55e..0d5de27a9d0 100755
--- a/Master/tlpkg/bin/tlpkg-ctan-check
+++ b/Master/tlpkg/bin/tlpkg-ctan-check
@@ -252,7 +252,7 @@ my @TLP_working = qw(
lua-alt-getopt lua-check-hyphen lua-visual-debug
lua2dox luabibentry luacode
luaindex luainputenc lualatex-doc lualatex-math lualibs luamplib luaotfload
- luapersian luasseq luatexbase luatexja luatextra
+ luapersian luasseq luatexbase luatexja luatextra luaxml
lxfonts ly1
macqassign macros2e mafr magaz magyar mailing mailmerge
makebarcode makebox makecell makecirc makecmds makedtx makeglos makeplot
diff --git a/Master/tlpkg/libexec/ctan2tds b/Master/tlpkg/libexec/ctan2tds
index 13198c3d96a..f3f8fa3309c 100755
--- a/Master/tlpkg/libexec/ctan2tds
+++ b/Master/tlpkg/libexec/ctan2tds
@@ -1320,6 +1320,7 @@ $standardtex='\.(.bx|cfg|sty|clo|ldf|cls|def|fd|cmap|4ht)$';
'lua-visual-debug', '\.lua|' . $standardtex,
'lua2dox', 'NULL', # .def is lua code
'lualatex-math', '\.sty', # not phst-doc.cls
+ 'luaxml', '\.lua|' . $standardtex,
'magyar', 'NULL', # do not install in runtime, conflicts with babel
'manjutex', '\.sty|\.clo|\.ldf|\.cls|\.def|\.fd$|manju.tex',
'math-e', 'NULL',
diff --git a/Master/tlpkg/tlpsrc/collection-luatex.tlpsrc b/Master/tlpkg/tlpsrc/collection-luatex.tlpsrc
index 5713f8fd6bf..63412456e54 100644
--- a/Master/tlpkg/tlpsrc/collection-luatex.tlpsrc
+++ b/Master/tlpkg/tlpsrc/collection-luatex.tlpsrc
@@ -24,4 +24,5 @@ depend luapersian
depend luasseq
depend luatexbase
depend luatextra
+depend luaxml
depend showhyphens
diff --git a/Master/tlpkg/tlpsrc/luaxml.tlpsrc b/Master/tlpkg/tlpsrc/luaxml.tlpsrc
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/Master/tlpkg/tlpsrc/luaxml.tlpsrc