summaryrefslogtreecommitdiff
path: root/macros/luatex/latex
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2024-03-21 03:01:49 +0000
committerNorbert Preining <norbert@preining.info>2024-03-21 03:01:49 +0000
commit1c5f075956663aa87b675cccdaa9f3eebfd83af9 (patch)
treedadac5496bfa26f280ccec7cdccf4bdbb484ee3b /macros/luatex/latex
parent414dee6c32fcf48cb611b8c24b6c7b211dc6a5c5 (diff)
CTAN sync 202403210301
Diffstat (limited to 'macros/luatex/latex')
-rw-r--r--macros/luatex/latex/ideavault/README.md27
-rw-r--r--macros/luatex/latex/ideavault/ideavault-doc.pdfbin0 -> 35243 bytes
-rw-r--r--macros/luatex/latex/ideavault/ideavault-doc.tex178
-rw-r--r--macros/luatex/latex/ideavault/ideavault-lua.lua355
-rw-r--r--macros/luatex/latex/ideavault/ideavault.sty67
5 files changed, 627 insertions, 0 deletions
diff --git a/macros/luatex/latex/ideavault/README.md b/macros/luatex/latex/ideavault/README.md
new file mode 100644
index 0000000000..9a1327791a
--- /dev/null
+++ b/macros/luatex/latex/ideavault/README.md
@@ -0,0 +1,27 @@
+Idea Vault
+
+## Description
+
+Package for management and reuse LaTeX content (ideas).
+
+It allows idea declaration and invocation, while also supporting dependencies and idea tagging.
+
+It is LuaLaTeX package -- it depends on Lua and cannot be used without it.
+
+## LICENCE
+
+Copyright 2024 Tomasz M. Czarkowski
+
+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 any later version.
+The latest version of this license is in
+ https://www.latex-project.org/lppl.txt
+and version 1.3c or later is part of all distributions of LaTeX
+version 2008 or later.
+
+This work has the LPPL maintenance status `maintained'.
+
+The Current Maintainer of this work is Tomasz M. Czarkowski
+
+This work consists of the files ideavault.sty and ideavault-lua.lua \ No newline at end of file
diff --git a/macros/luatex/latex/ideavault/ideavault-doc.pdf b/macros/luatex/latex/ideavault/ideavault-doc.pdf
new file mode 100644
index 0000000000..4f3d1562ed
--- /dev/null
+++ b/macros/luatex/latex/ideavault/ideavault-doc.pdf
Binary files differ
diff --git a/macros/luatex/latex/ideavault/ideavault-doc.tex b/macros/luatex/latex/ideavault/ideavault-doc.tex
new file mode 100644
index 0000000000..7bba38fc44
--- /dev/null
+++ b/macros/luatex/latex/ideavault/ideavault-doc.tex
@@ -0,0 +1,178 @@
+\documentclass[11pt]{article}
+\usepackage{ideavault}
+\author{Tomasz M. Czarkowski}
+\title{Idea Vault}
+
+\begin{document}
+\maketitle
+
+\section{Why}
+\par Assume, You are writing something large. For example, like me, a TT RPG system.
+\par Often You will find Yourself wanting to declare some concept (idea, if You indulge me) and later print it all over the place, without needing to copy and paste \textbf{it}
+\par For really complicated projects, You may want to classify some ideas using tags, or make them depend on each other.
+\par This is what the Idea Vault is used for.
+
+\section{Dependencies}
+\par Idea Vault requires some packages (most of them for styling the printed idea).
+\begin{itemize}
+\item \texttt{bookmark}
+\item \texttt{xargs}
+\item \texttt{luacode}
+\item \texttt{xpatch}
+\item \texttt{mdframed}
+\item \texttt{needspace}
+\end{itemize}
+
+\section{Usage}
+\par For idea creation there is \texttt{\textbackslash{}createIdea}, while for printing them there are a few more:
+\begin{itemize}
+\item \texttt{\textbackslash{}printIdea} -- prints one idea
+\item \texttt{\textbackslash{}printAllWithPrefix} -- prints all ideas in given prefix
+\item \texttt{\textbackslash{}printAllWithTag} -- prints all ideas in given prefix that have given tag
+\end{itemize}
+
+\subsection{\textbackslash{}createIdea}
+\begin{verbatim}
+\printIdea[prefix]{name}{content}[dependencies][tags][weight]
+\end{verbatim}
+\begin{itemize}
+\item \texttt{prefix}: prefix to locate the idea in. By default, equals to \texttt{default}.
+\item \texttt{name}: name of the idea. If such name exists in prefix, it will be overwritten
+\item \texttt{content}: valid LaTeX code for the content of idea. It will be evaluated at invocation time.
+\item \texttt{dependencies}: each dependency is Lua pair of strings, multiple dependencies are separated with comma.
+\item \texttt{tags}: each tag is Lua string, multiple tags are separated with comma.
+\item \texttt{weight}: a number used for sorting ideas when multiple are printed at the same time. By default, equal to \texttt{-1}.
+\end{itemize}
+\par Note: due to some strange problems on LaTeX/Lua connection, for ideas with exactly one dependency, the \{\} needs to be duplicated, while for multi dependency there is no need.
+\par Example:
+\begin{verbatim}
+\createIdea[somePrefix]{Not So Great Idea}{
+\par Boring content
+}[]["tag2"][1]
+
+\createIdea[somePrefix]{Great Idea}{
+ \par Long content
+ \par Very Interesting
+}[{{"somePrefix", "Not So Great Idea"}}]["tag1"][13]
+\end{verbatim}
+
+\subsection{\textbackslash{}printIdea}
+\begin{verbatim}
+\printIdea[prefix][style]{name}
+\end{verbatim}
+
+\begin{itemize}
+\item \texttt{prefix}: prefix to locate the idea in. By default, equals to \texttt{default}.
+\item \texttt{style}: style for printing the idea. For options, see later.
+\item \texttt{name}: name of the idea.
+\end{itemize}
+
+\par Example:
+\begin{verbatim}
+\printIdea[somePrefix][lcbf]{Great Idea}
+\end{verbatim}
+
+\subsection{\textbackslash{}printAllWithPrefix}
+\begin{verbatim}
+\printIdea[prefix][style]
+\end{verbatim}
+
+\begin{itemize}
+\item \texttt{prefix}: prefix to print.
+\item \texttt{style}: style for printing the idea. For options, see later.
+\end{itemize}
+
+\par Example:
+\begin{verbatim}
+\printIdeaAllWithPrefix[somePrefix][lcbf]
+\end{verbatim}
+
+\subsection{\textbackslash{}printAllWithTag}
+\begin{verbatim}
+\printIdea[prefix][style]{tag}
+\end{verbatim}
+
+\begin{itemize}
+\item \texttt{prefix}: prefix to locate the ideas in.
+\item \texttt{style}: style for printing the idea. For options, see later.
+\item \texttt{tag}: tag to print
+\end{itemize}
+
+\par Example:
+\begin{verbatim}
+\printIdeaAllWithTag[somePrefix][lcbf]{tag1}
+\end{verbatim}
+
+\section{Style}
+\par Printing style is decided by one letter flags.
+\begin{itemize}
+\item \texttt{f}: Frame whole idea
+\item \texttt{c}: Center whole idea
+\item \texttt{b}: Create bookmark leading to the idea
+\item \texttt{l}: Use large font for the name
+\item \texttt{s}: Reserve some space using needspace to avoid awkward pagebreaks
+\item \texttt{e}: emph the name
+\item \texttt{q}: do not print the name
+\end{itemize}
+
+\section{Example}
+\subsection{Code}
+\begin{verbatim}
+\createIdea[somePrefix]{Not So Great Idea}{
+\par Boring content
+}[]["tag2"][1]
+
+\createIdea[somePrefix]{Great Idea}{
+\par Long content
+\par Very Interesting
+}[{{"somePrefix", "Not So Great Idea"}}]["tag1"][13]
+
+\createIdea[somePrefix2]{Third Idea}{
+\par Third try is even longer
+\par But not very
+\par Only 3 lines
+}[{"somePrefix", "Not So Great Idea"}, {"somePrefix", "Great Idea"}][][21]
+
+\par Here is a Great Idea:
+\printIdea[somePrefix][lcf]{Great Idea}
+\vspace{1em}
+\par Here are all ideas in prefix \texttt{somePrefix}:
+\printAllWithPrefix[somePrefix][lcf]
+\vspace{1em}
+\par Here are all ideas in prefix \texttt{somePrefix} with tag \texttt{tag1}:
+\printAllWithTag[somePrefix][lcf]{tag1}
+\vspace{1em}
+\par And here is Third Idea, presenting nested dependencies:
+\printIdea[somePrefix2][lcf]{Third Idea}
+
+\end{verbatim}
+\subsection{Result}
+
+\createIdea[somePrefix]{Not So Great Idea}{
+\par Boring content
+}[]["tag2"][1]
+
+\createIdea[somePrefix]{Great Idea}{
+\par Long content
+\par Very Interesting
+}[{{"somePrefix", "Not So Great Idea"}}]["tag1"][13]
+
+\createIdea[somePrefix2]{Third Idea}{
+\par Third try is even longer
+\par But not very
+\par Only 3 lines
+}[{"somePrefix", "Not So Great Idea"}, {"somePrefix", "Great Idea"}][][21]
+
+\par Here is a Great Idea:
+\printIdea[somePrefix][lcf]{Great Idea}
+\vspace{1em}
+\par Here are all ideas in prefix \texttt{somePrefix}:
+\printAllWithPrefix[somePrefix][lcf]
+\vspace{1em}
+\par Here are all ideas in prefix \texttt{somePrefix} with tag \texttt{tag1}:
+\printAllWithTag[somePrefix][lcf]{tag1}
+\vspace{1em}
+\par And here is Third Idea, presenting nested dependencies:
+\printIdea[somePrefix2][lcf]{Third Idea}
+
+\end{document} \ No newline at end of file
diff --git a/macros/luatex/latex/ideavault/ideavault-lua.lua b/macros/luatex/latex/ideavault/ideavault-lua.lua
new file mode 100644
index 0000000000..6d4de1e383
--- /dev/null
+++ b/macros/luatex/latex/ideavault/ideavault-lua.lua
@@ -0,0 +1,355 @@
+-- ideavault-lua.lua
+-- Copyright 2024 Tomasz M. Czarkowski
+--
+-- 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 any later version.
+-- The latest version of this license is in
+-- https://www.latex-project.org/lppl.txt
+-- and version 1.3c or later is part of all distributions of LaTeX
+-- version 2008 or later.
+--
+-- This work has the LPPL maintenance status `maintained'.
+--
+-- The Current Maintainer of this work is Tomasz M. Czarkowski
+--
+-- This work consists of the files ideavault.sty and ideavault-lua.lua
+
+IdeaVaultClass = {}
+IdeaVaultClass.__index = IdeaVaultClass
+
+setmetatable(IdeaVaultClass, {
+ __call = function (cls, ...)
+ return cls.new(...)
+ end,
+})
+
+function IdeaVaultClass.new()
+ local self = setmetatable({}, IdeaVaultClass)
+ self.all = {}
+ return self
+end
+
+function IdeaVaultClass:addPrefix(prefix)
+ if (self.all[prefix] == nil)
+ then
+ self.all[prefix] = {}
+ end
+end
+
+function IdeaVaultClass:set(prefix, key, value)
+ self:addPrefix(prefix)
+ self.all[prefix][key] = value
+end
+
+function IdeaVaultClass:contains(prefix, key)
+ if (self.all[prefix] == nil or self.all[prefix][key] == nil)
+ then
+ return false
+ end
+ return true
+end
+
+function IdeaVaultClass:get(prefix, key)
+ if (self.all[prefix] == nil)
+ then
+ die("Prefix: '" .. prefix .. "' does not exist!")
+ end
+ if (self.all[prefix][key] == nil)
+ then
+ die("Key: '" .. key .. "' not found in prefix: '" .. prefix .. "'!")
+ end
+
+ return self.all[prefix][key]
+end
+
+function IdeaVaultClass:getAllWithPrefix(prefix)
+ ideas = {}
+ pr = self.all[prefix]
+ for _, value in pairs(pr)
+ do
+ table.insert(ideas, value)
+ end
+ table.sort(ideas, function(a,b)
+ if b:isGreaterThan(a) then return true end
+ end)
+ return ideas
+end
+
+function IdeaVaultClass:getAllWithTag(prefix, tag)
+ ideas = {}
+ pr = self.all[prefix]
+ for _, value in pairs(pr)
+ do
+ if (value:hasTag(tag))
+ then
+ table.insert(ideas, value)
+ end
+ end
+ table.sort(ideas, function(a,b)
+ if b:isGreaterThan(a) then return true end
+ end)
+ return ideas
+end
+
+function IdeaVaultClass:printIdea(prefix, key, style)
+ idea = self:get(prefix, key)
+ idea:printSelf(style)
+end
+
+function IdeaVaultClass:printAllWithTag(prefix, tag, style)
+ ideas = self:getAllWithTag(prefix, tag)
+ for _, idea in ipairs(ideas)
+ do
+ idea:printSelf(style)
+ end
+end
+
+function IdeaVaultClass:printAllWithPrefix(prefix, style)
+ ideas = self:getAllWithPrefix(prefix)
+ for _, idea in ipairs(ideas)
+ do
+ idea:printSelf(style)
+ end
+end
+
+IdeaClass = {}
+IdeaClass.__index = IdeaClass
+
+setmetatable(IdeaClass, {
+ __call = function (cls, ...)
+ return cls.new(...)
+ end,
+})
+
+function IdeaClass.new(title, content, dependencies, tags, value)
+ local self = setmetatable({}, IdeaClass)
+ self.title = title
+ self.content = content
+ self.dependencies = dependencies or {}
+ self.tags = tags or {}
+ self.value = value or 0
+ return self
+end
+
+function IdeaClass:getTitle()
+ return self.title
+end
+
+function IdeaClass:getContent()
+ return self.content
+end
+
+function IdeaClass:getTags()
+ return self.tags
+end
+
+function IdeaClass:getDependencies()
+ return self.dependencies
+end
+
+function IdeaClass:getValue()
+ return self.value
+end
+
+function IdeaClass:isGreaterThan(idea)
+ if self:getValue() > idea:getValue()
+ then
+ return true
+ else
+ if self:getValue() == idea:getValue()
+ then
+ if self:getTitle() > idea:getTitle()
+ then
+ return true
+ else
+ return false
+ end
+ else
+ return false
+ end
+ end
+end
+
+function IdeaClass:hasTag(tag)
+ for _, value in pairs(self:getTags())
+ do
+ if (value == tag)
+ then
+ return true
+ end
+ end
+ return false
+end
+
+bookmark_counter = 0
+
+function IdeaClass:printSelf(style)
+ style = style or ""
+ texio.write("Printing idea. Title: '" .. self:getTitle() .. "', style: '" .. style .. "'.\n")
+
+ local frame = false
+ local center = false
+ local bookmark = false
+ local large = false
+ local needSpace = false
+ local emph = false
+ local quiet = false
+ for c in style:gmatch"."
+ do
+ if (c == "f") then
+ frame = true
+ elseif (c == "c") then
+ center = true
+ elseif (c == "b") then
+ bookmark = true
+ elseif (c == "l") then
+ large = true
+ elseif (c == "s") then
+ needSpace = true
+ elseif (c == "e") then
+ emph = true
+ elseif (c == "q") then
+ quiet = true
+ else
+ die("Unknown style: '" .. c .. "'")
+ end
+ end
+ if (needSpace)
+ then
+ tex.sprint("\\needspace{5cm}%")
+ end
+ if (bookmark)
+ then
+ tex.sprint("\\hypertarget{" .. bookmark_counter .. "}{}%")
+ tex.sprint("\\bookmark[dest=" .. bookmark_counter .. ", level=\\bookDepth]{" .. self:getTitle() .. "}%")
+ --tex.sprint("\\subpdfbookmark{" .. self:getTitle() .. "}{" .. bookmark_counter .. "}%")
+ bookmark_counter = bookmark_counter + 1
+ tex.sprint("\\bookDown%")
+ end
+ if (frame)
+ then
+ tex.sprint("\\begin{mdframed}%")
+ end
+ if (center)
+ then
+ tex.sprint("\\begin{center}%")
+ end
+ if (not quiet)
+ then
+ if (large)
+ then
+ tex.sprint("{\\Large%")
+ end
+ if (emph)
+ then
+ tex.sprint("\\emph{,,")
+ end
+ tex.sprint(self:getTitle())
+ if (emph)
+ then
+ tex.sprint("''}%")
+ end
+ if (large)
+ then
+ tex.sprint("}%")
+ end
+ end
+ if (center)
+ then
+ tex.sprint("\\end{center}%")
+ end
+ tex.sprint(self:getContent() .. "%")
+ if (not quiet)
+ then
+ self:printDependencies()
+ end
+ if (frame)
+ then
+ tex.sprint("\\end{mdframed}%")
+ end
+ if (bookmark)
+ then
+ tex.sprint("\\bookUp%")
+ end
+end
+
+function IdeaClass:printDependencies()
+ for _, dependency in ipairs(self:getDependencies())
+ do
+ dependency:resolve():printSelf("lcf")
+ end
+end
+
+DependencyClass = {}
+DependencyClass.__index = DependencyClass
+
+setmetatable(DependencyClass, {
+ __call = function (cls, ...)
+ return cls.new(...)
+ end,
+})
+
+function DependencyClass.new(prefix, title)
+ local self = setmetatable({}, DependencyClass)
+ self.prefix = prefix or "default"
+ self.title = title or ""
+ if (not ideaVault:contains(self.prefix, self.title))
+ then
+ die("Broken dependency! Title: '" .. self.title .. "'. Prefix: '" .. self.prefix .. "'.")
+ end
+ return self
+end
+
+function DependencyClass:getPrefix()
+ return self.prefix
+end
+
+function DependencyClass:getTitle()
+ return self.title
+end
+
+function DependencyClass:resolve()
+ return ideaVault:get(self:getPrefix(), self:getTitle())
+end
+
+function DependencyClass:isGreaterThan(idea)
+ if self:getTitle() > idea:getTitle()
+ then
+ return true
+ else
+ return false
+ end
+end
+ideaVault = IdeaVaultClass()
+
+function createIdea(prefix, key, content, dependencies, tags, value)
+ t = "["
+ for _, a in pairs(tags)
+ do
+ t = t .. a .. ", "
+ end
+ t = t .. "]"
+ texio.write("Creating idea. Title: '" .. key .. "'. Prefix: '" .. prefix .. "', tags: " .. t .. ".\n")
+ deps = {}
+ for _, val in pairs(dependencies)
+ do
+ d = DependencyClass(val[1], val[2])
+ table.insert(deps, d)
+ end
+ table.sort(deps, function(a,b)
+ if b:isGreaterThan(a) then return true end
+ end)
+ idea = IdeaClass(key, content, deps, tags, value)
+ ideaVault:set(prefix, key, idea)
+end
+
+function die(reason)
+ reason = reason or "nil"
+ texio.write_nl("Critical error: " .. reason)
+ tex.error("Critical error: " .. reason)
+end
+
+function startsWith(text, prefix)
+ return text:find(prefix, 1, true) == 1
+end
diff --git a/macros/luatex/latex/ideavault/ideavault.sty b/macros/luatex/latex/ideavault/ideavault.sty
new file mode 100644
index 0000000000..07d6000645
--- /dev/null
+++ b/macros/luatex/latex/ideavault/ideavault.sty
@@ -0,0 +1,67 @@
+% ideavault.sty
+% Copyright 2024 Tomasz M. Czarkowski
+%
+% 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 any later version.
+% The latest version of this license is in
+% https://www.latex-project.org/lppl.txt
+% and version 1.3c or later is part of all distributions of LaTeX
+% version 2008 or later.
+%
+% This work has the LPPL maintenance status `maintained'.
+%
+% The Current Maintainer of this work is Tomasz M. Czarkowski
+%
+% This work consists of the files ideavault.sty and ideavault-lua.lua
+
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{ideavault}[1.0.1]
+\RequirePackage[open,openlevel=2,atend]{bookmark}
+\RequirePackage{xargs}
+\RequirePackage{luacode}
+\RequirePackage{xpatch}
+\RequirePackage{mdframed}
+% Magic that lets mdframed nest more than 3 times
+\makeatletter
+\xpatchcmd{\mdf@preenvsetting}
+ {\mdf@envdepth >\tw@}
+ {\mdf@envdepth >20}
+ {}
+ {}
+\makeatother
+\RequirePackage{needspace}
+
+\directlua{require("ideavault-lua")}
+
+% #1: prefix
+% #2: name
+% #3: content
+% #4: dependencies
+% #5: tags
+% #6: weight
+\newcommandx{\createIdea}[6][1=default, 4=,5=,6=-1]{\luadirect{createIdea(\luastringN{#1}, \luastringN{#2}, \luastringN{#3}, {#4}, {#5}, #6)}}
+
+% #1: prefix
+% #2: style
+% #3: name
+\newcommandx{\printIdea}[3][1=default, 2=lcf]{\luadirect{ideaVault:printIdea(\luastringN{#1}, \luastringN{#3}, \luastringN{#2})}}
+
+% #1: prefix
+% #2: style
+\newcommandx{\printAllWithPrefix}[2][1=default, 2=lcf]{\luadirect{ideaVault:printAllWithPrefix(\luastringN{#1}, \luastringN{#2})}}
+
+% #1: prefix
+% #2: style
+% #3: tag
+\newcommandx{\printAllWithTag}[3][1=default, 2=lcf]{\luadirect{ideaVault:printAllWithTag(\luastringN{#1}, \luastringN{#3}, \luastringN{#2})}}
+
+% Internal commands for managing bookmark depth
+\newcounter{bookmarkDepth}
+\newcommand{\bookDown}{\stepcounter{bookmarkDepth}}
+\newcommand{\bookUp}{\addtocounter{bookmarkDepth}{-1}}
+\newcommand{\bookSet}[1]{\setcounter{bookmarkDepth}{#1}}
+\newcommand{\bookDepth}{\arabic{bookmarkDepth}}
+
+\endinput