diff options
Diffstat (limited to 'macros/luatex/latex/yamlvars/YAMLvars.lua')
-rw-r--r-- | macros/luatex/latex/yamlvars/YAMLvars.lua | 369 |
1 files changed, 369 insertions, 0 deletions
diff --git a/macros/luatex/latex/yamlvars/YAMLvars.lua b/macros/luatex/latex/yamlvars/YAMLvars.lua new file mode 100644 index 0000000000..11f75edda3 --- /dev/null +++ b/macros/luatex/latex/yamlvars/YAMLvars.lua @@ -0,0 +1,369 @@ +--% Kale Ewasiuk (kalekje@gmail.com) +--% 2021-09-24 +--% +--% Copyright (C) 2021 Kale Ewasiuk +--% +--% Permission is hereby granted, free of charge, to any person obtaining a copy +--% of this software and associated documentation files (the "Software"), to deal +--% in the Software without restriction, including without limitation the rights +--% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +--% copies of the Software, and to permit persons to whom the Software is +--% furnished to do so, subject to the following conditions: +--% +--% The above copyright notice and this permission notice shall be included in +--% all copies or substantial portions of the Software. +--% +--% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +--% ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +--% TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +--% PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +--% SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +--% ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +--% ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +--% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +--% OR OTHER DEALINGS IN THE SOFTWARE. + + +-- tinyyaml license +--MIT License +-- +--Copyright (c) 2017 peposso +-- +--Permission is hereby granted, free of charge, to any person obtaining a copy +--of this software and associated documentation files (the "Software"), to deal +--in the Software without restriction, including without limitation the rights +--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +--copies of the Software, and to permit persons to whom the Software is +--furnished to do so, subject to the following conditions: +-- +--The above copyright notice and this permission notice shall be included in all +--copies or substantial portions of the Software. +-- +--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +--SOFTWARE. + + + +YAMLvars = {} -- self table +YAMLvars.xfm = {} +YAMLvars.prc = {} + +YAMLvars.varsvals = {} +YAMLvars.varspecs = {} + +YAMLvars.prcDefault = 'gdef' +YAMLvars.dftDefault = nil +YAMLvars.xfmDefault = {} + +YAMLvars.allowUndeclared = false + +YAMLvars.tabmidrule = 'hline' + +YAMLvars.yaml = require('tinyyaml') + + +-- xfm functions (transforms) -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +function YAMLvars.xfm.addxspace(var, val) + return val .. '\\xspace' +end + +function YAMLvars.xfm.tab2arr(var, val) + return pl.array2d.from_table(val) +end + +function YAMLvars.xfm.arrsort2ZA(var, val) + return pl.array2d.sortOP(val, pl.operator.strgt) +end + +function YAMLvars.xfm.addrule2arr(var, val) + return pl.array2d.map_slice2(_1..'\\\\\\'.. YAMLvars.tabmidrule..' ', val, 1,-1,-2,-1) -- todo make gmidrule +end + +function YAMLvars.xfm.arr2tabular(var, val) + return pl.array2d.toTeX(val)..'\\\\' +end + + +function YAMLvars.xfm.arr2itemize(var, val) + return pl.List(val):map('\\item '.._1):join(' ') +end + + +function YAMLvars.xfm.arrsortAZ(var, val) + return pl.List(val):sort(pl.operator.strlt) +end + +function YAMLvars.xfm.arrsortZA(var, val) + return pl.List(val):sort(pl.operator.strgt) +end + +local function complastname(a, b) + a = a:split(' ') + b = b:split(' ') + a = a[#a] + b = b[#b] + return a < b +end + +function YAMLvars.xfm.arrsortlastnameAZ(var, val) + val = pl.List(val):sort(complastname) + return val +end + +function YAMLvars.xfm.list2nl(var, val) + val = pl.array2d.map_slice1(_1..'\\\\', val, 1,-2) + return table.concat(val, '') + --return pl.tablex.reduce(_1.._2, val, '') +end + +function YAMLvars.xfm.lb2nl(var, val) + val, _ = val:gsub('\n','\\\\ ') + return val +end + +function YAMLvars.xfm.lowercase(var, val) + return val:lower() +end + + +function YAMLvars.xfm.markdown(var, val) + --return '\\begin{markdown} '..val..'\n \\end{markdown}' + help_wrt(val, md) + return [[begin markdown ..val.. + + par end markdown]] +end + + + +-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + + +-- prc functions (processing) -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + +function YAMLvars.prc.gdef(var, val) + token.set_macro(var, val, 'global') +end + +function YAMLvars.prc.yvdef(var, val) + token.set_macro('yv--'..var, val, 'global') +end + +function YAMLvars.prc.PDFtitle(var, val) + tex.print('\\hypersetup{pdftitle={'..val..'}}') + --tex.print('\\setPDFtitle{'..val..'}') +end + +function YAMLvars.prc.PDFauthor(var, val) + tex.print('\\hypersetup{pdfauthor={'..val..'}}') + --tex.print('\\setPDFauthor{'..val..'}') +end + + +function YAMLvars.prc.setheader(val, rl) + local _, count = string.gsub(val, '\\\\', '') + if count == 0 then + val = '{\\ }\\\\'..val + end + val = '\\setstretch{0.8}'..val + tex.print('\\'..rl..'ohead{'..val..'}') +end + +function YAMLvars.prc.rhead(var, val) + YAMLvars.prc.setheader(val, 'r') +end + +function YAMLvars.prc.lhead(var, val) + YAMLvars.prc.setheader(val, 'l') +end + +function YAMLvars.prc.title(var, val) + token.set_macro('@title', val, 'global') +end + +function YAMLvars.prc.author(var, val) + token.set_macro('@author', val, 'global') +end + +function YAMLvars.prc.date(var, val) + token.set_macro('@date', val, 'global') +end + + +-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + + + +local function prvcmd(cs, val) -- provide command via lua + if token.is_defined(cs) then + tex.print('\\PackageError{YAMLvars}{Variable '..cs..' already defined, could not declare}{}') + else + token.set_macro(cs, val, 'global') + end +end + +local function deccmd(cs, def) + if def == nil then + prvcmd(cs, '\\PackageError{YAMLvars}{Variable "'..cs..'" was declared and used but, not set}{}') + else + prvcmd(cs, def) + end +end + +local function getYAMLfile(y) + local f = io.open(y,"r") + if f ~= nil then + y = f:read('*a') + io.close(f) + return y + else + tex.print('\\PackageError{YAMLvars}{YAML file "'..y..'" not found}{}') + return 'YAMLvars: FileNotFound' + end +end + + +function YAMLvars.declareYAMLvarsStr(y) + local t = YAMLvars.yaml.parse(y) + for var, specs in pairs(t) do + YAMLvars.varspecs[var] = {xfm=YAMLvars.xfrmDefault,prc=YAMLvars.prcDefault,dft=YAMLvars.dftDefault} + if type(specs) == 'string' then + specs = {xfm={specs}} + end + if specs['xfm'] == nil then specs['xfm'] = {} end + for s, p in pairs(specs) do + if s == 'xfm' and type(p) ~= 'table' then p = {p} end + YAMLvars.varspecs[var][s] = p -- set property of var + end + if YAMLvars.varspecs[var]['prc'] == 'gdef' then + deccmd(var, YAMLvars.varspecs[var]['dft']) + elseif YAMLvars.varspecs[var]['prc'] == 'yvdef' then + deccmd('yv--'..var, YAMLvars.varspecs[var]['dft']) + end + end +end + +function YAMLvars.declareYAMLvarsFile(y) + YAMLvars.declareYAMLvarsStr(getYAMLfile(y)) +end + +function YAMLvars.parseYAMLvarsStr(y) + YAMLvars.varsvals = YAMLvars.yaml.parse(y) + for var, val in pairs(YAMLvars.varsvals) do + if YAMLvars.varspecs[var] == nil then + if YAMLvars.allowUndeclared then + if YAMLvars.prcDefault == 'yvdef' then + YAMLvars.prc.yvdef(var, val) + else + prvcmd(var, val) + end + else + tex.print('\\PackageError{YAMLvars}{Variable "'..var..'" set but not declared}{}') + end + else + --if string.sub(val, 1, 2) == '~' then -- todo + -- val = t[string.sub(val, 2, #val)] -- use other val + --end + for _, func in pairs(YAMLvars.varspecs[var]['xfm']) do --apply cleaning functions + local f = YAMLvars.xfm[func] + if f == nil then + tex.print('\\PackageWarning{YAMLvars}{xfm function "'..func..'" not defined, skipping}{}') + else + val = f(var, val) + end + end + f = YAMLvars.prc[YAMLvars.varspecs[var]['prc']] + if f == nil then + tex.print('\\PackageError{YAMLvars}{prc function "'..YAMLvars.varspecs[var]['prc']..'" not defined}{}') + end + f(var, val) -- prc the value of the variable + end + end +end + +function YAMLvars.parseYAMLvarsFile(y) + YAMLvars.parseYAMLvarsStr(getYAMLfile(y)) +end + + + +function YAMLvars.print_varspecs() + local pretty = require('pl.pretty') + texio.write_nl('VVVVVV Var specifications:') + texio.write_nl(pretty.write(YAMLvars.varspecs)) +end + + + +-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + +-- https://tex.stackexchange.com/questions/38150/in-lualatex-how-do-i-pass-the-content-of-an-environment-to-lua-verbatim +recordedbuf = "" +function readbuf(buf) + i,j = string.find(buf, '\\end{%w+}') + if i==nil then -- if not ending an environment + recordedbuf = recordedbuf .. buf .. "\n" + return "" + else + return nil + end +end + +function startrecording() + recordedbuf = "" + luatexbase.add_to_callback('process_input_buffer', readbuf, 'readbuf') +end + +function stoprecording() + luatexbase.remove_from_callback('process_input_buffer', 'readbuf') + recordedbuf = recordedbuf:gsub("\\end{%w+}\n","") +end + + + +function YAMLvars.doYAMLfiles(t) + if #t == 2 then + YAMLvars.declareYAMLvarsFile(t[1]) + YAMLvars.parseYAMLvarsFile(t[2]) + elseif #t == 1 then + YAMLvars.parseYAMLvarsFile(t[1]) + else + tex.print('\\PackageWarning{YAMLvars}{No .yaml files found in CLI args"}{}') + end +end + +function YAMLvars.getYAMLcli() + local t = {} + if arg then + for i,v in pairs(arg) do + if v:find('.*%.yaml$') then + t[#t+1] = v + end + end + end + help_wrt(t) + return t + end + + +return YAMLvars + + + + --clean = clean or true + --if clean then -- clean first part of yaml string + -- y = clean_tex_spaces(y) + --end +--local function clean_tex_spaces(s) +-- help_wrt(s) +-- if s:sub(1,2) == '%s' then +-- s, _ = s:gsub('%s+','',1) +-- end +-- s, _ = s:gsub('\\par ','\n\n') +-- return s +--end
\ No newline at end of file |