summaryrefslogtreecommitdiff
path: root/macros/luatex/latex/lua-placeholders/scripts/lua-placeholders-types.lua
diff options
context:
space:
mode:
Diffstat (limited to 'macros/luatex/latex/lua-placeholders/scripts/lua-placeholders-types.lua')
-rw-r--r--macros/luatex/latex/lua-placeholders/scripts/lua-placeholders-types.lua273
1 files changed, 273 insertions, 0 deletions
diff --git a/macros/luatex/latex/lua-placeholders/scripts/lua-placeholders-types.lua b/macros/luatex/latex/lua-placeholders/scripts/lua-placeholders-types.lua
new file mode 100644
index 0000000000..faa637c8f7
--- /dev/null
+++ b/macros/luatex/latex/lua-placeholders/scripts/lua-placeholders-types.lua
@@ -0,0 +1,273 @@
+-- lua-placeholders-types.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
+
+require('lua-placeholders-common')
+
+function table.copy(t)
+ local u = { }
+ for k, v in pairs(t) do
+ u[k] = v
+ end
+ return setmetatable(u, getmetatable(t))
+end
+
+base_param = {}
+function base_param:new(o)
+ o = o or {}
+ setmetatable(o, self)
+ self.__index = self
+ return o
+end
+
+function base_param:is_set()
+ return self and ((self.values or self.fields or self.value) ~= nil)
+end
+
+function base_param:val()
+ return self.value or self.values or self.default
+end
+
+function base_param:to_upper()
+ local val = self:val()
+ if type(val) == 'string' then
+ return val:upper()
+ elseif type(self.placeholder) == 'string' then
+ return '[' .. self.placeholder:upper() .. ']'
+ end
+end
+
+function base_param:print_val()
+ local value = self:val()
+ if value ~= nil then
+ tex.write(value)
+ else
+ tex.sprint(lua_placeholders_toks.placeholder_format, '{', self.placeholder or self.key, '}')
+ end
+end
+
+bool_param = base_param:new{
+ type = 'bool'
+}
+
+function bool_param:new(key, _o)
+ local o = {
+ key = key,
+ default = _o.default
+ }
+ setmetatable(o, self)
+ self.__index = self
+ tex.sprint(lua_placeholders_toks.new_bool, '{', o.key, '}')
+ return o
+end
+
+function bool_param:val()
+ local value
+ if self.value ~= nil then
+ value = tostring(self.value)
+ elseif self.default ~= nil then
+ value = tostring(self.default)
+ else
+ value = 'false'
+ end
+ return value
+end
+
+function bool_param:set_bool(key)
+ tex.sprint(lua_placeholders_toks.set_bool, '{', key, '}{', self:val(), '}')
+end
+
+str_param = base_param:new{
+ type = 'string'
+}
+
+function str_param:new(key, _o)
+ local o = {
+ key = key,
+ placeholder = _o.placeholder
+ }
+ setmetatable(o, self)
+ self.__index = self
+ return o
+end
+
+number_param = base_param:new{
+ type = 'number'
+}
+
+function number_param:new(key, _o)
+ local o = {
+ key = key,
+ placeholder = _o.placeholder,
+ default = _o.default
+ }
+ setmetatable(o, self)
+ self.__index = self
+ return o
+end
+
+function number_param:val()
+ if self.value or self.default then
+ return tex.number(self.value or self.default)
+ end
+end
+
+function number_param:print_num()
+ local val = self:val()
+ if val then
+ tex.print('\\numprint{' .. val .. '}')
+ else
+ tex.sprint(lua_placeholders_toks.placeholder_format, '{', self.placeholder or self.key, '}')
+ end
+end
+
+list_param = base_param:new{
+ type = 'list'
+}
+
+function list_param:new(key, _o)
+ local o = {
+ key = key,
+ item_type = base_param.define('list_item', { type = (_o["item type"] or 'string') }),
+ default = {}
+ }
+ if _o.default then
+ for _, default_val in ipairs(_o.default) do
+ local v = table.copy(o.item_type)
+ v:load('list_item', default_val)
+ table.insert(o.default, v)
+ end
+ end
+ setmetatable(o, self)
+ self.__index = self
+ return o
+end
+
+function list_param:val()
+ return self.values or self.default or {}
+end
+
+function list_param:print_val()
+ local list = self:val()
+ if #list > 0 then
+ if not self.values then
+ tex.sprint(lua_placeholders_toks.placeholder_format, '{')
+ end
+ tex.sprint(list[1]:val())
+ for i = 2, #list do
+ tex.sprint(lua_placeholders_toks.list_conj, list[i]:val())
+ end
+ if not self.values then
+ tex.sprint('}')
+ end
+ end
+end
+
+object_param = base_param:new{
+ type = 'object'
+}
+
+function object_param:new(key, _o)
+ local o = {
+ key = key,
+ fields = {},
+ default = _o.default
+ }
+ for _key, field in pairs(_o.fields) do
+ o.fields[_key] = base_param.define(_key, field)
+ end
+ setmetatable(o, self)
+ self.__index = self
+ return o
+end
+
+table_param = base_param:new{
+ type = 'table'
+}
+
+function table_param:new(key, _o)
+ local o = {
+ key = key,
+ columns = {}
+ }
+ for col_key, col in pairs(_o.columns) do
+ o.columns[col_key] = base_param.define(col_key, col)
+ end
+ setmetatable(o, self)
+ self.__index = self
+ return o
+end
+
+function base_param.define(key, o)
+ if o.type then
+ if o.type == 'bool' then
+ return bool_param:new(key, o)
+ elseif o.type == 'string' then
+ return str_param:new(key, o)
+ elseif o.type == 'number' then
+ return number_param:new(key, o)
+ elseif o.type == 'list' then
+ return list_param:new(key, o)
+ elseif o.type == 'object' then
+ return object_param:new(key, o)
+ elseif o.type == 'table' then
+ return table_param:new(key, o)
+ else
+ texio.write_nl('Warning: no such parameter type ' .. o.type)
+ end
+ else
+ error('ERROR: parameter must have a "type" field')
+ end
+end
+
+function base_param:load(key, value)
+ if self.type == 'list' then
+ self.values = {}
+ for _, val in ipairs(value) do
+ local param = table.copy(self.item_type)
+ param:load('list-item', val)
+ table.insert(self.values, param)
+ end
+ elseif self.type == 'table' then
+ self.values = {}
+ for _, row_vals in ipairs(value) do
+ local row = {}
+ for col_key, col in pairs(self.columns) do
+ local cell = table.copy(col)
+ cell:load(col.key, row_vals[col_key])
+ row[col_key] = cell
+ end
+ table.insert(self.values, row)
+ end
+ elseif self.type == 'object' then
+ for field_key, field in pairs(self.fields) do
+ local field_val = value[field_key]
+ if field_val then
+ field:load(field_key, field_val)
+ else
+ texio.write_nl('Warning: Passed unknown field to object', field_key)
+ end
+ end
+ else
+ self.value = value
+ end
+ if self.type == 'bool' then
+ self:set_bool(key)
+ end
+end