diff options
Diffstat (limited to 'macros/luatex/latex/lua-placeholders/scripts/lua-placeholders.lua')
-rw-r--r-- | macros/luatex/latex/lua-placeholders/scripts/lua-placeholders.lua | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/macros/luatex/latex/lua-placeholders/scripts/lua-placeholders.lua b/macros/luatex/latex/lua-placeholders/scripts/lua-placeholders.lua new file mode 100644 index 0000000000..255b4d1f26 --- /dev/null +++ b/macros/luatex/latex/lua-placeholders/scripts/lua-placeholders.lua @@ -0,0 +1,217 @@ +-- lua-placeholders.lua +-- Copyright 2024 E. Nijenhuis +-- +-- This work may be distributed and/or modified under the +-- conditions of the LaTeX Project Public License, either version 1.3c +-- of this license or (at your option) any later version. +-- The latest version of this license is in +-- http://www.latex-project.org/lppl.txt +-- and version 1.3c or later is part of all distributions of LaTeX +-- version 2005/12/01 or later. +-- +-- This work has the LPPL maintenance status ‘maintained’. +-- +-- The Current Maintainer of this work is E. Nijenhuis. +-- +-- This work consists of the files lua-placeholders.sty +-- lua-placeholders-manual.pdf lua-placeholders.lua +-- lua-placeholders-common.lua lua-placeholders-namespace.lua +-- lua-placeholders-parser.lua and lua-placeholders-types.lua + +if not modules then + modules = {} +end + +modules.lua_placeholders = { + version = "0.1.0", + date = "2024/01/12", + comment = 'Extended LaTeX Parameter Interface — for specifying and inserting document parameters', + author = 'Erik Nijenhuis', + license = 'free' +} + +local api = { + namespaces = {}, + parameters = {}, + strict = false, + toks = { + is_set_true = token.create('has@param@true'), + is_set_false = token.create('has@param@false'), + } +} +local lua_placeholders = {} +local lua_placeholders_mt = { + __index = api, + __newindex = function() + tex.error('Cannot override or set actions for this module...') + end +} + +setmetatable(lua_placeholders, lua_placeholders_mt) + +local lua_placeholders_namespace = require('lua-placeholders-namespace') +local load_resource = require('lua-placeholders-parser') + +local function get_param(key, namespace) + namespace = namespace or tex.jobname + local _namespace = api.namespaces[namespace] + return _namespace and _namespace:param(key) +end + +function api.set_strict() + api.strict = true +end + +function api.recipe(path, namespace_name) + if namespace_name == '' then + namespace_name = nil + end + local filename, abs_path = lua_placeholders_namespace.parse_filename(path) + local raw_recipe = load_resource(abs_path) + local name = namespace_name or raw_recipe.namespace or filename + local namespace = api.namespaces[name] or lua_placeholders_namespace:new { recipe_file = abs_path, strict = api.strict } + if not api.namespaces[name] then + api.namespaces[name] = namespace + end + if raw_recipe.namespace then + namespace:load_recipe(raw_recipe.parameters) + else + namespace:load_recipe(raw_recipe) + end + tex.print('\\UseOneTimeHook{namespace/' .. name .. '}') + if namespace.payload_file and not namespace.payload_loaded then + local raw_payload = load_resource(namespace.payload_file) + if raw_payload.namespace then + namespace:load_payload(raw_payload.parameters) + else + namespace:load_payload(raw_payload) + end + tex.print('\\UseOneTimeHook{namespace/' .. name .. '/loaded}') + end +end + +function api.payload(path, namespace_name) + if namespace_name == '' then + namespace_name = nil + end + local filename, abs_path = lua_placeholders_namespace.parse_filename(path) + local raw_payload = load_resource(abs_path) + local name = namespace_name or raw_payload.namespace or filename + local namespace = api.namespaces[name] or lua_placeholders_namespace:new { payload_file = abs_path, strict = api.strict } + if not api.namespaces[name] then + api.namespaces[name] = namespace + end + if namespace.recipe_loaded then + if raw_payload.namespace then + namespace:load_payload(raw_payload.parameters) + else + namespace:load_payload(raw_payload) + end + tex.print('\\UseOneTimeHook{namespace/' .. name .. '/loaded}') + end +end + +function api.param_object(key, namespace) + return get_param(key, namespace) +end + +function api.param(key, namespace) + local param = get_param(key, namespace) + if param then + param:print_val() + elseif api.strict then + tex.error('Error: Parameter not set "' .. key .. '" in namespace "' .. namespace .. '".') + else + tex.sprint(lua_placeholders_toks.unknown_format, '{', key, '}') + end +end + +function api.handle_param_is_set(key, namespace) + local param = get_param(key, namespace) + if param and param:is_set() then + tex.sprint(token.create('has@param@true')) + else + tex.sprint(token.create('has@param@false')) + end +end + +function api.field(object_key, field, namespace) + local param = get_param(object_key, namespace) + if param then + local object = param.fields or param.default or {} + local f = object[field] + if f then + f:print_val() + else + tex.sprint(lua_placeholders_toks.unknown_format, '{', field, '}') + end + else + tex.error('No such object', object_key) + end +end + +function api.with_object(object_key, namespace) + local object = get_param(object_key, namespace) + for key, param in pairs(object.fields) do + local val = param:val() + if val then + token.set_macro(key, param:val() .. '\\xspace') + else + token.set_macro(key, '\\paramplaceholder{' .. (param.placeholder or key) .. '}\\xspace') + end + end +end + +function api.for_item(list_key, namespace, csname) + local param = get_param(list_key, namespace) + local list = param:val() + if #list > 0 then + if token.is_defined(csname) then + local tok = token.create(csname) + for _, item in ipairs(list) do + if param.values then + tex.sprint(tok, '{', item:val(), '}') + else + tex.sprint(tok, '{', lua_placeholders_toks.placeholder_format, '{', item:val(), '}}') + end + end + else + tex.error('No such command ', csname or 'nil') + end + end +end + +function api.with_rows(key, namespace, csname) + local param = get_param(key, namespace) + if token.is_defined(csname) then + local row_content = token.get_macro(csname) + if param then + if param.values or api.strict then + if #param.values > 0 then + for _, row in ipairs(param.values) do + local format = row_content + for col_key, cell in pairs(row) do + format = format:gsub('\\' .. col_key, cell:val()) + end + tex.print(format) + end + end + elseif param.columns then + texio.write_nl("Warning: no values set for " .. param.key) + local format = row_content + for col_key, col in pairs(param.columns) do + format = format:gsub('\\' .. col_key, '{\\paramplaceholder{' .. (col.placeholder or col_key) .. '}}') + end + tex.print(format) + else + tex.error('No values either columns available') + end + else + tex.error('Error: no such parameter') + end + else + tex.error('Error: no such command: ', csname or 'nil') + end +end + +return lua_placeholders |