summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/luatex
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 /Master/texmf-dist/tex/luatex
parent99f6ebc940e504927ea38d6600f8ca9f893667bb (diff)
new luatex package luaxml (13aug12)
git-svn-id: svn://tug.org/texlive/trunk@27394 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/luatex')
-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
4 files changed, 990 insertions, 0 deletions
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