texlive[76032] Master/texmf-dist: luatodonotes (12aug25)
commits+karl at tug.org
commits+karl at tug.org
Tue Aug 12 22:14:59 CEST 2025
Revision: 76032
https://tug.org/svn/texlive?view=revision&revision=76032
Author: karl
Date: 2025-08-12 22:14:59 +0200 (Tue, 12 Aug 2025)
Log Message:
-----------
luatodonotes (12aug25)
Modified Paths:
--------------
trunk/Master/texmf-dist/doc/lualatex/luatodonotes/luatodonotes.pdf
trunk/Master/texmf-dist/source/lualatex/luatodonotes/luatodonotes.dtx
trunk/Master/texmf-dist/tex/lualatex/luatodonotes/luatodonotes.lua
trunk/Master/texmf-dist/tex/lualatex/luatodonotes/luatodonotes.sty
Added Paths:
-----------
trunk/Master/texmf-dist/tex/lualatex/luatodonotes/luatodonotes-inspect.lua
Removed Paths:
-------------
trunk/Master/texmf-dist/tex/lualatex/luatodonotes/inspect.lua
Modified: trunk/Master/texmf-dist/doc/lualatex/luatodonotes/luatodonotes.pdf
===================================================================
(Binary files differ)
Modified: trunk/Master/texmf-dist/source/lualatex/luatodonotes/luatodonotes.dtx
===================================================================
--- trunk/Master/texmf-dist/source/lualatex/luatodonotes/luatodonotes.dtx 2025-08-11 23:41:53 UTC (rev 76031)
+++ trunk/Master/texmf-dist/source/lualatex/luatodonotes/luatodonotes.dtx 2025-08-12 20:14:59 UTC (rev 76032)
@@ -24,7 +24,7 @@
%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%<package>\ProvidesPackage{luatodonotes}
%<*package>
- [2020/02/16 v0.5 luatodonotes source and documentation.]
+ [2025/08/11 v0.5a luatodonotes source and documentation.]
%</package>
%
%<*driver>
@@ -79,6 +79,8 @@
% 1.0.4)}
% \changes{0.4}{2017/10/01}{Incorporated some changes from todonotes (version
% 1.0.5)}
+% \changes{0.5a}{2025/08/08}{Renamed inspect.lua to luatodonotes-inspect.lua
+% in order to avoid file conflicts with other packages.}
% \GetFileInfo{luatodonotes.dtx}
%
% \DoNotIndex{\newcommand,\newenvironment}
@@ -105,7 +107,7 @@
%
% It is an extended version of the |todonotes| package and uses more advanced
% algorithms to place the to--do notes on the page.
-% For this algorithms it depends on Lua\TeX.
+% For these algorithms it depends on Lua\TeX.
% \end{abstract}
%
% \pdfbookmark[1]{Contents}{contents}
Deleted: trunk/Master/texmf-dist/tex/lualatex/luatodonotes/inspect.lua
===================================================================
--- trunk/Master/texmf-dist/tex/lualatex/luatodonotes/inspect.lua 2025-08-11 23:41:53 UTC (rev 76031)
+++ trunk/Master/texmf-dist/tex/lualatex/luatodonotes/inspect.lua 2025-08-12 20:14:59 UTC (rev 76032)
@@ -1,297 +0,0 @@
-local inspect ={
- _VERSION = 'inspect.lua 2.0.0',
- _URL = 'http://github.com/kikito/inspect.lua',
- _DESCRIPTION = 'human-readable representations of tables',
- _LICENSE = [[
- MIT LICENSE
-
- Copyright (c) 2013 Enrique García Cota
-
- 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.
- ]]
-}
-
--- Apostrophizes the string if it has quotes, but not aphostrophes
--- Otherwise, it returns a regular quoted string
-local function smartQuote(str)
- if str:match('"') and not str:match("'") then
- return "'" .. str .. "'"
- end
- return '"' .. str:gsub('"', '\\"') .. '"'
-end
-
-local controlCharsTranslation = {
- ["\a"] = "\\a", ["\b"] = "\\b", ["\f"] = "\\f", ["\n"] = "\\n",
- ["\r"] = "\\r", ["\t"] = "\\t", ["\v"] = "\\v"
-}
-
-local function escapeChar(c) return controlCharsTranslation[c] end
-
-local function escape(str)
- local result = str:gsub("\\", "\\\\"):gsub("(%c)", escapeChar)
- return result
-end
-
-local function isIdentifier(str)
- return type(str) == 'string' and str:match( "^[_%a][_%a%d]*$" )
-end
-
-local function isArrayKey(k, length)
- return type(k) == 'number' and 1 <= k and k <= length
-end
-
-local function isDictionaryKey(k, length)
- return not isArrayKey(k, length)
-end
-
-local defaultTypeOrders = {
- ['number'] = 1, ['boolean'] = 2, ['string'] = 3, ['table'] = 4,
- ['function'] = 5, ['userdata'] = 6, ['thread'] = 7
-}
-
-local function sortKeys(a, b)
- local ta, tb = type(a), type(b)
-
- -- strings and numbers are sorted numerically/alphabetically
- if ta == tb and (ta == 'string' or ta == 'number') then return a < b end
-
- local dta, dtb = defaultTypeOrders[ta], defaultTypeOrders[tb]
- -- Two default types are compared according to the defaultTypeOrders table
- if dta and dtb then return defaultTypeOrders[ta] < defaultTypeOrders[tb]
- elseif dta then return true -- default types before custom ones
- elseif dtb then return false -- custom types after default ones
- end
-
- -- custom types are sorted out alphabetically
- return ta < tb
-end
-
-local function getDictionaryKeys(t)
- local keys, length = {}, #t
- for k,_ in pairs(t) do
- if isDictionaryKey(k, length) then table.insert(keys, k) end
- end
- table.sort(keys, sortKeys)
- return keys
-end
-
-local function getToStringResultSafely(t, mt)
- local __tostring = type(mt) == 'table' and rawget(mt, '__tostring')
- local str, ok
- if type(__tostring) == 'function' then
- ok, str = pcall(__tostring, t)
- str = ok and str or 'error: ' .. tostring(str)
- end
- if type(str) == 'string' and #str > 0 then return str end
-end
-
-local maxIdsMetaTable = {
- __index = function(self, typeName)
- rawset(self, typeName, 0)
- return 0
- end
-}
-
-local idsMetaTable = {
- __index = function (self, typeName)
- local col = setmetatable({}, {__mode = "kv"})
- rawset(self, typeName, col)
- return col
- end
-}
-
-local function countTableAppearances(t, tableAppearances)
- tableAppearances = tableAppearances or setmetatable({}, {__mode = "k"})
-
- if type(t) == 'table' then
- if not tableAppearances[t] then
- tableAppearances[t] = 1
- for k,v in pairs(t) do
- countTableAppearances(k, tableAppearances)
- countTableAppearances(v, tableAppearances)
- end
- countTableAppearances(getmetatable(t), tableAppearances)
- else
- tableAppearances[t] = tableAppearances[t] + 1
- end
- end
-
- return tableAppearances
-end
-
-local function parse_filter(filter)
- if type(filter) == 'function' then return filter end
- -- not a function, so it must be a table or table-like
- filter = type(filter) == 'table' and filter or {filter}
- local dictionary = {}
- for _,v in pairs(filter) do dictionary[v] = true end
- return function(x) return dictionary[x] end
-end
-
-local function makePath(path, key)
- local newPath, len = {}, #path
- for i=1, len do newPath[i] = path[i] end
- newPath[len+1] = key
- return newPath
-end
-
--------------------------------------------------------------------
-function inspect.inspect(rootObject, options)
- options = options or {}
- local depth = options.depth or math.huge
- local filter = parse_filter(options.filter or {})
-
- local tableAppearances = countTableAppearances(rootObject)
-
- local buffer = {}
- local maxIds = setmetatable({}, maxIdsMetaTable)
- local ids = setmetatable({}, idsMetaTable)
- local level = 0
- local blen = 0 -- buffer length
-
- local function puts(...)
- local args = {...}
- for i=1, #args do
- blen = blen + 1
- buffer[blen] = tostring(args[i])
- end
- end
-
- local function down(f)
- level = level + 1
- f()
- level = level - 1
- end
-
- local function tabify()
- puts("\n", string.rep(" ", level))
- end
-
- local function commaControl(needsComma)
- if needsComma then puts(',') end
- return true
- end
-
- local function alreadyVisited(v)
- return ids[type(v)][v] ~= nil
- end
-
- local function getId(v)
- local tv = type(v)
- local id = ids[tv][v]
- if not id then
- id = maxIds[tv] + 1
- maxIds[tv] = id
- ids[tv][v] = id
- end
- return id
- end
-
- local putValue -- forward declaration that needs to go before putTable & putKey
-
- local function putKey(k)
- if isIdentifier(k) then return puts(k) end
- puts( "[" )
- putValue(k, {})
- puts("]")
- end
-
- local function putTable(t, path)
- if alreadyVisited(t) then
- puts('<table ', getId(t), '>')
- elseif level >= depth then
- puts('{...}')
- else
- if tableAppearances[t] > 1 then puts('<', getId(t), '>') end
-
- local dictKeys = getDictionaryKeys(t)
- local length = #t
- local mt = getmetatable(t)
- local to_string_result = getToStringResultSafely(t, mt)
-
- puts('{')
- down(function()
- if to_string_result then
- puts(' -- ', escape(to_string_result))
- if length >= 1 then tabify() end -- tabify the array values
- end
-
- local needsComma = false
- for i=1, length do
- needsComma = commaControl(needsComma)
- puts(' ')
- putValue(t[i], makePath(path, i))
- end
-
- for _,k in ipairs(dictKeys) do
- needsComma = commaControl(needsComma)
- tabify()
- putKey(k)
- puts(' = ')
- putValue(t[k], makePath(path, k))
- end
-
- if mt then
- needsComma = commaControl(needsComma)
- tabify()
- puts('<metatable> = ')
- putValue(mt, makePath(path, '<metatable>'))
- end
- end)
-
- if #dictKeys > 0 or mt then -- dictionary table. Justify closing }
- tabify()
- elseif length > 0 then -- array tables have one extra space before closing }
- puts(' ')
- end
-
- puts('}')
- end
-
- end
-
- -- putvalue is forward-declared before putTable & putKey
- putValue = function(v, path)
- if filter(v, path) then
- puts('<filtered>')
- else
- local tv = type(v)
-
- if tv == 'string' then
- puts(smartQuote(escape(v)))
- elseif tv == 'number' or tv == 'boolean' or tv == 'nil' then
- puts(tostring(v))
- elseif tv == 'table' then
- putTable(v, path)
- else
- puts('<',tv,' ',getId(v),'>')
- end
- end
- end
-
- putValue(rootObject, {})
-
- return table.concat(buffer)
-end
-
-setmetatable(inspect, { __call = function(_, ...) return inspect.inspect(...) end })
-
-return inspect
-
Added: trunk/Master/texmf-dist/tex/lualatex/luatodonotes/luatodonotes-inspect.lua
===================================================================
--- trunk/Master/texmf-dist/tex/lualatex/luatodonotes/luatodonotes-inspect.lua (rev 0)
+++ trunk/Master/texmf-dist/tex/lualatex/luatodonotes/luatodonotes-inspect.lua 2025-08-12 20:14:59 UTC (rev 76032)
@@ -0,0 +1,297 @@
+local inspect ={
+ _VERSION = 'inspect.lua 2.0.0',
+ _URL = 'http://github.com/kikito/inspect.lua',
+ _DESCRIPTION = 'human-readable representations of tables',
+ _LICENSE = [[
+ MIT LICENSE
+
+ Copyright (c) 2013 Enrique García Cota
+
+ 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.
+ ]]
+}
+
+-- Apostrophizes the string if it has quotes, but not aphostrophes
+-- Otherwise, it returns a regular quoted string
+local function smartQuote(str)
+ if str:match('"') and not str:match("'") then
+ return "'" .. str .. "'"
+ end
+ return '"' .. str:gsub('"', '\\"') .. '"'
+end
+
+local controlCharsTranslation = {
+ ["\a"] = "\\a", ["\b"] = "\\b", ["\f"] = "\\f", ["\n"] = "\\n",
+ ["\r"] = "\\r", ["\t"] = "\\t", ["\v"] = "\\v"
+}
+
+local function escapeChar(c) return controlCharsTranslation[c] end
+
+local function escape(str)
+ local result = str:gsub("\\", "\\\\"):gsub("(%c)", escapeChar)
+ return result
+end
+
+local function isIdentifier(str)
+ return type(str) == 'string' and str:match( "^[_%a][_%a%d]*$" )
+end
+
+local function isArrayKey(k, length)
+ return type(k) == 'number' and 1 <= k and k <= length
+end
+
+local function isDictionaryKey(k, length)
+ return not isArrayKey(k, length)
+end
+
+local defaultTypeOrders = {
+ ['number'] = 1, ['boolean'] = 2, ['string'] = 3, ['table'] = 4,
+ ['function'] = 5, ['userdata'] = 6, ['thread'] = 7
+}
+
+local function sortKeys(a, b)
+ local ta, tb = type(a), type(b)
+
+ -- strings and numbers are sorted numerically/alphabetically
+ if ta == tb and (ta == 'string' or ta == 'number') then return a < b end
+
+ local dta, dtb = defaultTypeOrders[ta], defaultTypeOrders[tb]
+ -- Two default types are compared according to the defaultTypeOrders table
+ if dta and dtb then return defaultTypeOrders[ta] < defaultTypeOrders[tb]
+ elseif dta then return true -- default types before custom ones
+ elseif dtb then return false -- custom types after default ones
+ end
+
+ -- custom types are sorted out alphabetically
+ return ta < tb
+end
+
+local function getDictionaryKeys(t)
+ local keys, length = {}, #t
+ for k,_ in pairs(t) do
+ if isDictionaryKey(k, length) then table.insert(keys, k) end
+ end
+ table.sort(keys, sortKeys)
+ return keys
+end
+
+local function getToStringResultSafely(t, mt)
+ local __tostring = type(mt) == 'table' and rawget(mt, '__tostring')
+ local str, ok
+ if type(__tostring) == 'function' then
+ ok, str = pcall(__tostring, t)
+ str = ok and str or 'error: ' .. tostring(str)
+ end
+ if type(str) == 'string' and #str > 0 then return str end
+end
+
+local maxIdsMetaTable = {
+ __index = function(self, typeName)
+ rawset(self, typeName, 0)
+ return 0
+ end
+}
+
+local idsMetaTable = {
+ __index = function (self, typeName)
+ local col = setmetatable({}, {__mode = "kv"})
+ rawset(self, typeName, col)
+ return col
+ end
+}
+
+local function countTableAppearances(t, tableAppearances)
+ tableAppearances = tableAppearances or setmetatable({}, {__mode = "k"})
+
+ if type(t) == 'table' then
+ if not tableAppearances[t] then
+ tableAppearances[t] = 1
+ for k,v in pairs(t) do
+ countTableAppearances(k, tableAppearances)
+ countTableAppearances(v, tableAppearances)
+ end
+ countTableAppearances(getmetatable(t), tableAppearances)
+ else
+ tableAppearances[t] = tableAppearances[t] + 1
+ end
+ end
+
+ return tableAppearances
+end
+
+local function parse_filter(filter)
+ if type(filter) == 'function' then return filter end
+ -- not a function, so it must be a table or table-like
+ filter = type(filter) == 'table' and filter or {filter}
+ local dictionary = {}
+ for _,v in pairs(filter) do dictionary[v] = true end
+ return function(x) return dictionary[x] end
+end
+
+local function makePath(path, key)
+ local newPath, len = {}, #path
+ for i=1, len do newPath[i] = path[i] end
+ newPath[len+1] = key
+ return newPath
+end
+
+-------------------------------------------------------------------
+function inspect.inspect(rootObject, options)
+ options = options or {}
+ local depth = options.depth or math.huge
+ local filter = parse_filter(options.filter or {})
+
+ local tableAppearances = countTableAppearances(rootObject)
+
+ local buffer = {}
+ local maxIds = setmetatable({}, maxIdsMetaTable)
+ local ids = setmetatable({}, idsMetaTable)
+ local level = 0
+ local blen = 0 -- buffer length
+
+ local function puts(...)
+ local args = {...}
+ for i=1, #args do
+ blen = blen + 1
+ buffer[blen] = tostring(args[i])
+ end
+ end
+
+ local function down(f)
+ level = level + 1
+ f()
+ level = level - 1
+ end
+
+ local function tabify()
+ puts("\n", string.rep(" ", level))
+ end
+
+ local function commaControl(needsComma)
+ if needsComma then puts(',') end
+ return true
+ end
+
+ local function alreadyVisited(v)
+ return ids[type(v)][v] ~= nil
+ end
+
+ local function getId(v)
+ local tv = type(v)
+ local id = ids[tv][v]
+ if not id then
+ id = maxIds[tv] + 1
+ maxIds[tv] = id
+ ids[tv][v] = id
+ end
+ return id
+ end
+
+ local putValue -- forward declaration that needs to go before putTable & putKey
+
+ local function putKey(k)
+ if isIdentifier(k) then return puts(k) end
+ puts( "[" )
+ putValue(k, {})
+ puts("]")
+ end
+
+ local function putTable(t, path)
+ if alreadyVisited(t) then
+ puts('<table ', getId(t), '>')
+ elseif level >= depth then
+ puts('{...}')
+ else
+ if tableAppearances[t] > 1 then puts('<', getId(t), '>') end
+
+ local dictKeys = getDictionaryKeys(t)
+ local length = #t
+ local mt = getmetatable(t)
+ local to_string_result = getToStringResultSafely(t, mt)
+
+ puts('{')
+ down(function()
+ if to_string_result then
+ puts(' -- ', escape(to_string_result))
+ if length >= 1 then tabify() end -- tabify the array values
+ end
+
+ local needsComma = false
+ for i=1, length do
+ needsComma = commaControl(needsComma)
+ puts(' ')
+ putValue(t[i], makePath(path, i))
+ end
+
+ for _,k in ipairs(dictKeys) do
+ needsComma = commaControl(needsComma)
+ tabify()
+ putKey(k)
+ puts(' = ')
+ putValue(t[k], makePath(path, k))
+ end
+
+ if mt then
+ needsComma = commaControl(needsComma)
+ tabify()
+ puts('<metatable> = ')
+ putValue(mt, makePath(path, '<metatable>'))
+ end
+ end)
+
+ if #dictKeys > 0 or mt then -- dictionary table. Justify closing }
+ tabify()
+ elseif length > 0 then -- array tables have one extra space before closing }
+ puts(' ')
+ end
+
+ puts('}')
+ end
+
+ end
+
+ -- putvalue is forward-declared before putTable & putKey
+ putValue = function(v, path)
+ if filter(v, path) then
+ puts('<filtered>')
+ else
+ local tv = type(v)
+
+ if tv == 'string' then
+ puts(smartQuote(escape(v)))
+ elseif tv == 'number' or tv == 'boolean' or tv == 'nil' then
+ puts(tostring(v))
+ elseif tv == 'table' then
+ putTable(v, path)
+ else
+ puts('<',tv,' ',getId(v),'>')
+ end
+ end
+ end
+
+ putValue(rootObject, {})
+
+ return table.concat(buffer)
+end
+
+setmetatable(inspect, { __call = function(_, ...) return inspect.inspect(...) end })
+
+return inspect
+
Property changes on: trunk/Master/texmf-dist/tex/lualatex/luatodonotes/luatodonotes-inspect.lua
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/tex/lualatex/luatodonotes/luatodonotes.lua
===================================================================
--- trunk/Master/texmf-dist/tex/lualatex/luatodonotes/luatodonotes.lua 2025-08-11 23:41:53 UTC (rev 76031)
+++ trunk/Master/texmf-dist/tex/lualatex/luatodonotes/luatodonotes.lua 2025-08-12 20:14:59 UTC (rev 76032)
@@ -1,5 +1,5 @@
--
--- Copyright (C) 2014-2020 by Fabian Lipp <fabian.lipp at gmx.de>
+-- Copyright (C) 2014-2025 by Fabian Lipp <fabian.lipp at gmx.de>
-- ------------------------------------------------------------
--
-- This file may be distributed and/or modified under the
@@ -15,7 +15,7 @@
require("lualibs")
--require("debugger")()
-local inspect = require('inspect')
+local inspect = require('luatodonotes-inspect')
local point = require'path_point'
local pathLine = require'path_line'
Modified: trunk/Master/texmf-dist/tex/lualatex/luatodonotes/luatodonotes.sty
===================================================================
--- trunk/Master/texmf-dist/tex/lualatex/luatodonotes/luatodonotes.sty 2025-08-11 23:41:53 UTC (rev 76031)
+++ trunk/Master/texmf-dist/tex/lualatex/luatodonotes/luatodonotes.sty 2025-08-12 20:14:59 UTC (rev 76032)
@@ -24,7 +24,7 @@
%%
\NeedsTeXFormat{LaTeX2e}[1999/12/01]
\ProvidesPackage{luatodonotes}
- [2020/02/16 v0.5 luatodonotes source and documentation.]
+ [2025/08/11 v0.5a luatodonotes source and documentation.]
\@ifpackageloaded{todonotes}{
\PackageError{luatodonotes}{%
More information about the tex-live-commits
mailing list.