From bd1be3fc4dd3c9add0933864e8aa65390cb71fc6 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Tue, 15 Mar 2022 19:59:30 +0000 Subject: yamlvars (15mar22) git-svn-id: svn://tug.org/texlive/trunk@62721 c570f23f-e606-0410-a88d-b1316a301751 --- .../texmf-dist/doc/lualatex/yamlvars/yamlvars.pdf | Bin 69460 -> 71526 bytes .../texmf-dist/doc/lualatex/yamlvars/yamlvars.tex | 23 +- .../texmf-dist/tex/lualatex/yamlvars/yamlvars.lua | 264 ++++++++++++++++----- .../texmf-dist/tex/lualatex/yamlvars/yamlvars.sty | 21 +- 4 files changed, 246 insertions(+), 62 deletions(-) (limited to 'Master') diff --git a/Master/texmf-dist/doc/lualatex/yamlvars/yamlvars.pdf b/Master/texmf-dist/doc/lualatex/yamlvars/yamlvars.pdf index 864a0842d4c..6fc0c5ce7ea 100644 Binary files a/Master/texmf-dist/doc/lualatex/yamlvars/yamlvars.pdf and b/Master/texmf-dist/doc/lualatex/yamlvars/yamlvars.pdf differ diff --git a/Master/texmf-dist/doc/lualatex/yamlvars/yamlvars.tex b/Master/texmf-dist/doc/lualatex/yamlvars/yamlvars.tex index 1c412c2f6d1..344185dd5f0 100644 --- a/Master/texmf-dist/doc/lualatex/yamlvars/yamlvars.tex +++ b/Master/texmf-dist/doc/lualatex/yamlvars/yamlvars.tex @@ -1,5 +1,5 @@ % Kale Ewasiuk (kalekje@gmail.com) -% 2022-03-03 +% 2022-03-15 % Copyright (C) 2021-2022 Kale Ewasiuk % % Permission is hereby granted, free of charge, to any person obtaining a copy @@ -147,6 +147,16 @@ If the token is available, it is set to a package error, so that if the variable tell the user they forgot to set it. This will be overwritten when you parse the variables and assign a value to it. +\paragraph{If you want a case-insensitive variable} In the declaration YAML document, +add a \cmd{lowcasevar: true} under the variable name. +This will make the variable name lowercase before any transforms or processing is done. +For example, if you have \cmd{title} as a YAML variable to set +the \cmd{prc} function \cmd{setdocvar}, a user could write +\cmd{Title} in the parsing file and still have it work. +You can toggle this behaviour globally with +the commands \cmd{\lowercasevarYVon} and \cmd{\lowercasevarYVoff} +See the last example below. + You can change the default \texttt{xfm}, \texttt{prc}, or \texttt{dft} by changing the value (in Lua): \texttt{YAMLvars.xfmDefault = ''} etc. @@ -164,6 +174,17 @@ Revisions: xfm: [sortZA, list2tab] Rhead: prc: setRightHead + + +author: + xfm: list2and # (joins a list with \and (or lets a single string be passed) + prc: setdocvar # calls \author{val} + lowcasevar: true # allows user to use Title: or TITLE: + +title: + xfm: lb2nl # (make line-breaks \\) + prc: setdocvar # calls \title{val} + lowcasevar: true # allows user to use Title: or TITLE: \end{declareYAMLvars} \end{verbatim} diff --git a/Master/texmf-dist/tex/lualatex/yamlvars/yamlvars.lua b/Master/texmf-dist/tex/lualatex/yamlvars/yamlvars.lua index f32627a21a4..b485236d10e 100644 --- a/Master/texmf-dist/tex/lualatex/yamlvars/yamlvars.lua +++ b/Master/texmf-dist/tex/lualatex/yamlvars/yamlvars.lua @@ -1,5 +1,5 @@ --% Kale Ewasiuk (kalekje@gmail.com) ---% 2022-03-03 +--% 2022-03-15 --% Copyright (C) 2021-2022 Kale Ewasiuk --% --% Permission is hereby granted, free of charge, to any person obtaining a copy @@ -61,6 +61,7 @@ YAMLvars.dec = {} -- table of declare function YAMLvars.varsvals = {} YAMLvars.varspecs = {} +YAMLvars.varslowcase = pl.List() YAMLvars.xfmDefault = {} YAMLvars.prcDefault = 'gdef' @@ -68,6 +69,7 @@ YAMLvars.dftDefault = nil YAMLvars.allowUndeclared = false YAMLvars.overwritedefs = false +YAMLvars.lowvasevarall = false YAMLvars.valTemp = '' YAMLvars.varTemp = '' @@ -85,6 +87,10 @@ function YAMLvars.debugtalk(s, ss) end end +function YAMLvars.pkgerr(m) + pl.tex.pkgerror('yamlvars', m, '', true) +end + -- xfm functions (transforms) -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- function YAMLvars.xfm.addxspace(var, val) @@ -133,11 +139,22 @@ function YAMLvars.xfm.arrsortlastnameAZ(var, val) val = pl.List(val):sort(complastname) return val end + -- todo need distinction beyyween table and penlight list ??? function YAMLvars.xfm.list2nl(var, val) + if type(val) == 'string' then + return val + end return pl.List(val):join('\\\\ ') end +function YAMLvars.xfm.list2and(var, val) -- for doc vars like author, publisher + if type(val) == 'string' then + return val + end + return pl.List(val):join('\\and ') +end + --val = pl.array2d.map_slice1(_1..'\\\\', val, 1,-2) --return val:join('') --return pl.tablex.reduce(_1.._2, val, '') @@ -188,12 +205,14 @@ end -- prc functions (processing) -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- function YAMLvars.prc.gdef(var, val) - token.set_macro(var, val, 'global') + --token.set_macro(var, val, 'global') -- old way, don't do as it will cause issues if val contains undef'd macros + pl.tex.defcmd(var, val) YAMLvars.debugtalk(var..' = '..val, 'prc gdef') end function YAMLvars.prc.yvdef(var, val) - token.set_macro('yv--'..var, val, 'global') + --token.set_macro('yv--'..var, val, 'global') -- todo fix with csname hack? + pl.tex.defmacro('yv--'..var, val) YAMLvars.debugtalk('yv--'..var..' = '..val, 'prc yvdef') end @@ -215,83 +234,81 @@ function YAMLvars.prc.length(t, v) YAMLvars.debugtalk(s, 'prc length') 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..'}') + + +function YAMLvars.prc.setATvar(var, val) -- set a @var directly: eg \gdef\@title{val} + pl.tex.defcmdAT('@'..var, val) end -function YAMLvars.prc.setheader(val, rl) - local _, count = string.gsub(val, '\\\\', '') - if count == 0 then - val = '{\\ }\\\\'..val + +function YAMLvars.prc.setdocvar(var, val) -- call a document var \var{val} = \title{val} + -- YAML syntax options + -- k: v -> \k{v} + -- k: + -- v1: v2 -> \k[v2]{v1} + -- k: [v1, v2] -> \k[v2]{v1} + -- k: [v1] -> \k{v1} + if type(val) ~= 'table' then + tex.sprint('\\'..var..'{'..val..'}') + elseif #val == 0 then -- assume single k,v passed + for k,v in pairs(val) do + tex.sprint('\\'..var..'['..v..']{'..k..'}') + end + elseif #val == 1 then + tex.sprint('\\'..var..'{'..val[1]..'}') + else + tex.sprint('\\'..var..'['..val[2]..']{'..val[1]..'}') 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') +function YAMLvars.prc.setPDFdata(var, val) + --update pdf metat data table + -- requires a table + for k, v in pairs(val) do + if type(v) == 'table' then + v = pl.List(v):join('\\sep ') + end + pl.tex.updatePDFtable(k, v, true) + end 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 --- do this with author, title, company -function YAMLvars.prc.setdocvar(var, val) - tex.print('\\'..var..'{'..val..'}') -end -function YAMLvars.prc.setdocvarOpts(var, val) - local s = '\\'..var..'{'..tostring(val[1])..'}' - for k, v in pairs(val) do - if k > 1 then - s = s..'['..tostring(v)..']' - end - end - tex.print(s) +-- with hyperref package +function YAMLvars.prc.PDFtitle(var, val) + tex.print('\\hypersetup{pdftitle={'..val..'}}') end +function YAMLvars.prc.PDFauthor(var, val) + tex.print('\\hypersetup{pdfauthor={'..val..'}}') +end -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - - -function YAMLvars.prvcmd(cs, val) -- provide command via lua +function YAMLvars.makecmd(cs, val) -- provide command via lua if token.is_defined(cs) and (not YAMLvars.overwritedefs) then - tex.print('\\PackageError{YAMLvars}{Variable '..cs..' already defined, could not declare}{}') + YAMLvars.pkgerr('Variable '..cs..' already defined, could not declare') else - token.set_macro(cs, val, 'global') + pl.tex.defcmd(cs, val) + --token.set_macro(cs, val, 'global') -- issues if val contains undefined macro end end function YAMLvars.deccmd(cs, def) if def == nil then - YAMLvars.prvcmd(cs, '\\PackageError{YAMLvars}{Variable "'..cs..'" was declared and used but, not set}{}') + YAMLvars.makecmd(cs, '\\PackageError{YAMLvars}{Variable "'..cs..'" was declared and used but, not set}{}') else - YAMLvars.prvcmd(cs, def) + YAMLvars.makecmd(cs, def) end end +-- -- -- -- -- -- local function getYAMLfile(y) local f = io.open(y,"r") @@ -300,16 +317,19 @@ local function getYAMLfile(y) io.close(f) return y else - tex.print('\\PackageError{YAMLvars}{YAML file "'..y..'" not found}{}') + YAMLvars.pkgerr('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 + if pl.hasval(specs['lowcasevar']) or YAMLvars.lowvasevarall then + var = var:lower() + YAMLvars.varslowcase:append(var) + end YAMLvars.varspecs[var] = {xfm=YAMLvars.xfmDefault,prc=YAMLvars.prcDefault,dft=YAMLvars.dftDefault} if type(specs) == 'string' then specs = {xfm={specs}} @@ -339,11 +359,14 @@ local function check_def(var, val) if YAMLvars.allowUndeclared then if YAMLvars.prcDefault == 'yvdef' then YAMLvars.prc.yvdef(var, val) + YAMLvars.debugtalk(var..' = '..val,'yvdef made (undeclared)') else - YAMLvars.prvcmd(var, val) + YAMLvars.makecmd(var, val) + YAMLvars.debugtalk(var..' = '..val,'gdef made (undeclared)') end else - tex.print('\\PackageError{YAMLvars}{Variable "'..var..'" set but not declared}{}') + --tex.print('\\PackageError{YAMLvars}{Variable "'..var..'" set but not declared}{}') + YAMLvars.pkgerr('Variable "'..var..'" set but not declared') end end @@ -355,7 +378,8 @@ local _YV_invalid_expression = '\1 invalid expression' local _YV_no_return = '\2 no return val' local function expr_err(var, val) - tex.print('\\PackageError{YAMLvars}{xfm with "= or /" error on var "'..var..'"}{}') -- todo make program stop + --tex.print('\\PackageError{YAMLvars}{xfm with "= or /" error on var "'..var..'"}{}') -- todo make program stop + YAMLvars.pkgerr('xfm with "= or /" error on var "'..var..'"}{}') -- todo make program stop end local function eval_expr(func, var, val) @@ -374,7 +398,8 @@ local function eval_expr(func, var, val) --pl.tex.help_wrt(s, var) local f, err = pcall(loadstring(s)) if not f then - tex.print('\\PackageError{YAMLvars}{xfm with "= or /" error on var "'..var..'"}{}') -- + --tex.print('\\PackageError{YAMLvars}{xfm with "= or /" error on var "'..var..'"}{}') -- + YAMLvars.pkgerr('xfm with "= or /" error on var "'..var) -- end if c > 0 then expr_err(var) @@ -390,7 +415,8 @@ local function transform_and_prc(var, val) if f == nil then local val2 = eval_expr(func, var, val) if val2 == _YV_invalid_expression then - tex.print('\\PackageError{YAMLvars}{xfm function "'..func..'" not defined or invalid expression passed on var "'..var..'"}{}') + --tex.print('\\PackageError{YAMLvars}{xfm function "'..func..'" not defined or invalid expression passed on var "'..var..'"}{}') + YAMLvars.pkgerr('xfm function "'..func..'" not defined or invalid expression passed on var "'..var) elseif val == _YV_no_return then else val = val2 @@ -401,7 +427,8 @@ local function transform_and_prc(var, val) end f = YAMLvars.prc[YAMLvars.varspecs[var]['prc']] if f == nil then - tex.print('\\PackageError{YAMLvars}{prc function "'..YAMLvars.varspecs[var]['prc']..'" on var "'..var..'" not defined}{}') + --tex.print('\\PackageError{YAMLvars}{prc function "'..YAMLvars.varspecs[var]['prc']..'" on var "'..var..'" not defined}{}') + YAMLvars.pkgerr('prc function "'..YAMLvars.varspecs[var]['prc']..'" on var "'..var..'" not defined') end f(var, val) -- prc the value of the variable end @@ -409,6 +436,9 @@ end function YAMLvars.parseYAMLvarsStr(y) YAMLvars.varsvals = YAMLvars.yaml.parse(y) for var, val in pairs(YAMLvars.varsvals) do + if YAMLvars.varslowcase:contains(var:lower()) then + var = var:lower() + end if YAMLvars.varspecs[var] == nil then check_def(var, val) -- if not declared -- todo consider free form parse declaring @@ -464,10 +494,127 @@ function YAMLvars.getYAMLcli() end + +YAMLvars.yaml2PDFmetadata = function(ytext) -- parse a YAML file and update the pdfmetadata table + __PDFmetadata__ = __PDFmetadata__ or {} -- existing metadata + if ytext ~= nil then + local pdfmetadata_yaml = YAMLvars.yaml.parse(ytext) -- new metadata + local t = {} + for k,v in pairs(pdfmetadata_yaml) do -- ensure first character is capital letter + t[k:upfirst()] = v + end + __PDFmetadata__ = table.update(__PDFmetadata__, t) + end + end + + + + + + + +-- graveyard + + +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.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.memoTo(var, val) + for k, v in pairs(v) do + pl.tex.defcmd('@memoTo', val) + v = YAMLvars.xfm.list2nl(var, v) + pl.tex.defcmd('@memoTo', val) + end +end +function YAMLvars.prc.memoFr(var, val) + for k, v in pairs(v) do + pl.tex.defcmd('@memoFr', val) + v = YAMLvars.xfm.list2nl(var, v) + pl.tex.defcmd('@memoFrAddr', val) + + end +end +-- produce \Var[val[2]\\val[3].....\val[n]]{val[1]} +--function YAMLvars.prc.setdocvarOpt(var, val) +-- if type(val) ~= 'table' then +-- val = {val} +-- end +-- local s = '\\'..var..'{'..tostring(val[1])..'}' +-- s = s..'['..pl.List(v):map_slice1():join()..']' -- what does this do? +-- tex.print(s) +--end +-- +-- +--function YAMLvars.prc.setdocvarOpts(var, val) +-- if type(val) ~= 'table' then +-- val = {val} +-- end +-- local s = '\\'..var..'{'..tostring(val[1])..'}' +-- for k, v in pairs(val) do +-- if k > 1 then +-- s = s..'['..tostring(v)..']' +-- end +-- end +-- tex.print(s) +--end + return YAMLvars + + + + + + + --token.set_macro('@memoFr', k, 'global') + --token.set_macro('@memoFrAddr', v, 'global') + --token.set_macro('@memoTo', k, 'global') + --token.set_macro('@memoToAddr', v, 'global') + --help_wrt(var,val) + -- token.set_macro('@'..var, val, 'global') + +--function YAMLvars.prc.title(var, val) +-- YAMLvars.prc.setdocvar('title', val) +--end +-- +-- +--function YAMLvars.prc.author(var, val) +-- YAMLvars.prc.setdocvar('author', val) +--end +-- +--function YAMLvars.prc.date(var, val) +-- YAMLvars.prc.setdocvar('date', val) +--end + + --clean = clean or true --if clean then -- clean first part of yaml string -- y = clean_tex_spaces(y) @@ -479,4 +626,5 @@ return YAMLvars -- end -- s, _ = s:gsub('\\par ','\n\n') -- return s ---end \ No newline at end of file +--end + diff --git a/Master/texmf-dist/tex/lualatex/yamlvars/yamlvars.sty b/Master/texmf-dist/tex/lualatex/yamlvars/yamlvars.sty index 1c4b8fcf322..852b0de8cc0 100644 --- a/Master/texmf-dist/tex/lualatex/yamlvars/yamlvars.sty +++ b/Master/texmf-dist/tex/lualatex/yamlvars/yamlvars.sty @@ -1,5 +1,5 @@ % Kale Ewasiuk (kalekje@gmail.com) -% 2022-03-03 +% 2022-03-15 % Copyright (C) 2021-2022 Kale Ewasiuk % % Permission is hereby granted, free of charge, to any person obtaining a copy @@ -25,7 +25,7 @@ \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{YAMLvars}[2022-03-03] +\ProvidesPackage{YAMLvars}[2022-03-15] \IfFileExists{markdown-tinyyaml.lua}{}{\PackageError{YAMLvars}{This package requires installation of the 'markdown' package, please install it and try again}{}} @@ -69,8 +69,23 @@ } \newenvironment{parseYAMLvars}{\luadirect{pl.tex.startrecording()}}{\luadirect{pl.tex.stoprecording()} - \luadirect{YAMLvars.parseYAMLvarsStr(pl.tex.recordedbuf)} } +\AfterEndEnvironment{parseYAMLvars}{\luadirect{YAMLvars.parseYAMLvarsStr(pl.tex.recordedbuf)}} +% necessary hack to get rohead and lohead to work.. +% .. https://tex.stackexchange.com/questions/637018/setting-koma-heading-within-lua/637021?noredirect=1#comment1587387_637021 \newcommand{\resetYAMLvarsspec}{\luadirect{YAMLvars.varspec = {}}} + +\newcommand{\lowercasevarYVon}{\luadirect{YAMLvars.lowvasevarall = true}} +\newcommand{\lowercasevarYVoff}{\luadirect{YAMLvars.lowvasevarall = false}} + + + +\newenvironment{parseYAMLpdfdata}{\luadirect{pl.tex.startrecording()}}{ + \luadirect{pl.tex.stoprecording() + YAMLvars.yaml2PDFmetadata(pl.tex.recordedbuf) + pl.tex.writePDFmetadata() + } +} + -- cgit v1.2.3