summaryrefslogtreecommitdiff
path: root/macros
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2024-04-04 03:02:05 +0000
committerNorbert Preining <norbert@preining.info>2024-04-04 03:02:05 +0000
commit00e667637a3a526b577b05c4d9fead45d65c4c57 (patch)
treec5488d29362ed4d6c10b2271fdf0b54676f18a1e /macros
parente0bd7da7a67c4cd2c53d232fb0f5cfccc4c37743 (diff)
CTAN sync 202404040301
Diffstat (limited to 'macros')
-rw-r--r--macros/generic/memoize/CHANGELOG.md12
-rw-r--r--macros/generic/memoize/Makefile6
-rw-r--r--macros/generic/memoize/doc/memoize-clean.1.md4
-rw-r--r--macros/generic/memoize/doc/memoize-code.pdfbin637916 -> 638117 bytes
-rw-r--r--macros/generic/memoize/doc/memoize-doc-common.sty4
-rw-r--r--macros/generic/memoize/doc/memoize-doc.pdfbin2230627 -> 2240783 bytes
-rw-r--r--macros/generic/memoize/doc/memoize-doc.sty26
-rw-r--r--macros/generic/memoize/doc/memoize-doc.tex1191
-rw-r--r--macros/generic/memoize/doc/memoize-extract.1.md4
-rwxr-xr-xmacros/generic/memoize/memoize-clean.pl4
-rwxr-xr-xmacros/generic/memoize/memoize-clean.py2
-rwxr-xr-xmacros/generic/memoize/memoize-extract.pl17
-rwxr-xr-xmacros/generic/memoize/memoize-extract.py23
-rw-r--r--macros/generic/memoize/memoize.edtx116
-rw-r--r--macros/latex/contrib/coloredtheorem/LICENSE415
-rw-r--r--macros/latex/contrib/coloredtheorem/README.md96
-rw-r--r--macros/latex/contrib/coloredtheorem/coloredtheorem-doc.pdfbin0 -> 201428 bytes
-rw-r--r--macros/latex/contrib/coloredtheorem/coloredtheorem-doc.tex197
-rw-r--r--macros/latex/contrib/coloredtheorem/coloredtheorem.sty59
-rw-r--r--macros/latex/contrib/easybook/easybook.dtx10
-rw-r--r--macros/latex/contrib/easybook/easybook.pdfbin608496 -> 608631 bytes
-rw-r--r--macros/latex/contrib/easybook/easybook.tex5
-rw-r--r--macros/latex/contrib/msu-thesis/README.md4
-rw-r--r--macros/latex/contrib/msu-thesis/docs/msu-thesis.tex12
-rw-r--r--macros/latex/contrib/msu-thesis/msu-thesis.cls26
-rw-r--r--macros/latex/contrib/msu-thesis/msu-thesis.pdfbin113875 -> 114013 bytes
-rw-r--r--macros/latex/contrib/msu-thesis/samples/MSU-thesis-testfile.pdfbin215120 -> 214979 bytes
-rw-r--r--macros/latex/contrib/resolsysteme/doc/ResolSysteme-doc.pdfbin196376 -> 196228 bytes
-rw-r--r--macros/latex/contrib/resolsysteme/doc/ResolSysteme-doc.tex6
-rw-r--r--macros/latex/contrib/resolsysteme/doc/ResolSysteme-exemples-pyluatex.pdfbin126723 -> 126738 bytes
-rw-r--r--macros/latex/contrib/resolsysteme/doc/ResolSysteme-exemples-pyluatex.tex2
-rw-r--r--macros/latex/contrib/resolsysteme/doc/ResolSysteme-exemples.pdfbin158171 -> 158189 bytes
-rw-r--r--macros/latex/contrib/resolsysteme/doc/ResolSysteme-exemples.tex2
-rw-r--r--macros/latex/contrib/resolsysteme/tex/ResolSysteme.sty7
-rw-r--r--macros/latex/contrib/schule/README4
-rw-r--r--macros/latex/contrib/schule/doc/Beispiele/beispiel-ab.pdfbin292663 -> 310127 bytes
-rw-r--r--macros/latex/contrib/schule/doc/Beispiele/beispiel-ab.tex52
-rw-r--r--macros/latex/contrib/schule/doc/Beispiele/beispiel-kl.pdfbin253607 -> 264809 bytes
-rw-r--r--macros/latex/contrib/schule/doc/Beispiele/beispiel-kl.tex46
-rw-r--r--macros/latex/contrib/schule/doc/Beispiele/bsp_aufgabe1/bsp_aufgabe_01.pdfbin167783 -> 167807 bytes
-rw-r--r--macros/latex/contrib/schule/doc/Beispiele/bsp_aufgabe1/bsp_aufgabe_01.tex8
-rw-r--r--macros/latex/contrib/schule/doc/Beispiele/bsp_aufgabe2/bsp_aufgabe.pdfbin184607 -> 184607 bytes
-rw-r--r--macros/latex/contrib/schule/doc/Beispiele/bsp_aufgabe2/bsp_aufgabe.tex8
-rw-r--r--macros/latex/contrib/schule/doc/Beispiele/minimal-ab-dev.pdfbin310619 -> 332031 bytes
-rw-r--r--macros/latex/contrib/schule/doc/Beispiele/minimal-ab-dev.tex6
-rw-r--r--macros/latex/contrib/schule/doc/Beispiele/minimal-ab.pdfbin184473 -> 198047 bytes
-rw-r--r--macros/latex/contrib/schule/doc/Beispiele/minimal-ab.tex2
-rw-r--r--macros/latex/contrib/schule/doc/Beispiele/minimal-ka.pdfbin114295 -> 123414 bytes
-rw-r--r--macros/latex/contrib/schule/doc/Beispiele/minimal-ka.tex14
-rw-r--r--macros/latex/contrib/schule/doc/Beispiele/minimal-kl-aufgabenpool.pdfbin196889 -> 196920 bytes
-rw-r--r--macros/latex/contrib/schule/doc/Beispiele/minimal-kl-et.pdfbin192919 -> 204958 bytes
-rw-r--r--macros/latex/contrib/schule/doc/Beispiele/minimal-kl-et.tex14
-rw-r--r--macros/latex/contrib/schule/doc/Beispiele/minimal-kl.pdfbin175997 -> 187089 bytes
-rw-r--r--macros/latex/contrib/schule/doc/Beispiele/minimal-kl.tex14
-rw-r--r--macros/latex/contrib/schule/doc/changelog.tex6
-rw-r--r--macros/latex/contrib/schule/doc/modulAufgabenpool.tex18
-rw-r--r--macros/latex/contrib/schule/doc/modulBewertung.tex4
-rw-r--r--macros/latex/contrib/schule/doc/modulSymbole.tex4
-rw-r--r--macros/latex/contrib/schule/doc/schule.pdfbin1431361 -> 1472723 bytes
-rw-r--r--macros/latex/contrib/schule/doc/schule.tex5
-rw-r--r--macros/latex/contrib/schule/latex/schule.mod.Aufgaben.code.tex22
-rw-r--r--macros/latex/contrib/schule/latex/schule.mod.Aufgabenpool.code.tex44
-rw-r--r--macros/latex/contrib/schule/latex/schule.mod.Bewertung.code.tex37
-rw-r--r--macros/latex/contrib/schule/latex/schule.mod.Symbole.code.tex4
-rw-r--r--macros/latex/contrib/schule/latex/schule.sty2
-rw-r--r--macros/luatex/generic/minim-mp/README52
-rw-r--r--macros/luatex/generic/minim-mp/minim-mp.doc272
-rw-r--r--macros/luatex/generic/minim-mp/minim-mp.ini2
-rw-r--r--macros/luatex/generic/minim-mp/minim-mp.lua213
-rw-r--r--macros/luatex/generic/minim-mp/minim-mp.mp21
-rw-r--r--macros/luatex/generic/minim-mp/minim-mp.pdfbin120799 -> 134407 bytes
-rw-r--r--macros/luatex/generic/minim-mp/minim-mp.sty50
-rw-r--r--macros/luatex/generic/minim-mp/minim-mp.tex82
-rw-r--r--macros/luatex/generic/minim-mp/minim.mp43
-rw-r--r--macros/luatex/generic/minim/README8
-rw-r--r--macros/luatex/generic/minim/minim-alloc.doc14
-rw-r--r--macros/luatex/generic/minim/minim-alloc.lua2
-rw-r--r--macros/luatex/generic/minim/minim-alloc.tex6
-rw-r--r--macros/luatex/generic/minim/minim-doc.sty3
-rw-r--r--macros/luatex/generic/minim/minim-hooks.tex4
-rw-r--r--macros/luatex/generic/minim/minim-lmodern.tex2
-rw-r--r--macros/luatex/generic/minim/minim-pdfresources.lua4
-rw-r--r--macros/luatex/generic/minim/minim-pdfresources.tex2
-rw-r--r--macros/luatex/generic/minim/minim.doc4
-rw-r--r--macros/luatex/generic/minim/minim.pdfbin383422 -> 397133 bytes
-rw-r--r--macros/luatex/latex/gitinfo-lua/doc/gitinfo-lua.pdfbin115812 -> 116004 bytes
-rw-r--r--macros/luatex/latex/gitinfo-lua/doc/gitinfo-lua.tex1
-rw-r--r--macros/luatex/latex/gitinfo-lua/scripts/gitinfo-lua-cmd.lua8
-rw-r--r--macros/luatex/latex/gitinfo-lua/scripts/gitinfo-lua-recorder.lua79
-rw-r--r--macros/luatex/latex/gitinfo-lua/scripts/gitinfo-lua.lua60
-rw-r--r--macros/luatex/latex/gitinfo-lua/tex/gitinfo-lua.sty6
-rw-r--r--macros/luatex/latex/lua-placeholders/README.md1
-rw-r--r--macros/luatex/latex/lua-placeholders/doc/lua-placeholders-example/example.pdfbin66376 -> 66214 bytes
-rw-r--r--macros/luatex/latex/lua-placeholders/doc/lua-placeholders-manual.pdfbin269309 -> 269558 bytes
-rw-r--r--macros/luatex/latex/lua-placeholders/doc/lua-placeholders-manual.tex12
-rw-r--r--macros/luatex/latex/lua-placeholders/scripts/lua-placeholders-parser.lua2
-rw-r--r--macros/luatex/latex/lua-placeholders/scripts/lua-placeholders.lua7
-rw-r--r--macros/luatex/latex/lua-placeholders/tex/lua-placeholders.sty2
98 files changed, 2398 insertions, 1128 deletions
diff --git a/macros/generic/memoize/CHANGELOG.md b/macros/generic/memoize/CHANGELOG.md
index 3b58418359..9d83b14920 100644
--- a/macros/generic/memoize/CHANGELOG.md
+++ b/macros/generic/memoize/CHANGELOG.md
@@ -3,6 +3,18 @@
For the development history, see [Memoize's GitHub
repository](https://github.com/sasozivanovic/memoize).
+## 2024/04/02 v1.3.0
+
+* New defaults:
+ * `memo dir` is now in effect by default.
+ * `mkdir command` is now initialized to `memoize-extract.pl --mkdir` even
+ when `extract=no` or `extract=tex`.
+* Update the manual to reflect the new defaults (plus many minor improvements).
+* Bugfixes:
+ * The extraction scripts (affecting Windows users): properly escape `\` in
+ log messages.
+ * Biblatex support: `\volcites` now works as advertised.
+
## 2024/03/15 v1.2.0
* Biblatex support:
diff --git a/macros/generic/memoize/Makefile b/macros/generic/memoize/Makefile
index 12737f4c7f..9fadae56ea 100644
--- a/macros/generic/memoize/Makefile
+++ b/macros/generic/memoize/Makefile
@@ -10,10 +10,10 @@ all: ctan/memoize.zip
# Prepare the CTAN submission.
PACKAGE = memoize
-VERSION = 1.2.0
+VERSION = 1.3.0
YEAR = 2024
-MONTH = 03
-DAY = 15
+MONTH = 04
+DAY = 02
FORMAT = generic
diff --git a/macros/generic/memoize/doc/memoize-clean.1.md b/macros/generic/memoize/doc/memoize-clean.1.md
index 3587477305..2d64fb5999 100644
--- a/macros/generic/memoize/doc/memoize-clean.1.md
+++ b/macros/generic/memoize/doc/memoize-clean.1.md
@@ -2,8 +2,8 @@
title: memoize-clean
section: 1
header: User Manual
-footer: memoize-clean of Memoize v1.2.0
-date: March 15, 2024
+footer: memoize-clean of Memoize v1.3.0
+date: April 02, 2024
hyphenate: false
---
diff --git a/macros/generic/memoize/doc/memoize-code.pdf b/macros/generic/memoize/doc/memoize-code.pdf
index 66835fe05d..6d179fcbe6 100644
--- a/macros/generic/memoize/doc/memoize-code.pdf
+++ b/macros/generic/memoize/doc/memoize-code.pdf
Binary files differ
diff --git a/macros/generic/memoize/doc/memoize-doc-common.sty b/macros/generic/memoize/doc/memoize-doc-common.sty
index 3df90535ce..7f2a783a8d 100644
--- a/macros/generic/memoize/doc/memoize-doc-common.sty
+++ b/macros/generic/memoize/doc/memoize-doc-common.sty
@@ -162,8 +162,8 @@
}%
}
-\RenewDocumentCommand\url{ O{} D(){} m }{%
- {\hypercolor{url}{#1}\href{#2#3}{\texttt{#3}}}}
+\RenewDocumentCommand\url{ o D(){} m }{%
+ {\IfValueT{#1}{\hypercolor{url}{#1}}\href{#2#3}{\texttt{#3}}}}
\def\pkgcolor{black}
\NewDocumentCommand\pkg{O{\pkgcolor}m}{{%
diff --git a/macros/generic/memoize/doc/memoize-doc.pdf b/macros/generic/memoize/doc/memoize-doc.pdf
index 14c2a43331..2f08ae2f30 100644
--- a/macros/generic/memoize/doc/memoize-doc.pdf
+++ b/macros/generic/memoize/doc/memoize-doc.pdf
Binary files differ
diff --git a/macros/generic/memoize/doc/memoize-doc.sty b/macros/generic/memoize/doc/memoize-doc.sty
index 29b3042af9..77b3048bb6 100644
--- a/macros/generic/memoize/doc/memoize-doc.sty
+++ b/macros/generic/memoize/doc/memoize-doc.sty
@@ -42,8 +42,6 @@
\usepackage{forest}
\useforestlibrary{edges}
-% \usepackage[extract=latex]{memoize}
-% \usepackage{memoize}
\usepackage[infoshow]{tracefnt}
\tcbuselibrary{xparse,breakable}
@@ -65,7 +63,12 @@
\AdviceOriginal#1\pgfeov
}
-\newcommand\introboxtitle[1]{\strut\textcolor{emphcolor}{\textbf{#1}}}
+\NewDocumentCommand\introboxtitle{om}{%
+ \strut
+ \textcolor{emphcolor}{%
+ \IfValueT{#1}{\hypertarget{#1}}{\textbf{#2}}%
+ }%
+}
\usepackage{fancyhdr}
\usepackage[skip=0.3\baselineskip plus 2pt]{parskip}
@@ -85,6 +88,7 @@
}
\SetEnumitemKey{comma}{itemjoin={{, }}}
\SetEnumitemKey{and}{itemjoin={{, }}, itemjoin*={{, and }}}
+\setlist[itemize,enumerate]{itemsep=0pt plus 1pt minus 2pt}
% \usepackage{lstdoc} % this must be loaded before hyperref
%\usepackage{lstautogobble} % todo: does not work!
@@ -351,7 +355,7 @@
interior style={left color=emphcolor, right color=white},
}
\let\oldparagraph\paragraph
-\def\paragraphskip{3.25ex \@plus1ex \@minus.2ex}
+\def\paragraphskip{3.25ex \@plus1ex \@minus1ex}
\RenewDocumentCommand\paragraph{sm}{%
\mmznext{disable}%
\@startsection{paragraph}{4}{\z@}{\paragraphskip}{-1em}{\paragraph@box}{#2}%
@@ -711,6 +715,20 @@
\usepackage{varioref}
+\NewDocumentCommand\TeXLive{o}{%
+ {%
+ \IfValueT{#1}{\hypercolor{url}{#1}}%
+ \href{https://www.tug.org/texlive/}{\hologo{TeX}~Live}%
+ }%
+ \xspace
+}
+\NewDocumentCommand\MiKTeX{o}{%
+ {%
+ \IfValueT{#1}{\hypercolor{url}{#1}}%
+ \href{https://miktex.org}{MiK\hologo{TeX}}%
+ }%
+ \xspace
+}
% \usepackage{caption}
% \captionsetup{labelformat=empty}
diff --git a/macros/generic/memoize/doc/memoize-doc.tex b/macros/generic/memoize/doc/memoize-doc.tex
index e9047b96c8..69f723441e 100644
--- a/macros/generic/memoize/doc/memoize-doc.tex
+++ b/macros/generic/memoize/doc/memoize-doc.tex
@@ -137,10 +137,14 @@
generic={name=TEXMF\_OUTPUT\_DIRECTORY, label=TEXMF_OUTPUT_DIRECTORY,
index annotation={environment variable, or variable in
\reffile[into index=false]{texmf.cnf}}},
+ generic={name=TEXLIVE\_WINDOWS\_TRY\_EXTERNAL\_PERL,
+ label=TEXLIVE_WINDOWS_TRY_EXTERNAL_PERL,
+ index annotation={variable in \reffile[into index=false]{texmf.cnf}}},
generic={name=openout\_any, label=openout_any,
index annotation={variable in \reffile[into index=false]{texmf.cnf}}},
generic={name=openin\_any, label=openin_any,
index annotation={variable in \reffile[into index=false]{texmf.cnf}}},
+ file={pkg=latexmk, name=memoize\_latexmkrc, label=memoize_latexmkrc},
}%
\docindex{%
cmd={name=pdfprimitive, see={\refcmd[into index=false,short]{primitive}}},
@@ -286,7 +290,7 @@
\end{tcolorbox}
\begin{tcolorbox}[
- title={\introboxtitle{How} does Memoize save your time?},
+ title={\introboxtitle[How]{How} does Memoize save your time?},
]
There is a reason why \TikZ uses an entire compilation cycle to produce a
single externalized picture: \TeX\ itself can only produce a single PDF per
@@ -420,131 +424,78 @@
Good news: using Memoize can be as easy as writing
\EmphVerbatim{\usepackage{memoize}} in the preamble.
-Bad news: Memoize won't work out of the box. The culprit is the extern
-extraction --- the process which ships the externalized graphics from the main
-document into separate extern files; for details, see the title page
-illustration and the ``How'' box in the Introduction. For the extraction to
-work, you will probably have to install some additional software, and you might
-also have to allow your \hologo{TeX} to execute the extraction script. But
-there's a silver lining: once Memoize is set up, it is set up for good.
+Bad news: Memoize won't work out of the box. For optimal operation, it
+requires additional software. The culprit is extern extraction --- the process
+which ships the externalized graphics from the main document into separate
+extern files; for details, see the title page illustration and the
+\hyperlink{How}{``How''} box in the Introduction. But there's a silver
+lining: once Memoize is set up, it is set up for good.
\begin{tcolorbox}[title=What do I have to do?]
-
In principle, all you have to do for Memoize to work \emph{under the default
- configuration} is install Perl library
- \hreftt{https://metacpan.org/pod/PDF::API2}{PDF::API2}; see the Perl section
- below for the installation guideline.
-
+ configuration} is install (\href{https://www.perl.org}{Perl} and) Perl
+ library \hreftt{https://metacpan.org/pod/PDF::API2}{PDF::API2} by following
+ the installation guidelines below.
\end{tcolorbox}
-Consult section~\ref{sec:extraction} if you want to use an extraction method
-other than the default \refmmz{extract=perl}-based method or adapt Memoize to
-your particular workflow (for example, if you're compiling via a Makefile).
-
-If you installed Memoize through the package manager of your \hologo{TeX}
-distribution, your system should be already set up to allow the execution of
-Memoize's extraction scripts. If this is not the case, please contact either
-me or the maintainer of your distribution; until the issue is resolved, you
-have to either
-\begin{enumerate}[(a)]
-\item compile documents loading Memoize with command-line option
- \docref{-shell-escape} (on \hologo{TeX}Live) or
- \docref{--enable-write18} (on MiK\hologo{TeX}), or
-\item set up the restricted shell escape mode to allow for the execution of
- \refscript{memoize-extract.pl}.\footnote{\label{fn:shell-escape-commands}On
- \hologo{TeX}Live, |tlmgr conf texmf shell\_escape| will tell you which shell
- escape mode is currently in effect (|p| = partial = restricted, |f| = disabled
- and |t| = enabled); if necessary, use |tlmgr conf texmf shell\_escape p| to
- set it to restricted. Then, execute \code{tlmgr conf texmf
- shell\_escape\_commands} to get the list of currently allowed commands
- \meta{current}, then add the script by executing \code{tlmgr conf texmf
- shell\_escape\_commands \meta{current},memoize-extract.pl}.
-
- On MiK\hologo{TeX}, the shell escape mode can be reported by |initexmf
- --show-config-value=[Core]ShellCommandMode|, and restricted mode set by
- |initexmf --set-config-value=[Core]ShellCommandMode=Restricted|, and you
- get the \meta{current} list by \code{initexmf
- --show-config-value=[Core]AllowedShellCommands[]}, and add to it by
- \code{initexmf
- --set-config-value=[Core]AllowedShellCommands[]=\meta{current};memoize-extract.pl}.}
-\end{enumerate}
-
Once you have set up your system, I advise you to follow the instructions in
section~\ref{sec:tut:test} to test if the setup was successful.
+\paragraph{Installing Perl}
+If you're running GNU/Linux or macOS, Perl is almost certainly already
+installed on your system; if it is not, install it using your system's package
+manager.
-\begingroup
-\setlength\intextsep{0pt}
-
-\vspace{-1ex}% manual
-
-\paragraph{Perl} If you're running GNU/Linux or macOS, Perl is most likely
-already installed on your system. On Windows, you might have to install it. I
-tested Memoize with Strawberry Perl, available
-at \url(https://){strawberryperl.com}; see \url(https://){www.perl.org} for
-other options. On \hologo{TeX}Live on Windows, you should also set
-\code{TEXLIVE\_WINDOWS\_TRY\_EXTERNAL\_PERL=1}.
-
-\begin{wrapfigure}[2]{r}{0.25\linewidth}
- \raisebox{0.5mm}[\dimexpr\height-0.5mm][\depth]{%
- \mmznext{no verbatim}
- \begin{tcolorbox}[
- % example title=Installing the required library in Perl,
- % attach shifted boxed title to top right,
- % top=2.5mm,
- fontupper=\small,
- left=2mm,
- force nobeforeafter,
- ]
- |cpan PDF::API2|
- \end{tcolorbox}%
- }%
-\end{wrapfigure}
+On Windows, you will most likely have to install Perl, if you haven't done so
+yet. I have tested Memoize with \href{https://strawberryperl.com}{Strawberry
+ Perl}; see \url(https://){www.perl.org} for other options.
+
+Having to install Perl on Windows also applies to users of \TeXLive;
+the built-in Perl won't suffice, as Memoize requires a PDF processing library
+not shipped with \TeXLive. Furthermore, you will also have to convince
+\TeXLive to use the so-called external Perl; from the command prompt
+(|cmd.exe|):
+
+\begin{tcolorbox}[fontupper=\small]
+ |tlmgr conf texmf TEXLIVE_WINDOWS_TRY_EXTERNAL_PERL 1|
+\end{tcolorbox}%
+
+\paragraph{Installing the PDF processing library}
Once Perl is installed on your system, you will also need to install the PDF
processing library \hreftt{https://metacpan.org/pod/PDF::API2}{PDF::API2} (or
its fork, \hreftt{https://metacpan.org/pod/PDF::Builder}{PDF::Builder}). On
some GNU/Linux distributions, this library is included as a package --- just
use your package manager to install it. Otherwise, install it from
\hreftt{https://www.cpan.org}{CPAN} using
-\hreftt{https://metacpan.org/pod/CPAN}{cpan} tool, as shown in the box.
-
-\vspace{-1ex}% manual
-
-\paragraph{Python} Installing (Python and) the required Python library is only
-necessary if you decide to use the Python-based extraction script; see
-section~\ref{sec:extraction}.
+\hreftt{https://metacpan.org/pod/CPAN}{cpan} tool:
-If you're running GNU/Linux, install Python using your package manager.
-Otherwise, download the installer from \url(https://){www.python.org}. You can
-install Python even if you don't have administrator privileges: simply uncheck
-the ``Install launcher for all users'' when running the installer.
-
-\begin{wrapfigure}[2]{r}{0.25\linewidth}
- \raisebox{0.2mm}[\dimexpr\height-0.2mm][\depth]{%
- \mmznext{no verbatim}
- \begin{tcolorbox}[
- % example title=Installing the required library in Python,
- % attach shifted boxed title to top right,
- % top=2.5mm,
- fontupper=\small,
- left=2mm,
- nobeforeafter,
- ]
- |pip install pdfrw2|
- \end{tcolorbox}%
- }%
-\end{wrapfigure}
+\begin{tcolorbox}[fontupper=\small]
+ |cpan PDF::API2|
+\end{tcolorbox}%
-Once Python is installed on your system, you will also need to install the PDF
-processing library |pdfrw2| library (or its predecessor, |pdfrw|, which will
-work just as well). Some GNU/Linux distributions offer this library as a
-package; if this is not the case, and on other operating systems, install it
-from \href{https://pypi.org}{The Python Package Index}
-using \href{https://pip.pypa.io}{pip} tool (if you
-run \href{https://pip.pypa.io}{pip} as a superuser, it will install the library
-system-wide, otherwise locally), as shown in the box.
+\bigskip
-\endgroup % \intextsep
+\begin{tcolorbox}[title=The default settings won't cut it for me!]
+ Here are some situations which require alternative settings (with a brief
+ hint):
+ \begin{itemize}
+ \item If you are compiling your documents using \pkg{latexmk}, install Perl
+ and the PDF processing library as detailed above, integrate the example
+ configuration file \reffile{memoize_latexmkrc} (shipped with \pkg{latexmk}
+ since version~4.84) in your |latexmkrc|, and (optionally) set
+ \code{\refmmz{extract}=\refmmz{extract=no}}. Note that
+ \reffile{memoize_latexmkrc} can be adjusted to perform Python-based
+ extraction.
+ \item If you cannot install Perl or one of the required PDF processing
+ libraries, or extern extraction using these libraries fails, install Python
+ and library |pdfrw2| and then use
+ \code{\refmmz{extract}=\refmmz{extract=python}}.
+ \item If neither Perl or Python are an option, use
+ \code{\refmmz{extract}=\refmmz{extract=tex}}. However, this option is slow
+ and requires some fiddling to set up.
+ \end{itemize}
+ For details, consult sections~\ref{sec:extraction} and~\ref{sec:ref:externs}.
+\end{tcolorbox}
\subsection{The configuration commands}
@@ -557,53 +508,53 @@ or sometimes just \meta{key}. The \meta{keylist} argument is processed by packa
\pkg{pgfkeys} (see \PGFmanual{88}), so you can use all the bells and whistles
of that fantastic PGF utility (like easily defining your own styles).
-Here's some examples of \refcmd{mmzset}. For one, to whet your appetite to learn
-about the various keys in the \refkeypath{/mmz} path, but more importantly now, to show
-you that white-space is irrelevant in the \meta{keylist} argument, so you can
-format the keylist as you wish --- as long as it does not contain an empty
-line.\footnote{I like to add a comma after the final key as well, as shown in
- the bottom left example, because if I don't, I often forget to insert it when
- I add more keys.}
+Here's some examples of \refcmd{mmzset}. For one, to whet your appetite to
+learn about the various keys in the \refkeypath{/mmz} path, but more
+importantly now, to show you that white-space is irrelevant in the
+\meta{keylist} argument, so you can format the keylist as you wish --- as long
+as it does not contain an empty line (bottom right). I like to add a comma
+after the final key (bottom left), because if I don't, I often forget to insert
+it when I add more keys.
\begin{tcbraster}[raster columns=4, raster valign=bottom]
\begin{tcboxedraster}[raster columns=1]{blankest, raster multicolumn=3, valign=bottom}
\begin{tcblisting}{listing only}
-~\mmzset~{memo dir,recompile,memoize=circuitikz}
+~\mmzset~{recompile,auto={circuitikz}{memoize},deactivate=\tikz}
\end{tcblisting}
\begin{tcblisting}{listing only}
-~\mmzset~{memo dir, recompile, memoize=circuitikz}
+~\mmzset~{ auto = \myref {ref}, meaning to context = \foo }
\end{tcblisting}
\end{tcboxedraster}
\begin{tcblisting}{listing only}
~\mmzset~{
- memo dir,
- recompile,
+ no memo dir,
+ verbatim,
padding=2in}
\end{tcblisting}
\end{tcbraster}\par
\begin{tcbraster}[raster columns=4, raster valign=top]
\begin{tcblisting}{listing only, raster multicolumn=2}
~\mmzset~{
- memo dir, readonly,
- memoize=\qrcode{om},
- deactivate=\label,
- disable,
+ auto = \qrcode{memoize, args=om},
+ auto = \mycite{cite},
+ extract = python,
+ record = makefile,
}
\end{tcblisting}
\begin{tcblisting}{listing only}
~\mmzset~{
- memo dir,
- recompile,
+ trace,
+ verb,
% comment
- padding=2in
+ capture=vbox
}
\end{tcblisting}
\begin{tcblisting}{listing only, bad}
~\mmzset~{
- memo dir,
- recompile,
-
- padding=2in
+ extract=tex,
+ no verbatim,
+
+ prefix=memos/
}
\end{tcblisting}
\end{tcbraster}
@@ -646,7 +597,10 @@ once, only the final invocation takes effect.
I like to follow |\usepackage{memoize}| by \refcmd{mmzset}, but if you prefer,
you can also provide the document-wide configuration as \Emph{package options.}
For example, the following are equivalent --- both will force
-re-externalization of all the externs in the document.
+re-externalization of all the externs in the document.\footnote{Note that a
+ slash (\code{/}) may not appear unbraced within package options. While this
+ is usually not an issue, it prevents using \pkg{pgfkeys} key handlers. The
+ workaround is to use key \refmmz{options}.}
\begin{tcbraster}[raster columns=2, raster equal height=rows]
\begin{tcblisting}{listing only}
@@ -669,8 +623,7 @@ files, the location of this file determines whether it applies system-wide,
user-wide or directory-wide. The directory-wide location is clearly the
directory itself. The user-wide and system-wide location depend on the
\hologo{TeX} distribution and which format(s) you want to use
-\reffile{memoize.cfg} with:\footnote{The |memoize| subfolder is not
- obligatory.}
+\reffile{memoize.cfg} with:
\begin{center}
\meta{the relevant texmf tree root}|/tex/|\meta{format}|/memoize/memoize.cfg|
@@ -678,13 +631,14 @@ directory itself. The user-wide and system-wide location depend on the
You can say |generic| for \meta{format} if you want the configuration file to
be accessible by all formats, otherwise \meta{format} should be one of the
-formats supported by Memoize: |plain|, |latex| or |context|. The texmf root
-directory depends on the distribution, here's how to figure out what it is:
+formats supported by Memoize: |plain|, |latex| or |context|. The |memoize|
+subfolder shown above is not obligatory. The texmf root directory depends on
+the distribution, here's how to figure out what it is:
\begin{tcboxedraster}
[raster columns=1, raster valign=top, raster force size=false]
{title=The roots of TEXMF trees}
-\begin{tcolorbox}[title={\hologo{TeX} Live\hfill\url[white](https://){tug.org/texlive}}]
+\begin{tcolorbox}[title={\TeXLive[white]\hfill\url[white](https://){tug.org/texlive}}]
\begin{description}[itemsep=0pt]
\item[user-wide]
|tlmgr conf texmf TEXMFHOME|
@@ -699,48 +653,44 @@ directory depends on the distribution, here's how to figure out what it is:
\smallskip
Don't forget to run |texhash| or |mktexlsr| after creating \reffile{memoize.cfg}.
\end{tcolorbox}
-\begin{tcolorbox}[title={MiK\hologo{TeX}\hfill\url[white](https://){miktex.org}}, before upper={\parskip0.3\baselineskip plus 2pt\relax},]
- Open the MiK\hologo{TeX} Console, select the ``Settings'' page and then the
+\begin{tcolorbox}[title={\MiKTeX[white]\hfill\url[white](https://){miktex.org}},
+ before upper={\parskip0.3\baselineskip plus 2pt\relax},]
+ Open the \MiKTeX Console, select the ``Settings'' page and then the
``Directories'' tab.
If there is a folder marked with the ``Generic'' purpose with attribute
``User'' (for a user-wide \reffile{memoize.cfg}) or ``Common'' (for a system-wide
\reffile{memoize.cfg}), that's the folder you are looking for. Otherwise, create a
- folder following MiK\hologo{TeX}'s instructions and add it to the list.
+ folder following \MiKTeX's instructions and add it to the list.
Don't forget to click ``Refresh file name database'' (in the ``Tools'' menu
- of the MiK\hologo{TeX} Console) after creating \reffile{memoize.cfg}.
+ of the \MiKTeX Console) after creating \reffile{memoize.cfg}.
\end{tcolorbox}
\end{tcboxedraster}
Note that a directory config file will override the user config, and the user
config will in turn override the system-wide one. This should not concern you
too much, because you will probably only want to use the user-wide config
-anyway,\cprotect\footnote{If you want to have a directory-wide configuration
- based on (rather than overriding) the user-wide configuration, your could
- write down the real user-wide config in, say, |memoize.user.cfg| (located
- user-wide), and then |\input| this file by both the user-wide and the
- directory-wide \reffile{memoize.cfg}. Of course, the same logic can be used to base
- a user-wide config on the system-wide one.} which might look something like
-this:
+anyway, which might look something like this:
\ExampleName{memoize}
\makeexample{\examplename.cfg.c1}
\tcbinputexample[.cfg]{listing only}
-I recommend including \refmmz{memo dir} in your \reffile{memoize.cfg},
-as shown in the first line. It reduces the clutter in the document
-directories; see section~\ref{sec:tut:memodir} for details.
-
-The \refmmz{extract} line concludes the story on ``permanently'' selecting the
-extraction method, started in chapter~\ref{sec:setup}. As the final note,
-observe that \refmmz{extract} and other extraction-related keys like
-\refmmz{perl extraction options} only make sense as a package option or as a
+(The \refmmz{extract} line above ``permanently'' selects the Python-based
+internal extraction method, which uses script \refscript{memoize-extract.py}.
+Note that \refmmz{extract} and other extraction-related keys like \refmmz{perl
+ extraction options} only make sense as a package option or as a
\refcmd{mmzset} key in \reffile{memoize.cfg}. They will have no effect as a
-\refcmd{mmzset} key in the document, because the extraction happens while the
-package is loaded.
-
+\refcmd{mmzset} key in the document, because extraction happens while the
+package is loaded.)
+If you want to have a directory-wide configuration based on (rather than
+overriding) the user-wide configuration, your could write down the ``real''
+user-wide config in, say, |memoize.user.cfg| (located user-wide), and then
+|\input| this file by both the user-wide and the directory-wide
+\reffile{memoize.cfg}, overriding what you want in the latter. Of course, the
+same logic can be used to base a user-wide config on the system-wide one.
\section{Your first memoized documents}
\label{sec:tut}
@@ -838,8 +788,8 @@ ignores any spaces surrounding the given code.
Both the \refenv{memoize} environment and the \refcmd{mmz} command take a
configuration keylist as the optional argument, so their full syntax is
-\cs{begin}\marg{\refenv{memoize}}\oarg{keylist}\meta{code to be
- externalized}\cs{end}\marg{\refenv{memoize}} and and
+\cs{begin}\braces{\refenv{memoize}}\oarg{keylist}\meta{code to be
+ externalized}\cs{end}\braces{\refenv{memoize}} and
\refcmd{mmz}\oarg{keylist}\marg{code to be externalized}. The keys given in
this optional argument take precedence over the keys set by \refcmd{mmzset}.
Note that \refcmd{mmznext} does not apply to manual memoization.
@@ -992,9 +942,9 @@ Memoize to reexternalize the picture. The simplest way to do that is by using
the \Emph{\refmmz{recompile}} key; below, we write
\refcmd{mmznext}\bracestt{\refmmz{recompile}} just before the picture and
compile the document again (remember from section~\ref{sec:mmzset} that
-whatever keys we provide through \refcmd{mmznext} only apply to the instance of
-automemoization). After the compilation, we may (and should) remove the
-\refmmz{recompile} directive (otherwise, Memoize will produce the extern page
+whatever keys we provide through \refcmd{mmznext} only apply to the next instance of
+automemoization). After the compilation, we should remove the
+\refmmz{recompile} directive, otherwise, Memoize will produce the extern page
again and again).
\tcbinputexample[.tex][.c3]{
@@ -1161,11 +1111,11 @@ comma-separated list of command and environment names, e.g.\
Memoize offers several variants of \refmmz{meaning to context}, applicable to
various types of commands. For example, the easiest way of making the picture
-depend on the definition of a \pkg{pgfkeys} style is to use handler
+depend on the definition of a \pkg{pgfkeys} style is to use key handler
\Emph{\refkey{/handlers/.meaning to context}} --- note the dot in the name, and
observe that \code{emph/.meaning to context} below is executed within
-\cs{tikzset}, not \refcmd{mmzset}; see \PGFmanual{87} to learn about key
-handlers.
+\cs{tikzset} (where key \code{emph} was defined), not \refcmd{mmzset}; see
+\PGFmanual{87} to learn about key handlers.
\ExampleName{meaning-to-context}
\makeexample{\examplename.pdf N=2}
@@ -1200,112 +1150,123 @@ single picture, as \refkey{/handlers/.meaning to context} cannot be used within
\label{sec:tut:memodir}
Memoize produces lots of auxiliary files. For each piece of memoized code, it
-produces two \emph{memo} files (we will learn more about these in
-section~\ref{sec:memos}), which will be joined by the extern PDF upon the next
-compilation.\footnote{If you're using the \hologo{TeX}-based extraction, each
- extern (|.pdf|) is also accompanied by a log file (|.log|) produced during
- the compilation that extracted the extern.} You can recognize these files
-easily: their names start with the name of your document and include one or two
-long hexadecimal numbers.
+produces two \emph{memo} files (a \emph{c-memo} and a \emph{cc-memo}; we will
+learn more about them in section~\ref{sec:memos}), which will be joined by the
+extern PDF once extern extraction takes place --- under the default settings,
+upon the next compilation. To top it off, changing the memoized code will
+produce new memo and extern files, with the old files staying in place.
+
+To reduce the clutter (imagine the directory listing as below, but for a
+document with a hundred externalized pictures which you have been working on
+for a month) in the output directory (which is normally the directory where you
+keep your source files and where the document PDF is created), Memoize keeps
+memos and externs in the \emph{memo directory}, named \code{\meta{document
+ name}.memo.dir} by default. The names of these files consist of one or two
+long hexadecimal numbers, followed by extension |.memo| for memos and |.pdf|
+for externs. The first hexadecimal number in these filenames is the MD5 sum of
+the memoized code and that's how Memoize knows which memo belongs to which
+piece of code. The second hexadecimal number is the MD5 sum of the
+\emph{context}, a concept crucial for properly externalizing code containing
+cross-references and such; we will discuss this concept in detail in
+section~\ref{sec:cross-referencing}.
+
+Besides memos and externs, Memoize produces two other auxiliary files, the
+\dmmz record file and an extraction log with suffix |.mmz.log|. These files
+facilitate the communication between the \hologo{TeX} part of the package and
+the extern extraction scripts; see section~\ref{sec:record-files} for
+details.\cprotect\footnote{If you're using the \hologo{TeX}-based extraction
+ (\code{\refmmz{extract}=\refmmz{extract=tex}}), each extern (|.pdf|) is also
+ accompanied by a \hologo{TeX} log file (|.log|) produced during the
+ compilation that extracted the extern.}
-\ExampleName{dirty-house}
+\ExampleName{clean-house}
\makeexample{\examplename.pdf}
-{
+{%
\relaxmmzcommands
\edef\marshal{%
\noexpand\def\noexpand\mynewextern\examplename
- }\marshal.#1-#2.pdf\relax{%
+ }\marshal.memo.dir/#1-#2.pdf\relax{%
\forestset{
- append={[\examplename.#1.memo\vphantom{p},pointcolor]},
- append={[\examplename.#1-#2.memo\vphantom{p},pointcolor]},
- append={[\examplename.#1-#2.pdf,pointcolor]},
+ append={[#1.memo\vphantom{p},pointcolor,name=cmemo]},
+ append={[#1-#2.memo\vphantom{p},pointcolor,name=ccmemo]},
+ append={[#1-#2.pdf,pointcolor,name=extern]},
}%
}
\tcbinputexample{
+ middle=1mm,
comment={%
- \begin{tcolorbox}[reset, left=2mm, bottom=0mm,
+ \begin{tcolorbox}[reset, left=2mm, top=0mm, bottom=0mm, right=0mm,
my boxed title=the folder contents (after two compilations),
attach shifted boxed title to top right,
]
\begin{forest}
before typesetting nodes={for tree={
font=\scriptsize\tt, grow'=0, folder, s sep=0}},
- [\meta{the document folder}, inner xsep=0,
- TeX={%
- \def\mmzNewExtern##1##2##3##4{\mynewextern##1\relax}%
- \input{\examplepath.mmz}%
- },
+ [\meta{the document folder}, inner xsep=0
[\examplename.tex]
[\examplename.pdf]
[\normalsize\dots, no edge]
- [\examplename.mmz, tikz={\draw[dotted](.east)--+(5em,0ex) node [anchor=south west, yshift=-1ex, align=justify, text width=14em, font=\footnotesize]{This is another auxiliary file produced by Memoize. We will mention it at the end of the section.};}]
+ [\examplename.mmz, pointcolor, name=mmz]
+ [\examplename.mmz.log, pointcolor, name=mmzlog]
+ [\examplename.memo.dir, pointcolor, name=memodir,
+ TeX={%
+ \def\mmzNewExtern##1##2##3##4{\mynewextern##1\relax}%
+ \input{\examplepath.mmz}%
+ },
+ ]
]
+ \draw[dotted, every node/.style={anchor=west, font=\footnotesize\strut}]
+ (ccmemo.east) -- +(1.5em,0pt) node(temp){the cc-memo}
+ (mmz.east) -- (mmz -| temp.west) node{the \dmmz file}
+ (mmzlog.east) -- (mmzlog -| temp.west) node{the extraction log}
+ (memodir.east) -- (memodir -| temp.west) node{the memo directory}
+ (cmemo.east) -- (cmemo -| temp.west) node{the c-memo}
+ (extern.east) -- (extern -| temp.west) node{the extern}
+ ;
\end{forest}
\end{tcolorbox}
},
}
}
-To top it off, changing the memoized code will produce new memo (and extern)
-files, with the old files staying in place. This is all by design --- the
-first hexadecimal number in these filenames is the MD5 sum of the memoized code
-and that's how Memoize knows which memo belongs to which piece of
-code\footnote{The second hexadecimal number in the memo and extern filenames is
- the MD5 sum of the \emph{context}. The context is crucial for properly
- externalizing code containing cross-references, see
- section~\ref{sec:cross-referencing} for details.} --- but it has the downside
-that the folder containing your document can get quite cluttered (imagine the
-directory listing as above, but for a document with a hundred externalized
-pictures which you have been working on for a month).
-
-\ExampleName{clean-house}
-
-I like to keep a clean house by instructing Memoize to put memos and friends
-into their own directory. This can be achieved by writing
-\refcmd{mmzset}\braces{\Emph{\refmmz{memo dir}}} into the preamble (anytime
-after loading the package).\footnote{The \refmmz{memo dir} key is in fact
- merely an abbreviation for \code{\refmmz{prefix}=\string\jobname.memo.dir};
- use this key if you need more control over the name and location of the
- auxiliary files. Furthermore, there is also the \refmmz{no memo dir} key,
- which reverts the configuration back to the dirty default.} This will put
-the memo and the extern files into folder \meta{document name}|.memo.dir| (and
-it will also omit the \meta{document name} prefix in their filenames, because
-it makes no sense to repeat it there).
+The clean house (clean in the sense that most of the auxiliary files reside in
+a dedicated directory) depicted above is courtesy of key \refmmz{memo dir},
+which is in effect by default since Memoize version 1.3.0. Here's how a dirty
+house, which we can produce using key \refmmz{no memo dir}, would look like:
+\ExampleName{dirty-house}
\makeexample{\examplename.pdf}
-{%
+{
\relaxmmzcommands
\edef\marshal{%
\noexpand\def\noexpand\mynewextern\examplename
- }\marshal.memo.dir/#1-#2.pdf\relax{%
+ }\marshal.#1-#2.pdf\relax{%
\forestset{
- append={[#1.memo\vphantom{p},pointcolor]},
- append={[#1-#2.memo\vphantom{p},pointcolor]},
- append={[#1-#2.pdf,pointcolor]},
+ append={[\examplename.#1.memo\vphantom{p},pointcolor]},
+ append={[\examplename.#1-#2.memo\vphantom{p},pointcolor]},
+ append={[\examplename.#1-#2.pdf,pointcolor]},
}%
}
\tcbinputexample{
+ middle=1mm,
comment={%
- \begin{tcolorbox}[reset, left=2mm, bottom=0mm,
+ \begin{tcolorbox}[reset, left=2mm, top=0mm, bottom=0mm,
my boxed title=the folder contents (after two compilations),
attach shifted boxed title to top right,
]
\begin{forest}
before typesetting nodes={for tree={
font=\scriptsize\tt, grow'=0, folder, s sep=0}},
- [\meta{the document folder}, inner xsep=0
+ [\meta{the document folder}, inner xsep=0,
+ TeX={%
+ \def\mmzNewExtern##1##2##3##4{\mynewextern##1\relax}%
+ \input{\examplepath.mmz}%
+ },
[\examplename.tex]
[\examplename.pdf]
[\normalsize\dots, no edge]
- [\examplename.mmz]
- [\examplename.memo.dir,pointcolor,
- % tikz={\draw[dotted](.east)--+(9em,0ex) node [anchor=south west, yshift=-1ex, font=\footnotesize, emphshade=black!5!white, text width=15em, align=justify]{You need to create this directory by hand, or allow Memoize to create it by adding |mkdir| to the list of restricted shell escape commands.};},
- tikz={\draw[dotted](.east)--+(9em,0ex) node [anchor=west, font=\footnotesize, emphshade=black!5!white]{This directory must be created, somehow.};},
- TeX={%
- \def\mmzNewExtern##1##2##3##4{\mynewextern##1\relax}%
- \input{\examplepath.mmz}%
- },
- ]
+ [\examplename.mmz, pointcolor]
+ [\examplename.mmz.log, pointcolor]
]
\end{forest}
\end{tcolorbox}
@@ -1313,73 +1274,73 @@ it makes no sense to repeat it there).
}
}
-\begin{tcolorbox}[title={Why is \refmmz[link color=white]{memo dir} not the default?}]
- The \code{clean-house} example most likely compiled just fine, and you are
- wondering why \refmmz{memo dir} is not in effect by default. Well, out of
- the box, \hologo{TeX} cannot create directories, so it is the fact that
- Memoize \emph{can} create them (at least under the default settings) which
- requires explanation. By default, Memoize triggers extraction by executing
- the Perl extraction script \refscript{memoize-extract.pl}, and it is this
- script which actually creates the memo directory. However, not everybody
- will necessarily use this script \dots\ so \refmmz{memo dir} should not be
- the default.
-
- The Python extraction script \refscript{memoize-extract.pl}, used when
- \refmmz{extract}|=|\refmmz{extract=python}, works the same as the Perl
- variant. With \hologo{TeX}-based extraction
- \refmmz{extract}|=|\refmmz{extract=tex}, things are different. If you are
- compiling the document with a full shell escape mode
- (\docref{-shell-escape}), Memoize successfully creates the directory with the
- system command |mkdir|.\footnote{|mkdir| is the default value of key
- \refmmz{mkdir command}, but executing the extraction method
- \refmmz{extract=perl} or \refmmz{extract=python} overrides this default.}
- However, if you're using the restricted shell escape mode, the attempt to
- create the directory won't succeed unless you include |mkdir| among the
- restricted shell escape commands (see footnote~\ref{fn:shell-escape-commands}
- on page~\pageref{fn:shell-escape-commands} for how to do this, but note that
- it is not recommended).
-
- If you are using external extraction, you have to create directory
- \texttt{\examplename.memo.dir} by hand, prior to the first compilation of the
- document (with Memoize). This is the case even if you are performing the
- extraction using one of the shipped extraction methods, and it is due to the
- fact that Memoize needs the memo directory to be present even before extern
- extraction, because it writes the |.memo| files into the same directory.
- (When Memoize uses the extraction script to create the memo directory, it
- does so completely independently of extraction, and prior to creating any
- |.memo| files.)
-\end{tcolorbox}
+I assume \refmmz{no memo dir} will only be useful in very special situations,
+when Memoize is unable to create the memo directory. Presumably, this could
+only happen if neither Perl nor Python is available on the system (the author
+is then most likely falling back to \hologo{TeX}-based extraction by issuing
+\code{\refmmz{extract}=\refmmz{extract=tex}}). For details, see
+section~\ref{sec:extraction}.
-I actually suggest adding \refcmd{mmzset}\braces{\refmmz{memo dir}} into your
-user-wide \reffile{memoize.cfg} (see section~\ref{sec:memoize.cfg} for details
-on this file). This will keep all your houses clean --- without work! --- as
-Memoize will automatically use the memo directory for any document your create.
+We have seen that Memoize keeps the document folder reasonably clean by writing
+most of its auxiliary files into the memo directory. However, you might
+sometimes want to perform some additional clean-up by removing all or certain
+memos and externs. Perhaps to return to the blank slate after a major
+redefinition of macros which the externalized pictures depend on, perhaps due
+to strange errors which you believe might be caused by Memoize (in that case,
+please write to me!), or perhaps just to save some disk space --- remember that
+typically, many memos and externs are \emph{stale} anyway, i.e.\ they reflect
+some previous state of your document and are not needed anymore. Whatever the
+reason for the clean-up, rest assured that it is always safe to delete memos
+(|.memo|) and externs (|.pdf|s residing next to memos and bearing the same
+basename), or even the entire \code{\meta{document name}.memo.dir} directory,
+in the sense that you cannot lose data this way.
+
+Stale memos and externs may be deleted without any repercussions whatsoever
+(unless you later revert to a previous version of the document, of course). In
+fact, you might \emph{want} to delete them periodically, or at least once you
+finish writing the document. As it is hard to figure out which memos and
+externs are stale, Memoize ships with a clean-up script: writing
+\EmphTT{\refscript{memoize-clean.pl}} \meta{document name} (substitute |.py|
+for |.pl| to use the Python rather than the Perl version of the script) into
+the command line will delete all memos and externs belonging to the document
+which are not used in the current version of the document (the script inspects
+the \dmmz file to see which memos and externs are currently in use).
+
+To delete all memos and externs, even the ones currently in use, execute the
+clean-up script with option \refscript{memoize-clean.pl--all}. Users of
+\pkg{latexmk} can this perform this full clean-up by the regular \code{latexmk
+ -c}, as long as they have integrated the example configuration file
+\reffile{memoize_latexmkrc} into their |latexmkrc|.
+
+If you delete a memo or an extern currently in use, you will trigger
+recompilation of their code --- so deleting a memo or an extern is actually a
+perfectly legal alternative to using the \refmmz{recompile} key! The only
+issue with triggering recompilation of a specific extern in this way is that
+the extern might be hard to locate. When the number of externs is small
+enough, visual inspection via file manager thumbnails works great. When the
+number is greater, it might be best to invoke \refmmz{direct ccmemo input} and
+use the inverse search function of your \hologo{TeX} editor, but one could also
+use \refmmz{trace} or grep the c-memos.
-It is always safe to delete memos (|.memo|) and externs (|.pdf|s residing next
-to memos), in the sense that you cannot lose data this way.\footnote{The same
- goes for the extern |.log| files produced by the \hologo{TeX}-based
- extraction.}
+\begin{tcolorbox}[warning]
+ Deleting memos and externs is never an irreversible operation, as you can
+ always recreate them, but it is still wise to be cautious when cleaning up.
+ For one, avoid running \refscript{memoize-clean.pl} after a compilation which
+ produced errors; a failed compilation can lead to an incomplete \dmmz file,
+ which can in turn lead to over-deletion. Another bad idea is cleaning up
+ after disabling Memoize for a part of a document, for the same reason.
-\begin{itemize}
+ All that said, Memoize takes some precautions itself. It will cowardly
+ refuse to perform the clean-up when the \dmmz file is missing the
+ end-of-file marker (|\endinput|), assuming that this indicates a fatal error
+ in the previous compilation. It will do the same in case the \dmmz file is
+ absent or empty. The latter is assumed to be a result of a globally
+ \refmmz{disable}d memoization, but note that clean-up will be performed if
+ memoization was disabled using package \refpkg{nomemoize}: that package does not
+ touch the \dmmz file, so cleaning up should work as intended.
+\end{tcolorbox}
-\item Many memos and externs are typically stale anyway, i.e.\ they reflect
- some previous state of your document and are not needed anymore. These files
- can be deleted without any repercussions whatsoever (unless you later revert
- to a previous version of the document, of course). In fact, you might
- \emph{want} to delete them periodically, or at least once you finish writing
- the document. As it is hard to figure out which memos/externs are stale,
- Memoize ships with a clean-up script: writing \refscript{memoize-clean.pl}
- \meta{document name}\dmmz (replace |.pl| with |.py| if you use Python rather
- than Perl) into the command line will delete all the \emph{stale} auxiliary
- files belonging to the document.
-
-\item If you delete a memo or an extern currently in use, you will trigger
- recompilation of their code --- so deleting a memo or an extern is actually a
- perfectly legal alternative to using the \refmmz{recompile} key!\footnote{For the
- users of the \hologo{TeX}-based extraction: deleting the |.log| file does
- \emph{not} trigger recompilation.}
-\end{itemize}
It is also safe to delete the \dmmz file (or any other kind of record file, see
section~\ref{sec:record-files}) residing next to your document's |.pdf|. The
@@ -1407,12 +1368,17 @@ process --- work sensibly in this kind of situation? More precisely, can the
book and the individual chapters share the memos and the externs? Yes they
can! If we instruct Memoize to use the same memo directory for both the book
job and the chapter jobs, then we can externalize graphics when compiling a
-chapter and have the externs included when compiling the book (and vice
-versa).\footnote{Package \pkg{docmute} makes \hologo{LaTeX} ignore the preamble of
- the chapter file when including this file into the main document.} All we
-need to do is use our old friend \refmmz{memo dir} from section~\ref{sec:tut:memodir}
---- we see now that this setting is good for more than just keeping a clean
-house!
+chapter and have the externs included when compiling the book (and vice versa).
+As shown below,\footnote{Package \pkg{docmute} makes \hologo{LaTeX} ignore the
+ preamble of the chapter file when including this file into the main
+ document.} all we need to do is use key \refmmz{memo dir} mentioned in
+section~\ref{sec:tut:memodir}. When given a value, \code{\refmmz{memo
+ dir}=\meta{name}}, it effectively makes Memoize pretend it is working on
+document \code{\meta{name}.tex}, in the sense that it stores the memos and
+externs in directory \code{\meta{name}.memo.dir}.\footnote{Use key
+ \refmmz{prefix} if you need need more control over the name and location of
+ the auxiliary files.} (As you can see below on the left, \meta{name} may
+contain a directory part.)
\ExampleName{book}
\makeexample{\examplename.tex.c1}
@@ -1428,22 +1394,24 @@ In the above example, the individual chapters reside in files stored in the
\code{\refmmz{memo dir}=chapters/book} (rather than \code{\refmmz{memo
dir}=book} or just \refmmz{memo dir}). However, Memoize has no trouble
with a situation where the main file and the chapters reside in the same
-folder; the setup is even simpler, as we then say \code{\refmmz{memo dir}=book}
-in both the book and the chapter preamble. The more complicated situation was
-chosen to point out the following potential problem with the setup where the
-chapters reside in a subdirectory.
+folder; the setup is even simpler, as we may then omit the \refmmz{memo dir}
+invocation in the main file. The more complicated situation was chosen to
+point out the following potential problem with the setup where the chapters
+reside in a subdirectory.
If you're anything like me, you would first go for having a memo directory
-immediately contained in the project directory (so |examples/book.memo.dir|
-above) and set up \refmmz{memo dir} as shown below. Well, this won't work, or
-at least it won't work with the vanilla \hologo{TeX} Live, because \hologo{TeX}
-will refuse to \emph{write} into (memo) files outside the directory where it
-was executed,\cprotect\footnote{In \hologo{TeX} Live, the \reffile{texmf.cnf}
- option controlling this behaviour is called \docref{openout_any}. By default, it is
- set to |p| (paranoid), which ``disallow[s] opening dot files [and]
- \emph{going to parent directories}, and restrict[s] absolute paths to be
- under \docref{TEXMFOUTPUT}'' (emphasis mine).} and this is precisely what
-the chapter compilation is asked to do below.
+immediately contained in the project directory and set up \refmmz{memo dir} as
+shown below. Well, this won't work, or at least it won't work with the vanilla
+\TeXLive, because \hologo{TeX} will refuse to \emph{write} into (memo)
+files outside the directory where it was
+executed,\cprotect\footnote{\label{fn:openout_any}In \TeXLive, the
+ \reffile{texmf.cnf} option controlling this behaviour is called
+ \docref{openout_any}. By default, it is set to |p| (paranoid), which
+ ``disallow[s] opening dot files [and] \emph{going to parent directories}, and
+ restrict[s] absolute paths to be under \docref{TEXMFOUTPUT}'' (emphasis
+ mine). (In \MiKTeX, the option is called
+ |[Core]AllowUnsafeOutputFiles|.)} and this is precisely what the chapter
+compilation is asked to do below.
\begin{tcboxedraster}[raster columns=2, raster valign=top]{blankest, bad}
\begin{tcblisting}{example title, title=the main file, listing only}
@@ -1495,19 +1463,19 @@ set), you will have a reasonably up-to-date set of externs.
This is the trick in a nutshell, but to make it really work we have to
address one further issue: the original document and the region have to share
- memos and externs. This happens automatically if the original document sets
- \refmmz{memo dir} explicitly (e.g.\ if a document called |doc.tex| contains
- \code{\refmmz{memo dir}=doc} in the preamble), but I'm lazy and don't want to
- write this in every document --- if I have to do that, what's the point of
- \refmmz{memo dir} I put into my \reffile{memoize.cfg} in
- section~\ref{sec:tut:memodir}? Fortunately, the region file starts with
- |\message{ !name(|\meta{original document name}|.tex)}| to indicate the
- origin. The complicated part of the code below (everything following
- \refcmd{mmzset}\braces{\refmmz{readonly}} parses this header to extract the
- \meta{original document name}, which is then fed to \refmmz{memo dir}. Now,
- the trick works automatically for any document.\footnote{The assumption here
- is that \refmmz{memo dir} is in effect for the original document. If not,
- the trick can be adapted to use \refmmz{prefix}.}
+ memos and externs. This happens automatically if the original document
+ provides an explicit value to \refmmz{memo dir}, e.g.\ if a document called
+ |doc.tex| contains \code{\refmmz{memo dir}=doc} in the preamble, but I'm lazy
+ and don't want to write this in every document. Fortunately, the region file
+ starts with |\message{ !name(|\meta{original document name}|.tex)}| to
+ indicate the origin. The complicated part of the code below (everything
+ following \refcmd{mmzset}\braces{\refmmz{readonly}}) parses this header to
+ extract the \meta{original document name}, which is then fed to \refmmz{memo
+ dir}. Now, the trick works automatically for any document.\footnote{More
+ precisely, the trick works for every document where \refmmz{memo dir} is in
+ effect --- which, remember, is the default. It is easy enough, however, to
+ adapt the trick to use \refmmz{no memo dir} or an arbitrary
+ \refmmz{prefix}.}
\tcbinputexample{
title=\tt memoize.cfg,
@@ -1558,11 +1526,11 @@ one) appearing on all overlays. The key may be invoked either from a prior
section~\ref{sec:tut:verbatim} to learn what that is.} or executed in the
memoized code itself. The example below illustrates the latter option, and
also shows that we may invoke it via its full path,
-\refkeypath{/mmz}|/|\refmmz{per overlay}, when listed among options processed by
-\pkg{pgfkeys}.\footnote{Read section~\ref{sec:per-overlay} to learn how the
- Beamer support is implemented. The implementation only uses Memoize's public
- interface, so understanding it should help if you need to support some other
- presentation package.}
+\refkeypath{/mmz}|/|\refmmz{per overlay}, when listed among \TikZ options, or
+any other options processed by \pkg{pgfkeys}.\footnote{Read
+ section~\ref{sec:per-overlay} to learn how the Beamer support is implemented.
+ The implementation only uses Memoize's public interface, so understanding it
+ should help if you need to support some other presentation package.}
\tcbinputexample{
listing options app={firstline=3},
@@ -1646,7 +1614,7 @@ document. In our example, however, the default padding is not enough --- the
pin is only partially visible.\footnote{You might wonder why I didn't make the
default padding much bigger, like 10 inches. \hologo{TeX} wouldn't be
bothered (unless the resulting extern size exceeded its maximum dimension),
- but you might be, because with such a large default padding, all the externs
+ but you might be, because with such a large default padding, all externs
would be huge, most often bigger than the document pages, and remember that
the externs are first dumped into the document, where they can bother you.}
@@ -1761,7 +1729,7 @@ of your document, at least if you intend to distribute it in electronic form,
for two reasons:
\begin{itemize}
\item An externalized picture cannot contain hyperlinks. Any hyperlinks (or
- hyperlink anchors) contained in the original picture will silently disappear
+ hyperlink anchors) contained in the original picture silently disappear
during the production of the extern.
\item When the document contains many externs, the size of the resulting PDF
can be several times the size of the PDF compiled without externalization.
@@ -1796,54 +1764,29 @@ can be sure that not a single memo or extern was loaded or produced.
There is one issue you might need to resolve manually before package
\refpkg{nomemoize} works as intended, though. If you have used any
\refkeypath{/mmz} keys outside \refcmd{mmzset}, you need to list them in
-\refcmd{nommzkeys}. For example, if you used \refmmz{per overlay} in the manner
-illustrated in section~\ref{sec:tut:beamer}, i.e.\ as
+\refcmd{nommzkeys}. For example, if you used \refmmz{per overlay} in the
+manner illustrated in section~\ref{sec:tut:beamer}, i.e.\ as
\refkeypath{/mmz}|/|\refmmz{per overlay} among the \TikZ keys, you need to
write \refcmd{nommzkeys}\braces{\refmmz{per overlay}} into the document
-preamble.
+preamble. (This command may also appear in a document loading \pkg{memoize},
+where it does nothing.)
Another thing you might want to do once you have produced the final version of
the document (in fact, just before you disable Memoize for good) is clean up.
-As we saw in sections~\ref{sec:tut:memodir} and~\ref{sec:tut:redefinitions},
-Memoize produces a lot of auxiliary files (memos and externs) and it keeps the
-old versions around! Once your document is prepared, you can reduce the
-clutter (and save some disk space) by deleting memos and externs belonging to
-the work-in-progress versions of your document, and keep only those used in the
-final version.
-
-You could achieve this by deleting all the memos and externs (if you're using
-the \refmmz{memo dir} directive, this amounts to the entire contents of the
-memo directory) and compiling your document for the final couple of times.
-However, there is an easier (but \hologo{TeX}-external) way: on the command
-line, change into the directory containing your (main) document and write
-\EmphTT{\refscript{memoize-clean.pl}} \meta{document name}\dmmz (substitute
-|.py| for |.pl| to use Python rather than Perl). The script will inspect the
-contents of the \dmmz record file to see which memos and externs were used in
-the final compilation, and delete all other memos and externs belonging to the
-given document.
-
-\begin{tcolorbox}[warning]
- Deleting memos and externs is never an irreversible operation, as you can
- always recreate them, but it is still wise to be cautious when cleaning up.
- For one, avoid cleaning up after a compilation which produced errors; a
- failed compilation can lead to an incomplete \dmmz file, which can in turn
- lead to over-deletion. Another bad idea is cleaning up after disabling
- Memoize for a part of a document, for the same reason.
-
- All that said, Memoize takes some precautions itself. It will cowardly
- refuse to perform the clean-up when the \dmmz file is missing the
- end-of-file marker (|\endinput|), assuming that this indicates a fatal error
- in the previous compilation. It will do the same in case the \dmmz file is
- absent or empty. The latter is assumed to be a result of a globally
- \refmmz{disable}d memoization, but note that clean-up will be performed if
- memoization was disabled using package \refpkg{nomemoize}: that package does not
- touch the \dmmz file, so cleaning up should work as intended.
-\end{tcolorbox}
+As we saw in section~\ref{sec:tut:memodir}, Memoize produces a lot of auxiliary
+files (memos and externs) and it keeps the old versions around! Once your
+document is prepared, you can reduce the clutter (and save some disk space) by
+deleting memos and externs belonging to the work-in-progress versions of your
+document, and keep only those used in the final version. Return to
+section~\ref{sec:tut:memodir} to remember how to deploy script
+\refscript{memoize-clean.pl} to achieve this.
As the final note, memos and externs (cleaned-up or not) may be copied (along
the document source) to another directory or machine, where they should be
-picked up by Memoize. There is no need to copy the \dmmz file (assuming that
-the document PDF contains no extern pages waiting for extraction).
+picked up by Memoize. When they are copied to another directory, one should
+clearly set \refmmz{memo dir} or \refmmz{prefix} accordingly. There is no need
+to copy the \dmmz file (assuming that the document PDF contains no extern pages
+waiting for extraction).
\section{Digging deeper}
@@ -2021,27 +1964,30 @@ What are your options in this kind of a situation?
Remember that in Memoize, externalization is a two-step process. First,
externs are typeset on separate pages of the main document, called extern
pages. Then, these extern pages are extracted out of the main document PDF
-into extern files. The process is illustrated on the title page.
+into extern files, using a program external to \hologo{TeX}. The process is
+illustrated on the title page; in this section, we learn how and when the
+extraction process can be triggered.
Memoize is flexible in terms of which piece of software is used to perform
extern extraction. It ships with three \emph{extraction methods}:
\begin{description}
\item[\refmmz{extract=perl}] A Perl script, \refscript{memoize-extract.pl}.
- This method is the default because it is fast and because Perl is usually
- already installed on a system running \hologo{TeX}. However, you will most
+ This method is the default because it is fast and because Perl is already
+ installed on many systems running \hologo{TeX}. However, you will most
likely still need to install the PDF processing library
\hreftt{https://metacpan.org/pod/PDF::API2}{PDF::API2}, or its fork
- \hreftt{https://metacpan.org/pod/PDF::Builder}{PDF::Builder}; the
- installation guidelines can be found in section~\ref{sec:install}.
+ \hreftt{https://metacpan.org/pod/PDF::Builder}{PDF::Builder}. This is as
+ easy as executing \code{cpan PDF::API2} on the command line.
\item[\refmmz{extract=python}] A Python script, \refscript{memoize-extract.py}.
This method is even faster than the Perl script, though not by much. Try it
out if you have problems installing Perl or the required libraries, or if the
Perl script chokes on your document (see section~\ref{sec:troubleshooting}
- for the list of known issues). Besides Python ($\geq 3.8$), you will also
- need the Python library \hreftt{https://pypi.org/project/pdfrw/}{pdfrw} or
- \hreftt{https://pypi.org/project/pdfrw2/}{pdfrw2}. For the installation
- guidelines, see section~\ref{sec:install}.
+ for the list of known issues). Besides \href{https://www.python.org}{Python}
+ ($\geq 3.8$), you will also need the Python library
+ \hreftt{https://pypi.org/project/pdfrw2/}{pdfrw2}, or its predecessor
+ \hreftt{https://pypi.org/project/pdfrw/}{pdfrw}. Once again, the
+ installation is a breeze: |pip install pdfrw2|.
\item[\refmmz{extract=tex}] \hologo{TeX}-based extraction requires no
additional software, but it is much slower than the scripts. As \hologo{TeX}
can only produce a single PDF per compilation, an instance of \hologo{TeX}
@@ -2059,61 +2005,123 @@ providing two \emph{extraction modes}:
document; more precisely, any externs produced in a compilation are extracted
during the next compilation. To choose an extraction method other than the
default Perl script, load Memoize with the package option
- \EmphTT{\refmmz{extract}=\meta{extraction method}}.
+ \EmphTT{\refmmz{extract}=\meta{extraction method}}, e.g.\
+ \code{\refmmz{extract}=\refmmz{extract=python}}.
-\item[external] Loading Memoize with with package option
+\item[external] Loading Memoize with package option
\EmphTT{\refmmz{extract}=\refmmz{extract=no}} instructs Memoize to \emph{not}
- trigger the (internal) extraction. When instructed to use extraction
- ``method'' \refmmz{extract=no}, Memoize expects you to trigger the extraction
- yourself, in any way that is convenient to you: manually from the command
- line, or automatically through your editor, a Makefile, etc. --- all Memoize
- cares about is that the extraction takes place before the next compilation of
- the document.
+ trigger the (internal) extraction. Now Memoize expects you to trigger the
+ extraction yourself, in any way that is convenient to you: manually from the
+ command line, or automatically through your editor, a Makefile, etc. One
+ particularly convenient option is \pkg{latexmk}, which supports Memoize
+ through the example configuration file \reffile{memoize_latexmkrc}. All
+ Memoize cares about is that the extraction takes place before the next
+ compilation of the document.
\end{description}
Summing up, the extraction mode and method are selected by providing the
-appropriate value to package option key \refmmz{extract}; the possible values
-are listed in the table below. Note that this key can only be used as a
-package option, or in \refcmd{mmzset} within \reffile{memoize.cfg}. In
-particular, it is disabled in the document preamble, because Memoize performs
-extraction while it is loaded.
-
-\medskip
-\begin{center}
- \begin{tabular}{lll}
+appropriate value to key \refmmz{extract}; the possible values are listed in
+the Table~\ref{tab:extraction-methods}. Note that unless you're using
+\hologo{plainTeX}, this key can only be used as a package option, or in
+\refcmd{mmzset} within \reffile{memoize.cfg}. In particular, it is disabled in
+the document preamble, because Memoize performs internal extraction while it is
+loaded.
+
+\begin{table}[b]
+ \centering
+ \begin{tabular}{llll}
\toprule
- extraction method&external program&Memoize invocation\\
+ extraction mode&extraction method&package option&extraction program\\
\midrule
- \refmmz{extract=perl}&\refscript{memoize-extract.pl}&\refcmd{usepackage}\braces{\refpkg{memoize}}\footnotemark\\
- \refmmz{extract=python}&\refscript{memoize-extract.py}&\refcmd{usepackage}\bracketstt{\refmmz{extract}=\refmmz{extract=python}}\braces{\refpkg{memoize}}\\
- \refmmz{extract=tex}&|pdftex|&\refcmd{usepackage}\bracketstt{\refmmz{extract}=\refmmz{extract=tex}}\braces{\refpkg{memoize}}\\
- \refmmz{extract=no}&none (external extraction)&\refcmd{usepackage}\bracketstt{\refmmz{extract}=\refmmz{extract=no}}\braces{\refpkg{memoize}}\\
+ &\refmmz{extract=perl}&\code{\refmmz{extract}=\refmmz{extract=perl}}, or none&\refscript{memoize-extract.pl}\\
+ internal &\refmmz{extract=python}&\code{\refmmz{extract}=\refmmz{extract=python}}&\refscript{memoize-extract.py}\\
+ &\refmmz{extract=tex}&\code{\refmmz{extract}=\refmmz{extract=tex}}&|pdftex|\\
+ \midrule
+ external &any&(\code{\refmmz{extract}=\refmmz{extract=no}})&any\\
\bottomrule
\end{tabular}%
- \footnotetext{Or
- \refcmd{usepackage}\bracketstt{\refmmz{extract}=\refmmz{extract=perl}}%
- \braces{\refpkg{memoize}}. This is useful if you have changed the default
- using \reffile{memoize.cfg}.}%
-\end{center}
-\smallskip
+ \caption{Extraction methods}
+ \label{tab:extraction-methods}
+\end{table}
+
+Strictly speaking, external extraction does not require
+\code{\refmmz{extract}=\refmmz{extract=no}}. If you extract externs before the
+next compilation takes place, and you do this using
+\refscript{memoize-extract.pl} or \refscript{memoize-extract.py} (without
+option \refscript{memoize-extract.pl--keep}), the extraction script will mark
+externs as extracted (by commenting out the relevant lines in the \dmmz file).
+The internal extraction, which is triggered at the beginning of the next
+compilation, will then find it has nothing to do. Writing
+\code{\refmmz{extract}=\refmmz{extract=no}} merely saves you the bit of time
+needed for the internal extraction to realize that the externs were already
+extracted.
+
+\paragraph{Internal extraction and shell escape mode}
For internal extraction, \hologo{TeX} must be allowed to execute the external
-program implementing the chosen extraction method. Both |memoize-extract|
-scripts should be listed among restricted shell escape mode commands in your
-\hologo{TeX} distribution; their execution should therefore be allowed under
-the default, restricted shell escape mode. However, the |pdftex| program,
-executed by extraction method \refmmz{extract=tex}, is not listed there, nor
-should it be. If you are forced to use this fallback method, I suggest you
-compile documents loading Memoize under the full shell escape mode, by adding
-command-line option \docref{-shell-escape} (on \hologo{TeX}Live) or
-\docref{--enable-write18} (on MiK\hologo{TeX}) to the invocation of the
-\hologo{TeX} program. The answers linked from question
-``\href{https://tex.stackexchange.com/q/598818/16819}{How can I enable
- shell-escape?}'' on \href{https://tex.stackexchange.com}{\hologo{TeX}
- StackExchange} will tell you how you can ask your editor to do this for you.
+program implementing the chosen extraction method. If you installed Memoize
+through the package manager of either \TeXLive or \MiKTeX, your system should
+be already set up to allow the execution of Memoize's extraction scripts,
+\refscript{memoize-extract.pl} and \refscript{memoize-extract.py}, so
+\code{\refmmz{extract}=\refmmz{extract=perl}} and
+\code{\refmmz{extract}=\refmmz{extract=python}} should work out of the box.
+Otherwise, you can:
+
+\begin{enumerate}[(a)]
+\item\label{item:fallback-external} perform the extraction externally
+ (\code{\refmmz{extract}=\refmmz{extract=no}}),
+\item\label{item:fallback-full} compile documents loading Memoize with
+ command-line option \docref{-shell-escape} (on \TeXLive) or
+ \docref{--enable-write18} (on \MiKTeX),\footnote{The answers linked
+ from question ``\href{https://tex.stackexchange.com/q/598818/16819}{How can
+ I enable shell-escape?}''
+ on \href{https://tex.stackexchange.com}{\hologo{TeX} StackExchange} will
+ tell you how you can ask your editor to do this for you.} or
+\item\label{item:fallback-restricted} set up the restricted shell escape mode
+ to allow for the execution of \refscript{memoize-extract.pl} and/or
+ \refscript{memoize-extract.py}.
+
+ On \TeXLive:
+ \begin{enumerate}[1.]
+ \item Execute |tlmgr conf texmf shell_escape| to learn which shell escape
+ mode is currently in effect: |p| = partial = restricted, |f| = disabled and
+ |t| = enabled.
+ \item If necessary, use |tlmgr conf texmf shell_escape p| to select the
+ restricted shell escape mode.
+ \item Execute |tlmgr conf texmf shell_escape_commands| to get the
+ \meta{current} list of allowed commands.
+ \item To add (e.g.) \refscript{memoize-extract.pl} to the list of allowed
+ commands, execute \code{tlmgr conf texmf shell\_escape\_commands
+ \meta{current},memoize-extract.pl}.
+ \end{enumerate}
+
+ On \MiKTeX:
+ \begin{enumerate}[1.]
+ \item Execute |initexmf --show-config-value=[Core]ShellCommandMode| to learn
+ which shell escape mode is currently in effect.
+ \item If necessary, use |initexmf
+ --set-config-value=[Core]ShellCommandMode=Restricted| to select the
+ restricted shell escape mode.
+ \item Execute \code{initexmf
+ --show-config-value=[Core]AllowedShellCommands[]} to get the
+ \meta{current} list of allowed commands.
+ \item To add (e.g.) \refscript{memoize-extract.pl} to the list of allowed
+ commands, execute \code{initexmf
+ --set-config-value=[Core]AllowedShellCommands[]=\meta{current};memoize-extract.pl}
+ \end{enumerate}
+\end{enumerate}
+
+The |pdftex| program, employed by extraction method \refmmz{extract=tex}, is
+normally not listed among the restricted shell escape mode commands, nor should
+it be. If you are forced to use this fallback extraction method, I suggest
+going for option~\ref{item:fallback-external} or~\ref{item:fallback-full}
+above.
+
+\paragraph{External extraction}
-You may use any extraction method to perform external extraction. The simplest
-option is to use the Perl or the Python script. Supposing you are doing this
+You may use any extraction method\slash program to perform external extraction.
+The simplest option is to use the Perl or the Python script,
+\refscript{memoize-extract.pl} or \refscript{memoize-extract.py}. To do this
manually from the command line, change into the directory containing your
document, which should contain the auxiliary \dmmz file produced by Memoize,
and execute:
@@ -2128,21 +2136,93 @@ and execute:
See sections~\ref{sec:.mmz} and \ref{sec:ref:extraction-perl-python} for
further details on the \dmmz file and the extraction scripts.
-Things are a bit more complicated if you want to use the \hologo{TeX}-based
-extraction method externally, because an instance of |pdftex| needs to be
-invoked for each extern (and these have unwieldy names and can be many in
-number), but Memoize can help you here by producing a shell script or a
-makefile, executing which will extract all the externs at once. To have Memoize
-produce a shell script, use package option
+Things are much more complicated if you want to manually invoke the
+\hologo{TeX}-based extraction method, because an instance of |pdftex| needs to
+be invoked for each extern, and these have unwieldy names and can be many in
+number. In this case, I suggest asking Memoize for help, which it can do by
+producing a shell script or a makefile, executing which will extract all the
+externs at once. To have Memoize produce a shell script, use key
\code{\refmmz{record}=\refmmz{record=sh}} (or
-\code{\refmmz{record}=\refmmz{record=bat}} on Windows); package option
+\code{\refmmz{record}=\refmmz{record=bat}} on Windows); key
\code{\refmmz{record}=\refmmz{record=makefile}} will make a makefile. By
default, these files are named |memoize-extract.|\meta{document name} plus the
-|.sh|, |.bat| or |.makefile| suffix. If neither a shell script nor a makefile
-works for you, you can also define your own kind of \emph{record file}, to be
-processed by the external tool of your choice (and implementation) in order to
-extract the externs; see section~\ref{sec:new-record-file} to learn how to do
-this.
+|.sh|, |.bat| or |.makefile| suffix.\footnote{If neither a shell script nor a
+ makefile works for you, you can also define your own kind of \emph{record
+ file}, to be processed by the external tool of your choice (and
+ implementation) in order to extract the externs; see
+ section~\ref{sec:new-record-file} to learn how to do this.}
+
+All that said, triggering the external extraction manually is probably noone's
+cup of tea. One appealing option is to use \pkg{latexmk}, which supports
+Memoize since version~4.84. All you have to do is integrate the example
+configuration file \reffile{memoize_latexmkrc}, shipped with \pkg{latexmk},
+into your |latexmkrc|. With this configuration file, |latexmk| will trigger
+extraction (using \refscript{memoize-extract.pl} or
+\refscript{memoize-extract.py}) and recompile the source when new externs are
+detected, and include the auxiliary files created by Memoize in a clean-up when
+called with option |-c|. The suggested configuration allows for the aux and
+out directory to differ, and may be safely used even with documents which do not
+load Memoize.
+
+\paragraph{The memo directory}
+
+Out of the box, Memoize stores memos and externs in a separate directory,
+\code{\meta{document name}.memo.dir}, creating this directory if it does not
+exist. This behaviour, illustrated in section~\ref{sec:tut:memodir}, is
+trigerred by key \refmmz{memo dir}, which is in effect by default since Memoize
+version~1.3.0.
+
+It is however worth noting that something rather unusual is happening behind
+the scenes here. Out of the box, \hologo{TeX} cannot create directories, so
+the fact that Memoize \emph{can} create them requires an explanation. You can
+create a directory in \hologo{TeX} only by executing an external program which
+does that. However, executing the system command |mkdir| is not allowed by
+default. This command is considered unsafe, in the sense that it does not
+respect the restrictions imposed by a \hologo{TeX} distribution setting called
+\docref{openout_any} (in \TeXLive; in \MiKTeX, it is called
+|[Core]AllowUnsafeOutputFiles|). Out of the box, \docref{openout_any} is set
+to |p| (paranoid), which ``disallow[s] opening dot files [and] going to parent
+directories, and restrict[s] absolute paths to be under \docref{TEXMFOUTPUT}.''
+Command |mkdir| violates the second clause of this restriction as it can create
+a directory anywhere on the system, and this is why |mkdir| is \emph{not} the
+initial value of setting \refmmz{mkdir command}, which specifies the system
+command used to create the memo directory.
+
+However, Memoize's extraction scripts \emph{are} considered safe in the sense
+that they respect restrictions imposed by \docref{openout_any}, so Memoize can
+circumvents the |mkdir| issue by assigning these scripts a secondary task:
+executing an extraction script with option
+\refscript{memoize-extract.pl--mkdir} turns it into a restricted |mkdir|, i.e.\
+a ``make directory'' command which respects the restrictions imposed by
+\docref{openout_any}. Accordingly, option \refmmz{mkdir command} is
+initialized to \code{\refscript{memoize-extract.pl}
+ \refscript{memoize-extract.pl--mkdir}} (and
+\code{\refmmz{extract}=\refmmz{extract=python}} reinitializes it to
+\code{\refscript{memoize-extract.pl} \refscript{memoize-extract.pl--mkdir}}).
+At the end of the day, it is thus an extraction script which actually creates
+the memo directory (in an invocation independent of the internal extraction).
+Therefore, Memoize can create the memo directory on any system which allows its
+extraction scripts to be executed from \hologo{TeX} itself. Out of the box,
+this is the case with both major distributions, \TeXLive and
+\MiKTeX.
+
+The default \refmmz{memo dir} regime can therefore fail only on a system where
+Memoize's extraction script cannot be executed. Ignoring the case of the user
+tightening the security, this can only happen when both Perl and Python,
+powering the two variants of the extraction script, are unavailable. This
+could presumably happen on Mik\hologo{TeX} on Windows, if the user can install
+neither Perl nor Python (note that this does not apply to \TeXLive, as
+\code{\refscript{memoize-extract.pl} \refscript{memoize-extract.pl--mkdir}}
+works with the built-in Perl). Of course, this situation is undesirable in and
+of itself, as it forces the author to fall back to the slower
+\hologo{TeX}-based extraction by issuing
+\code{\refmmz{extract}=\refmmz{extract=tex}}, but note that it will additionaly
+prevent the execution of the default \refmmz{mkdir command}. Possible
+workarounds include either undoing the effect of \refmmz{memo dir} by issuing
+\refmmz{no memo dir}, or changing the \refmmz{mkdir command} to a command like
+|mkdir| while allowing \emph{(do this at your own risk)} it to be executed, for
+example by compiling the document with \docref{-shell-escape}.
+
\subsection{From cross-references to the context}
@@ -5273,7 +5353,7 @@ on how to handle this properly.
This option primarily exists to allow any key--value pair accepted by
\refcmd{mmzset} to be used as a package option. In particular, this applies
- key handlers (see \PGFmanual{87}), because their invocation includes a slash
+ to key handlers (see \PGFmanual{87}), because their invocation includes a slash
(|/|). For example, one cannot directly use
\begin{center}
\code{\cs{usepackage}[\refmmz{perl extraction
@@ -6135,53 +6215,60 @@ require.
\label{sec:ref:dirs}
\begin{doc}{easy,
- key={name=memo dir,par=\meta{name}, desc={style, default \texttt{\string\jobname}}},
+ key={name=memo dir,par=\meta{name}, desc={style, default \cs{jobname}}},
}
A convenient way to store memos and externs in a dedicated directory (see
- sections~\ref{sec:tut:memodir} and~\ref{sec:tut:multifile} for the tutorial).
+ sections~\ref{sec:tut:memodir} and~\ref{sec:tut:multifile} for the tutorial
+ and an illustration of the resulting directory structure). Note that since
+ Memoize version 1.3.0, this key is initially in effect.
- Without an argument, this key places these files in subdirectory
- \meta{document name}|.memo.dir| of the current directory. With an argument,
- these files are stored in subdirectory \meta{name}|.memo.dir|. In both
- cases, memo and extern filenames contain no prefix, as \meta{name} already
- occurs in the directory name.
+ This key places memos and externs in subdirectory \meta{name}|.memo.dir| of
+ the output directory, with \meta{name} defaulting to the document name.
+ (Without an argument, these files are thus stored in subdirectory
+ \meta{document name}|.memo.dir|.) Note that memo and extern filenames are
+ set to contain no prefix; it is unnecessary, as \meta{name} already occurs in
+ the directory name.
- The definition of this style is very simple: |memo
- dir/.style={|\refmmz{prefix}|={#1.memo.dir/}}| (note the slash). Feel free
- to redefine it, or to define another style to suit your needs.
+ Under the hood, this style merely issues ||\refmmz{prefix}|={#1.memo.dir/}|
+ (note the slash).
\end{doc}
-\begin{doc}{easy,key={name=no memo dir,desc=style}}
- A convenient way to undo the effect of \refmmz{memo dir} and revert to the
- initial \refmmz{prefix} setting which locates memos and externs in the
- current directory, with filenames prefixed by \meta{document name}|.| (mind
- the dot).
+\begin{doc}{easy,key={name=no memo dir,par=\meta{name},
+ desc={style, default=\cs{jobname}}}}
+ A convenient way to undo the effect of \refmmz{memo dir}, such that memos and
+ externs are placed in the output directory, with filenames prefixed by
+ \meta{name}|.| (mind the dot), where \meta{name} defaults to the document
+ name. See section~\ref{sec:tut:memodir} for an illustration of the resulting
+ directory contents.
+
+ This style is an abbreviation for \code{\refmmz{prefix}={\meta{name}.}}.
\end{doc}
\begin{doc}{
key={name=prefix, par=\meta{prefix},
- desc={no default, initially \texttt{\string\jobname.}}},
+ desc={no default, initially \code{\cs{jobname}.memo.dir/}}},
}
This key determines the location of memo and extern files, and the initial
part of their filenames.
- If \meta{prefix} contains no |/|, memos and externs are stored in the current
+ If \meta{prefix} contains no |/|, memos and externs are stored in the output
directory, alongside the output PDF, and their filenames begin with
\meta{prefix} (and continue with the identifier, see below). For example,
- this is what happens with the initial value of this key, where memo and
- extern filenames are prefixed by \meta{jobname} (i.e.\ the name of the
- document) plus |.| (a dot). Such a situation is shown in the |dirty-house|
- example in section~\ref{sec:tut:memodir}.
+ \refmmz{no memo dir} (without an argument) sets \refmmz{prefix} to
+ \code{\cs{jobname}.}, i.e.\ the name of the document plus |.| (a dot). The
+ resulting situation is depicted in the |dirty-house| example in
+ section~\ref{sec:tut:memodir}.
If \meta{prefix} contains slashes, everything up to the final slash
determines the directory which memos and externs will be stored into, and the
part after the final slash determines the starting part of their filenames; a
slash (|/|) as a directory separator should be used even on Windows, where
the system directory separator is a backslash (|\|). For example,
- \refmmz{memo dir} sets \refmmz{prefix} to |\jobname.memo.dir/|. As shown in
- the |clean-house| example in section~\ref{sec:tut:memodir}, this results in
- memos and externs stored in directory \meta{jobname}|.memo.dir|, with their
- filenames consisting solely of the identifier.
+ \refmmz{memo dir} (without an argument) sets \refmmz{prefix} to
+ |\jobname.memo.dir/|. As shown in the |clean-house| example in
+ section~\ref{sec:tut:memodir}, this results in memos and externs stored in
+ directory \meta{jobname}|.memo.dir|, with their filenames consisting solely
+ of the identifier.
In detail, the paths to memos and externs are constructed as shown below,
where \meta{code md5 sum} and \meta{context md5 sum} identify the memoized
@@ -6208,22 +6295,25 @@ require.
\begin{tcolorbox}[warning,title=The final slash matters]
To reiterate, the presence vs.\ absence of a slash (|/|) determines whether
memos and externs are stored in a dedicated directory or not. For example,
- if you want to store memos and externs in directory |memos|, you should set
- \code{\refmmz{prefix}=memos/}, with the final slash. Without the final
- slash, these files would end up in the current directory.
+ if you want to store memos and externs in subdirectory |memos| of the
+ output directory, you should set \code{\refmmz{prefix}=memos/}, with the
+ final slash. Without the final slash, these files would end up in the
+ output directory.
\end{tcolorbox}
In principle, the directory specified by this key must already exist.
However, Memoize does it best to create it for you, and should succeed at
- least when extraction method is set to \refmmz{extract=perl} or
- \refmmz{extract=python}. See also \refmmz{mkdir} and \refmmz{mkdir command}.
+ least when extraction method \refmmz{extract=perl} or \refmmz{extract=python}
+ can be used on the system. See also \refmmz{mkdir} and \refmmz{mkdir
+ command}.
When invoked from the document body, each invocation of this key records the
- new prefix by invoking \refmmz{record/record type/prefix} (this typically
- results in a \refcmd{mmzPrefix} entry in the \dmmz file) and attempts to
- create memo directory if \refmmz{mkdir} is in effect. When \refmmz{prefix}
- is executed in the document preamble, these actions are only carried out at
- the beginning of the document, for the final value of the key.
+ new prefix by invoking \refmmz[show keypath]{record/record type/prefix} for
+ each active \meta{record type} (this typically results in a
+ \refcmd{mmzPrefix} entry in the \dmmz file) and attempts to create memo
+ directory if \refmmz{mkdir} is in effect. When \refmmz{prefix} is executed
+ in the document preamble, these actions are only carried out at the beginning
+ of the document, for the final value of the key.
\end{doc}
@@ -6240,7 +6330,7 @@ require.
\begin{doc}{
key={name=mkdir command, par=\meta{system command},
- desc={no default, initially empty}},
+ desc={no default, initially \code{\refscript{memoize-extract.pl} \refscript{memoize-extract.pl--mkdir}}}},
}
This key sets the command used to create the memo directory specified
by \refmmz{prefix} when \refmmz{mkdir} is in effect.
@@ -6254,22 +6344,27 @@ require.
This key could be set to |mkdir| (on Linux, |mkdir -p| would be an even
better choice), however, this is not advisable as |mkdir| does not respect
\hologo{TeX}'s output restrictions, set by \docref{openout_any} in
- \hologo{TeX}Live and |[Core]AllowUnsafeInputFiles| in MiK\hologo{TeX}.
+ \TeXLive and |[Core]AllowUnsafeOutputFiles| in \MiKTeX.
Further note that as the value of this key is a system command, an
appropriate shell escape mode must be in effect to execute it successfully;
again, not something to be taken lightly.
- The extractions scripts shipped with Memoize accept option
+ The extraction scripts shipped with Memoize accept option
\refscript{memoize-extract.pl--mkdir}, which makes them behave as a safe
variant of |mkdir|, i.e.\ a |mkdir| which respects \hologo{TeX}'s output
- restrictions. Therefore, extraction methods \refmmz{extract=perl} and
- \refmmz{extract=python} set \refmmz{mkdir command} to
- \refscript{memoize-extract.pl} \refscript{memoize-extract.pl--mkdir} and
- \refscript{memoize-extract.py} \refscript{memoize-extract.pl--mkdir},
- respectively. In effect, as the initial extraction method is
- \refmmz{extract=perl}, the memo directory (if set via \refmmz{prefix} or
- \refmmz{memo dir}) should be created under the initial settings without any
- user intervention.
+ restrictions. As most \hologo{TeX} setups will have access to at least a
+ rudimentary Perl installation required to successfully execute
+ \code{\refscript{memoize-extract.pl} \refscript{memoize-extract.pl--mkdir}},
+ this command is the default value of \refmmz{mkdir command}. Therefore, in
+ most cases, the memo directory (if set via \refmmz{prefix} or \refmmz{memo
+ dir}) should be created under the initial settings without any user
+ intervention.
+
+ Invoking \code{\refmmz{extract}=\refmmz{extract=python}} changes the value of
+ \refmmz{mkdir command} to \code{\refscript{memoize-extract.py}
+ \refscript{memoize-extract.pl--mkdir}}, but only if \refmmz{mkdir command}
+ is currently set to the initial value, i.e.\ it will not effect the change if
+ the user adjusted \refmmz{mkdir command} manually.
\end{doc}
@@ -6329,11 +6424,11 @@ require.
(with \refmmz{extract}|=|\refmmz{extract=no}), and trigger the internal
extraction manually.
- Executing extraction method \refmmz{extract=perl} or \refmmz{extract=python}
- has an additional effect of setting the \refmmz{mkdir command} to the
- extraction script with option \refscript{memoize-extract.pl--mkdir}. This
- obviates the need to include |mkdir| among the restricted shell commands if
- one is using the restricted shell mode.
+ Executing extraction method \refmmz{extract=python} has an additional effect
+ of setting \refmmz{mkdir command} to \code{\refscript{memoize-extract.pl}
+ \refscript{memoize-extract.pl--mkdir}}, but only if \refmmz{mkdir command}
+ is currently set to the initial value, i.e.\ it will not effect the change if
+ the user adjusted \refmmz{mkdir command} manually.
\end{doc}
\subsubsection{Perl- and Python-based extraction}
@@ -6394,10 +6489,10 @@ Perl- and Python-based extraction is triggered by
\refmmz{extract}|=|\refmmz{extract=python}.
Argument \meta{name}\dmmz may be given either in full (e.g.\ |doc.mmz|), or
- merely as the stem (|doc|). In the latter case, |.mmz| is appended to the
+ merely as the stem (|doc|). In the latter case, \dmmz is appended to the
given argument even if it already contains a suffix (e.g.\ |my.doc| will
result in |my.doc.mmz|); the exception is suffix |.tex|, which is replaced by
- |.mmz|.
+ \dmmz.
The script inspects the given record file, \meta{name}\dmmz, for lines of
form \refcmd{mmzNewExtern}\marg{extern filename}\marg{extern page
@@ -6505,7 +6600,7 @@ Perl- and Python-based extraction is triggered by
option={name=mkdir, short name=m}
}
When given this option, the extraction script transforms into a paranoid
- |mkdir| (|-p|). Argument \meta{name}|.mmz| is interpreted as a path to the
+ |mkdir| (|-p|). Argument \meta{name}\dmmz is interpreted as a path to the
directory to create; all other options are ignored.
The ancestors of the directory are created as needed. The script will
@@ -6517,9 +6612,9 @@ Perl- and Python-based extraction is triggered by
not have to list |mkdir| among the restricted shell mode commands (and it
is also safer than a plain |mkdir|).
- Memoize automatically uses this script to create the memo directory when
- option \refmmz{extract} is given value \refmmz{extract=perl} or
- \refmmz{extract=python}.
+ Initially, \refmmz{mkdir command} is set to
+ \code{\refscript{memoize-extract.pl}
+ \refscript{memoize-extract.pl--mkdir}}.
\end{doc}
\begin{doc}{
option={name=version, short name=V}
@@ -7974,7 +8069,7 @@ be generalized to \meta{namespace} and \meta{setup key} of
\refenv{forest}&\refmmzauto{memoize}\\
\refcmd{Forest}&\refmmzauto{memoize}\\
\refcmd{index}&\refmmzauto{replicate}&The argument is expanded prior to replication.\\
- \refcmd{label}&custom&\refmmzauto{run if memoizing}; globally appends
+ \refcmd{label}&custom&\refmmzauto{run if memoizing}; the handler globally appends
\refcmd{mmzLabel}\marg{label key}\marg{current label}
to register \refcmd{mmzCCMemo}.\\
\refcmd{pageref}&\refmmzauto{ref}\\
@@ -8442,7 +8537,7 @@ be generalized to \meta{namespace} and \meta{setup key} of
The \meta{options} are a comma-separated list of \meta{key}|=|\meta{value}
pairs. They are processed using the \pkg{pgfkeys} utility of PGF/\TikZ (see
- \PGFmanual{87}), with the default path set to \docaux{key path}{collargs}.
+ \PGFmanual{87}), with the default path set to \refkeypath{/collargs}.
This key may be used either outside an invocation of
\refcmd{CollectArguments}\slash \refcmd{CollectArgumentsRaw}, to set defaults
@@ -8458,11 +8553,12 @@ be generalized to \meta{namespace} and \meta{setup key} of
Define \meta{symbol} as an abbreviation of \marg{definition} within the
\meta{argument specification} passed to \refcmd{CollectArguments}.
- For example, Memoize's \pkg{biblatex} support sets
+ For example, Memoize's \pkg{biblatex} support allows the user to mark the
+ citation key argument simply by preceding it by a star (|*|) by setting
\code{\refcollargs{alias}=%
\braces{*}\braces{\&\&\braces{\cs{mmz@biblatex@mark@citation@key}}}}, with
\cs{mmz@biblatex@mark@citation@key} an internal macro which stores the
- contents of \refcmd{collargsArg} into another internal macro.
+ contents of register \refcmd{collargsArg} into another internal macro.
\end{doc}
\begin{doc}[
@@ -8695,10 +8791,10 @@ grab the environment body in the verbatim mode.)
\nohyphen``\cs{the}\refcmd{collargsArg}''}. Or, to trim spaces from an
argument using |\trim@spaces@noexp| from package \pkg{trimspaces}:
\code{\refcollargs{append expandable preprocessor}=%
- \cs{expandafter}\cs{trim@spaces@noexp}\cs{expandafter}\braces{%
- \cs{the}\refcmd{collargsArg}}}. A pre-processor is the right choice in
- both these cases because we want to modify the argument before it is dressed
- up in the original delimiters.
+ \cs{expandafter}\nohyphen\cs{trim@spaces@noexp}\nohyphen\cs{expandafter}%
+ \nohyphen\braces{\cs{the}\refcmd{collargsArg}}}. A pre-processor is the
+ right choice in both these cases because we want to modify the argument
+ before it is dressed up in the original delimiters.
Let us consider another, more involved example. As the example for
\refcollargs{append preprocessor} above, it is inspired by \pkg{cprotect},
@@ -9086,9 +9182,10 @@ as follows: \docref{xparse:o}, \docref{xparse:d}, \docref{xparse:s},
\subsubsection{PGF}
-When package \PGF is loaded, commands \refcmd{mmzPgfAtBeginMemoization}
-and \refcmd{mmzPgfAtEndMemoization} are defined and appended to hooks
-\refmmz{at begin memoization} and \refmmz{at end memoization}, respectively.
+\PGF support defines commands \refcmd{mmzPgfAtBeginMemoization} and
+\refcmd{mmzPgfAtEndMemoization}, and appends them to hooks \refmmz{at begin
+ memoization} and \refmmz{at end memoization}, respectively. This happens
+automatically whenever \PGF is loaded.
Note that environment \env{pgfpicture} is \emph{not} submitted to
automemoization. Doing this would probably not be a good idea, as it is used
@@ -9164,8 +9261,13 @@ specifying option \refmmzauto{args} unnecessary.
\subsubsection{Beamer}
-Memoize should be loaded by writing |\RequirePackage{memoize}| (rather than
-|\usepackage{memoize}|) before (rather than after) |\documentclass{beamer}|.
+In the Beamer class, Memoize cannot be loaded in the standard way, by writing
+|\usepackage{memoize}| in the preamble, \emph{when performing internal
+ extraction} (the external extraction does not pose a problem). This is the
+case because Beamer opens the document PDF while loading the class, while
+Memoize requires the PDF from the previous compilation intact in order to
+extract the externs. The workaround is to load Memoize by writing
+|\RequirePackage{memoize}| \emph{before} |\documentclass{beamer}|.
\begin{doc}{easy, key={name=per overlay,desc=style}}
Applying this style to a piece of memoized code contained in a Beamer
@@ -9189,29 +9291,30 @@ Memoize should be loaded by writing |\RequirePackage{memoize}| (rather than
\meta{additional configuration} is executed within \refcmd{mmzset}.
When \pkg{biblatex} support is loaded, all citation commands defined by this
- package\footnote{In \pkg{biblatex} version 3.19: \cs{cite}, \cs{Cite},
- \cs{parencite}, \cs{Parencite}, \cs{footcite}, \cs{footcitetext},
- \cs{textcite}, \cs{Textcite}, \cs{smartcite}, \cs{Smartcite},
- \cs{supercite}, \cs{cites}, \cs{Cites}, \cs{parencites}, \cs{Parencites},
- \cs{footcites}, \cs{footcitetexts}, \cs{smartcites}, \cs{Smartcites},
- \cs{textcites}, \cs{Textcites}, \cs{supercites}, \cs{autocite},
- \cs{Autocite}, \cs{autocites}, \cs{Autocites}, \cs{citeauthor},
- \cs{Citeauthor}, \cs{citetitle}, \cs{citeyear}, \cs{citedate},
- \cs{citeurl}, \cs{nocite}, \cs{fullcite}, \cs{footfullcite}, \cs{volcite},
- \cs{Volcite}, \cs{volcites}, \cs{Volcites}, \cs{pvolcite}, \cs{Pvolcite},
- \cs{pvolcites}, \cs{Pvolcites}, \cs{fvolcite}, \cs{Fvolcite},
- \cs{fvolcites}, \cs{Fvolcites}, \cs{ftvolcite}, \cs{ftvolcites},
- \cs{Ftvolcite}, \cs{Ftvolcites}, \cs{svolcite}, \cs{Svolcite},
- \cs{svolcites}, \cs{Svolcites}, \cs{tvolcite}, \cs{Tvolcite},
- \cs{tvolcites}, \cs{Tvolcites}, \cs{avolcite}, \cs{Avolcite},
- \cs{avolcites}, \cs{Avolcites}, \cs{notecite}, \cs{Notecite},
- \cs{pnotecite}, \cs{Pnotecite}, \cs{fnotecite}, \cs{citename},
- \cs{citelist}, \cs{citefield}.} behave like \refcmd{ref} in the sense that
- changing a bibliography entry referred to by a citation command within a
- piece of memoized code triggers recompilation of that code. For example, it
- is safe to use \code{\cs{textcite}\braces{\meta{citation key}}} inside
- memoized code, in the sense that the extern will be recompiled when the entry
- for the \meta{citation key} is changed in the |.bib| file.
+ package\footnote{\hbadness 3000 In \pkg{biblatex} version 3.19: \cs{cite},
+ \cs{Cite}, \cs{parencite}, \cs{Parencite}, \cs{footcite},
+ \cs{footcitetext}, \cs{textcite}, \cs{Textcite}, \cs{smartcite},
+ \cs{Smartcite}, \cs{supercite}, \cs{cites}, \cs{Cites}, \cs{parencites},
+ \cs{Parencites}, \cs{footcites}, \cs{footcitetexts}, \cs{smartcites},
+ \cs{Smartcites}, \cs{textcites}, \cs{Textcites}, \cs{supercites},
+ \cs{autocite}, \cs{Autocite}, \cs{autocites}, \cs{Autocites},
+ \cs{citeauthor}, \cs{Citeauthor}, \cs{citetitle}, \cs{citeyear},
+ \cs{citedate}, \cs{citeurl}, \cs{nocite}, \cs{fullcite}, \cs{footfullcite},
+ \cs{volcite}, \cs{Volcite}, \cs{volcites}, \cs{Volcites}, \cs{pvolcite},
+ \cs{Pvolcite}, \cs{pvolcites}, \cs{Pvolcites}, \cs{fvolcite},
+ \cs{Fvolcite}, \cs{fvolcites}, \cs{Fvolcites}, \cs{ftvolcite},
+ \cs{ftvolcites}, \cs{Ftvolcite}, \cs{Ftvolcites}, \cs{svolcite},
+ \cs{Svolcite}, \cs{svolcites}, \cs{Svolcites}, \cs{tvolcite},
+ \cs{Tvolcite}, \cs{tvolcites}, \cs{Tvolcites}, \cs{avolcite},
+ \cs{Avolcite}, \cs{avolcites}, \cs{Avolcites}, \cs{notecite},
+ \cs{Notecite}, \cs{pnotecite}, \cs{Pnotecite}, \cs{fnotecite},
+ \cs{citename}, \cs{citelist}, \cs{citefield}.} behave like \refcmd{ref} in
+ the sense that changing a bibliography entry referred to by a citation
+ command within a piece of memoized code triggers recompilation of that code.
+ For example, it is safe to use \code{\cs{textcite}\braces{\meta{citation
+ key}}} inside memoized code, in the sense that the extern will be
+ recompiled when the entry for the \meta{citation key} is changed in the
+ |.bib| file.
Furthermore, Memoize takes care that even once an extern which contains a
reference to \meta{citation key} is utilized (i.e.\ included into the
@@ -9476,15 +9579,15 @@ Errors:
{\meta{mode}})"}
Your \hologo{TeX} distribution does not allow this file to be written to.
- The relevant setting is called \docref{openin_any} in \hologo{TeX}Live and
- |[Core]AllowUnsafeOutputFiles| in MiK\hologo{TeX}.
+ The relevant setting is called \docref{openout_any} in \TeXLive and
+ |[Core]AllowUnsafeOutputFiles| in \MiKTeX.
\item \code{Error: I'm not allowed to read from '{\meta{filename}}' (openin\_any
= {\meta{mode}})"}
Your \hologo{TeX} distribution does not allow this file to be read from. The
- relevant setting is called \docref{openout_any} in \hologo{TeX}Live and
- |[Core]AllowUnsafeInputFiles| in MiK\hologo{TeX}.
+ relevant setting is called \docref{openin_any} in \TeXLive and
+ |[Core]AllowUnsafeInputFiles| in \MiKTeX.
\item \code{Error: "Semi-absolute" paths are disallowed: '\meta{filename}'}
@@ -9531,15 +9634,13 @@ Errors:
\begin{itemize}
\item Is the shell escape configured properly? It should be, as both
Memoize's extraction scripts are listed among restricted shell escape
- commands in both \hologo{TeX}Live and MiK\hologo{TeX}, but it never hurts
+ commands in both \TeXLive and \MiKTeX, but it never hurts
to check.
The easiest way to see if shell escape is the culprit is to compile the
- document with command option \docref{-shell-escape} (on \hologo{TeX}Live)
- or \docref{--enable-write18} (on MiK\hologo{TeX}). If this resolves the
- problem, check your shell escape mode; see
- footnote~\ref{fn:shell-escape-commands} on
- page~\pageref{fn:shell-escape-commands} for how to do this.
+ document with command option \docref{-shell-escape} (on \TeXLive) or
+ \docref{--enable-write18} (on \MiKTeX); see section~\ref{sec:extraction}
+ for details.
\item Is environment variable PATH set correctly, so that the system can find
the extraction script?
\item Is Perl\slash Python installed on your system, and accessible to
@@ -9714,15 +9815,15 @@ But there were others as well. Shunsaku Hirata of the \hologo{XeTeX} team
promptly resolved an issue with forward references in |xdvipdfmx|, and thereby
made Memoize work with \hologo{XeTeX}. Joseph Wright kindly didn't object to
me misappropriating \pkg{etoolbox} for other formats. Petra Rübe-Pugliese
-(CTAN) and Karl Berry (\hologo{TeX}Live) offered good advice on packaging the
-package; I would never get to call Advice Advice without their advice. Karl
-also performed a security review of the extraction scripts, providing some very
+(CTAN) and Karl Berry (\TeXLive) offered good advice on packaging the package;
+I would never get to call Advice Advice without their advice. Karl also
+performed a security review of the extraction scripts, providing some very
useful comments along the way, and agreed to include the scripts among the
-shell escape commands allowed in \hologo{TeX}Live. Christian Schenk worked
-hard to support Memoize in MiK\hologo{TeX}. After the package was first
-published, amonakov, mbert, Qrrbrbirlbel, and Ulrike Fischer provided valuable
-feedback, suggestions and\slash or bug reports; cfr did all that, and also
-advertised the package extensively.
+shell escape commands allowed in \TeXLive. Christian Schenk worked hard to
+support Memoize in \MiKTeX, and John Collins implemented \pkg{latexmk} support.
+After the package was first published, amonakov, mbert, Qrrbrbirlbel, and
+Ulrike Fischer provided valuable feedback, suggestions and\slash or bug
+reports; cfr did all that, and also advertised the package extensively.
Thank you all!
diff --git a/macros/generic/memoize/doc/memoize-extract.1.md b/macros/generic/memoize/doc/memoize-extract.1.md
index e670476441..190d6efb9a 100644
--- a/macros/generic/memoize/doc/memoize-extract.1.md
+++ b/macros/generic/memoize/doc/memoize-extract.1.md
@@ -2,8 +2,8 @@
title: memoize-extract
section: 1
header: User Manual
-footer: memoize-extract of Memoize v1.2.0
-date: March 15, 2024
+footer: memoize-extract of Memoize v1.3.0
+date: April 02, 2024
hyphenate: false
---
diff --git a/macros/generic/memoize/memoize-clean.pl b/macros/generic/memoize/memoize-clean.pl
index 4901a98aa3..b2d9c90c4a 100755
--- a/macros/generic/memoize/memoize-clean.pl
+++ b/macros/generic/memoize/memoize-clean.pl
@@ -19,7 +19,7 @@
# <texmf>/doc/generic/memoize/FILES.
my $PROG = 'memoize-clean.pl';
-my $VERSION = '2024/03/15 v1.2.0';
+my $VERSION = '2024/04/02 v1.3.0';
use strict;
use Getopt::Long;
@@ -53,7 +53,7 @@ GetOptions(
"yes|y" => \$yes,
"all|a" => \$all,
"prefix|p=s" => \@prefixes,
- "quiet|q|?" => \$quiet,
+ "quiet|q" => \$quiet,
"help|h|?" => \$help,
"version|V" => \$print_version,
) or die $usage;
diff --git a/macros/generic/memoize/memoize-clean.py b/macros/generic/memoize/memoize-clean.py
index 3b70d63a31..74b8d9b57a 100755
--- a/macros/generic/memoize/memoize-clean.py
+++ b/macros/generic/memoize/memoize-clean.py
@@ -18,7 +18,7 @@
# The files belonging to this work and covered by LPPL are listed in
# <texmf>/doc/generic/memoize/FILES.
-__version__ = '2024/03/15 v1.2.0'
+__version__ = '2024/04/02 v1.3.0'
import argparse, re, sys, pathlib, os
diff --git a/macros/generic/memoize/memoize-extract.pl b/macros/generic/memoize/memoize-extract.pl
index d5cd1f9aa4..0f2cfa3a22 100755
--- a/macros/generic/memoize/memoize-extract.pl
+++ b/macros/generic/memoize/memoize-extract.pl
@@ -19,7 +19,7 @@
# <texmf>/doc/generic/memoize/FILES.
my $PROG = 'memoize-extract.pl';
-my $VERSION = '2024/03/15 v1.2.0';
+my $VERSION = '2024/04/02 v1.3.0';
use strict;
use File::Basename qw/basename/;
@@ -86,6 +86,7 @@ sub error {
print(STDOUT "$_\n");
}
if ($log) {
+ $short =~ s/\\/\\string\\/g;
$long =~ s/\\/\\string\\/g;
$_ = $ERROR{$format};
s/\$short/$short/;
@@ -98,12 +99,6 @@ sub error {
sub warning {
my $text = shift;
- if ($log) {
- $_ = $WARNING{$format};
- s/\$texindent/$texindent/;
- s/\$text/$text/;
- print(LOG "$_\n");
- }
if (! $quiet) {
$_ = $WARNING{''};
s/\$header/$header/;
@@ -111,6 +106,13 @@ sub warning {
s/\$text/$text/;
print(STDOUT "$_\n");
}
+ if ($log) {
+ $_ = $WARNING{$format};
+ $text =~ s/\\/\\string\\/g;
+ s/\$texindent/$texindent/;
+ s/\$text/$text/;
+ print(LOG "$_\n");
+ }
$exit_code = 10;
}
@@ -124,6 +126,7 @@ sub info {
print(STDOUT "$_\n");
if ($log) {
$_ = $INFO{$format};
+ $text =~ s/\\/\\string\\/g;
s/\$texindent/$texindent/;
s/\$text/$text/;
print(LOG "$_\n");
diff --git a/macros/generic/memoize/memoize-extract.py b/macros/generic/memoize/memoize-extract.py
index 962f6380e8..e1fcbe5ad3 100755
--- a/macros/generic/memoize/memoize-extract.py
+++ b/macros/generic/memoize/memoize-extract.py
@@ -18,7 +18,7 @@
# The files belonging to this work and covered by LPPL are listed in
# <texmf>/doc/generic/memoize/FILES.
-__version__ = '2024/03/15 v1.2.0'
+__version__ = '2024/04/02 v1.3.0'
import argparse, re, sys, os, subprocess, itertools, traceback, platform
from pathlib import Path, PurePath
@@ -72,6 +72,7 @@ def error(short, long):
if not args.quiet:
print(ERROR[None].format(short = short, long = long, header = header))
if log:
+ short = short.replace('\\', '\\string\\')
long = long.replace('\\', '\\string\\')
print(
ERROR[args.format].format(
@@ -82,13 +83,14 @@ def error(short, long):
endinput()
def warning(text):
+ if text and not args.quiet:
+ print(WARNING[None].format(text = text, header = header, indent = indent))
if log:
+ text = text.replace('\\', '\\string\\')
print(
WARNING[args.format].format(
text = text, texindent = texindent, package_name = package_name),
file = log)
- if not args.quiet:
- print(WARNING[None].format(text = text, header = header, indent = indent))
global exit_code
exit_code = 10
@@ -96,6 +98,7 @@ def info(text):
if text and not args.quiet:
print(INFO[None].format(text = text, header = header, indent = indent))
if log:
+ text = text.replace('\\', '\\string\\')
print(
INFO[args.format].format(
text = text, texindent = texindent, package_name = package_name),
@@ -424,7 +427,7 @@ if __name__ == '__main__':
info(f"Extracting new externs listed in '{mmz_file}' from '{pdf_file}'")
done_message = "Done (there was nothing to extract)"
indent = ' '
- texindent = '\space\space '
+ texindent = r'\space\space '
# \paragraph{Process \texttt{.mmz}}
@@ -482,12 +485,12 @@ if __name__ == '__main__':
except pdfrw.errors.PdfParseError as err:
error(rf"File '{pdf_file}' seems corrupted. Perhaps you "
rf"have to load Memoize earlier in the preamble",
- f"In particular, Memoize must be loaded before "
- f"TikZ library 'fadings' and any package "
- f"deploying it, and in Beamer, load Memoize "
- f"by writing \RequirePackage{{memoize}} before "
- f"\documentclass{{beamer}}. "
- f"This was the error thrown by Python: \n{err}")
+ rf"In particular, Memoize must be loaded before "
+ rf"TikZ library 'fadings' and any package "
+ rf"deploying it, and in Beamer, load Memoize "
+ rf"by writing \RequirePackage{{memoize}} before "
+ rf"\documentclass{{beamer}}. "
+ rf"This was the error thrown by Python: \n{err}")
# Does the page exist?
if page_n >= len(pdf.pages):
error(rf"I cannot extract page {page_n} from '{pdf_file}', "
diff --git a/macros/generic/memoize/memoize.edtx b/macros/generic/memoize/memoize.edtx
index e77be9a39f..d974aff72a 100644
--- a/macros/generic/memoize/memoize.edtx
+++ b/macros/generic/memoize/memoize.edtx
@@ -90,55 +90,55 @@
%
% \paragraph{Identification} of |memoize|, |memoizable| and |nomemoize|.
%<*mmz>
-%<latex>\ProvidesPackage{memoize}[2024/03/15 v1.2.0 Fast and flexible externalization]
+%<latex>\ProvidesPackage{memoize}[2024/04/02 v1.3.0 Fast and flexible externalization]
%<context>%D \module[
%<context>%D file=t-memoize.tex,
-%<context>%D version=1.2.0,
+%<context>%D version=1.3.0,
%<context>%D title=Memoize,
%<context>%D subtitle=Fast and flexible externalization,
%<context>%D author=Saso Zivanovic,
-%<context>%D date=2024-03-15,
+%<context>%D date=2024-04-02,
%<context>%D copyright=Saso Zivanovic,
%<context>%D license=LPPL,
%<context>%D ]
%<context>\writestatus{loading}{ConTeXt User Module / memoize}
%<context>\unprotect
%<context>\startmodule[memoize]
-%<plain>% Package memoize 2024/03/15 v1.2.0
+%<plain>% Package memoize 2024/04/02 v1.3.0
%</mmz>
%<*mmzable>
-%<latex>\ProvidesPackage{memoizable}[2024/03/15 v1.2.0 A programmer's stub for Memoize]
+%<latex>\ProvidesPackage{memoizable}[2024/04/02 v1.3.0 A programmer's stub for Memoize]
%<context>%D \module[
%<context>%D file=t-memoizable.tex,
-%<context>%D version=1.2.0,
+%<context>%D version=1.3.0,
%<context>%D title=Memoizable,
%<context>%D subtitle=A programmer's stub for Memoize,
%<context>%D author=Saso Zivanovic,
-%<context>%D date=2024-03-15,
+%<context>%D date=2024-04-02,
%<context>%D copyright=Saso Zivanovic,
%<context>%D license=LPPL,
%<context>%D ]
%<context>\writestatus{loading}{ConTeXt User Module / memoizable}
%<context>\unprotect
%<context>\startmodule[memoizable]
-%<plain>% Package memoizable 2024/03/15 v1.2.0
+%<plain>% Package memoizable 2024/04/02 v1.3.0
%</mmzable>
%<*nommz>
-%<latex>\ProvidesPackage{nomemoize}[2024/03/15 v1.2.0 A no-op stub for Memoize]
+%<latex>\ProvidesPackage{nomemoize}[2024/04/02 v1.3.0 A no-op stub for Memoize]
%<context>%D \module[
%<context>%D file=t-nomemoize.tex,
-%<context>%D version=1.2.0,
+%<context>%D version=1.3.0,
%<context>%D title=Memoize,
%<context>%D subtitle=A no-op stub for Memoize,
%<context>%D author=Saso Zivanovic,
-%<context>%D date=2024-03-15,
+%<context>%D date=2024-04-02,
%<context>%D copyright=Saso Zivanovic,
%<context>%D license=LPPL,
%<context>%D ]
%<context>\writestatus{loading}{ConTeXt User Module / nomemoize}
%<context>\unprotect
%<context>\startmodule[nomemoize]
-%<mmz>% Package nomemoize 2024/03/15 v1.2.0
+%<mmz>% Package nomemoize 2024/04/02 v1.3.0
%</nommz>
%
% \paragraph{Required packages} and \hologo{LaTeX}ization of \hologo{plainTeX}
@@ -457,16 +457,10 @@
recompile/.code={\let\mmz@mode\mmz@mode@recompile},
}
% \end{key}
-%
% \begin{key}{prefix}
-% Key |path| executes the given keylist in path |/mmz/path|, to determine the
-% full \emph{path prefix} to memo and extern files
-% (\MS\ref{sec:tut:memodir},\ref{sec:memos}): |relative|, true by default,
-% determines whether the location of these files is relative to the current
-% directory; |dir| sets their directory; and |prefix| sets the first, fixed
-% part of their basename; the second part containing the MD5 sum(s) is not
-% under user control, and neither is the suffix. These subkeys will be
-% initialized a bit later, via |no memo dir|.
+% Key |prefix| determines the location of memo and extern files
+% (|\mmz@prefix@dir|) and the first, fixed part of their basename
+% (|\mmz@prefix@name|).
\mmzset{%
prefix/.code={\mmz@parse@prefix{#1}},
}
@@ -474,7 +468,7 @@
% This macro stores the detokenized expansion of |#1| into |\mmz@prefix|,
% which it then splits into |\mmz@prefix@dir| and |\mmz@prefix@name| at the
% final |/|. The slash goes into |\mmz@prefix@dir|. If there is no slash,
-% |\mmz@prefix@dir| is empty.
+% |\mmz@prefix@dir| is empty; in particular, it is empty under |no memo dir|.
\begingroup
\catcode`\/=12
\gdef\mmz@parse@prefix#1{%
@@ -514,14 +508,18 @@
%
% \begin{key}{mkdir, mkdir command}
% Should we create the memo/extern directory if it doesn't exist? And which
-% command should we use to create it? There is no initial value for the
-% latter, because |mkdir| cannot be executed out of the box, but note that
-% |extract=perl| and |extract=python| will set the extraction script with
-% option |--mkdir| as the value of |mkdir command|.
+% command should we use to create it? Initially, we attempt to create this
+% directory, and we attempt to do this via |memoize-extract.pl --mkdir|. The
+% roundabout way of setting the initial value of |mkdir command| allows
+% |extract=python| to change the initial value to |memoize-extract.py
+% --mkdir| only in the case the user did not modify it.
+\def\mmz@initial@mkdir@command{\mmzvalueof{perl extraction command} --mkdir}
\mmzset{
+ % This conditional is perhaps a useless leftover from the early versions, but
+ % we let it be.
mkdir/.is if=mmz@mkdir,
mkdir command/.store in=\mmz@mkdir@command,
- mkdir command={},
+ mkdir command/.expand once=\mmz@initial@mkdir@command,
}
% The underlying conditional \cs{ifmmz@mkdir} is only ever used in
% |\mmz@maybe@mkmemodir| below, which is itself only executed at the end of
@@ -530,7 +528,8 @@
\mmz@mkdirtrue
% We only attempt to create the memo directory if |\ifmmz@mkdir| is in effect
% and if both |\mmz@mkdir@command| and |\mmz@prefix@dir| are specified (i.e.\
-% non-empty).
+% non-empty). In particular, no attempt to create it will be made when |no
+% memo dir| is in effect.
\def\mmz@maybe@mkmemodir{%
\ifmmz@mkdir
\ifdefempty\mmz@mkdir@command{}{%
@@ -544,18 +543,17 @@
% \end{key}
%
% \begin{key}{memo dir, no memo dir}
-% Shortcuts for two common settings of |path| keys. The default |no memo
-% dir| will place the memos and externs in the current directory, prefixed
-% with |#1.|, where |#1| defaults to (unquoted) |\jobname|. Key |memo dir|
+% Shortcuts for two handy settings of |prefix|. Key |no memo dir| will
+% place the memos and externs in the current directory, prefixed with |#1.|,
+% where |#1| defaults to (unquoted) |\jobname|. The default |memo dir|
% places the memos and externs in a dedicated directory, |#1.memo.dir|; the
-% filenames themselves have no prefix. Furthermore, |memo dir| triggers the
-% creation of the directory.
+% filenames themselves have no prefix.
\mmzset{%
memo dir/.style={prefix={#1.memo.dir/}},
memo dir/.default=\jobname,
no memo dir/.style={prefix={#1.}},
no memo dir/.default=\jobname,
- no memo dir,
+ memo dir,
}
% \end{key}
%
@@ -2376,7 +2374,6 @@
\mmzvalueof{perl extraction options}%
}%
\mmz@check@extraction@log{perl}%
- \def\mmz@mkdir@command{\mmzvalueof{perl extraction command} --mkdir}%
},
perl extraction command/.initial=memoize-extract.pl,
perl extraction options/.initial={\space
@@ -2393,7 +2390,11 @@
\mmzvalueof{python extraction options}%
}%
\mmz@check@extraction@log{python}%
- \def\mmz@mkdir@command{\mmzvalueof{python extraction command} --mkdir}%
+ % Change the initial value of |mkdir command| to |memoize-extract.py
+ % --mkdir|, but only in the case the user did not modify it.
+ \ifx\mmz@mkdir@command\mmz@initial@mkdir@command
+ \def\mmz@mkdir@command{\mmzvalueof{python extraction command} --mkdir}%
+ \fi
},
python extraction command/.initial=memoize-extract.py,
python extraction options/.initial={\space
@@ -3414,7 +3415,7 @@
}%
}
%
-% \subsection{\pkg{PGF}}
+% \subsection[PGF]{\pkg{PGF}}
%
\mmz@if@package@loaded{pgf}{%
%<plain>\pgfpicture
@@ -3566,7 +3567,7 @@
raw collector options=\collargsReturnPlain,
},
% \begin{mmzautokey}{cite,volcite,cites,volcites}
- % Define handlers for citation commands.
+ % \indentmacrocode Define handlers for citation commands.
auto/cite/.style={
run conditions=\mmz@biblatex@cite@rc,
outer handler=\mmz@biblatex@cite@outer,
@@ -3574,9 +3575,9 @@
raw collector options=\mmz@biblatex@def@star\collargsReturnNo,
inner handler=\mmz@biblatex@cite@inner,
},
- % We need a dedicated |volcite| even though |\volcite| executes |\cite|
- % because otherwise, we would end up with |\cite{volume}{key}| in the cc-memo
- % when |biblatex ccmemo cite=replicate|.
+ % \noindentmacrocode We need a dedicated |volcite| even though |\volcite|
+ % executes |\cite| because otherwise, we would end up with
+ % |\cite{volume}{key}| in the cc-memo when |biblatex ccmemo cite=replicate|.
auto/volcite/.style={
run if memoizing,
outer handler=\mmz@biblatex@cite@outer,
@@ -3585,17 +3586,19 @@
inner handler=\mmz@biblatex@cite@inner,
},
auto/cites/.style={
- run conditions=\mmz@biblatex@cite@rc,
+ run conditions=\mmz@biblatex@cites@rc,
outer handler=\mmz@biblatex@cites@outer,
args=l*m,
- raw collector options=\mmz@biblatex@def@star\collargsClearArgsfalse\collargsReturnNo,
+ raw collector options=
+ \mmz@biblatex@def@star\collargsClearArgsfalse\collargsReturnNo,
inner handler=\mmz@biblatex@cites@inner,
},
auto/volcites/.style={
run if memoizing,
outer handler=\mmz@biblatex@cites@outer,
args=lml*m,
- raw collector options=\mmz@biblatex@def@star\collargsClearArgsfalse\collargsReturnNo,
+ raw collector options=
+ \mmz@biblatex@def@star\collargsClearArgsfalse\collargsReturnNo,
inner handler=\mmz@biblatex@cites@inner,
},
% \end{mmzautokey}
@@ -3618,21 +3621,28 @@
\mmz@scantokens{\AdviceOriginal{#1}#2}%
}
% \end{macro}
-% \begin{macro}{\mmz@biblatex@cite@rc}
-% Run if memoizing but not within a |\volcite| command. Applied to |\cite(s)|.
+% \begin{macro}{\mmz@biblatex@cite@rc,\mmz@biblatex@cites@rc}
+% \indentmacrocode Run if memoizing but not within a |\volcite|
+% command. Applied to |\cite(s)|.
\def\mmz@biblatex@cite@rc{%
\ifmemoizing
- % We cannot use the official |\ifvolcite|, or even the |blx@volcite| toggle
- % it depends on, because these are defined\slash set within the
- % next-citation hook, which is yet to be executed. So we depend on the
- % internal detail that |\volcite| and friends redefine |\blx@citeargs| to
- % |\blx@volciteargs|.
+ % \noindentmacrocode We cannot use the official |\ifvolcite|, or even the
+ % |blx@volcite| toggle it depends on, because these are defined\slash set
+ % within the next-citation hook, which is yet to be executed. So we
+ % depend on the internal detail that |\volcite| and friends redefine
+ % |\blx@citeargs| to |\blx@volciteargs|.
\ifx\blx@citeargs\blx@volciteargs
\else
\AdviceRuntrue
\fi
\fi
}
+\def\mmz@biblatex@cites@rc{%
+ \ifmemoizing
+ % The internal detail with |\volcites|: it defines a hook.
+ \ifdef\blx@hook@mcite@before{}{\AdviceRuntrue}%
+ \fi
+}
% \end{macro}
% \begin{macro}{\mmz@biblatex@cite@outer}
% Initialize the macro receiving the citation key(s), and execute the
@@ -3654,9 +3664,9 @@
}
% \end{macro}
% \begin{macro}{\mmz@biblatex@cite@inner}
+% This macro puts the cites reference keys into the context, and adds
+% |\nocite|, or the handled citation command, to the cc-memo.
\def\mmz@biblatex@cite@inner{%
- % This macro puts the cites reference keys into the context, and adds
- % |\nocite|, or the handled citation command, to the cc-memo.
\mmz@biblatex@do@context
\mmz@biblatex@do@ccmemo
\expandafter\AdviceOriginal\the\collargsArgs
diff --git a/macros/latex/contrib/coloredtheorem/LICENSE b/macros/latex/contrib/coloredtheorem/LICENSE
new file mode 100644
index 0000000000..f8b699e6eb
--- /dev/null
+++ b/macros/latex/contrib/coloredtheorem/LICENSE
@@ -0,0 +1,415 @@
+The LaTeX Project Public License
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+LPPL Version 1.3c 2008-05-04
+
+Copyright 1999 2002-2008 LaTeX3 Project
+ Everyone is allowed to distribute verbatim copies of this
+ license document, but modification of it is not allowed.
+
+
+PREAMBLE
+========
+
+The LaTeX Project Public License (LPPL) is the primary license under
+which the LaTeX kernel and the base LaTeX packages are distributed.
+
+You may use this license for any work of which you hold the copyright
+and which you wish to distribute. This license may be particularly
+suitable if your work is TeX-related (such as a LaTeX package), but
+it is written in such a way that you can use it even if your work is
+unrelated to TeX.
+
+The section `WHETHER AND HOW TO DISTRIBUTE WORKS UNDER THIS LICENSE',
+below, gives instructions, examples, and recommendations for authors
+who are considering distributing their works under this license.
+
+This license gives conditions under which a work may be distributed
+and modified, as well as conditions under which modified versions of
+that work may be distributed.
+
+We, the LaTeX3 Project, believe that the conditions below give you
+the freedom to make and distribute modified versions of your work
+that conform with whatever technical specifications you wish while
+maintaining the availability, integrity, and reliability of
+that work. If you do not see how to achieve your goal while
+meeting these conditions, then read the document `cfgguide.tex'
+and `modguide.tex' in the base LaTeX distribution for suggestions.
+
+
+DEFINITIONS
+===========
+
+In this license document the following terms are used:
+
+ `Work'
+ Any work being distributed under this License.
+
+ `Derived Work'
+ Any work that under any applicable law is derived from the Work.
+
+ `Modification'
+ Any procedure that produces a Derived Work under any applicable
+ law -- for example, the production of a file containing an
+ original file associated with the Work or a significant portion of
+ such a file, either verbatim or with modifications and/or
+ translated into another language.
+
+ `Modify'
+ To apply any procedure that produces a Derived Work under any
+ applicable law.
+
+ `Distribution'
+ Making copies of the Work available from one person to another, in
+ whole or in part. Distribution includes (but is not limited to)
+ making any electronic components of the Work accessible by
+ file transfer protocols such as FTP or HTTP or by shared file
+ systems such as Sun's Network File System (NFS).
+
+ `Compiled Work'
+ A version of the Work that has been processed into a form where it
+ is directly usable on a computer system. This processing may
+ include using installation facilities provided by the Work,
+ transformations of the Work, copying of components of the Work, or
+ other activities. Note that modification of any installation
+ facilities provided by the Work constitutes modification of the Work.
+
+ `Current Maintainer'
+ A person or persons nominated as such within the Work. If there is
+ no such explicit nomination then it is the `Copyright Holder' under
+ any applicable law.
+
+ `Base Interpreter'
+ A program or process that is normally needed for running or
+ interpreting a part or the whole of the Work.
+
+ A Base Interpreter may depend on external components but these
+ are not considered part of the Base Interpreter provided that each
+ external component clearly identifies itself whenever it is used
+ interactively. Unless explicitly specified when applying the
+ license to the Work, the only applicable Base Interpreter is a
+ `LaTeX-Format' or in the case of files belonging to the
+ `LaTeX-format' a program implementing the `TeX language'.
+
+
+
+CONDITIONS ON DISTRIBUTION AND MODIFICATION
+===========================================
+
+1. Activities other than distribution and/or modification of the Work
+are not covered by this license; they are outside its scope. In
+particular, the act of running the Work is not restricted and no
+requirements are made concerning any offers of support for the Work.
+
+2. You may distribute a complete, unmodified copy of the Work as you
+received it. Distribution of only part of the Work is considered
+modification of the Work, and no right to distribute such a Derived
+Work may be assumed under the terms of this clause.
+
+3. You may distribute a Compiled Work that has been generated from a
+complete, unmodified copy of the Work as distributed under Clause 2
+above, as long as that Compiled Work is distributed in such a way that
+the recipients may install the Compiled Work on their system exactly
+as it would have been installed if they generated a Compiled Work
+directly from the Work.
+
+4. If you are the Current Maintainer of the Work, you may, without
+restriction, modify the Work, thus creating a Derived Work. You may
+also distribute the Derived Work without restriction, including
+Compiled Works generated from the Derived Work. Derived Works
+distributed in this manner by the Current Maintainer are considered to
+be updated versions of the Work.
+
+5. If you are not the Current Maintainer of the Work, you may modify
+your copy of the Work, thus creating a Derived Work based on the Work,
+and compile this Derived Work, thus creating a Compiled Work based on
+the Derived Work.
+
+6. If you are not the Current Maintainer of the Work, you may
+distribute a Derived Work provided the following conditions are met
+for every component of the Work unless that component clearly states
+in the copyright notice that it is exempt from that condition. Only
+the Current Maintainer is allowed to add such statements of exemption
+to a component of the Work.
+
+ a. If a component of this Derived Work can be a direct replacement
+ for a component of the Work when that component is used with the
+ Base Interpreter, then, wherever this component of the Work
+ identifies itself to the user when used interactively with that
+ Base Interpreter, the replacement component of this Derived Work
+ clearly and unambiguously identifies itself as a modified version
+ of this component to the user when used interactively with that
+ Base Interpreter.
+
+ b. Every component of the Derived Work contains prominent notices
+ detailing the nature of the changes to that component, or a
+ prominent reference to another file that is distributed as part
+ of the Derived Work and that contains a complete and accurate log
+ of the changes.
+
+ c. No information in the Derived Work implies that any persons,
+ including (but not limited to) the authors of the original version
+ of the Work, provide any support, including (but not limited to)
+ the reporting and handling of errors, to recipients of the
+ Derived Work unless those persons have stated explicitly that
+ they do provide such support for the Derived Work.
+
+ d. You distribute at least one of the following with the Derived Work:
+
+ 1. A complete, unmodified copy of the Work;
+ if your distribution of a modified component is made by
+ offering access to copy the modified component from a
+ designated place, then offering equivalent access to copy
+ the Work from the same or some similar place meets this
+ condition, even though third parties are not compelled to
+ copy the Work along with the modified component;
+
+ 2. Information that is sufficient to obtain a complete,
+ unmodified copy of the Work.
+
+7. If you are not the Current Maintainer of the Work, you may
+distribute a Compiled Work generated from a Derived Work, as long as
+the Derived Work is distributed to all recipients of the Compiled
+Work, and as long as the conditions of Clause 6, above, are met with
+regard to the Derived Work.
+
+8. The conditions above are not intended to prohibit, and hence do not
+apply to, the modification, by any method, of any component so that it
+becomes identical to an updated version of that component of the Work as
+it is distributed by the Current Maintainer under Clause 4, above.
+
+9. Distribution of the Work or any Derived Work in an alternative
+format, where the Work or that Derived Work (in whole or in part) is
+then produced by applying some process to that format, does not relax or
+nullify any sections of this license as they pertain to the results of
+applying that process.
+
+10. a. A Derived Work may be distributed under a different license
+ provided that license itself honors the conditions listed in
+ Clause 6 above, in regard to the Work, though it does not have
+ to honor the rest of the conditions in this license.
+
+ b. If a Derived Work is distributed under a different license, that
+ Derived Work must provide sufficient documentation as part of
+ itself to allow each recipient of that Derived Work to honor the
+ restrictions in Clause 6 above, concerning changes from the Work.
+
+11. This license places no restrictions on works that are unrelated to
+the Work, nor does this license place any restrictions on aggregating
+such works with the Work by any means.
+
+12. Nothing in this license is intended to, or may be used to, prevent
+complete compliance by all parties with all applicable laws.
+
+
+NO WARRANTY
+===========
+
+There is no warranty for the Work. Except when otherwise stated in
+writing, the Copyright Holder provides the Work `as is', without
+warranty of any kind, either expressed or implied, including, but not
+limited to, the implied warranties of merchantability and fitness for a
+particular purpose. The entire risk as to the quality and performance
+of the Work is with you. Should the Work prove defective, you assume
+the cost of all necessary servicing, repair, or correction.
+
+In no event unless required by applicable law or agreed to in writing
+will The Copyright Holder, or any author named in the components of the
+Work, or any other party who may distribute and/or modify the Work as
+permitted above, be liable to you for damages, including any general,
+special, incidental or consequential damages arising out of any use of
+the Work or out of inability to use the Work (including, but not limited
+to, loss of data, data being rendered inaccurate, or losses sustained by
+anyone as a result of any failure of the Work to operate with any other
+programs), even if the Copyright Holder or said author or said other
+party has been advised of the possibility of such damages.
+
+
+MAINTENANCE OF THE WORK
+=======================
+
+The Work has the status `author-maintained' if the Copyright Holder
+explicitly and prominently states near the primary copyright notice in
+the Work that the Work can only be maintained by the Copyright Holder
+or simply that it is `author-maintained'.
+
+The Work has the status `maintained' if there is a Current Maintainer
+who has indicated in the Work that they are willing to receive error
+reports for the Work (for example, by supplying a valid e-mail
+address). It is not required for the Current Maintainer to acknowledge
+or act upon these error reports.
+
+The Work changes from status `maintained' to `unmaintained' if there
+is no Current Maintainer, or the person stated to be Current
+Maintainer of the work cannot be reached through the indicated means
+of communication for a period of six months, and there are no other
+significant signs of active maintenance.
+
+You can become the Current Maintainer of the Work by agreement with
+any existing Current Maintainer to take over this role.
+
+If the Work is unmaintained, you can become the Current Maintainer of
+the Work through the following steps:
+
+ 1. Make a reasonable attempt to trace the Current Maintainer (and
+ the Copyright Holder, if the two differ) through the means of
+ an Internet or similar search.
+
+ 2. If this search is successful, then enquire whether the Work
+ is still maintained.
+
+ a. If it is being maintained, then ask the Current Maintainer
+ to update their communication data within one month.
+
+ b. If the search is unsuccessful or no action to resume active
+ maintenance is taken by the Current Maintainer, then announce
+ within the pertinent community your intention to take over
+ maintenance. (If the Work is a LaTeX work, this could be
+ done, for example, by posting to comp.text.tex.)
+
+ 3a. If the Current Maintainer is reachable and agrees to pass
+ maintenance of the Work to you, then this takes effect
+ immediately upon announcement.
+
+ b. If the Current Maintainer is not reachable and the Copyright
+ Holder agrees that maintenance of the Work be passed to you,
+ then this takes effect immediately upon announcement.
+
+ 4. If you make an `intention announcement' as described in 2b. above
+ and after three months your intention is challenged neither by
+ the Current Maintainer nor by the Copyright Holder nor by other
+ people, then you may arrange for the Work to be changed so as
+ to name you as the (new) Current Maintainer.
+
+ 5. If the previously unreachable Current Maintainer becomes
+ reachable once more within three months of a change completed
+ under the terms of 3b) or 4), then that Current Maintainer must
+ become or remain the Current Maintainer upon request provided
+ they then update their communication data within one month.
+
+A change in the Current Maintainer does not, of itself, alter the fact
+that the Work is distributed under the LPPL license.
+
+If you become the Current Maintainer of the Work, you should
+immediately provide, within the Work, a prominent and unambiguous
+statement of your status as Current Maintainer. You should also
+announce your new status to the same pertinent community as
+in 2b) above.
+
+
+WHETHER AND HOW TO DISTRIBUTE WORKS UNDER THIS LICENSE
+======================================================
+
+This section contains important instructions, examples, and
+recommendations for authors who are considering distributing their
+works under this license. These authors are addressed as `you' in
+this section.
+
+Choosing This License or Another License
+----------------------------------------
+
+If for any part of your work you want or need to use *distribution*
+conditions that differ significantly from those in this license, then
+do not refer to this license anywhere in your work but, instead,
+distribute your work under a different license. You may use the text
+of this license as a model for your own license, but your license
+should not refer to the LPPL or otherwise give the impression that
+your work is distributed under the LPPL.
+
+The document `modguide.tex' in the base LaTeX distribution explains
+the motivation behind the conditions of this license. It explains,
+for example, why distributing LaTeX under the GNU General Public
+License (GPL) was considered inappropriate. Even if your work is
+unrelated to LaTeX, the discussion in `modguide.tex' may still be
+relevant, and authors intending to distribute their works under any
+license are encouraged to read it.
+
+A Recommendation on Modification Without Distribution
+-----------------------------------------------------
+
+It is wise never to modify a component of the Work, even for your own
+personal use, without also meeting the above conditions for
+distributing the modified component. While you might intend that such
+modifications will never be distributed, often this will happen by
+accident -- you may forget that you have modified that component; or
+it may not occur to you when allowing others to access the modified
+version that you are thus distributing it and violating the conditions
+of this license in ways that could have legal implications and, worse,
+cause problems for the community. It is therefore usually in your
+best interest to keep your copy of the Work identical with the public
+one. Many works provide ways to control the behavior of that work
+without altering any of its licensed components.
+
+How to Use This License
+-----------------------
+
+To use this license, place in each of the components of your work both
+an explicit copyright notice including your name and the year the work
+was authored and/or last substantially modified. Include also a
+statement that the distribution and/or modification of that
+component is constrained by the conditions in this license.
+
+Here is an example of such a notice and statement:
+
+ %% pig.dtx
+ %% Copyright 2005 M. Y. Name
+ %
+ % This work may be distributed and/or modified under the
+ % conditions of the LaTeX Project Public License, either version 1.3
+ % 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.3 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 M. Y. Name.
+ %
+ % This work consists of the files pig.dtx and pig.ins
+ % and the derived file pig.sty.
+
+Given such a notice and statement in a file, the conditions
+given in this license document would apply, with the `Work' referring
+to the three files `pig.dtx', `pig.ins', and `pig.sty' (the last being
+generated from `pig.dtx' using `pig.ins'), the `Base Interpreter'
+referring to any `LaTeX-Format', and both `Copyright Holder' and
+`Current Maintainer' referring to the person `M. Y. Name'.
+
+If you do not want the Maintenance section of LPPL to apply to your
+Work, change `maintained' above into `author-maintained'.
+However, we recommend that you use `maintained', as the Maintenance
+section was added in order to ensure that your Work remains useful to
+the community even when you can no longer maintain and support it
+yourself.
+
+Derived Works That Are Not Replacements
+---------------------------------------
+
+Several clauses of the LPPL specify means to provide reliability and
+stability for the user community. They therefore concern themselves
+with the case that a Derived Work is intended to be used as a
+(compatible or incompatible) replacement of the original Work. If
+this is not the case (e.g., if a few lines of code are reused for a
+completely different task), then clauses 6b and 6d shall not apply.
+
+
+Important Recommendations
+-------------------------
+
+ Defining What Constitutes the Work
+
+ The LPPL requires that distributions of the Work contain all the
+ files of the Work. It is therefore important that you provide a
+ way for the licensee to determine which files constitute the Work.
+ This could, for example, be achieved by explicitly listing all the
+ files of the Work near the copyright notice of each file or by
+ using a line such as:
+
+ % This work consists of all files listed in manifest.txt.
+
+ in that place. In the absence of an unequivocal list it might be
+ impossible for the licensee to determine what is considered by you
+ to comprise the Work and, in such a case, the licensee would be
+ entitled to make reasonable conjectures as to which files comprise
+ the Work.
diff --git a/macros/latex/contrib/coloredtheorem/README.md b/macros/latex/contrib/coloredtheorem/README.md
new file mode 100644
index 0000000000..805393b738
--- /dev/null
+++ b/macros/latex/contrib/coloredtheorem/README.md
@@ -0,0 +1,96 @@
+# coloredtheorem
+
+A colourful boxed theorem environment, combining `tcolorbox` and breakable boxes. It supports full `tcolorbox` customization, automatic numbering, `\label{...}` and `\ref{…}`, and `\listof…`
+
+<!--
+--------
+
+<picture>
+ <source
+ media="(prefers-color-scheme: dark)"
+ srcset="
+ https://api.star-history.com/svg?repos=joaomlourenco/coloredtheorem&type=Date&theme=dark
+ "
+ />
+ <source
+ media="(prefers-color-scheme: light)"
+ srcset="
+ https://api.star-history.com/svg?repos=joaomlourenco/coloredtheorem&type=Date
+ "
+ />
+ <img
+ width="500"
+ alt="Star History Chart"
+ src="https://api.star-history.com/svg?repos=joaomlourenco/coloredtheorem&type=Date"
+ />
+</picture>
+
+--------
+-->
+
+## Introduction
+
+The `coloredtheorem` package is a simple environment, which takes no options, and that allows to write stuff inside boxes from `tcolorbox`. So, this packages includes `tcolorbox` if necessary. You may include `tcolorbox` with your own favourite options prior to including this package.
+
+Akin to `\newtheorem` from the `amsmath` package, the user should start by defining a new theorem/box group and customize its aspect. Each new environment will have its own counter/numnering. Notice that `\label{...}` and `\ref{...}` work as expected. The is also a command to generate the corresponding `\listof...`
+
+## Usage
+
+* `\cthnewtheorem{<envname>}{<Name>}[<tcolorbox options>]`
+ * Load the tcbtheorem package. This package will load tcolorbox if not already loaded.
+* `\cthnewtheorem{<envname>}{<Name>}[<tcolorbox options>]`
+ * `<envname>` is the environment name, e.g., theorem.
+ * `<Name>` is the name for new environment being defined, e.g., Theorem.
+ * `<tcolorbox options>` options to be passed to the `tcolorbox` environment to customize the boxes for the given environment (this argument is optional).
+* `\begin{<envname>}{<Caption>}[<tcolorbox options>]<Contents>\end{<envname>}`
+ * `<envname>` is the environment name, e.g., theorem.
+ * `<Caption>` is the caption/title of the box.
+ * `<tcolorbox options>` options to be passed to the `tcolorbox` environment, which will override the defaults given in `\cthnewtheorem`.
+ * `<Contents>` the contents to by typeset inside the coulored environment.
+* `\listof<envname>s`
+ * Where `<envname>` is the environment name, e.g., `\listoftheorems`. Please notice that there is a ‘s’ (plural) after `<envname>`.
+
+## Example
+
+Let’s start by creating two new environments, one for algorithms and another for examples, both defaulting to a gray frame, the former with a yellowish background and the latter with a lighter gray background.
+
+ \cthnewtheorem{algorithm}{Algorithm}[coltitle=black, colback=yellow!10,
+ colframe=black!15]
+ \cthnewtheorem{example}{Example}[coltitle=black, colback=black!5,
+ colframe=black!30]
+
+An algorithm box will be created with:
+
+ \begin{cthalgorithm}{Advance a counter to the next value in a domain
+ $\omega \in \mathbb{N}$.}
+
+ Algorithm body here!
+ \end{cthalgorithm}
+
+<img width="491" alt="image" src="https://github.com/joaomlourenco/tcbtheorem/assets/2064643/54147631-3f5d-4ae0-a8b7-8b18b48d8db2">
+
+Now, let's rewrite Algorithm 1, but now with a different customized visual, just for this entry! The customization (3rd) argument is passed straight to the `tcolorbox` environment, so anything valid for `tcolorbox` is also valid here.
+
+<img width="491" alt="image" src="https://github.com/joaomlourenco/tcbtheorem/assets/2064643/be180e78-bc59-48ff-9efa-a26af5dae0bd">
+
+(page break here!)
+
+<img width="489" alt="image" src="https://github.com/joaomlourenco/tcbtheorem/assets/2064643/04c6fcaa-1a27-4550-8b17-2ae4d90809b0">
+
+Now, let’s add an example here, this time using the default visual that was given when creating the environment with `\cthnewtheorem`…
+
+<img width="490" alt="image" src="https://github.com/joaomlourenco/tcbtheorem/assets/2064643/835c1537-5b18-48b6-8ac1-ba6a6cff7b1b">
+
+And now and example with no caption and a different visual... this example will not go into the` \listofexamples` below!
+
+<img width="492" alt="image" src="https://github.com/joaomlourenco/tcbtheorem/assets/2064643/329e61a9-a12b-4cfe-9edf-1977f8158ee9">
+
+Now let’s print the lists of algorithms and examples. Remember to add the prefix cthth to the listof, i.e., `\cthlistofalgorithms` and `\cthlistofexamples`!
+
+## List of Algorithms
+<img width="492" alt="image" src="https://github.com/joaomlourenco/tcbtheorem/assets/2064643/f935bfcb-3387-426e-8511-c1f0efdcdd85">
+
+## List of Examples
+<img width="487" alt="image" src="https://github.com/joaomlourenco/tcbtheorem/assets/2064643/033f83d4-24c3-4e9d-8947-135f5765e3f3">
+
+
diff --git a/macros/latex/contrib/coloredtheorem/coloredtheorem-doc.pdf b/macros/latex/contrib/coloredtheorem/coloredtheorem-doc.pdf
new file mode 100644
index 0000000000..046c79dcc6
--- /dev/null
+++ b/macros/latex/contrib/coloredtheorem/coloredtheorem-doc.pdf
Binary files differ
diff --git a/macros/latex/contrib/coloredtheorem/coloredtheorem-doc.tex b/macros/latex/contrib/coloredtheorem/coloredtheorem-doc.tex
new file mode 100644
index 0000000000..55ae3d3ae5
--- /dev/null
+++ b/macros/latex/contrib/coloredtheorem/coloredtheorem-doc.tex
@@ -0,0 +1,197 @@
+\documentclass{article}
+
+\usepackage[margin=1.6in]{geometry}
+\usepackage{fancyvrb}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% AMSMATH stuff
+% \usepackage{amsthm}
+% \usepackage{thmtools}
+% \usepackage{amsfonts}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% TCBTHEOREM stuff
+\usepackage{coloredtheorem}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% EXAMPLE document
+\usepackage{amsfonts}
+\usepackage{kantlipsum}
+\usepackage{tabularx}
+\usepackage{xspace}
+\newcommand\tcthrm{\texttt{coloredtheorem}\xspace}
+
+%% ALGPSEUDOCODEX stuff
+\usepackage{algorithm}
+\usepackage[
+ noEnd=false,
+ beginComment={$\triangleright$~\scriptsize},
+ beginLComment={$\triangleright$~},
+ endLComment={},
+]{algpseudocodex}
+
+\algnewcommand\Input{\textbf{Input:~}}
+\algrenewcommand\Output{\textbf{Output:~}}
+\algrenewcommand\algorithmicforall{\textbf{for each}}
+\algnewcommand\Vspace{%
+ {\setlength\itemsep{-1ex}\item[]~}
+}
+\algnewcommand\Let[2]{\State \ensuremath{#1 \gets #2}}
+\algnewcommand\And{\ensuremath{\wedge}\xspace}
+\algnewcommand\Or{\ensuremath{\vee}\xspace}
+\algnewcommand\Not{\ensuremath{\neg}\xspace}
+
+\usepackage[colorlinks,linkcolor=blue!80]{hyperref}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% MAIN DOCUMENT
+\begin{document}
+ \title{The \tcthrm package}
+ \author{João M. Lourenço\\\texttt{\small joao.lourenco@fct.unl.pt}}
+ \date{March 31, 2024}
+
+ \maketitle
+
+
+\section{Introduction}
+\label{sec:introduction}
+
+The \tcthrm package is a simple environment, which takes no options, and that allows to write stuff inside boxes from \texttt{tcolorbox}. So, this packages includes \texttt{tcolorbox} if necessary. You may include \texttt{tcolorbox} with your own favourite options prior to including this package.
+
+Akin to \verb!\newtheorem! from the \verb!amsmath! package, the user should start by defining a new \emph{theorem/box} group and customize its aspect. Each new environment will have its own counter/numbering. Notice that \verb!\label{…}! and \verb!\ref{…}! work as expected. The is also a command to generate the corresponding \emph{list of …}
+
+\section{Usage}
+\label{sec:usage}
+
+\begin{description}
+ \item[]{\bfseries\verb+\usepackage{coloredtheorem}+}
+ \begin{description}
+ \item[]Load the \texttt{coloredtheorem} package. This package will load \texttt{tcolorbox} if necessary.
+ \end{description}
+ \item[]{\bfseries\Verb[commandchars=!()]+\!tcbth()newtheorem{<envname>}{<Name>}[<tcolorbox options>]+}
+ \begin{description}
+ \item[]\verb+<envname>+ is the environment name, e.g., \verb!theorem!.
+ \item[]\verb+<Name>+ is the name for new environment being defined, e.g., \emph{Theorem}.
+ \item[]\verb+<tcolorbox options>+ options to be passed to the \verb+tcolorbox+ environment to customize the boxes for the given environment (this argument is optional).
+ \end{description}
+ \item[]{\bfseries\Verb[commandchars=!()]+\begin{!tcbth()<envname>}{<Caption>}[<tcolorbox options>]<Contents>\end{!tcbth()<envname>}+}
+ \begin{description}
+ \item[]\verb+<envname>+ is the environment name, e.g., \verb+theorem+.
+ \item[]\verb+<Caption>+ is the caption/title of the box.
+ \item[]\verb+<tcolorbox options>+ options to be passed to the \verb+tcolobox+ environment, which will override the defaults given in \verb+\cthnewtheorem+.
+ \item[]\verb+<Contents>+ the contents to by typeset inside the coulored environment.
+ \end{description}
+ \item[]{\bfseries\Verb[commandchars=!()]+\!tcbth()listof<envname>s+}
+ \begin{description}
+ \item[]\verb+<envname>+ is the environment name, e.g., e.g., \Verb[commandchars=!()]+\!tcbth()listoftheorems+. Please notice that there is a `s' (plural) after \verb+<envname>+.
+ \end{description}
+\end{description}
+
+\section{Example}
+\label{sec:examples}
+
+Let's start by creating two new environments, one for \emph{algorithms} and another for \emph{examples}, both defaulting to a gray frame, the former with a yellowish background and the latter with a lighter gray background.
+
+\begin{verbatim}
+\cthnewtheorem{algorithm}{Algorithm}[coltitle=black, colback=yellow!10,
+ colframe=black!15]
+\cthnewtheorem{example}{Example}[coltitle=black, colback=black!5,
+ colframe=black!30]
+\end{verbatim}
+
+\cthnewtheorem{algorithm}{Algorithm}[coltitle=black, colback=yellow!10, colframe=black!15]
+\cthnewtheorem{example}{Example}[coltitle=black, colback=black!5, colframe=black!30]
+
+
+An algorithm box will be created with:
+\begin{verbatim}
+\begin{cthalgorithm}{Advance a counter to the next value in a domain
+ $\omega \in \mathbb{N}$.}
+
+Algorithm body here!
+\end{cthalgorithm}
+\end{verbatim}
+
+\newcommand{\bracesemptyset}{\ensuremath{\lbrace\,\rbrace}}
+
+\begin{cthalgorithm}{Advance a counter to the next value in a domain $\omega \in \mathbb{N}$.}
+ \label{alg:advance1}
+\begin{algorithmic}[1]
+ \Statex \Input $\alpha$: The current value; and $\omega$: the domain.
+ \Statex \Output The next value of $\alpha$ within the domain $\omega$.
+ \LComment{\color{blue}
+ e.g., $\alpha = 3 \And \omega = \lbrace 8, 3, 2, 21, 5, 1 \rbrace \rightarrow 5$}
+
+ \Vspace
+
+ \Function{advance}{$\alpha$: int, $\omega$: set} $\rightarrow$ int \textbf{is}
+ % \Statex\Comment{As we are incrementing one by one on the operation IDs, the complexity of this function is linear in the value of the largest operation id.}
+ \Let {\alpha} {\alpha + 1}
+ \Comment{try the next value}
+ \While{$\alpha \not\in \omega \And \omega \neq \bracesemptyset$}
+ \Comment{if this value is not in the domain}
+ \Let {\alpha} {\alpha + 1}
+ \Comment{try the next value}
+ \EndWhile
+ \If{$\omega \neq \bracesemptyset$}
+ \Let {\omega} {\omega \,\backslash \lbrace \alpha \rbrace}
+ \Comment{remove the value from the domain}
+ \EndIf
+ \State \Return $\alpha$
+ \Comment{\color{red} the next value (or the last value plus one if no more values)}
+ \EndFunction
+\end{algorithmic}
+\end{cthalgorithm}
+
+Now, let's rewrite \autoref{alg:advance1}, but now with a different customized visual, just for this entry! The customization (3rd) argument is passed straight to the \texttt{tcolorbox} environment, so anything valid for \texttt{tcolorbox} is also valid here.
+
+\begin{cthalgorithm}{Advance a counter to the next value in a domain $\omega \in \mathbb{N}$, but now with a customized visual. Also, notice that this algorithm breaks the page boundaries.}[coltitle=white, colback=green!10, colframe=green!70!black, fonttitle=\sffamily\bfseries\large, colbacktitle=red!50!white]
+ \label{alg:advance2}
+\begin{algorithmic}[1]
+ \Statex \Input $\alpha$: The current value; and $\omega$: the domain.
+ \Statex \Output The next value of $\alpha$ within the domain $\omega$.
+ \LComment{\color{blue}
+ e.g., $\alpha = 3 \And \omega = \lbrace 8, 3, 2, 21, 5, 1 \rbrace \rightarrow 5$}
+
+ \Vspace
+
+ \Function{advance}{$\alpha$: int, $\omega$: set} $\rightarrow$ int \textbf{is}
+ % \Statex\Comment{As we are incrementing one by one on the operation IDs, the complexity of this function is linear in the value of the largest operation id.}
+ \Let {\alpha} {\alpha + 1}
+ \Comment{try the next value}
+ \While{$\alpha \not\in \omega \And \omega \neq \bracesemptyset$}
+ \Comment{if this value is not in the domain}
+ \Let {\alpha} {\alpha + 1}
+ \Comment{try the next value}
+ \EndWhile
+ \If{$\omega \neq \bracesemptyset$}
+ \Let {\omega} {\omega \,\backslash \lbrace \alpha \rbrace}
+ \Comment{remove the value from the domain}
+ \EndIf
+ \State \Return $\alpha$
+ \Comment{\color{red} the next value (or the last value plus one if no more values)}
+ \EndFunction
+\end{algorithmic}
+\end{cthalgorithm}
+
+Now, let's add an example here, this time using the default visual that was given when creating the environment with \verb+\cthnewtheorem+…
+
+\begin{cthexample}{This is an example!}
+ \emph{\kant[3]}
+\end{cthexample}
+
+And now an example with no caption and a different visual… this example will not go into the \verb+\listofexamples+ below!
+
+\begin{cthexample}{}[coltitle=yellow, colback=blue!30, colframe=blue!70]
+ \emph{\kant[4]}
+\end{cthexample}
+
+Now let's print the lists of algorithms and examples. Remember to add the prefix \texttt{cthth} to the \texttt{listof}, i.e., \verb+\cthlistofalgorithms+ and \verb+\cthlistofexamples+!
+
+\cthlistofalgorithms
+
+\cthlistofexamples
+
+\end{document}
diff --git a/macros/latex/contrib/coloredtheorem/coloredtheorem.sty b/macros/latex/contrib/coloredtheorem/coloredtheorem.sty
new file mode 100644
index 0000000000..dd553ba75d
--- /dev/null
+++ b/macros/latex/contrib/coloredtheorem/coloredtheorem.sty
@@ -0,0 +1,59 @@
+%% This is file `tcbtheorem.sty',
+%%
+%% Copyright (C) 2024 by João Lourenço <joao.lourenco@fct.unl.pt>
+%%
+%% This file 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 2006/05/20 or later.
+%%
+\NeedsTeXFormat{LaTeX2e}[2020/06/01]
+\ProvidesPackage{coloredtheorem}
+ [2024/03/31 v1.0 - a theorem-like environment inside a tcolobox]
+
+\RequirePackage{tcolorbox}
+\tcbuselibrary{breakable}
+
+\gdef\tcbth{cth}
+
+\expandafter\NewDocumentCommand\csname\tcbth newtheorem\endcsname { m m O{} }{%
+ \expandafter\newcounter\expandafter{\tcbth#1}%
+ \expandafter\gdef\csname\tcbth#1name\endcsname{#2}%
+ \expandafter\gdef\csname\tcbth list#1name\endcsname{List of #2s}%
+ \expandafter\gdef\csname#1autorefname\endcsname{#2}%
+ \AtEndPreamble{%
+ \ifdefined\crefname\expandafter\crefname\csname\tcbth#1\endcsname{#2}{#2s}\fi}%
+ \expandafter\gdef\csname\tcbth listof#1s\endcsname
+ {%
+ \section*{\csname\tcbth list#1name\endcsname}%
+ \expandafter\@starttoc\expandafter{lo#1}%
+ }
+ \expandafter\NewDocumentEnvironment\expandafter{\tcbth#1} {O{} m O{}}%
+ {% \begin{tcb<SOMETHING>}
+ \begin{center}%
+ \ifx\relax##1\relax
+ \ifx\relax##2\relax\else
+ \expandafter\refstepcounter\expandafter{\tcbth#1}%
+ \expandafter\addcontentsline\expandafter{lo#1}{subsection}
+ {\protect\numberline{\csname the\tcbth#1\endcsname}##2}%
+ \fi
+ \else
+ \expandafter\addcontentsline\expandafter{lo#1}{subsection}
+ {\protect\numberline{\csname the\tcbth#1\endcsname}##1}%
+ \fi
+ \begin{tcolorbox}[breakable,
+ title={\textbf{\csname\tcbth#1name\endcsname
+ \ifx\relax##2\relax\else
+ ~\csname the\tcbth#1\endcsname\fi}~~##2},
+ #3, ##3,
+ ]%
+ }{% \end{tcb<SOMETHING>}
+ \end{tcolorbox}%
+ \end{center}%
+ }%
+}
diff --git a/macros/latex/contrib/easybook/easybook.dtx b/macros/latex/contrib/easybook/easybook.dtx
index 2ce884d5f3..64ece3b038 100644
--- a/macros/latex/contrib/easybook/easybook.dtx
+++ b/macros/latex/contrib/easybook/easybook.dtx
@@ -15,7 +15,7 @@
%<*class>
\NeedsTeXFormat{LaTeX2e}[2021/11/15]
\RequirePackage{l3keys2e}
-\ProvidesExplClass{easybook}{2024/03/15}{2024ap}
+\ProvidesExplClass{easybook}{2024/04/02}{2024ar}
{Easily typesetting Chinese theses or books}
\bool_new:N \l__eb_compile_draft_bool
@@ -297,7 +297,7 @@
%<*package>
\NeedsTeXFormat{LaTeX2e}[2021/11/15]
\RequirePackage{l3keys2e,etoolbox}
-\ProvidesExplPackage{easybase}{2024/03/15}{2024ap}
+\ProvidesExplPackage{easybase}{2024/04/02}{2024ar}
{Easily typesetting Chinese theses or books}
\cs_generate_variant:Nn \dim_set:Nn { NV }
@@ -1540,7 +1540,7 @@
#1/tocformat .tl_set:c = l__eb_toc_#1_format_tl,
#1/tocformat+ .code:n = \tl_put_right:cn { l__eb_toc_#1_format_tl } {##1},
#1/tocformat~+ .code:n = \tl_put_right:cn { l__eb_toc_#1_format_tl } {##1},
- #1/tocindent .dim_set:c = l__eb_toc_#1_indent_dim,
+ #1/tocindent .tl_set:c = l__eb_toc_#1_indent_tl,
#1/tocrule .tl_set:c = l__eb_toc_#1_rule_tl,
#1/tocafter .tl_set:c = l__eb_toc_#1_after_tl,
#1/tocbelow .tl_set:c = l__eb_toc_#1_below_tl
@@ -1549,7 +1549,7 @@
\cs_new_protected:Npn \eb_toc_format_initial:n #1
{
\titlecontents{#1}
- [\dim_use:c { l__eb_toc_#1_indent_dim }]
+ [\tl_use:c { l__eb_toc_#1_indent_tl }]
{\tl_use:c { l__eb_toc_#1_format_tl }}
{\eb_toc_entry_if_hang:n {#1}}{}
{\tl_use:c { l__eb_toc_#1_rule_tl }}
@@ -2392,7 +2392,7 @@
}
%</package>
%<*tcolorbox>
-\ProvidesExplFile{eb-tcolorbox.cfg}{2024/03/15}{2024ap}
+\ProvidesExplFile{eb-tcolorbox.cfg}{2024/04/02}{2024ar}
{Customization of tcolorbox for easybook}
\cs_set_protected:Npn \addtotcbstyle #1#2
diff --git a/macros/latex/contrib/easybook/easybook.pdf b/macros/latex/contrib/easybook/easybook.pdf
index 2fe646ac7e..505b625244 100644
--- a/macros/latex/contrib/easybook/easybook.pdf
+++ b/macros/latex/contrib/easybook/easybook.pdf
Binary files differ
diff --git a/macros/latex/contrib/easybook/easybook.tex b/macros/latex/contrib/easybook/easybook.tex
index 104080059b..edd3c476ce 100644
--- a/macros/latex/contrib/easybook/easybook.tex
+++ b/macros/latex/contrib/easybook/easybook.tex
@@ -23,8 +23,8 @@
name = easybook,
color-scheme = blue,
title = EASYBOOK使用手册,
- version = v2024ap,
- date = 2024/03/15,
+ version = v2024ar,
+ date = 2024/04/02,
authors = 瞿毅,
info = 简便地排版中文学位论文或书籍,
email = toquyi@163.com,
@@ -1420,6 +1420,7 @@
\item 新增行间公式与正文上下间距选项 \option{abovedisplayskip} 和 \option{belowdisplayskip}。
\item 新增目录文件扩展名分配命令 \cs{AllotCaptionExt}。
\end{version}
+ \shortversion{v = 2024aq,date = 2022/03/31,changes = 修复命令 \cs{ebifbitoc} 用于条目缩进选项 \option{tocindent} 失效的问题。}
\end{changelog}
\nocite{*}
diff --git a/macros/latex/contrib/msu-thesis/README.md b/macros/latex/contrib/msu-thesis/README.md
index 13a939dc53..31d83c056a 100644
--- a/macros/latex/contrib/msu-thesis/README.md
+++ b/macros/latex/contrib/msu-thesis/README.md
@@ -1,6 +1,6 @@
-# MSU Thesis Class Version 4.1h 2023/10/07
+# MSU Thesis Class Version 4.2 2024/02/18
-Copyright 2011-2023 by Alan Munn <amunn@msu.edu>
+Copyright 2011-2024 by Alan Munn <amunn@msu.edu>
This is a class file for producing dissertations and theses according to
the Michigan State University Graduate School Guidelines for Electronic
diff --git a/macros/latex/contrib/msu-thesis/docs/msu-thesis.tex b/macros/latex/contrib/msu-thesis/docs/msu-thesis.tex
index 98f76d3c07..01ca59e7ad 100644
--- a/macros/latex/contrib/msu-thesis/docs/msu-thesis.tex
+++ b/macros/latex/contrib/msu-thesis/docs/msu-thesis.tex
@@ -2,8 +2,8 @@
\documentclass[11pt]{article}
-\def\msuversion{4.1h}
-\def\msudate{2023/10/07}
+\def\msuversion{4.2}
+\def\msudate{2024/02/18}
\title{\textbf{Using the MSU Thesis Class}}
\author{\textbf{Alan Munn}\\Department of Linguistics, Languages, and Cultures\\Michigan State University\\\texttt{\href{mailto:amunn@msu.edu}{amunn@msu.edu}}}
\date{Version \msuversion\\\msudate}
@@ -434,7 +434,8 @@ Version 3.6 added built-in support for the Key to Abbreviations.
Version 3.7 added improved support for \pkg{hyperref}.
Version 4.0 implements the new requirements as of September 2022, including adding a |\dualmajor| command.
Various spacing changes have been made which will make your document look like you used Word, but this is what the thesis office seems to care about.
-Version 4.1 added the |msutocdepth| counter to allow for the chapters-only format that the thesis office recommends.
+Version 4.1 added the |msutocdepth| counter to allow for the chapters-only format that the thesis office recommends.
+Version 4.2 changed the spacing parameters for subsections to appease the thesis office yet again.
\section{Acknowledgements}
Thanks to Lars Madsen, Ulrike Fischer and Peter Wilson for help with setting up parts of
@@ -442,12 +443,13 @@ the memoir code for versions 1.0--1.4 (now eliminated due to changed requirement
to Wolfgang Sternefeld for supplying the \pkg{linguex}\ spacing fix code, Leo Liu for the
landscape page numbering code, which greatly simplified my original version. Thanks to
Florent Chervet for early \pkg{hyperref} code (up until v.3.6), and Ulrike Fischer for the
-current \pkg{hyperref} code. Thanks also to the following students who have reported
+current \pkg{hyperref} code. Thanks to David Carlisle for helping me understand a ridiculous spacing problem.
+Thanks also to the following students who have reported
problems over the years: Irina Agafonova, Ali Al-jiboory, Abubakr Ayesh, Julian Blank,
Nathan Brugnone, Dmitriy Bryndin, Greg Christian, Kyle Crayne, Ciaron Hamilton, Matt Husband, Changkuk
Jung, Claire Kopenhafer, Adam Liter, Vanessa Maldonado, Andriana Manousidaki, Ben Miller, William Muir, Eureka
Pai, Alicia Parrish, Neil ver Planck, Taha Posos, Nick Rekuski, Giacomo Romanini, William Sands, Adam
-Soliman, Mookyong Son, Erik Stitt, Fanurs C.E. Teh, Eremey Valetov, Matthew Vincent, Michael Wojcik, Stephen Yowono, Ali
+Soliman, Mookyong Son, Erik Stitt, Fanurs C.E. Teh, Eremey Valetov, Matthew Vincent, Michael Wojcik, Stephen Yowono, Atacan Yücesoy, Ali
Zare, and Yisu Zhou. A special thank you to Non Thongprong who graciously provided a copy
of his entire thesis which allowed me to debug some especially subtle spacing
inconsistencies.
diff --git a/macros/latex/contrib/msu-thesis/msu-thesis.cls b/macros/latex/contrib/msu-thesis/msu-thesis.cls
index f77d580788..c73d4be4d0 100644
--- a/macros/latex/contrib/msu-thesis/msu-thesis.cls
+++ b/macros/latex/contrib/msu-thesis/msu-thesis.cls
@@ -1,6 +1,6 @@
% MSU Thesis Class
%
-% Copyright 2009-2023 by Alan Munn <amunn@msu.edu>
+% Copyright 2009-2024 by Alan Munn <amunn@msu.edu>
%
% This is a class file for producing dissertations and theses according to the
% Michigan State University Graduate School Guidelines
@@ -190,10 +190,12 @@
% Version 4.1f 2023/07/28 Fixed title page spacing issue
% Version 4.1g 2023/08/12 Per chapter appendices and bibliography TOC issue
% Version 4.1h 2023/10/07 Changed option processing code
+% Version 4.1i 2023/12/02 Fixed spurious blank page with biblatex bibliography
+% Version 4.2 2024/02/18 Changed spacing for sections to address complaints about adjacent sectioning commands
% Report bugs/problems/questions to <amunn@msu.edu>
%
-\def\msu@version{4.1h}
-\def\msu@date{2023/10/07}
+\def\msu@version{4.2}
+\def\msu@date{2024/02/18}
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{msu-thesis}[\msu@date\space Michigan State University Thesis Class version \msu@version]
\DeclareKeys[msu-thesis]
@@ -359,10 +361,16 @@ chapterapp.code = {
% set up the section styles
-
-\setsecheadstyle{\normalfont\SingleSpacing\bfseries} % made uniform size v4
-\setsubsecheadstyle{\normalfont\SingleSpacing\bfseries}
-\setsubsubsecheadstyle{\normalfont\SingleSpacing\bfseries}
+% Added spacing command v4.2 due to complaints about extra space when two
+% sectioning commands are adjacent
+\newcommand*{\msu@SingleSpacing}{%
+ \setSpacing{\m@m@singlespace}%
+ \ifx\@nodocument\relax\vskip\onelineskip\fi% correction for coming into single spacing
+}
+%
+\setsecheadstyle{\normalfont\msu@SingleSpacing\bfseries} % made uniform size v4
+\setsubsecheadstyle{\normalfont\msu@SingleSpacing\bfseries}
+\setsubsubsecheadstyle{\normalfont\msu@SingleSpacing\bfseries}
% 2023 requirements seem to want "uniform" spacing even after headings, even though this
% is not stated explicitly anywhere. After skips must be positive not zero to avoid runin formatting
% Before skips can be 0
@@ -811,11 +819,13 @@ chapterapp.code = {
% as chapters or as sections in the bibliography. Thesis office isn't consistent in this.
% \clearpage added 7/19/2023 because page numbers were off in the TOC.
% This code probably needs to be revisited since it’s a unholy amalgam of old and new code
+% Removed clearpage from the document level code in response to issue #26.
+% Problem seems to only arise with biblatex so more testing is needed
\newcommand\msu@addbibheadtotoc{%
\ifmsu@chapterbib
\clearpage\phantomsection\addcontentsline{toc}{\msu@bibsection}{\bibtocname}
\else
- \clearpage\phantomsection\addcontentsline{toc}{chapter}{\bibtocname}
+ \phantomsection\addcontentsline{toc}{chapter}{\bibtocname}
\fi
}
% Since the bibliography page is the TOC entry we remove the bib in the TOC
diff --git a/macros/latex/contrib/msu-thesis/msu-thesis.pdf b/macros/latex/contrib/msu-thesis/msu-thesis.pdf
index 4acc940f9f..533ec424b9 100644
--- a/macros/latex/contrib/msu-thesis/msu-thesis.pdf
+++ b/macros/latex/contrib/msu-thesis/msu-thesis.pdf
Binary files differ
diff --git a/macros/latex/contrib/msu-thesis/samples/MSU-thesis-testfile.pdf b/macros/latex/contrib/msu-thesis/samples/MSU-thesis-testfile.pdf
index c4d0e9127c..1b819b0aa0 100644
--- a/macros/latex/contrib/msu-thesis/samples/MSU-thesis-testfile.pdf
+++ b/macros/latex/contrib/msu-thesis/samples/MSU-thesis-testfile.pdf
Binary files differ
diff --git a/macros/latex/contrib/resolsysteme/doc/ResolSysteme-doc.pdf b/macros/latex/contrib/resolsysteme/doc/ResolSysteme-doc.pdf
index 317157a051..1ee7bc9bba 100644
--- a/macros/latex/contrib/resolsysteme/doc/ResolSysteme-doc.pdf
+++ b/macros/latex/contrib/resolsysteme/doc/ResolSysteme-doc.pdf
Binary files differ
diff --git a/macros/latex/contrib/resolsysteme/doc/ResolSysteme-doc.tex b/macros/latex/contrib/resolsysteme/doc/ResolSysteme-doc.tex
index b54741a518..97155dee5c 100644
--- a/macros/latex/contrib/resolsysteme/doc/ResolSysteme-doc.tex
+++ b/macros/latex/contrib/resolsysteme/doc/ResolSysteme-doc.tex
@@ -3,8 +3,8 @@
% arara: lualatex: {shell: yes, synctex: no, interaction: batchmode} if found('log', '(undefined references|Please rerun|Rerun to get)')
\documentclass[french,a4paper,11pt]{article}
-\def\TPversion{0.1.5}
-\def\TPdate{25 Février 2023}
+\def\TPversion{0.1.6}
+\def\TPdate{2 avril 2024}
\usepackage[executable=python.exe]{pyluatex}
\usepackage[table,svgnames]{xcolor}
\usepackage{amsmath,amssymb}
@@ -319,6 +319,8 @@ L'idée est ici de proposer une version, adaptée à des dimensions classiques,
\part{Historique}
+\verb|v0.1.6|~:~~~~Correction de bugs dans certains calculs.
+
\verb|v0.1.5|~:~~~~Inverse d'une matrice 4x4 et système 4x4 (même en normal).
\verb|v0.1.4|~:~~~~Ajout de commandes pour du calcul matriciel sans python (de taille raisonnable) ;
diff --git a/macros/latex/contrib/resolsysteme/doc/ResolSysteme-exemples-pyluatex.pdf b/macros/latex/contrib/resolsysteme/doc/ResolSysteme-exemples-pyluatex.pdf
index a07a5766a1..d5bc819d92 100644
--- a/macros/latex/contrib/resolsysteme/doc/ResolSysteme-exemples-pyluatex.pdf
+++ b/macros/latex/contrib/resolsysteme/doc/ResolSysteme-exemples-pyluatex.pdf
Binary files differ
diff --git a/macros/latex/contrib/resolsysteme/doc/ResolSysteme-exemples-pyluatex.tex b/macros/latex/contrib/resolsysteme/doc/ResolSysteme-exemples-pyluatex.tex
index 7f92c1e701..407a26aa3e 100644
--- a/macros/latex/contrib/resolsysteme/doc/ResolSysteme-exemples-pyluatex.tex
+++ b/macros/latex/contrib/resolsysteme/doc/ResolSysteme-exemples-pyluatex.tex
@@ -2,7 +2,7 @@
% !TeX TXS-program:compile = txs:///lualatex/[--shell-escape]
\documentclass[french,a4paper,10pt]{article}
-\def\RSver{0.1.5}
+\def\RSver{0.1.6}
\usepackage[margin=1.5cm]{geometry}
\usepackage[executable=python.exe]{pyluatex}
\usepackage[pyluatex]{ResolSysteme}
diff --git a/macros/latex/contrib/resolsysteme/doc/ResolSysteme-exemples.pdf b/macros/latex/contrib/resolsysteme/doc/ResolSysteme-exemples.pdf
index 7189d713dc..cd7b6e1fd3 100644
--- a/macros/latex/contrib/resolsysteme/doc/ResolSysteme-exemples.pdf
+++ b/macros/latex/contrib/resolsysteme/doc/ResolSysteme-exemples.pdf
Binary files differ
diff --git a/macros/latex/contrib/resolsysteme/doc/ResolSysteme-exemples.tex b/macros/latex/contrib/resolsysteme/doc/ResolSysteme-exemples.tex
index 9d785b294f..0eb228e552 100644
--- a/macros/latex/contrib/resolsysteme/doc/ResolSysteme-exemples.tex
+++ b/macros/latex/contrib/resolsysteme/doc/ResolSysteme-exemples.tex
@@ -2,7 +2,7 @@
% !TeX TXS-program:compile = txs:///pdflatex
\documentclass[french,a4paper,10pt]{article}
-\def\RSver{0.1.5}
+\def\RSver{0.1.6}
\usepackage[margin=1.5cm]{geometry}
\usepackage{ResolSysteme}
\usepackage{systeme}
diff --git a/macros/latex/contrib/resolsysteme/tex/ResolSysteme.sty b/macros/latex/contrib/resolsysteme/tex/ResolSysteme.sty
index 847d00ebe7..025ea98cfe 100644
--- a/macros/latex/contrib/resolsysteme/tex/ResolSysteme.sty
+++ b/macros/latex/contrib/resolsysteme/tex/ResolSysteme.sty
@@ -2,7 +2,8 @@
% licence........: Released under the LaTeX Project Public License v1.3c or later, see http://www.latex-project.org/lppl.txtf
\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{ResolSysteme}[2023/02/25 v0.1.5 Quelques commandes pour travailler avec des matrices et des sytemes lineaires]
+\ProvidesPackage{ResolSysteme}[2024/04/02 v0.1.6 Quelques commandes pour travailler avec des matrices et des sytemes lineaires]
+% 0.1.6 Correction de bugs dans certains calculs
% 0.1.5 Inverse d'une matrice en 4x4 (même en normal !) + Système 4x4 (en normal !)
% 0.1.4 Travail sur graphe probabiliste (2x2/3x3/4x4 en python, ou 2x2 en normal...) + Calculs 4x4 en normal
% 0.1.3 Produit matriciel + Puissance matricielle (2x2/3x3 carré en normal, 2x2/3x3/4x4 avec python) + Inversion comportement commandes étoilées
@@ -1282,13 +1283,13 @@ def etat_prob_DD(AA,BB,a,b,c,d,puiss) :
\IfBooleanTF{#1}%version étoilée := moins sur num
{%
\def\MatResA{\ConvVersFrac*[#2]{\CoeffAa*\CoeffBa+\CoeffAb*\CoeffBc}}%
- \def\MatResB{\ConvVersFrac*[#2]{\CoeffAa*\CoeffBb+\CoeffAd*\CoeffBd}}%
+ \def\MatResB{\ConvVersFrac*[#2]{\CoeffAa*\CoeffBb+\CoeffAb*\CoeffBd}}%
\def\MatResC{\ConvVersFrac*[#2]{\CoeffAc*\CoeffBa+\CoeffAd*\CoeffBc}}%
\def\MatResD{\ConvVersFrac*[#2]{\CoeffAc*\CoeffBb+\CoeffAd*\CoeffBd}}%
}%
{%
\def\MatResA{\ConvVersFrac[#2]{\CoeffAa*\CoeffBa+\CoeffAb*\CoeffBc}}%
- \def\MatResB{\ConvVersFrac[#2]{\CoeffAa*\CoeffBb+\CoeffAd*\CoeffBd}}%
+ \def\MatResB{\ConvVersFrac[#2]{\CoeffAa*\CoeffBb+\CoeffAb*\CoeffBd}}%
\def\MatResC{\ConvVersFrac[#2]{\CoeffAc*\CoeffBa+\CoeffAd*\CoeffBc}}%
\def\MatResD{\ConvVersFrac[#2]{\CoeffAc*\CoeffBb+\CoeffAd*\CoeffBd}}%
}%
diff --git a/macros/latex/contrib/schule/README b/macros/latex/contrib/schule/README
index 55cf949be6..01d7ce215e 100644
--- a/macros/latex/contrib/schule/README
+++ b/macros/latex/contrib/schule/README
@@ -12,8 +12,8 @@ sequence diagrams, object diagrams and class diagrams) as well as into
classes for written exams (tests, quizzes, teaching observations,
information sheets, worksheets, and answer keys).
------------------------------------------------------------------------
-Version: 0.9.0
-Last change: 2023/10/07
+Version: 0.10.0
+Last change: 2023/04/01
The package is still a work in progress. Open development steps are
shown in the documentation.
diff --git a/macros/latex/contrib/schule/doc/Beispiele/beispiel-ab.pdf b/macros/latex/contrib/schule/doc/Beispiele/beispiel-ab.pdf
index 645bf09dbe..f5f0a98d7f 100644
--- a/macros/latex/contrib/schule/doc/Beispiele/beispiel-ab.pdf
+++ b/macros/latex/contrib/schule/doc/Beispiele/beispiel-ab.pdf
Binary files differ
diff --git a/macros/latex/contrib/schule/doc/Beispiele/beispiel-ab.tex b/macros/latex/contrib/schule/doc/Beispiele/beispiel-ab.tex
index 5d02fbda96..e251f76463 100644
--- a/macros/latex/contrib/schule/doc/Beispiele/beispiel-ab.tex
+++ b/macros/latex/contrib/schule/doc/Beispiele/beispiel-ab.tex
@@ -67,11 +67,9 @@
\teilaufgabe Keine Aufgabe
\end{teilaufgaben}
\end{loesung}
- \begin{erwartungen}
- \erwartung{\weva gibt eine Lösung an.}{1}
- \erwartung{erfüllt eine \so{ehrlich völlig überzogene} Erwartung.}{10}
- \erwartung{gibt nicht auf.}{0}[10]
- \end{erwartungen}
+ \erwartung{\weva gibt eine Lösung an.}{1}
+ \erwartung{erfüllt eine \so{ehrlich völlig überzogene} Erwartung.}{10}
+ \erwartung{gibt nicht auf.}{0}[10]
\begin{bearbeitungshinweis}
\begin{teilaufgaben}
\teilaufgabe Man kann auch Hinweise geben.
@@ -93,19 +91,17 @@
\begin{loesung}
Eine Lösung.
\end{loesung}
- \begin{erwartungen}
- \erwartung{hat den {\LARGE Text} \textcolor{red}{gelesen}.}{1}
- \erwartung{gibt eine Lösung an.}{4}
- \erwartung{erfüllt eine ehrlich völlig überzogene Erwartung.
- \begin{tabular}{|c|c|}
- \hline
- a & b \\
- \hline
- c & d \\
- \hline
- \end{tabular}
- }{10}
- \end{erwartungen}
+ \erwartung{hat den {\LARGE Text} \textcolor{red}{gelesen}.}{1}
+ \erwartung{gibt eine Lösung an.}{4}
+ \erwartung{erfüllt eine ehrlich völlig überzogene Erwartung.
+ \begin{tabular}{|c|c|}
+ \hline
+ a & b \\
+ \hline
+ c & d \\
+ \hline
+ \end{tabular}
+ }{10}
\end{aufgabe}
\begin{aufgabe}
@@ -123,9 +119,7 @@
\teilaufgabe drittens
\end{teilaufgaben}
\end{loesung}
-% \begin{erwartungen}
-% \erwartung{sollte eine weitere \symAuge Lösung angeben.}{30}
-% \end{erwartungen}
+% \erwartung{sollte eine weitere \symAuge Lösung angeben.}{30}
\begin{bearbeitungshinweis}
Man kann auch Hinweise geben.
\begin{itemize}
@@ -149,9 +143,7 @@
\begin{loesung}
\mcloesung
\end{loesung}
- \begin{erwartungen}
- \erwartung{kreuzt \textbf{alles} richtig an.}{10}
- \end{erwartungen}
+ \erwartung{kreuzt \textbf{alles} richtig an.}{10}
\end{aufgabe}
\begin{aufgabe}[symbol=\symBleistift,subtitle={Lückentext}]
@@ -159,9 +151,7 @@
\begin{loesung}
Das ist ein total verrückter \textluecke{Lückentext}. Für alle \textluecke{Menschen}, die \textluecke{Lücken} lieben.
\end{loesung}
- \begin{erwartungen}
- \erwartung{füllt die Lücken richtig aus.}{10}
- \end{erwartungen}
+ \erwartung{füllt die Lücken richtig aus.}{10}
\end{aufgabe}
\begin{aufgabe*}
@@ -169,9 +159,7 @@
\begin{loesung*}
Eine weitere Lösung.
\end{loesung*}
- \begin{erwartungen}
- \erwartung{sollte eine $7+4=11$ weitere Lösung angeben.}{}[2]
- \end{erwartungen}
+ \erwartung{sollte eine $7+4=11$ weitere Lösung angeben.}{}[2]
\begin{bearbeitungshinweis}
Noch ein Hinweis. Und noch einer.
\end{bearbeitungshinweis}
@@ -190,9 +178,7 @@
tmp = "Hallo "
print(tmp + weltname + "!")
\end{lstlisting}
- \begin{erwartungen}
- \erwartung{Ergänzt die Funktionsaufrufe korrekt.}{10}
- \end{erwartungen}
+ \erwartung{Ergänzt die Funktionsaufrufe korrekt.}{10}
\begin{bearbeitungshinweis}
Denke gut darüber nach wie man vorgeht.
\end{bearbeitungshinweis}
diff --git a/macros/latex/contrib/schule/doc/Beispiele/beispiel-kl.pdf b/macros/latex/contrib/schule/doc/Beispiele/beispiel-kl.pdf
index c3b5cf87d7..3ed68dcf0d 100644
--- a/macros/latex/contrib/schule/doc/Beispiele/beispiel-kl.pdf
+++ b/macros/latex/contrib/schule/doc/Beispiele/beispiel-kl.pdf
Binary files differ
diff --git a/macros/latex/contrib/schule/doc/Beispiele/beispiel-kl.tex b/macros/latex/contrib/schule/doc/Beispiele/beispiel-kl.tex
index 05ad494ae9..f3330a167a 100644
--- a/macros/latex/contrib/schule/doc/Beispiele/beispiel-kl.tex
+++ b/macros/latex/contrib/schule/doc/Beispiele/beispiel-kl.tex
@@ -60,22 +60,20 @@
\begin{loesung}
\includegraphics[scale=0.8]{aufgabe-1}
\end{loesung}
- \begin{erwartungen}
- \erwartung{ermittelt die Objekte \texttt{margret}, \texttt{dieter}, \texttt{franz}, \texttt{manni}, \texttt{formular1} und \texttt{formular2}.}{3}
- \erwartung{ermittelt die Attribute \texttt{alter}, \texttt{hatFormular}, \texttt{lieblingslied} und ordnet sie korrekt zu.}{3}
- \erwartung{ermittelt die Methoden \texttt{nimmAn(formular)}, \texttt{erledigeFormalitaet} und \texttt{singeLied}.}{4}
- \erwartung{entwirft ein, der Situation entsprechendes, Objektdiagramm.}{5}
- \erwartung{stellt das Objektdiagramm den Konventionen entsprechend dar:
- \begin{smallitemize}
- \item Objektnamen klein
- \item Attributwerte groß
- \item Aufträge im Imperativ
- \item Präfixe bei den Attributen
- \item Anführungszeichen bei Zeichenketten
- \end{smallitemize}
- }{5}
- \erwartung{stellt die Beziehungen zwischen den Objekten vollständig und korrekt dar.}{5}
- \end{erwartungen}
+ \erwartung{ermittelt die Objekte \texttt{margret}, \texttt{dieter}, \texttt{franz}, \texttt{manni}, \texttt{formular1} und \texttt{formular2}.}{3}
+ \erwartung{ermittelt die Attribute \texttt{alter}, \texttt{hatFormular}, \texttt{lieblingslied} und ordnet sie korrekt zu.}{3}
+ \erwartung{ermittelt die Methoden \texttt{nimmAn(formular)}, \texttt{erledigeFormalitaet} und \texttt{singeLied}.}{4}
+ \erwartung{entwirft ein, der Situation entsprechendes, Objektdiagramm.}{5}
+ \erwartung{stellt das Objektdiagramm den Konventionen entsprechend dar:
+ \begin{smallitemize}
+ \item Objektnamen klein
+ \item Attributwerte groß
+ \item Aufträge im Imperativ
+ \item Präfixe bei den Attributen
+ \item Anführungszeichen bei Zeichenketten
+ \end{smallitemize}
+ }{5}
+ \erwartung{stellt die Beziehungen zwischen den Objekten vollständig und korrekt dar.}{5}
\end{aufgabe}
\section*{Sequenz- und Klassendiagramme}
@@ -142,16 +140,14 @@
\end{call}
\end{sequencediagram}
}
+ \erwartung{gibt die Aufträge \texttt{begutachteRoller}, \texttt{zustand} und \texttt{kostenNeu}, sowie die zugehörigen Antworten an und erweitert das Diagramm entsprechend.}{5}
\teilaufgabe Klassendiagramm:
\includegraphics[scale=0.8]{aufgabe-2}
+ \erwartung{modelliert ein zu den vorherigen Aufgaben konsistentes Klassendiagramm.}{8}
+ \erwartung{stellt das Klassendiagramm unter Berücksichtigung der geltenden Vereinbarungen korrekt dar.}{2}
\end{teilaufgaben}
\end{loesung}
- \begin{erwartungen}
- \erwartung{gibt die Aufträge \texttt{begutachteRoller}, \texttt{zustand} und \texttt{kostenNeu}, sowie die zugehörigen Antworten an und erweitert das Diagramm entsprechend.}{5}
- \erwartung{modelliert ein zu den vorherigen Aufgaben konsistentes Klassendiagramm.}{8}
- \erwartung{stellt das Klassendiagramm unter Berücksichtigung der geltenden Vereinbarungen korrekt dar.}{2}
- \end{erwartungen}
\end{aufgabe}
\begin{aufgabe}
@@ -172,10 +168,8 @@
roller.schalteAus()
\end{lstlisting}
\end{loesung}
- \begin{erwartungen}
- \erwartung{implementiert eine dem Klassendiagramm entsprechende Methode unter Verwendung der notwendigen Anfragen und Aufträge.}{8}
- \erwartung{wendet beim Implementieren die korrekte Syntax an.}{2}
- \end{erwartungen}
+ \erwartung{implementiert eine dem Klassendiagramm entsprechende Methode unter Verwendung der notwendigen Anfragen und Aufträge.}{8}
+ \erwartung{wendet beim Implementieren die korrekte Syntax an.}{2}
\end{aufgabe}
-\end{document} \ No newline at end of file
+\end{document}
diff --git a/macros/latex/contrib/schule/doc/Beispiele/bsp_aufgabe1/bsp_aufgabe_01.pdf b/macros/latex/contrib/schule/doc/Beispiele/bsp_aufgabe1/bsp_aufgabe_01.pdf
index 564095dce7..875958c447 100644
--- a/macros/latex/contrib/schule/doc/Beispiele/bsp_aufgabe1/bsp_aufgabe_01.pdf
+++ b/macros/latex/contrib/schule/doc/Beispiele/bsp_aufgabe1/bsp_aufgabe_01.pdf
Binary files differ
diff --git a/macros/latex/contrib/schule/doc/Beispiele/bsp_aufgabe1/bsp_aufgabe_01.tex b/macros/latex/contrib/schule/doc/Beispiele/bsp_aufgabe1/bsp_aufgabe_01.tex
index 994f41a4b8..d88c9d8c56 100644
--- a/macros/latex/contrib/schule/doc/Beispiele/bsp_aufgabe1/bsp_aufgabe_01.tex
+++ b/macros/latex/contrib/schule/doc/Beispiele/bsp_aufgabe1/bsp_aufgabe_01.tex
@@ -22,14 +22,12 @@
\begin{teilaufgaben}
\teilaufgabe[2] Male ein X.
+ \erwartung{malt ein X}{2}
\teilaufgabe[3] Schreibe einen Satz.
+ \erwartung{schreibt einen Satz}{2}
+ \erwartung{achtet auf die Rechtschreibung}{1}
\end{teilaufgaben}
- \begin{erwartungen}
- \erwartung{malt ein X}{2}
- \erwartung{schreibt einen Satz}{2}
- \erwartung{achtet auf die Rechtschreibung}{1}
- \end{erwartungen}
\end{aufgabe}
\begin{loesung}
\begin{teilaufgaben}
diff --git a/macros/latex/contrib/schule/doc/Beispiele/bsp_aufgabe2/bsp_aufgabe.pdf b/macros/latex/contrib/schule/doc/Beispiele/bsp_aufgabe2/bsp_aufgabe.pdf
index cfa4297177..98bb6d6a14 100644
--- a/macros/latex/contrib/schule/doc/Beispiele/bsp_aufgabe2/bsp_aufgabe.pdf
+++ b/macros/latex/contrib/schule/doc/Beispiele/bsp_aufgabe2/bsp_aufgabe.pdf
Binary files differ
diff --git a/macros/latex/contrib/schule/doc/Beispiele/bsp_aufgabe2/bsp_aufgabe.tex b/macros/latex/contrib/schule/doc/Beispiele/bsp_aufgabe2/bsp_aufgabe.tex
index 6949983ad7..5b2549411c 100644
--- a/macros/latex/contrib/schule/doc/Beispiele/bsp_aufgabe2/bsp_aufgabe.tex
+++ b/macros/latex/contrib/schule/doc/Beispiele/bsp_aufgabe2/bsp_aufgabe.tex
@@ -37,10 +37,12 @@
Aber mache etwas wirklich gutes.
}
- \begin{erwartungen}
+ \ifAufgabenpoolOptionTF{optionA}{
\erwartung{macht etwas damit}{5}
- \erwartung{lässt anderes sein}{1}
- \end{erwartungen}
+ }{
+ \erwartung{macht etwas anderes damit}{5}
+ }
+ \erwartung{lässt anderes sein}{1}
\end{aufgabe}
\begin{loesung}
Eigentlich ist es ganz egal.
diff --git a/macros/latex/contrib/schule/doc/Beispiele/minimal-ab-dev.pdf b/macros/latex/contrib/schule/doc/Beispiele/minimal-ab-dev.pdf
index 53cc4fabc2..7e4d30029d 100644
--- a/macros/latex/contrib/schule/doc/Beispiele/minimal-ab-dev.pdf
+++ b/macros/latex/contrib/schule/doc/Beispiele/minimal-ab-dev.pdf
Binary files differ
diff --git a/macros/latex/contrib/schule/doc/Beispiele/minimal-ab-dev.tex b/macros/latex/contrib/schule/doc/Beispiele/minimal-ab-dev.tex
index a2225d8f00..f311d1d4c0 100644
--- a/macros/latex/contrib/schule/doc/Beispiele/minimal-ab-dev.tex
+++ b/macros/latex/contrib/schule/doc/Beispiele/minimal-ab-dev.tex
@@ -172,9 +172,7 @@
\end{teilaufgaben}
\end{loesung*}
- \begin{erwartungen}
- \erwartung{sollte eine $7+4=11$ weitere Lösung angeben.}{}[2]
- \end{erwartungen}
+ \erwartung{sollte eine $7+4=11$ weitere Lösung angeben.}{}[2]
\begin{bearbeitungshinweis}
Noch ein Hinweis.
\end{bearbeitungshinweis}
@@ -238,4 +236,4 @@
\section*{Notenverteilung}
\notenverteilung
-\end{document} \ No newline at end of file
+\end{document}
diff --git a/macros/latex/contrib/schule/doc/Beispiele/minimal-ab.pdf b/macros/latex/contrib/schule/doc/Beispiele/minimal-ab.pdf
index c309a0d318..dfac2e9c64 100644
--- a/macros/latex/contrib/schule/doc/Beispiele/minimal-ab.pdf
+++ b/macros/latex/contrib/schule/doc/Beispiele/minimal-ab.pdf
Binary files differ
diff --git a/macros/latex/contrib/schule/doc/Beispiele/minimal-ab.tex b/macros/latex/contrib/schule/doc/Beispiele/minimal-ab.tex
index d1d3a792bf..7598a61919 100644
--- a/macros/latex/contrib/schule/doc/Beispiele/minimal-ab.tex
+++ b/macros/latex/contrib/schule/doc/Beispiele/minimal-ab.tex
@@ -101,4 +101,4 @@
\section*{Notenverteilung}
\notenverteilung
-\end{document} \ No newline at end of file
+\end{document}
diff --git a/macros/latex/contrib/schule/doc/Beispiele/minimal-ka.pdf b/macros/latex/contrib/schule/doc/Beispiele/minimal-ka.pdf
index d5b6f2e05e..ceb9444c50 100644
--- a/macros/latex/contrib/schule/doc/Beispiele/minimal-ka.pdf
+++ b/macros/latex/contrib/schule/doc/Beispiele/minimal-ka.pdf
Binary files differ
diff --git a/macros/latex/contrib/schule/doc/Beispiele/minimal-ka.tex b/macros/latex/contrib/schule/doc/Beispiele/minimal-ka.tex
index 4e93eebe3c..8605b2a2fc 100644
--- a/macros/latex/contrib/schule/doc/Beispiele/minimal-ka.tex
+++ b/macros/latex/contrib/schule/doc/Beispiele/minimal-ka.tex
@@ -32,15 +32,13 @@
\blindtext
\begin{teilaufgaben}
\teilaufgabe Lies den Text!
+ \erwartung{Du hast den Text gelesen.}{}
\teilaufgabe Unterschlängele alle Nomen.
+ \erwartung{Du hast alle alle Nomen unterschlängelt.}{}
\end{teilaufgaben}
\begin{loesung}
Dies hier ist ein \uwave{Blindtext} zum \uwave{Testen} von \uwave{Textausgaben}\dots
\end{loesung}
- \begin{erwartungen}
- \erwartung{Du hast den Text gelesen.}{}
- \erwartung{Du hast alle alle Nomen unterschlängelt.}{}
- \end{erwartungen}
\end{aufgabe}
\begin{aufgabe*}
@@ -52,16 +50,14 @@
\begin{loesung*}
\begin{teilaufgaben}
\teilaufgabe Die Lösung lautet 1.
+ \erwartung{Deine Lösung zu Teilaufgabe a) ist richtig.}{}
\teilaufgabe Die Lösung lautet 2.
+ \erwartung{Deine Lösung zu Teilaufgabe b) ist richtig.}{}
\end{teilaufgaben}
\end{loesung*}
- \begin{erwartungen}
- \erwartung{Deine Lösung zu Teilaufgabe a) ist richtig.}{}
- \erwartung{Deine Lösung zu Teilaufgabe b) ist richtig.}{}
- \end{erwartungen}
\end{aufgabe*}
\vspace{1cm}
{\Huge Viel Erfolg!}
-\end{document} \ No newline at end of file
+\end{document}
diff --git a/macros/latex/contrib/schule/doc/Beispiele/minimal-kl-aufgabenpool.pdf b/macros/latex/contrib/schule/doc/Beispiele/minimal-kl-aufgabenpool.pdf
index 6be283a536..803354db15 100644
--- a/macros/latex/contrib/schule/doc/Beispiele/minimal-kl-aufgabenpool.pdf
+++ b/macros/latex/contrib/schule/doc/Beispiele/minimal-kl-aufgabenpool.pdf
Binary files differ
diff --git a/macros/latex/contrib/schule/doc/Beispiele/minimal-kl-et.pdf b/macros/latex/contrib/schule/doc/Beispiele/minimal-kl-et.pdf
index 40d6aec8bb..43c864b13c 100644
--- a/macros/latex/contrib/schule/doc/Beispiele/minimal-kl-et.pdf
+++ b/macros/latex/contrib/schule/doc/Beispiele/minimal-kl-et.pdf
Binary files differ
diff --git a/macros/latex/contrib/schule/doc/Beispiele/minimal-kl-et.tex b/macros/latex/contrib/schule/doc/Beispiele/minimal-kl-et.tex
index 4f40e73ef0..3338b8fc8b 100644
--- a/macros/latex/contrib/schule/doc/Beispiele/minimal-kl-et.tex
+++ b/macros/latex/contrib/schule/doc/Beispiele/minimal-kl-et.tex
@@ -32,15 +32,13 @@
\blindtext
\begin{teilaufgaben}
\teilaufgabe[5] Lies den Text!
+ \erwartung{hat den Text gelesen.}{5}
\teilaufgabe[10] Nimm dazu begründet Stellung.
+ \erwartung{nimmt begründet Stellung zum Text und berücksichtigt, dass es sich um einen Blindtext handelt.}{10}
\end{teilaufgaben}
\begin{loesung}
Es handelt sich eindeutig um einen Blindtext.
\end{loesung}
- \begin{erwartungen}
- \erwartung{hat den Text gelesen.}{5}
- \erwartung{nimmt begründet Stellung zum Text und berücksichtigt, dass es sich um einen Blindtext handelt.}{10}
- \end{erwartungen}
\end{aufgabe}
\begin{aufgabe*}
@@ -52,16 +50,14 @@
\begin{loesung*}
\begin{teilaufgaben}
\teilaufgabe Die Lösung lautet 1.
+ \erwartung{gibt eine richtige Lösung zu Teilaufgabe a) an.}{}[5]
\teilaufgabe Die Lösung lautet 2.
+ \erwartung{gibt eine richtige Lösung zu Teilaufgabe b) an.}{}[5]
\end{teilaufgaben}
\end{loesung*}
- \begin{erwartungen}
- \erwartung{gibt eine richtige Lösung zu Teilaufgabe a) an.}{}[5]
- \erwartung{gibt eine richtige Lösung zu Teilaufgabe b) an.}{}[5]
- \end{erwartungen}
\end{aufgabe*}
\vspace{1cm}
{\Huge Viel Erfolg!}
-\end{document} \ No newline at end of file
+\end{document}
diff --git a/macros/latex/contrib/schule/doc/Beispiele/minimal-kl.pdf b/macros/latex/contrib/schule/doc/Beispiele/minimal-kl.pdf
index 75732e79a1..753d9ec46b 100644
--- a/macros/latex/contrib/schule/doc/Beispiele/minimal-kl.pdf
+++ b/macros/latex/contrib/schule/doc/Beispiele/minimal-kl.pdf
Binary files differ
diff --git a/macros/latex/contrib/schule/doc/Beispiele/minimal-kl.tex b/macros/latex/contrib/schule/doc/Beispiele/minimal-kl.tex
index af132ce73f..7e38c73f99 100644
--- a/macros/latex/contrib/schule/doc/Beispiele/minimal-kl.tex
+++ b/macros/latex/contrib/schule/doc/Beispiele/minimal-kl.tex
@@ -31,15 +31,13 @@
\blindtext
\begin{teilaufgaben}
\teilaufgabe[5] Lies den Text!
+ \erwartung{hat den Text gelesen.}{5}
\teilaufgabe[10] Nimm dazu begründet Stellung.
+ \erwartung{nimmt begründet Stellung zum Text und berücksichtigt, dass es sich um einen Blindtext handelt.}{10}
\end{teilaufgaben}
\begin{loesung}
Es handelt sich eindeutig um einen Blindtext.
\end{loesung}
- \begin{erwartungen}
- \erwartung{hat den Text gelesen.}{5}
- \erwartung{nimmt begründet Stellung zum Text und berücksichtigt, dass es sich um einen Blindtext handelt.}{10}
- \end{erwartungen}
\end{aufgabe}
\begin{aufgabe*}
@@ -51,13 +49,11 @@
\begin{loesung*}
\begin{teilaufgaben}
\teilaufgabe Die Lösung lautet 1.
+ \erwartung{gibt eine richtige Lösung zu Teilaufgabe a) an.}{}[5]
\teilaufgabe Die Lösung lautet 2.
+ \erwartung{gibt eine richtige Lösung zu Teilaufgabe b) an.}{}[5]
\end{teilaufgaben}
\end{loesung*}
- \begin{erwartungen}
- \erwartung{gibt eine richtige Lösung zu Teilaufgabe a) an.}{}[5]
- \erwartung{gibt eine richtige Lösung zu Teilaufgabe b) an.}{}[5]
- \end{erwartungen}
\end{aufgabe*}
\vspace{1cm}
@@ -66,4 +62,4 @@
\vfill
\punktuebersicht
-\end{document} \ No newline at end of file
+\end{document}
diff --git a/macros/latex/contrib/schule/doc/changelog.tex b/macros/latex/contrib/schule/doc/changelog.tex
index 149be23c76..d11563f2bf 100644
--- a/macros/latex/contrib/schule/doc/changelog.tex
+++ b/macros/latex/contrib/schule/doc/changelog.tex
@@ -2,6 +2,12 @@
Im Laufe der Jahre wurde das Paket immer wieder erweitert. Nicht nur die Anpassung an veränderte Anforderungen, etwa bei den Unterrichtsbesuchen, sondern auch neue Funktionalitäten fließen in das Paket ein.
Die folgende Liste bietet eine Übersicht über die letzten Änderungen.
\begin{itemize}
+ \item \textbf{0.10.0} -- 2024-04-01
+ \begin{itemize}
+ \item Das Modul Aufgabenpool um Möglichkeiten für Anhänge erweitert
+ \item Einbinden von Erwartungen für den Erwartungshorizont flexibler gestaltet
+ \item Bugfix
+ \end{itemize}
\item \textbf{0.9.0} -- 2023-10-07
\begin{itemize}
\item Modul Aufgabenpool ausgebaut, damit es variable einsetzbar ist
diff --git a/macros/latex/contrib/schule/doc/modulAufgabenpool.tex b/macros/latex/contrib/schule/doc/modulAufgabenpool.tex
index 9b736eb0f6..750ac6c2cd 100644
--- a/macros/latex/contrib/schule/doc/modulAufgabenpool.tex
+++ b/macros/latex/contrib/schule/doc/modulAufgabenpool.tex
@@ -41,3 +41,21 @@ Zu jeder Aufgabe lassen sich einstellbare Optionen angeben. Mit diesen kann man
\command{setAufgabenpoolOptionen}[\marg{Optionennamen}]
Dieses kann im Kopf der Aufgabendatei genutzt werden, um die Optionen zu setzen. So lassen sich die verschiedenen Ansichten bereits im Aufgabendokument anzeigen.
\end{commands}
+
+\subsection{Anhänge an Aufgaben}\sinceversion{0.10.0}
+Bei der Nutzung des Aufgabenpools kann es vorkommen, dass Aufgaben auch Elemente haben, die im Anhang angegeben werden. Teilweise können auch mehrere Aufgaben den gleichen Anhang nutzen. Daher werden zwei verschiedene Möglichkeiten zum Einbinden von Anhängen bereitgestellt. Die Ausgabe des Anhangs wird dann unterdrückt, wenn der Aufruf des Anhangs sich innerhalb einer eingebundenen Aufgabendatei befindet. Für das Gesamtdokument gibt es mit \cs{showIncludeAppendix} einen extra Befehl, der dann für die Ausgabe sorgt.
+
+\subsubsection{Umgebungen}
+\begin{environments}
+ \environment{onceAppendix}[\marg{Name}]
+ Innerhalb der Umgebung kann Inhalt für den Anhang angegeben werden. Durch die Angabe des Namens wird dafür gesorgt, dass Anhang mit gleichem Namen nur einmal ausgegeben wird.
+\end{environments}
+
+\subsubsection{Befehle}
+\begin{commands}
+ \command{inputOnceAppendix}[\marg{Datei}]
+ Eine Datei kann, mit \cs{getBasedir} für den Dateipfad, angegeben werden. Diese wird nur einmal als Anhang eingebunden in das Dokument.
+
+ \command{showIncludeAppendix}
+ Der Befehl wird an einer Stelle verwendet, an der die Anhänge eingebunden werden sollen.
+\end{commands}
diff --git a/macros/latex/contrib/schule/doc/modulBewertung.tex b/macros/latex/contrib/schule/doc/modulBewertung.tex
index b73d348842..fd48af2a27 100644
--- a/macros/latex/contrib/schule/doc/modulBewertung.tex
+++ b/macros/latex/contrib/schule/doc/modulBewertung.tex
@@ -42,12 +42,12 @@ Das Modul \module{Bewertung} ergänzt das Modul \module{Aufgaben} um die Möglic
\subsubsection{Umgebungen}
\begin{environments}
- \environment{erwartungen} erlaubt es, zu einzelnen Aufgaben Erwartungen anzugeben. Die einzelnen Erwartungen werden dabei mit dem Makro \cs{erwartung} angegeben. Diese Umgebung kann nur direkt innerhalb der Umgebung einer Aufgabe genutzt werden.
+ \environment{erwartungen} \deprecatedversion{0.10.0} Diese Umgebung wird nicht mehr für Erwartungen benötigt und gibt eine Warnung aus.
\end{environments}
\subsubsection{Befehle}
\begin{commands}
- \command{erwartung}[\marg{Erwartung}\marg{Punkte}\oarg{Zusatzpunkte}] definiert eine einzelne Erwartung innerhalb der Umgebung \env{erwartungen}. Der Parameter kann beliebigen \LaTeX-Code enthalten bis auf Verbatim-Elemente. Des weiteren werden die Punkte für diese Erwartung als Parameter erwartet. Als optionalen Parameter können Zusatzpunkte angegeben werden.
+ \command{erwartung}[\marg{Erwartung}\marg{Punkte}\oarg{Zusatzpunkte}] definiert eine einzelne Erwartung, die innerhalb einer \env{aufgabe} oder einer \env{loesung} angegeben werden muss. Der Parameter kann beliebigen \LaTeX-Code enthalten bis auf Verbatim-Elemente. Des weiteren werden die Punkte für diese Erwartung als Parameter erwartet. Als optionalen Parameter können Zusatzpunkte angegeben werden. Wird die Erwartung innerhalb einer \env{teilaufgaben}-Umgebung eingefügt, so bekommt die Erwartung die Nummer der Teilaufgabe mit.
\command{erwartungshorizont} setzt den Erwartungshorizont im gewählten Stil, falls die automatische Erzeugung über die Paketoption \option{erwartungshorizontAnzeigen} nicht genutzt wird.
\command{notenverteilung} setzt die Notenverteilung, falls die automatische Erzeugung über den Erwartungshorizont nicht genutzt wird. Die Verteilung wird über die Gesamtpunkte aller Aufgaben unter Berücksichtigung des gewählten Notenschemas ermittelt.
\end{commands}
diff --git a/macros/latex/contrib/schule/doc/modulSymbole.tex b/macros/latex/contrib/schule/doc/modulSymbole.tex
index 9ffd841a55..0d11875549 100644
--- a/macros/latex/contrib/schule/doc/modulSymbole.tex
+++ b/macros/latex/contrib/schule/doc/modulSymbole.tex
@@ -105,7 +105,7 @@ Dieses Modul stellt einige für den Schulkontext relevante Unicode-Symbole aus d
\command{symKeineGlocke}
{\Huge\usym{1F515}} (1F515)
\command{symLupe}
- {\Huge\usym{1F5FD}} (1F5FD)
+ {\Huge\usym{1F50D}} (1F50D)
\end{commands}
@@ -378,4 +378,4 @@ Dieses Modul stellt einige für den Schulkontext relevante Unicode-Symbole aus d
\command{symWuerfelSechs}
{\Huge\usym{2685}} (2685)
\end{commands}
-\end{multicols} \ No newline at end of file
+\end{multicols}
diff --git a/macros/latex/contrib/schule/doc/schule.pdf b/macros/latex/contrib/schule/doc/schule.pdf
index 1129996f96..95c6c626c7 100644
--- a/macros/latex/contrib/schule/doc/schule.pdf
+++ b/macros/latex/contrib/schule/doc/schule.pdf
Binary files differ
diff --git a/macros/latex/contrib/schule/doc/schule.tex b/macros/latex/contrib/schule/doc/schule.tex
index e2621da5a5..01029dbc1d 100644
--- a/macros/latex/contrib/schule/doc/schule.tex
+++ b/macros/latex/contrib/schule/doc/schule.tex
@@ -52,8 +52,8 @@
\setcnltx{
name = schule ,
title = schule ,
- version = 0.9.0 ,
- date = 2023-10-07 ,
+ version = 0.10.0 ,
+ date = 2024-04-01 ,
subtitle = {\LaTeX-Klassen und Pakete für den Einsatz im Bereich der Schule},
info = Paketdokumentation ,
authors = {Johannes Pieper, Johannes Kuhaupt, Ludger Humbert, Andr\'e Hilbig, Adrian Salamon, Daniel Spittank} ,
@@ -73,6 +73,7 @@
}
},
}
+\newnote*\deprecatedversion[1]{\mbox{Veraltet} seit~#1}
% \includeonly{module}
diff --git a/macros/latex/contrib/schule/latex/schule.mod.Aufgaben.code.tex b/macros/latex/contrib/schule/latex/schule.mod.Aufgaben.code.tex
index 1ea304ecf4..0dcbcbbea6 100644
--- a/macros/latex/contrib/schule/latex/schule.mod.Aufgaben.code.tex
+++ b/macros/latex/contrib/schule/latex/schule.mod.Aufgaben.code.tex
@@ -77,7 +77,7 @@
\DeclareExerciseTranslation{German}{default-heading}{%
\XSIMmixedcase{\GetExerciseParameter{solution-name}}en zu den
\XSIMmixedcase{\GetExerciseParameter{exercise-name}}%
- \XSIMifeqF{\GetExerciseParameter{exercise-name}}{Aufgabe}{}n%
+ \XSIMifeqF{\GetExerciseParameter{exercise-env}}{aufgabe}{\XSIMifeqF{\GetExerciseParameter{exercise-env}}{aufgabe*}{e}}n%
}
\DeclareExerciseTranslation{German}{collection-heading}{%
@@ -100,24 +100,26 @@
}
-
% Teilaufgaben
% --------------------------------------------------------------------
-\newcounter{teilpunkte}
+\ExplSyntaxOn
+\bool_new:N \g__schule_in_teilaufgaben_bool
+\bool_gset_false:N \g__schule_in_teilaufgaben_bool
\@ifclassloaded{beamer}{
\newenvironment{teilaufgaben}{\begin{enumerate}[a)]
}{\end{enumerate}}
}{
- \newlist{teilaufgaben}{enumerate}{1}
- \setlist[teilaufgaben]{
- label=\textbf{\alph{teilaufgabeni})},
+ \newlist{teilaufgabenIntern}{enumerate}{1}
+ \setlist[teilaufgabenIntern]{
+ label=\textbf{\alph{teilaufgabenInterni})},
topsep=0.2em,
itemsep=-0.1em,
}
+ \newenvironment{teilaufgaben}%
+ {\bool_gset_true:N \g__schule_in_teilaufgaben_bool \begin{teilaufgabenIntern}}
+ {\end{teilaufgabenIntern} \bool_gset_false:N \g__schule_in_teilaufgaben_bool}
}
-\newcommand{\Teilpunkte}{\arabic{teilpunkte}}
-
\makeatletter
\NewDocumentCommand{\teilaufgabe}{o}{
\IfInsideSolutionTF{
@@ -131,7 +133,9 @@
}
% Gedacht, wenn es bei Teilaufgaben kein Lösung angegeben werden soll
-\newcommand{\teilaufgabeOhneLoesung}{\addtocounter{teilaufgabeni}{1}}
+\newcommand{\teilaufgabeOhneLoesung}{\addtocounter{teilaufgabenInterni}{1}}
+
+\ExplSyntaxOff
% Spezielle Aufgabentypen
% ********************************************************************
diff --git a/macros/latex/contrib/schule/latex/schule.mod.Aufgabenpool.code.tex b/macros/latex/contrib/schule/latex/schule.mod.Aufgabenpool.code.tex
index 76e66d9795..33579f61b4 100644
--- a/macros/latex/contrib/schule/latex/schule.mod.Aufgabenpool.code.tex
+++ b/macros/latex/contrib/schule/latex/schule.mod.Aufgabenpool.code.tex
@@ -5,15 +5,15 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\clist_new:N \g__schule_aufgabenoptionen_clist
-\DeclareDocumentCommand{\ifAufgabenpoolOptionTF}{m m m}{
+\DeclareDocumentCommand{\ifAufgabenpoolOptionTF}{m +m +m}{
\clist_if_in:NnTF \g__schule_aufgabenoptionen_clist {#1} {#2} {#3}
}
-\DeclareDocumentCommand{\ifAufgabenpoolOptionT}{m m}{
+\DeclareDocumentCommand{\ifAufgabenpoolOptionT}{m +m}{
\clist_if_in:NnT \g__schule_aufgabenoptionen_clist {#1} {#2}
}
-\DeclareDocumentCommand{\ifAufgabenpoolOptionF}{m m}{
+\DeclareDocumentCommand{\ifAufgabenpoolOptionF}{m +m}{
\clist_if_in:NnF \g__schule_aufgabenoptionen_clist {#1} {#2}
}
@@ -46,21 +46,21 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Aufgabenhinweise
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\bool_new:N \g__schule_aufgabenhinweis_bool
-\bool_gset_true:N \g__schule_aufgabenhinweis_bool
+\bool_new:N \g__schule_inAufgabenInput_bool
+\bool_gset_false:N \g__schule_inAufgabenInput_bool
\NewDocumentEnvironment{aufgabenpoolHinweis}{+b}{
- \bool_if:NT \g__schule_aufgabenhinweis_bool {#1}
+ \bool_if:NF \g__schule_inAufgabenInput_bool {#1}
}{}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Aufgabeneinbindung
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\DeclareDocumentCommand{\aufgabeninput}{o m m}{
- \bool_gset_false:N \g__schule_aufgabenhinweis_bool
+ \bool_gset_true:N \g__schule_inAufgabenInput_bool
\str_gset:Nn \g__schule_basedir_string {#2}
\clist_set:Nn \g__schule_aufgabenoptionen_clist {#1}
\input{#2/#3}
- \bool_gset_true:N \g__schule_aufgabenhinweis_bool
+ \bool_gset_false:N \g__schule_inAufgabenInput_bool
}
\xsimsetup{
@@ -72,6 +72,9 @@
% InputOnce
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\clist_new:N \g__schule_inputonce_clist
+\clist_new:N \g__schule_inputonceAppendix_clist
+\prop_new:N \g__schule_appendix_prop
+\prop_new:N \g__schule_appendixBasedir_prop
\DeclareDocumentCommand{\inputOnce}{m}{
\clist_if_in:NnF \g__schule_inputonce_clist {#1} {
@@ -80,4 +83,29 @@
}
}
+\DeclareDocumentCommand{\inputOnceAppendix}{m}{
+ \exp_args:Nnf \clist_if_in:NnF {\g__schule_inputonceAppendix_clist} {\getBasedir/#1} {
+ \exp_args:Nnf \clist_gput_right:Nx {\g__schule_inputonceAppendix_clist} {\getBasedir/#1}
+ \bool_if:NF \g__schule_inAufgabenInput_bool {\input{\getBasedir/#1}}
+ }
+}
+
+\DeclareDocumentCommand{\showIncludeAppendix}{}{
+ \clist_map_inline:Nn \g__schule_inputonceAppendix_clist {
+ \input{##1}
+ }
+ \prop_map_inline:Nn \g__schule_appendix_prop {
+ \exp_args:Nnf \str_gset:Nn \g__schule_basedir_string {\prop_item:Nn \g__schule_appendixBasedir_prop {##1}}
+ ##2
+ }
+}
+
+\NewDocumentEnvironment{onceAppendix}{m +b}{
+ \prop_gput:Nnn \g__schule_appendix_prop {#1} {#2}
+ \exp_args:Nnnf \prop_gput:Nnn {\g__schule_appendixBasedir_prop} {#1} {\getBasedir}
+ \bool_if:NF \g__schule_inAufgabenInput_bool {
+ #2
+ }
+}{}
+
\ExplSyntaxOff
diff --git a/macros/latex/contrib/schule/latex/schule.mod.Bewertung.code.tex b/macros/latex/contrib/schule/latex/schule.mod.Bewertung.code.tex
index ef906573a3..2483e825e0 100644
--- a/macros/latex/contrib/schule/latex/schule.mod.Bewertung.code.tex
+++ b/macros/latex/contrib/schule/latex/schule.mod.Bewertung.code.tex
@@ -10,13 +10,7 @@
% ********************************************************************
% Erwartungen *
% ********************************************************************
-% Zur Speicherung der Erwartungen werden die Eigenschaften von xsim
-% Aufgaben erweitert. Hierzu ist es erforderlich, dass die Inhalte
-% der Umgebung expandiert oder serialisiert (detokenized) werden
-% und dem "SetExerciseProperty"-Makro als Wert für den Schlüssel
-% "erwartungen" übergeben werden.
-% Um den folgenden Quelltext halbwegs lesbar zu halten, wird auf
-% das environ-Paket zurückgegriffen und viele Dinge aus LaTeX3 genutzt.
+% Zur Speicherung der Erwartungen werden extra Tokenlisten erstellt.
\ExplSyntaxOn
@@ -32,12 +26,27 @@
% Erwartungen-Umgebung
% ********************************************************************
+\msg_new:nnn {schule}{erwartungen}{Deprecated: erwartungen-Umgebung~wird~nicht~mehr~benoetigt}
\NewEnviron{erwartungen}{
- \exp_args:Nno\SetExerciseProperty{erwartungen}{\BODY}
+ % Kann auf Dauer entfernt werden, da es nur in der überarbeiteten Version benötigt wurde
+ \msg_warning:nn{schule} {erwartungen}
+ \BODY
}
-% Einzelerwartung in Form bringen
+\cs_new_protected:Nn \l_schule_erwartungen_einfuegen:nnnn {
+ \tl_if_exist:cF {l_schule_erwartung{\ExerciseType}!{\ExerciseID}_tl} {\tl_new:c {l_schule_erwartung{\ExerciseType}!{\ExerciseID}_tl}}
+ \tl_gput_right:co {l_schule_erwartung{\ExerciseType}!{\ExerciseID}_tl} {\l_schule_erwartungen_ausgabe:nnnn {#1}{#2}{#3}{#4}}
+}
+\cs_generate_variant:Nn \l_schule_erwartungen_einfuegen:nnnn {nnne}
+
\NewDocumentCommand{\erwartung}{m m O{}}{%
+ \bool_if:NTF \g__schule_in_teilaufgaben_bool
+ {\l_schule_erwartungen_einfuegen:nnne {#1} {#2} {#3} {\alph{teilaufgabenInterni}}}
+ {\l_schule_erwartungen_einfuegen:nnne {#1} {#2} {#3} {}}
+}
+
+% Einzelerwartung in Form bringen
+\cs_new_protected:Nn \l_schule_erwartungen_ausgabe:nnnn {%
%Zeilenfarbe
\bool_if:NTF \schule_erwartungen_zeile_gerade_bool {
\bool_gset_false:N \schule_erwartungen_zeile_gerade_bool
@@ -49,13 +58,15 @@
\IfEqCase{\schule@erwartungshorizontStil}{
{simpel}{
- \tl_gput_right:Nn \schule_zeilen_erwartungen_str {\detokenize{#1 & & & \\ \hline}}
+ \str_if_eq:nnF {#4} {} {\tl_gput_right:Nn \schule_zeilen_erwartungen_str {\detokenize{#4)~}}}
+ \tl_gput_right:Nn \schule_zeilen_erwartungen_str {\detokenize{#4)~ #1 & & & \\ \hline}}
}%
}[%
% Standard oder Einzel
\int_gadd:Nn \schule_aufgaben_punkte_int {\_str_to_int_with_zero:n{#2}} %Punkte
\int_gadd:Nn \schule_aufgaben_zusatzpunkte_int {\_str_to_int_with_zero:n{#3}} %Zusatzpunkte
+ \str_if_eq:nnF {#4} {} {\tl_gput_right:Nn \schule_zeilen_erwartungen_str {\detokenize{#4)~}}}
\tl_gput_right:Nn \schule_zeilen_erwartungen_str {\detokenize{#1 & }}
\tl_gput_right:Nn \schule_zeilen_erwartungen_str {\_schule_punkte_anzeige:nn {\_str_to_int_with_zero:n{#2}}{\_str_to_int_with_zero:n{#3}}} %Punkte
\tl_gput_right:Nn \schule_zeilen_erwartungen_str {\detokenize{ & \\ \hline}} %Zeile
@@ -119,7 +130,7 @@
%Definition der Aufgabe in entsprechende Befehle laden
\def\ExerciseType{##1}%
\def\ExerciseID{##2}%
- \GetExercisePropertyTF{erwartungen}{\PropertyValue}{}
+ \tl_if_exist:cT {l_schule_erwartung{\ExerciseType}!{\ExerciseID}_tl} {\tl_use:c {l_schule_erwartung{\ExerciseType}!{\ExerciseID}_tl}}
%Punkte setzen
\_schule_erwartungen_punkte_speichern
@@ -180,7 +191,7 @@
%Definition der Aufgabe in entsprechende Befehle laden
\def\ExerciseType{##1}%
\def\ExerciseID{##2}%
- \GetExercisePropertyTF{erwartungen}{\PropertyValue}{}
+ \tl_if_exist:cT {l_schule_erwartung{\ExerciseType}!{\ExerciseID}_tl} {\tl_use:c {l_schule_erwartung{\ExerciseType}!{\ExerciseID}_tl}}
%Gesamtaufgabe
\tl_gput_right:Nx \schule_aufgaben_erwartungen_str \_schule_aufgaben_erwartungen_zeile
@@ -237,7 +248,7 @@
%Definition der Aufgabe in entsprechende Befehle laden
\def\ExerciseType{##1}%
\def\ExerciseID{##2}%
- \GetExercisePropertyTF{erwartungen}{\PropertyValue}{}
+ \tl_if_exist:cT {l_schule_erwartung{\ExerciseType}!{\ExerciseID}_tl} {\tl_use:c {l_schule_erwartung{\ExerciseType}!{\ExerciseID}_tl}}
%Gesamtaufgabe
\tl_gput_right:Nx \schule_aufgaben_erwartungen_str \_schule_aufgaben_erwartungen_zeile_simple
diff --git a/macros/latex/contrib/schule/latex/schule.mod.Symbole.code.tex b/macros/latex/contrib/schule/latex/schule.mod.Symbole.code.tex
index deb993ec0c..1ed69a988e 100644
--- a/macros/latex/contrib/schule/latex/schule.mod.Symbole.code.tex
+++ b/macros/latex/contrib/schule/latex/schule.mod.Symbole.code.tex
@@ -47,7 +47,7 @@
\newcommand{\symSchluessel}{\usym{1F511}}
\newcommand{\symGlocke}{\usym{1F514}}
\newcommand{\symKeineGlocke}{\usym{1F515}}
-\newcommand{\symLupe}{\usym{1F5FD}}
+\newcommand{\symLupe}{\usym{1F50D}}
% Musik
\newcommand{\symNote}{\usym{1F39C}}
@@ -184,4 +184,4 @@
\newcommand{\symWuerfelDrei}{\usym{2682}}
\newcommand{\symWuerfelVier}{\usym{2683}}
\newcommand{\symWuerfelFuenf}{\usym{2684}}
-\newcommand{\symWuerfelSechs}{\usym{2685}} \ No newline at end of file
+\newcommand{\symWuerfelSechs}{\usym{2685}}
diff --git a/macros/latex/contrib/schule/latex/schule.sty b/macros/latex/contrib/schule/latex/schule.sty
index ac95a93be7..d94eed218d 100644
--- a/macros/latex/contrib/schule/latex/schule.sty
+++ b/macros/latex/contrib/schule/latex/schule.sty
@@ -1,5 +1,5 @@
\NeedsTeXFormat{LaTeX2e}[2011/11/11]
-\ProvidesPackage{schule}[2023/10/07 v0.9.0 %
+\ProvidesPackage{schule}[2023/04/01 v0.10.0 %
Kommandos fuer die Schule]
% ********************************************************************
diff --git a/macros/luatex/generic/minim-mp/README b/macros/luatex/generic/minim-mp/README
index 372e9626e1..bf03e5114e 100644
--- a/macros/luatex/generic/minim-mp/README
+++ b/macros/luatex/generic/minim-mp/README
@@ -1,9 +1,9 @@
-Version: 2024/1.5
+Version: 2024/1.6
SUMMARY
-This package offers low-level mplib integration for plain LuaTeX and is
-designed with the purpose of being easy to extend.
+This package offers low-level mplib integration for both plain LuaTeX and
+LuaLaTeX. It is designed with the purpose of being easy to extend.
The use of multiple simultaneous MetaPost instances is supported, as well as
running TeX or lua code from within MetaPost. With the included minim-mp
@@ -17,9 +17,47 @@ In order to obtain the typeset manual of this package, simply say:
luatex minim-mp.doc
+INSTALLATION
+
+In order to use minim-mp as a stand-alone metapost compiler, you will have to
+generate the appropriate format files. For metapost with plain tex, say
+
+ luatex --ini minim-mp.ini
+
+For metapost with latex, say
+
+ luatex --ini minim-lamp.ini
+
+The resulting format (.fmt) files will be found if they are either in the same
+directory as your metapost source file, or in ${TEXMFHOME}/web2c/luatex (the
+latter is of course recommended).
+
+Useful shell aliases are
+
+ alias mpost='luatex --fmt=minim-mp'
+ alias lampost='luatex --fmt=minim-lamp'
+
+
HISTORY
-2025/1.5 (in development)
+2024/1.6 (25/3/2024)
+
+ New features:
+
+ * Add per-instance \everymp token lists
+ * Reduce the number of metapost error messages echoed to the terminal.
+ * The operators infont and glyph of now also accept font names.
+ * Provide \mpdim to latex class.
+
+ Bug fixes:
+
+ * Newlines are now handled by metapost too.
+ * As are all special characters: #$%^&_~
+ * Plain and luatex now use the same catcode regime.
+ * Add the missing tex.skip macro.
+ * Improve debugging messages.
+
+2024/1.5 (25/2/2024)
New features:
@@ -33,9 +71,9 @@ HISTORY
2024/1.4 (5/1/2024)
- * Support the extended graphics state (extgstate)
- * Allow box resource (xform) creation directly from metapost
- * Support transparency and transparency groups
+ * Support the extended graphics state (extgstate).
+ * Allow box resource (xform) creation directly from metapost.
+ * Support transparency and transparency groups.
2023/1.3 (20/10/2023)
diff --git a/macros/luatex/generic/minim-mp/minim-mp.doc b/macros/luatex/generic/minim-mp/minim-mp.doc
index 0cd4ff574e..9b4806807d 100644
--- a/macros/luatex/generic/minim-mp/minim-mp.doc
+++ b/macros/luatex/generic/minim-mp/minim-mp.doc
@@ -8,8 +8,8 @@
\else \startmetadata
author {Esger Renkema}
title {minim-mp}
- date {2024-02-25}
- version {2024/1.5}
+ date {2024-03-25}
+ version {2024/1.6}
keywords {LuaTeX; Plain TeX; MetaPost; mplib}
stopmetadata
\maketitle \fi
@@ -20,18 +20,26 @@ running tex or lua code from within metapost.
In order to use it, simply say ⟦\input minim-mp.tex⟧.
After this, ⟦*\directmetapost [ options ] { mp code }⟧ will result in a series
-of images corresponding to the ⟦beginfig ... endfig⟧ statements in your
+of images corresponding to the ⟦beginfig() ... endfig;⟧ statements in your
⟦mp code⟧. Every image will be in a box of its own.
+The metapost code to-be-run will be read under a special catcode regime in
+which most ‘special’ characters (including {\tt\#} and {\tt\%}) are inert.
+However, any control sequences will be expanded fully, as inside an ⟦\edef⟧.
+Keep this in mind and define any macros you want to use in a ⟦btex ... etex;⟧
+environment as ⟦\protected⟧ (with the latex package, latex’s ‘protected’ macros
+are safe-to-use, too).
+
Every call to ⟦\directmetapost⟧ opens and closes a separate metapost instance.
If you want your second call to remember the first, you will have to define
a persistent metapost instance. This will also give you more control over image
extraction. See below under „Metapost instances”. The ⟦options⟧ will also be
explained there (for simple cases, you will not need them).
-The logs of the metapost run will be included in the regular log file. If an
+The logs of the metapost run will be embedded in the regular log file. If an
error occurs, the log of the last snippet will also be shown on the terminal.
+
\section As a stand-alone Metapost compiler % 1
This package can also be used as a stand-alone metapost compiler. Saying
@@ -47,6 +55,7 @@ With minim-lamp, for specifying the contents of the preamble, you can use
Concluding the preamble with ⟦\begin{document}⟧ is optional, as both ⟦\begin⟧
and ⟦\end{document}⟧ will be inserted automatically if omitted.
+
\section LaTeX compatibility % 1
An experimental latex package is included in ⟦minim-mp.sty⟧. It really is
@@ -61,14 +70,19 @@ commands described in the next section.
As in luamplib, you can use ⟦*\mpcolor {name}⟧ to insert the proper colour
values; this macro is only available inside the above environments.
+A ⟦\mpdim⟧ macro is present too, but quite superfluous: since the contents of
+the metapost environments are fully expanded before metapost sees them, you can
+use ⟦\the⟧ and ⟦\the\dimexpr⟧ like everywhere else. Tex’s registers can also be
+accessed by metapost itself (see below).
When the package is loaded with the option ⟦luamplib⟧, minim-mp will try and
act as a drop-in replacement for luamplib. The effort made is not very great
though, but it will define an ⟦mplibcode⟧ environment, as well as the
⟦\mplibcodeinherit⟧, ⟦\mplibshowlog⟧, ⟦\mplibsetformat⟧ and
-⟦\mplibnumbersystem⟧ switches.
+⟦\mplibnumbersystem⟧ switches;
+also the macros ⟦\everymplib⟧ and ⟦\everyendmplib⟧.
Please do note that this is not the recommended way of using minim-mp, which
-remains the interface documented in the next section.
+remains the interface documented above and further in the next section.
\section Metapost instances % 1
@@ -76,7 +90,8 @@ remains the interface documented in the next section.
For more complicated uses, you can define your own instances by saying
⟦*\newmetapostinstance [ options ] \id⟧.
An instance can be closed with ⟦*\closemetapostinstance \id⟧.
-These are the options you can use:
+The ⟦options⟧ are directly passed to lua, as a table, and can contain the
+following keys:
\smallskip\smallskip\automarktable
\halign{#\quad\hfil&#\quad\hfil&#\hfil\cr
@@ -85,7 +100,7 @@ Option&Default&Description\cr
⟦format⟧&⟦'plain.mp'⟧&Format to initialise the instance with.\cr
⟦mathmode⟧&⟦'scaled'⟧&One of ⟦scaled⟧, ⟦decimal⟧ or ⟦double⟧.\cr
⟦seed⟧&⟦nil⟧&Random seed for this instance.\cr
-⟦catcodes⟧&⟦0⟧&Catcode table for ⟦btex ... etex⟧.\cr
+⟦catcodes⟧&(internal value)&Catcode table for ⟦btex ... etex⟧.\cr
⟦env⟧&copy of ⟦_G⟧&Lua environment; see below.\cr
}\smallskip
@@ -100,7 +115,6 @@ There, the image will be contained in a single box node.
⟦*\getnamedmpimage \id {name}⟧
– Retrieves an image by name
-regardless of its position,
and writes it to the current node list.
⟦*\boxnextmpimage \id box-nr⟧
@@ -110,12 +124,82 @@ tex can parse as a number.
⟦*\boxnamedmpimage \id box-nr {name}⟧
– Puts the image named ⟦name⟧ in box ⟦box-nr⟧.
-Say ⟦*\remainingmpimages \id⟧ for the number of images not yet retrieved.
+Say ⟦*\remainingmpimages \id⟧ for the number of images not yet retrieved
+and ⟦*\getallmpimages \id⟧ to insert all remaining images.
Finally, as a shorthand, ⟦*\runmetapostimage \id { code }⟧ will add
⟦beginfig ... endfig;⟧ to your ⟦code⟧ and write the resulting image immediately
to the current list.
+Associated to every instance are four token registers containing tex and/or
+metapost code to be inserted before or after each executed chunk.
+You can access them with ⟦*\everymp \id {pre|post} {tex|mp}⟧.
+The token lists where ${\tt id}=0$ do not correspond to any instance and will
+apply to every instance instead.
+All four token lists are empty by default if you use minim-mp with plain tex.
+The latex package, on the other hand, uses them for its own purposes, so take
+care in that case to use ⟦\tokspre⟧ and ⟦\toksapp⟧ instead of overwriting their
+contents. As a bonus, when using the latex package, you can use the environment
+name instead of the numerical ⟦\id⟧.
+
+
+\section Lua interface % 1
+
+In what follows, you should assume ⟦M⟧ to be the result of
+\stopformulatagging$$\hbox{⟦M = require('minim-mp')⟧}$$\startformulatagging
+as this package does not claim a table in the global environment for itself.
+
+You can open a new instance with ⟦*nr = M.open {options}⟧.
+This returns an index in the ⟦*M.instances⟧ table.
+Run code with ⟦*M.run (nr, code)⟧ and close the instance with ⟦*M.close (nr)⟧.
+Images can be retrieved only with ⟦*box_node = M.get_image(nr, [name])⟧; omit
+the ⟦name⟧ to select the first image.
+Say ⟦*nr_remaining = M.left(nr)⟧ for the number of remaining images.
+
+Each metapost instance is a table containing the following entries:
+
+\smallskip\smallskip
+\marktableaslist
+\tagattribute List ListNumbering /Description
+\halign{\qquad#\quad\hfil&#\hfil\cr
+⟦jobname⟧&The jobname.\cr
+⟦instance⟧&The primitive metapost instance.\cr
+⟦results⟧&A linked list of unretrieved images.\cr
+⟦status⟧&The last exit status (will never decrease).\cr
+⟦catcodes⟧&Number of the catcode table used with ⟦btex ... etex⟧.\cr
+⟦env⟧&The lua environment for ⟦runscript⟧.\cr}
+
+Default values for the format and number system are available in the
+⟦*M.default_format⟧ and ⟦*M.default_mathmode⟧ variables.
+The full initialisation sequence for new instances (i.e. the first metapost
+chunk, that is executed automatically) is contained in the ⟦*M.init_code⟧
+table.
+
+
+\section Logs and debugging % 1
+
+Metapost log output of every processed chunk of metapost code will be printed
+to the main log file in a quoted form.
+The logs will be duplicated to the terminal if an error occurs or if the
+variable ⟦*M.on_line⟧ is ⟦true⟧ (the default is ⟦false⟧, but set to ⟦true⟧ in
+the stand-alone format files).
+Because a single error message might trigger many others, log output to the
+terminal (but not the log file) will be cut after a certain number of errors:
+this behaviour is governed by the ⟦*M.max_errprint⟧ variable (default ⟦1⟧; set
+to ⟦0⟧ to disable).
+
+You can enable (global) debugging by saying ⟦*debug_pdf⟧ to metapost,
+⟦*\debugmetapost⟧ to tex or ⟦*M.enable_debugging()⟧ to lua. This will write
+out a summary of metapost object information to the pdf file, just above the
+pdf instructions that object was translated into. For this purpose, the pdf
+will be generated uncompressed. Additionally, the metapost code itself will be
+echoed to the log, as well as ⟦runscript⟧ and ⟦maketext⟧ invocations, and
+a small summary of every generated image will be written to log and terminal.
+
+For debugging the results of ⟦maketext⟧ and the like, you can set the
+⟦*debug_tex_bboxes⟧ variable to ⟦true⟧ and have their resulting bounding boxes
+drawn on the pdf.
+
\section Running tex from within metapost % 1
@@ -139,10 +223,12 @@ You can also use metapost’s ⟦*infont⟧ operator, which restricts the text
to-be-typeset to a single font, but returns an ⟦picture⟧ containing a ⟦picture⟧
for each character. The right-hand argument of ⟦infont⟧ should either be
a (numerical) font~id or the (cs)name of a font (without backslash).
+A traditional font name (e.g. ‘cmtt10’) is also accepted; this will silently
+load the font.
One possible use of the ⟦infont⟧ operator is setting text along curves:
-\nobreak
+\goodbreak
⟦beginfig(1)
save t, w, r, a; picture t;
t = "Running TeX from within MetaPost" infont "tenrm";
@@ -157,7 +243,7 @@ endfig;⟧
\vskip-2\parskip plus 2\parskip
\quitvmode\hfil
\startelement alt {The text ‘Running TeX from within MetaPost’ set along a half-circle.} {Figure}%
-\startsinglecontentitem\directmetapost{%
+\startsinglecontentitem\directmetapost [jobname='tex-in-mp'] {%
beginfig(1)
save t, w, r, a; picture t;
t = "Running TeX from within MetaPost" infont "tenrm";
@@ -189,35 +275,7 @@ Be aware that the contours returned by these operators may be disjoint:
a letter ⟦o⟧, for example, will consists of two. This means you cannot recreate
the characters by just filling each contour: this would turn the ⟦o⟧ into
a filled-in circle. Instead, you must use ⟦multifill⟧ on the entire output of
-⟦glyph of⟧ or ⟦contours of⟧ (see the next section).
-
-
-\section Partial paths and the even-odd rule % 1
-
-You can fill or draw two or more disjoint paths in one go by using ⟦*nofill⟧ as
-drawing operator for all paths but the last. This may make it easier to cut
-something out of a shape, since you do not have to worry about stitching the
-paths together.
-
-While metapost fills paths according to the winding number, the pdf format also
-supports filling according to the even-odd rule. This has been made possible
-with the ⟦*eofill⟧ and ⟦*eofilldraw⟧ drawing statements, which can of course
-also be used as the final statement after a series of nofills.
-
-The macros ⟦*multi(draw|fill|filldraw|eofill|eofilldraw)⟧ take a list of paths
-between parentheses and can be followed by the usual drawing options.
-For example,
-⟦multidraw (contours "example" of "tenbf") withpen currentpen scaled 1/10;⟧
-will give the word%
-\markelement{Span}{\setactualtext{example }\startsinglecontentitem\space
-\directmetapost{beginfig(1) multidraw (contours "example" of "tenbf")
-withpen currentpen scaled 1/10; baseline 0; endfig;}\stopsinglecontentitem}
-in a thin outline.
-
-Finally, two handy clipping macros have been added:
-⟦*clipout⟧ and ⟦*clipto⟧, which both receive a list of paths as a ‘text’
-parameter and either clip their ensemble out of the picture, or the picture to
-the ensemble.
+⟦glyph of⟧ or ⟦contours of⟧ (see below under ‘partial paths’).
\section Running lua from within metapost % 1
@@ -228,10 +286,10 @@ you make are local to the instance. (You can of course order the global
environment to be used by giving ⟦env = _G⟧ as option to
⟦\newmetapostinstance⟧.)
Any environment you specify will be supplemented with the contents of the
-⟦*M.mp_functions⟧ table. It currently contains two functions: ⟦quote(s)⟧, which
-escapes all double quotes in the string ⟦s⟧ before surrounding it with the same
-(so that it may be read as a metapost string literal); and ⟦sp_to_pt(nr)⟧,
-which prints dimensions in points (preventing overflows).
+⟦*M.mp_functions⟧ table. Two useful functions pre-supplied are ⟦quote(s)⟧,
+which escapes all double quotes in the string ⟦s⟧ before surrounding it with
+the same (so that it may be read as a metapost string literal); and
+⟦sp_to_pt(nr)⟧, which prints dimensions in points (preventing overflows).
When using ⟦runscript⟧ in this way, you must ensure its argument is a correct
lua program. As an escape hatch, raw strings can be passed to lua with
@@ -289,11 +347,40 @@ For accessing count, dimen, attribute or toks registers, the macros are
setting values.
+\section Partial paths and the even-odd rule % 1
+
+You can fill or draw two or more disjoint paths in one go by using ⟦*nofill⟧ as
+drawing operator for all paths but the last. This may make it easier to cut
+something out of a shape, since you do not have to worry about stitching the
+paths together.
+
+While metapost fills paths according to the winding number, the pdf format also
+supports filling according to the even-odd rule. You can use that method
+with the ⟦*eofill⟧ and ⟦*eofilldraw⟧ drawing statements, which can of course
+also be used as the final statement after a series of nofills.
+
+The macros ⟦*multi(draw|fill|filldraw|eofill|eofilldraw)⟧ take a list of paths
+between parentheses and can be followed by the usual drawing options.
+For example,
+⟦multidraw (contours "example" of "tenbf") withpen currentpen scaled 1/10;⟧
+will give the word%
+\markelement{Span}{\setactualtext{example }\startsinglecontentitem\space
+\directmetapost [jobname='outline']
+{beginfig(1) multidraw (contours "example" of "tenbf")
+withpen currentpen scaled 1/10; baseline 0; endfig;}\stopsinglecontentitem}
+in a thin outline.
+
+Finally, two handy clipping macros have been added:
+⟦*clipout⟧ and ⟦*clipto⟧, which both receive a list of paths as a ‘text’
+parameter and either clip their ensemble out of the picture, or the picture to
+the ensemble.
+
+
\section Tiling patterns % 1
-The condition ⟦*withpattern(<name>)⟧ added to a ⟦fill⟧ statement will fill the path with
-a pattern instead of a solid colour. If the patterns contains no colour
-information of itself, it will have the colour given by ⟦withcolor⟧.
+The specification ⟦*withpattern(<name>)⟧ added to a ⟦fill⟧ statement will fill
+the path with a pattern instead of a solid colour. If the pattern itself does
+not contain any colour statements, it will have the colour given by ⟦withcolor⟧.
Stroking operations (the ⟦draw⟧ part) will not be affected.
Patterns will always look the same, irrespective of any transformations you
apply to the picture.
@@ -315,8 +402,8 @@ information on these parameters.
You can use text inside patterns, as in this example:
\hfill \vbox to 0pt{
\startelement alt{A circle filled with red As in a rectangular pattern.}{Figure}
-\startsinglecontentitem \directmetapost{
-% define the pattern
+\startsinglecontentitem \directmetapost [jobname='pattern']
+{% define the pattern
picture letter; letter = maketext("a");
beginpattern(a)
draw letter rotated 45;
@@ -365,19 +452,19 @@ For applying transparency, ⟦*setalpha(a)⟧ updates the ⟦CA⟧ and ⟦ca⟧
as a stand-alone command and ⟦*withalpha(a)⟧ can be used in a drawing statement
where it will save/restore the graphical state around it. For applying
transparency to an ensemble of drawing statements, ⟦*transparent (a) <picture>⟧
-will create and insert the proper transparency group. The transparency group
-attributes can be set with the string internal ⟦transparency_group_attrs⟧,
-while for all three macros the blend mode can be set with the string internal
-⟦blend_mode⟧ (it will be added whenever set).
+instead of ⟦draw <picture>⟧ will create and insert the proper transparency group.
+The transparency group attributes can be set with the string internal
+⟦*transparency_group_attrs⟧, while for all three macros the blend mode can be
+set with the string internal ⟦*blend_mode⟧ (it will be added whenever set).
A transparency group is a special kind of XForm, and these can be created from
-withing metapost: ⟦<id> =⟧ ⟦*saveboxresource (<attributes>) <picture>⟧ returns
-a number identifying the resource and can be fed attributes in the same way as
-⟦setgstate⟧. XForms defined through metapost are available to other metapost
-instances but not to tex, though the macro painting them, ⟦*boxresource <id>⟧,
-also accepts identifiers of tex-defined box resources. There remains a subtle
-difference, however: metapost-defined box resources are placed at their
-original origin.
+within metapost: ⟦<id> =⟧ ⟦*saveboxresource (<attributes>) <picture>⟧ returns
+a number identifying the resource; the ⟦<attributes>⟧ can be given in the same
+way as the arguments to ⟦setgstate⟧. XForms defined through metapost are
+available to other metapost instances but not to tex, though the macro painting
+them, ⟦*boxresource <id>⟧, also accepts identifiers of tex-defined box
+resources. There remains a subtle difference, however: metapost-defined box
+resources are placed at their original origin.
\section Other metapost extensions % 1
@@ -400,8 +487,16 @@ In that case, they will be added before or after the object they are attached to
Do note that all ⟦special⟧ statements will appear at the beginning of the
image; use pre- and postscripts to drawing statements if the order matters.
-Minim-mp also provides a few elementary macros and constants that are
-conspicuously absent from plain.mp; I hope their addition is uncontroversial.
+
+\section Additions to plain.mp % 1
+
+Minim-mp provides a few elementary macros and constants that are
+conspicuously absent from plain.mp; I hope their addition is uncontroversial.
+All are provided in the file minim.mp; the contents of this file do not depend
+on functions specific to minim-mp and thus it can safely be used with other
+metapost processors. It is included automatically right after the format file
+(i.e. plain.mp).
+
The constants are ⟦*pi⟧ (355/113), ⟦*fullsquare⟧, ⟦*unitcircle⟧ and the
cmyk-colours ⟦*cyan⟧, ⟦*magenta⟧, ⟦*yellow⟧ and ⟦*key⟧. The macros are
⟦*clockwise⟧, ⟦*xshifted⟧, ⟦*yshifted⟧, ⟦*hflip⟧ and ⟦*vflip⟧, where the flips
@@ -413,49 +508,12 @@ etc. that save and declare in one go; the missing trigonometric functions
drawing function ⟦*arc(⟧$θ_0$⟦*,⟧$θ_ℓ$⟦*)⟧ (taking a starting angle and arc
length, both in degrees).
-\section Lua interface % 1
-
-In what follows, you should assume ⟦M⟧ to be the result of
-\stopformulatagging$$\hbox{⟦M = require('minim-mp')⟧}$$\startformulatagging
-as this package does not claim a table in the global environment for itself.
-
-You can open a new instance with ⟦*nr = M.open {options}⟧.
-This returns an index in the ⟦*M.instances⟧ table.
-Run code with ⟦*M.run (nr, code)⟧ and close the instance with ⟦*M.close (nr)⟧.
-Images can be retrieved only with ⟦*box_node = M.get_image(nr, [name])⟧; omit
-the ⟦name⟧ to select the first image.
-Say ⟦*nr_remaining = M.left(nr)⟧ for the number of remaining images.
+Version 1.6 brought ⟦*empty⟧ for testing empty suffixes, ⟦*typeof(v)⟧
+expanding to the type (⟦numeric⟧, ⟦pair⟧ etc.) of variable ⟦v⟧,
+⟦*getbounds⟧ as complement to ⟦setbounds⟧, the (twodimensional) exterior product
+⟦*p extprod q⟧ and the test ⟦*collinear(p,q,r)⟧.
-Each metapost instance is a table containing the following entries:
-
-\smallskip\smallskip
-\marktableaslist
-\tagattribute List ListNumbering /Description
-\halign{\qquad#\quad\hfil&#\hfil\cr
-⟦jobname⟧&The jobname.\cr
-⟦instance⟧&The primitive metapost instance.\cr
-⟦results⟧&A linked list of unretrieved images.\cr
-⟦status⟧&The last exit status (will never decrease).\cr
-⟦catcodes⟧&Number of the catcode table used with ⟦btex ... etex⟧.\cr
-⟦env⟧&The lua environment for ⟦runscript⟧.\cr}
-
-Default values for the format and number system are available in the
-⟦M.default_format⟧ and ⟦M.default_mathmode⟧ variables,
-while ⟦M.on_line⟧ controls whether the logs are always printed to the
-terminal.
-
-
-\section Debugging % 1
-
-You can enable (global) debugging by saying ⟦*debug_pdf⟧ to metapost or
-⟦*M.enable_debugging()⟧ to lua. This will write out a summary of metapost
-object information to the pdf file, just above the pdf instructions that object
-was translated into. For this purpose, the pdf will be generated uncompressed.
-Additionally, a small summary of every generated image will be written to log
-and terminal.
-
-
-\section Extending metapost % 1
+\section Metapost specials % 1
You can extend this package by adding new metapost specials. Specials should
have the form ⟦"identifier: instructions"⟧ and can be added as pre- or
@@ -483,9 +541,5 @@ properly-dimensioned boxes. If a ⟦user.save_fn⟧ function is defined, it will
replace the normal saving of the image to the image list and the image node
list will be flushed.
-The ⟦*M.init_code⟧ table contains the code used for initialing new instances.
-In it, the string ⟦INIT⟧ will be replaced with the value of the ⟦format⟧ option
-(normally ⟦plain.mp⟧).
-
\endmanual %
diff --git a/macros/luatex/generic/minim-mp/minim-mp.ini b/macros/luatex/generic/minim-mp/minim-mp.ini
index 11387e00d1..0f62835442 100644
--- a/macros/luatex/generic/minim-mp/minim-mp.ini
+++ b/macros/luatex/generic/minim-mp/minim-mp.ini
@@ -1,7 +1,7 @@
\catcode`\{=1 \catcode`\}=2
\def\fmtname{minim-mp}
-\def\fmtversion{2023/1.3}
+\def\fmtversion{2024/1.6}
\input minim.ini
diff --git a/macros/luatex/generic/minim-mp/minim-mp.lua b/macros/luatex/generic/minim-mp/minim-mp.lua
index fba6573239..885a6941e4 100644
--- a/macros/luatex/generic/minim-mp/minim-mp.lua
+++ b/macros/luatex/generic/minim-mp/minim-mp.lua
@@ -102,6 +102,14 @@ function M.enable_debugging()
end
E.enable_debugging = M.enable_debugging
+alloc.luadef('debugmetapost', M.enable_debugging)
+
+local function debug(...)
+ if debugging then
+ alloc.log(...)
+ end
+end
+
local function print_prop(append, obj, prop)
if obj[prop] then
local val = string.gsub(tostring(obj[prop]), '\r', '<CR>')
@@ -136,9 +144,8 @@ local function print_knots(append, obj, ptype)
end
function A.printobj(append, obj)
- if not debugging then return end
local nc = append.node_count
- append:literal('%%Object Type: %s', obj.type)
+ append:literal('%% Object Type: %s', obj.type)
print_prop(append, obj, 'text')
print_prop(append, obj, 'font')
print_prop(append, obj, 'dsize')
@@ -151,16 +158,16 @@ function A.printobj(append, obj)
print_knots(append, obj, 'htap')
if obj.pen then
local x = obj.pen.type or 'not elliptical'
- append:literal('%% pen: see below, form: %s', x)
+ append:literal('%% pen is %s', x)
x = mplib.pen_info(obj)
- append:literal('%% | width: %s', tostring(x.width))
- append:literal('%% | sx: %s', tostring(x.sx))
- append:literal('%% | sy: %s', tostring(x.sy))
- append:literal('%% | rx: %s', tostring(x.rx))
- append:literal('%% | ry: %s', tostring(x.ry))
- append:literal('%% | tx: %s', tostring(x.tx))
- append:literal('%% | ty: %s', tostring(x.ty))
- print_knots(append, obj, 'pen')
+ append:literal('%% width: %s', tostring(x.width))
+ append:literal('%% sx: %s', tostring(x.sx))
+ append:literal('%% sy: %s', tostring(x.sy))
+ append:literal('%% rx: %s', tostring(x.rx))
+ append:literal('%% ry: %s', tostring(x.ry))
+ append:literal('%% tx: %s', tostring(x.tx))
+ append:literal('%% ty: %s', tostring(x.ty))
+ print_knots(append, obj, 'pen path')
end
if obj.dash then
local d = ''
@@ -420,7 +427,9 @@ function A.linestate (append, object)
append.dashed = false
table.insert(res, '[] 0 d')
end
- append:literal(table.concat(res, ' '))
+ if #res > 0 then
+ append:literal(table.concat(res, ' '))
+ end
end
-- 2 path literals
@@ -482,7 +491,7 @@ function A.curve(append, path, open, concat)
elseif #path == 1 then
append_line(path[1], 'l') -- special case: draw a point
end
- append:literal(table.concat(res, ' '))
+ append:literal(table.concat(res, '\n'))
end
-- And actually draw the path.
@@ -556,7 +565,9 @@ end
local function parse_object(append, object)
append.object_info = { }
- append:printobj(object)
+ if debugging then
+ append:printobj(object)
+ end
local processor = nil
for sp, instr in split_specials(object.prescript) do
if not sp then
@@ -1018,8 +1029,8 @@ M.instances = instances
-- parameters: wd, ht+dp, dp
local function make_transform(w, h, d)
- return string.format('identity xscaled %fpt yscaled %fpt shifted (0,-%fpt)',
- w/65536, (h+d)/65536, d/65536)
+ return string.format('identity xscaled %fpt yscaled %fpt shifted (0,%fpt)',
+ w/65536, (h+d)/65536, -d/65536)
end
local status_names = { [0] = 'good', 'warning', 'error', 'fatal' }
@@ -1028,16 +1039,19 @@ local function print_status(st)
end
M.on_line = false
+M.max_errprint = 1
local function print_log (nr, res, why)
local i = instances[nr]
-- only write to term if on_line or if exit status increases
- local log, alog
+ local log, alog --luacheck:ignore 231
if M.on_line or res.status > i.status then
- local nrlines, maxlines = 0, 16
alog = alloc.amsg
+ local nr_errs = 0
log = function(...)
- if M.on_line or nrlines < maxlines then
- nrlines = nrlines + 1
+ if string.sub(table.pack(...)[2],1,2) == "! " then
+ nr_errs = nr_errs + 1
+ end
+ if M.max_errprint < 1 or M.max_errprint >= nr_errs then
alloc.msg(...)
else
alloc.log(...)
@@ -1050,17 +1064,18 @@ local function print_log (nr, res, why)
end
-- split log into lines; discard empty lines at the end
local report = res.log and res.log:explode('\n') or { }
- while report[#report] == '' do
- report[#report] = nil
- end
-- write out the log
- log('┌ %smetapost instance %s (%d)', why or '', i.jobname, i.nr)
+ log('┌ %smetapost instance {%s} (%d)', why or '', i.jobname, i.nr)
for _,line in ipairs(report) do
- log('│ %s', line)
+ if line ~= '' and line ~= "(Please type a command or say `end')" then
+ log('│ %s', line)
+ end
end
log('└ %s', print_status(res.status))
-- generate error or warning if needed
if res.status > i.status then
+ local ecl = tex.errorcontextlines -- TODO: why does TeX fill the error context
+ tex.errorcontextlines = 0 -- with repeated <inserted text> BAD ???
if res.status == 3 then
alloc.err('Metapost instance now defunct')
elseif res.status == 2 then
@@ -1068,6 +1083,7 @@ local function print_log (nr, res, why)
elseif res.status == 1 then
alloc.msg('Metapost code caused warning')
end
+ tex.errorcontextlines = ecl
end
-- save the exit status for later comparison
i.status = res.status
@@ -1107,6 +1123,9 @@ local function process_results(nr, res)
local fig = res.fig[i]
local name = fig:filename()
local append = init_append()
+ if debugging then
+ append:literal('%% START OF MP FIGURE %s (instance %d)', name, nr)
+ end
-- parse and append all objects
append:save()
local objects = fig:objects()
@@ -1114,6 +1133,9 @@ local function process_results(nr, res)
parse_object (append, objects[j])
end
append:restore()
+ if debugging then
+ append:literal('%% END OF MP FIGURE %s (instance %d)', name, nr)
+ end
-- bounding box and baseline information
local bb = fig:boundingbox()
local llx, lly, urx, ury = table.unpack(bb)
@@ -1174,12 +1196,19 @@ end
-- change in the future.)
local function mkluastring(s)
- return "'"..(s:gsub('\\', '\\\\'):gsub("'", "\\'"):gsub('\n', '\\n')).."'"
+ return "'"..(s
+ :gsub('\\', '\\\\')
+ :gsub("'", "\\'")
+ :gsub('\n', '\\n')
+ :gsub('\013', '\\r')
+ :gsub('\000', '\\000')
+ ).."'"
end
local function runscript(code)
+ debug('┌ runscript: %s', code)
-- (possibly) pass directly to function
- local fn, arg = code:match('^%[%[(.+)%]%](.*)')
+ local fn, arg = code:match('^%[%[(.-)%]%](.*)')
if fn then code = 'return '..fn .. mkluastring(arg) end
-- execute the script
local f, msg = load(code, current_instance.jobname, 't', current_instance.env)
@@ -1187,32 +1216,39 @@ local function runscript(code)
if f then
local result = f()
if result == nil then
+ debug('└ (no return value)')
return
else
local t = type(result)
if t == 'number' then
- return string.format('%.16f', result)
+ result = string.format('%.16f', result)
elseif t == 'string' then
- return result
+ result = result
elseif t == 'table' and result[1] == 'box_size' then
- return make_transform(result[2], result[3], result[4])
+ result = make_transform(result[2], result[3], result[4])
elseif t == 'table' and #result < 5 then
local fmt = #result == 1 and '%.16f'
or #result == 2 and '(%.16f, %.16f)'
or #result == 3 and '(%.16f, %.16f, %.16f)'
or #result == 4 and '(%.16f, %.16f, %.16f, %.16f)'
- return fmt:format(table.unpack(result))
+ result = fmt:format(table.unpack(result))
elseif t == 'table' and #result == 6 then
- return table.concat({
- 'begingroup save t; transform t;',
+ result = table.concat({
+ 'begingroup save t; transform t',
'xxpart t = %.16f', 'xypart t = %.16f',
'yxpart t = %.16f', 'yypart t = %.16f',
'xpart t = %.16f', 'ypart t = %.16f',
't endgroup' },
';'):format(table.unpack(result))
else
- return tostring(result)
+ result = tostring(result)
end
+ if #result > 120 then
+ debug('└ %s etc. etc.', result:sub(1,110))
+ else
+ debug('└ %s', result)
+ end
+ return result
end
else
local mp_msg = string.gsub(msg, '"', '"&ditto&"')
@@ -1257,7 +1293,8 @@ E.catcodes = { numbers =
, vrbcatcodes = cct_maketext , prtcatcodes = cct_maketext
, ctxcatcodes = cct_maketext , txtcatcodes = cct_maketext
} }
-E.mp = mp or { } -- all seem nonessential
+E.mp = mp or { } --luacheck: ignore 113
+-- all functions below seem nonessential
E.mp.mf_path_reset = E.mp.mf_path_reset or function() end
E.mp.mf_finish_saving_data = E.mp.mf_finish_saving_data or function() end
E.mp.report = E.mp.report or function() end
@@ -1283,19 +1320,51 @@ E.mp.report = E.mp.report or function() end
local function maketext(text, mode)
if mode == 0 then -- btex or maketext
local nr = alloc.new_box()
+ debug('┌ btex: %s', text)
table.insert(current_instance.boxes, nr)
local assignment = string.format('\\global\\setbox%s=\\hbox{\\the\\everymaketext %s}', nr, text)
tex.runtoks(function() tex.print(current_instance.catcodes, assignment:explode('\n')) end)
local box = tex.box[nr]
+ debug('└ etex: box %d', nr)
return string.format('_set_maketext_result_(%d, %s)', nr,
make_transform(box.width, box.height, box.depth))
elseif mode == 1 then -- verbatimtex
+ debug('┌ verbatimtex: %s', text)
tex.runtoks(function() tex.print(current_instance.catcodes, text:explode('\n')) end)
+ debug('└ etex')
+ end
+end
+
+-- a font cache for infont and glyph of
+local infont_fonts = { }
+local function get_infont_font(fnt)
+ local csname = 'minim-mp infont '..fnt
+ local res = infont_fonts[csname]
+ if res then
+ debug('├ resolved font "%s" (%d)', fnt, res)
+ else
+ tex.runtoks(function()
+ tex.print(current_instance.catcodes, string.format(
+ '\\expandafter\\font\\csname %s\\endcsname={%s}\\relax', csname, fnt))
+ end)
+ res = font.id(csname)
+ infont_fonts[csname] = res
+ debug('├ loaded font "%s" (%d)', fnt, res)
end
+ return res
+end
+
+local function fontid_from_csname(fnt)
+ local id = font.id(fnt)
+ if id < 0 then return end
+ debug('├ resolved font \\%s (%d)', fnt, id)
+ return id
end
local function getfontid(fnt)
- return tonumber(fnt) or font.id(fnt)
+ return tonumber(fnt)
+ or fontid_from_csname(fnt)
+ or get_infont_font(fnt)
end
local typeset_box = alloc.new_box('infont box')
@@ -1377,17 +1446,23 @@ function M.make_glyph(glyphname, fnt)
end
local function get_glyphname(c_id)
- return luaotfload.aux.name_of_slot(c_id)
+ if type(c_id) == 'string' then return c_id end
+ local res = luaotfload.aux.name_of_slot(c_id)
+ debug('├ name of glyph %d is %s', c_id, res)
+ return res
end
function E.get_glyph(c_id, fnt)
- local name = (type(c_id) == 'string') and c_id or get_glyphname(c_id)
+ debug('┌ glyph %s of %s', c_id, fnt)
+ local name = get_glyphname(c_id)
local contours, size = M.make_glyph(name, fnt)
local res = { }
for _, c in ipairs(contours) do
- table.insert(res, string.format(
- '%s scaled %f', c, size/65536/1000))
+ local scaled = string.format('%s scaled %f', c, size/65536/1000)
+ debug('│ %s', scaled)
+ table.insert(res, scaled)
end
+ debug('└ %d contours returned', #res)
return table.concat(res, ', ')
end
@@ -1419,7 +1494,7 @@ local function apply_default_instance_opts(t)
--, script_error = ...
, job_name = t.jobname
, math_mode = t.mathmode or t.math or M.default_mathmode
- , random_seed = t.seed or nil
+ , random_seed = t.randomseed or t.seed or nil
-- , file_line_error_style
, make_text = maketext
, run_script = runscript
@@ -1451,7 +1526,17 @@ function M.run (nr, code)
return
end
current_instance = self
+ if debugging then
+ alloc.log('┌ metapost chunk for {%s} (%d)', self.jobname, nr)
+ for _, line in ipairs(code:explode('\013')) do
+ alloc.log('│ %s', line)
+ end
+ alloc.log('└')
+ end
+ local cct = tex.catcodetable
+ tex.catcodetable = self.catcodes
local res = self.instance:execute(code)
+ tex.catcodetable = cct
print_log(nr, res)
local picts = process_results(nr, res)
save_image_list(self, picts)
@@ -1460,17 +1545,19 @@ end
M.init_code = { 'let dump=endinput;'
, 'boolean mplib; mplib:=true;'
, 'input INIT;'
- , 'input minim-mp.mp;'
- , 'input minim.mp;' }
+ , 'input minim.mp;'
+ , 'input minim-mp.mp;' }
local maketext_catcodes = alloc.registernumber('minim:mp:catcodes:maketext')
function M.open (t)
local nr = #instances + 1
- t.jobname = t.jobname or ':metapost:'
+ tex.count['mp:cur:inst'] = nr
-- creating instance options
+ t.jobname = t.jobname or ':metapost:'
local init = string.gsub(table.concat(M.init_code, ''), 'INIT', t.format or M.default_format)
local opts = apply_default_instance_opts(t)
local instance = mplib.new(opts)
+ tex.runtoks 'mp:init:env'
-- adding the instance
instances[nr] =
{ nr = nr
@@ -1484,11 +1571,13 @@ function M.open (t)
}
current_instance = instances[nr]
print_log(nr, instance:execute(init), 'opening ')
+ tex.count['mp:cur:inst'] = -1
return nr
end
function M.close (nr)
local i = instances[nr]
+ tex.count['mp:cur:inst'] = nr
if i.instance then
local res = i.instance:finish()
print_log(nr, res, 'closing ')
@@ -1498,6 +1587,7 @@ function M.close (nr)
tex.box[b] = nil
end
instances[nr] = false
+ tex.count['mp:cur:inst'] = -1
end
-- 2 retrieving and using results
@@ -1569,25 +1659,30 @@ end
local scan_int = token.scan_int
local scan_string = token.scan_string
+alloc.luadef('closemetapostinstance', function() M.close(scan_int()) end)
+
local code_catcodes = alloc.registernumber('minim:mp:catcodes:mpcode')
-local function scan_codestring()
+
+alloc.luadef('runmetapost', function()
+ local id = scan_int()
+ tex.count['mp:cur:inst'] = id
+ -- run tex code before
+ tex.runtoks 'mp:inst:pre:tex'
+ -- scan the argument with inert catcodes
local cct = tex.catcodetable
tex.catcodetable = code_catcodes
- local res = token.scan_string()
+ token.scan_keyword '\013' -- ^^M has catcode 12 now
+ local code = token.scan_string()
tex.catcodetable = cct
- return res
-end
-
-alloc.luadef('closemetapostinstance', function() M.close(scan_int()) end)
-
-alloc.luadef('runmetapost', function()
- M.run(scan_int(), scan_codestring())
-end, 'protected')
-alloc.luadef('runmetapostimage', function()
- local i = scan_int()
- local code = 'beginfig(0)'..scan_codestring()..';endfig;'
- M.run(i, code)
- node.write(M.get_image(i))
+ -- prepare the argument further
+ tex.toks['mp:mpcode'] = code
+ tex.runtoks 'mp:makempcode'
+ code = tex.toks['mp:mpcode']
+ -- run the code
+ M.run(id, code)
+ -- run tech code after
+ tex.runtoks 'mp:inst:post:tex'
+ tex.count['mp:cur:inst'] = -1
end, 'protected')
alloc.luadef('getnextmpimage', function()
diff --git a/macros/luatex/generic/minim-mp/minim-mp.mp b/macros/luatex/generic/minim-mp/minim-mp.mp
index 2fd2db1074..30b7d86252 100644
--- a/macros/luatex/generic/minim-mp/minim-mp.mp
+++ b/macros/luatex/generic/minim-mp/minim-mp.mp
@@ -7,12 +7,7 @@ delimiters ();
message "Setting up the minim MetaPost extensions";
-def save_picture text t = save t; picture t; enddef;
-def save_boolean text t = save t; boolean t; enddef;
-def save_string text t = save t; string t; enddef;
-def save_path text t = save t; path t; enddef;
-
-% 1 lua scripts, functions and variables
+% 1 lua scripts and functions
def luafunction = gobble inner_luafunction enddef;
vardef inner_luafunction @# (text args) = endgroup
@@ -85,9 +80,6 @@ vardef quote_for_lua tertiary a =
","& (hexadecimal magentapart a) &
","& (hexadecimal yellowpart a) &
","& (hexadecimal blackpart a) & "}"
- elseif pen a:
- hide(errmessage("I cannot pass a pen value to lua");)
- "nil"
elseif transform a:
"{"& (hexadecimal xxpart a) &
","& (hexadecimal xypart a) &
@@ -95,6 +87,9 @@ vardef quote_for_lua tertiary a =
","& (hexadecimal yypart a) &
","& (hexadecimal xpart a) &
","& (hexadecimal ypart a) & "}"
+ elseif pen a:
+ hide(errmessage("I cannot pass a pen value to lua");)
+ "nil"
elseif picture a:
hide(errmessage("I cannot pass a picture value to lua");)
"nil"
@@ -121,7 +116,7 @@ vardef make_lua_keyval @# expr e =
(str @#) & " = " & quote_for_lua e
enddef;
-% tex registers
+% 1 tex registers
string _SUFFIX_HACK_[];
vardef index_or_suffix (suffix s) =
@@ -138,6 +133,8 @@ vardef tex.attribute @# =
runscript ("return tex.attribute" & index_or_suffix(@#)) enddef;
vardef tex.dimen @# =
runscript ("return sp_to_pt(tex.dimen" & index_or_suffix(@#) & ")") enddef;
+vardef tex.skip @# =
+ runscript ("return sp_to_pt(tex.skip" & index_or_suffix(@#) & ".width)") enddef;
vardef tex.toks @# =
runscript ("return quote(tex.toks" & index_or_suffix(@#) & ")") enddef;
@@ -382,8 +379,4 @@ def debug_pdf = luafunction enable_debugging(); enddef;
vardef texmessage text msg = luafunction texmessage (msg) enddef;
-vardef rgb_to_gray expr c =
- luafunction rgb_to_gray (redpart c, greenpart c, bluepart c)
-enddef;
-
% 
diff --git a/macros/luatex/generic/minim-mp/minim-mp.pdf b/macros/luatex/generic/minim-mp/minim-mp.pdf
index eae0cd360e..4760106341 100644
--- a/macros/luatex/generic/minim-mp/minim-mp.pdf
+++ b/macros/luatex/generic/minim-mp/minim-mp.pdf
Binary files differ
diff --git a/macros/luatex/generic/minim-mp/minim-mp.sty b/macros/luatex/generic/minim-mp/minim-mp.sty
index 6240c80b9a..948c6034b7 100644
--- a/macros/luatex/generic/minim-mp/minim-mp.sty
+++ b/macros/luatex/generic/minim-mp/minim-mp.sty
@@ -11,35 +11,35 @@
\def\mnm@setnormalfont{{\normalfont
\xdef\mnm@normalfont{\expandafter\csstring\the\font}}}
-% a one-off metapost environment
-\newenvironment{metapost}[1][]{%
- \begingroup \catcode`\#=12
- \let\mpcolor = \minimpcolor
- \csname:metapost:\endcsname[#1]}
- {\csname end:metapost:\endcsname \endgroup}
-\NewDocumentEnvironment{:metapost:}{O{}+b}{%
+% global instance configuration
+\everymp0{pre}{mp}{defaultfont:="\mnm@normalfont";}
+\everymp0{pre}{tex}{%
\mnm@setnormalfont
- \let\protect=\noexpand
- \directmetapost[#1]{%
- defaultfont:="\mnm@normalfont"; #2; }%
- \let\protect=\mnm@protect}{}
+ \let\mpcolor = \minimpcolor
+ \let\protect = \noexpand}
+\everymp0{post}{tex}{%
+ \let\protect=\mnm@protect}
+
+% a one-off metapost environment
+\newenvironment{metapost}[1][]{\begingroup
+ \catcodetable\csname minim:mp:catcodes:mpcode\endcsname
+ \csname:metapost:\endcsname[#1]}
+ {\csname end:metapost:\endcsname}
+\NewDocumentEnvironment{:metapost:}{O{}+b}{\endgroup
+ \directmetapost[#1]{#2}}{}
% separate metapost instances
\newcommand\newmetapostenvironment[2][]{%
\newmetapostinstance[#1]\mnm@tmp
\expandafter\let\csname #2@instance\endcsname\mnm@tmp
- \newenvironment{#2}{%
- \begingroup \catcode`\#=12 \catcode`\%=12
- \let\mpcolor = \minimpcolor
+ \everymp\mnm@tmp{post}{tex}{%
+ \getallmpimages \csname #2@instance\endcsname}
+ \newenvironment{#2}{\begingroup
+ \catcodetable\csname minim:mp:catcodes:mpcode\endcsname
\csname:#2:\endcsname}
- {\csname end:#2:\endcsname \endgroup}%
- \NewDocumentEnvironment{:#2:}{+b}{%
- \mnm@setnormalfont
- \let\protect=\noexpand
- \runmetapostimage
- \csname #2@instance\endcsname
- {defaultfont:="\mnm@normalfont";##1;}%
- \let\protect=\mnm@protect}{}}
+ {\csname end:#2:\endcsname}%
+ \NewDocumentEnvironment{:#2:}{+b}{\endgroup
+ \runmetapost \csname #2@instance\endcsname{##1}}{}}
% \mpcolor support
\def\minimpcolor#1#{\dominimpcolor{#1}}
@@ -58,9 +58,9 @@
require 'minim-mp'.on_line = %
\ifcsname minimp@switch@#1\endcsname
true \else false \fi }}
- \newmetapostenvironment[jobname='\jobname']{@mplibcode}
\def\mplibcodeinherit#1{%
\ifcsname minimp@switch@#1\endcsname
+ \newmetapostenvironment[jobname='\jobname']{@mplibcode}
\let\mplibcode=\@mplibcode
\let\endmplibcode=\@mplibcode
\else
@@ -72,6 +72,10 @@
require 'minim-mp'.default_format = '#1.mp' }}
\def\mplibnumbersystem#1{\directlua{
require 'minim-mp'.default_math = '#1' }}
+ \newcommand\everymplib[2][0]{%
+ \everymp{#1}{pre}{mp}{defaultfont:="\mnm@normalfont";#2}}
+ \newcommand\everyendmplib[2][0]{%
+ \everymp{#1}{post}{mp}{#2}}
} \ProcessOptions*
\let\minimp@switch@@enable=\relax
diff --git a/macros/luatex/generic/minim-mp/minim-mp.tex b/macros/luatex/generic/minim-mp/minim-mp.tex
index 7b8cef6c6b..ddc925ab3a 100644
--- a/macros/luatex/generic/minim-mp/minim-mp.tex
+++ b/macros/luatex/generic/minim-mp/minim-mp.tex
@@ -1,6 +1,6 @@
\ifdefined\minimmploaded
- \message{(skipped)}
+ \wlog{(skipped)}
\expandafter\endinput\fi
\chardef\minimmploaded = \catcode`\:
\catcode`\: = 11
@@ -14,10 +14,11 @@
\savecatcodetable\csname minim:mp:catcodes:maketext\endcsname}
% and an empty catcode table for reading metapost code
\newcatcodetable \minim:mp:catcodes:mpcode
-{\catcodetable\minim:initcatcodes
+{\def\\{}\catcodetable\minim:initcatcodes
\catcode`\{=1 \catcode`\}=2 \catcode9=10
+ \catcode`\$=12 \catcode`\^=12 \catcode`\_=12 \catcode`\&=12
\catcode`\#=12 \catcode`\%=12 \catcode`\~=12
- \savecatcodetable\csname minim:mp:catcodes:mpcode\endcsname}
+ \catcode"0D=12 \savecatcodetable\csname\\minim:mp:catcodes:mpcode\endcsname}
\directlua { require('minim-mp') }
@@ -28,24 +29,39 @@
%
% \closemetapostinstance \instance
% \runmetapost \instance { code } % \protected
-% \runmetapostimage \instance { code } % \protected
% \getnextmpimage \instance
% \getnamedmpimage \instance {name}
% \remainingmpimages \instance
% \boxnextmpimage \instance box-nr
% \boxnamedmpimage \instance box-nr {name}
+% \getallmpimages \instance
+\newcount\mp:tmpcount
+\protected\def\getallmpimages{%
+ \afterassignment\getallmpimages:do\mp:tmpcount=}
+\def\getallmpimages:do{\loop
+ \ifnum \remainingmpimages\mp:tmpcount>0\relax
+ \getnextmpimage\mp:tmpcount \repeat}
+
+% \runmetapostimage \instance { code }
+\protected\def\runmetapostimage{\begingroup
+ \afterassignment\runmetapostimage:do\mp:tmpcount=}
+\def\runmetapostimage:do{%
+ \toksapp\everymp\mp:tmpcount{pre}{mp}{beginfig(0) }%
+ \tokspre\everymp\mp:tmpcount{post}{mp}{ endfig;}%
+ \toksapp\everymp\mp:tmpcount{post}{tex}{%
+ \getallmpimages\mp:tmpcount \endgroup}%
+ \runmetapost\mp:tmpcount}
+
% \directmetapost [ options ] { code }
\protected\def\directmetapost{%
- \begingroup\catcodetable\minim:mp:catcodes:mpcode
- \withoptions[]\directmetapost:}
-\long\def\directmetapost:[#1]#2{%
- \newmetapostinstance[#1]\:mpinst:
- \runmetapost\:mpinst:{#2}%
- \loop \ifnum\remainingmpimages\:mpinst:>0\relax
- \getnextmpimage\:mpinst: \repeat
- \closemetapostinstance\:mpinst:
- \endgroup}
+ \withoptions[]\directmetapost:opt}
+\long\def\directmetapost:opt[#1]{%
+ \newmetapostinstance[#1]\:mpinst:
+ \everymp\:mpinst:{post}{tex}{%
+ \getallmpimages\:mpinst:
+ \closemetapostinstance\:mpinst:}%
+ \runmetapost\:mpinst:}
% \newmetapostinstance [ options ] \instance
\protected\def\newmetapostinstance{\withoptions[]\newmetapostinstance:}
@@ -54,6 +70,41 @@
tex.sprint(require('minim-mp').open{#1})
}\relax}
+% tex side of metapost instance initialisation
+\newcount \mp:cur:inst
+\newtoks \mp:init:env \mp:init:env{%
+ % four token lists for every instance
+ \expandafter\newtoks\csname mp:inst:pre:tex:\the\mp:cur:inst\endcsname
+ \expandafter\newtoks\csname mp:inst:pre:mp:\the\mp:cur:inst\endcsname
+ \expandafter\newtoks\csname mp:inst:post:mp:\the\mp:cur:inst\endcsname
+ \expandafter\newtoks\csname mp:inst:post:tex:\the\mp:cur:inst\endcsname}
+% the zeroth quarted applies to all
+\mp:cur:inst=0 \the\mp:init:env \mp:cur:inst=-1
+
+% \everymp \id {pre|post}{mp|tex} % accesses the above token lists
+\def\everymp#1#2#3{\csname mp:inst:#2:#3:\the
+ \ifcsname \string#1@instance\endcsname % for the latex environments
+ \lastnamedcs\else\numexpr#1\fi
+ \endcsname}
+
+% combining the relevant toks registers
+\newtoks\mp:inst:pre:tex \mp:inst:pre:tex{%
+ \the\everymp0{pre}{tex}%
+ \the\everymp\mp:cur:inst{pre}{tex}}
+\newtoks\mp:inst:post:tex \mp:inst:post:tex{%
+ \the\everymp\mp:cur:inst{post}{tex}%
+ \the\everymp0{post}{tex}}
+\newtoks\mp:mpcode % see lua function scan_mp_chunk()
+\newtoks\mp:makempcode \mp:makempcode{%
+ \edef\minim:mp:tmp{%
+ \the\everymp0{pre}{mp}%
+ \the\everymp\mp:cur:inst{pre}{mp}%
+ \unexpanded{\the\mp:mpcode}%
+ \the\everymp\mp:cur:inst{post}{mp}%
+ \the\everymp0{post}{mp}}%
+ \edef\minim:mp:tmp{\minim:mp:tmp}%
+ \mp:mpcode=\expandafter{\minim:mp:tmp}}
+
% colour conversion: 1 grayscale 2 cmyk 3 rgb 4 rgb as spot
\newcount \convertmpcolours
\convertmpcolours = 0
@@ -62,10 +113,9 @@
\newcount\GtoG \GtoG = 7152
\newcount\BtoG \BtoG = 0722
+% miscellaneous bits and ends
\newtoks \everymaketext
+\def\mpdim#1{\the\dimexpr#1\relax}
\catcode`\: = \minimmploaded
-
-
-
diff --git a/macros/luatex/generic/minim-mp/minim.mp b/macros/luatex/generic/minim-mp/minim.mp
index b0df361b94..ed152a018b 100644
--- a/macros/luatex/generic/minim-mp/minim.mp
+++ b/macros/luatex/generic/minim-mp/minim.mp
@@ -1,8 +1,7 @@
if known minim.mp:
- message "skipping: already read";
expandafter endinput fi
-minim.mp := 1.3;
+minim.mp := 1.6;
% This file only contains code that is not specific to the minim metapost
% processor. See minim-mp.mp for the wireup of minim-mp’s extensions.
@@ -42,6 +41,9 @@ vardef clipto text t =
vardef clipout text t =
clip currentpicture to
for c = t: c -- cycle -- endfor cycle enddef;
+vardef getbounds primary p = % without bboxmargin
+ llcorner p -- lrcorner p -- urcorner p -- ulcorner p -- cycle
+enddef;
% cmyk colours
cmykcolor cyan, magenta, yellow, key;
@@ -50,12 +52,9 @@ magenta = (0,1,0,0);
yellow = (0,0,1,0);
key = (0,0,0,1);
-% also in minim-mp.mp
-if unknown rgb_to_gray red:
- vardef rgb_to_gray expr c =
- 0.2126*redpart c + 0.7152*greenpart c + 0.0722*bluepart c
- enddef;
-fi
+vardef rgb_to_gray expr c =
+ 0.2126*redpart c + 0.7152*greenpart c + 0.0722*bluepart c
+enddef;
% shorthands
def save_pen text t = save t; pen t; enddef;
@@ -91,3 +90,31 @@ vardef arc (expr thetafrom, thetalen) =
and (p - c) .. p
endfor; a enddef;
+% some linear algebra
+primarydef v extprod w = begingroup
+ xpart v * ypart w - ypart v * xpart w
+endgroup enddef;
+
+vardef collinear(expr p,q,r) =
+ (p <> q) and (q <> r) and (p <> r)
+ and (eps > abs( (p-q) extprod (q-r) ))
+enddef;
+
+% type helpers
+def typeof (expr v) =
+ if numeric v: numeric
+ elseif pair v: pair
+ elseif color v: color
+ elseif cmykcolor v: cmykcolor
+ elseif boolean v: boolean
+ elseif path v: path
+ elseif picture v: picture
+ elseif transform v: transform
+ elseif string v: string
+ elseif pen v: pen
+ fi enddef;
+
+vardef empty suffix s = save_boolean b;
+ b := string _EMPTY_ s; b enddef;
+string _EMPTY_;
+
diff --git a/macros/luatex/generic/minim/README b/macros/luatex/generic/minim/README
index a61e0f74ec..751c428bad 100644
--- a/macros/luatex/generic/minim/README
+++ b/macros/luatex/generic/minim/README
@@ -1,4 +1,4 @@
-Version: 2024/1.5
+Version: 2024/1.6
SUMMARY
@@ -31,7 +31,11 @@ the packages mentioned above.
HISTORY
-2024/1.4 (25/2/2024)
+2024/1.6 (25/3/2024)
+
+ No changes.
+
+2024/1.5 (25/2/2024)
No changes.
diff --git a/macros/luatex/generic/minim/minim-alloc.doc b/macros/luatex/generic/minim/minim-alloc.doc
index 5a343c4b85..b1f6ed77bd 100644
--- a/macros/luatex/generic/minim/minim-alloc.doc
+++ b/macros/luatex/generic/minim/minim-alloc.doc
@@ -123,17 +123,17 @@ functions will be called in order, each function receiving the result of the
last.
After one function returns ⟦false⟧, no others will be called.
Callbacks of this type are
-⟦pre_linebreak_filter⟧,
+⟦pre_output_filter⟧,
⟦post_linebreak_filter⟧,
+⟦pre_linebreak_filter⟧,
⟦hpack_filter⟧,
-⟦vpack_filter⟧,
-⟦pre_output_filter⟧ and
-⟦mlist_to_mlist⟧.
+⟦vpack_filter⟧
+and ⟦mlist_to_mlist⟧.
Similarly, for the ⟦*data⟧ callbacks
-⟦process_input_buffer⟧,
-⟦process_output_buffer⟧ and
⟦process_jobname⟧,
+⟦process_output_buffer⟧ and
+⟦process_input_buffer⟧,
all registered functions will be called in order on the output of the previous.
Returning ⟦false⟧ will in this case result in the output of the previous
function passing to the next.
@@ -237,7 +237,7 @@ the argument ⟦s⟧ to ⟦M.add_bookmark⟧ will consist of a table with at mos
following entries: ⟦open⟧, ⟦closed⟧, ⟦dest⟧ and ⟦title⟧, though entries whose
keywords do not occur will not be present.
-This function is particularly useful when used together with
+This function is particularly useful when used with
⟦*M.luadef('csname', function, ...)⟧, which defines primitive-like tex macros
from lua. There, ⟦function⟧ can be any function (it will be assigned a lua
function register) and at the place of the dots you may append ⟦'protected'⟧
diff --git a/macros/luatex/generic/minim/minim-alloc.lua b/macros/luatex/generic/minim/minim-alloc.lua
index ce53e5d440..3b14f5cc80 100644
--- a/macros/luatex/generic/minim/minim-alloc.lua
+++ b/macros/luatex/generic/minim/minim-alloc.lua
@@ -45,7 +45,7 @@ end
-- re-encode to utf-16
local function pdf_hex_string(text)
local str = { [1] = '<feff' }
- for i in text:utfvalues() do
+ for _, i in utf8.codes(text) do
if i <= 0xffff then
insert_formatted(str, '%04x', i)
else
diff --git a/macros/luatex/generic/minim/minim-alloc.tex b/macros/luatex/generic/minim/minim-alloc.tex
index 1b3ca06795..f83e043ad4 100644
--- a/macros/luatex/generic/minim/minim-alloc.tex
+++ b/macros/luatex/generic/minim/minim-alloc.tex
@@ -1,6 +1,6 @@
\ifdefined \minimloaded
- \message{(skipped)}
+ \wlog{(skipped)}
\expandafter\endinput\fi
\chardef\minimloaded=\catcode`\:
\catcode`\:=11
@@ -115,6 +115,10 @@
\ifdefined \documentclass
% latex has no \globcount etc.
\alloc:globoffset = 10
+ \ifnum\count10<256 \count10=256 \fi
+ \ifnum\count11<256 \count11=256 \fi
+ \ifnum\count12<256 \count12=256 \fi
+ \ifnum\count14<256 \count14=256 \fi
\else \ifdefined \globcount
% use global allocation (see etex.src)
\let\newcount = \globcount
diff --git a/macros/luatex/generic/minim/minim-doc.sty b/macros/luatex/generic/minim/minim-doc.sty
index 6f662dced6..32c8a1e991 100644
--- a/macros/luatex/generic/minim/minim-doc.sty
+++ b/macros/luatex/generic/minim/minim-doc.sty
@@ -7,6 +7,7 @@
\input minim
%\decompressedpdf
+%\debugmetapost
\pdfalevel 3a
\pdfualevel 1
@@ -97,7 +98,7 @@
% 1 the minim symbol
\newbox\notehead
-\newmetapostinstance \mnmMP
+\newmetapostinstance [jobname='logo'] \mnmMP
\runmetapost \mnmMP {
beginfig(1)
w:=1/27; pickup pencircle scaled 1/9;
diff --git a/macros/luatex/generic/minim/minim-hooks.tex b/macros/luatex/generic/minim/minim-hooks.tex
index deef66fc9a..da19182a48 100644
--- a/macros/luatex/generic/minim/minim-hooks.tex
+++ b/macros/luatex/generic/minim/minim-hooks.tex
@@ -16,7 +16,7 @@
% know if you run into any problems.
\ifdefined\minimhooksloaded
- \message{(skipped)}
+ \wlog{(skipped)}
\expandafter\endinput\fi
\chardef\minimhooksloaded = \catcode`\:
\catcode`\: = 11
@@ -48,7 +48,7 @@
{\expandafter}\the\minim:atnextpar}
\let\minim:changeparindent = \relax % as of yet unused
-% There is no need for the following.
+% There is presently no need for the following.
%\let\minim:par = \par
%\newtoks\minim:aftereverypar
diff --git a/macros/luatex/generic/minim/minim-lmodern.tex b/macros/luatex/generic/minim/minim-lmodern.tex
index e420dd2a1c..c169b77e57 100644
--- a/macros/luatex/generic/minim/minim-lmodern.tex
+++ b/macros/luatex/generic/minim/minim-lmodern.tex
@@ -3,7 +3,7 @@
% from plain.tex with latin modern equivalents.
\ifdefined\minimlmodernloaded
- \message{(skipped)}
+ \wlog{(skipped)}
\expandafter\endinput\fi
\chardef\minimlmodernloaded=\catcode`\:
\catcode`\:=11
diff --git a/macros/luatex/generic/minim/minim-pdfresources.lua b/macros/luatex/generic/minim/minim-pdfresources.lua
index 66d168f4ec..244d4c2bcd 100644
--- a/macros/luatex/generic/minim/minim-pdfresources.lua
+++ b/macros/luatex/generic/minim/minim-pdfresources.lua
@@ -77,8 +77,8 @@ end
-- those, the M.use_resouce() function will be called automatically.
--
local page_resources = init_resources() -- name ↦ '/Key <value>'
---
-function _with_pdf_resource_(kind, name) -- global, for use in latelua
+-- global, for use in latelua
+function _with_pdf_resource_(kind, name) --luacheck: ignore 111
page_resources[kind][name] = M.use_resource(kind, name)
end
function M.use_resource_node(kind, name)
diff --git a/macros/luatex/generic/minim/minim-pdfresources.tex b/macros/luatex/generic/minim/minim-pdfresources.tex
index 57e9d8f012..8ad794fe54 100644
--- a/macros/luatex/generic/minim/minim-pdfresources.tex
+++ b/macros/luatex/generic/minim/minim-pdfresources.tex
@@ -1,6 +1,6 @@
\ifdefined \minimpdfresourcesloaded
- \message{(skipped)}
+ \wlog{(skipped)}
\expandafter\endinput\fi
\chardef\minimpdfresourcesloaded=\catcode`\:
\catcode`\:=11
diff --git a/macros/luatex/generic/minim/minim.doc b/macros/luatex/generic/minim/minim.doc
index ef35a8ea4e..f1538c5724 100644
--- a/macros/luatex/generic/minim/minim.doc
+++ b/macros/luatex/generic/minim/minim.doc
@@ -4,8 +4,8 @@
\startmetadata
author {Esger Renkema}
title {minim}
- date {2024-02-25}
- version {2024/1.5}
+ date {2024-03-25}
+ version {2024/1.6}
keywords {LuaTeX; Plain TeX; MetaPost; PDF/A; Tagged PDF; accessibility; a11y;
Unicode mathematics; XMP; metadata; hypertext; bookmarks}
stopmetadata
diff --git a/macros/luatex/generic/minim/minim.pdf b/macros/luatex/generic/minim/minim.pdf
index e632089dfa..e7a0519965 100644
--- a/macros/luatex/generic/minim/minim.pdf
+++ b/macros/luatex/generic/minim/minim.pdf
Binary files differ
diff --git a/macros/luatex/latex/gitinfo-lua/doc/gitinfo-lua.pdf b/macros/luatex/latex/gitinfo-lua/doc/gitinfo-lua.pdf
index 02edd681a7..693b905da3 100644
--- a/macros/luatex/latex/gitinfo-lua/doc/gitinfo-lua.pdf
+++ b/macros/luatex/latex/gitinfo-lua/doc/gitinfo-lua.pdf
Binary files differ
diff --git a/macros/luatex/latex/gitinfo-lua/doc/gitinfo-lua.tex b/macros/luatex/latex/gitinfo-lua/doc/gitinfo-lua.tex
index ef7781dd01..fe7bdd4e97 100644
--- a/macros/luatex/latex/gitinfo-lua/doc/gitinfo-lua.tex
+++ b/macros/luatex/latex/gitinfo-lua/doc/gitinfo-lua.tex
@@ -103,6 +103,7 @@ latexmk -pvc -lualatex -shell-escape main
Note that in both cases option \texttt{-shell-escape} is required.
This is required for issuing \texttt{git} via the commandline.
+ When utilizing the continuous compilation option \texttt{-pvc} with \texttt{latexmk}, it's important to note that only committed changes will be detected, while tag changes, unfortunately, won't be recognized.
\section{LaTeX Interface}
diff --git a/macros/luatex/latex/gitinfo-lua/scripts/gitinfo-lua-cmd.lua b/macros/luatex/latex/gitinfo-lua/scripts/gitinfo-lua-cmd.lua
index 5aa0dc56e5..68ac3c09a9 100644
--- a/macros/luatex/latex/gitinfo-lua/scripts/gitinfo-lua-cmd.lua
+++ b/macros/luatex/latex/gitinfo-lua/scripts/gitinfo-lua-cmd.lua
@@ -1,5 +1,5 @@
-- gitinfo-lua-cmd.lua
--- Copyright 2023 E. Nijenhuis
+-- 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
@@ -14,14 +14,15 @@
-- The Current Maintainer of this work is E. Nijenhuis.
--
-- This work consists of the files gitinfo-lua.sty gitinfo-lua.pdf
--- gitinfo-cmd.lua and gitinfo-lua.lua
+-- gitinfo-lua-cmd.lua, gitinfo-lua-recorder.lua and gitinfo-lua.lua
local api = {
cwd = nil,
executable = 'git',
default_sort = '',
attribute_separator = '\\pop',
- record_separator = '\\end'
+ record_separator = '\\end',
+ recorder = require('gitinfo-lua-recorder')
}
local cache = {}
function cache:seek(_key)
@@ -40,6 +41,7 @@ end
function api:exec(command, do_caching, target_dir)
local cmd = self.executable .. ' ' .. command
local cwd = target_dir or self.cwd
+ api.recorder.record_head(cwd)
if cwd then
cmd = 'cd ' .. cwd .. ' && ' .. cmd
end
diff --git a/macros/luatex/latex/gitinfo-lua/scripts/gitinfo-lua-recorder.lua b/macros/luatex/latex/gitinfo-lua/scripts/gitinfo-lua-recorder.lua
new file mode 100644
index 0000000000..8d4aa78af2
--- /dev/null
+++ b/macros/luatex/latex/gitinfo-lua/scripts/gitinfo-lua-recorder.lua
@@ -0,0 +1,79 @@
+-- gitinfo-lua-recorder.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 gitinfo-lua.sty gitinfo-lua.pdf
+-- gitinfo-lua-cmd.lua, gitinfo-lua-recorder.lua and gitinfo-lua.lua
+
+local kpse = kpse or require('kpse')
+local texio = texio or require('texio')
+
+local api = {
+ record_list = {}
+}
+
+---record_head
+---Records .git/HEAD and .git/refs/heads/<branch> respectively,
+---in order to trigger a rebuild in LaTeX.
+---@param git_directory string
+function api.record_head(git_directory)
+ local head_path = '.git/HEAD'
+ if git_directory then
+ head_path = git_directory .. head_path
+ end
+ if not api.record_list[head_path] then
+ api.record_list[head_path] = true
+ if kpse.in_name_ok(head_path) then
+ local head_file = io.open(head_path, 'rb')
+ if not head_file then
+ texio.write_nl('Warning: couldn\'t read HEAD from git project directory')
+ return
+ end
+ kpse.record_input_file(head_path)
+ texio.write_nl('Info: recording input file ' .. head_path)
+ local head_info = head_file:read('*a')
+ head_file:close()
+ local i, j = string.find(head_info, '^ref: .+\n$')
+ local ref_path = string.sub(head_info, i + 5, j-1)
+ if not ref_path then
+ texio.write_nl('Warning: couldn\'t find ref of HEAD')
+ return
+ end
+ ref_path = '.git/' .. ref_path
+ if git_directory then
+ ref_path = git_directory .. ref_path
+ end
+ if kpse.in_name_ok(ref_path) then
+ kpse.record_input_file(ref_path)
+ texio.write_nl('Info: recording input file ' .. ref_path)
+ else
+ texio.write_nl('Warning: couldn\'t read ref file: ' .. ref_path)
+ end
+ else
+ texio.write_nl('Couldn\'t open input file ' .. head_path)
+ end
+ end
+end
+
+
+
+local gitinfo_recorder = {}
+local gitinfo_recorder_mt = {
+ __index = api,
+ __newindex = nil
+}
+
+setmetatable(gitinfo_recorder, gitinfo_recorder_mt)
+
+return gitinfo_recorder
diff --git a/macros/luatex/latex/gitinfo-lua/scripts/gitinfo-lua.lua b/macros/luatex/latex/gitinfo-lua/scripts/gitinfo-lua.lua
index 0f3a1315d3..cba19b19d7 100644
--- a/macros/luatex/latex/gitinfo-lua/scripts/gitinfo-lua.lua
+++ b/macros/luatex/latex/gitinfo-lua/scripts/gitinfo-lua.lua
@@ -1,5 +1,5 @@
-- gitinfo-lua.lua
--- Copyright 2023 E. Nijenhuis
+-- 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
@@ -14,7 +14,7 @@
-- The Current Maintainer of this work is E. Nijenhuis.
--
-- This work consists of the files gitinfo-lua.sty gitinfo-lua.pdf
--- gitinfo-cmd.lua and gitinfo-lua.lua
+-- gitinfo-lua-cmd.lua, gitinfo-lua-recorder.lua and gitinfo-lua.lua
if not modules then
modules = {}
@@ -23,8 +23,8 @@ end
local module = {
name = 'gitinfo-lua',
info = {
- version = '1.0.2', --TAGVERSION
- date = '2024/02/23', --TAGDATE
+ version = '1.0.3', --TAGVERSION
+ date = '2024/04/02', --TAGDATE
comment = "Git info Lua — Git integration with LaTeX",
author = "Erik Nijenhuis",
license = "free"
@@ -81,58 +81,6 @@ function api:escape_str(value)
return buf
end
--- experimental
-function api:get_tok()
- if self.cur_tok == nil then
- self.cur_tok = token.get_next()
- end
- return self.cur_tok
-end
-
--- experimental
-function api:parse_opts()
- local tok = self:get_tok()
- if tok.cmdname == 'other_char' then
- --token.put_next(tok)
- local opts = token.scan_word()
- self.cur_tok = nil
- -- todo: parse []
- return opts
- end
-end
-
--- experimental
-function api:parse_arguments(argc)
- local result_list = {}
- for _ = 1, argc do
- local tok = self:get_tok()
- if tok.cmdname == 'left_brace' then
- token.put_next(tok)
- table.insert(result_list, token.scan_argument())
- self.cur_tok = nil
- else
- tex.error("Expected left brace")
- return
- end
- end
- return table.unpack(result_list)
-end
-
--- experimental
-function api:parse_macro()
- --tex.print('\\noexpand')
- local tok = self:get_tok()
- if (tok.cmdname == 'call') or tok.cmdname == 'long_call' then
- self.cur_tok = nil
- return tok
- else
- tex.error("Expected Macro")
- for i = 1, 5 do
- local _tok = token.get_next()
- end
- end
-end
-
function api:dir(path)
self.cmd.cwd = path
end
diff --git a/macros/luatex/latex/gitinfo-lua/tex/gitinfo-lua.sty b/macros/luatex/latex/gitinfo-lua/tex/gitinfo-lua.sty
index 3f850a1146..c9ab3a4cd6 100644
--- a/macros/luatex/latex/gitinfo-lua/tex/gitinfo-lua.sty
+++ b/macros/luatex/latex/gitinfo-lua/tex/gitinfo-lua.sty
@@ -1,5 +1,5 @@
%% gitinfo-lua.sty
-%% Copyright 2023 E. Nijenhuis
+%% 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
@@ -14,9 +14,9 @@
% The Current Maintainer of this work is E. Nijenhuis.
%
% This work consists of the files gitinfo-lua.sty gitinfo-lua.pdf
-% gitinfo-cmd.lua and gitinfo-lua.lua
+% gitinfo-lua-cmd.lua, gitinfo-lua-recorder.lua and gitinfo-lua.lua
\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{gitinfo-lua}[2024/02/23 1.0.2 Xerdi's Git Package]
+\ProvidesPackage{gitinfo-lua}[2024/04/02 1.0.3 Xerdi's Git Package]
\RequirePackage{luacode}
diff --git a/macros/luatex/latex/lua-placeholders/README.md b/macros/luatex/latex/lua-placeholders/README.md
index 6859910816..b1b43e23b9 100644
--- a/macros/luatex/latex/lua-placeholders/README.md
+++ b/macros/luatex/latex/lua-placeholders/README.md
@@ -1,5 +1,6 @@
# Lua(TeX) Placeholders
![CTAN Version](https://img.shields.io/ctan/v/lua-placeholders)
+[![build](https://github.com/Xerdi/lua-placeholders/actions/workflows/build.yml/badge.svg)](https://github.com/Xerdi/lua-placeholders/actions/workflows/build.yml)
A LaTeX package for specifying and inserting document placeholders with JSON or YAML formats.
diff --git a/macros/luatex/latex/lua-placeholders/doc/lua-placeholders-example/example.pdf b/macros/luatex/latex/lua-placeholders/doc/lua-placeholders-example/example.pdf
index 979941c702..a91d000cdd 100644
--- a/macros/luatex/latex/lua-placeholders/doc/lua-placeholders-example/example.pdf
+++ b/macros/luatex/latex/lua-placeholders/doc/lua-placeholders-example/example.pdf
Binary files differ
diff --git a/macros/luatex/latex/lua-placeholders/doc/lua-placeholders-manual.pdf b/macros/luatex/latex/lua-placeholders/doc/lua-placeholders-manual.pdf
index 2054633991..6a5c5860ad 100644
--- a/macros/luatex/latex/lua-placeholders/doc/lua-placeholders-manual.pdf
+++ b/macros/luatex/latex/lua-placeholders/doc/lua-placeholders-manual.pdf
Binary files differ
diff --git a/macros/luatex/latex/lua-placeholders/doc/lua-placeholders-manual.tex b/macros/luatex/latex/lua-placeholders/doc/lua-placeholders-manual.tex
index 210270b939..ff078470c1 100644
--- a/macros/luatex/latex/lua-placeholders/doc/lua-placeholders-manual.tex
+++ b/macros/luatex/latex/lua-placeholders/doc/lua-placeholders-manual.tex
@@ -91,13 +91,12 @@
For proper number formatting package \texttt{numprint}\cite{numprint} is required.
\subsubsection{YAML Support}
- If you're using JSON as \meta{recipe} and \meta{payload} format, the following requirements are no longer needed, since Lua\TeX{} already supports JSON formats out of the box.
+ Starting from version 1.0.2, the preferred YAML implementation has changed from \texttt{lyaml}\cite{lyaml} to \texttt{lua-tinyyaml}\cite{lua-tinyyaml}.
+ The reason for this change is that \texttt{lua-tinyyaml} doesn't require any platform-specific dependencies, such as \texttt{libYAML}\cite{libYAML}.
+
+ The older YAML implementation will still function for older installations that do not have \texttt{lua-tinyyaml}.
+ As before, when no YAML implementation is found, \texttt{lua-placeholders} will fall back to JSON support.
- For YAML support, however, this package requires the \texttt{lyaml}\cite{lyaml} Lua module for parsing the YAML files.
- This also includes the \texttt{libYAML}\cite{libYAML} platform dependent library and optionally LuaRocks for installing \texttt{lyaml}.
- Another requirement is Lua, which version meets the Lua version used by Lua\TeX{}.
- If no \texttt{LUA\_PATH} is set, and you use LuaRocks, this package tries to call the LuaRocks executable to find the \texttt{LUA\_PATH}.
- If \texttt{lyaml} can't be loaded, this package will first try to fall back with \texttt{lua-tinyyaml}\cite{lua-tinyyaml} for lesser YAML support and secondly fall back on accepting JSON files only.
\clearpage
\section{Usage}
@@ -115,6 +114,7 @@
\DescribeMacro{\loadpayload} The same behaviour counts for \cmd{\loadpayload}\oarg{namespace}\marg{filename}.
The order of loading \meta{recipe} and \meta{payload} files doesn't matter.
If the \meta{payload} file got loaded first, it will be yielded until the corresponding \meta{recipe} file is loaded.
+ When a file is loaded, a \LaTeX\ hook will trigger once for \texttt{namespace/\meta{namespace}} and once for \texttt{namespace\meta{namespace}/loaded}, respectively.
All other macros of this package also take the optional \meta{namespace}, which by default is equal to \cmd{\jobname}.
\DescribeMacro{\setnamespace} This default \meta{namespace} can be changed with \cmd{\setnamespace}\marg{new default namespace}.\\
diff --git a/macros/luatex/latex/lua-placeholders/scripts/lua-placeholders-parser.lua b/macros/luatex/latex/lua-placeholders/scripts/lua-placeholders-parser.lua
index 4a0304c463..0de9d25c9c 100644
--- a/macros/luatex/latex/lua-placeholders/scripts/lua-placeholders-parser.lua
+++ b/macros/luatex/latex/lua-placeholders/scripts/lua-placeholders-parser.lua
@@ -19,6 +19,7 @@
-- lua-placeholders-parser.lua and lua-placeholders-types.lua
local LUA_VERSION = string.sub(_VERSION, 5, -1)
+local kpse = kpse or require('kpse')
yaml_supported = false
@@ -87,6 +88,7 @@ return function(filename)
end
local raw = file:read "*a"
file:close()
+ kpse.record_input_file(filename)
if ext == 'json' then
return utilities.json.tolua(raw)
else
diff --git a/macros/luatex/latex/lua-placeholders/scripts/lua-placeholders.lua b/macros/luatex/latex/lua-placeholders/scripts/lua-placeholders.lua
index 24f0a6c5ca..98c2b13416 100644
--- a/macros/luatex/latex/lua-placeholders/scripts/lua-placeholders.lua
+++ b/macros/luatex/latex/lua-placeholders/scripts/lua-placeholders.lua
@@ -23,8 +23,8 @@ if not modules then
end
modules.lua_placeholders = {
- version = "1.0.2",
- date = "2024/02/21",
+ version = "1.0.3",
+ date = "2024/04/02",
comment = 'Lua Placeholders — for specifying and inserting document parameters',
author = 'Erik Nijenhuis',
license = 'free'
@@ -78,7 +78,10 @@ function api.recipe(path, namespace_name)
else
namespace:load_recipe(raw_recipe)
end
+ tex.print('\\NewHook{namespace/' .. name .. '}')
+ tex.print('\\NewHook{namespace/' .. name .. '/loaded}')
tex.print('\\UseOneTimeHook{namespace/' .. name .. '}')
+ texio.write_nl(name)
if namespace.payload_file and not namespace.payload_loaded then
local raw_payload = load_resource(namespace.payload_file)
if raw_payload.namespace then
diff --git a/macros/luatex/latex/lua-placeholders/tex/lua-placeholders.sty b/macros/luatex/latex/lua-placeholders/tex/lua-placeholders.sty
index 1d2a26f720..ddba421f49 100644
--- a/macros/luatex/latex/lua-placeholders/tex/lua-placeholders.sty
+++ b/macros/luatex/latex/lua-placeholders/tex/lua-placeholders.sty
@@ -19,7 +19,7 @@
% lua-placeholders-parser.lua and lua-placeholders-types.lua
\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{lua-placeholders}[2024/02/21 1.0.2 Lua Placeholders Package]
+\ProvidesPackage{lua-placeholders}[2024/04/02 1.0.3 Lua Placeholders Package]
\RequirePackage{ifthen}
\RequirePackage{luapackageloader}