diff options
Diffstat (limited to 'Master/texmf-dist/tex/luatex/luaxml/luaxml-sty.lua')
-rw-r--r-- | Master/texmf-dist/tex/luatex/luaxml/luaxml-sty.lua | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/luatex/luaxml/luaxml-sty.lua b/Master/texmf-dist/tex/luatex/luaxml/luaxml-sty.lua new file mode 100644 index 00000000000..35548688ce2 --- /dev/null +++ b/Master/texmf-dist/tex/luatex/luaxml/luaxml-sty.lua @@ -0,0 +1,155 @@ +--- Helper functions for the luaxml.sty package +--- @module luaxml-sty +--- @author Michal Hoftich <michal.h21@gmail.com +-- provide global object with all variables we will use +luaxml_sty = { + current = { + transformation = "default", + parameters = {}, -- "parameters" argument for transform:add_action + }, + packages = {}, + -- we want to support multiple transformation objects, they will be stored here + transformations = {}, +} +luaxml_sty.packages.transform = require "luaxml-transform" +luaxml_sty.packages.domobject = require "luaxml-domobject" + +-- declare default transformer, used if no explicit transformer is used in LuaXML LaTeX commands +luaxml_sty.transformations.default = luaxml_sty.packages.transform.new() + +-- debuggind functions +function luaxml_sty.error(...) + local arg = {...} + print("LuaXML error: " .. table.concat(arg, " ")) +end + +luaxml_sty.do_debug = false + +function luaxml_sty.debug(...) + if luaxml_sty.do_debug then + local arg = {...} + print("LuaXML: " .. table.concat(arg, " ")) + end +end + +--- Declare new transformer +---@param name string transformer name +---@return table transformer object +function luaxml_sty.declare_transformer(name) + luaxml_sty.transformations[name] = luaxml_sty.packages.transform.new() + return luaxml_sty.transformations[name] +end + + +--- Add luaxml-transform rule +--- @param current string transformer name, empty for the default object +--- @param selector string CSS selector to be used +--- @param rule string luaxml-transform rule +function luaxml_sty.add_rule(current, selector, rule) + if current == "" then + current = luaxml_sty.current.transformation + end + -- the +v parameter type in LaTeX replaces newlines with \obeyedline. we need to replace it back to newlines + rule = rule:gsub("\\obeyedline", "\n") + luaxml_sty.debug("************* luaxml_sty rule: " .. selector, rule, current, (luaxml_sty.current.parameters.verbatim and "verbatim" or "not verbatim")) + local transform = luaxml_sty.transformations[current] or luaxml_sty.declare_transformer(current) + if not transform then + luaxml_sty.error("Cannot find LuaXML transform object: " .. (current or "")) + return nil, "Cannot find LuaXML transform object: " .. (current or "") + end + transform:add_action(selector, rule, luaxml_sty.current.parameters) +end + +-- by default, we will use XML parser, so use_xml is set to true +luaxml_sty.use_xml = true + +--- Use XML parser for parsing of next snippets +function luaxml_sty.set_xml() + luaxml_sty.use_xml = true +end + + +--- Use HTML parser for parsing of next snippets +function luaxml_sty.set_html() + luaxml_sty.use_xml = false +end + +--- transform XML string and print it to the output +---@param current string transformer name, empty for the default object +---@param xml_string string to be transformed +function luaxml_sty.parse_snippet(current, xml_string) + local domobject = luaxml_sty.packages.domobject + -- get the current transformer object + if current == "" then + current = luaxml_sty.current.transformation + end + local transform = luaxml_sty.transformations[current] + if not transform then + luaxml_sty.error("Cannot load transformer: " .. current) + return nil, "Cannot load transformer: " .. current + end + local dom + -- decide if we should use XML or HTML parser + if luaxml_sty.use_xml then + dom = domobject.parse(xml_string) + else + dom = domobject.html_parse(xml_string) + end + luaxml_sty.debug(dom:serialize()) + local result = transform:process_dom(dom) + luaxml_sty.debug(result) + luaxml_sty.packages.transform.print_tex(result) +end + +--- Transform file +---@param current string transformer name, empty for the default object +---@param filename string file to be transformed +function luaxml_sty.parse_file(current, filename) + local f = io.open(filename, "r") + if not f then + luaxml_sty.packages.transform.print_tex("\\textbf{LuaXML error}: cannot find file " .. filename) + return nil, "Cannot find file " .. filename + end + local content = f:read("*a") + f:close() + luaxml_sty.parse_snippet(current, content) +end + +--- parse environment contents using Lua +---@param env_name string environment name +---@param callback_name string name which will be used in the callback registration +---@return function +-- idea from https://tex.stackexchange.com/a/574323/2891 +function luaxml_sty.store_lines(env_name, callback_name) + return function(str) + luaxml_sty.debug("str", str) + local env_str = [[\end{]] .. env_name .. "}" + if string.find (str , env_str:gsub("%*", "%%*")) then + luaxml_sty.debug("end of environment") + luatexbase.remove_from_callback ( "process_input_buffer" , callback_name) + return env_str -- str + else + table.insert(luaxml_sty.verb_table, str) + end + return "" + end +end + +--- require line grabbing for an environment +---@param env_name string environment name +function luaxml_sty.register_verbatim(env_name) + luaxml_sty.verb_table = {} + local callback_name = "luaxml_store_lines_".. env_name + local fn = luaxml_sty.store_lines(env_name, callback_name) + luatexbase.add_to_callback( + "process_input_buffer" , fn , callback_name) +end + +--- parse content of the previous environment registered using luaxml_sty.register_verbatim() +--- and print the transformed content +---@param transformer string transformer name, empty for the default object +function luaxml_sty.print_verbatim(transformer) + luaxml_sty.parse_snippet(transformer, table.concat(luaxml_sty.verb_table, "\n")) +end + +return luaxml_sty |