diff options
author | Karl Berry <karl@freefriends.org> | 2020-07-21 21:39:07 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2020-07-21 21:39:07 +0000 |
commit | a4824d556273f90fbb37d24449cca150397ab7f2 (patch) | |
tree | 27fa3e556270c65afd257af5c0e69168c8c2633b /Master | |
parent | a5ed6b49fd24fce0a996e8db92f76022c41c5007 (diff) |
latex-dev (21jul20)
git-svn-id: svn://tug.org/texlive/trunk@55898 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master')
174 files changed, 11120 insertions, 472 deletions
diff --git a/Master/texmf-dist/doc/latex-dev/base/README.md b/Master/texmf-dist/doc/latex-dev/base/README.md index f2eb61eca38..6fcc4e9a1fe 100644 --- a/Master/texmf-dist/doc/latex-dev/base/README.md +++ b/Master/texmf-dist/doc/latex-dev/base/README.md @@ -1,7 +1,7 @@ The LaTeX kernel ================ -Release 2020-10-01 pre-release 6 +Release 2020-10-01 pre-release 7 Overview -------- diff --git a/Master/texmf-dist/doc/latex-dev/base/alltt.pdf b/Master/texmf-dist/doc/latex-dev/base/alltt.pdf Binary files differindex 033cb5ff35e..9931c1aa9a5 100644 --- a/Master/texmf-dist/doc/latex-dev/base/alltt.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/alltt.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/cfgguide.pdf b/Master/texmf-dist/doc/latex-dev/base/cfgguide.pdf Binary files differindex 4c6572d7a33..0825e5ce68b 100644 --- a/Master/texmf-dist/doc/latex-dev/base/cfgguide.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/cfgguide.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/changes.txt b/Master/texmf-dist/doc/latex-dev/base/changes.txt index 6c37210ae9a..1ef6f2cd44e 100644 --- a/Master/texmf-dist/doc/latex-dev/base/changes.txt +++ b/Master/texmf-dist/doc/latex-dev/base/changes.txt @@ -6,12 +6,82 @@ completeness or accuracy and it contains some references to files that are not part of the distribution. ================================================================================ +2020-07-16 Frank Mittelbach <Frank.Mittelbach@latex-project.org> + + * ltmiscen.dtx: \begin should not be long for better + error recovery (gh/354) + +2020-07-09 Frank Mittelbach <Frank.Mittelbach@latex-project.org> + + * lthooks.dtx, ltshipout.dtx, ltfilehook.dtx: + Integrate hook management into the kernel + +2020-07-08 Joseph Wright <joseph.wright@latex-project.org> + + * ltexpl.dtx: + Add hook \@expl@finalise@setup@@ + + * ltfinal.dtx: + Execute hook \@expl@finalise@setup@@ + +2020-07-07 Johannes Braams <Johannes.Braams@latex-project.org> + + * docstrip.dtx: Merge the @@-module functionality of + l3docstrip.dtx into docstrip.dtx (gh/337) + +2020-07-04 Marcel Krüger <Marcel.Krueger@latex-project.org> + + * ltoutenc.dtx: + Suppress tlig ligatures in LuaTeX without font reloading (gh/165) + +2020-06-15 Frank Mittelbach <Frank.Mittelbach@latex-project.org> + + * doc.dtx (subsection{Macros surrounding the `definition parts'}): + Void \@labels for vertical typesetting (gh/344) + +2020-06-05 Phelype Oleinik <phelype.oleinik@latex-project.org> + + * ltdefns.dtx (subsection{Loading further extensions}): + Moved loading of ltexpl.ltx earlier (from ltfinal.dtx) to ltdefns to + allow usage of expl3 extensions while loading the kernel. Further + changes to support this one listed below: + + * ltfinal.dtx: + Removed loading of ltexpl.ltx + + * ltclass.dtx: + Added \@expl@push@filename@@ and \@expl@push@filename@aux@@ to + \@pushfilename and \@expl@pop@filename@@ to \@popfilename. + + * ltfiles.dtx (section{File Handling}): + Added \@expl@sys@load@backend@@ in \document. + + * ltexpl.dtx: + - Added blank definitions for \@expl@sys@load@backend@@, + \@expl@push@filename@@, \@expl@push@filename@aux@@, and + \@expl@pop@filename@@. + - Added temporary definitions for some kernel commands. + +2020-06-04 Marcel Krüger <Marcel.Krueger@latex-project.org> + + * format.ins: Load ltluatex.dtx before ltdefns.dtx + +2020-05-31 Frank Mittelbach <Frank.Mittelbach@latex-project.org> + + * ltmiscen.dtx (subsection{Center, Flushright, Flushleft}): + % Added \finalhyphendemerits=0 to avoid extra line in + \centering, \raggedleft or \raggedright (gh/247) + 2020-05-19 Frank Mittelbach <Frank.Mittelbach@latex-project.org> * ltfssini.dtx (section{Custom series settings for main document families}): Added \IfFontSeriesContextTF so that it is possible to reliably detect the current font series context (gh/335) +2020-05-17 Johannes Braams <Johannes.Braams@latex-project.org> + + * ltxdoc.dtx: Support spaces within filenames (gh/218) + 2020-05-15 Frank Mittelbach <Frank.Mittelbach@latex-project.org> * ltdefns.dtx (subsection{Initex initialisations}): @@ -20,8 +90,8 @@ are not part of the distribution. 2020-05-11 Marcel Krüger <Marcel.Krueger@latex-project.org> - * ltdefns.dtx: - Use primitive \- with LuaTeX + * ltdefns.dtx: + Use primitive \- with LuaTeX 2020-05-07 Ulrike Fischer <Ulrike.Fischer@latex-project.org> @@ -30,15 +100,15 @@ are not part of the distribution. 2020-05-06 Marcel Krüger <Marcel.Krueger@latex-project.org> - * ltspace.dtx: - Make Unicode softhyphen U+00AD active and defined as \-. + * ltspace.dtx: + Make Unicode softhyphen U+00AD active and defined as \-. -2020-05-02 Johannes Braams <texniek at braams.xs4all.nl> +2020-05-02 Johannes Braams <Johannes.Braams@latex-project.org> * ltexpl.dtx: Created aliases for two expl3 macros in order to use them to remove leading and trailing spaces from filenames (gh/217) -2020-05-02 Johannes Braams <texniek at braams.xs4all.nl> +2020-05-02 Johannes Braams <Johannes.Braams@latex-project.org> * ltfiles.dtx: Modified \include and \includeony to support filenames with spaces in them (gh/217) @@ -132,7 +202,7 @@ are not part of the distribution. * ltmath.dtx (subsubsection{The UNSORTED Rest}): Add \texttt{amsmath} math/text spacing commands to the kernel (gh/303) -2020-03-08 Johannes Braams <texniek at braams.xs4all.nl> +2020-03-08 Johannes Braams <Johannes.Braams@latex-project.org> * letter.dtx: merged changes to classes.dtx into letter.dtx diff --git a/Master/texmf-dist/doc/latex-dev/base/classes.pdf b/Master/texmf-dist/doc/latex-dev/base/classes.pdf Binary files differindex 1c33a811b0c..d8f283622a1 100644 --- a/Master/texmf-dist/doc/latex-dev/base/classes.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/classes.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/clsguide.pdf b/Master/texmf-dist/doc/latex-dev/base/clsguide.pdf Binary files differindex ef43b41db09..3bcc695f6b3 100644 --- a/Master/texmf-dist/doc/latex-dev/base/clsguide.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/clsguide.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/cmfonts.pdf b/Master/texmf-dist/doc/latex-dev/base/cmfonts.pdf Binary files differindex cd291a5f9a5..ac154a6eea4 100644 --- a/Master/texmf-dist/doc/latex-dev/base/cmfonts.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/cmfonts.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/cyrguide.pdf b/Master/texmf-dist/doc/latex-dev/base/cyrguide.pdf Binary files differindex 2bbc7d8f185..4ecc0eec71c 100644 --- a/Master/texmf-dist/doc/latex-dev/base/cyrguide.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/cyrguide.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/doc.pdf b/Master/texmf-dist/doc/latex-dev/base/doc.pdf Binary files differindex f4f1b1fa76b..76dc52e218a 100644 --- a/Master/texmf-dist/doc/latex-dev/base/doc.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/doc.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/docstrip.pdf b/Master/texmf-dist/doc/latex-dev/base/docstrip.pdf Binary files differindex 3f74e31d4e8..67d5187d442 100644 --- a/Master/texmf-dist/doc/latex-dev/base/docstrip.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/docstrip.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/encguide.pdf b/Master/texmf-dist/doc/latex-dev/base/encguide.pdf Binary files differindex d651b88475d..d54e91c1967 100644 --- a/Master/texmf-dist/doc/latex-dev/base/encguide.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/encguide.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/exscale.pdf b/Master/texmf-dist/doc/latex-dev/base/exscale.pdf Binary files differindex 65bc658e9e7..39cb0b1d14a 100644 --- a/Master/texmf-dist/doc/latex-dev/base/exscale.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/exscale.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/fix-cm.pdf b/Master/texmf-dist/doc/latex-dev/base/fix-cm.pdf Binary files differindex 2cd2d911b82..64c783ef042 100644 --- a/Master/texmf-dist/doc/latex-dev/base/fix-cm.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/fix-cm.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/fntguide.pdf b/Master/texmf-dist/doc/latex-dev/base/fntguide.pdf Binary files differindex 2b2017d5019..2af45dc5f7b 100644 --- a/Master/texmf-dist/doc/latex-dev/base/fntguide.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/fntguide.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/fntguide.tex b/Master/texmf-dist/doc/latex-dev/base/fntguide.tex index 8610bc99f77..b6576a02370 100644 --- a/Master/texmf-dist/doc/latex-dev/base/fntguide.tex +++ b/Master/texmf-dist/doc/latex-dev/base/fntguide.tex @@ -33,12 +33,16 @@ \documentclass{ltxguide}[1995/11/28] +\usepackage{varioref} + \title{\LaTeXe{} font selection} -\author{\copyright~Copyright 1995--2019, \LaTeX3 Project Team.\\ +\author{\copyright~Copyright 1995--2020, \LaTeX3 Project + Team.\thanks{Thanks to Arash Esbati for documenting the + newer NFSS features of 2020}\\ All rights reserved.} -\date{October 2019} +\date{July 2020} \begin{document} @@ -284,14 +288,26 @@ naming scheme to allow for sensible default substitutions if necessary, e.g., ``demi-bold'' is normally just another name for ``semi-bold'', so should get |sb| assigned, etc. +\NEWdescription{2020/02/02} The most common values for the font shape are: \begin{center} \begin{minipage}{.7\linewidth} \begin{tabular}{rl} - |n| & Normal (that is `upright' or `roman') \\ - |it| & Italic \\ - |sl| & Slanted (or `oblique') \\ - |sc| & Caps and small caps + |n| & Normal (that is `upright' or `roman') \\ + |it| & Italic \\ + |sl| & Slanted (or `oblique') \\ + |sc| & Caps and small caps \\ + |scit| & Caps and small caps italic \\ + |scsl| & Caps and small caps slanted \\ + |sw| & Swash + \end{tabular} + \end{minipage} +\end{center} +A less common value for font shape is: +\begin{center} + \begin{minipage}{.7\linewidth} + \begin{tabular}{rl} + |ssc| & Spaced caps and small caps \end{tabular} \end{minipage} \end{center} @@ -337,6 +353,9 @@ The author commands for fonts set the five attributes: |\textit{..}| or |\itshape| & shape & |it| \\ |\textsl{..}| or |\slshape| & shape & |sl| \\ |\textsc{..}| or |\scshape| & shape & |sc| \\ + |\textssc{..}| or |\sscshape| & shape & |ssc| \\ + |\textsw{..}| or |\swshape| & shape & |sw| \\ + |\textulc{..}| or |\ulcshape| & shape & |ulc| \\ |\tiny| & size & |5pt| \\ |\scriptsize| & size & |7pt| \\ |\footnotesize| & size & |8pt| \\ @@ -489,14 +508,27 @@ the fonts provided by |psnfss|) is to define silent substitutions from and the |ssub| size function, see Section~\ref{sec:sizefunct}. \begin{decl} - |\itdefault| \\ - |\sldefault| \\ - |\scdefault| \\ + |\itdefault| \\ + |\sldefault| \\ + |\scdefault| \\ + |\sscdefault| \\ + |\swdefault| \\ + |\ulcdefault| \\ |\updefault| \end{decl} +\NEWfeature{2020/02/02} The shapes selected by |\textit|, |\itshape|, |\textsl|, |\slshape|, -|\textsc|, |\scshape|, |\textup| and |\upshape|. By default these are -|it|, |sl|, |sc| and |n|. +|\textsc|, |\scshape|, |\textssc|, |\sscshape|, |\textsw|, |\swshape|, +|\textulc|, |\ulcshape|, |\textup| and |\upshape|. By default these are +|it|, |sl|, |sc|, |ssc|, |sw|, |ulc| and |n|. |ulc| is special here +since it is a virtual one; it doesn't exist as a real shape. The +respective macros |\textulc| or |\ulcshape| change small capitals back +to upper/lower case but will not change the font with respect to +italics, slanted or swash. |\upshape| or |\textup| in contrast will +switch italics or slanted back to upright but not alter the state of +upper/lower case, e.g., keep small capitals if present. Finally, the +command |\normalshape| is provided to reset the shape back to normal +which is a shorthand for |\upshape\ulcshape|. Note that there are no parameters for the size commands. These should be defined directly in class files, for example: @@ -1874,6 +1906,264 @@ dependencies that you have to obey: declarations. \end{itemize} +\subsection{Font series defaults per document family} + +\NEWfeature{2020/02/02} +With additional weights and widths being available in many font families +nowadays, it is more likely that somebody will want to match, say, a +medium weight serif family with a semi-light sans serif family, or that +with one family one wants to use the bold-extended face when |\textbf| +is used, while with another it should be bold (not extended) or +semi-bold, etc. The default values can be altered using the +|\DeclareFontSeriesDefault| declaration in packages or document +preambles: +\begin{decl} + |\DeclareFontSeriesDefault| \oarg{meta family} + \arg{meta series} \arg{series value} +\end{decl} +This declaration takes three arguments: +\begin{description} +\item[Meta family interface:] Can be either |rm|, |sf| or |tt|. This is + optional and if not present the next two arguments apply to the + overall default. +\item[Meta series interface:] Can be |md| or |bf|. +\item[Series value:] This is the value that is going to be used when the + combination of \m{meta family} and \m{meta series} is requested. +\end{description} +For example, +\begin{verbatim} + \DeclareFontSeriesDefault[rm]{bf}{sb} +\end{verbatim} +would use |sb| (semi-bold) when |\rmfamily\bfseries| is requested in +document. + +\subsection{Handling of nested emphasis} + +\begin{decl} + |\DeclareEmphSequence| \arg{list of font declarations} +\end{decl} + +\NEWfeature{2020/02/02} +This declaration takes a comma separated list of font declarations each +specifying how increasing levels of emphasis should be handled. For +example: +\begin{verbatim} + \DeclareEmphSequence{\itshape,% + \upshape\scshape,% + \itshape} +\end{verbatim} +uses italics for the first, small capitals for the second, and italic +small capitals for the third level. If there are more nesting levels +than provided, declarations stored in |\emreset| (by default +|\ulcshape\upshape|) are used for the next level and then the list +restarts. + +\subsection{Providing font family substitutions} + +\begin{decl} + |\DeclareFontFamilySubstitution| \arg{encoding} + \arg{family} + \arg{new-family} +\end{decl} + +\NEWfeature{2020/02/02} +This declaration selects the font family \m{new-family} as replacement +for \m{family} in the font encoding \m{encoding}. For example, +\begin{verbatim} + \DeclareFontFamilySubstitution{LGR} + {Montserrat-LF}{IBMPlexSans-TLF} +\end{verbatim} +tells \LaTeX{} to substitute the sans serif font |Montserrat-LF| in the +Greek encoding |LGR| with |IBMPlexSans-TLF| once requested in a +document. + +\section{Additional text symbols -- \textsf{textcomp}} + +\NEWfeature{2020/02/02} +For a long time the interface to additional text symbols and the text +companion encoding |TS1| in general was the \textsf{textcomp} package. +All the symbols provided by the \textsf{textcomp} package are now +available in \LaTeX{} kernel. Furthermore, an intelligent substitution +mechanism has been implemented so that glyphs missing in some fonts are +automatically substituted with default glyphs that are sans serif if you +typeset in |\textsf| and monospaced if you typeset using |\texttt|. In +the past they were always taken from Computer Modern Roman if +substitution was necessary. + +{\sffamily This is most noticeable with |\oldstylenums| which are now + taken from |TS1| so that you no longer get \legacyoldstylenums{1234} + but \oldstylenums{1234} when typesetting in sans serif fonts \ttfamily + and \oldstylenums{1234} when using typewriter fonts.} + +\begin{decl} + |\legacyoldstylenums| \arg{nums}\\ + |\UseLegacyTextSymbols| +\end{decl} +If there ever is a need to use the original (inferior) definition, then +that remains available as |\legacyoldstylenums|; and to fully revert to +the old behavior there is also |\UseLegacyTextSymbols|. The latter +declaration reverts |\oldstylenums| and also changes the footnote +symbols, such as |\textdagger|, |\textparagraph|, etc., to pick up their +glyphs from the math fonts instead of the current text font (this means +they always keep the same shape and do not nicely blend in with the text +font). + +The following tables show the macros available. The next commands are +`constructed' accents and are built via \TeX{} macros: +\begin{center} + \begin{tabular}[t]{@{}ll} + \verb*|\capitalcedilla A| & \capitalcedilla A \\ + \verb*|\capitalogonek A| & \capitalogonek A \\ + \verb*|\textcircled a| & \textcircled a + \end{tabular} +\end{center} + +These accents are available via font encoding. The numbers in third row +show the slot number: +\begin{center} + \begin{tabular}[t]{@{}p{0.32\linewidth}p{1em}p{2em}@{}} + \verb|\capitalgrave| & \capitalgrave{} & 0 \\ + \verb|\capitalacute| & \capitalacute{} & 1 \\ + \verb|\capitalcircumflex| & \capitalcircumflex{} & 2 \\ + \verb|\capitaltilde| & \capitaltilde{} & 3 \\ + \verb|\capitaldieresis| & \capitaldieresis{} & 4 \\ + \verb|\capitalhungarumlaut| & \capitalhungarumlaut{} & 5 \\ + \verb|\capitalring| & \capitalring{} & 6 \\ + \verb|\capitalcaron| & \capitalcaron{} & 7 + \end{tabular} + \quad + \begin{tabular}[t]{@{}p{0.32\linewidth}p{1em}p{2em}@{}} + \verb|\capitalbreve| & \capitalbreve{} & 8 \\ + \verb|\capitalmacron| & \capitalmacron{} & 9 \\ + \verb|\capitaldotaccent| & \capitaldotaccent{} & 10 \\ + \verb|\t| & \t{} & 26 \\ + \verb|\capitaltie| & \capitaltie{} & 27 \\ + \verb|\newtie| & \newtie{} & 28 \\ + \verb|\capitalnewtie| & \capitalnewtie{} & 29 + \end{tabular} +\end{center} + +Table~\vref{tab:textcomp} contains macros to access text symbols. Again, +the numbers are the slots in the encoding. + +\begin{table} +\centering\footnotesize + \begin{tabular}[t]{@{}lp{1.5em}l@{}} + \verb|\textcapitalcompwordmark| & \textcapitalcompwordmark & 23 \\ + \verb|\textascendercompwordmark| & \textascendercompwordmark & 31 \\ + \verb|\textquotestraightbase| & \textquotestraightbase & 13 \\ + \verb|\textquotestraightdblbase| & \textquotestraightdblbase & 18 \\ + \verb|\texttwelveudash| & \texttwelveudash & 21 \\ + \verb|\textthreequartersemdash| & \textthreequartersemdash & 22 \\ + \verb|\textleftarrow| & \textleftarrow & 24 \\ + \verb|\textrightarrow| & \textrightarrow & 25 \\ + \verb|\textblank| & \textblank & 32 \\ + \verb|\textdollar| & \textdollar & 36 \\ + \verb|\textquotesingle| & \textquotesingle & 39 \\ + \verb|\textasteriskcentered| & \textasteriskcentered & 42 \\ + \verb|\textdblhyphen| & \textdblhyphen & 45 \\ + \verb|\textfractionsolidus| & \textfractionsolidus & 47 \\ + \verb|\textzerooldstyle| & \textzerooldstyle & 48 \\ + \verb|\textoneoldstyle| & \textoneoldstyle & 49 \\ + \verb|\texttwooldstyle| & \texttwooldstyle & 50 \\ + \verb|\textthreeoldstyle| & \textthreeoldstyle & 51 \\ + \verb|\textfouroldstyle| & \textfouroldstyle & 52 \\ + \verb|\textfiveoldstyle| & \textfiveoldstyle & 53 \\ + \verb|\textsixoldstyle| & \textsixoldstyle & 54 \\ + \verb|\textsevenoldstyle| & \textsevenoldstyle & 55 \\ + \verb|\texteightoldstyle| & \texteightoldstyle & 56 \\ + \verb|\textnineoldstyle| & \textnineoldstyle & 57 \\ + \verb|\textlangle| & \textlangle & 60 \\ + \verb|\textminus| & \textminus & 61 \\ + \verb|\textrangle| & \textrangle & 62 \\ + \verb|\textmho| & \textmho & 77 \\ + \verb|\textbigcircle| & \textbigcircle & 79 \\ + \verb|\textohm| & \textohm & 87 \\ + \verb|\textlbrackdbl| & \textlbrackdbl & 91 \\ + \verb|\textrbrackdbl| & \textrbrackdbl & 93 \\ + \verb|\textuparrow| & \textuparrow & 94 \\ + \verb|\textdownarrow| & \textdownarrow & 95 \\ + \verb|\textasciigrave| & \textasciigrave & 96 \\ + \verb|\textborn| & \textborn & 98 \\ + \verb|\textdivorced| & \textdivorced & 99 \\ + \verb|\textdied| & \textdied & 100 \\ + \verb|\textleaf| & \textleaf & 108 \\ + \verb|\textmarried| & \textmarried & 109 \\ + \verb|\textmusicalnote| & \textmusicalnote & 110 \\ + \verb|\texttildelow| & \texttildelow & 126 \\ + \verb|\textdblhyphenchar| & \textdblhyphenchar & 127 \\ + \verb|\textasciibreve| & \textasciibreve & 128 \\ + \verb|\textasciicaron| & \textasciicaron & 129 \\ + \verb|\textacutedbl| & \textacutedbl & 130 \\ + \verb|\textgravedbl| & \textgravedbl & 131 \\ + \verb|\textdagger| & \textdagger & 132 \\ + \verb|\textdaggerdbl| & \textdaggerdbl & 133 \\ + \verb|\textbardbl| & \textbardbl & 134 \\ + \verb|\textperthousand| & \textperthousand & 135 \\ + \verb|\textbullet| & \textbullet & 136 \\ + \verb|\textcelsius| & \textcelsius & 137 \\ + \verb|\textdollaroldstyle| & \textdollaroldstyle & 138 \\ + \verb|\textcentoldstyle| & \textcentoldstyle & 139 + \end{tabular}\qquad + \begin{tabular}[t]{lp{1.5em}l} + \verb|\textflorin| & \textflorin & 140 \\ + \verb|\textcolonmonetary| & \textcolonmonetary & 141 \\ + \verb|\textwon| & \textwon & 142 \\ + \verb|\textnaira| & \textnaira & 143 \\ + \verb|\textguarani| & \textguarani & 144 \\ + \verb|\textpeso| & \textpeso & 145 \\ + \verb|\textlira| & \textlira & 146 \\ + \verb|\textrecipe| & \textrecipe & 147 \\ + \verb|\textinterrobang| & \textinterrobang & 148 \\ + \verb|\textinterrobangdown| & \textinterrobangdown & 149 \\ + \verb|\textdong| & \textdong & 150 \\ + \verb|\texttrademark| & \texttrademark & 151 \\ + \verb|\textpertenthousand| & \textpertenthousand & 152 \\ + \verb|\textpilcrow| & \textpilcrow & 153 \\ + \verb|\textbaht| & \textbaht & 154 \\ + \verb|\textnumero| & \textnumero & 155 \\ + \verb|\textdiscount| & \textdiscount & 156 \\ + \verb|\textestimated| & \textestimated & 157 \\ + \verb|\textopenbullet| & \textopenbullet & 158 \\ + \verb|\textservicemark| & \textservicemark & 159 \\ + \verb|\textlquill| & \textlquill & 160 \\ + \verb|\textrquill| & \textrquill & 161 \\ + \verb|\textcent| & \textcent & 162 \\ + \verb|\textsterling| & \textsterling & 163 \\ + \verb|\textcurrency| & \textcurrency & 164 \\ + \verb|\textyen| & \textyen & 165 \\ + \verb|\textbrokenbar| & \textbrokenbar & 166 \\ + \verb|\textsection| & \textsection & 167 \\ + \verb|\textasciidieresis| & \textasciidieresis & 168 \\ + \verb|\textcopyright| & \textcopyright & 169 \\ + \verb|\textordfeminine| & \textordfeminine & 170 \\ + \verb|\textcopyleft| & \textcopyleft & 171 \\ + \verb|\textlnot| & \textlnot & 172 \\ + \verb|\textcircledP| & \textcircledP & 173 \\ + \verb|\textregistered| & \textregistered & 174 \\ + \verb|\textasciimacron| & \textasciimacron & 175 \\ + \verb|\textdegree| & \textdegree & 176 \\ + \verb|\textpm| & \textpm & 177 \\ + \verb|\texttwosuperior| & \texttwosuperior & 178 \\ + \verb|\textthreesuperior| & \textthreesuperior & 179 \\ + \verb|\textasciiacute| & \textasciiacute & 180 \\ + \verb|\textmu| & \textmu & 181 \\ + \verb|\textparagraph| & \textparagraph & 182 \\ + \verb|\textperiodcentered| & \textperiodcentered & 183 \\ + \verb|\textreferencemark| & \textreferencemark & 184 \\ + \verb|\textonesuperior| & \textonesuperior & 185 \\ + \verb|\textordmasculine| & \textordmasculine & 186 \\ + \verb|\textsurd| & \textsurd & 187 \\ + \verb|\textonequarter| & \textonequarter & 188 \\ + \verb|\textonehalf| & \textonehalf & 189 \\ + \verb|\textthreequarters| & \textthreequarters & 190 \\ + \verb|\texteuro| & \texteuro & 191 \\ + \verb|\texttimes| & \texttimes & 214 \\ + \verb|\textdiv| & \textdiv & 246 + \end{tabular} +\caption{Text symbols formerly from the \textsf{textcomp} package} +\label{tab:textcomp} +\end{table} \section{If you need to know more \ldots} diff --git a/Master/texmf-dist/doc/latex-dev/base/graphpap.pdf b/Master/texmf-dist/doc/latex-dev/base/graphpap.pdf Binary files differindex 6445993704c..8228eeef948 100644 --- a/Master/texmf-dist/doc/latex-dev/base/graphpap.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/graphpap.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ifthen.pdf b/Master/texmf-dist/doc/latex-dev/base/ifthen.pdf Binary files differindex d9c284461f1..c4a2758d2d6 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ifthen.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ifthen.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/inputenc.pdf b/Master/texmf-dist/doc/latex-dev/base/inputenc.pdf Binary files differindex ee5a4e8bbe5..a9e5de11017 100644 --- a/Master/texmf-dist/doc/latex-dev/base/inputenc.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/inputenc.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/latexchanges.pdf b/Master/texmf-dist/doc/latex-dev/base/latexchanges.pdf Binary files differindex d4b0bd2de20..41cbf57ca19 100644 --- a/Master/texmf-dist/doc/latex-dev/base/latexchanges.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/latexchanges.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/latexrelease.pdf b/Master/texmf-dist/doc/latex-dev/base/latexrelease.pdf Binary files differindex e914f5ee309..d2e28e7b3eb 100644 --- a/Master/texmf-dist/doc/latex-dev/base/latexrelease.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/latexrelease.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/latexsym.pdf b/Master/texmf-dist/doc/latex-dev/base/latexsym.pdf Binary files differindex 5a41af71235..e50c21e049e 100644 --- a/Master/texmf-dist/doc/latex-dev/base/latexsym.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/latexsym.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/lb2.pdf b/Master/texmf-dist/doc/latex-dev/base/lb2.pdf Binary files differindex abb4820d335..675ad85fe31 100644 --- a/Master/texmf-dist/doc/latex-dev/base/lb2.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/lb2.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/letter.pdf b/Master/texmf-dist/doc/latex-dev/base/letter.pdf Binary files differindex 4df07710744..afc2790ef9a 100644 --- a/Master/texmf-dist/doc/latex-dev/base/letter.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/letter.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/lgc2.pdf b/Master/texmf-dist/doc/latex-dev/base/lgc2.pdf Binary files differindex f3c7b5ff3e7..9dd6a2d932b 100644 --- a/Master/texmf-dist/doc/latex-dev/base/lgc2.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/lgc2.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/lppl.pdf b/Master/texmf-dist/doc/latex-dev/base/lppl.pdf Binary files differindex 14c251a5542..fbb4dfd8a5b 100644 --- a/Master/texmf-dist/doc/latex-dev/base/lppl.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/lppl.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltfilehook-code.pdf b/Master/texmf-dist/doc/latex-dev/base/ltfilehook-code.pdf Binary files differnew file mode 100644 index 00000000000..bd183ac9bcf --- /dev/null +++ b/Master/texmf-dist/doc/latex-dev/base/ltfilehook-code.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltfilehook-code.tex b/Master/texmf-dist/doc/latex-dev/base/ltfilehook-code.tex new file mode 100644 index 00000000000..2a9c1d1815a --- /dev/null +++ b/Master/texmf-dist/doc/latex-dev/base/ltfilehook-code.tex @@ -0,0 +1,10 @@ +% This will typeset documentation + code +% +% However, you may first have to unpack the .sty file via +% +% latex ltfilehook.ins +% +% as it is used when processing the doumentation. + +\AtBeginDocument{\AlsoImplementation} +\input{ltfilehook.dtx} diff --git a/Master/texmf-dist/doc/latex-dev/base/ltfilehook-doc.pdf b/Master/texmf-dist/doc/latex-dev/base/ltfilehook-doc.pdf Binary files differnew file mode 100644 index 00000000000..d58188e4fbe --- /dev/null +++ b/Master/texmf-dist/doc/latex-dev/base/ltfilehook-doc.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltfilehook-doc.tex b/Master/texmf-dist/doc/latex-dev/base/ltfilehook-doc.tex new file mode 100644 index 00000000000..d3a20f74ef1 --- /dev/null +++ b/Master/texmf-dist/doc/latex-dev/base/ltfilehook-doc.tex @@ -0,0 +1,12 @@ +% This will typeset only documentation but not the code +% +% However, you may first have to unpack the .sty file via +% +% latex ltfilehook.ins +% +% as it is used when processing the doumentation. + +\AtBeginDocument{\OnlyDescription +% \let\tableofcontents\relax + } +\input{ltfilehook.dtx} diff --git a/Master/texmf-dist/doc/latex-dev/base/lthooks-code.pdf b/Master/texmf-dist/doc/latex-dev/base/lthooks-code.pdf Binary files differnew file mode 100644 index 00000000000..336bf58d942 --- /dev/null +++ b/Master/texmf-dist/doc/latex-dev/base/lthooks-code.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/lthooks-code.tex b/Master/texmf-dist/doc/latex-dev/base/lthooks-code.tex new file mode 100644 index 00000000000..32822fcfd84 --- /dev/null +++ b/Master/texmf-dist/doc/latex-dev/base/lthooks-code.tex @@ -0,0 +1,10 @@ +% This will typeset documentation + code +% +% However, you may first have to unpack the .sty file via +% +% latex lthooks.ins +% +% as it is used when processing the doumentation. + +\AtBeginDocument{\AlsoImplementation} +\input{lthooks.dtx} diff --git a/Master/texmf-dist/doc/latex-dev/base/lthooks-doc.pdf b/Master/texmf-dist/doc/latex-dev/base/lthooks-doc.pdf Binary files differnew file mode 100644 index 00000000000..b02d0e67985 --- /dev/null +++ b/Master/texmf-dist/doc/latex-dev/base/lthooks-doc.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/lthooks-doc.tex b/Master/texmf-dist/doc/latex-dev/base/lthooks-doc.tex new file mode 100644 index 00000000000..47d86a45991 --- /dev/null +++ b/Master/texmf-dist/doc/latex-dev/base/lthooks-doc.tex @@ -0,0 +1,12 @@ +% This will typeset only documentation but not the code +% +% However, you may first have to unpack the .sty file via +% +% latex lthooks.ins +% +% as it is used when processing the doumentation. + +\AtBeginDocument{\OnlyDescription +% \let\tableofcontents\relax + } +\input{lthooks.dtx} diff --git a/Master/texmf-dist/doc/latex-dev/base/ltluatex.pdf b/Master/texmf-dist/doc/latex-dev/base/ltluatex.pdf Binary files differindex eaada989fab..515a409e897 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltluatex.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltluatex.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews.pdf b/Master/texmf-dist/doc/latex-dev/base/ltnews.pdf Binary files differindex ced28ce0e1d..d74896f57a0 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews01.pdf b/Master/texmf-dist/doc/latex-dev/base/ltnews01.pdf Binary files differindex fc3ed1119d0..f284c0fb850 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews01.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews01.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews02.pdf b/Master/texmf-dist/doc/latex-dev/base/ltnews02.pdf Binary files differindex 34d40b49ec6..2ebf8c72f66 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews02.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews02.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews03.pdf b/Master/texmf-dist/doc/latex-dev/base/ltnews03.pdf Binary files differindex df30947cd9e..246e0fe7e94 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews03.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews03.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews04.pdf b/Master/texmf-dist/doc/latex-dev/base/ltnews04.pdf Binary files differindex 8b18c27fda8..c953675edc8 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews04.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews04.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews05.pdf b/Master/texmf-dist/doc/latex-dev/base/ltnews05.pdf Binary files differindex 7a079ebd734..319669efd60 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews05.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews05.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews06.pdf b/Master/texmf-dist/doc/latex-dev/base/ltnews06.pdf Binary files differindex e6ca705920f..b13e9e0522d 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews06.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews06.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews07.pdf b/Master/texmf-dist/doc/latex-dev/base/ltnews07.pdf Binary files differindex 66a14575666..cda0340e74b 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews07.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews07.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews08.pdf b/Master/texmf-dist/doc/latex-dev/base/ltnews08.pdf Binary files differindex 2732f77234d..8aa4e628bfc 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews08.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews08.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews09.pdf b/Master/texmf-dist/doc/latex-dev/base/ltnews09.pdf Binary files differindex b81df70446f..c66c8cfa4f9 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews09.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews09.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews10.pdf b/Master/texmf-dist/doc/latex-dev/base/ltnews10.pdf Binary files differindex 1fa4ff29976..0e895283ca1 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews10.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews10.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews11.pdf b/Master/texmf-dist/doc/latex-dev/base/ltnews11.pdf Binary files differindex 33b9db87fc8..ec2365e8022 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews11.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews11.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews12.pdf b/Master/texmf-dist/doc/latex-dev/base/ltnews12.pdf Binary files differindex 3df0f8da10f..771d5bc0888 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews12.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews12.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews13.pdf b/Master/texmf-dist/doc/latex-dev/base/ltnews13.pdf Binary files differindex 9f250dda698..bc759bc70b5 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews13.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews13.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews14.pdf b/Master/texmf-dist/doc/latex-dev/base/ltnews14.pdf Binary files differindex aeef5a6352d..a747c427e7a 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews14.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews14.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews15.pdf b/Master/texmf-dist/doc/latex-dev/base/ltnews15.pdf Binary files differindex e2df12335b5..7ed464e1e48 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews15.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews15.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews16.pdf b/Master/texmf-dist/doc/latex-dev/base/ltnews16.pdf Binary files differindex 1eb4b413992..b733ab0bb1f 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews16.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews16.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews17.pdf b/Master/texmf-dist/doc/latex-dev/base/ltnews17.pdf Binary files differindex d3c7bbda621..63d06bb742b 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews17.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews17.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews18.pdf b/Master/texmf-dist/doc/latex-dev/base/ltnews18.pdf Binary files differindex 3f78dcfaeb0..766b54786cd 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews18.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews18.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews19.pdf b/Master/texmf-dist/doc/latex-dev/base/ltnews19.pdf Binary files differindex a5c96735c98..8fd4131aa28 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews19.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews19.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews20.pdf b/Master/texmf-dist/doc/latex-dev/base/ltnews20.pdf Binary files differindex fcf4ef9a2b6..a9fd7578bfc 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews20.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews20.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews21.pdf b/Master/texmf-dist/doc/latex-dev/base/ltnews21.pdf Binary files differindex 948dec89172..9fe01bd05ab 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews21.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews21.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews22.pdf b/Master/texmf-dist/doc/latex-dev/base/ltnews22.pdf Binary files differindex c7576c9e0ef..06539b04f36 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews22.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews22.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews23.pdf b/Master/texmf-dist/doc/latex-dev/base/ltnews23.pdf Binary files differindex 513c215ff4d..4f0cbf72489 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews23.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews23.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews24.pdf b/Master/texmf-dist/doc/latex-dev/base/ltnews24.pdf Binary files differindex 5d826a3aa16..2088def4ff8 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews24.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews24.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews25.pdf b/Master/texmf-dist/doc/latex-dev/base/ltnews25.pdf Binary files differindex 60f2c7f2036..b788f5e5c4c 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews25.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews25.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews26.pdf b/Master/texmf-dist/doc/latex-dev/base/ltnews26.pdf Binary files differindex 4dce56adfad..fdda73b9d50 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews26.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews26.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews27.pdf b/Master/texmf-dist/doc/latex-dev/base/ltnews27.pdf Binary files differindex 483ff44824f..cd893f6f528 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews27.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews27.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews28.pdf b/Master/texmf-dist/doc/latex-dev/base/ltnews28.pdf Binary files differindex 694668f4e72..52fa5ff2b50 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews28.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews28.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews29.pdf b/Master/texmf-dist/doc/latex-dev/base/ltnews29.pdf Binary files differindex db198ebdd8d..e7178a91548 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews29.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews29.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews30.pdf b/Master/texmf-dist/doc/latex-dev/base/ltnews30.pdf Binary files differindex 5d045c4cf1e..f32e6f46477 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews30.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews30.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews31.pdf b/Master/texmf-dist/doc/latex-dev/base/ltnews31.pdf Binary files differindex d4eea094cc0..e152614b670 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews31.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews31.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews32.pdf b/Master/texmf-dist/doc/latex-dev/base/ltnews32.pdf Binary files differindex 7c8dc3fac7e..931e86541d6 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews32.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews32.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltnews32.tex b/Master/texmf-dist/doc/latex-dev/base/ltnews32.tex index fdf8211ef0f..fdea39b6e3a 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltnews32.tex +++ b/Master/texmf-dist/doc/latex-dev/base/ltnews32.tex @@ -187,6 +187,56 @@ the kernel code; these are deprecated but still available by explicitly loading \pkg{xparse}. All other argument types \emph{are} now available directly within the \LaTeXe{} kernel. + + + + + +\section{A hook management system for \LaTeX{}} + +With the fall 2020 release of \LaTeX{} we provide a general hook +management system for the kernel and for packages. This will allow +packages to safely add code to various kernel and package hooks and if +necessary define rules to reorder the code in the hooks to resolve +typical package loading order issues. This hook system is written in +the L3 programming layer and thus forms the first larger application +within the kernel that makes use of the \LaTeX3 functionality now +available (if we discount \pkg{xparse} which was already available for +a long time as a separate package). + +The file \texttt{lthooks.dtx} holds the core management code for hooks +and defines basic hooks for environments (as previously offered by +\pkg{etoolbox}), \texttt{ltshipout.dtx} provides kernel hooks into the +shipout process (making packages like \pkg{atbegshi}, +etc.\ unnecessary) and the file \texttt{ltfilehook.dtx} holds +redefinition for commands like \cs{input} or \cs{usepackage} so that +they offer hooks in a similar fashion to what is provided by the +\pkg{filehook} package. + +At the moment the integration is lightweight, overwriting definitions +made earlier during format generation (though this will change after +more thorough testing). For that reason the documention isn't in its +final form either and you have to read through three different +documents: +\begin{description} + \item[\texttt{lthooks-doc.pdf}] Core management interface and basic + hooks for environments provided by the kernel. + + \item[\texttt{ltshipout-doc.pdf}] Hooks accessible while a page is + being shipped out. + + \item[\texttt{ltfilehook-doc.pdf}] Hooks used when reading a file. +\end{description} +For those who wish to also study the code, replace \texttt{-doc} with +\texttt{-code}, e.g., \texttt{lthooks-code.pdf}. All documents should +be accessible via \texttt{texdoc}, e.g., +\begin{verbatim} + texdoc lthooks-doc +\end{verbatim} +should open the core documentation for you. + + + \section{Other changes to the \LaTeX{} kernel} @@ -259,9 +309,18 @@ can also contain spaces with any leading and trailing spaces stripped from the individual filenames while the spaces \emph{in} the file names will remain intact. % -\githubissue{217} +\githubissue[s]{217 and 218} +\subsection{Avoid extra line in \cs{centering}, \cs{raggedleft} or \cs{raggedright}} + +If we aren't justifing paragraphs then a very long word (longer than a +line) could result in an unnecessary extra line in order to prevent a +hyphen in the second-last line of the paragraph. This is now avoided +by setting \cs{finalhyphendemerits} to zero in unjustified settings. +% +\githubissue{274} + \subsection{Set a non-zero \cs{baselineskip} in text scripts} @@ -323,7 +382,7 @@ used in bold context (e.g., inside \cs{textbf}. Now that it is possible in \LaTeX{} to specify different \enquote{\texttt{bf}} defaults based for each of the three meta families (\texttt{rm}, \texttt{sf} and \texttt{tt}) via \cs{DeclareFontSeriesDefault}, it is -not any longer easy to answer the question \enquote{am I typsetting in +not any longer easy to answer the question \enquote{am I typesetting in a bold context?}. To help with this problem a new command was provided: \begin{quote} \cs{IfFontSeriesContextTF}\Arg{context}\\ @@ -404,7 +463,7 @@ To implement compatibility code or to ensure that certain features are available it is helpful and often necessary to check the date of the format or that of a package or class and execute different code based on the result. For that \LaTeX\ only had some internal commands -(\cs{@ifpackagelater} and \cs{@ifclasslater}) for testting package or +(\cs{@ifpackagelater} and \cs{@ifclasslater}) for testing package or class names but nothing really for testing the format date. For the latter one had to resort to some obscure command \cs{@ifl@t@r} that, given its cryptic name, was clearly never intended for use even in @@ -447,26 +506,38 @@ are ignored as elsewhere. \githubissue{327} -\subsection{Record the counter name stepped by \cs{refstepcounter}} -\cs{refstepcounter} now stores the name of counter in \cs{\@currentcounter}. -This allows packages like \pkg{zref} and \pkg{hyperref} to store the name without -having to patch \cs{refstepcounter}. +\subsection{Merge \pkg{l3docstrip} into \pkg{docstrip}} + +The file \pkg{l3docstrip.tex} offered a small extension over the +original \pkg{docstrip.tex} file supporting the +\texttt{\%\string<@@=\meta{module}\string>} syntax of \pkg{expl3}. +This has now been merged into \pkg{docstrip} so that it can now be +used both for traditional \texttt{.dtx} files and those containing +code written in the L3 programming layer language. % -\githubissue{300} +\githubissue{337} -\subsection{Add support for Unicode soft hyphens} +\subsection{Support vertical typesetting with \pkg{doc}} -For a long time, the UTF-8 option for \pkg{inputenc} made the Unicode -soft hyphen character (U+00AD) an alias for the \LaTeX\ soft hyphen -\cs{-}. The Unicode engines \XeTeX{} and \LuaTeX{} behaved -different though: They either ignored U+00AD or interpreted it as an -unconditional hyphen. This inconsistency is fixed now and \LaTeX{} -always treats \texttt{U+00AD} as \cs{-}. +The \texttt{macrocode} environment uses a \texttt{trivlist} internally +and as part of this sets up the \cs{@labels} box to contain some +horizontal skips, but that box is never used. As a result this +generates an issue in some circumstances if the typesetting direction +is vertical. This has now been corrected to support such use cases as +well. % -\githubissue{323} +\githubissue{344} + +\subsection{Record the counter name stepped by \cs{refstepcounter}} + +\cs{refstepcounter} now stores the name of counter in \cs{@currentcounter}. +This allows packages like \pkg{zref} and \pkg{hyperref} to store the name without +having to patch \cs{refstepcounter}. +% +\githubissue{300} \subsection{Native Lua\TeX\ behaviour for \cs{-}} @@ -489,6 +560,40 @@ now allowed. % \githubissue{335} +\subsection{Spacing commands moved from \pkg{amsmath} to the kernel} +Originally \LaTeX{} only provided a small set of spacing commands +for use in text and math, some of the commands like \cs{;} were +only supported in math mode. \texttt{amsmath} normalized and +provided all of them in text and math. This code has now been +moved to the kernel so that it is generally available. +% +\githubissue{303} + +\begin{tabular}{lll} +command name(s) & math & text\\\hline +\cs{,} \cs{thinspace} & $x\,x$ & x\,x\\ +\cs{!} \cs{negthinspace} & $x\!x$ & x\!x\\ +\cs{:} \cs{>} \cs{medspace} & $x\:x$ & x\:x\\ +\cs{negmedspace} & $x\negmedspace x$ & x\negmedspace x\\ +\cs{;} \cs{thickspace} & $x\;x$ & x\;x\\ +\cs{negthickspace} & $x\negthickspace x$ & x\negthickspace x\\ +\end{tabular} + + + +\subsection{Access raw glyphs in \LuaTeX\ without reloading fonts} + +\LaTeX's definitions for \cs{textquotesingle}, \cs{textasciigrave}, and +\cs{textquotedbl} for the TU encoding in \LuaTeX\ need special handling to +stop the shaper from replacing these characters with curly quotes. +This used to be done by reloading the current font without the \texttt{tlig} +feature, but that came with multiple disadvantages: It behaves different +than the corresponding \XeTeX\ code and it is not very efficient. +This code has now been replaced with a implementation which injects a +protected glyph nodes which is not affected by font shaping. +% +\githubissue{165} + \section{Changes to packages in the \pkg{graphics} category} @@ -535,6 +640,25 @@ in such documents. % \githubissue{297} +\subsection{\pkg{array}: Fix for \cs{firsthline} and \cs{lasthline}} + +Replacing \cs{hline} with \cs{firsthline} or \cs{lasthline} could lead +in some cases to an increase of the tabular width. This has now been +corrected. +% +\githubissue{322} + +\subsection{\pkg{varioref}: Support Japanese as a language option} + +The package now recognizes \texttt{japanese} as a language option. +The extra complication is that for gramatical reasons \cs{vrefrange} +needs a structure different from all other languages currently +supported. To accomodate for this \cs{vrefrangeformat} was added to +all languages. +% +\githubissue{352} + + \subsection{\pkg{xr}: Support for spaces in filenames} The commannd \cs{externaldocument}, provided by \pkg{xr}, now also @@ -543,6 +667,8 @@ supports filenames with spaces, just like \cs{include} and % \githubissue{223} + + \section{Changes to packages in the \pkg{amsmath} category} \subsection{Placement corrections for two accent commands} @@ -583,7 +709,7 @@ Furthermore, the traditional model to define and select languages is still the preferred one in monolingual documents, is being extended with a new model (which can be called \enquote{horizontal}) based on \emph{services} provided by \pkg{babel}, which allows to define and -redefine locales with the help of simple |ini| files based on +redefine locales with the help of simple \texttt{ini} files based on key/value pairs. Babel provides about of 250 of these files, which have been generated with the help of the Unicode Common Language Data Repository. diff --git a/Master/texmf-dist/doc/latex-dev/base/ltshipout-code.pdf b/Master/texmf-dist/doc/latex-dev/base/ltshipout-code.pdf Binary files differnew file mode 100644 index 00000000000..afc4ad7aee1 --- /dev/null +++ b/Master/texmf-dist/doc/latex-dev/base/ltshipout-code.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltshipout-code.tex b/Master/texmf-dist/doc/latex-dev/base/ltshipout-code.tex new file mode 100644 index 00000000000..a22dd75fb97 --- /dev/null +++ b/Master/texmf-dist/doc/latex-dev/base/ltshipout-code.tex @@ -0,0 +1,10 @@ +% This will typeset documentation + code +% +% However, you may first have to unpack the .sty file via +% +% latex ltshipout.ins +% +% as it is used when processing the doumentation. + +\AtBeginDocument{\AlsoImplementation} +\input{ltshipout.dtx} diff --git a/Master/texmf-dist/doc/latex-dev/base/ltshipout-doc.pdf b/Master/texmf-dist/doc/latex-dev/base/ltshipout-doc.pdf Binary files differnew file mode 100644 index 00000000000..95c0d8345ee --- /dev/null +++ b/Master/texmf-dist/doc/latex-dev/base/ltshipout-doc.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltshipout-doc.tex b/Master/texmf-dist/doc/latex-dev/base/ltshipout-doc.tex new file mode 100644 index 00000000000..de7f3e30a71 --- /dev/null +++ b/Master/texmf-dist/doc/latex-dev/base/ltshipout-doc.tex @@ -0,0 +1,12 @@ +% This will typeset only documentation but not the code +% +% However, you may first have to unpack the .sty file via +% +% latex ltshipout.ins +% +% as it is used when processing the doumentation. + +\AtBeginDocument{\OnlyDescription +% \let\tableofcontents\relax + } +\input{ltshipout.dtx} diff --git a/Master/texmf-dist/doc/latex-dev/base/ltx3info.pdf b/Master/texmf-dist/doc/latex-dev/base/ltx3info.pdf Binary files differindex cee525e1138..978ee6da26c 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltx3info.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltx3info.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/ltxdoc.pdf b/Master/texmf-dist/doc/latex-dev/base/ltxdoc.pdf Binary files differindex ed047478675..f6e9112d731 100644 --- a/Master/texmf-dist/doc/latex-dev/base/ltxdoc.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/ltxdoc.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/makeindx.pdf b/Master/texmf-dist/doc/latex-dev/base/makeindx.pdf Binary files differindex fc3f0bb5073..3b35cf18bf4 100644 --- a/Master/texmf-dist/doc/latex-dev/base/makeindx.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/makeindx.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/manual.pdf b/Master/texmf-dist/doc/latex-dev/base/manual.pdf Binary files differindex 19aca62958a..c0e6bba4200 100644 --- a/Master/texmf-dist/doc/latex-dev/base/manual.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/manual.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/modguide.pdf b/Master/texmf-dist/doc/latex-dev/base/modguide.pdf Binary files differindex 8b9cf82d07d..1a7d261cd3a 100644 --- a/Master/texmf-dist/doc/latex-dev/base/modguide.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/modguide.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/nfssfont.pdf b/Master/texmf-dist/doc/latex-dev/base/nfssfont.pdf Binary files differindex bd5c9aef0f1..b1f82eb3eb5 100644 --- a/Master/texmf-dist/doc/latex-dev/base/nfssfont.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/nfssfont.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/proc.pdf b/Master/texmf-dist/doc/latex-dev/base/proc.pdf Binary files differindex 4a2bf118465..b86a51575ca 100644 --- a/Master/texmf-dist/doc/latex-dev/base/proc.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/proc.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/slides.pdf b/Master/texmf-dist/doc/latex-dev/base/slides.pdf Binary files differindex 5922db016b6..73f6b017a8b 100644 --- a/Master/texmf-dist/doc/latex-dev/base/slides.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/slides.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/slifonts.pdf b/Master/texmf-dist/doc/latex-dev/base/slifonts.pdf Binary files differindex 638b84873be..1236827191e 100644 --- a/Master/texmf-dist/doc/latex-dev/base/slifonts.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/slifonts.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/source2e.pdf b/Master/texmf-dist/doc/latex-dev/base/source2e.pdf Binary files differindex 882d7b2cc6a..2e8a083187a 100644 --- a/Master/texmf-dist/doc/latex-dev/base/source2e.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/source2e.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/source2e.tex b/Master/texmf-dist/doc/latex-dev/base/source2e.tex index ccb19a8b2e7..3529d437371 100644 --- a/Master/texmf-dist/doc/latex-dev/base/source2e.tex +++ b/Master/texmf-dist/doc/latex-dev/base/source2e.tex @@ -242,6 +242,8 @@ page_precedence "rnaA" \DocInclude{ltvers} % Current version date + \DocInclude{ltluatex} % Luatex support + \DocInclude{ltdefns} % Initial definitions. \DocInclude{ltalloc} % Allocation of counters and others. @@ -318,8 +320,6 @@ page_precedence "rnaA" \DocInclude{lthyphen} % Hyphenation (hyphen.ltx). - \DocInclude{ltluatex} % Luatex support - \DocInclude{ltfinal} % Last minute initialisations and dump \includeltpatch % Corrections distributed after the full release diff --git a/Master/texmf-dist/doc/latex-dev/base/syntonly.pdf b/Master/texmf-dist/doc/latex-dev/base/syntonly.pdf Binary files differindex e2387a21b2b..689a9b868bd 100644 --- a/Master/texmf-dist/doc/latex-dev/base/syntonly.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/syntonly.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/tlc2.pdf b/Master/texmf-dist/doc/latex-dev/base/tlc2.pdf Binary files differindex 90de5dd226a..4ed83c61ba2 100644 --- a/Master/texmf-dist/doc/latex-dev/base/tlc2.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/tlc2.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/tulm.pdf b/Master/texmf-dist/doc/latex-dev/base/tulm.pdf Binary files differindex 483f155a562..858d723cf0b 100644 --- a/Master/texmf-dist/doc/latex-dev/base/tulm.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/tulm.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/usrguide.pdf b/Master/texmf-dist/doc/latex-dev/base/usrguide.pdf Binary files differindex a2dcf1b785b..de2858ad8ef 100644 --- a/Master/texmf-dist/doc/latex-dev/base/usrguide.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/usrguide.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/utf8ienc.pdf b/Master/texmf-dist/doc/latex-dev/base/utf8ienc.pdf Binary files differindex c27ce9669bf..644e2935e34 100644 --- a/Master/texmf-dist/doc/latex-dev/base/utf8ienc.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/utf8ienc.pdf diff --git a/Master/texmf-dist/doc/latex-dev/base/webcomp.pdf b/Master/texmf-dist/doc/latex-dev/base/webcomp.pdf Binary files differindex 32a69c71c96..2e8dc80d011 100644 --- a/Master/texmf-dist/doc/latex-dev/base/webcomp.pdf +++ b/Master/texmf-dist/doc/latex-dev/base/webcomp.pdf diff --git a/Master/texmf-dist/doc/latex-dev/graphics/README.md b/Master/texmf-dist/doc/latex-dev/graphics/README.md index 9195e612d15..08cd8cabdec 100644 --- a/Master/texmf-dist/doc/latex-dev/graphics/README.md +++ b/Master/texmf-dist/doc/latex-dev/graphics/README.md @@ -1,7 +1,7 @@ The LaTeX `graphics` bundle =========================== -Release 2020-10-01 pre-release 1 +Release 2020-10-01 pre-release 2 Overview -------- diff --git a/Master/texmf-dist/doc/latex-dev/graphics/changes.txt b/Master/texmf-dist/doc/latex-dev/graphics/changes.txt index 42ce0dea02e..bbe1893e63e 100644 --- a/Master/texmf-dist/doc/latex-dev/graphics/changes.txt +++ b/Master/texmf-dist/doc/latex-dev/graphics/changes.txt @@ -4,6 +4,10 @@ completeness or accuracy and it contains some references to files that are not part of the distribution. ======================================================================= +2020-05-28 David Carlisle <David.Carlisle@latex-project.org> + + * lscape.dtx: delay saving \cs{@makefcolumn} gh340 + 2020-02-24 Ulrike Fischer <Ulrike.Fischer@latex-project.org> * color.dtx: corrected a tests, graphics/3635 diff --git a/Master/texmf-dist/doc/latex-dev/graphics/color.pdf b/Master/texmf-dist/doc/latex-dev/graphics/color.pdf Binary files differindex 4749ea345fe..dca850b1288 100644 --- a/Master/texmf-dist/doc/latex-dev/graphics/color.pdf +++ b/Master/texmf-dist/doc/latex-dev/graphics/color.pdf diff --git a/Master/texmf-dist/doc/latex-dev/graphics/drivers.pdf b/Master/texmf-dist/doc/latex-dev/graphics/drivers.pdf Binary files differindex 418d8f8f472..3e6c1a9d76e 100644 --- a/Master/texmf-dist/doc/latex-dev/graphics/drivers.pdf +++ b/Master/texmf-dist/doc/latex-dev/graphics/drivers.pdf diff --git a/Master/texmf-dist/doc/latex-dev/graphics/epsfig.pdf b/Master/texmf-dist/doc/latex-dev/graphics/epsfig.pdf Binary files differindex 3949a190c2a..816d353c513 100644 --- a/Master/texmf-dist/doc/latex-dev/graphics/epsfig.pdf +++ b/Master/texmf-dist/doc/latex-dev/graphics/epsfig.pdf diff --git a/Master/texmf-dist/doc/latex-dev/graphics/graphics.pdf b/Master/texmf-dist/doc/latex-dev/graphics/graphics.pdf Binary files differindex f7fb560c233..aeac04b4c05 100644 --- a/Master/texmf-dist/doc/latex-dev/graphics/graphics.pdf +++ b/Master/texmf-dist/doc/latex-dev/graphics/graphics.pdf diff --git a/Master/texmf-dist/doc/latex-dev/graphics/graphicx.pdf b/Master/texmf-dist/doc/latex-dev/graphics/graphicx.pdf Binary files differindex 75b1f1e5329..6bc77b28eee 100644 --- a/Master/texmf-dist/doc/latex-dev/graphics/graphicx.pdf +++ b/Master/texmf-dist/doc/latex-dev/graphics/graphicx.pdf diff --git a/Master/texmf-dist/doc/latex-dev/graphics/grfguide.pdf b/Master/texmf-dist/doc/latex-dev/graphics/grfguide.pdf Binary files differindex caf1b70912d..b385e649577 100644 --- a/Master/texmf-dist/doc/latex-dev/graphics/grfguide.pdf +++ b/Master/texmf-dist/doc/latex-dev/graphics/grfguide.pdf diff --git a/Master/texmf-dist/doc/latex-dev/graphics/keyval.pdf b/Master/texmf-dist/doc/latex-dev/graphics/keyval.pdf Binary files differindex 8536c2c7168..cbefa8b143d 100644 --- a/Master/texmf-dist/doc/latex-dev/graphics/keyval.pdf +++ b/Master/texmf-dist/doc/latex-dev/graphics/keyval.pdf diff --git a/Master/texmf-dist/doc/latex-dev/graphics/lscape.pdf b/Master/texmf-dist/doc/latex-dev/graphics/lscape.pdf Binary files differindex 02d9c42d636..020b0f8af2f 100644 --- a/Master/texmf-dist/doc/latex-dev/graphics/lscape.pdf +++ b/Master/texmf-dist/doc/latex-dev/graphics/lscape.pdf diff --git a/Master/texmf-dist/doc/latex-dev/graphics/rotating.pdf b/Master/texmf-dist/doc/latex-dev/graphics/rotating.pdf Binary files differindex 5abe51370c7..822bc418794 100644 --- a/Master/texmf-dist/doc/latex-dev/graphics/rotating.pdf +++ b/Master/texmf-dist/doc/latex-dev/graphics/rotating.pdf diff --git a/Master/texmf-dist/doc/latex-dev/graphics/rotex.pdf b/Master/texmf-dist/doc/latex-dev/graphics/rotex.pdf Binary files differindex 98919825a33..2481248e537 100644 --- a/Master/texmf-dist/doc/latex-dev/graphics/rotex.pdf +++ b/Master/texmf-dist/doc/latex-dev/graphics/rotex.pdf diff --git a/Master/texmf-dist/doc/latex-dev/graphics/trig.pdf b/Master/texmf-dist/doc/latex-dev/graphics/trig.pdf Binary files differindex 9863ea585e8..08570f57531 100644 --- a/Master/texmf-dist/doc/latex-dev/graphics/trig.pdf +++ b/Master/texmf-dist/doc/latex-dev/graphics/trig.pdf diff --git a/Master/texmf-dist/doc/latex-dev/tools/README.md b/Master/texmf-dist/doc/latex-dev/tools/README.md index 9167c2292c4..1cc4996d924 100644 --- a/Master/texmf-dist/doc/latex-dev/tools/README.md +++ b/Master/texmf-dist/doc/latex-dev/tools/README.md @@ -1,7 +1,7 @@ The LaTeX `tools` bundle ======================== -Release 2020-10-01 pre-release 3 +Release 2020-10-01 pre-release 4 Overview -------- diff --git a/Master/texmf-dist/doc/latex-dev/tools/afterpage.pdf b/Master/texmf-dist/doc/latex-dev/tools/afterpage.pdf Binary files differindex 8b7c701c7a7..a23f13ee6df 100644 --- a/Master/texmf-dist/doc/latex-dev/tools/afterpage.pdf +++ b/Master/texmf-dist/doc/latex-dev/tools/afterpage.pdf diff --git a/Master/texmf-dist/doc/latex-dev/tools/array.pdf b/Master/texmf-dist/doc/latex-dev/tools/array.pdf Binary files differindex 508b57f29b6..af15a8f1d7b 100644 --- a/Master/texmf-dist/doc/latex-dev/tools/array.pdf +++ b/Master/texmf-dist/doc/latex-dev/tools/array.pdf diff --git a/Master/texmf-dist/doc/latex-dev/tools/bm.pdf b/Master/texmf-dist/doc/latex-dev/tools/bm.pdf Binary files differindex b780310b89d..d6a1d0c8a56 100644 --- a/Master/texmf-dist/doc/latex-dev/tools/bm.pdf +++ b/Master/texmf-dist/doc/latex-dev/tools/bm.pdf diff --git a/Master/texmf-dist/doc/latex-dev/tools/calc.pdf b/Master/texmf-dist/doc/latex-dev/tools/calc.pdf Binary files differindex bb3cbeacf00..e507bc2536c 100644 --- a/Master/texmf-dist/doc/latex-dev/tools/calc.pdf +++ b/Master/texmf-dist/doc/latex-dev/tools/calc.pdf diff --git a/Master/texmf-dist/doc/latex-dev/tools/changes.txt b/Master/texmf-dist/doc/latex-dev/tools/changes.txt index fc18afe98a9..b06956271db 100644 --- a/Master/texmf-dist/doc/latex-dev/tools/changes.txt +++ b/Master/texmf-dist/doc/latex-dev/tools/changes.txt @@ -5,11 +5,28 @@ completeness or accuracy and it contains some references to files that are not part of the distribution. ======================================================================= +2020-07-20 Frank Mittelbach <Frank.Mittelbach@latex-project.org> + + * array.dtx (subsection{Support for \firsthline ...): + Ensure that the tabular width isn't changed (gh/322) + + * array.dtx (subsection{Handling of rules}): + Clarified the handling of rules, no code change (gh/319). + + * varioref.dtx (subsection{Options}): + Option japanese added (gh/352) + +2020-06-06 Johannes Braams <Johannes.Braams@latex-project.org> + + * verbatim.dtx: Save the value if \@filef@und before the call to + \@verbatim to make sure that \verbatiminput reads the right + file. (gh/222). + 2020-05-10 Johannes Braams <Johannes.Braams@latex-project.org> * xr.dtx: Remove leading and trailing spaces from the argument to \externaldocument, making sure that spaces *in* filenames are - supprted (gh/217). + supprted (gh/217). 2020-04-22 Frank Mittelbach <Frank.Mittelbach@latex-project.org> diff --git a/Master/texmf-dist/doc/latex-dev/tools/dcolumn.pdf b/Master/texmf-dist/doc/latex-dev/tools/dcolumn.pdf Binary files differindex d6cf6917e84..c0d24f3df95 100644 --- a/Master/texmf-dist/doc/latex-dev/tools/dcolumn.pdf +++ b/Master/texmf-dist/doc/latex-dev/tools/dcolumn.pdf diff --git a/Master/texmf-dist/doc/latex-dev/tools/delarray.pdf b/Master/texmf-dist/doc/latex-dev/tools/delarray.pdf Binary files differindex c171247f784..4d6ad2efcdc 100644 --- a/Master/texmf-dist/doc/latex-dev/tools/delarray.pdf +++ b/Master/texmf-dist/doc/latex-dev/tools/delarray.pdf diff --git a/Master/texmf-dist/doc/latex-dev/tools/enumerate.pdf b/Master/texmf-dist/doc/latex-dev/tools/enumerate.pdf Binary files differindex 753327a1ab3..e2efd5f4e4a 100644 --- a/Master/texmf-dist/doc/latex-dev/tools/enumerate.pdf +++ b/Master/texmf-dist/doc/latex-dev/tools/enumerate.pdf diff --git a/Master/texmf-dist/doc/latex-dev/tools/fileerr.pdf b/Master/texmf-dist/doc/latex-dev/tools/fileerr.pdf Binary files differindex 6e98faa5401..bf6941329c8 100644 --- a/Master/texmf-dist/doc/latex-dev/tools/fileerr.pdf +++ b/Master/texmf-dist/doc/latex-dev/tools/fileerr.pdf diff --git a/Master/texmf-dist/doc/latex-dev/tools/fontsmpl.pdf b/Master/texmf-dist/doc/latex-dev/tools/fontsmpl.pdf Binary files differindex a8cfedb50a4..1e989bbf8bc 100644 --- a/Master/texmf-dist/doc/latex-dev/tools/fontsmpl.pdf +++ b/Master/texmf-dist/doc/latex-dev/tools/fontsmpl.pdf diff --git a/Master/texmf-dist/doc/latex-dev/tools/ftnright.pdf b/Master/texmf-dist/doc/latex-dev/tools/ftnright.pdf Binary files differindex adea07ca136..21f5d84058e 100644 --- a/Master/texmf-dist/doc/latex-dev/tools/ftnright.pdf +++ b/Master/texmf-dist/doc/latex-dev/tools/ftnright.pdf diff --git a/Master/texmf-dist/doc/latex-dev/tools/hhline.pdf b/Master/texmf-dist/doc/latex-dev/tools/hhline.pdf Binary files differindex 934fe19a13a..e5adddce653 100644 --- a/Master/texmf-dist/doc/latex-dev/tools/hhline.pdf +++ b/Master/texmf-dist/doc/latex-dev/tools/hhline.pdf diff --git a/Master/texmf-dist/doc/latex-dev/tools/indentfirst.pdf b/Master/texmf-dist/doc/latex-dev/tools/indentfirst.pdf Binary files differindex b03eec1024c..96c0754ff73 100644 --- a/Master/texmf-dist/doc/latex-dev/tools/indentfirst.pdf +++ b/Master/texmf-dist/doc/latex-dev/tools/indentfirst.pdf diff --git a/Master/texmf-dist/doc/latex-dev/tools/layout.pdf b/Master/texmf-dist/doc/latex-dev/tools/layout.pdf Binary files differindex 65c765dbc0f..78737b787b9 100644 --- a/Master/texmf-dist/doc/latex-dev/tools/layout.pdf +++ b/Master/texmf-dist/doc/latex-dev/tools/layout.pdf diff --git a/Master/texmf-dist/doc/latex-dev/tools/longtable.pdf b/Master/texmf-dist/doc/latex-dev/tools/longtable.pdf Binary files differindex e2efb5af882..0d6ec2e8dd2 100644 --- a/Master/texmf-dist/doc/latex-dev/tools/longtable.pdf +++ b/Master/texmf-dist/doc/latex-dev/tools/longtable.pdf diff --git a/Master/texmf-dist/doc/latex-dev/tools/multicol.pdf b/Master/texmf-dist/doc/latex-dev/tools/multicol.pdf Binary files differindex 5749c442958..087a089b438 100644 --- a/Master/texmf-dist/doc/latex-dev/tools/multicol.pdf +++ b/Master/texmf-dist/doc/latex-dev/tools/multicol.pdf diff --git a/Master/texmf-dist/doc/latex-dev/tools/rawfonts.pdf b/Master/texmf-dist/doc/latex-dev/tools/rawfonts.pdf Binary files differindex ac87123c56c..24240a6b22c 100644 --- a/Master/texmf-dist/doc/latex-dev/tools/rawfonts.pdf +++ b/Master/texmf-dist/doc/latex-dev/tools/rawfonts.pdf diff --git a/Master/texmf-dist/doc/latex-dev/tools/shellesc.pdf b/Master/texmf-dist/doc/latex-dev/tools/shellesc.pdf Binary files differindex 45dcd372a2f..363244517da 100644 --- a/Master/texmf-dist/doc/latex-dev/tools/shellesc.pdf +++ b/Master/texmf-dist/doc/latex-dev/tools/shellesc.pdf diff --git a/Master/texmf-dist/doc/latex-dev/tools/showkeys.pdf b/Master/texmf-dist/doc/latex-dev/tools/showkeys.pdf Binary files differindex 853da80f2b4..2651d5f3080 100644 --- a/Master/texmf-dist/doc/latex-dev/tools/showkeys.pdf +++ b/Master/texmf-dist/doc/latex-dev/tools/showkeys.pdf diff --git a/Master/texmf-dist/doc/latex-dev/tools/somedefs.pdf b/Master/texmf-dist/doc/latex-dev/tools/somedefs.pdf Binary files differindex a0b4cab54d7..5a8e6f9981b 100644 --- a/Master/texmf-dist/doc/latex-dev/tools/somedefs.pdf +++ b/Master/texmf-dist/doc/latex-dev/tools/somedefs.pdf diff --git a/Master/texmf-dist/doc/latex-dev/tools/tabularx.pdf b/Master/texmf-dist/doc/latex-dev/tools/tabularx.pdf Binary files differindex ac1b6bf40e4..29171267e0c 100644 --- a/Master/texmf-dist/doc/latex-dev/tools/tabularx.pdf +++ b/Master/texmf-dist/doc/latex-dev/tools/tabularx.pdf diff --git a/Master/texmf-dist/doc/latex-dev/tools/theorem.pdf b/Master/texmf-dist/doc/latex-dev/tools/theorem.pdf Binary files differindex a3695260c78..baa8ebf95ef 100644 --- a/Master/texmf-dist/doc/latex-dev/tools/theorem.pdf +++ b/Master/texmf-dist/doc/latex-dev/tools/theorem.pdf diff --git a/Master/texmf-dist/doc/latex-dev/tools/tools-overview.pdf b/Master/texmf-dist/doc/latex-dev/tools/tools-overview.pdf Binary files differindex 599af2d14f0..16764202ae1 100644 --- a/Master/texmf-dist/doc/latex-dev/tools/tools-overview.pdf +++ b/Master/texmf-dist/doc/latex-dev/tools/tools-overview.pdf diff --git a/Master/texmf-dist/doc/latex-dev/tools/trace.pdf b/Master/texmf-dist/doc/latex-dev/tools/trace.pdf Binary files differindex 07e50dc2220..4cf9f71bfd8 100644 --- a/Master/texmf-dist/doc/latex-dev/tools/trace.pdf +++ b/Master/texmf-dist/doc/latex-dev/tools/trace.pdf diff --git a/Master/texmf-dist/doc/latex-dev/tools/varioref.pdf b/Master/texmf-dist/doc/latex-dev/tools/varioref.pdf Binary files differindex 2ecf15a73a3..4f6e71a2a24 100644 --- a/Master/texmf-dist/doc/latex-dev/tools/varioref.pdf +++ b/Master/texmf-dist/doc/latex-dev/tools/varioref.pdf diff --git a/Master/texmf-dist/doc/latex-dev/tools/verbatim.pdf b/Master/texmf-dist/doc/latex-dev/tools/verbatim.pdf Binary files differindex b0452349ba7..3f3905dbc3a 100644 --- a/Master/texmf-dist/doc/latex-dev/tools/verbatim.pdf +++ b/Master/texmf-dist/doc/latex-dev/tools/verbatim.pdf diff --git a/Master/texmf-dist/doc/latex-dev/tools/xr.pdf b/Master/texmf-dist/doc/latex-dev/tools/xr.pdf Binary files differindex 8e3c988fc2b..90910f21ccc 100644 --- a/Master/texmf-dist/doc/latex-dev/tools/xr.pdf +++ b/Master/texmf-dist/doc/latex-dev/tools/xr.pdf diff --git a/Master/texmf-dist/doc/latex-dev/tools/xspace.pdf b/Master/texmf-dist/doc/latex-dev/tools/xspace.pdf Binary files differindex 7eeda199724..4a4c7f2ddee 100644 --- a/Master/texmf-dist/doc/latex-dev/tools/xspace.pdf +++ b/Master/texmf-dist/doc/latex-dev/tools/xspace.pdf diff --git a/Master/texmf-dist/source/latex-dev/base/doc.dtx b/Master/texmf-dist/source/latex-dev/base/doc.dtx index 3011994d9d1..7e7817153c8 100644 --- a/Master/texmf-dist/source/latex-dev/base/doc.dtx +++ b/Master/texmf-dist/source/latex-dev/base/doc.dtx @@ -35,7 +35,7 @@ %<+package|shortvrb>\NeedsTeXFormat{LaTeX2e}[1994/12/01] %<+package> \ProvidesPackage{doc} %<+shortvrb>\ProvidesPackage{shortvrb} -%<+package|shortvrb> [2019/12/16 v2.1l +%<+package|shortvrb> [2020/06/15 v2.1m %<+package|shortvrb> Standard LaTeX documentation package (FMi)] %\catcode`\<=12 % @@ -139,7 +139,7 @@ % \changes{v1.9t}{1995/05/11}{Use \cs{GetFileInfo}} % \GetFileInfo{doc.sty} % -% \CheckSum{2208} ^^A % keep the checksum in this file +% \CheckSum{2213} ^^A % keep the checksum in this file % % \title{The \DOC{} and \texttt{shortvrb} Packages\thanks % {This file has version number \fileversion{} dated \filedate{}.}} @@ -1324,6 +1324,16 @@ \if@inlabel\leavevmode\fi \trivlist \parskip \z@ \item[]% % \end{macrocode} +% The \cs{item} command sets the \cs{@labels} box but that box is +% never typeset (as \cs{everypar} that normally does this gets +% redefined later). That is normally not an issue, but produces a +% problem when typesetting in mixed directions, (e.g., in +% Japanese), so we explicitly clear it for that use case. +% \changes{v2.1m}{2020/06/15}{Void \cs{@labels} for vertical +% typesetting (gh/344)} +% \begin{macrocode} + \global\setbox\@labels\box\voidb@x +% \end{macrocode} % Additionally, everything should be set in \texttt{typewriter} font. % Some people might prefer it somewhat differently; because of this % the font choice is @@ -1448,7 +1458,8 @@ % bothered since doc-sources should be up-to-date but since the % request came from someone called David Carlisle \ldots :-) % \changes{v1.9y}{1996/01/26}{Support compat mode} -% \changes{v2.1l}{2019/12/16}{Use \cs{shapedefault} not \cs{updefault} for extended NFSS} +% \changes{v2.1l}{2019/12/16}{Use \cs{shapedefault} not +% \cs{updefault} for extended NFSS} % \begin{macrocode} \def\MacroFont{\small \usefont\encodingdefault diff --git a/Master/texmf-dist/source/latex-dev/base/docstrip.dtx b/Master/texmf-dist/source/latex-dev/base/docstrip.dtx index 3ce6ed56967..a0a06311edb 100644 --- a/Master/texmf-dist/source/latex-dev/base/docstrip.dtx +++ b/Master/texmf-dist/source/latex-dev/base/docstrip.dtx @@ -29,9 +29,9 @@ \catcode`\{=1 \catcode`\}=2 \def\filename{docstrip.dtx} -\def\fileversion{v2.5h} -\def\filedate{2020/04/18} -\def\docdate {2018/05/03} +\def\fileversion{v2.6a} +\def\filedate{2020-07-07} +\def\docdate {2020-07-11} %% % %\iffalse @@ -42,7 +42,7 @@ %% Frank Mittelbach %% Copyright (C) 1995 Marcin Woli\'nski %% Copyright (C) 1996-1997 Mark Wooding, Marcin Woli\'nski -%% Copyright (C) 1998-2003 LaTeX3 project and the above authors +%% Copyright (C) 1998-2020 LaTeX3 project and the above authors %% All rights are reserved. %% % @@ -82,6 +82,8 @@ % \changes{2.3e}{1996/10/02}{Introduced ``open lists''} % \changes{2.4a}{1996/06/06}{Add stream limits (MDW)} % \changes{2.4c}{1996/06/11}{Add initex support (DPC)} +% \changes{v2.6a}{2020-07-07}{Added the handling of @@-modules from +% \texttt{l3docstrip.dtx} (gh/337)} % % \DoNotIndex{\#,\$,\%,\&,\@,\\,\{,\},\^,\_,\~,\ } % \DoNotIndex{\@ne} @@ -785,6 +787,57 @@ % When a block of code is {\em not\/} included, any guards that occur % within that block are {\em not\/} evaluated. % +% \section{Internal functions and variables} +% +% An important consideration for \LaTeX3 development is separating +% out public and internal functions. Functions and variables which +% are private to one module should not be used or modified by any +% other module. As \TeX{} does not have any formal namespacing +% system, this requires a convention for indicating which functions +% in a code-level module are public and which are private. +% +% Using \ds\ allows internal functions to be indicated +% using a `two part' system. Within the \texttt{.dtx} file, +% internal functions may be indicated using |@@| in place of the +% module name, for example +% \begin{verbatim} +% \cs_new_protected:Npn \@@_some_function:nn #1#2 +% { +% % Some code here +% } +% \tl_new:N \l_@@_internal_tl +% \end{verbatim} +% +% To extract the code using \ds, the original `guard' +% mecahnism is extended by the introduction of the syntax +% \texttt{\%<@@=\meta{module}>}. The \meta{module} name then +% replaces the |@@| when the code is extracted, so that +% \begin{verbatim} +% %<*package> +% %<@@=foo> +% \cs_new_protected:Npn \@@_some_function:nn #1#2 +% { +% % Some code here +% } +% \tl_new:N \l_@@_internal_tl +% %</package> +% \end{verbatim} +% is extracted as +% \begin{verbatim} +% \cs_new_protected:Npn \__foo_some_function:nn #1#2 +% { +% % Some code here +% } +% \tl_new:N \l__foo_internal_tl +% \end{verbatim} +% where the |__| indicates that the functions and variables are +% internal to the \texttt{foo} module. +% +% Use |@@@@| to obtain |@@| in the output (|@@@@@| to get |@@@|). +% For longer pieces of code the replacement can be completely +% suppressed by giving an empty module name, namely using the +% syntax \texttt{\%<@@=>}. +% % \section{Those other languages} % Since \TeX\ is an open system some of \TeX\ packages include % non-\TeX\ files. Some authors use \ds\ to generate PostScript @@ -853,7 +906,7 @@ % % \subsection{Verbatim mode} % If your programming language uses some construct that can -% interferes badly with \ds\ (e.g., percent in column one) you may +% interfere badly with \ds\ (e.g., percent in column one) you may % need a way for preventing it from being stripped off. For that % purpose \ds\ features `verbatim mode'. % @@ -2245,9 +2298,14 @@ Z % \subsection{Processing the input lines} % % \begin{macro}{\normalLine} +% \changes{v2.6a}{2020-07-07}{The search-and-replace macro +% \cs{replaceModuleInLine} added from \textsf{l3docstrip.dtx} +% (gh/337)} % The macro |\normalLine| writes its argument (which has to be % delimited with |\endLine|) on all active output files i.e. -% those with off-counters equal to zero. +% those with off-counters equal to zero. It uses the +% search-and-replace macro \cs{replaceModuleInLine} to replace any +% occurences of \texttt{@@} with the current module name. % If statistics are included, the counter % |\codeLinesPassed| is incremented by $1$. % \begin{macrocode} @@ -2257,6 +2315,7 @@ Z %</stats> \maybeMsg{.}% \def\inLine{#1}% + \replaceModuleInLine \let\do\putline@do \activefiles } @@ -2417,14 +2476,17 @@ Z % \changes{2.3a}{1995/08/18}{Adapted to concurrent version} % \changes{2.3a}{1995/08/20}{Trying to avoid assignments} % \changes{2.3e}{1996/09/16}{Verbatim mode} +% \changes{v2.6a}{2020-07-07}{Add the @-sign option from +% \textsf{l3docstrip.dtx} (gh/337)} +% % When the macros that process a line have found that the line % starts with `\texttt{\%<}', a guard line has been encountered. % The first character of a guard can be an asterisk (\texttt{*}), a % slash (\texttt{/}) a plus (\texttt{+}), a minus (\texttt{-}), a -% less-than sign (\texttt{<}) starting verbatim mode or -% any other character that can be found in an option name. This -% means that we have to peek at the next token and -% decide what kind of guard we have. +% less-than sign (\texttt{<}) starting verbatim mode, a commercial +% at (\texttt{@}) or any other character that can be found in an +% option name. This means that we have to peek at the next token +% and decide what kind of guard we have. % % We reinsert |#1| as it may be needed by |\doOption|. % \begin{macrocode} @@ -2432,12 +2494,13 @@ Z \ifcase \ifx*#10\else \ifx/#11\else \ifx+#12\else \ifx-#13\else - \ifx<#14\else 5\fi\fi\fi\fi\fi\relax + \ifx<#14\else \ifx @#15\else 6\fi\fi\fi\fi\fi\fi\relax \expandafter\starOption\or \expandafter\slashOption\or \expandafter\plusOption\or \expandafter\minusOption\or \expandafter\verbOption\or + \expandafter\moduleOption\or \expandafter\doOption\fi #1} % \end{macrocode} @@ -2452,12 +2515,17 @@ Z % result of the test |\if1\Expr{|\meta{options}|}|, the current % line is either copied to the output stream or removed. Then % the test is computed for all active output files. +% \changes{v2.6a}{2020-07-07}{Now use \cs{InLine} and call +% \cs{replaceModuleInline} (gh/337)} % \begin{macrocode} \def\doOption#1>#2\endLine{% \maybeMsg{<#1 . >}% \Evaluate{#1}% \def\do##1##2##3{% - \if1\Expr{##2}\StreamPut##1{#2}\fi + \if1\Expr{##2}% + \def\inLine{#2}% + \replaceModuleInLine + \StreamPut##1{\inLine}\fi }% \activefiles } @@ -2681,6 +2749,94 @@ Z % \end{macrocode} % \end{macro} % +% \begin{macro}{\moduleOption} +% \changes{v2.6a}{2020-07-07}{Macro added from +% \textsf{l3docstrip.dtx} (gh/337)} +% +% In the case where the line starts |%<@|: the defined syntax requires that +% this continues to |%<@@=|. At the moment, we assume that the syntax is +% correct and |#1| here is the module name for substitution into any +% internal functions in the extracted material. +% \begin{macrocode} +\def\moduleOption @@=#1>#2\endLine{% + \maybeMsg{<@@=#1>}% + \prepareActiveModule{#1}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\prepareActiveModule} +% \changes{v2.6a}{2020-07-07}{Macro added from +% \textsf{l3docstrip.dtx} (gh/337)} +% \begin{macro}{\replaceModuleInLine} +% \changes{v2.6a}{2020-07-07}{Macro added from +% \textsf{l3docstrip.dtx} (gh/337)} +% Here, we set up to do the search-and-replace when doing the +% extraction. The argument (|#1|) is the replacement text to use, +% or if empty an indicator that no replacement should be done. The +% search material is one of |__@@|, |_@@| or |@@|, done in order +% such that all three end up the same in the output. The string +% |@@@@| is hidden from these replacements by temporarily turning +% it into a pair of letters with different category codes, not +% produced by \ds; this allows to get |@@| in the +% output. The replacement function is initialised as a do-nothing +% for the case where |%<@@=| is never seen. +% \begin{macrocode} +\begingroup + \catcode`\_ = 12 % + \long\gdef\prepareActiveModule#1{% + \ifx\relax#1\relax + \let\replaceModuleInLine\empty + \else + \edef\replaceModuleInLine{% + \noexpand\replaceAllIn\noexpand\inLine{@@@@}{\string aa}% + \noexpand\replaceAllIn\noexpand\inLine{__@@}{__#1}% + \noexpand\replaceAllIn\noexpand\inLine{_@@}{__#1}% + \noexpand\replaceAllIn\noexpand\inLine{@@}{__#1}% + \noexpand\replaceAllIn\noexpand\inLine{\string aa}{@@}% + }% + \fi + } +\endgroup +\let\replaceModuleInLine\empty +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\replaceAllIn} +% \changes{v2.6a}{2020-07-07}{Macro added from +% \textsf{l3docstrip.dtx} (gh/337)} +% \begin{macro}{\replaceAllInAuxI} +% \changes{v2.6a}{2020-07-07}{Macro added from +% \textsf{l3docstrip.dtx} (gh/337)} +% \begin{macro}{\replaceAllInAuxII} +% \changes{v2.6a}{2020-07-07}{Macro added from +% \textsf{l3docstrip.dtx} (gh/337)} +% \begin{macro}{\replaceAllInAuxIII} +% \changes{v2.6a}{2020-07-07}{Macro added from +% \textsf{l3docstrip.dtx} (gh/337)} +% The code here is a simple search-and-replace routine for a macro +% |#1|, replacing |#2| by |#3|. As set up here, there is an +% assumption that nothing is going to be expandable, which is +% reasonable as \ds\ deals with `string' material. +% \begin{macrocode} +\long\def\replaceAllIn#1#2#3{% + \long\def\tempa##1##2#2{% + ##2\qMark\replaceAllInAuxIII#3##1% + }% + \edef#1{\expandafter\replaceAllInAuxI#1\qMark#2\qStop}% +} +\def\replaceAllInAuxI{% + \expandafter\replaceAllInAuxII\tempa\replaceAllInAuxI\empty +} +\long\def\replaceAllInAuxII#1\qMark#2{#1} +\long\def\replaceAllInAuxIII#1\qStop{} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% % \subsection{Batchfile commands} % \changes{2.3e}{1996/10/02}{Added doc} % \ds{} keeps information needed to control inclusion of sources in diff --git a/Master/texmf-dist/source/latex-dev/base/format.ins b/Master/texmf-dist/source/latex-dev/base/format.ins index 940161edd5b..5d96b5e1f35 100644 --- a/Master/texmf-dist/source/latex-dev/base/format.ins +++ b/Master/texmf-dist/source/latex-dev/base/format.ins @@ -161,6 +161,7 @@ the system are in the document `cfgguide.tex'. \from{ltdirchk.dtx}{initex,2ekernel,dircheck} \from{ltplain.dtx}{2ekernel} \from{ltvers.dtx}{2ekernel} + \from{ltluatex.dtx}{2ekernel} \from{ltdefns.dtx}{2ekernel} \from{ltalloc.dtx}{2ekernel} \from{ltcntrl.dtx}{2ekernel} @@ -196,7 +197,6 @@ the system are in the document `cfgguide.tex'. \from{ltpage.dtx}{2ekernel} \from{ltoutput.dtx}{2ekernel} \from{ltclass.dtx}{2ekernel,tracerollback} - \from{ltluatex.dtx}{2ekernel} \from{ltfinal.dtx}{2ekernel}} \file{tracefnt.sty}{% \from{ltfsstrc.dtx}{package,trace}} diff --git a/Master/texmf-dist/source/latex-dev/base/ltclass.dtx b/Master/texmf-dist/source/latex-dev/base/ltclass.dtx index dd35be9ae41..152adf82ff2 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltclass.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltclass.dtx @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltclass.dtx} - [2020/04/24 v1.3k LaTeX Kernel (Class & Package Interface)] + [2020/06/05 v1.3l LaTeX Kernel (Class & Package Interface)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltclass.dtx} @@ -552,22 +552,58 @@ % |#2| current extension. \\ % |#3| current catcode of |@|. \\ % |#4| Rest of the stack. +% \changes{v1.3l}{2020/06/05}{Added \cs{@expl@push@filename@@} +% and \cs{@expl@push@filename@aux@@}} % \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}{\@pushfilename}% +%<latexrelease> {Add \@expl@push@filename@@ and \@expl@push@filename@aux@@}% \def\@pushfilename{% + \@expl@push@filename@@ \xdef\@currnamestack{% {\@currname}% {\@currext}% {\the\catcode`\@}% - \@currnamestack}} + \@currnamestack}% + \@expl@push@filename@aux@@} +%<latexrelease>\EndIncludeInRelease +%<latexrelease> +%<latexrelease>\IncludeInRelease{0000/00/00}{\@pushfilename}% +%<latexrelease> {Add \@expl@push@filename@@ and \@expl@push@filename@aux@@}% +%<latexrelease>\def\@pushfilename{% +%<latexrelease> \xdef\@currnamestack{% +%<latexrelease> {\@currname}% +%<latexrelease> {\@currext}% +%<latexrelease> {\the\catcode`\@}% +%<latexrelease> \@currnamestack}} +%<latexrelease>\EndIncludeInRelease \@onlypreamble\@pushfilename % \end{macrocode} % +% \changes{v1.3l}{2020/06/05}{Added \cs{@expl@pop@filename@@}} % \begin{macrocode} -\def\@popfilename{\expandafter\@p@pfilename\@currnamestack\@nil} +%<latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}{\@popfilename}% +%<latexrelease> {Add \@expl@pop@filename@@}% +\def\@popfilename{\expandafter\@p@pfilename\@currnamestack\@nil + \@expl@pop@filename@@} +%<latexrelease>\EndIncludeInRelease +%<latexrelease> +%<latexrelease>\IncludeInRelease{0000/00/00}{\@pushfilename}% +%<latexrelease> {Add \@expl@push@filename@@ and \@expl@push@filename@aux@@}% +%<latexrelease>\def\@popfilename{\expandafter\@p@pfilename\@currnamestack\@nil} +%<latexrelease>\EndIncludeInRelease \@onlypreamble\@popfilename % \end{macrocode} % % \begin{macrocode} +%</2ekernel|latexrelease> +%<*2ekernel> +% \end{macrocode} +% +% \begin{macrocode} \def\@p@pfilename#1#2#3#4\@nil{% \gdef\@currname{#1}% \gdef\@currext{#2}% diff --git a/Master/texmf-dist/source/latex-dev/base/ltdefns.dtx b/Master/texmf-dist/source/latex-dev/base/ltdefns.dtx index 8b7a307ad2d..3abd251e4c9 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltdefns.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltdefns.dtx @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltdefns.dtx} - [2020/05/15 v1.5h LaTeX Kernel (definition commands)] + [2020/06/04 v1.5i LaTeX Kernel (definition commands)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltdefns.dtx} @@ -101,6 +101,16 @@ %<*2ekernel> % \end{macrocode} % +% \subsection{Loading further extensions} +% +% \changes{v1.5i}{2020-06-04}{Load \textsf{ltexpl} in \texttt{ltdefns}} +% Simply load further code: it's deliberately separate. +% This is done as soon as possible here in \texttt{ltdefns.dtx} so that +% we have the extensions as soon as possible. +% \begin{macrocode} +\input ltexpl.ltx +% \end{macrocode} +% % \subsection{Initex initialisations} % % \task{???}{This section needs extension} diff --git a/Master/texmf-dist/source/latex-dev/base/ltexpl.dtx b/Master/texmf-dist/source/latex-dev/base/ltexpl.dtx index 5e726298b26..7a567e378f3 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltexpl.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltexpl.dtx @@ -33,10 +33,10 @@ %<*driver> % \fi \ProvidesFile{ltexpl.dtx} - [2020-05-03 v1.2b LaTeX Kernel (expl3-dependent code)] + [2020-07-08 v1.2d LaTeX Kernel (expl3-dependent code)] % \iffalse \documentclass{ltxdoc} -\GetFileInfo{ltfinal.dtx} +\GetFileInfo{ltexpl.dtx} \title{\filename} \date{\filedate} \author{% @@ -44,7 +44,7 @@ \begin{document} \MaintainedByLaTeXTeam{latex} \maketitle - \DocInput{ltfinal.dtx} + \DocInput{ltexpl.dtx} \end{document} %</driver> % \fi @@ -55,69 +55,170 @@ % % \changes{v0.0}{2019-10-02}{Initial version} % +% \subsection{Loader} +% +% \changes{v1.0a}{2020/03/02} +% {Don't load expl3 if already in the format (gh/295)} +% \changes{v1.1}{2020/03/05} +% {Load xparse.ltx if \cs{NewDocumentCommand} is not defined +% by expl3.ltx} +% \changes{v1.2c}{2020/06/04} +% {Define a local version of some \LaTeXe{} basic macros to support +% package loading} +% +% First define some blank commands, so that in case something goes wrong while +% loading \textsf{expl3}, we won't get strange \texttt{Undefined control +% sequence} errors. % \begin{macrocode} %<*2ekernel> +\def\@expl@sys@load@backend@@{} +\def\@expl@push@filename@@{} +\def\@expl@push@filename@aux@@{} +\def\@expl@pop@filename@@{} +%</2ekernel> % \end{macrocode} % -% \subsection{Loader} +% \changes{v1.2d}{2020/07/08} +% {Add a last-minute hook for \textsf{expl3}} +% Create a hook for last-minute \pkg{expl3} material. +% \begin{macrocode} +%<*2ekernel> +\def\@expl@finalise@setup@@{} +%</2ekernel> +% \end{macrocode} % -% Check for the required primitive/engine support and the existence of -% a loader. +% Now define some basics to support loading \textsf{expl3}. These macros can +% be defined here safely, because they are redefined later on by the kernel, +% so we define simpler versions just to suit our needs. % \begin{macrocode} +%<*2ekernel> +\long\def\@gobble#1{} +\long\def\@firstofone#1{#1} +\long\def\@firstoftwo#1#2{#1} +\long\def\@secondoftwo#1#2{#2} +\long\def\IfFileExists#1{% + \openin\@inputcheck"#1" % + \ifeof\@inputcheck + \expandafter\@secondoftwo + \else + \closein\@inputcheck + \expandafter\@firstoftwo + \fi} +\long\def\@ifnextchar#1#2#3{% + \let\reserved@d=#1% + \def\reserved@a{#2}% + \def\reserved@b{#3}% + \futurelet\@let@token\@ifnch} +\def\@ifnch{% + \ifx\@let@token\reserved@d + \expandafter\reserved@a + \else + \expandafter\reserved@b + \fi} %</2ekernel> -%<*2ekernel|latexrelease> -%<latexrelease>\IncludeInRelease{2020/02/02}% -%<latexrelease> {expl3}{Pre-load expl3}% % \end{macrocode} +% % If we are doing a rollback with a format containing expl3 we % aren't reloading it as that creates havoc. This may need a % refined version! -% \changes{v1.0a}{2020/03/02} -% {Don't load expl3 if already in the format (gh/295)} -% \changes{v1.1}{2020/03/05} -% {Load xparse.ltx if \cs{NewDocumentCommand} is not defined -% by expl3.ltx} % \begin{macrocode} +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {expl3}{Pre-load expl3}% \expandafter\ifx\csname tex\string _let:D\endcsname\relax - \IfFileExists{expl3.ltx} - {% - \ifnum0% - \ifdefined\pdffilesize 1\fi - \ifdefined\filesize 1\fi - \ifdefined\luatexversion\ifnum\luatexversion>94 1\fi\fi - >0 % - \expandafter\@firstofone - \else - \message{Skipping expl3-dependent extensions} -%<2ekernel> \expandafter\endinput -%<latexrelease> \expandafter\@gobble - \fi - } - {% - \message{Skipping expl3-dependent extensions}% -%<2ekernel> \endinput -%<latexrelease> \@gobble - }% - {% - \input{expl3.ltx} - \ifdefined\NewDocumentCommand - \else - \IfFileExists{xparse.ltx} - {\input{xparse.ltx}} - {}% - \fi - }% + \expandafter\@firstofone \else - \GenericInfo{}{Skipping: expl3 code already part of the format} + \GenericInfo{}{Skipping: expl3 code already part of the format}% +%<2ekernel> \expandafter\endinput +%<latexrelease> \expandafter\@gobble \fi -%</2ekernel|latexrelease> +% \end{macrocode} +% +% Check for the required primitive/engine support and the existence of +% a loader. +% \begin{macrocode} + {% + \IfFileExists{expl3.ltx} + {% + \ifnum0% + \ifdefined\pdffilesize 1\fi + \ifdefined\filesize 1\fi + \ifdefined\luatexversion\ifnum\luatexversion>94 1\fi\fi + \ifdefined\kanjiskip 1\fi + >0 % + \expandafter\@firstofone + \else +% \end{macrocode} +% +% In \texttt{2ekernel} mode, an error is fatal and building the format +% is aborted. Use \verb=\batchmode \read -1 to \tokenlist=, which errors +% with +% \verb=! Emergency stop. (cannot \read from terminal in nonstop modes)= +% and aborts the \TeX{} run. In \texttt{latexrelease} mode, raise an +% error and do nothing. Both ways, the error message shows the minimum +% \textsf{expl3} engine requirements. +% \begin{macrocode} +%<2ekernel> \def~{ }\def\MessageBreak{^^J~~~~~~~~~~~~~~~}% +%<2ekernel> \errmessage{LaTeX Error: +%<latexrelease> \@latex@error{% + LaTeX requires the e-TeX primitives and additional\MessageBreak + functionality available in the engines:\MessageBreak + - pdfTeX v1.40\MessageBreak + - XeTeX v0.99992\MessageBreak + - LuaTeX v0.95\MessageBreak + - e-(u)pTeX mid-2012\MessageBreak + or later% +%<latexrelease> }\@ehd \expandafter\@gobble +%<2ekernel> }\batchmode \read -1 to \reserved@a + \fi + } + {% +%<*2ekernel> + \errmessage{LaTeX requires expl3}% + \batchmode \read -1 to \reserved@a +%</2ekernel> +%<*latexrelease> + \@latex@error{LaTeX requires expl3}\@ehd + \@gobble +%</latexrelease> + }% + {% + \input expl3.ltx + \ifdefined\NewDocumentCommand + \else + \IfFileExists{xparse.ltx} + {\input xparse.ltx } + {}% + \fi + }% + } +%<latexrelease>\EndIncludeInRelease +%<latexrelease> +%<latexrelease>\IncludeInRelease{2020/02/02}% +%<latexrelease> {expl3}{Pre-load expl3}% +%<latexrelease>\IfFileExists{expl3.ltx} +%<latexrelease> {% +%<latexrelease> \ifnum0% +%<latexrelease> \ifdefined\pdffilesize 1\fi +%<latexrelease> \ifdefined\filesize 1\fi +%<latexrelease> \ifdefined\luatexversion\ifnum\luatexversion>94 1\fi\fi +%<latexrelease> >0 % +%<latexrelease> \else +%<latexrelease> \message{Skipping expl3-dependent extensions} +%<latexrelease> \expandafter\@gobbletwo +%<latexrelease> \fi +%<latexrelease> } +%<latexrelease> {% +%<latexrelease> \message{Skipping expl3-dependent extensions}% +%<latexrelease> \@gobbletwo +%<latexrelease> }% +%<latexrelease>\input{expl3.ltx} %<latexrelease>\EndIncludeInRelease % \end{macrocode} % % \subsection{Using expl3 code} % % \begin{macrocode} -%<*2ekernel|latexrelease> %<latexrelease>\IncludeInRelease{2020/10/01}% %<latexrelease> {\@expl@tl@trim@spaces@apply@@nN} %<latexrelease> {l3 macro for use in include}% @@ -141,7 +242,6 @@ % \end{macrocode} % % \begin{macrocode} -%</2ekernel|latexrelease> %<latexrelease>\EndIncludeInRelease %<latexrelease>\IncludeInRelease{0000/00/00}% %<latexrelease> {\@expl@tl@trim@spaces@apply@@nN} @@ -150,11 +250,7 @@ %<latexrelease>\let\@expl@tl@trim@spaces@apply@@nN\@undefined %<latexrelease> %<latexrelease>\EndIncludeInRelease -%<*2ekernel> -% \end{macrocode} -% -% \begin{macrocode} -%</2ekernel> +%</2ekernel|latexrelease> % \end{macrocode} % % \Finale diff --git a/Master/texmf-dist/source/latex-dev/base/ltfilehook.dtx b/Master/texmf-dist/source/latex-dev/base/ltfilehook.dtx new file mode 100644 index 00000000000..6c16a9832ea --- /dev/null +++ b/Master/texmf-dist/source/latex-dev/base/ltfilehook.dtx @@ -0,0 +1,1161 @@ +% \iffalse meta-comment +% +%% File: ltfilehook.dtx (C) Copyright 2020 Frank Mittelbach, LaTeX Team +% +% It may be distributed and/or modified under the conditions of the +% LaTeX Project Public License (LPPL), either version 1.3c of this +% license or (at your option) any later version. The latest version +% of this license is in the file +% +% https://www.latex-project.org/lppl.txt +% +% +% The development version of the bundle can be found below +% +% https://github.com/FrankMittelbach/... +% +% for those people who are interested or want to report an issue. +% +% \begin{macrocode} +\providecommand\ltfilehookversion{v0.9a} +\providecommand\ltfilehookdate{2020/07/19} +% \end{macrocode} +% +%<*driver> + +\RequirePackage{lthooks} % needed for structedlog if running old format + +\documentclass{l3doc} + +% bug fix fo l3doc.cls +\ExplSyntaxOn +\cs_set_protected:Npn \__codedoc_macro_typeset_one:nN #1#2 + { + \vbox_set:Nn \l__codedoc_macro_box + { + \vbox_unpack_drop:N \l__codedoc_macro_box + \hbox { \llap { \__codedoc_print_macroname:nN {#1} #2 + \MacroFont % <----- without it the \ is in lmr10 if a link is made + \ + } } + } + \int_incr:N \l__codedoc_macro_int + } +\ExplSyntaxOff + +\usepackage{structuredlog} % for demonstration + +\EnableCrossrefs +\CodelineIndex +\begin{document} + \DocInput{ltfilehook.dtx} +\end{document} +%</driver> +% +% \fi +% +% +% \long\def\fmi#1{\begin{quote}\itshape Todo: #1\end{quote}} +% +% \let\hook\texttt +% +% \title{The \texttt{ltfilehook} package\thanks{This package has version +% \ltfilehookversion\ dated \ltfilehookdate, \copyright\ \LaTeX\ +% Project.}} +% +% \author{Frank Mittelbach} +% +% \maketitle +% +% +% +% \tableofcontents +% +% \section{Introduction} +% +% +% +% \subsection{Provided hooks} +% +% The code offers a number of hooks into which packages (or the +% user) can add code to support different use cases. +% Many hooks are offered as pairs (i.e., the second hook is +% reversed. Also important to know is that these pairs are +% properly nested with respect to other pairs of hooks. +% +% There are hooks that are executed for all files of a certain type +% (if they contain code), e.g., for all \enquote{include files} or +% all \enquote{packages}, +% and there are also hooks that are specific to a single file, +% e.g., do something after the package \texttt{foo.sty} has been +% loaded. +% +% +% \subsection{General hooks for file reading} +% \label{sec:general-file-hooks} +% +% There are four hooks that are called for each file that is read +% using document-level commands such as \cs{input}, \cs{include}, +% \cs{usepackage}, etc. They are not called for files read using +% internal low-level methods, such as \cs{@input} or \cs{openin}. +% +% \begin{variable}{file/before,file/before/..., +% file/after/...,file/after, +% } +% These are: +% \begin{description} +% \item[\texttt{file/before}, \texttt{file/before/\meta{file-name}}] +% +% These hooks are executed in that order just before the file is +% loaded for reading. The code of the first hook is used is used +% with every file, while the second is executed only for the +% file with matching \meta{file-name} allowing you to specify +% code that only applies to one file. +% +% \item[\texttt{file/after/\meta{file-name}}, \texttt{file/after}] +% +% These hooks are after the file with name \meta{file-name} has +% been fully consumed. The order is swapped (the specific one +% comes first) so that the \texttt{before} and \texttt{after} +% hooks nest properly, which is important if any of them involve +% grouping (e.g., contain environments, for example). +% furthermore both hooks are reversed hooks to support correct +% nesting of different packages add code to both +% \texttt{/before} and \texttt{/after} hooks. +% +% \end{description} +% \end{variable} +% +% +% So the overall sequence of hook processing for any file read +% through the user interface commands of \LaTeX{} is: +% +% \begin{tabbing} +% mm\=mm\=mm\=mm\=\kill +% \>\cs{UseHook}\marg{\hook{file/before}} \\ +% \>\cs{UseHook}\marg{\hook{file/before/\meta{file name}}} \\ +% \>\> \meta{file contents} \\ +% \>\cs{UseHook}\marg{\hook{file/after/\meta{file name}}} \\ +% \>\cs{UseHook}\marg{\hook{file/after}} +% \end{tabbing} +% +% \fmi{With a higher-level interface that doesn't matter, but it +% is a bit weird, if you use \cs{AddToHook} or \cs{hook_gput:nnn} +% directly, so I guess that has to be done differently!} +% +% The file hooks only refer to the file by its name and extension, +% so the \meta{file name} should be the file name as it is on the +% filesystem with extension (if any) and without paths. Different +% from \cs{input} and similar commands, for hooks the \texttt{.tex} +% extension is not assumed, so \texttt{.tex} files must also be given +% with their extension. +% Files within subfolders should also be addressed by their name and +% extension only. +% +% Extensionless files also work, and should then be given without +% extension. Note however that \TeX{} prioritizes \texttt{.tex} +% files, so if two files \texttt{foo} and \texttt{foo.tex} exist in +% the search path, only the latter will be seen. +% +% When a file is input, the \meta{file name} is available in +% \cs{CurrentFile}, which is then used when accessing the +% \hook{file/before/\meta{file name}} and +% \hook{file/after/\meta{file name}}. +% +% \begin{variable}{\CurrentFile} +% The name of the file about to be read (or just finished) is +% available to the hooks through \cs{CurrentFile} (there is no +% \texttt{expl3} name for it for now). The file is always provided +% with its extension, i.e., how it appears on your hard drive, but +% without any specified path to it. For example, +% \verb=\input{sample}= and \verb=\input{app/sample.tex}= would +% both have \cs{CurrentFile} being \texttt{sample.tex}. +% \end{variable} +% +% \begin{variable}{\CurrentFilePath} +% The path to the current file (complement to \cs{CurrentFile}) is +% available in \cs{CurrentFilePath} if needed. +% The paths returned in \cs{CurrentFilePath} are only user paths, +% given through \cs{input@path} (or \pkg{expl3}'s equivalent +% \cs{l_file_search_path_seq}) or by directly typing in the path +% in the \cs{input} command or equivalent. Files located by +% \texttt{kpsewhich} get the path added internally by the \TeX{} +% implementation, so at the macro level it looks as if the file were +% in the current folder, so the path in \cs{CurrentFilePath} is empty +% in these cases (package and class files, mostly). +% \end{variable} +% +% \subsection{Hooks for package and class files} +% +% Commands to load package and class files (e.g., \cs{usepackage}, +% \cs{RequirePackage}, \cs{LoadPackageWithOptions}, etc.) offer the +% hooks from section~\ref{sec:general-file-hooks} when they are +% used to load a package or class file, e.g., +% \texttt{file/after/array.sty} would be called after the +% \pkg{array} package got loaded. But as packages and classes form as special group +% of files, there are some additional hooks available that only +% apply when a package or class is loaded. +% +% +% \begin{variable}{ +% package/before,package/after, +% package/before/...,package/after/..., +% class/before,class/after, +% class/before/...,class/after/..., +% } +% These are: +% \begin{description} +% \item[\texttt{package/before}, \texttt{package/after}] +% +% These hooks are called for each package being loaded. +% +% \item[\texttt{package/before/\meta{name}}, +% \texttt{package/after/\meta{name}}] +% +% These hooks are additionally called if the package name is +% \meta{name} (without extension). +% +% \item[\texttt{class/before}, \texttt{class/after}] +% +% These hooks are called for each class being loaded. +% +% \item[\texttt{class/before/\meta{name}}, \texttt{class/after/\meta{name}}] +% +% These hooks are additionally called if the class name is +% \meta{name} (without extension). +% +% \end{description} +% \end{variable} +% All \hook{/after} hooks are implemented as reversed hooks. +% +% \noindent The overall sequence of execution for \cs{usepackage} +% and friends is therefore: +% \begin{tabbing} +% mm\=mm\=mm\=mm\=\kill +% \>\cs{UseHook}\marg{\hook{package/before}} \\ +% \>\cs{UseHook}\marg{\hook{package/before/\meta{package name}}} \\[5pt] +% \>\>\cs{UseHook}\marg{\hook{file/before}} \\ +% \>\>\cs{UseHook}\marg{\hook{file/before/\meta{package name}.sty}} \\ +% \>\>\> \meta{package contents} \\ +% \>\>\cs{UseHook}\marg{\hook{file/after/\meta{package name}.sty}} \\ +% \>\>\cs{UseHook}\marg{\hook{file/after}} \\[5pt] +% \>\>\emph{code from \cs{AtEndOfPackage} if +% used inside the package} \\[5pt] +% \>\cs{UseHook}\marg{\hook{package/after/\meta{package name}}} \\ +% \>\cs{UseHook}\marg{\hook{package/after}} +% \end{tabbing} +% and similar for class file loading, except that \texttt{package/} +% is replaced by \texttt{class/} and \cs{AtEndOfPackage} by +% \cs{AtEndOfClass}. +% +% If a package or class is not loaded (or it was loaded before the +% hooks were set) none of the hooks are executed! +% +% \subsection{Hooks for \cs{include} files} +% +% To manage \cs{include} files, \LaTeX{} issues a \cs{clearpage} +% before and after loading such a file. Depending on the use case +% one may want to execute code before or after these +% \cs{clearpage}s especially for the one that is issued at the end. +% +% Executing code before the final \cs{clearpage}, means that the +% code is processed while the last page of the included material is +% still under construction. Executing code after it means that all +% floats from inside the include file are placed (which +% might have added further pages) and the final page has finished. +% +% Because of these different scenarios we offer hooks in three +% places.\footnote{If you want to execute code before the first +% \cs{clearpage} there is no need to use a hook---you can write it +% directly in front of the \cs{include}.} +% None of the hooks are executed when an \cs{include} file is +% bypassed because of an \cs{includeonly} declaration. They are, +% however, all executed if \LaTeX{} makes an attempt to load the +% \cs{include} file (even if it doesn't exist and all that happens +% is \enquote{\texttt{No file \meta{filename}.tex}}). +% +% +% \begin{variable}{include/before,include/before/..., +% include/end,include/end/..., +% include/after,include/after/..., +% } +% These are: +% \begin{description} +% +% \item[\texttt{include/before}, \texttt{include/before/\meta{name}}] +% +% These hooks are executed one after another after the initial +% \cs{clearpage} and after \texttt{.aux} file is changed to use +% \texttt{\meta{name}.aux}, but before the +% \texttt{\meta{name}.tex} file is loaded. In other words they are executed +% at the very beginning of the first page of the \cs{include} +% file. +% +% +% \item[\texttt{include/end/\meta{name}}, \texttt{include/end}] +% +% These hooks are executed (in that order) after \LaTeX{} has +% stopped reading from the \cs{include} file, but before it has +% issued a \cs{clearpage} to output any deferred floats. +% +% +% \item[\texttt{include/after/\meta{name}}, \texttt{include/after}] +% +% These hooks are executed (in that order) after \LaTeX{} has +% issued the \cs{clearpage} but before is has switched back +% writing to the main \texttt{.aux} file. Thus technically we are +% still inside the \cs{include} and if the hooks generate any +% further typeset material including anything that writes to the +% \texttt{.aux} file, then it would be considered part of the +% included material and bypassed if it is not loaded because of +% some \cs{includeonly} statement.\footnotemark +% +% \end{description} +% \end{variable}\footnotetext{For that reason +% another \cs{clearpage} is executed after these hooks which +% normally does nothing, but starts a new page if further material +% got added this way.} +% +% \subsection{High-level interfaces for \LaTeX{}} +% +% We do not provide any high-level \LaTeX{} commands (like +% \pkg{filehook} or \pkg{scrlfile} do) but think that for package +% writers the commands from for hook management are sufficient. +% +% \subsection{A sample package for structuring the log output} +% +% As an application we provide the package \pkg{structuredlog} that +% adds lines to the \texttt{.log} when a file is opened and closed +% for reading keeping track of nesting level es well. +% For example, for the current document it adds the lines +%\begin{verbatim} +% = (LEVEL 1 START) t1lmr.fd +% = (LEVEL 1 STOP) t1lmr.fd +% = (LEVEL 1 START) supp-pdf.mkii +% = (LEVEL 1 STOP) supp-pdf.mkii +% = (LEVEL 1 START) nameref.sty +% == (LEVEL 2 START) refcount.sty +% == (LEVEL 2 STOP) refcount.sty +% == (LEVEL 2 START) gettitlestring.sty +% == (LEVEL 2 STOP) gettitlestring.sty +% = (LEVEL 1 STOP) nameref.sty +% = (LEVEL 1 START) ltfilehook-doc.out +% = (LEVEL 1 STOP) ltfilehook-doc.out +% = (LEVEL 1 START) ltfilehook-doc.out +% = (LEVEL 1 STOP) ltfilehook-doc.out +% = (LEVEL 1 START) ltfilehook-doc.hd +% = (LEVEL 1 STOP) ltfilehook-doc.hd +% = (LEVEL 1 START) ltfilehook.dtx +% == (LEVEL 2 START) ot1lmr.fd +% == (LEVEL 2 STOP) ot1lmr.fd +% == (LEVEL 2 START) omllmm.fd +% == (LEVEL 2 STOP) omllmm.fd +% == (LEVEL 2 START) omslmsy.fd +% == (LEVEL 2 STOP) omslmsy.fd +% == (LEVEL 2 START) omxlmex.fd +% == (LEVEL 2 STOP) omxlmex.fd +% == (LEVEL 2 START) umsa.fd +% == (LEVEL 2 STOP) umsa.fd +% == (LEVEL 2 START) umsb.fd +% == (LEVEL 2 STOP) umsb.fd +% == (LEVEL 2 START) ts1lmr.fd +% == (LEVEL 2 STOP) ts1lmr.fd +% == (LEVEL 2 START) t1lmss.fd +% == (LEVEL 2 STOP) t1lmss.fd +% = (LEVEL 1 STOP) ltfilehook.dtx +%\end{verbatim} +% Thus if you inspect an issue in the \texttt{.log} it is easy to +% figure out in which file it occurred, simply by searching back for +% \texttt{LEVEL} and if it is a \texttt{STOP} then remove 1 from +% the level value and search further for \texttt{LEVEL} with that value +% which should then be the \texttt{START} level of the file you are in. +% +% \StopEventually{\setlength\IndexMin{200pt} \PrintIndex } +% +% +% \section{The Implementation} +% \begin{macrocode} +%<*2ekernel> +% \end{macrocode} +% +% \subsection{\pkg{expl3} helpers} +% +% \begin{macrocode} +%<@@=filehook> +% \end{macrocode} +% +% \begin{macro}{\CurrentFile,\CurrentFilePath} +% User-level macros that hold the current file name and file path. +% These are used internally as well because the code takes care to +% protect against a possible redefinition of these macros in the loaded +% file (it's necessary anyway to make hooks work with nested +% \cs{input}). +% \begin{macrocode} +\def\CurrentFile{} +\def\CurrentFilePath{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\l_@@_internal_tl} +% \begin{macro}{\@filehook@set@curr@file,\@@_normalise_file_name:n} +% When inputting a file, \cs{@filehook@set@curr@file} does a file +% lookup (in \cs{input@path} and \cs{l_file_search_path_seq}) and +% returns the actual file name (\meta{base} plus \meta{ext}) in +% \cs{CurrentFile}. Only the base and extension are returned, +% regardless of the input (both \texttt{path/to/file.tex} and +% \texttt{file.tex} end up as \texttt{file.tex} in \cs{CurrentFile}). +% The path is returned in \cs{CurrentFilePath}, in case it's needed. +% \cs{CurrentFile} is then used to run the file hooks with +% \texttt{file/before/\cs{CurrentFile}} and +% \texttt{file/after/\cs{CurrentFile}}. +% \begin{macrocode} +\ExplSyntaxOn +\tl_new:N \l_@@_internal_tl +\cs_new_protected:Npn \@filehook@set@curr@file #1 + { \exp_args:NV \@@_normalise_file_name:n #1 } +\cs_new_protected:Npn \@@_normalise_file_name:n #1 + { + \file_if_exist:nTF {#1} + { + \exp_args:Nx \file_parse_full_name:nNNN + { \file_full_name:n {#1} } + } + { \file_parse_full_name:nNNN {#1} } + \CurrentFilePath \CurrentFile \l_@@_internal_tl + \tl_set:Nx \CurrentFile { \CurrentFile \l_@@_internal_tl } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\g_@@_input_file_seq} +% \begin{macro}{\@filehook@file@push,\@filehook@file@pop} +% \begin{macro}{\@@_file_pop_assign:nn} +% Yet another stack, to keep track of \cs{CurrentFile} and +% \cs{CurrentFilePath} with nested \cs{input}s. At the beginning of +% \cs{InputIfFileExists}, the current value of \cs{CurrentFilePath} +% and \cs{CurrentFile} is pushed to \cs{g_@@_input_file_seq}, and +% at the end, it is popped and the value reassigned. +% \cs{IfFileExists} does \cs{set@curr@file} internally, which changes +% \cs{CurrentFile}, so \cs{@filehook@file@push} has to be executed +% before \cs{IfFileExists}. +% \begin{macrocode} +\seq_new:N \g_@@_input_file_seq +\cs_new_protected:Npn \@filehook@file@push + { + \seq_gpush:Nx \g_@@_input_file_seq + { { \CurrentFilePath } { \CurrentFile } } + } +\cs_new_protected:Npn \@filehook@file@pop + { + \seq_gpop:NNTF \g_@@_input_file_seq \l_@@_internal_tl + { \exp_after:wN \@@_file_pop_assign:nn \l_@@_internal_tl } + { \ERROR_should_not_happen } + } +\cs_new_protected:Npn \@@_file_pop_assign:nn #1 #2 + { + \tl_set:Nn \CurrentFilePath {#1} + \tl_set:Nn \CurrentFile {#2} + } +\ExplSyntaxOff +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \subsection{Declaring the file-related hooks} +% +% All hooks starting with \texttt{file/} \texttt{include/}, +% \texttt{class/} or \texttt{package/} are generic and will be +% allocated if code is added to them. Thus there is no need to +% explicitly declare any hook in the code below. +% +% Furthermore, those named \texttt{.../after} or \texttt{.../end} are +% automatically declared as reversed hooks if filled with code, so this +% is also automatically taken care of. +% +% \subsection{Patching \LaTeX{} commands (need proper integration later)} +% +% Most of what we have to do is adding \cs{UseHook} into several +% \LaTeXe{} core commands, which is done for now by patching them. +% \begin{macrocode} +%<@@=> +% \end{macrocode} +% +% \begin{macro}{\InputIfFileExists} +% \cs{InputIfFileExists} loads any file if it is available so we +% have to add the hooks \texttt{file/before} and +% \texttt{file/after} in the right places. If the file doesn't +% exist no hooks should be executed. +% \begin{macrocode} +\let\InputIfFileExists\@undefined +\DeclareRobustCommand \InputIfFileExists[3]{% + \@filehook@file@push + \IfFileExists{#1}% + {% +% \end{macrocode} +% If the file exists then \cs{@curr@file} holds its name. But we +% can't rely on that still being true after the file has been +% processed. Thus for using the name in the file hooks we need to +% preserve the name and then restored it for the +% \texttt{file/after/...} hook. +% +% The hook always refers to the \emph{actual} file that will be +% operated on, regardless of how the user had it written in the +% document. \pkg{expl3}'s \cs{file_full_name:n} normalizes the file +% name (to factor out differences in the |.tex| extension), and +% then does a file lookup to take into account a possible path from +% \cs{l_file_search_path_seq} and \cs{input@path}. However only +% the file name and extension are returned so that file hooks can +% refer to the file by their name only. The path to the file is +% returned in \cs{CurrentFilePath}. +% \begin{macrocode} + \edef\reserved@a{\@filef@und + \def\noexpand\CurrentFile{\CurrentFile}% + \def\noexpand\CurrentFilePath{\CurrentFilePath}% + }% + \expandafter\@swaptwoargs\expandafter + {\reserved@a}% + {% + #2% + \@addtofilelist{#1}% + \UseHook{file/before}% +% \end{macrocode} +% The current file name is available in \cs{@curr@file} so we use +% that in the specific hook. +% \begin{macrocode} + \UseHook{file/before/\CurrentFile}% + \@@input + }% +% \end{macrocode} +% And it is restored here so we can use it once more. +% \begin{macrocode} + \UseHook{file/after/\CurrentFile}% + \UseHook{file/after}% + \@filehook@file@pop + }% + {\@filehook@file@pop #3}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\set@curr@file} +% Now we just hook into \cs{set@curr@file} to add +% \cs{@filehook@set@curr@file} at the end, after \cs{@curr@file} is +% set. +% \begin{macrocode} +\def\set@curr@file#1{% + \begingroup + \escapechar\m@ne + \xdef\@curr@file{% + \expandafter\expandafter\expandafter\unquote@name + \expandafter\expandafter\expandafter{% + \expandafter\string + \csname\@firstofone#1\@empty\endcsname}}% + \endgroup + \@filehook@set@curr@file{\@curr@file}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\load@onefilewithoptions} +% This macro is used when loading packages or classes. +% \begin{macrocode} +\def\load@onefilewithoptions#1[#2][#3]#4{% + \@pushfilename + \xdef\@currname{#1}% + \global\let\@currext#4% + \let\CurrentOption\@empty + \@reset@ptions + \makeatletter + \def\reserved@a{% + \@ifl@aded\@currext{#1}% + {\@if@ptions\@currext{#1}{#2}{}% + {\@latex@error + {Option clash for \@cls@pkg\space #1}% + {The package #1 has already been loaded + with options:\MessageBreak + \space\space[\@ptionlist{#1.\@currext}]\MessageBreak + There has now been an attempt to load it + with options\MessageBreak + \space\space[#2]\MessageBreak + Adding the global options:\MessageBreak + \space\space + \@ptionlist{#1.\@currext},#2\MessageBreak + to your \noexpand\documentclass declaration may fix this.% + \MessageBreak + Try typing \space <return> \space to proceed.}}}% + {\@pass@ptions\@currext{#2}{#1}% + \global\expandafter + \let\csname ver@\@currname.\@currext\endcsname\@empty + \expandafter\let\csname\@currname.\@currext-h@@k\endcsname\@empty + \InputIfFileExists + {\@currname.\@currext}% + {% +%----------------------------------------- +% \end{macrocode} +% When the current extension is \cs{@pkgextension} we are loading a +% package otherwise, if it is \cs{@clsextension}, a class, so +% depending on that we execute different hooks. If the extension is +% neither, then it is another type of file without special hooks. +% \begin{macrocode} + \ifx\@currext\@pkgextension + \UseHook{package/before}% + \UseHook{package/before/\@currname}% + \else + \ifx\@currext\@clsextension + \UseHook{class/before}% + \UseHook{class/before/\@currname}% + \fi + \fi +% \end{macrocode} +% The value of \cs{CurrentFile} holds during \cs{InputIfFileExists}, +% so the hooks above have that available for using. However at this +% point \cs{CurrentFile} is reset to its previous value by +% \cs{@filehook@file@pop} because it doesn't know that we'll have +% more hooks ahead. So here (still in the \meta{true} branch of +% \cs{InputIfFileExists}, right after actually reading the file in) +% we'll cheat: use \cs{@filehook@file@push} once more, so there are +% two entries for the current file in the name stack, so that when +% \cs{InputIfFileExists} pops it, there's still one (identical) left. +% \begin{macrocode} + \@filehook@file@push +%----------------------------------------- + }% + {\@missingfileerror\@currname\@currext}% + \let\@unprocessedoptions\@@unprocessedoptions + \csname\@currname.\@currext-h@@k\endcsname + \expandafter\let\csname\@currname.\@currext-h@@k\endcsname + \@undefined +%----------------------------------------- +% \end{macrocode} +% And same procedure, James, when we are finished loading, except +% that the hook order is now reversed. +% \begin{macrocode} + \ifx\@currext\@pkgextension + \UseHook{package/after/\@currname}% + \UseHook{package/after}% + \else + \ifx\@currext\@clsextension + \UseHook{class/after/\@currname}% + \UseHook{class/after}% + \fi + \fi +% \end{macrocode} +% Now here we do \cs{@filehook@file@pop} to restore the +% \cs{CurrentFile} before this file being loaded and fix what we've +% done in the stack right above. +% \begin{macrocode} + \@filehook@file@pop +%----------------------------------------- + \@unprocessedoptions}% + \@ifl@ter\@currext{#1}{#3}{}% + {\@latex@warning@no@line + {You have requested,\on@line, + version\MessageBreak + `#3' of \@cls@pkg\space #1,\MessageBreak + but only version\MessageBreak + `\csname ver@#1.\@currext\endcsname'\MessageBreak + is available}}% + \ifx\@currext\@clsextension\let\LoadClass\@twoloadclasserror\fi + \@popfilename + \@reset@ptions}% + \reserved@a} +% \end{macrocode} +% +% The code for this macro has changed between 2020/02/02 and +% 2020/10/01 so the never version is this: +% \begin{macrocode} +\@ifl@t@r\fmtversion{2020/10/01} +{% +\def\load@onefilewithoptions#1[#2][#3]#4{% + \@pushfilename + \xdef\@currname{#1}% + \global\let\@currext#4% + \let\CurrentOption\@empty + \@reset@ptions + \makeatletter + \def\reserved@a{% + \@ifl@aded\@currext{#1}% + {\@if@ptions\@currext{#1}{#2}{}% + {\@latex@error + {Option clash for \@cls@pkg\space #1}% + {The package #1 has already been loaded + with options:\MessageBreak + \space\space[\@ptionlist{#1.\@currext}]\MessageBreak + There has now been an attempt to load it + with options\MessageBreak + \space\space[#2]\MessageBreak + Adding the global options:\MessageBreak + \space\space + \@ptionlist{#1.\@currext},#2\MessageBreak + to your \noexpand\documentclass declaration may fix this.% + \MessageBreak + Try typing \space <return> \space to proceed.}}}% + {\@pass@ptions\@currext{#2}{#1}% + \global\expandafter + \let\csname ver@\@currname.\@currext\endcsname\@empty + \expandafter\let\csname\@currname.\@currext-h@@k\endcsname\@empty + \InputIfFileExists + {\@currname.\@currext}% + {% +%----------------------------------------- + \ifx\@currext\@pkgextension + \UseHook{package/before}% + \UseHook{package/before/\@currname}% + \else + \ifx\@currext\@clsextension + \UseHook{class/before}% + \UseHook{class/before/\@currname}% + \fi + \fi + \@filehook@file@push +%----------------------------------------- + }% + {\@missingfileerror\@currname\@currext}% + \expandafter\let\csname unprocessedoptions-\@currname.\@currext\endcsname + \@@unprocessedoptions + \csname\@currname.\@currext-h@@k\endcsname + \expandafter\let\csname\@currname.\@currext-h@@k\endcsname + \@undefined + \ifx\@unprocessedoptions\relax + \let\@unprocessedoptions\@undefined + \else + \csname unprocessedoptions-\@currname.\@currext\endcsname + \fi + \expandafter\let + \csname unprocessedoptions-\@currname.\@currext\endcsname + \@undefined +%----------------------------------------- + \ifx\@currext\@pkgextension + \UseHook{package/after/\@currname}% + \UseHook{package/after}% + \else + \ifx\@currext\@clsextension + \UseHook{class/after/\@currname}% + \UseHook{class/after}% + \fi + \fi + \@filehook@file@pop +%----------------------------------------- + }% + \@ifl@ter\@currext{#1}{#3}{}% + {\@latex@warning@no@line + {You have requested,\on@line, + version\MessageBreak + `#3' of \@cls@pkg\space #1,\MessageBreak + but only version\MessageBreak + `\csname ver@#1.\@currext\endcsname'\MessageBreak + is available}}% + \ifx\@currext\@clsextension\let\LoadClass\@twoloadclasserror\fi + \@popfilename + \@reset@ptions}% + \reserved@a} +}{}% +% \end{macrocode} +% \end{macro} + + + + +% \begin{macro}{\@include} +% \begin{macrocode} +\def\@include#1 {% + \clearpage + \if@filesw + \immediate\write\@mainaux{\string\@input{#1.aux}}% + \fi + \@tempswatrue + \if@partsw + \@tempswafalse + \edef\reserved@b{#1}% + \@for\reserved@a:=\@partlist\do + {\ifx\reserved@a\reserved@b\@tempswatrue\fi}% + \fi + \if@tempswa + \let\@auxout\@partaux + \if@filesw + \immediate\openout\@partaux #1.aux + \immediate\write\@partaux{\relax}% + \fi +%----------------------------------------- +% \end{macrocode} +% First we need to fix \cs{CurrentFile}, because due the pesky +% space-delimited \cs{@include}, \cs{CurrentFile} contains the +% \cs{include}'d file with a space. To fix that, we re-do +% \cs{set@curr@file}. The 2020/10/01 release doesn't need this as +% \cs{include} was changed to do \cs{set@curr@file} on the correct +% file name, rather than one with a trailing space. +% \begin{macrocode} + \set@curr@file{#1}% +% \end{macrocode} +% Execute the \texttt{before} hooks just after we switched the +% \texttt{.aux} file \ldots +% \begin{macrocode} + \UseHook{include/before}% + \UseHook{include/before/#1}% +%----------------------------------------- + \@input@{#1.tex}% +% \end{macrocode} +% \ldots{} then \texttt{end} hooks \ldots +% \begin{macrocode} +%----------------------------------------- + \UseHook{include/end/#1}% + \UseHook{include/end}% +%----------------------------------------- + \clearpage +% \end{macrocode} +% \ldots{} and after the \cs{clearpage} the \texttt{after} hooks +% followed by another \cs{clearpage} just in case new material got +% added (after all we need to be in well defined state after the +% \cs{include}). +% \begin{macrocode} +%----------------------------------------- + \UseHook{include/after/#1}% + \UseHook{include/after}% +% \end{macrocode} +% The additional \cs{clearpage} is needed to ensure that switching +% the \texttt{.aux} files happen at a defined point even if the +% above hooks add further material. +% \begin{macrocode} + \clearpage +%----------------------------------------- + \@writeckpt{#1}% + \if@filesw + \immediate\closeout\@partaux + \fi + \else + \deadcycles\z@ + \@nameuse{cp@#1}% + \fi + \let\@auxout\@mainaux +} +% \end{macrocode} +% +% The code for this macro has changed between 2020/02/02 and +% 2020/10/01 so the never version is this: +% \begin{macrocode} +\@ifl@t@r\fmtversion{2020/10/01} +{% +\def\@include#1 {% + \clearpage + \if@filesw + \immediate\write\@mainaux{\string\@input{"#1.aux"}}% + \fi + \@tempswatrue + \if@partsw + \@tempswafalse + \edef\reserved@b{#1}% + \@for\reserved@a:=\@partlist\do + {\ifx\reserved@a\reserved@b\@tempswatrue\fi}% + \fi + \if@tempswa + \let\@auxout\@partaux + \if@filesw + \immediate\openout\@partaux "#1.aux" + \immediate\write\@partaux{\relax}% + \fi +%----------------------------------------- + \UseHook{include/before}% + \UseHook{include/before/#1}% +%----------------------------------------- + \@input@{#1.tex}% +%----------------------------------------- + \UseHook{include/end/#1}% + \UseHook{include/end}% +%----------------------------------------- + \clearpage +%----------------------------------------- + \UseHook{include/after/#1}% + \UseHook{include/after}% + \clearpage +%----------------------------------------- + \@writeckpt{#1}% + \if@filesw + \immediate\closeout\@partaux + \fi + \else + \deadcycles\z@ + \@nameuse{cp@#1}% + \fi + \let\@auxout\@mainaux} +}{} +% \end{macrocode} +% \end{macro} +% +% +% +% \subsection{High-level interfaces for \LaTeX{}} +% +% None so far and the general feeling for now is that the hooks are +% enough. Packages like \pkg{filehook}, etc., may use them to set +% up their interfaces (samples are given below) but for the now the +% kernel will not provide any. +% +% +% +% \begin{macrocode} +%</2ekernel> +% \end{macrocode} +% +% +% +% \section{Package emulation for compatibility} +% +% +% \subsection{Package \pkg{filehook} emulation} +% +% This is a partial implementation of the \pkg{filehook} +% interfaces. It is only meant for guidance in case that package +% gets updated to use the hook management. +% +% Not implemented are: +%\begin{verbatim} +% \AtBeginOfFiles +% \AtEndOfFiles +% \AtBeginOfInputs +% \AtEndOfInputs +% \AtBeginOfInputFile +% \AtEndOfInputFile +%\end{verbatim} +% +% \begin{macrocode} +%<*filehook-draft> +% \end{macrocode} +% +% \begin{macrocode} +\newcommand\AtBeginOfEveryFile [1] + {\AddToHook{file/before}{#1}} +\newcommand\AtEndOfEveryFile [1] + {\AddToHook{file/after}{#1}} +% \end{macrocode} +% +% \begin{macrocode} +\newcommand\AtBeginOfIncludes [1] + {\AddToHook{include/before}{#1}} +\newcommand\AtEndOfIncludes [1] + {\AddToHook{include/end}{#1}} +\newcommand\AfterIncludes [1] + {\AddToHook{include/after}{#1}} +% \end{macrocode} +% +% \begin{macrocode} +\newcommand\AtBeginOfPackages [1] + {\AddToHook{package/before}{#1}} +\newcommand\AtEndOfPackages [1] + {\AddToHook{package/after}{#1}} +% \end{macrocode} +% +% \begin{macrocode} +\newcommand\AtBeginOfClasses [1] + {\AddToHook{class/before}{#1}} +\newcommand\AtEndOfClasses [1] + {\AddToHook{class/after}{#1}} +% \end{macrocode} +% +% For normal files we drop the \texttt{.tex} extension for now: +% \begin{macrocode} +\newcommand\AtBeginOfFile [2] + {\AddToHook{file/before/#1}{#2}} +\newcommand\AtEndOfFile [2] + {\AddToHook{file/after/#1}{#2}} +% \end{macrocode} +% +% \begin{macrocode} +\DeclareDocumentCommand \AtBeginOfPackageFile {smm} + {\IfBooleanTF{#1}% + {\@ifpackageloaded{#2}% + {#3}% + {\AddToHook{package/before/#2}{#3}}}% + {\AddToHook{package/before/#2}{#3}}% + } +\DeclareDocumentCommand \AtEndOfPackageFile {smm} + {\IfBooleanTF{#1}% + {\@ifpackageloaded{#2}% + {#3}% + {\AddToHook{package/after/#2}{#3}}}% + {\AddToHook{package/after/#2}{#3}}% + } +% \end{macrocode} +% +% Are the * forms here of any use? I know they are use 3--4 times +% on CTAN but I wonder if those are real or mistaken usages. +% \begin{macrocode} +\DeclareDocumentCommand \AtBeginOfClassFile {smm} + {\IfBooleanTF{#1}% + {\@ifclassloaded{#2}% + {#3}% + {\AddToHook{class/before/#2}{#3}}}% + {\AddToHook{class/before/#2}{#3}}% + } +\DeclareDocumentCommand \AtEndOfClassFile {smm} + {\IfBooleanTF{#1}% + {\@ifclassloaded{#2}% + {#3}% + {\AddToHook{class/after/#2}{#3}}}% + {\AddToHook{class/after/#2}{#3}}% + } +% \end{macrocode} +% +% \begin{macrocode} +\newcommand\AtBeginOfIncludeFile [2] + {\AddToHook{include/before/#1}{#2}} +\newcommand\AtEndOfIncludeFile [2] + {\AddToHook{include/end/#1}{#2}} +\newcommand\AfterIncludeFile [2] + {\AddToHook{include/after/#1}{#2}} +% \end{macrocode} +% +% +% This is missing some interfaces so disabling the package isn't +% really correct, but then this code above is not supposed to stay +% like this anyway. +% \begin{macrocode} +\expandafter\let\csname ver@filehook.sty\endcsname\fmtversion +\@namedef {ver@filehook.sty}{2020/10/01} +% \end{macrocode} +% +% +% \begin{macrocode} +%</filehook-draft> +% \end{macrocode} +% +% +% +% +% \subsection{Package \pkg{scrlfile} emulation} +% +% This is a partial implementation of the \pkg{scrlfile} +% interfaces. It is only meant for guidance in case that package +% gets updated to use the hook management. +% +% \begin{macrocode} +%<*scrlfile-draft> +% \end{macrocode} +% +% I think this is roughly correct (using the \texttt{file/...} +% hooks rather than the class or package hooks at least for the +% \cs{After...} commands but it needs some further verification. +% +% The star and plus variants haven't been implemented so far, this +% is only a rough draft. +% \begin{macrocode} +\newcommand\BeforeClass[2] + {\AddToHook{file/before/#1.cls}{#2}} +\newcommand\AfterClass [2] + {\AddToHook{file/after/#1.cls}{#2}} +\newcommand\AfterAtEndOfClass [2] + {\AddToHook{class/after/#1}{#2}} +% \end{macrocode} +% +% \begin{macrocode} +\newcommand\BeforePackage [2] + {\AddToHook{package/before/#1.sty}{#2}} +\newcommand\AfterPackage [2] + {\AddToHook{file/after/#1.sty}{#2}} +\newcommand\AfterEndOfPackage [2] + {\AddToHook{package/after/#1}{#2}} +% \end{macrocode} +% +% \begin{macrocode} +\newcommand\BeforeFile [2] + {% + \typeout{BeforeFile: #1!!!}% + \AddToHook{file/before/#1}{#2}} +\newcommand\AfterFile [2] + {% + \typeout{AfterFile: #1!!!}% + \AddToHook{file/after/#1}{#2}} +% \end{macrocode} +% +% This is missing some interfaces so disabling the package isn't +% really correct, but then this code above is not supposed to stay +% like this anyway. +% \begin{macrocode} +\expandafter\let\csname ver@scrlfile.sty\endcsname\fmtversion +\@namedef {ver@scrlfile.sty}{2020/10/01} +% \end{macrocode} +% +% \begin{macrocode} +%</scrlfile-draft> +% \end{macrocode} +% +% +% +% \section{A sample package for structuring the log output} +% +% \begin{macrocode} +%<*structuredlog> +%<@@=filehook> +% \end{macrocode} +% +% \begin{macrocode} +\ProvidesExplPackage + {structuredlog}{\ltfilehookdate}{\ltfilehookversion} + {Structuring the TeX transcript file} +% \end{macrocode} + + + +% \begin{macrocode} +\int_new:N \g_@@_nesting_level_int +% \end{macrocode} + +% \begin{macrocode} +\tl_new:N \g_@@_nesting_prefix_tl +\tl_gset:Nn \g_@@_nesting_prefix_tl { } +% \end{macrocode} +% +% \begin{macrocode} +\AddToHook{file/before}{ + \int_gincr:N \g_@@_nesting_level_int + \tl_gput_right:Nn\g_@@_nesting_prefix_tl {=} + \iow_term:x { + \g_@@_nesting_prefix_tl \space + ( LEVEL~ \int_use:N \g_@@_nesting_level_int \space START )~ + \CurrentFile ^^J + } +} +% \end{macrocode} +% We don't want to install the \hook{file/after} hook immediately, +% because that would mean it is the first time executed when the +% package finishes. We therefore put the declaration inside +% \cs{AddToHookNext} so that it gets only installed when we have +% left the package. +% \begin{macrocode} +\AddToHookNext{file/after}{ + \AddToHook{file/after}{ + \iow_term:x { + \g_@@_nesting_prefix_tl \space + ( LEVEL~ \int_use:N \g_@@_nesting_level_int \space STOP )~ + \CurrentFile ^^J + } + \int_gdecr:N \g_@@_nesting_level_int + \tl_gset:Nx \g_@@_nesting_prefix_tl + {\exp_after:wN \use_none:n \g_@@_nesting_prefix_tl} + } +} +% \end{macrocode} +% +% We have to manually increment the level because now that we have +% installed the code in \texttt{file/after} it gets decremented +% when we leave the package without ever being incremented upon +% entry. +% \begin{macrocode} +%\int_incr:N\g_@@_nesting_level_int +% \end{macrocode} +% +% \begin{macrocode} +%</structuredlog> +% \end{macrocode} + +% \Finale +% + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\endinput +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + diff --git a/Master/texmf-dist/source/latex-dev/base/ltfiles.dtx b/Master/texmf-dist/source/latex-dev/base/ltfiles.dtx index 8e9611d9180..60b6a23e5c2 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltfiles.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltfiles.dtx @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltfiles.dtx} - [2020-05-05 v1.2g LaTeX Kernel (File Handling)] + [2020-06-05 v1.2h LaTeX Kernel (File Handling)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltfiles.dtx} @@ -234,14 +234,18 @@ % \changes{v0.9e}{1993/12/09}{Hook added} % \begin{macrocode} %</2ekernel> -%<latexrelease>\IncludeInRelease{2017/04/15}% -%<latexrelease> {\document}{Save language for hyphenation}% +%<latexrelease>\IncludeInRelease{2020/06/05}% +%<latexrelease> {\document}{Added hook to load l3backend code}% %<*2ekernel|latexrelease> % \end{macrocode} % Cancel the |\begingroup| from |\begin|. % \begin{macrocode} \def\document{\endgroup % \end{macrocode} +% \changes{v1.2h}{2020/06/05}{Added hook to load \textsf{l3backend} code} +% \begin{macrocode} + \@expl@sys@load@backend@@ +% \end{macrocode} % If some options on |\documentclass| haven't been used by any % package we will now give a warning since this is most certainly a % misspelling. @@ -406,6 +410,64 @@ \ignorespaces} %</2ekernel|latexrelease> %<latexrelease>\EndIncludeInRelease +%<latexrelease> +%<latexrelease>\IncludeInRelease{2017/04/15}% +%<latexrelease> {\document}{Save language for hyphenation}% +%<latexrelease>\def\document{\endgroup +%<latexrelease> \ifx\@unusedoptionlist\@empty\else +%<latexrelease> \@latex@warning@no@line{Unused global option(s):^^J% +%<latexrelease> \@spaces[\@unusedoptionlist]}% +%<latexrelease> \fi +%<latexrelease> \@colht\textheight +%<latexrelease> \@colroom\textheight \vsize\textheight +%<latexrelease> \columnwidth\textwidth +%<latexrelease> \@clubpenalty\clubpenalty +%<latexrelease> \if@twocolumn +%<latexrelease> \advance\columnwidth -\columnsep +%<latexrelease> \divide\columnwidth\tw@ \hsize\columnwidth \@firstcolumntrue +%<latexrelease> \fi +%<latexrelease> \hsize\columnwidth \linewidth\hsize +%<latexrelease> \begingroup\@floatplacement\@dblfloatplacement +%<latexrelease> \makeatletter\let\@writefile\@gobbletwo +%<latexrelease> \global \let \@multiplelabels \relax +%<latexrelease> \@input{\jobname.aux}% +%<latexrelease> \endgroup +%<latexrelease> \if@filesw +%<latexrelease> \immediate\openout\@mainaux\jobname.aux +%<latexrelease> \immediate\write\@mainaux{\relax}% +%<latexrelease> \fi +%<latexrelease> \process@table +%<latexrelease> \let\glb@currsize\@empty % Force math initialization. +%<latexrelease> \normalsize +%<latexrelease> \everypar{}% +%<latexrelease> \ifx\normalsfcodes\@empty +%<latexrelease> \ifnum\sfcode`\.=\@m +%<latexrelease> \let\normalsfcodes\frenchspacing +%<latexrelease> \else +%<latexrelease> \let\normalsfcodes\nonfrenchspacing +%<latexrelease> \fi +%<latexrelease> \fi +%<latexrelease> \ifx\document@default@language\m@ne +%<latexrelease> \chardef\document@default@language\language +%<latexrelease> \fi +%<latexrelease> \@noskipsecfalse +%<latexrelease> \let \@refundefined \relax +%<latexrelease> \let\AtBeginDocument\@firstofone +%<latexrelease> \@begindocumenthook +%<latexrelease> \ifdim\topskip<1sp\global\topskip 1sp\relax\fi +%<latexrelease> \global\@maxdepth\maxdepth +%<latexrelease> \global\let\@begindocumenthook\@undefined +%<latexrelease> \ifx\@listfiles\@undefined +%<latexrelease> \global\let\@filelist\relax +%<latexrelease> \global\let\@addtofilelist\@gobble +%<latexrelease> \fi +%<latexrelease> \gdef\do##1{\global\let ##1\@notprerr}% +%<latexrelease> \@preamblecmds +%<latexrelease> \global\let \@nodocument \relax +%<latexrelease> \global\let\do\noexpand +%<latexrelease> \ignorespaces} +%<latexrelease>\EndIncludeInRelease +%<latexrelease> %<latexrelease>\IncludeInRelease{0000/00/00}% %<latexrelease> {\document}{Save language for hyphenation} %<latexrelease>\def\document{\endgroup diff --git a/Master/texmf-dist/source/latex-dev/base/ltfinal.dtx b/Master/texmf-dist/source/latex-dev/base/ltfinal.dtx index 56549507624..9089c8a7055 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltfinal.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltfinal.dtx @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltfinal.dtx} - [2019-10-02 v2.2 LaTeX Kernel (Final Settings)] + [2020-07-16 v2.2f LaTeX Kernel (Final Settings)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltfinal.dtx} @@ -460,6 +460,14 @@ \fi % \end{macrocode} % +% \changes{v2.2b}{2020/07/08} +% {Add a last-minute hook for \textsf{expl3}} +% At this stage, we can install any last-minute \textsf{expl3} set-up. +% \begin{macrocode} +\@expl@finalise@setup@@ +\def\@expl@finalise@setup@@{} +% \end{macrocode} +% % This is as good a place as any to active a few Xe\TeX{}-specific % settings % \begin{macrocode} @@ -1044,13 +1052,8 @@ % }{} % \end{macrocode} % -% \subsection{Loading further extensions} -% % \changes{v2.2}{2019-10-02}{Load \textsf{ltexpl}} -% Simply load further code: it's deliberately separate -% \begin{macrocode} -\input{ltexpl.ltx} -% \end{macrocode} +% \changes{v2.2a}{2020-06-04}{Load \textsf{ltexpl} in \texttt{ltdefns}} % % \subsection{Freeing Memory} % @@ -1124,14 +1127,6 @@ % \end{macro} % \end{macro} % -% \subsection{Some last minute initializations \ldots} -% -% This initializes the 2020/02/02 extensions to NFSS after any changes -% in the preamble. -% \begin{macrocode} -\AtBeginDocument{\reinstall@nfss@defs\init@series@setup} -% \end{macrocode} -% % % % \subsection{Do some temporary work for pre-release} @@ -1139,9 +1134,233 @@ % This is a good place to load code that hasn't yet been % integrated into the other files \ldots % \begin{macrocode} -%\input ... +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\ShowHook}{The hook management}% +\input lthooks.ltx +\input ltshipout.ltx +\input ltfilehook.ltx +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\ShowHook}{The hook management}% + +%<latexrelease> +%<latexrelease>\DeclareRobustCommand*\begin[1]{% +%<latexrelease> \@ifundefined{#1}% +%<latexrelease> {\def\reserved@a{\@latex@error{Environment #1 undefined}\@eha}}% +%<latexrelease> {\def\reserved@a{\def\@currenvir{#1}% +%<latexrelease> \edef\@currenvline{\on@line}% +%<latexrelease> \csname #1\endcsname}}% +%<latexrelease> \@ignorefalse +%<latexrelease> \begingroup\@endpefalse\reserved@a} +%<latexrelease> +%<latexrelease>\@namedef{end }#1{% +%<latexrelease> \csname end#1\endcsname\@checkend{#1}% +%<latexrelease> \expandafter\endgroup\if@endpe\@doendpe\fi +%<latexrelease> \if@ignore\@ignorefalse\ignorespaces\fi} +%<latexrelease> +%<latexrelease>\DeclareDocumentCommand \NewHook {m}{} +%<latexrelease>\DeclareDocumentCommand \NewReversedHook {m}{} +%<latexrelease>\DeclareDocumentCommand \NewMirroredHookPair {mm}{} +%<latexrelease> +%<latexrelease>\DeclareDocumentCommand \AddToHookNext {m+m}{} +%<latexrelease>\DeclareDocumentCommand \RemoveFromHook {mo}{} +%<latexrelease>\def \UseHook #1{} +%<latexrelease>\def \UseOneTimeHook #1{} +%<latexrelease>\def \ShowHook #1{} +%<latexrelease>\let \DebugHookOn \@empty +%<latexrelease>\let \DebugHookOff\@empty +%<latexrelease> +%<latexrelease>\DeclareDocumentCommand \DeclareHookRule {mmmm}{} +%<latexrelease>\DeclareDocumentCommand \DeclareDefaultHookRule {mmm}{} +%<latexrelease>\DeclareDocumentCommand \ClearHookRule {mmm}{} +% \end{macrocode} +% If the hook management is not provided we make the test for existence +% false and the test for empty true in the hope that this is most +% of the time reasonable. If not a package would need to guard +% against running in an old kernel. +% \begin{macrocode} +%<latexrelease>\DeclareExpandableDocumentCommand \IfHookExistTF {mmm}{#3} +%<latexrelease>\DeclareExpandableDocumentCommand \IfHookEmptyTF {mmm}{#2} +%<latexrelease> +%<latexrelease>\DeclareRobustCommand\AtBeginDocument{\g@addto@macro\@begindocumenthook} +%<latexrelease>\DeclareRobustCommand\AtEndDocument{\g@addto@macro\@enddocumenthook} +%<latexrelease> +%<latexrelease>\let\AtBeginEnvironment \@undefined +%<latexrelease>\let\AtEndEnvironment \@undefined +%<latexrelease>\let\BeforeBeginEnvironment \@undefined +%<latexrelease>\let\AfterEndEnvironment \@undefined +%<latexrelease> +%<latexrelease>\def\@pushfilename{% +%<latexrelease> \@expl@push@filename@@ +%<latexrelease> \xdef\@currnamestack{% +%<latexrelease> {\@currname}% +%<latexrelease> {\@currext}% +%<latexrelease> {\the\catcode`\@}% +%<latexrelease> \@currnamestack}% +%<latexrelease> \@expl@push@filename@aux@@} +%<latexrelease>\def\@popfilename{\expandafter\@p@pfilename\@currnamestack\@nil +%<latexrelease> \@expl@pop@filename@@} +%<latexrelease> +%<latexrelease> +%<latexrelease>% next goes away again when etoolbox is updated ... +%<latexrelease>\expandafter\let\csname ver@etoolbox.sty\endcsname\@undefined +%<latexrelease> +%<latexrelease>\def\document{\endgroup +%<latexrelease> \@expl@sys@load@backend@@ +%<latexrelease> \ifx\@unusedoptionlist\@empty\else +%<latexrelease> \@latex@warning@no@line{Unused global option(s):^^J% +%<latexrelease> \@spaces[\@unusedoptionlist]}% +%<latexrelease> \fi +%<latexrelease> \@colht\textheight +%<latexrelease> \@colroom\textheight \vsize\textheight +%<latexrelease> \columnwidth\textwidth +%<latexrelease> \@clubpenalty\clubpenalty +%<latexrelease> \if@twocolumn +%<latexrelease> \advance\columnwidth -\columnsep +%<latexrelease> \divide\columnwidth\tw@ \hsize\columnwidth \@firstcolumntrue +%<latexrelease> \fi +%<latexrelease> \hsize\columnwidth \linewidth\hsize +%<latexrelease> \begingroup\@floatplacement\@dblfloatplacement +%<latexrelease> \makeatletter\let\@writefile\@gobbletwo +%<latexrelease> \global \let \@multiplelabels \relax +%<latexrelease> \@input{\jobname.aux}% +%<latexrelease> \endgroup +%<latexrelease> \if@filesw +%<latexrelease> \immediate\openout\@mainaux\jobname.aux +%<latexrelease> \immediate\write\@mainaux{\relax}% +%<latexrelease> \fi +%<latexrelease> \process@table +%<latexrelease> \let\glb@currsize\@empty % Force math initialization. +%<latexrelease> \normalsize +%<latexrelease> \everypar{}% +%<latexrelease> \ifx\normalsfcodes\@empty +%<latexrelease> \ifnum\sfcode`\.=\@m +%<latexrelease> \let\normalsfcodes\frenchspacing +%<latexrelease> \else +%<latexrelease> \let\normalsfcodes\nonfrenchspacing +%<latexrelease> \fi +%<latexrelease> \fi +%<latexrelease> \ifx\document@default@language\m@ne +%<latexrelease> \chardef\document@default@language\language +%<latexrelease> \fi +%<latexrelease> \@noskipsecfalse +%<latexrelease> \let \@refundefined \relax +%<latexrelease> \let\AtBeginDocument\@firstofone +%<latexrelease> \@begindocumenthook +%<latexrelease> \ifdim\topskip<1sp\global\topskip 1sp\relax\fi +%<latexrelease> \global\@maxdepth\maxdepth +%<latexrelease> \global\let\@begindocumenthook\@undefined +%<latexrelease> \ifx\@listfiles\@undefined +%<latexrelease> \global\let\@filelist\relax +%<latexrelease> \global\let\@addtofilelist\@gobble +%<latexrelease> \fi +%<latexrelease> \gdef\do##1{\global\let ##1\@notprerr}% +%<latexrelease> \@preamblecmds +%<latexrelease> \global\let \@nodocument \relax +%<latexrelease> \global\let\do\noexpand +%<latexrelease> \ignorespaces} +%<latexrelease> +%<latexrelease>\def\enddocument{% +%<latexrelease> \let\AtEndDocument\@firstofone +%<latexrelease> \@enddocumenthook +%<latexrelease> \@checkend{document}% +%<latexrelease> \clearpage +%<latexrelease> \begingroup +%<latexrelease> \if@filesw +%<latexrelease> \immediate\closeout\@mainaux +%<latexrelease> \let\@setckpt\@gobbletwo +%<latexrelease> \let\@newl@bel\@testdef +%<latexrelease> \@tempswafalse +%<latexrelease> \makeatletter \@@input\jobname.aux +%<latexrelease> \fi +%<latexrelease> \@dofilelist +%<latexrelease> \ifdim \font@submax >\fontsubfuzz\relax +%<latexrelease> \@font@warning{Size substitutions with differences\MessageBreak +%<latexrelease> up to \font@submax\space have occurred.\@gobbletwo}% +%<latexrelease> \fi +%<latexrelease> \@defaultsubs +%<latexrelease> \@refundefined +%<latexrelease> \if@filesw +%<latexrelease> \ifx \@multiplelabels \relax +%<latexrelease> \if@tempswa +%<latexrelease> \@latex@warning@no@line{Label(s) may have changed. +%<latexrelease> Rerun to get cross-references right}% +%<latexrelease> \fi +%<latexrelease> \else +%<latexrelease> \@multiplelabels +%<latexrelease> \fi +%<latexrelease> \fi +%<latexrelease> \endgroup +%<latexrelease> \deadcycles\z@\@@end} +%<latexrelease> +%<latexrelease>\expandafter\let\csname ver@atveryend.sty\endcsname\@undefined +%<latexrelease>\let\AfterLastShipout \@undefined +%<latexrelease>\let\AtVeryEndDocument \@undefined +%<latexrelease>\let\AtEndAfterFileList \@undefined +%<latexrelease>\let\AtVeryVeryEnd \@undefined +%<latexrelease>\let\BeforeClearDocument \@undefined +%<latexrelease> +%<latexrelease> +%<latexrelease>\expandafter\let\expandafter\shipout\csname tex_shipout:D\endcsname +%<latexrelease> +%<latexrelease>\let \ShipoutBox\@undefined +%<latexrelease>\let \ReadonlyShipoutCounter \@undefined +%<latexrelease>\let \c@totalpages \@undefined +%<latexrelease>\let \thetotalpages \@undefined +%<latexrelease> +%<latexrelease>\let \DiscardShipoutBox \@undefined +%<latexrelease>\let \DebugShipoutOn \@undefined +%<latexrelease>\let \DebugShipoutOff \@undefined +%<latexrelease> +%<latexrelease>\DeclareRobustCommand \AtBeginDvi [1]{% +%<latexrelease> \global \setbox \@begindvibox +%<latexrelease> \vbox{\unvbox \@begindvibox #1}% +%<latexrelease>} +%<latexrelease> +%<latexrelease>\let \AtBeginShipout \@undefined +%<latexrelease>\let \AtBeginShipoutNext \@undefined +%<latexrelease> +%<latexrelease>\let \AtBeginShipoutFirst \@undefined +%<latexrelease> +%<latexrelease>\let \ShipoutBoxHeight \@undefined +%<latexrelease>\let \ShipoutBoxDepth \@undefined +%<latexrelease>\let \ShipoutBoxWidth \@undefined +%<latexrelease> +%<latexrelease>\let \AtBeginShipoutDiscard \@undefined +%<latexrelease> +%<latexrelease>\let \AtBeginShipoutAddToBox \@undefined +%<latexrelease>\let \AtBeginShipoutAddToBoxForeground \@undefined +%<latexrelease>\let \AtBeginShipoutUpperLeft \@undefined +%<latexrelease>\let \AtBeginShipoutUpperLeftForeground \@undefined +%<latexrelease> +%<latexrelease>\expandafter\let\csname ver@atbegshi.sty\endcsname \@undefined +%<latexrelease> +%<latexrelease>\let \EveryShipout \@undefined +%<latexrelease>\let \AtNextShipout \@undefined +%<latexrelease>\expandafter \let \csname ver@everyshi.sty\endcsname \@undefined +%<latexrelease> +%<latexrelease>\let \AtEndDvi \@undefined +%<latexrelease>\expandafter\let \csname ver@atenddvi.sty\endcsname \@undefined +%<latexrelease> +%<latexrelease>\AtBeginDocument{\reinstall@nfss@defs\init@series@setup} +%<latexrelease> +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% +% \subsection{Some last minute initializations \ldots} +% +% This initializes the 2020/02/02 extensions to NFSS after any changes +% in the preamble. +% \begin{macrocode} +\g@addto@macro\@kernel@after@env@document@begin + {\reinstall@nfss@defs\init@series@setup} % \end{macrocode} % +% % \subsection{Dumping the format} % Finally we make |@| into a letter, ensure the format will % be in the `normal' error mode, and dump everything into the diff --git a/Master/texmf-dist/source/latex-dev/base/lthooks.dtx b/Master/texmf-dist/source/latex-dev/base/lthooks.dtx new file mode 100644 index 00000000000..603b472e44a --- /dev/null +++ b/Master/texmf-dist/source/latex-dev/base/lthooks.dtx @@ -0,0 +1,3925 @@ +% \iffalse meta-comment +% +%% File: lthooks.dtx (C) Copyright 2020 Frank Mittelbach, LaTeX Team +% +% It may be distributed and/or modified under the conditions of the +% LaTeX Project Public License (LPPL), either version 1.3c of this +% license or (at your option) any later version. The latest version +% of this license is in the file +% +% https://www.latex-project.org/lppl.txt +% +% +% The development version of the bundle can be found below +% +% https://github.com/FrankMittelbach/... +% +% for those people who are interested or want to report an issue. +% +% \begin{macrocode} +\providecommand\lthooksversion{v0.9b} +\providecommand\lthooksdate{2020/07/19} +% \end{macrocode} +% +%<*driver> +\RequirePackage[debug]{lthooks} + +\documentclass{l3doc} + +% bug fix fo l3doc.cls +\ExplSyntaxOn +\cs_set_protected:Npn \__codedoc_macro_typeset_one:nN #1#2 + { + \vbox_set:Nn \l__codedoc_macro_box + { + \vbox_unpack_drop:N \l__codedoc_macro_box + \hbox { \llap { \__codedoc_print_macroname:nN {#1} #2 + \MacroFont % <----- without it the \ is in lmr10 if a link is made + \ + } } + } + \int_incr:N \l__codedoc_macro_int + } +\ExplSyntaxOff + +\EnableCrossrefs +\CodelineIndex +\begin{document} + \DocInput{lthooks.dtx} +\end{document} +%</driver> +% +% \fi +% +% +% \long\def\fmi#1{\begin{quote}\itshape FMi: #1\end{quote}} +% \long\def\pho#1{\begin{quote}\itshape PhO: #1\end{quote}} +% +% \newcommand\hook[1]{\texttt{#1}} +% +% +% \title{The \texttt{lthooks} package\thanks{This package has version +% \lthooksversion\ dated \lthooksdate, \copyright\ \LaTeX\ +% Project.}} +% +% \author{Frank Mittelbach\thanks{Code improvements for speed and other goodies by Phelype Oleinik}} +% +% \maketitle +% +% +% \tableofcontents +% +% \section{Introduction} +% +% Hooks are points in the code of commands or environments where it +% is possible to add processing code into existing commands. This +% can be done by different packages that do not know about each +% other and to allow for hopefully safe processing it is necessary +% to sort different chunks of code added by different packages into +% a suitable processing order. +% +% This is done by the packages adding chunks of code (via +% \cs{AddToHook}) and labeling their code with some label by +% default using the package name as a label. +% +% At \verb=\begin{document}= all code for a hook is then sorted +% according to some rules (given by \cs{DeclareHookRule}) for fast +% execution without processing overhead. If the hook code is +% modified afterwards (or the rules are changed), +% a new version for fast processing is generated. +% +% Some hooks are used already in the preamble of the document. If +% that happens then the hook is prepared for execution (and sorted) +% already at that point. +% +% +% \section{Package writer interface} +% +% The hook management system is offered as a set of CamelCase +% commands for traditional \LaTeXe{} packages (and for use in the +% document preamble if needed) as well as \texttt{expl3} commands +% for modern packages, that use the L3 programming layer of +% \LaTeX{}. Behind the scenes, a single set of data structures is +% accessed so that packages from both worlds can coexist and access +% hooks in other packages. +% +% +% +% \subsection{\LaTeXe\ interfaces} +% +% \subsubsection{Declaring hooks and using them in code} +% +% With two exceptions, hooks have to be declared before they can be +% used. The exceptions are hooks in environments (i.e., executed at +% \cs{begin} and \cs{end}) and hooks run when loading files, +% e.g. before and after a package is loaded, etc. Their hook names +% depend on the environment or the file name and so declaring them +% beforehand is difficult. +% +% +% \begin{function}{\NewHook} +% \begin{syntax} +% \cs{NewHook} \Arg{hook} +% \end{syntax} +% Creates a new \meta{hook}. +% If this is a hook provided as part of a package it is suggested +% that the \meta{hook} name is always structured as follows: +% \meta{package-name}\texttt{/}\meta{hook-name}. If necessary you +% can further subdivide the name by adding more \texttt{/} parts. +% If a hook name is already taken, an error is raised and the hook +% is not created. +% +% The \meta{hook} can be specified using the dot-syntax to denote +% the current package name. See section~\ref{sec:default-label}. +% \end{function} +% +% \begin{function}{\NewReversedHook} +% \begin{syntax} +% \cs{NewReversedHook} \Arg{hook} +% \end{syntax} +% Like \cs{NewHook} declares a new \meta{hook}. +% the difference is that the code chunks for this hook are in +% reverse order by default (those added last are executed first). +% Any rules for the hook are applied after the default ordering. +% See sections~\ref{sec:order} and \ref{sec:reversed-order} +% for further details. +% +% The \meta{hook} can be specified using the dot-syntax to denote +% the current package name. See section~\ref{sec:default-label}. +% \end{function} +% +% +% \begin{function}{\NewMirroredHookPair} +% \begin{syntax} +% \cs{NewMirroredHookPair} \Arg{hook-1} \Arg{hook-2} +% \end{syntax} +% A shorthand for +% \cs{NewHook}\Arg{hook-1}\cs{NewReversedHook}\Arg{hook-2}. +% +% The \meta{hooks} can be specified using the dot-syntax to denote +% the current package name. See section~\ref{sec:default-label}. +% \end{function} +% + + + +% \begin{function}{\UseHook} +% \begin{syntax} +% \cs{UseHook} \Arg{hook} +% \end{syntax} +% Execute the hook code inside a command or environment.\footnote{For +% legacy hooks such as \hook{begindocument} it is also +% possible to call \cs{@...hook}, e.g., \cs{@begindocumenthook}, +% but this syntax is discouraged.} +% +% Before \verb=\begin{document}= the fast execution code for a hook +% is not set up, so in order to use a hook there it is explicitly +% initialized first. As that involves assignments using a hook at +% those times is not 100\% the same as using it after +% \verb=\begin{document}=. +% +% The \meta{hook} \emph{cannot} be specified using the dot-syntax. +% A leading |.| is treated literally. +% \end{function} +% +% \begin{function}{\UseOneTimeHook} +% \begin{syntax} +% \cs{UseOneTimeHook} \Arg{hook} +% \end{syntax} +% Some hooks are only used (and can be only used) in one place, for +% example, those in \verb=\begin{document}= or +% \verb=\end{document}=. Once we have passed that point adding to +% the hook through a defined \cs{\meta{addto-cmd}} command (e.g., +% \cs{AddToHook} or \cs{AtBeginDocument}, etc.\@) would have no +% effect (as would the use of such a command inside the hook code +% itself). It is therefore customary to redefine +% \cs{\meta{addto-cmd}} to simply process its argument, i.e., +% essentially make it behave like \cs{@firstofone}. +% +% \cs{UseOneTimeHook} does that: it records that the hook has been +% consumed and any further attempt to add to it will result in +% executing the code to be added immediately. +% +% \fmi{Maybe add an error version as well?} +% +% The \meta{hook} \emph{cannot} be specified using the dot-syntax. +% A leading |.| is treated literally. +% \end{function} +% +% +% \subsubsection{Updating code for hooks} +% +% \begin{function}{\AddToHook} +% \begin{syntax} +% \cs{AddToHook} \Arg{hook}\oarg{label}\Arg{code} +% \end{syntax} +% Adds \meta{code} to the \meta{hook} labeled by \meta{label}. If +% the optional argument \meta{label} is not provided, if \cs{AddToHook} +% is used in a package/class, then the current +% package/class name is used, otherwise \hook{top-level} is +% used~(see section~\ref{sec:default-label}). +% +% If there already exists code under the \meta{label} then the new +% \meta{code} is appended to the existing one (even if this is a reversed hook). +% If you want to replace existing code under the +% \meta{label}, first apply \cs{RemoveFromHook}. +% +% The hook doesn't have to exist for code to be added to +% it. However, if it is not declared later then obviously the +% added \meta{code} will never be executed. This +% allows for hooks to work regardless of package loading order and +% enables packages to add to hook of other packages without +% worrying whether they are actually used in the current document. +% See section~\ref{sec:querying}. +% +% The \meta{hook} and \meta{label} can be specified using the +% dot-syntax to denote the current package name. +% See section~\ref{sec:default-label}. +% \end{function} +% +% \begin{function}{\RemoveFromHook} +% \begin{syntax} +% \cs{RemoveFromHook} \Arg{hook}\oarg{label} +% \end{syntax} +% Removes any code labeled by \meta{label} from the \meta{hook}. +% If the optional +% argument \meta{label} is not provided, if \cs{AddToHook} +% is used in a package/class, then the current +% package/class name is used, otherwise \hook{top-level} is used. +% +% If the optional argument is \texttt{*}, then all code chunks are +% removed. This is rather dangerous as it drops code from other +% packages one may not know about! +% +% The \meta{hook} and \meta{label} can be specified using the +% dot-syntax to denote the current package name. +% See section~\ref{sec:default-label}. +% \end{function} +% +% \medskip +% +% A useful application for this declaration inside the document body +% is when one wants to temporarily add code to hooks and later remove +% it again, e.g., +%\begin{verbatim} +% \AddToHook{env/quote/before}{\small} +% \begin{quote} +% A quote set in a smaller typeface +% \end{quote} +% ... +% \RemoveFromHook{env/quote/before} +% ... now back to normal for further quotes +%\end{verbatim} +% Note that you can't cancel the setting with +%\begin{verbatim} +% \AddToHook{env/quote/before}{} +%\end{verbatim} +% because that only \enquote{adds} a further empty chunk of code to +% the hook. Adding \cs{normalsize} would work but that means the hook +% then contained \cs{small}\cs{normalsize} which means to font size +% changes for no good reason. +% +% The above is only needed if one wants to typeset several quotes in a +% smaller typeface. If the hook is only needed once then +% \cs{AddToHookNext} is simpler, because it resets itself after one use. +% +% +% \begin{function}{\AddToHookNext} +% \begin{syntax} +% \cs{AddToHookNext} \Arg{hook}\Arg{code} +% \end{syntax} +% Adds \meta{code} to the next invocation of the \meta{hook}. +% The code is executed after the normal hook code has finished and +% it is executed only once, i.e. it is deleted after it was used. +% +% Using the declaration is a global operation, i.e., the code is +% not lost, even if the declaration is used inside a group and the +% next invocation happens after the group. If the declaration is +% used several times before the hook is executed then all code is +% executed in the order in which it was declared.\footnotemark +% +% The hook doesn't have to exist for code to be added to it. This +% allows for hooks to work regardless of package loading order. +% See section~\ref{sec:querying}. +% +% The \meta{hook} can be specified using the dot-syntax to denote +% the current package name. See section~\ref{sec:default-label}. +% \end{function}\footnotetext{There is +% no mechanism to reorder such code chunks (or delete them).} +% +% \subsubsection{Hook names and default labels} +% \label{sec:default-label} +% +% It is best practice to use \cs{AddToHook} in packages or classes +% \emph{without specifying a \meta{label}} because then the package +% or class name is automatically used, which is helpful if rules are +% needed, and avoids mistyping the \meta{label}. +% +% Using an explicit \meta{label} is only necessary in very specific +% situations, e.g., if you want to add several chunks of code into a +% single hook and have them placed in different parts of the hook +% (by providing some rules). +% +% The other case is when you develop a larger package with several +% sub-packages. In that case you may want to use the same +% \meta{label} throughout the sub-packages in order to avoid +% that the labels change if you internally reorganize your code. +% +% It is not enforced, but highly recommended that the hooks defined by +% a package, and the \meta{labels} used to add code to other hooks +% contain the package name to easily identify the source of the code +% chunk and to prevent clashes. This should be the standard practice, +% so this hook management code provides a shortcut to refer to the +% current package in the name of a \meta{hook} and in a \meta{label}. +% If \meta{hook} name or \meta{label} consist just of a single dot +% (|.|), or starts with a dot followed by a slash (|./|) then the dot +% denotes the \meta{default label} (usually the current package or class +% name---see~\cs{DeclareDefaultHookLabel}). +% A \enquote{|.|} or \enquote{|./|} anywhere else in a \meta{hook} or in +% \meta{label} is treated literally and is not replaced. + +% For example, +% inside the package \texttt{mypackage.sty}, the default label is +% \texttt{mypackage}, so the instructions: +% \begin{verbatim} +% \NewHook {./hook} +% \AddToHook {./hook}[.]{code} % Same as \AddToHook{./hook}{code} +% \AddToHook {./hook}[./sub]{code} +% \DeclareHookRule{begindocument}{.}{<}{babel} +% \AddToHook {file/after/foo.tex}{code} +% \end{verbatim} +% are equivalent to: +% \begin{verbatim} +% \NewHook {mypackage/hook}[mypackage]{code} +% \AddToHook {mypackage/hook}[mypackage]{code} +% \AddToHook {mypackage/hook}[mypackage/sub]{code} +% \DeclareHookRule{begindocument}{mypackage}{<}{babel} +% \AddToHook {file/after/foo.tex}{code} % unchanged +% \end{verbatim} +% +% The \meta{default label} is automatically set to the name of the +% current package or class (using \cs{@currname}). If \cs{@currname} +% is not set (because the hook command is used outside of a package, or +% the current file wasn't loaded with \cs{usepackage} or +% \cs{documentclass}), then the \texttt{top-level} is used as the +% \meta{default label}. +% +% This syntax is available in all \meta{label} arguments and most +% \meta{hook}, both in the \LaTeXe{} interface, and the \LaTeX3 +% interface described in section~\ref{sec:l3hook-interface}. +% +% Note, however, that the replacement of |.| by the \meta{default label} +% takes place when the hook command is executed, so actions that are +% somehow executed after the package ends will have the wrong +% \meta{default label} if the dot-syntax is used. For that reason, +% this syntax is not available in \cs{UseHook} (and \cs{hook_use:n}) +% because the hook is most of the time used outside of the package file +% in which it was defined. This syntax is also not available in the hook +% conditionals \cs{IfHookEmptyTF} (and \cs{hook_if_empty:nTF}) and +% \cs{IfHookExistTF} (and \cs{hook_if_exist:nTF}) because these +% conditionals are used in some performance-critical parts of the hook +% management code, and because they are usually used to refer to other +% package's hooks, so the dot-syntax doesn't make much sense. +% +% In some cases, for example in large packages, one may want to separate +% it in logical parts, but still use the main package name as +% \meta{label}, then the \meta{default label} can be set using +% \cs{DeclareDefaultHookLabel}: +% +% \begin{function}{\DeclareDefaultHookLabel} +% \begin{syntax} +% \cs{DeclareDefaultHookLabel} \Arg{default label} +% \end{syntax} +% Sets the \meta{default label} to be used in \meta{label} arguments. +% If \cs{DeclareDefaultHookLabel} is not used in the +% current package, \cs{@currname} is used instead. If \cs{@currname} +% is not set, the code is assumed to be in the main document, in which +% case \texttt{top-level} is used. +% +% The effect of \cs{DeclareDefaultHookLabel} holds for the current +% file, and is reset to the previous value when the file is closed. +% \end{function} +% +% +% \subsubsection{Defining relations between hook code} +% +% The default assumption is that code added to hooks by different +% packages is independent and the order in which it is executed is +% irrelevant. While this is true in many case it is obviously false +% in many others. +% +% Before the hook management system was introduced +% packages had to take elaborate precaution to determine of some other +% package got loaded as well (before or after) and find some ways to +% alter its behavior accordingly. In addition is was often the user's +% responsibility to load packages in the right order so that code +% added to hooks got added in the right order and some cases even +% altering the loading order wouldn't resolve the conflicts. +% +% With the new hook management system it is now possible to define +% rules (i.e., relationships) between code chunks added by different +% packages and explicitly describe in which order they should be +% processed. +% +% \begin{function}{\DeclareHookRule} +% \begin{syntax} +% \cs{DeclareHookRule} \Arg{hook}\Arg{label1}\Arg{relation}\Arg{label2} +% \end{syntax} +% Defines a relation between \meta{label1} and \meta{label2} for a +% given \meta{hook}. If \meta{hook} is \texttt{??} this defines a +% relation for all hooks that use the two labels, i.e., that have +% chunks of code labeled with \meta{label1} and \meta{label2}. +% Rules specific to a given hook take precedence over default +% rules that use \texttt{??} as the \meta{hook}. +% +% Currently, the supported relations are the following: +% \begin{itemize} +% +% \item[\texttt{before} or \texttt{\string<}] +% +% Code for \meta{label1} comes before code for \meta{label2}. +% +% \item[\texttt{after} or \texttt{\string>}] +% Code for \meta{label1} comes after code for \meta{label2}. +% +% \item[\texttt{incompatible-warning}] +% +% Only code for either \meta{label1} or \meta{label2} can appear +% for that hook (a way to say that two packages---or parts of +% them---are incompatible). A warning is raised if both labels +% appear in the same hook. +% +% \item[\texttt{incompatible-error}] +% +% Like \texttt{incompatible-error} but instead of a warning a +% \LaTeX{} error is raised, and the code for both labels are +% dropped from that hook until the conflict is resolved. +% +% \item[\texttt{removes}] +% +% Code for \meta{label1} overwrites code for \meta{label2}. More +% precisely, code for \meta{label2} is dropped for that +% hook. This can be used, for example if one package is a +% superset in functionality of another one and therefore wants to +% undo code in some hook and replace it with its own version. +% +% \item[\texttt{unrelated}] +% +% The order of code for \meta{label1} and \meta{label2} is +% irrelevant. This rule is there to undo an incorrect rule +% specified earlier. +% +% \end{itemize} +% +% The \meta{hook} and \meta{label} can be specified using the +% dot-syntax to denote the current package name. +% See section~\ref{sec:default-label}. +% \end{function} +% +% +% \begin{function}{\ClearHookRule} +% \begin{syntax} +% \cs{ClearHookRule}\Arg{hook}\Arg{label1}\Arg{label2} +% \end{syntax} +% Syntactic sugar for saying that \meta{label1} and \meta{label2} +% are unrelated for the given \meta{hook}. +% \end{function} +% +% +% +% \begin{function}{\DeclareDefaultHookRule} +% \begin{syntax} +% \cs{DeclareDefaultHookRule}\Arg{label1}\Arg{relation}\Arg{label2} +% \end{syntax} +% This sets up a relation between \meta{label1} and \meta{label2} +% for all hooks unless overwritten by a specific rule for a hook. +% Useful for cases where one package has a specific relation to +% some other package, e.g., is \texttt{incompatible} or always +% needs a special ordering \texttt{before} or \texttt{after}. +% (Technically it is just a shorthand for using \cs{DeclareHookRule} +% with \texttt{??} as the hook name.) +% +% Declaring default rules is only supported in the document +% preamble.\footnotemark{} +% +% The \meta{label} can be specified using the dot-syntax to denote +% the current package name. See section~\ref{sec:default-label}. +% \end{function}\footnotetext{Trying to do so, e.g., via +% \cs{DeclareHookRule} with \texttt{??} has bad side-effects and +% is not supported (though not explicitly caught for performance +% reasons).} +% +% +% +% \subsubsection{Querying hooks} +% \label{sec:querying} +% +% Simpler data types, like token lists, have three possible states; they +% can: +% \begin{itemize} +% \item exist and be empty; +% \item exist and be non-empty; and +% \item not exist (in which case emptiness doesn't apply); +% \end{itemize} +% Hooks are a bit more complicated: they have four possible states. +% A hook may exist or not, and either way it may or may not be empty. +% This means that even a hook that doesn't exist may be non-empty. +% +% This seemingly strange state may happen when, for example, package~$A$ +% defines hook \hook{A/foo}, and package $B$ adds some code to that +% hook. However, a document may load package $B$ before package $A$, or +% may not load package $A$ at all. In both cases some code is added to +% hook \hook{A/foo} without that hook being defined yet, thus that +% hook is said to be non-empty, whereas it doesn't exist. Therefore, +% querying the existence of a hook doesn't imply its emptiness, neither +% does the other way around. +% +% A hook is said to be empty when no code was added to it, either to +% its permanent code pool, or to its ``next'' token list. The hook +% doesn't need to be declared to have code added to its code pool. +% A hook is said to exist when it was declared with \cs{NewHook} or +% some variant thereof. +% +% \begin{function}[EXP]{\IfHookEmptyTF} +% \begin{syntax} +% \cs{IfHookEmptyTF} \Arg{hook} \Arg{true code} \Arg{false code} +% \end{syntax} +% Tests if the \meta{hook} is empty (\emph{i.e.}, no code was added to +% it using either \cs{AddToHook} or \cs{AddToHookNext}), and +% branches to either \meta{true code} or \meta{false code} depending +% on the result. +% +% The \meta{hook} \emph{cannot} be specified using the dot-syntax. +% A leading |.| is treated literally. +% \end{function} +% +% \begin{function}[EXP]{\IfHookExistTF} +% \begin{syntax} +% \cs{IfHookExistTF} \Arg{hook} \Arg{true code} \Arg{false code} +% \end{syntax} +% Tests if the \meta{hook} exists (if it was created with either +% \cs{NewHook}, \cs{NewReversedHook}, or \cs{NewMirroredHookPair}), and +% branches to either \meta{true code} or \meta{false code} depending +% on the result. +% +% The existence of a hook usually doesn't mean much from the viewpoint +% of code that tries to add/remove code from that hook, since package +% loading order may vary, thus the creation of hooks is asynchronous +% to adding and removing code from it, so this test should be used +% sparingly. +% +% The \meta{hook} \emph{cannot} be specified using the dot-syntax. +% A leading |.| is treated literally. +% \end{function} +% +% \fmi{Would be helpful if we provide some use cases} +% +% \subsubsection{Displaying hook code} +% +% If one has to adjust the code execution in a hook using a hook +% rule it is helpful to get some information about the code +% associated with a hook, its current order and the existing rules. +% +% \begin{function}{\ShowHook} +% \begin{syntax} +% \cs{ShowHook} \Arg{hook} +% \end{syntax} +% Displays information about the \meta{hook} such as +% \begin{itemize} +% \item +% the code chunks (and their labels) added to it, +% \item +% any rules set up to order them, +% \fmi{currently this is missing the default rules that apply, +% guess that needs fixing} +% \item +% the computed order (if already defined), +% \item +% any code executed on the next invocation only. +% \end{itemize} +% +% The \meta{hook} can be specified using the dot-syntax to denote +% the current package name. See section~\ref{sec:default-label}. +% \end{function} +% +% +% \subsubsection{Debugging hook code} +% +% \begin{function}{\DebugHookOn,\DebugHookOff} +% \begin{syntax} +% \cs{DebugHookOn} +% \end{syntax} +% Turn the debugging of hook code on or off. This displays changes +% made to the hook data structures. The output is rather coarse and +% not really intended for normal use. +% \end{function} +% +% +% \subsection{L3 programming layer (\texttt{expl3}) interfaces} +% \label{sec:l3hook-interface} +% +% +% This is a quick summary of the \LaTeX3 programming interfaces for +% use with packages written in \texttt{expl3}. In contrast to the +% \LaTeXe{} interfaces they always use mandatory arguments only, e.g., +% you always have to specify the \meta{label} for a code chunk. We +% therefore suggest to use the declarations discussed in the previous +% section even in \texttt{expl3} packages, but the choice is yours. +% +% +% \begin{function} +% {\hook_new:n,\hook_new_reversed:n,\hook_new_pair:nn} +% \begin{syntax} +% \cs{hook_new:n}\Arg{hook} +% \cs{hook_new_pair:nn}\Arg{hook-1}\Arg{hook-2} +% \end{syntax} +% Creates a new \meta{hook} with normal or reverse ordering of code +% chunks. \cs{hook_new_pair:nn} creates a pair of such hooks with +% \Arg{hook-2} being a reversed hook. +% If a hook name is already taken, an error is raised and the hook +% is not created. +% +% The \meta{hook} can be specified using the dot-syntax to denote +% the current package name. See section~\ref{sec:default-label}. +% \end{function} +% +% +% +% \begin{function}{\hook_use:n} +% \begin{syntax} +% \cs{hook_use:n} \Arg{hook} +% \end{syntax} +% Executes the \Arg{hook} code followed (if set up) by the code for next +% invocation only, then empties that next invocation code. +% +% The \meta{hook} \emph{cannot} be specified using the dot-syntax. +% A leading |.| is treated literally. +% \end{function} +% +% \begin{function}{\hook_use_once:n} +% \begin{syntax} +% \cs{hook_use_once:n} \Arg{hook} +% \end{syntax} +% Changes the \Arg{hook} status so that from now on any addition to +% the hook code is executed immediately. Then execute any +% \Arg{hook} code already set up. +% \fmi{better L3 name?} +% +% The \meta{hook} \emph{cannot} be specified using the dot-syntax. +% A leading |.| is treated literally. +% \end{function} +% +% \begin{function}{\hook_gput_code:nnn} +% \begin{syntax} +% \cs{hook_gput_code:nnn} \Arg{hook} \Arg{label} \Arg{code} +% \end{syntax} +% Adds a chunk of \meta{code} to the \meta{hook} labeled +% \meta{label}. If the label already exists the \meta{code} is +% appended to the already existing code. +% +% If code is added to an external \meta{hook} (of the kernel or +% another package) then the convention is to use the package name +% as the \meta{label} not some internal module name or some other +% arbitrary string. +% +% The \meta{hook} and \meta{label} can be specified using the +% dot-syntax to denote the current package name. +% See section~\ref{sec:default-label}. +% \end{function} +% +% \begin{function} +% {\hook_gput_next_code:nn} +% \begin{syntax} +% \cs{hook_gput_next_code:nn} \Arg{hook} \Arg{code} +% \end{syntax} +% Adds a chunk of \meta{code} for use only in the next invocation of the +% \meta{hook}. Once used it is gone. +% +% This is simpler than \cs{hook_gput_code:nnn}, the code is simply +% appended to the hook in the order of declaration at the very end, +% i.e., after all standard code for the hook got executed. +% +% Thus if one needs to undo what the standard does one has to do +% that as part of \meta{code}. +% +% The \meta{hook} can be specified using the dot-syntax to denote +% the current package name. See section~\ref{sec:default-label}. +% \end{function} +% + + +% \begin{function}{\hook_gremove_code:nn} +% \begin{syntax} +% \cs{hook_gremove_code:nn} \Arg{hook} \Arg{label} +% \end{syntax} +% Removes any code for \meta{hook} labeled \meta{label}. +% +% If the code for that \meta{label} wasn't yet added to the +% \meta{hook}, an order is set so that when some code attempts to add +% that label, the removal order takes action and the code is not +% added. +% +% If the second argument is \texttt{*}, then all code chunks are +% removed. This is rather dangerous as it drops code from other +% packages one may not know about, so think twice before using +% that! +% +% The \meta{hook} and \meta{label} can be specified using the +% dot-syntax to denote the current package name. +% See section~\ref{sec:default-label}. +% \end{function} + + +% \begin{function}{\hook_gset_rule:nnnn} +% \begin{syntax} +% \cs{hook_gset_rule:nnnn} \Arg{hook} \Arg{label1} \Arg{relation} \Arg{label2} +% \end{syntax} +% Relate \meta{label1} with \meta{label2} when used in \meta{hook}. +% See \cs{DeclareHookRule} for the allowed \meta{relation}s. +% If \meta{hook} is \texttt{??} a default rule is specified. +% +% The \meta{hook} and \meta{label} can be specified using the +% dot-syntax to denote the current package name. +% See section~\ref{sec:default-label}. +% The dot-syntax is parsed in both \meta{label} arguments, but it +% usually makes sense to be used in only one of them. +% \end{function} +% +% \begin{function}[pTF]{\hook_if_empty:n} +% \begin{syntax} +% \cs{hook_if_empty:n} \Arg{hook} \Arg{true code} \Arg{false code} +% \end{syntax} +% Tests if the \meta{hook} is empty (\emph{i.e.}, no code was added to +% it using either \cs{AddToHook} or \cs{AddToHookNext}), and +% branches to either \meta{true code} or \meta{false code} depending +% on the result. +% +% The \meta{hook} \emph{cannot} be specified using the dot-syntax. +% A leading |.| is treated literally. +% \end{function} +% +% \begin{function}[pTF]{\hook_if_exist:n} +% \begin{syntax} +% \cs{hook_if_exist:n} \Arg{hook} \Arg{true code} \Arg{false code} +% \end{syntax} +% Tests if the \meta{hook} exists (if it was created with either +% \cs{NewHook}, \cs{NewReversedHook}, or \cs{NewMirroredHookPair}), and +% branches to either \meta{true code} or \meta{false code} depending +% on the result. +% +% \fmi{what are the results for generic hooks that do not need to be declared?} +% +% The existence of a hook usually doesn't mean much from the viewpoint +% of code that tries to add/remove code from that hook, since package +% loading order may vary, thus the creation of hooks is asynchronous +% to adding and removing code from it, so this test should be used +% sparingly. +% +% The \meta{hook} \emph{cannot} be specified using the dot-syntax. +% A leading |.| is treated literally. +% \end{function} +% +% +% \begin{function}{\hook_debug_on:,\hook_debug_off:} +% \begin{syntax} +% \cs{hook_debug_on:} +% \end{syntax} +% Turns the debugging of hook code on or off. This displays changes +% to the hook data. +% \end{function} +% +% +% +% \subsection{On the order of hook code execution} \label{sec:order} +% +% Chunks of code for a \meta{hook} under different labels are supposed +% to be independent if there are no special rules set up that +% define a relation between the chunks. This means that you can't +% make assumptions about the order of execution! +% +% Suppose you have the following declarations: +%\begin{verbatim} +% \NewHook{myhook} +% \AddToHook{myhook}[packageA]{\typeout{A}} +% \AddToHook{myhook}[packageB]{\typeout{B}} +% \AddToHook{myhook}[packageC]{\typeout{C}} +%\end{verbatim} +% then executing the hook with \cs{UseHook} will produce the +% typeout \texttt{A} \texttt{B} \texttt{C} in that order. In other +% words, the execution order is computed to be \texttt{packageA}, +% \texttt{packageB}, \texttt{packageC} which you can verify with +% \cs{ShowHook}\texttt{\{myhook\}}: +%\begin{verbatim} +% The hook 'myhook': +% Code chunks: +% packageA -> \typeout {A} +% packageB -> \typeout {B} +% packageC -> \typeout {C} +% Extra code next invocation: +% --- +% Rules: +% --- +% Execution order: +% packageA, packageB, packageC +%\end{verbatim} +% The reason is that the code chunks are internally saved in a property list +% and the initial order of such a property list is the order in +% which key-value pairs got added. However, that is only true if +% nothing other than adding happens! +% +% Suppose, or example, you want to replace the code chunk for +% \texttt{packageA}, e.g., +%\begin{verbatim} +% \RemoveFromHook{myhook}[packageA] +% \AddToHook{myhook}[packageA]{\typeout{A alt}} +%\end{verbatim} +% then your order becomes \texttt{packageB}, +% \texttt{packageC}, \texttt{packageA} because the label got removed +% from the property list and then re-added (at its end). +% +% While that may not be too surprising, the execution order is +% also sometimes altered if you add a redundant rule, e.g. if you specify +%\begin{verbatim} +% \DeclareHookRule{myhook}{packageA}{before}{packageB} +%\end{verbatim} +% instead of the previous lines we get +%\begin{verbatim} +% The hook 'myhook': +% Code chunks: +% packageA -> \typeout {A} +% packageB -> \typeout {B} +% packageC -> \typeout {C} +% Extra code next invocation: +% --- +% Rules: +% packageA|packageB with relation before +% Execution order (after applying rules): +% packageA, packageC, packageB +%\end{verbatim} +% As you can see the code chunks are still in the same order, but +% in the execution order for the labels \texttt{packageB} and +% \texttt{packageC} have +% swapped places. +% The reason is that, with the rule there are two orders that +% satisfy it, and the algorithm for sorting happened to pick a +% different one compared to the case without rules (where it +% doesn't run at all as there is nothing to resolve). +% Incidentally, if we had instead specified the redundant rule +%\begin{verbatim} +% \DeclareHookRule{myhook}{packageB}{before}{label-3} +%\end{verbatim} +% the execution order would not have changed. +% +% In summary: it is not possible to rely on the order of execution +% unless there are rules that partially or fully define the order +% (in which you can rely on them being fulfilled). +% +% +% \subsection{The use of \enquote{reversed} hooks} \label{sec:reversed-order} +% +% You may have wondered why you can declare a \enquote{reversed} hook +% with \cs{NewReversedHook} and what that does exactly. +% +% In short: the execution order of a reversed hook (without any +% rules!) is exactly reversed to the order you would have gotten for +% a hook declared with \cs{NewHook}. +% +% This is helpful if you have a pair of hooks where you expect to see +% code added that involves grouping, e.g., starting an environment +% in the first and closing that environment in the second hook. +% To give a somewhat contrived example\footnote{there are simpler +% ways to achieve the same effect.}, suppose there is a package +% adding the following: +%\begin{verbatim} +% \AddToHook{env/quote/before}[package-1]{\begin{itshape}} +% \AddToHook{env/quote/after} [package-1]{\end{itshape}} +%\end{verbatim} +% As a result, all quotes will be in italics. +% Now suppose further that the user wants the quotes also in blue +% and therefore adds: +%\begin{verbatim} +% \usepackage{color} +% \AddToHook{env/quote/before}{\begin{color}{blue}} +% \AddToHook{env/quote/after} {\end{color}} +%\end{verbatim} +% Now if the \hook{env/quote/after} hook would be a normal hook we +% would get the same execution order in both hooks, namely: +%\begin{verbatim} +% package-1, top-level +%\end{verbatim} +% (or vice versa) and as a result, would get: +%\begin{verbatim} +% \begin{itshape}\begin{color}{blue} ... +% \end{itshape}\end{color} +%\end{verbatim} +% and an error message that \verb=\begin{color}= ended by +% \verb=\end{itshape}=. +% With \hook{env/quote/after} declared as a reversed hook the +% execution order is reversed and so all environments are closed in +% the correct sequence and \cs{ShowHook} would give us the +% following output: +%\begin{verbatim} +% The hook 'env/quote/after': +% Code chunks: +% package-1 -> \end {itshape} +% top-level -> \end {color} +% Extra code next invocation: +% --- +% Rules: +% --- +% Execution order (after reversal): +% top-level, package-1 +%\end{verbatim} +% +% The reversal of the execution order happens before applying any +% rules, so if you alter the order you will probably have to alter +% it in both hooks, not just in one, but that depends on the use case. +% +% +% +% +% \subsection{Private \LaTeX{} kernel hooks} +% +% There are a few places where it is absolutely essential for +% \LaTeX{} to function correctly that code is executed in a precisely +% defined order. Even that could have been implemented with the +% hook management (by adding various rules to ensure the +% appropriate ordering with respect to other code added by +% packages). However, this makes every document unnecessary +% slow, because there has to be sorting even through the result is +% predetermined. Furthermore it forces package writers to +% unnecessarily add such rules if they add further code to the hook +% (or break \LaTeX{}). +% +% For that reason such code is not using the hook management, but +% instead private kernel commands directly before or after a public +% hook with the following naming +% convention: \cs{@kernel@before@\meta{hookname}} or +% \cs{@kernel@after@\meta{hookname}}. For example, in +% \cs{enddocument} you find +%\begin{verbatim} +% \UseHook{enddocument}% +% \@kernel@after@enddocument +%\end{verbatim} +% which means first the user/package-accessible \hook{enddocument} +% hook is executed and then the internal kernel hook. As their name +% indicates these kernel commands should not be altered by third-party +% packages, so please refrain from that in the interest of +% stability and instead use the public hook next to it.\footnote{As +% with everything in \TeX{} there is not enforcement of this rule, +% and by looking at the code it is easy to find out how the kernel +% adds to them. The main reason of this section is therefore to say +% \enquote{please don't do that, this is unconfigurable code!}} +% +% +% +% \subsection{Legacy \LaTeXe{} interfaces} +% +% \LaTeXe{} offered a small number of hooks together with commands to +% add to them. They are listed here and are retained for backwards +% compatibility. +% +% With the new hook management several additional hooks have been added +% to \LaTeX\ and more will follow. See the next section for what +% is already available. +% +% +% \begin{function}{\AtBeginDocument} +% \begin{syntax} +% \cs{AtBeginDocument} \oarg{label} \Arg{code} +% \end{syntax} +% If used without the optional argument \meta{label}, it works essentially +% like before, i.e., it is adding \meta{code} to the hook +% \hook{begindocument} +% (which is executed inside \verb=\begin{document}=). +% However, all code added this way is labeled with the label +% \hook{top-level} if done outside of a package or class or with the +% package/class name if called inside such a file. +% +% This way one can add further code to the hook using +% \cs{AddToHook} or \cs{AtBeginDocument} using a different label +% and explicitly order the code chunks as necessary, e.g., run some +% code before or after the \hook{top-level} code. When using the +% optional argument the call is equivalent to running +% \cs{AddToHook} \texttt{\{begindocument\}} \oarg{label} +% \Arg{code}. +% +% For important packages with known order requirement we may over +% time add rules to the kernel (or to those packages) so that they +% work regardless of the loading-order in the document. +% \end{function} +% +% \begin{function}{\AtEndDocument} +% \begin{syntax} +% \cs{AtEndDocument} \oarg{label} \Arg{code} +% \end{syntax} +% Like \cs{AtBeginDocument} but for the \hook{enddocument} hook. +% \end{function} +% +% +% +% \begin{function}{\AtBeginDvi} +% \begin{syntax} +% \cs{AtBeginDvi} \oarg{label} \Arg{code} +% \end{syntax} +% This hook is discussed in conjunction with the shipout hooks. +% \end{function} +% +% +% +% \subsection{\LaTeXe{} commands and environments augmented by +% hooks} +% +% \emph{intro to be written} +% +% \subsubsection{Generic hooks for all environments} +% +% Every environment \meta{env} has now four associated hooks coming +% with it: +% \begin{description} +% \item[\hook{env/\meta{env}/before}] +% +% This hook is executed as part of \cs{begin} as the very first +% action, in particular prior to starting the environment group. +% Its scope is therefore not restricted by the environment. +% +% \item[\hook{env/\meta{env}/begin}] +% +% This hook is executed as part of \cs{begin} directly in front +% of the code specific to the environment start (e.g., the +% second argument of \cs{newenvironment}). Its scope is the +% environment body. +% +% \item[\hook{env/\meta{env}/end}] +% +% This is executed as part of \cs{end} directly in front of the +% code specific to the end of the environment (e.g., the third +% argument of \cs{newenvironment}). +% +% \item[\hook{env/\meta{env}/after}] +% +% This is executed as part of \cs{end} after the +% code specific to the environment end and after the environment +% group has ended. +% Its scope is therefore not restricted by the environment. +% +% This hook is implemented as a reversed hook so if two packages +% add code to \hook{env/\meta{env}/before} and to +% \hook{env/\meta{env}/after} they can add surrounding +% environments and the order of closing them happens in the +% right sequence. +% +% \end{description} +% In contrast to other hooks these hooks do not need to be declared +% using \cs{NewHook}. +% +% The hooks are only executed if \cs{begin}\Arg{env} and +% \cs{end}\Arg{env} is used. If the environment code is executed +% via low-level calls to \cs{\meta{env}} and \cs{end\meta{env}} +% (e.g., to avoid the environment grouping) they are not +% available. If you want them available in code using this method, +% you would need to add them yourself, i.e., write something like +%\begin{verbatim} +% \UseHook{env/quote/before}\quote +% ... +% \endquote\UseHook{env/quote/after} +%\end{verbatim} +% to add the outer hooks, etc. +% +% +% +% \subsubsection{Hooks provided by \cs{begin}\texttt{\{document\}}} +% +% Until 2020 \cs{begin}\texttt{\{document\}} offered exactly one +% hook that one had to fill using \cs{AtBeginDocument}. Experience +% has shown that this single hook in one place was not enough and +% as part of adding the general hook management system a number of +% additional hooks have been added at this point. The places for +% hooks have been chosen to provide the same support as offered by +% external packages, such as \pkg{etoolbox} and others that +% augmented \cs{document} to gain better control. +% +% Supported are now the following hooks: +% \begin{description} +% +% \item[\hook{env/document/before}] +% +% This is the generic environment hook executed effectively +% before \verb=\begin{document}= starts, i.e., one can think of +% it as a hook for code at the end of the preamble section. +% +% \item[\hook{env/document/begin}] +% +% This is the second generic environment hook that is executed +% after the environment has started its group. But given that for the +% \texttt{document} environment this group is canceled there is +% little difference to the previous one as the two are directly +% executed one after another (the only difference is that in this +% hook \cs{@currenvir} is now set to \texttt{document} but +% anybody adding to this hook would know that already). +% +% +% \item[\hook{begindocument}] +% +% This hook is added to by \cs{AtBeginDocument} and is executed +% after the \texttt{.aux} file as be read in and most +% initialization are done, so they can be altered and inspected by +% the hook code. It is followed by a small number of further +% initializations that shouldn't be altered and are therefore +% coming later. +% +% \item[\hook{begindocument/end}] +% +% This hook is executed at the end of the \cs{document} code in +% other words at the beginning of the document body. The only +% command that follows it is \cs{ignorespaces}. +% +% \end{description} +% +% +% +% +% \subsubsection{Hooks provided by \cs{end}\texttt{\{document\}}} +% +% \LaTeXe{} always provided \cs{AtEndDocument} to add code to the +% execution of \verb=\end{document}= just in front of the code that +% is normally executed there. While this was a big improvement over +% the situation in \LaTeX\,2.09 it was not flexible enough for a +% number of use cases and so packages, such as \pkg{etoolbox}, +% \pkg{atveryend} and others patched \cs{enddocument} to add +% additional points where code could be hooked into. +% +% Patching using packages is always problematical as leads to +% conflicts (code availability, ordering of patches, incompatible +% patches, etc.). For this reason a number of additional hooks +% have been added to the \cs{enddocument} code to allow packages +% to add code in various places in a controlled way without the +% need for overwriting or patching the core code. +% +% Supported are now the following hooks: +% \begin{description} +% +% \item[\hook{env/document/end}] The generic hook inside \cs{end}. +% +% \item[\hook{enddocument}] + +% The hook associated with \cs{AtEndDocument}. It is immediately +% called after the previous hook so there could be just +% one.\footnote{We could make \cs{AtEndDocument} just fill the +% \hook{env/document/end} but maybe that is a bit confusing.} +% +% When this hook is executed there may be still unprocessed +% material (e.g., floats on the deferlist) and the hook may add +% further material to be typeset. After it, \cs{clearpage} is +% called to ensure that all such material gets typeset. If there +% is nothing waiting the \cs{clearpage} has no effect. +% +% +% \item[\hook{enddocument/afterlastpage}] +% +% As the name indicates this hook should not receive code that +% generates material for further pages. It is the right place to +% do some final housekeeping and possibly write out some +% information to the \texttt{.aux} file (which is still open at +% this point to receive data). It is also the correct place to +% set up any testing code to be run when the \texttt{.aux} file +% is re-read in the next step. +% +% +% After this hook has been executed the \texttt{.aux} file is +% closed for writing and then read back in to do some tests +% (e.g., looking for missing references or duplicated labels, etc.). +% +% \item[\hook{enddocument/afteraux}] +% +% At this point, the \texttt{.aux} file has been reprocessed and so +% this is a possible place for final checks and display of +% information to the user. However, for the latter you might +% prefer the next hook, so that your information is displayed after the +% (possibly longish) list of files if that got requested via \cs{listfiles}. +% +% \item[\hook{enddocument/info}] +% +% This hook is meant to receive code that write final information +% messages to the terminal. It follows immediately after the +% previous hook (so both could have been combined, but then +% packages adding further code would always need to also supply +% an explicit rule to specify where it should go. +% +% This hook already contains some code added by the kernel (under +% the labels \texttt{kernel/filelist} and +% \texttt{kernel/warnings}), namely the list of files when +% \cs{listfiles} has been used and the warnings for duplicate +% labels, missing references, font substitutions etc. +% +% \item[\hook{enddocument/end}] +% +% Finally, this hook is executed just in front of the final call +% to \cs{@{}@end}. +% +% \end{description} +% +% +% There is also the hook \hook{shipout/lastpage}. This hook is +% executed as part of the last \cs{shipout} in the document to +% allow package to add final \cs{special}'s to that page. Where +% this hook is executed in relation to those from the above list +% can vary from document to document. Furthermore to determine correctly +% which of the \cs{shipout}s is the last one, \LaTeX{} needs to be run +% several times, so initially it might get executed on the wrong +% page. See section~\ref{sec:shipout} for where to find the details. +% +% +% \subsubsection{Hooks provided \cs{shipout} operations} +% \label{sec:shipout} +% +% There are several hooks and mechanisms added to \LaTeX{}'s +% process of generating pages. These are documented in +% \texttt{ltshipout-doc.pdf} or with code in +% \texttt{ltshipout-code.pdf}. +% +% +% \subsubsection{Hooks provided file loading operations} +% +% There are several hooks added to \LaTeX{}'s +% process of loading file via its high-level interfaces such as +% \cs{input}, \cs{include}, \cs{usepackage}, etc. These are documented in +% \texttt{ltfilehook-doc.pdf} or with code in +% \texttt{ltfilehook-code.pdf}. +% +% + +% \StopEventually{\setlength\IndexMin{200pt} \PrintIndex } +% +% +% \section{The Implementation} +% \begin{macrocode} +%<@@=hook> +% \end{macrocode} +% +% \begin{macrocode} +%<*2ekernel> +% \end{macrocode} +% +% \begin{macrocode} +\ExplSyntaxOn +% \end{macrocode} +% +% +% \subsection{Debugging} +% +% \begin{macro}{\g_@@_debug_bool} +% Holds the current debugging state. +% \begin{macrocode} +\bool_new:N \g_@@_debug_bool +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hook_debug_on:,\hook_debug_off:} +% \begin{macro}{\@@_debug:n} +% \begin{macro}{\@@_debug_gset:} +% Turns debugging on and off by redefining \cs{@@_debug:n}. +% \begin{macrocode} +\cs_new_eq:NN \@@_debug:n \use_none:n +\cs_new_protected:Npn \hook_debug_on: + { + \bool_gset_true:N \g_@@_debug_bool + \@@_debug_gset: + } +\cs_new_protected:Npn \hook_debug_off: + { + \bool_gset_false:N \g_@@_debug_bool + \@@_debug_gset: + } +\cs_new_protected:Npn \@@_debug_gset: + { + \cs_gset_protected:Npx \@@_debug:n ##1 + { \bool_if:NT \g_@@_debug_bool {##1} } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} + +% +% +% \subsection{Borrowing from internals of other kernel modules} +% +% +% \begin{macro}[EXP]{\@@_str_compare:nn} +% Private copy of \cs{__str_if_eq:nn} +% \begin{macrocode} +\cs_new_eq:NN \@@_str_compare:nn \__str_if_eq:nn +% \end{macrocode} +% \end{macro} +% +% \subsection{Declarations} +% +% \begin{macro}{\l_@@_return_tl,\l_@@_tmpa_tl,\l_@@_tmpb_tl} +% Scratch variables used throughout the package. +% \begin{macrocode} +\tl_new:N \l_@@_return_tl +\tl_new:N \l_@@_tmpa_tl +\tl_new:N \l_@@_tmpb_tl +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g_@@_all_seq} +% In a few places we need a list of all hook names ever defined so +% we keep track if them in this sequence. +% \begin{macrocode} +\seq_new:N \g_@@_all_seq +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g_@@_removal_list_prop} +% A property list to hold delayed removals. +% \begin{macrocode} +\tl_new:N \g_@@_removal_list_tl +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\l_@@_cur_hook_tl} +% Stores the name of the hook currently being sorted. +% \begin{macrocode} +\tl_new:N \l_@@_cur_hook_tl +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g_@@_code_temp_prop} +% A property list to temporarily save the original one so that it +% isn't permanently changed during sorting. +% \begin{macrocode} +\prop_new:N \g_@@_code_temp_prop +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g_@@_hook_curr_name_tl,\g_@@_name_stack_seq} +% Default label used for hook commands, and a stack to keep track of +% packages within packages. +% \begin{macrocode} +\tl_new:N \g_@@_hook_curr_name_tl +\seq_new:N \g_@@_name_stack_seq +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_tmp:w} +% Temporary macro for generic usage. +% \begin{macrocode} +\cs_new_eq:NN \@@_tmp:w ? +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tl_gremove_once:Nx} +% Some variants of \pkg{expl3} functions. \fmi{should be moved to expl3} +% \begin{macrocode} +\cs_generate_variant:Nn \tl_gremove_once:Nn { Nx } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\s_@@_mark} +% Scan mark used for delimited arguments. +% \begin{macrocode} +\scan_new:N \s_@@_mark +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Providing new hooks} +% +% \begin{macro}{\g_@@_..._code_prop,\g_@@_..._rules_prop, +% \g_@@_..._code_tl,\g_@@_..._next_code_tl} +% +% Hooks have a \meta{name} and for each hook we have to provide a number of +% data structures. These are +% \begin{description} +% \item[\cs{g_@@_\meta{name}_code_prop}] A property list holding the code +% for the hook in separate chunks. The keys are by default the +% package names that add code to the hook, but it is possible +% for packages to define other keys. +% +% \item[\cs{g_@@_\meta{name}_rules_prop}] A property listing holding +% relation info how the code chunks should be ordered within a +% hook. This is used for debugging only. The actual rule for a +% \meta{hook} is stored in a separate token lists named +% \cs[no-index]{g_@@_\meta{hook}_rule_\meta{label1}\string|\meta{label2}_tl} +% for a pair of labels. +% +% \item[\cs{g_@@_\meta{name}_code_tl}] The code that is actually executed +% when the hook is called in the document is stored in this token +% list. It is constructed from the code chunks applying the +% information. +% +% \item[\cs{g_@@_\meta{name}_next_code_tl}] Finally there is extra code +% (normally empty) that is used on the next invocation of the hook +% (and then deleted). This can be used to define some special +% behavior for a single occasion from within the document. +% +% \end{description} +% \end{macro} + + +% +% +% \begin{macro}{\hook_new:n} +% The \cs{hook_new:n} declaration declare a new hook and expects +% the hook \meta{name} as its argument, e.g., +% \hook{begindocument}. +% \begin{macrocode} +\cs_new_protected:Npn \hook_new:n #1 + { + \exp_args:Nx \@@_new:n + { \@@_parse_label_default:nn {#1} { top-level } } + } +\cs_new_protected:Npn \@@_new:n #1 { +% \end{macrocode} +% We check for one of the internal data structures and if it +% already exists we complain. +% \begin{macrocode} + \hook_if_exist:nTF {#1} + { \ErrorHookExists } +% \end{macrocode} +% Otherwise we add the hook name to the list of all hooks and +% allocate the necessary data structures for the new hook. +% \begin{macrocode} + { \seq_gput_right:Nn \g_@@_all_seq {#1} +% \end{macrocode} +% This is only used by the actual code of the current hook, so +% declare it normally: +% \begin{macrocode} + \tl_new:c { g_@@_#1_code_tl } +% \end{macrocode} +% Now ensure that the base data structure for the hook exists: +% \begin{macrocode} + \@@_declare:n {#1} +% \end{macrocode} +% The \cs{g_@@_\meta{hook}_labels_clist} holds the sorted list of +% labels (once it got sorted). This is used only for debugging. +% \begin{macrocode} + \clist_new:c {g_@@_#1_labels_clist} +% \end{macrocode} +% Some hooks should reverse the default order of code chunks. To +% signal this we have a token list which is empty for normal hooks +% and contains a \verb=-= for reversed hooks. +% \begin{macrocode} + \tl_new:c { g_@@_#1_reversed_tl } +% \end{macrocode} +% The above is all in L3 convention, but we also provide an +% interface to legacy \LaTeXe{} for use in the current kernel. This +% is done in a separate macro. +% \begin{macrocode} + \@@_provide_legacy_interface:n {#1} + } +} +% \end{macrocode} +% \end{macro} + +% +% +% \begin{macro}{\@@_declare:n} +% This function declares the basic data structures for a hook without +% actually declaring the hook itself. This is needed to allow adding +% to undeclared hooks. Here it is unnecessary to check whether both +% variables exist, since both are declared at the same time (either +% both exist, or neither). +% \begin{macrocode} +\cs_new_protected:Npn \@@_declare:n #1 + { + \@@_if_exist:nF {#1} + { + \prop_new:c { g_@@_#1_code_prop } + \tl_new:c { g_@@_#1_next_code_tl } + \prop_new:c { g_@@_#1_rules_prop } % only for debugging + } + } +% \end{macrocode} +% \end{macro} + + + +% \begin{macro}{\hook_new_reversed:n} +% +% Declare a new hook. The default ordering of code chunks is +% reversed, signaled by setting the token list to a minus sign. +% \begin{macrocode} +\cs_new_protected:Npn \hook_new_reversed:n #1 { + \hook_new:n {#1} + \tl_gset:cn { g_@@_#1_reversed_tl } { - } +} +% \end{macrocode} +% \end{macro} + +% \begin{macro}{\hook_new_pair:nn} +% A shorthand for declaring a normal and a (matching) reversed hook in one go. +% \begin{macrocode} +\cs_new_protected:Npn \hook_new_pair:nn #1#2 { + \hook_new:n {#1} \hook_new_reversed:n {#2} +} +% \end{macrocode} +% \end{macro} + + +% \begin{macro}{\@@_provide_legacy_interface:n} +% The \LaTeX{} legacy concept for hooks uses with hooks the +% following naming scheme in the code: \cs{@...hook}. +% +% We follow this convention and insert the hook code using this +% naming scheme in \LaTeXe{}. At least as long as this code is in a +% package, some such hooks are already filled with data when we move +% them over to the new scheme. We therefore insert already existing +% code under the label \texttt{legacy} into the hook management +% machinery and then replace the \cs{@...hook} with its counterpart +% which is \cs{g_@@_\#1_code_tl}.\footnote{This means one extra +% unnecessary expansion on each invocation in the document but +% keeps the \LaTeXe{} and the L3 coding side properly separated.} +% \begin{macrocode} +\cs_new_protected:Npn \@@_provide_legacy_interface:n #1 + { +% \end{macrocode} +% If the \pkg{expl3} code is run with checking on then assigning or +% using non L3 names such as \cs{@enddocumenthook} with \pkg{expl3} +% functions will trigger warnings so we run this code with +% debugging explicitly suspended. +% \begin{macrocode} + \debug_suspend: + \tl_if_exist:cT { @#1hook } +% \end{macrocode} +% Of course if the hook exists but is still empty, there is no need +% to add anything under \texttt{legacy} or the current package name. +% \begin{macrocode} + { + \tl_if_empty:cF { @#1hook } + { + \@@_gput_code:nxv {#1} + { \@@_parse_label_default:Vn \c_novalue_tl { legacy } } + { @#1hook } + } + } +% \end{macrocode} +% We need a global definition in case the declaration is done +% inside a group (which happens below at the end of the file). +% This is another reason why need to suspend checking, otherwise +% \cs{tl_gset:co} would complain about \cs{@...hook} not starting +% with \cs{g_}. +% \begin{macrocode} + \tl_gset:co{@#1hook}{\cs:w g_@@_#1_code_tl\cs_end:} + \debug_resume: + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Parsing a label} +% +% \begin{macro}[EXP]{\@@_parse_label_default:nn,\@@_parse_label_default:Vn} +% This macro checks if a label was given (not \cs{c_novalue_tl}), and +% if so, tries to parse the label looking for a leading \verb|.| to +% replace for \cs{@currname}. Otherwise \cs{@@_currname_or_default:n} +% is used to pick \cs{@currname} or the fallback value. +% \begin{macrocode} +\cs_new:Npn \@@_parse_label_default:nn #1 #2 + { + \tl_if_novalue:nTF {#1} + { \@@_currname_or_default:n {#2} } + { \tl_trim_spaces_apply:nN {#1} \@@_parse_dot_label:nn {#2} } + } +\cs_generate_variant:Nn \@@_parse_label_default:nn { V } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[EXP]{\@@_parse_dot_label:nn} +% \begin{macro}[EXP]{ +% \@@_parse_dot_label:nw, +% \@@_parse_dot_label_cleanup:w, +% \@@_parse_dot_label_aux:nw +% } +% Start by checking if the label is empty, which raises an error, and +% uses the fallback value. If not, +% split the label at a \verb|./|, if any, and check if no tokens are +% before the \verb|./|, or if the only character is a \verb|.|. +% If these requirements are fulfilled, the leading +% \verb|.| is replaced with \cs{@@_currname_or_default:n}. Otherwise +% the label is returned unchanged. +% \begin{macrocode} +\cs_new:Npn \@@_parse_dot_label:nn #1 #2 + { + \tl_if_empty:nTF {#1} + { + \msg_expandable_error:nnn { hooks } { empty-label } {#2} + #2 + } + { + \str_if_eq:nnTF {#1} { . } + { \@@_currname_or_default:n {#1} } + { \@@_parse_dot_label:nw {#2} #1 ./ \s_@@_mark } + } + } +\cs_new:Npn \@@_parse_dot_label:nw #1 #2 ./ #3 \s_@@_mark + { + \tl_if_empty:nTF {#2} + { \@@_parse_dot_label_aux:nw {#1} #3 \s_@@_mark } + { + \tl_if_empty:nTF {#3} + {#2} + { \@@_parse_dot_label_cleanup:w #2 ./ #3 \s_@@_mark } + } + } +\cs_new:Npn \@@_parse_dot_label_cleanup:w #1 ./ \s_@@_mark {#1} +\cs_new:Npn \@@_parse_dot_label_aux:nw #1 #2 ./ \s_@@_mark + { \@@_currname_or_default:n {#1} / #2 } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[EXP]{\@@_currname_or_default:n} +% Uses \cs{g_@@_hook_curr_name_tl} if it is set, otherwise tries +% \cs{@currname}. If neither is set, uses the fallback value +% \verb|#1| (usually \texttt{top-level}). +% \begin{macrocode} +\cs_new:Npn \@@_currname_or_default:n #1 + { + \tl_if_empty:NTF \g_@@_hook_curr_name_tl + { + \tl_if_empty:NTF \@currname + {#1} + { \@currname } + } + { \g_@@_hook_curr_name_tl } + } +% \end{macrocode} +% \end{macro} + + + + +% \begin{macro}{\hook_gput_code:nnn} +% \begin{macro}{\@@_gput_code:nnn,\@@_gput_code:nxv,\@@_hook_gput_code_do:nnn} +% +% With \cs{hook_gput_code:nnn}\Arg{hook}\Arg{label}\Arg{code} a +% chunk of \meta{code} is added to an existing \meta{hook} labeled +% with \meta{label}. +% \begin{macrocode} +\cs_new_protected:Npn \hook_gput_code:nnn #1 #2 + { + \exp_args:Nxx \@@_gput_code:nnn + { \@@_parse_label_default:nn {#1} { top-level } } + { \@@_parse_label_default:nn {#2} { top-level } } + } +\cs_new_protected:Npn \@@_gput_code:nnn #1 #2 #3 + { +% \end{macrocode} +% First we check if the hook exists. +% \begin{macrocode} + \@@_if_marked_removal:nnTF {#1} {#2} + { \@@_unmark_removal:nn {#1} {#2} } + { +% \end{macrocode} +% First we check if the hook exists. +% \begin{macrocode} + \hook_if_exist:nTF {#1} +% \end{macrocode} +% If so we simply add (or append) the new code to the property list +% holding different chunks for the hook. At \verb=\begin{document}= +% this is then sorted into a token list for fast execution. +% \begin{macrocode} + { + \@@_hook_gput_code_do:nnn {#1} {#2} {#3} +% \end{macrocode} +% However, if there is an update within the document we need to alter +% this execution code which is done by +% \cs{@@_update_hook_code:n}. In the preamble this does nothing. +% \begin{macrocode} + \@@_update_hook_code:n {#1} + } +% \end{macrocode} +% +% \begin{macrocode} + { \@@_try_declaring_generic_hook:nnn {#1} {#2} {#3} } + } + } +\cs_generate_variant:Nn \@@_gput_code:nnn { nxv } +% \end{macrocode} +% +% This macro will unconditionally add a chunk of code to the given hook. +% \begin{macrocode} +\cs_new_protected:Npn \@@_hook_gput_code_do:nnn #1 #2 #3 + { +% However, first some debugging info if debugging is enabled: +% \begin{macrocode} + \@@_debug:n{\iow_term:x{****~ Add~ to~ + \hook_if_exist:nF {#1} { undeclared~ } + hook~ #1~ (#2) + \on@line\space <-~ \tl_to_str:n{#3}} } +% \end{macrocode} +% Then try to get the code chunk labeled \verb=#2= from the hook. +% If there's code already there, then append \verb=#3= to that, +% otherwise just put \verb=#3=. +% \begin{macrocode} + \prop_get:cnNTF { g_@@_#1_code_prop } {#2} \l_@@_return_tl + { + \prop_gput:cno { g_@@_#1_code_prop } {#2} + { \l_@@_return_tl #3 } + } + { \prop_gput:cnn { g_@@_#1_code_prop } {#2} {#3} } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_gput_undeclared_hook:nnn} +% Often it may happen that a package $A$ defines a hook \verb=foo=, +% but package $B$, that adds code to that hook, is loaded before $A$. +% In such case we need to add code to the hook before its declared. +% \begin{macrocode} +\cs_new_protected:Npn \@@_gput_undeclared_hook:nnn #1 #2 #3 + { + \@@_declare:n {#1} + \@@_hook_gput_code_do:nnn {#1} {#2} {#3} + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_try_declaring_generic_hook:nnn} +% \begin{macro}{\@@_try_declaring_generic_next_hook:nn} +% These entry-level macros just pass the arguments along to the +% common \cs{@@_try_declaring_generic_hook:nNNnn} with the right +% functions to execute when some action is to be taken. +% +% The wrapper \cs{@@_try_declaring_generic_hook:nnn} then defers +% \cs{hook_gput_code:nnn} if the generic hook was declared, or to +% \cs{@@_gput_undeclared_hook:nnn} otherwise (the hook was tested for +% existence before, so at this point if it isn't generic, it doesn't +% exist). +% +% The wrapper \cs{@@_try_declaring_generic_next_hook:nn} for +% next-execution hooks does the same: it defers the code to +% \cs{hook_gput_next_code:nn} if the generic hook was declared, or +% to \cs{@@_gput_next_do:nn} otherwise. +% \begin{macrocode} +\cs_new_protected:Npn \@@_try_declaring_generic_hook:nnn #1 + { + \@@_try_declaring_generic_hook:nNNnn {#1} + \hook_gput_code:nnn \@@_gput_undeclared_hook:nnn + } +\cs_new_protected:Npn \@@_try_declaring_generic_next_hook:nn #1 + { + \@@_try_declaring_generic_hook:nNNnn {#1} + \hook_gput_next_code:nn \@@_gput_next_do:nn + } +% \end{macrocode} +% +% \begin{macro}{ +% \@@_try_declaring_generic_hook:nNNnn, +% \@@_try_declaring_generic_hook_split:nNNnn +% } +% \begin{macro}[TF]{\@@_try_declaring_generic_hook:wn} +% \cs{@@_try_declaring_generic_hook:nNNnn} now splits the hook name +% at the first \texttt{/} (if any) and first checks if it is a +% file-specific hook (they require some normalization) using +% \cs{@@_if_file_hook:wTF}. If not then check it is one of a +% predefined set for generic names. We also split off the second +% component to see if we have to make a reversed hook. In either case +% the function returns \meta{true} for a generic hook and \meta{false} +% in other cases. +% \begin{macrocode} +\cs_new_protected:Npn \@@_try_declaring_generic_hook:nNNnn #1 + { + \@@_if_file_hook:wTF #1 / / \s_@@_mark + { + \exp_args:Ne \@@_try_declaring_generic_hook_split:nNNnn + { \exp_args:Ne \@@_file_hook_normalise:n {#1} } + } + { \@@_try_declaring_generic_hook_split:nNNnn {#1} } + } +\cs_new_protected:Npn \@@_try_declaring_generic_hook_split:nNNnn #1 #2 #3 + { + \@@_try_declaring_generic_hook:wnTF #1 / / / \scan_stop: {#1} + { #2 } + { #3 } {#1} + } +\prg_new_protected_conditional:Npnn \@@_try_declaring_generic_hook:wn + #1 / #2 / #3 / #4 \scan_stop: #5 { TF } + { + \tl_if_empty:nTF {#2} + { \prg_return_false: } + { + \prop_if_in:NnTF \c_@@_generics_prop {#1} + { + \hook_if_exist:nF {#5} { \hook_new:n {#5} } +% \end{macrocode} +% After having declared the hook we check the second component (for +% file hooks) or the third component for environment hooks) and +% if it is on the list of components for which we should have declared +% a reversed hook we alter the hook data structure accordingly. +% \begin{macrocode} + \prop_if_in:NnTF \c_@@_generics_reversed_ii_prop {#2} + { \tl_gset:cn { g_@@_#5_reversed_tl } { - } } + { + \prop_if_in:NnT \c_@@_generics_reversed_iii_prop {#3} + { \tl_gset:cn { g_@@_#5_reversed_tl } { - } } + } +% \end{macrocode} +% Now that we know that the hook is declared we can add the code to it. +% \begin{macrocode} + \prg_return_true: + } + { \prg_return_false: } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[pTF]{\@@_if_file_hook:w} +% \cs{@@_if_file_hook:wTF} checks if the argument is a valid +% file-specific hook (not, for example, |file/before|, but +% |file/before/foo.tex|). If it is a file-specific hook, then it +% executes the \meta{true} branch, otherwise \meta{false}. +% +% A file-specific hook is \texttt{file/\meta{position}/\meta{name}}. +% If any of these parts don't exist, it is a general file hook or not +% a file hook at all, so the conditional evaluates to \meta{false}. +% Otherwise, it checks that the first part is |file| and that the +% \meta{position} is in the \cs{c_@@_generics_file_prop}. +% +% A property list is used here to avoid having to worry with catcodes, +% because \pkg{expl3}'s file name parsing turns all characters into +% catcode-12 tokens, which might differ from hand-input letters. +% \begin{macrocode} +\prg_new_conditional:Npnn \@@_if_file_hook:w + #1 / #2 / #3 \s_@@_mark { TF } + { + \str_if_eq:nnTF {#1} { file } + { + \bool_lazy_or:nnTF + { \tl_if_empty_p:n {#3} } + { \str_if_eq_p:nn {#3} { / } } + { \prg_return_false: } + { + \prop_if_in:NnTF \c_@@_generics_file_prop {#2} + { \prg_return_true: } + { \prg_return_false: } + } + } + { \prg_return_false: } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[EXP]{\@@_file_hook_normalise:n} +% \begin{macro}[EXP]{\@@_strip_double_slash:n,\@@_strip_double_slash:w} +% When a file-specific hook is found, before being declared it is +% lightly normalized by \cs{@@_file_hook_normalise:n}. The current +% implementation just replaces two consecutive slashes (|//|) by a +% single one, to cope with simple cases where the user did something +% like \verb|\def\input@path{{./mypath/}}|, in which case a hook would +% have to be \verb|\AddToHook{file/after/./mypath//file.tex}|. +% \begin{macrocode} +\cs_new:Npn \@@_file_hook_normalise:n #1 + { \@@_strip_double_slash:n {#1} } +\cs_new:Npn \@@_strip_double_slash:n #1 + { \@@_strip_double_slash:w #1 // \s_@@_mark } +\cs_new:Npn \@@_strip_double_slash:w #1 // #2 \s_@@_mark + { + \tl_if_empty:nTF {#2} + {#1} + { \@@_strip_double_slash:w #1 / #2 \s_@@_mark } + } +% \end{macrocode} +% \end{macro} +% \end{macro} + + + + + +% \begin{macro}{\c_@@_generics_prop} +% Clist holding the generic names. We don't provide any user +% interface to this as this is meant to be static. +% \begin{description} +% \item[\texttt{env}] +% The generic hooks used in \cs{begin} and \cs{end}. +% \item[\texttt{file}] +% The generic hooks used when loading a file +% \end{description} +% \begin{macrocode} +\prop_const_from_keyval:Nn \c_@@_generics_prop + {env=,file=,package=,class=,include=} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\c_@@_generics_reversed_ii_prop, +% \c_@@_generics_reversed_iii_prop, +% \c_@@_generics_file_prop} +% Some of the generic hooks are supposed to use reverse ordering, these are +% the following (only the second or third sub-component is checked): +% \begin{macrocode} +\prop_const_from_keyval:Nn \c_@@_generics_reversed_ii_prop {after=,end=} +\prop_const_from_keyval:Nn \c_@@_generics_reversed_iii_prop {after=} +\prop_const_from_keyval:Nn \c_@@_generics_file_prop {before=,after=} +% \end{macrocode} +% \end{macro} + + +% \begin{macro}{\@@_update_hook_code:n} +% Before \verb=\begin{document}= this does nothing, in the body it +% reinitializes the hook code using the altered data. +% \begin{macrocode} +\cs_new_eq:NN \@@_update_hook_code:n \use_none:n +% \end{macrocode} +% \end{macro} + + +% \begin{macro}{\hook_gremove_code:nn} +% \begin{macro}{\@@_gremove_code:nn} +% +% With \cs{hook_gremove_code:nn}\Arg{hook}\Arg{label} any code +% for \meta{hook} stored under \meta{label} is removed. +% \begin{macrocode} +\cs_new_protected:Npn \hook_gremove_code:nn #1 #2 + { + \exp_args:Nxx \@@_gremove_code:nn + { \@@_parse_label_default:nn {#1} { top-level } } + { \@@_parse_label_default:nn {#2} { top-level } } + } +\cs_new_protected:Npn \@@_gremove_code:nn #1 #2 + { +% \end{macrocode} +% First check that the hook code pool exists. \cs{hook_if_exist:nTF} +% isn't used here because it should be possible to remove code from a +% hook before its defined (see section~\ref{sec:querying}). +% \begin{macrocode} + \@@_if_exist:nTF {#1} +% \end{macrocode} +% Then remove the chunk and run \cs{@@_update_hook_code:n} so +% that the execution token list reflects the change if we are after +% \verb=\begin{document}=. +% \begin{macrocode} + { + \str_if_eq:nnTF {#2} {*} + { + \prop_gclear:c { g_@@_#1_code_prop } + \clist_gclear:c { g_@@_#1_labels_clist } % for debugging only + } + { +% \end{macrocode} +% Check if the label being removed exists in the code pool. If it does, +% just call \cs{@@_gremove_code_do:nn} to do the removal, otherwise mark it +% to be removed. +% \begin{macrocode} + \prop_get:cnNTF { g_@@_#1_code_prop } {#2} \l_@@_return_tl + { \@@_gremove_code_do:nn } + { \@@_mark_removal:nn } + {#1} {#2} + } +% \end{macrocode} +% Finally update the code, if the hook exists. +% \begin{macrocode} + \hook_if_exist:nT {#1} + { \@@_update_hook_code:n {#1} } + } + { \@@_mark_removal:nn {#1} {#2} } + } +% \end{macrocode} +% +% \begin{macro}{\@@_gremove_code_do:nn} +% \begin{macrocode} +\cs_new_protected:Npn \@@_gremove_code_do:nn #1 #2 + { + \prop_gremove:cn { g_@@_#1_code_prop } {#2} +% \end{macrocode} +% Removing the dropped label from \verb=\g_@@_#1_labels_clist= is +% rather tricky, because that clists holds the labels as strings +% (i.e., not ordinary text which is what we have in \verb=#2=). +% \begin{macrocode} + \exp_args:Nco \clist_gremove_all:Nn + { g_@@_#1_labels_clist } { \tl_to_str:n {#2} } % for debugging only + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} + + +% +% \begin{macro}{\@@_mark_removal:nn} +% Marks \meta{label} (\verb=#2=) to be removed from \meta{hook} +% (\verb=#1=). +% \begin{macrocode} +\cs_new_protected:Npn \@@_mark_removal:nn #1 #2 + { + \tl_gput_right:Nx \g_@@_removal_list_tl + { \@@_removal_tl:nn {#1} {#2} } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_unmark_removal:nn} +% Unmarks \meta{label} (\verb=#2=) to be removed from \meta{hook} +% (\verb=#1=). \cs{tl_gremove_once:Nx} is used rather than +% \cs{tl_gremove_all:Nx} so that two additions are needed to cancel +% two marked removals, rather than only one. +% \begin{macrocode} +\cs_new_protected:Npn \@@_unmark_removal:nn #1 #2 + { + \tl_gremove_once:Nx \g_@@_removal_list_tl + { \@@_removal_tl:nn {#1} {#2} } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[TF]{\@@_if_marked_removal:nn} +% Checks if the \cs{g_@@_removal_list_tl} contains the current +% \meta{label} (\verb=#2=) and \meta{hook} (\verb=#1=). +% \begin{macrocode} +\prg_new_protected_conditional:Npnn \@@_if_marked_removal:nn #1 #2 { TF } + { + \exp_args:NNx \tl_if_in:NnTF \g_@@_removal_list_tl + { \@@_removal_tl:nn {#1} {#2} } + { \prg_return_true: } { \prg_return_false: } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[rEXP]{\@@_removal_tl:nn} +% Builds a token list with \verb=#1= and \verb=#2= which can only be +% matched by \verb=#1= and \verb=#2=. +% \begin{macrocode} +\cs_new:Npn \@@_removal_tl:nn #1 #2 + { & \tl_to_str:n {#2} $ \tl_to_str:n {#1} $ } +% \end{macrocode} +% \end{macro} + + + + +% +% +% +% \begin{macro}{ +% \g_@@_??_rules_prop, +% \g_@@_??_code_prop, +% \g_@@_??_code_tl, +% \g_@@_??_reversed_tl, +% } +% +% Default rules applying to all hooks are stored in this property +% list. Initially it simply used an empty ``label'' name (not two +% question marks). This was a bit unfortunate, because then +% \texttt{l3doc} complains about \verb=__= in the middle of a +% command name when trying to typeset the documentation. However +% using a ``normal'' name such as \texttt{default} has the +% disadvantage of that being not really distinguishable from a real +% hook name. I now have settled for \texttt{??} which needs some +% gymnastics to get it into the csname, but since this is used a +% lot things should be fast, so this is not done with \texttt{c} +% expansion in the code later on. +% +% \cs{g_@@_??_code_tl} isn't used, but it has to be defined to trick +% the code into thinking that \verb=??= is actually a hook. +% \begin{macrocode} +\prop_new:c {g_@@_??_rules_prop} +\prop_new:c {g_@@_??_code_prop} +\prop_new:c {g_@@_??_code_tl} +% \end{macrocode} +% +% Default rules are always given in normal ordering (never in +% reversed ordering). If such a rule is applied to a reversed +% hook it behaves as if the rule is reversed (e.g., +% \texttt{after} becomes \texttt{before}) +% because those rules are applied first and then the order is reversed. +% \begin{macrocode} +\tl_new:c {g_@@_??_reversed_tl} +% \end{macrocode} +% \end{macro} + + + +% \begin{macro}{\@@_debug_gset_rule:nnnn} +% +% \fmi{this needs cleanup and docu correction!} +% +% With +% \cs{@@_debug_gset_rule:nnnn}\Arg{hook}\Arg{label1}\Arg{relation}\Arg{label2} +% a relation is defined between the two code labels for the given +% \meta{hook}. The special hook \texttt{??} stands for \emph{any} +% hook describing a default rule. +% \begin{macrocode} +\cs_new_protected:Npn \@@_debug_gset_rule:nnnn #1#2#3#4 + { +% \end{macrocode} +% If so we drop any existing rules with the two labels (in case +% there are any). +% \begin{macrocode} + \prop_gremove:cn{g_@@_#1_rules_prop}{#2|#4} + \prop_gremove:cn{g_@@_#1_rules_prop}{#4|#2} +% \end{macrocode} +% Then we add the new one (normalizing the input a bit, e.g., we +% always use \texttt{before} and not \texttt{after} and +% instead reorder the labels): +% \begin{macrocode} + \str_case_e:nnF {#3} + { + {before} { \prop_gput:cnn {g_@@_#1_rules_prop}{#2|#4}{<} } + {after} { \prop_gput:cnn {g_@@_#1_rules_prop}{#4|#2}{<} } +% \end{macrocode} +% More special rule types \ldots +% \begin{macrocode} + {incompatible-error} { \prop_gput:cnn {g_@@_#1_rules_prop}{#2|#4}{xE} } + {incompatible-warning} { \prop_gput:cnn {g_@@_#1_rules_prop}{#2|#4}{xW} } + {removes} { \prop_gput:cnn {g_@@_#1_rules_prop}{#2|#4}{->} } +% \end{macrocode} +% Undo a setting: +% \begin{macrocode} + {unrelated}{ \prop_gremove:cn {g_@@_#1_rules_prop}{#2|#4} + \prop_gremove:cn {g_@@_#1_rules_prop}{#4|#2} } + } + { \ERRORunknownrule } + } +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Setting rules for hooks code} +% +% \begin{macro}{\hook_gset_rule:nnnn} +% \begin{macro}{\@@_gset_rule:nnnn} +% +% \fmi{needs docu correction given new implementation} +% +% With +% \cs{hook_gset_rule:nnnn}\Arg{hook}\Arg{label1}\Arg{relation}\Arg{label2} +% a relation is defined between the two code labels for the given +% \meta{hook}. The special hook \texttt{??} stands for \emph{any} +% hook describing a default rule. +% \begin{macrocode} +\cs_new_protected:Npn \hook_gset_rule:nnnn #1#2#3#4 + { + \use:x + { + \@@_gset_rule:nnnn + { \@@_parse_label_default:nn {#1} { top-level } } + { \@@_parse_label_default:nn {#2} { top-level } } + {#3} + { \@@_parse_label_default:nn {#4} { top-level } } + } + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_gset_rule:nnnn #1#2#3#4 + { +% \end{macrocode} +% First we ensure the basic data structure of the hook exists: +% \begin{macrocode} + \@@_declare:n {#1} +% \end{macrocode} +% Then we clear any previous relationship between both labels. +% \begin{macrocode} + \@@_rule_gclear:nnn {#1} {#2} {#4} +% \end{macrocode} +% Then we call the function to handle the given rule. Throw an error if the +% rule is invalid. +% \begin{macrocode} + \debug_suspend: + \cs_if_exist_use:cTF { @@_rule_#3_gset:nnn } + { + {#1} {#2} {#4} + \@@_update_hook_code:n {#1} + } + { \ERRORunknownrule } + \debug_resume: + \@@_debug_gset_rule:nnnn {#1} {#2} {#3} {#4} % for debugging + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_rule_before_gset:nnn, \@@_rule_after_gset:nnn, +% \@@_rule_<_gset:nnn, \@@_rule_>_gset:nnn} +% Then we add the new rule. We need to normalize the rules here to +% allow for faster processing later. Given a pair of labels +% $l_A$ and $l_B$, the rule $l_A>l_B$ is the same as $l_B<l_A$\fmi{} +% said differently. But normalizing the +% forms of the rule to a single representation, say, $l_B<l_A$, then +% the time spent looking for the rules later is considerably reduced. +% +% Here we do that normalization by using \cs[no-index]{(pdf)strcmp} to +% lexically sort labels $l_A$ and $l_B$ to a fixed order. This order +% is then enforced every time these two labels are used together. +% +% Here we use \cs{@@_label_pair:nn}~\Arg{hook}~\Arg{l_A}~\Arg{l_B} +% to build a string \texttt{$l_B$\string|$l_A$} with a fixed order, and +% use \cs{@@_label_ordered:nnTF} to apply the correct rule to the pair +% of labels, depending if it was sorted or not. +% \begin{macrocode} +\cs_new_protected:Npn \@@_rule_before_gset:nnn #1#2#3 + { + \tl_gset:cx { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl } + { \@@_label_ordered:nnTF {#2} {#3} { < } { > } } + } +\cs_new_eq:cN { @@_rule_<_gset:nnn } \@@_rule_before_gset:nnn +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_rule_after_gset:nnn #1#2#3 + { + \tl_gset:cx { g_@@_#1_rule_ \@@_label_pair:nn {#3} {#2} _tl } + { \@@_label_ordered:nnTF {#3} {#2} { < } { > } } + } +\cs_new_eq:cN { @@_rule_>_gset:nnn } \@@_rule_after_gset:nnn +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_rule_removes_gset:nnn} +% This rule removes (clears, actually) the code from label |#3| if +% label |#2| is in the hook |#1|. +% \begin{macrocode} +\cs_new_protected:Npn \@@_rule_removes_gset:nnn #1#2#3 + { + \tl_gset:cx { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl } + { \@@_label_ordered:nnTF {#2} {#3} { -> } { <- } } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{ +% \@@_rule_incompatible-error_gset:nnn, +% \@@_rule_incompatible-warning_gset:nnn, +% } +% These relations make an error/warning if labels |#2| and |#3| appear +% together in hook |#1|. +% \begin{macrocode} +\cs_new_protected:cpn { @@_rule_incompatible-error_gset:nnn } #1#2#3 + { \tl_gset:cn { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl } { xE } } +\cs_new_protected:cpn { @@_rule_incompatible-warning_gset:nnn } #1#2#3 + { \tl_gset:cn { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl } { xW } } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_rule_unrelated_gset:nnn, \@@_rule_gclear:nnn} +% Undo a setting. \cs{@@_rule_unrelated_gset:nnn} doesn't need to do anything, +% since we use \cs{@@_rule_gclear:nnn} before setting any rule. +% \begin{macrocode} +\cs_new_protected:Npn \@@_rule_unrelated_gset:nnn #1#2#3 { } +\cs_new_protected:Npn \@@_rule_gclear:nnn #1#2#3 + { \cs_undefine:c { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl } } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[EXP]{\@@_label_pair:nn} +% Ensure that the lexically greater label comes first. +% \begin{macrocode} +\cs_new:Npn \@@_label_pair:nn #1#2 + { + \if_case:w \@@_str_compare:nn {#1} {#2} \exp_stop_f: + #1 | #1 % 0 + \or: #1 | #2 % +1 + \else: #2 | #1 % -1 + \fi: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[pTF]{\@@_label_ordered:nn} +% Check that labels |#1| and |#2| are in the correct order (as +% returned by \cs{@@_label_pair:nn}) and if so return true, else +% return false. +% \begin{macrocode} +\prg_new_conditional:Npnn \@@_label_ordered:nn #1#2 { TF } + { + \if_int_compare:w \@@_str_compare:nn {#1} {#2} > 0 \exp_stop_f: + \prg_return_true: + \else + \prg_return_false: + \fi: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[EXP]{\@@_if_label_case:nnnnn} +% To avoid doing the string comparison twice in \cs{@@_initialize_single:NNNNn} +% (once with \cs{str_if_eq:nn} and again with \cs{@@_label_ordered:nn}), +% we use a three-way branching macro that will compare |#1| and |#2| +% and expand to \cs{use_i:nnn} if they are equal, \cs{use_ii:nn} if +% |#1| is lexically greater, and \cs{use_iii:nn} otherwise. +% \begin{macrocode} +\cs_new:Npn \@@_if_label_case:nnnnn #1#2 + { + \cs:w use_ + \if_case:w \@@_str_compare:nn {#1} {#2} + i \or: ii \else: iii \fi: :nnn + \cs_end: + } +% \end{macrocode} +% \end{macro} + + +% \begin{macro}{\@@_initialize_all:} +% Initialize all known hooks (at \verb=\begin{document}=), i.e., +% update the fast execution token lists to hold the necessary code +% in the right order. +% \begin{macrocode} +\cs_new_protected:Npn \@@_initialize_all: { +% \end{macrocode} +% First we change \cs{@@_update_hook_code:n} which so far was a +% no-op to now initialize one hook. This way any later updates to +% the hook will run that code and also update the execution token +% list. +% \begin{macrocode} + \cs_gset_eq:NN \@@_update_hook_code:n \@@_initialize_hook_code:n +% \end{macrocode} +% Now we loop over all hooks that have been defined and update each +% of them. +% \begin{macrocode} + \@@_debug:n { \prop_gclear:N \g_@@_used_prop } + \seq_map_inline:Nn \g_@@_all_seq + { + \@@_update_hook_code:n {##1} + } +% \end{macrocode} +% If we are debugging we show results hook by hook for all hooks +% that have data. +% \begin{macrocode} + \@@_debug:n + { \iow_term:x{^^JAll~ initialized~ (non-empty)~ hooks:} + \prop_map_inline:Nn \g_@@_used_prop + { \iow_term:x{^^J~ ##1~ ->~ + \exp_not:v {g_@@_##1_code_tl}~ } + } + } +% +% \end{macrocode} +% After all hooks are initialized we change the ``use'' to just +% call the hook code and not initialize it (as it was done in the +% preamble. +% \begin{macrocode} + \cs_gset_eq:NN \hook_use:n \@@_use_initialized:n + \cs_gset_eq:NN \@@_preamble_hook:n \use_none:n +} +% \end{macrocode} +% \end{macro} + + + +% \begin{macro}{\@@_initialize_hook_code:n} +% Initializing or reinitializing the fast execution hook code. In +% the preamble this is selectively done in case a hook gets used +% and at \verb=\begin{document}= this is done for all hooks and +% afterwards only if the hook code changes. +% \begin{macrocode} +\cs_new_protected:Npn \@@_initialize_hook_code:n #1 { + \@@_debug:n{ \iow_term:x{^^JUpdate~ code~ for~ hook~ + '#1' \on@line :^^J} } +% \end{macrocode} +% This does the sorting and the updates. If there aren't any code +% chunks for the current hook, there is no point in even starting +% the sorting routine so we make a quick test for that and in that +% case just update \cs{g_@@_\meta{hook}_code_tl} to hold the next +% code. If there are code chunks we call +% \cs{@@_initialize_single:NNNNn} and pass to it ready made csnames +% as they are needed several times inside. This way we save a bit +% on processing time if we do that up front. +% \begin{macrocode} + \hook_if_exist:nT {#1} + { + \prop_if_empty:cTF {g_@@_#1_code_prop} + { \tl_gset:co {g_@@_#1_code_tl} + {\cs:w g_@@_#1_next_code_tl \cs_end: } } + { +% \end{macrocode} +% By default the algorithm sorts the code chunks and then saves the +% result in a token list for fast execution by adding the code one +% after another using \cs{tl_gput_right:NV}. When we sort code for +% a reversed hook, all we have to do is to add the code chunks in +% the opposite order into the token list. So all we have to do +% in preparation is to change two definitions used later on. +% \begin{macrocode} + \@@_if_reversed:nTF {#1} + { \cs_set_eq:NN \@@_tl_gput:NV \tl_gput_left:NV + \cs_set_eq:NN \@@_clist_gput:NV \clist_gput_left:NV } + { \cs_set_eq:NN \@@_tl_gput:NV \tl_gput_right:NV + \cs_set_eq:NN \@@_clist_gput:NV \clist_gput_right:NV } +% \end{macrocode} +% +% When sorting, some relations (namely \verb|->| \verb|<-|) need to +% act destructively on the code property lists to remove code that +% shouldn't appear in the sorted hook token list. +% \begin{macrocode} + \prop_gset_eq:Nc \g_@@_code_temp_prop { g_@@_#1_code_prop } + \@@_initialize_single:ccccn + { g_@@_#1_code_prop } { g_@@_#1_code_tl } + { g_@@_#1_next_code_tl } { g_@@_#1_labels_clist } + {#1} + \prop_gset_eq:cN { g_@@_#1_code_prop } \g_@@_code_temp_prop +% \end{macrocode} +% For debug display we want to keep track of those hooks that +% actually got code added to them, so we record that in plist. We +% use a plist to ensure that we record each hook name only once, +% i.e., we are only interested in storing the keys and the value is arbitrary +% \begin{macrocode} + \@@_debug:n{ \exp_args:NNx \prop_gput:Nnn \g_@@_used_prop {#1}{} } + } + } +} +% \end{macrocode} +% \end{macro} + + +% \begin{macro}{\g_@@_used_prop} +% All hooks that receive code (for use in debugging display). +% \begin{macrocode} +\prop_new:N\g_@@_used_prop +% \end{macrocode} +% \end{macro} + + +% +% \begin{macro}[EXP]{\@@_tl_csname:n,\@@_seq_csname:n} +% It is faster to pass a single token and expand it when necessary +% than to pass a bunch of character tokens around. +% \fmi{note to myself: verify} +% \begin{macrocode} +\cs_new:Npn \@@_tl_csname:n #1 { l_@@_label_#1_tl } +\cs_new:Npn \@@_seq_csname:n #1 { l_@@_label_#1_seq } +% \end{macrocode} +% \end{macro} +% + +% +% +% \begin{macro}{\l_@@_labels_seq,\l_@@_labels_int,\l_@@_front_tl, +% \l_@@_rear_tl,\l_@@_label_0_tl} +% +% For the sorting I am basically implementing Knuth's algorithm for +% topological sorting as given in TAOCP volume 1 pages 263--266. +% For this algorithm we need a number of local variables: +% \begin{itemize} +% \item +% List of labels used in the current hook to label code chunks: +% \begin{macrocode} +\seq_new:N \l_@@_labels_seq +% \end{macrocode} +% \item +% Number of labels used in the current hook. In Knuth's algorithm +% this is called $N$: +% \begin{macrocode} +\int_new:N \l_@@_labels_int +% \end{macrocode} +% \item +% The sorted code list to be build is managed using two pointers +% one to the front of the queue and one to the rear. We model this +% using token list pointers. Knuth calls them $F$ and $R$: +% \begin{macrocode} +\tl_new:N \l_@@_front_tl +\tl_new:N \l_@@_rear_tl +% \end{macrocode} +% \item +% The data for the start of the queue is kept in this token list, +% it corresponds to what Don calls \texttt{QLINK[0]} but since we +% aren't manipulating individual words in memory it is slightly +% differently done: +% \begin{macrocode} +\tl_new:c { \@@_tl_csname:n { 0 } } +% \end{macrocode} +% +% \end{itemize} +% \end{macro} + + +% \begin{macro}{\@@_initialize_single:NNNNn,\@@_initialize_single:ccccn} +% +% \cs{@@_initialize_single:NNNNn} implements the sorting of the code +% chunks for a hook and saves the result in the token list for fast +% execution (\verb=#3=). The arguments are \meta{hook-code-plist}, +% \meta{hook-code-tl}, \meta{hook-next-code-tl}, +% \meta{hook-ordered-labels-clist} and \meta{hook-name} (the latter +% is only used for debugging---the \meta{hook-rule-plist} is accessed +% using the \meta{hook-name}). +% +% The additional complexity compared to Don's algorithm is that we +% do not use simple positive integers but have arbitrary +% alphanumeric labels. As usual Don's data structures are chosen in +% a way that one can omit a lot of tests and I have mimicked that as +% far as possible. The result is a restriction I do not test for at +% the moment: a label can't be equal to the number 0! \fmi{Needs +% checking for, just in case} +% \begin{macrocode} +\cs_new_protected:Npn \@@_initialize_single:NNNNn #1#2#3#4#5 { +% \end{macrocode} +% +% \begin{macrocode} + \debug_suspend: +% \end{macrocode} +% Step T1: Initialize the data structure \ldots +% \begin{macrocode} + \seq_clear:N \l_@@_labels_seq + \int_zero:N \l_@@_labels_int +% \end{macrocode} +% +% Store the name of the hook: +% \begin{macrocode} + \tl_set:Nn \l_@@_cur_hook_tl {#5} +% \end{macrocode} +% +% We loop over the property list holding the code and record all +% labels listed there. Only rules for those labels are of interest +% to us. While we are at it we count them (which gives us the $N$ +% in Knuth's algorithm. The prefix |label_| is added to the variables +% to ensure that labels named |front|, |rear|, |labels|, or |return| +% don't interact with our code. +% \begin{macrocode} + \prop_map_inline:Nn #1 + { + \int_incr:N \l_@@_labels_int + \seq_put_right:Nn \l_@@_labels_seq {##1} + \tl_set:cn { \@@_tl_csname:n {##1} }{0} % the counter k for number of + % j before k rules + \seq_clear_new:c { \@@_seq_csname:n {##1} } % sequence of successors to k + % i.e., k before j rules (stores + % the names of the j's) + } +% \end{macrocode} +% Steps T2 and T3: Sort the relevant rules into the data structure\ldots +% +% This loop constitutes a square matrix of the labels in |#1| in the +% vertical and the horizontal directions. However since the rule +% $l_A\meta{rel}l_B$ is the same as $l_B\meta{rel}^{-1}l_A$ we can cut +% the loop short at the diagonal of the matrix (\emph{i.e.}, when +% both labels are equal), saving a good amount of time. The way the +% rules were set up (see the implementation of \cs{@@_rule_before_gset:nnn} +% above) ensures that we have no rule in the ignored side of the +% matrix, and all rules are seen. The rules are applied in +% \cs{@@_apply_label_pair:nnn}, which takes the properly-ordered pair +% of labels as argument. +% \begin{macrocode} + \prop_map_inline:Nn #1 + { + \prop_map_inline:Nn #1 + { + \@@_if_label_case:nnnnn {##1} {####1} + { \prop_map_break: } + { \@@_apply_label_pair:nnn {##1} {####1} } + { \@@_apply_label_pair:nnn {####1} {##1} } + {#5} + } + } +% \end{macrocode} +% Take a breath and take a look at the data structures that have +% been set up: +% \begin{macrocode} + \@@_debug:n { \@@_debug_label_data:N #1 } +% \end{macrocode} +% +% +% Step T4: +% \begin{macrocode} + \tl_set:Nn \l_@@_rear_tl { 0 } + \tl_set:cn { \@@_tl_csname:n { 0 } } { 0 } % really {l_@@_label_ \l_@@_rear_tl _tl} + \seq_map_inline:Nn \l_@@_labels_seq + { + \int_compare:nNnT { \cs:w \@@_tl_csname:n {##1} \cs_end: } = 0 + { + \tl_set:cn { \@@_tl_csname:n { \l_@@_rear_tl } }{##1} + \tl_set:Nn \l_@@_rear_tl {##1} + } + } + \tl_set_eq:Nc \l_@@_front_tl { \@@_tl_csname:n { 0 } } +% \end{macrocode} +% +% \begin{macrocode} + \tl_gclear:N #2 + \clist_gclear:N #4 +% \end{macrocode} +% +% The whole loop combines steps T5--T7: +% \begin{macrocode} + \bool_while_do:nn { ! \str_if_eq_p:Vn \l_@@_front_tl { 0 } } + { +% \end{macrocode} +% This part is step T5: +% \begin{macrocode} + \int_decr:N \l_@@_labels_int + \prop_get:NVN #1 \l_@@_front_tl \l_@@_return_tl + \@@_tl_gput:NV #2 \l_@@_return_tl +% \end{macrocode} +% +% \begin{macrocode} + \@@_clist_gput:NV #4 \l_@@_front_tl + \@@_debug:n{ \iow_term:x{Handled~ code~ for~ \l_@@_front_tl} } +% \end{macrocode} +% +% This is step T6 except that we don't use a pointer $P$ to move +% through the successors, but instead use \verb=##1= of the mapping +% function. +% \begin{macrocode} + \seq_map_inline:cn { \@@_seq_csname:n { \l_@@_front_tl } } + { + \tl_set:cx { \@@_tl_csname:n {##1} } + { \int_eval:n { \cs:w \@@_tl_csname:n {##1} \cs_end: - 1 } } + \int_compare:nNnT { \cs:w \@@_tl_csname:n {##1} \cs_end: } = 0 + { + \tl_set:cn { \@@_tl_csname:n { \l_@@_rear_tl } } {##1} + \tl_set:Nn \l_@@_rear_tl {##1} + } + } +% \end{macrocode} +% and step T7: +% \begin{macrocode} + \tl_set_eq:Nc \l_@@_front_tl { \@@_tl_csname:n { \l_@@_front_tl } } +% \end{macrocode} +% +% This is step T8: If we haven't moved the code for all labels +% (i.e., if \cs{l_@@_labels_int} is still greater than zero) we +% have a loop and our partial order can't be flattened out. +% \begin{macrocode} + } + \int_compare:nNnF \l_@@_labels_int = 0 + { + \iow_term:x{====================} + \iow_term:x{Error:~ label~ rules~ are~ incompatible:} +% \end{macrocode} +% +% This is not really the information one needs in the error case +% but will do for now \ldots \fmi{fix} +% \begin{macrocode} + \@@_debug_label_data:N #1 + \iow_term:x{====================} + } +% \end{macrocode} +% After we have added all hook code to \verb=#2= we finish it off +% with adding extra code for a one time execution. That is stored +% in \verb=#3= but is normally empty. +% \begin{macrocode} + \tl_gput_right:Nn #2 {#3} +% \end{macrocode} +% +% \begin{macrocode} + \debug_resume: +} +% \end{macrocode} +% +% \begin{macrocode} +\cs_generate_variant:Nn \@@_initialize_single:NNNNn {cccc} +% \end{macrocode} +% \end{macro} + + + +% \begin{macro}{\@@_tl_gput:NV,\@@_clist_gput:NV} +% These append either on the right (normal hook) or on the left +% (reversed hook). This is setup up in +% \cs{@@_initialize_hook_code:n}, elsewhere their behavior is undefined. +% \begin{macrocode} +\cs_new:Npn \@@_tl_gput:NV {\ERROR} +\cs_new:Npn \@@_clist_gput:NV {\ERROR} +% \end{macrocode} +% \end{macro} + + +% +% \begin{macro}{\@@_apply_label_pair:nnn,\@@_label_if_exist_apply:nnnF} +% +% This is the payload of steps T2 and T3 executed in the loop described +% above. This macro assumes |#1| and |#2| are ordered, which means that +% any rule pertaining the pair |#1| and |#2| is +% \cs{g_@@_\meta{hook}_rule_\#1\string|\#2_tl}, and not +% \cs{g_@@_\meta{hook}_rule_\#2\string|\#1_tl}. This also saves a great deal +% of time since we only need to check the order of the labels once. +% +% The arguments here are \meta{label1}, \meta{label2}, \meta{hook}, and +% \meta{hook-code-plist}. We are about to apply the next rule and +% enter it into the data structure. \cs{@@_apply_label_pair:nnn} will +% just call \cs{@@_label_if_exist_apply:nnnF} for the \meta{hook}, and +% if no rule is found, also try the \meta{hook} name \verb=??= +% denoting a default hook rule. +% +% \cs{@@_label_if_exist_apply:nnnF} will check if the rule exists for +% the given hook, and if so call \cs{@@_apply_rule:nnn}. +% \begin{macrocode} +\cs_new_protected:Npn \@@_apply_label_pair:nnn #1#2#3 + { +% \end{macrocode} +% Extra complication: as we use default rules and local hook specific +% rules we first have to check if there is a local rule and if that +% exist use it. Otherwise check if there is a default rule and use +% that. +% \begin{macrocode} + \@@_label_if_exist_apply:nnnF {#1} {#2} {#3} + { +% \end{macrocode} +% If there is no hook-specific rule we check for a default one and +% use that if it exists. +% \begin{macrocode} + \@@_label_if_exist_apply:nnnF {#1} {#2} { ?? } { } + } + } +\cs_new_protected:Npn \@@_label_if_exist_apply:nnnF #1#2#3 + { + \if_cs_exist:w g_@@_ #3 _rule_ #1 | #2 _tl \cs_end: +% \end{macrocode} +% What to do precisely depends on the type of rule we have +% encountered. If it is a \texttt{before} rule it will be handled by the +% algorithm but other types need to be managed differently. All +% this is done in \cs{@@_apply_rule:nnnN}. +% \begin{macrocode} + \@@_apply_rule:nnn {#1} {#2} {#3} + \exp_after:wN \use_none:n + \else: + \use:nn + \fi: + } +% \end{macrocode} +% \end{macro} + + + + +% \begin{macro}{\@@_apply_rule:nnn} +% This is the code executed in steps T2 and T3 while looping through +% the matrix This is part of step T3. We are about to apply the next +% rule and enter it into the data structure. The arguments are +% \meta{label1}, \meta{label2}, \meta{hook-name}, and \meta{hook-code-plist}. +% \begin{macrocode} +\cs_new_protected:Npn \@@_apply_rule:nnn #1#2#3 + { + \cs:w @@_apply_ + \cs:w g_@@_#3_reversed_tl \cs_end: rule_ + \cs:w g_@@_ #3 _rule_ #1 | #2 _tl \cs_end: :nnn \cs_end: + {#1} {#2} {#3} + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_apply_rule_<:nnn,\@@_apply_rule_>:nnn} +% The most common cases are \texttt{\string<} and \texttt{\string>} so we handle +% that first. They are relations $\prec$ and $\succ$ in TAOCP, and +% they dictate sorting. +% \begin{macrocode} +\cs_new_protected:cpn { @@_apply_rule_<:nnn } #1#2#3 + { + \@@_debug:n { \@@_msg_pair_found:nnn {#1} {#2} {#3} } + \tl_set:cx { \@@_tl_csname:n {#2} } + { \int_eval:n{ \cs:w \@@_tl_csname:n {#2} \cs_end: + 1 } } + \seq_put_right:cn{ \@@_seq_csname:n {#1} }{#2} + } +\cs_new_protected:cpn { @@_apply_rule_>:nnn } #1#2#3 + { + \@@_debug:n { \@@_msg_pair_found:nnn {#1} {#2} {#3} } + \tl_set:cx { \@@_tl_csname:n {#1} } + { \int_eval:n{ \cs:w \@@_tl_csname:n {#1} \cs_end: + 1 } } + \seq_put_right:cn{ \@@_seq_csname:n {#2} }{#1} + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_apply_rule_xE:nnn,\@@_apply_rule_xW:nnn} +% These relations make two labels incompatible within a hook. +% |xE| makes raises an error if the labels are found in the same +% hook, and |xW| makes it a warning. +% \begin{macrocode} +\cs_new_protected:cpn { @@_apply_rule_xE:nnn } #1#2#3 + { + \@@_debug:n { \@@_msg_pair_found:nnn {#1} {#2} {#3} } + \msg_error:nnnnnn { hooks } { labels-incompatible } + {#1} {#2} {#3} { 1 } + \use:c { @@_apply_rule_->:nnn } {#1} {#2} {#3} + \use:c { @@_apply_rule_<-:nnn } {#1} {#2} {#3} + } +\cs_new_protected:cpn { @@_apply_rule_xW:nnn } #1#2#3 + { + \@@_debug:n { \@@_msg_pair_found:nnn {#1} {#2} {#3} } + \msg_warning:nnnnnn { hooks } { labels-incompatible } + {#1} {#2} {#3} { 0 } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_apply_rule_->:nnn,\@@_apply_rule_<-:nnn} +% If we see \texttt{\detokenize{->}} we have to drop code for label +% \verb=#3= and carry on. We could do a little better and trop +% everything for that label since it doesn't matter where we sort +% in the empty code. However that would complicate the algorithm a +% lot with little gain. So we still unnecessarily try to sort it in +% and depending on the rules that might result in a loop that is +% otherwise resolved. If that turns out to be a real issue, we can +% improve the code. +% +% Here the code is removed from \cs{l_@@_cur_hook_tl} rather than +% \verb=#3= because the latter may be \verb=??=, and the default +% hook doesn't store any code. Removing from \cs{l_@@_cur_hook_tl} +% makes default rules \verb=->= and \verb=<-= work properly. +% \begin{macrocode} +\cs_new_protected:cpn { @@_apply_rule_->:nnn } #1#2#3 + { + \@@_debug:n + { + \@@_msg_pair_found:nnn {#1} {#2} {#3} + \iow_term:x{--->~ Drop~ '#2'~ code~ from~ + \iow_char:N \\ g_@@_ \l_@@_cur_hook_tl _code_prop ~ because~ of~ '#1' } + } + \prop_gput:cnn { g_@@_ \l_@@_cur_hook_tl _code_prop } {#2} { } + } +\cs_new_protected:cpn { @@_apply_rule_<-:nnn } #1#2#3 + { + \@@_debug:n + { + \@@_msg_pair_found:nnn {#1} {#2} {#3} + \iow_term:x{--->~ Drop~ '#1'~ code~ from~ + \iow_char:N \\ g_@@_ \l_@@_cur_hook_tl _code_prop ~ because~ of~ '#2' } + } + \prop_gput:cnn { g_@@_ \l_@@_cur_hook_tl _code_prop } {#1} { } + } +% \end{macrocode} +% \end{macro} + +% \begin{macro}{ +% \@@_apply_-rule_<:nnn, +% \@@_apply_-rule_>:nnn, +% \@@_apply_-rule_<-:nnn, +% \@@_apply_-rule_->:nnn, +% \@@_apply_-rule_x:nnn, +% } +% Reversed rules. +% \begin{macrocode} +\cs_new_eq:cc { @@_apply_-rule_<:nnn } { @@_apply_rule_>:nnn } +\cs_new_eq:cc { @@_apply_-rule_>:nnn } { @@_apply_rule_<:nnn } +\cs_new_eq:cc { @@_apply_-rule_<-:nnn } { @@_apply_rule_<-:nnn } +\cs_new_eq:cc { @@_apply_-rule_->:nnn } { @@_apply_rule_->:nnn } +\cs_new_eq:cc { @@_apply_-rule_xE:nnn } { @@_apply_rule_xE:nnn } +\cs_new_eq:cc { @@_apply_-rule_xW:nnn } { @@_apply_rule_xW:nnn } +% \end{macrocode} +% \end{macro} + + +% \begin{macro}{\@@_msg_pair_found:nnn} +% A macro to avoid moving this many tokens around. +% \begin{macrocode} +\cs_new_protected:Npn \@@_msg_pair_found:nnn #1#2#3 + { + \iow_term:x{~ \str_if_eq:nnTF {#3} {??} {default} {~normal} ~ + rule~ \@@_label_pair:nn {#1} {#2}:~ + \use:c { g_@@_#3_rule_ \@@_label_pair:nn {#1} {#2} _tl } ~ found} + } +% \end{macrocode} +% \end{macro} + + +% \begin{macro}{\@@_debug_label_data:N} +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_debug_label_data:N #1 { + \iow_term:x{Code~ labels~ for~ sorting:} + \iow_term:x{~ \seq_use:Nnnn\l_@@_labels_seq {~and~}{,~}{~and~} } % fix name! + \iow_term:x{^^J Data~ structure~ for~ label~ rules:} + \prop_map_inline:Nn #1 + { + \iow_term:x{~ ##1~ =~ \tl_use:c{ \@@_tl_csname:n {##1} }~ ->~ + \seq_use:cnnn{ \@@_seq_csname:n {##1} }{~->~}{~->~}{~->~} + } + } + \iow_term:x{} +} +% \end{macrocode} +% \end{macro} + + + +% \begin{macro}{\hook_log:n} +% This writes out information about the hook given in its argument +% onto the terminal and the \texttt{.log} file. +% \begin{macrocode} +\cs_new_protected:Npn \hook_log:n #1 + { + \exp_args:Nx \@@_log:n + { \@@_parse_label_default:nn {#1} { top-level } } + } +\cs_new_protected:Npn \@@_log:n #1 + { + \iow_term:x{^^JThe~ hook~ '#1':} +% \end{macrocode} +% +% \begin{macrocode} + \hook_if_exist:nF {#1} + { \iow_term:x {~Hook~ is~ not~ declared!} } + \@@_if_exist:nTF {#1} + { + \iow_term:x{~Code~ chunks:} + \prop_if_empty:cTF {g_@@_#1_code_prop} + { \iow_term:x{\@spaces ---} } + { + \prop_map_inline:cn {g_@@_#1_code_prop} + { \iow_term:x{\@spaces ##1~ ->~ \tl_to_str:n{##2} } } + } +% \end{macrocode} +% +% \begin{macrocode} + \iow_term:x{~Extra~ code~ next~ invocation:} + \iow_term:x{\@spaces + \tl_if_empty:cTF { g_@@_#1_next_code_tl } + {---} {->~ \str_use:c{g_@@_#1_next_code_tl} } } +% \end{macrocode} +% +% \fmi{This is currently only displaying the local rules, but it +% should also show the matching global rules!} +% +% \begin{macrocode} + \iow_term:x{~Rules:} + \prop_if_empty:cTF {g_@@_#1_rules_prop} + { \iow_term:x{\@spaces ---} } + { \prop_map_inline:cn {g_@@_#1_rules_prop} + { \iow_term:x{\@spaces ##1~ with~ relation~ ##2} } + } +% \end{macrocode} +% +% \begin{macrocode} + \hook_if_exist:nT {#1} + { \iow_term:x { ~Execution~ order + \prop_if_empty:cTF {g_@@_#1_rules_prop} + { \@@_if_reversed:nT {#1} + { ~ (after~ reversal) } + } + { ~ (after~ + \@@_if_reversed:nT {#1} {reversal~ and~} + applying~ rules) + } + : + } + \iow_term:x { \@spaces + \clist_if_empty:cTF{g_@@_#1_labels_clist} + {not~ set~ yet} + { \clist_use:cnnn {g_@@_#1_labels_clist} + { ,~ } { ,~ } { ,~ } } + } + } + } + { \iow_term:n { ~The~hook~is~empty. } } + \iow_term:n { } + } +% \end{macrocode} +% +% \end{macro} + + + +% \subsection{Specifying code for next invocation} +% +% +% +% +% +% \begin{macro}{\hook_gput_next_code:nn} +% +% \begin{macrocode} +\cs_new_protected:Npn \hook_gput_next_code:nn #1 + { + \exp_args:Nx \@@_gput_next_code:nn + { \@@_parse_label_default:nn {#1} { top-level } } + } +\cs_new_protected:Npn \@@_gput_next_code:nn #1 #2 + { + \@@_declare:n {#1} + \hook_if_exist:nTF {#1} + { \@@_gput_next_do:nn {#1} {#2} } + { \@@_try_declaring_generic_next_hook:nn {#1} {#2} } + } +\cs_new_protected:Npn \@@_gput_next_do:nn #1 #2 + { + \tl_gput_right:cn { g_@@_#1_next_code_tl } + { #2 \tl_gclear:c { g_@@_#1_next_code_tl } } + } +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Using the hook} +% +% \begin{macro}{\hook_use:n} +% \begin{macro}[EXP]{\@@_use_initialized:n} +% \begin{macro}{\@@_preamble_hook:n} +% \cs{hook_use:n} as defined here is used in the preamble, where +% hooks aren't initialized by default. \cs{@@_use_initialized:n} is +% also defined, which is the non-\tn{protected} version for use within +% the document. Their definition is identical, except for the +% \cs{@@_preamble_hook:n} (which wouldn't hurt in the expandable +% version, but it would be an unnecessary extra expansion). +% +% \cs{@@_use_initialized:n} holds the expandable definition while in +% the preamble. \cs{@@_preamble_hook:n} initializes the hook in the +% preamble, and is redefined to \cs{use_none:n} at |\begin{document}|. +% +% Both versions do the same internally: check if the hook exist as +% given, and if so use it as quickly as possible. If it doesn't +% exist, the a call to \cs{@@_use:wn} checks for file hooks. +% +% At |\begin{document}|, all hooks are initialized, and any change in +% them causes an update, so \cs{hook_use:n} can be made expandable. +% This one is better not protected so that it can expand into nothing +% if containing no code. Also important in case of generic hooks that +% we do not generate a \cs{relax} as a side effect of checking for a +% csname. In contrast to the \TeX{} low-level +% \verb=\csname ...\endcsname= construct \cs{tl_if_exist:c} is +% careful to avoid this. +% \begin{macrocode} +\cs_new_protected:Npn \hook_use:n #1 + { + \tl_if_exist:cTF { g_@@_#1_code_tl } + { + \@@_preamble_hook:n {#1} + \cs:w g_@@_#1_code_tl \cs_end: + } + { \@@_use:wn #1 / \s_@@_mark {#1} } + } +\cs_new:Npn \@@_use_initialized:n #1 + { + \tl_if_exist:cTF { g_@@_#1_code_tl } + { \cs:w g_@@_#1_code_tl \cs_end: } + { \@@_use:wn #1 / \s_@@_mark {#1} } + } +\cs_new_protected:Npn \@@_preamble_hook:n #1 + { \@@_initialize_hook_code:n {#1} } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[EXP]{\@@_use:wn} +% \begin{macro}{\@@_try_file_hook:n,\@@_if_exist_use:n} +% \cs{@@_use:wn} does a quick check to test if the current hook is a +% file hook: those need a special treatment. If it is not, the hook +% does not exist. If it is, then \cs{@@_try_file_hook:n} is called, +% and checks that the current hook is a file-specific hook using +% \cs{@@_if_file_hook:wTF}. If it's not, then it's a generic |file/| +% hook and is used if it exist. +% +% If it is a file-specific hook, it passes through the same +% normalization as during declaration, and then it is used if defined. +% \cs{@@_if_exist_use:n} checks if the hook exist, and calls +% \cs{@@_preamble_hook:n} if so, then uses the hook. +% \begin{macrocode} +\cs_new:Npn \@@_use:wn #1 / #2 \s_@@_mark #3 + { + \str_if_eq:nnTF {#1} { file } + { \@@_try_file_hook:n {#3} } + { } % Hook doesn't exist + } +\cs_new_protected:Npn \@@_try_file_hook:n #1 + { + \@@_if_file_hook:wTF #1 / / \s_@@_mark + { + \exp_args:Ne \@@_if_exist_use:n + { \exp_args:Ne \@@_file_hook_normalise:n {#1} } + } + { \@@_if_exist_use:n {#1} } % file/ generic hook (e.g. file/before) + } +\cs_new_protected:Npn \@@_if_exist_use:n #1 + { + \tl_if_exist:cT { g_@@_#1_code_tl } + { + \@@_preamble_hook:n {#1} + \cs:w g_@@_#1_code_tl \cs_end: + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\hook_use_once:n} +% For hooks that can and should be used only once we have a special +% use command that remembers the hook name in +% \cs{g_@@_execute_immediately_clist}. This has the effect that any +% further code added to the hook is executed immediately rather +% than stored in the hook. +% \begin{macrocode} +\cs_new_protected:Npn \hook_use_once:n #1 + { + \tl_if_exist:cT { g_@@_#1_code_tl } + { + \clist_gput_left:Nn \g_@@_execute_immediately_clist {#1} + \hook_use:n {#1} + } + } +% \end{macrocode} +% \end{macro} + +% \subsection{Querying a hook} +% +% Simpler data types, like token lists, have three possible states; they +% can exist and be empty, exist and be non-empty, and they may not +% exist, in which case emptiness doesn't apply (though +% \cs{tl_if_empty:N} returns false in this case). +% +% Hooks are a bit more complicated: they have four possible states. +% A hook may exist or not, and either way it may or may not be empty +% (even a hook that doesn't exist may be non-empty). +% +% A hook is said to be empty when no code was added to it, either to +% its permanent code pool, or to its ``next'' token list. The hook +% doesn't need to be declared to have code added to its code pool +% (it may happen that a package $A$ defines a hook \hook{foo}, but +% it's loaded after package $B$, which adds some code to that hook. +% In this case it is important that the code added by package $B$ is +% remembered until package $A$ is loaded). +% +% A hook is said to exist when it was declared with \cs{hook_new:n} or +% some variant thereof. +% +% \begin{macro}[pTF]{\hook_if_empty:n} +% Test if a hook is empty (that is, no code was added to that hook). +% A hook being empty means that \emph{both} its +% \cs[no-index]{g_@@_\meta{hook}_code_prop} and its +% \cs[no-index]{g_@@_\meta{hook}_next_code_tl} are empty. +% \begin{macrocode} +\prg_new_conditional:Npnn \hook_if_empty:n #1 { p , T , F , TF } + { + \@@_if_exist:nTF {#1} + { + \bool_lazy_and:nnTF + { \prop_if_empty_p:c { g_@@_#1_code_prop } } + { \tl_if_empty_p:c { g_@@_#1_next_code_tl } } + { \prg_return_true: } + { \prg_return_false: } + } + { \prg_return_true: } + } +% \end{macrocode} +% \end{macro} + +% \begin{macro}[pTF]{\hook_if_exist:n} +% A canonical way to test if a hook exists. A hook exists if the +% token list that stores the sorted code for that hook, +% \cs[no-index]{g_@@_\meta{hook}_code_tl}, exists. The property list +% \cs[no-index]{g_@@_\meta{hook}_code_prop} cannot be used here +% because often it is necessary to add code to a hook without knowing +% if such hook was already declared, or even if it will ever be +% (for example, in case the package that defines it isn't loaded). +% \begin{macrocode} +\prg_new_conditional:Npnn \hook_if_exist:n #1 { p , T , F , TF } + { + \tl_if_exist:cTF { g_@@_#1_code_tl } + { \prg_return_true: } + { \prg_return_false: } + } +% \end{macrocode} +% \end{macro} + +% \begin{macro}[pTF]{\@@_if_exist:n} +% An internal check if the hook has already been declared with +% \cs{@@_declare:n}. This means that the hook was already used somehow +% (a code chunk or rule was added to it), but it still wasn't declared +% with \cs{hook_new:n}. +% \begin{macrocode} +\prg_new_conditional:Npnn \@@_if_exist:n #1 { p , T , F , TF } + { + \prop_if_exist:cTF { g_@@_#1_code_prop } + { \prg_return_true: } + { \prg_return_false: } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[pTF]{\@@_if_reversed:n} +% An internal conditional that checks if a hook is reversed. +% \begin{macrocode} +\prg_new_conditional:Npnn \@@_if_reversed:n #1 { p , T , F , TF } + { + \if_int_compare:w \cs:w g_@@_#1_reversed_tl \cs_end: 1 < 0 \exp_stop_f: + \prg_return_true: + \else: + \prg_return_false: + \fi: + } +% \end{macrocode} +% \end{macro} + + +% \begin{macro}{\g_@@_execute_immediately_clist} +% List of hooks that from no on should not longer receive code. +% \begin{macrocode} +\clist_new:N \g_@@_execute_immediately_clist +% \end{macrocode} +% \end{macro} +% +% \subsection{Messages} +% +% \begin{macrocode} +\msg_new:nnnn { hooks } { labels-incompatible } + { + Labels~`#1'~and~`#2'~are~incompatible + \str_if_eq:nnF {#3} {??} { ~in~hook~`#3' } .~ + \int_compare:nNnT {#4} = { 1 } + { The~code~for~both~labels~will~be~dropped. } + } + { + LaTeX~found~two~incompatible~labels~in~the~same~hook.~ + This~indicates~an~incompatibility~between~packages. + } +\msg_new:nnn { hooks } { empty-label } + { Empty~code~label~\msg_line_context:.~Using~`#1'~instead. } +% \end{macrocode} +% +% \subsection{\LaTeXe{} package interface commands} +% + + +% \begin{macro}{\NewHook,\NewReversedHook,\NewMirroredHookPair} +% Declaring new hooks \ldots +% \begin{macrocode} +\NewDocumentCommand \NewHook { m }{ \hook_new:n {#1} } +\NewDocumentCommand \NewReversedHook { m }{ \hook_new_reversed:n {#1} } +\NewDocumentCommand \NewMirroredHookPair { mm }{ \hook_new_pair:nn {#1}{#2} } +% \end{macrocode} +% \end{macro} + +% \begin{macro}{\AddToHook} +% +% \begin{macrocode} +\NewDocumentCommand \AddToHook { m o +m } + { + \clist_if_in:NnTF \g_@@_execute_immediately_clist {#1} + {#3} + { \hook_gput_code:nnn {#1} {#2} {#3} } + } +% \end{macrocode} +% \end{macro} + +% \begin{macro}{\AddToHookNext} +% +% \begin{macrocode} +\NewDocumentCommand \AddToHookNext { m +m } + { \hook_gput_next_code:nn {#1} {#2} } +% \end{macrocode} +% \end{macro} + + +% \begin{macro}{\RemoveFromHook} +% +% \begin{macrocode} +\NewDocumentCommand \RemoveFromHook { m o } + { \hook_gremove_code:nn {#1} {#2} } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\DeclareDefaultHookLabel} +% \begin{macro}{\@@_curr_name_push:n,\@@_curr_name_pop:} +% The token list \cs{g_@@_hook_curr_name_tl} stores the name of the +% current package/file to be used as label for hooks. +% Providing a consistent interface is tricky, because packages can +% be loaded within packages, and some packages may not use +% \cs{DeclareDefaultHookLabel} to change the default label (in which case +% \cs{@currname} is used, if set). +% +% To pull that off, we keep a stack that contains the default label +% for each level of input. The bottom of the stack contains the +% default label for the top-level. Since the string \verb|top-level| +% is hardcoded, here this item of the stack is empty. Also, since +% we're in an input level, add \verb|lthooks| to the stack as well. +% This stack should never go empty, so we loop through \LaTeXe's +% file name stack, and add empty entries to \cs{g_@@_name_stack_seq} +% for each item in that stack. The last item is the \verb|top-level|, +% which also gets an empty entry. +% +% Also check for the case we're loading \texttt{lthooks} in the +% \LaTeXe{} kernel. In that case, \cs{@currname} isn't \verb|lthooks| +% and just the top-level is added to the stack as an empty entry. +% \begin{macrocode} +\str_if_eq:VnTF \@currname { lthooks } + { + \seq_gpush:Nn \g_@@_name_stack_seq { lthooks } + \cs_set_protected:Npn \@@_tmp:w #1 #2 #3 + { + \quark_if_recursion_tail_stop:n {#1} + \seq_gput_right:Nn \g_@@_name_stack_seq { } + \@@_tmp:w + } + \exp_after:wN \@@_tmp:w + \@currnamestack + \q_recursion_tail \q_recursion_tail + \q_recursion_tail \q_recursion_stop + } + { \seq_gpush:Nn \g_@@_name_stack_seq { } } +% \end{macrocode} +% +% Two commands keep track of the stack: when a file is input, +% \cs{@@_curr_name_push:n} pushes an (empty by default) label to the +% stack: +% \begin{macrocode} +\cs_new_protected:Npn \@@_curr_name_push:n #1 + { + \seq_gpush:Nn \g_@@_name_stack_seq {#1} + \tl_gset:Nn \g_@@_hook_curr_name_tl {#1} + } +% +% \end{macrocode} +% and when an input is over, the topmost item of the stack is popped, +% since the label will not be used again, and \cs{g_@@_hook_curr_name_tl} +% is updated to the now topmost item of the stack: +% \begin{macrocode} +\cs_new_protected:Npn \@@_curr_name_pop: + { + \seq_gpop:NN \g_@@_name_stack_seq \l_@@_return_tl + \seq_get:NNTF \g_@@_name_stack_seq \l_@@_return_tl + { \tl_gset_eq:NN \g_@@_hook_curr_name_tl \l_@@_return_tl } + { \ERROR_should_not_happen } + } +% \end{macrocode} +% +% The token list \cs{g_@@_hook_curr_name_tl} is but a mirror of the top +% of the stack. +% +% Now define a wrapper that replaces the top of the stack with the +% argument, and updates \cs{g_@@_hook_curr_name_tl} accordingly. +% \begin{macrocode} +\NewDocumentCommand \DeclareDefaultHookLabel { m } + { + \seq_gpop:NN \g_@@_name_stack_seq \l_@@_return_tl + \@@_curr_name_push:n {#1} + } +% \begin{macrocode} +% +% The push and pop macros are injected in \cs{@pushfilename} and +% \cs{@popfilename} so that they correctly keep track of the label.s +% \begin{macrocode} +% TODO! \pho{Properly integrate in the kernel} +\tl_gput_left:Nn \@pushfilename { \@@_curr_name_push:n { } } +\tl_gput_left:Nn \@popfilename { \@@_curr_name_pop: } +% TODO! \pho{Properly integrate in the kernel} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% +% +% \begin{macro}{\UseHook} +% Avoid the overhead of \pkg{xparse} and its protection that we +% don't want here (since the hook should vanish without trace if empty)! +% \begin{macrocode} +\newcommand \UseHook { \hook_use:n } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\UseOneTimeHook} +% +% \begin{macrocode} +\cs_new_protected:Npn \UseOneTimeHook { \hook_use_once:n } +% \end{macrocode} +% \end{macro} + + + +% \begin{macro}{\ShowHook} +% +% \begin{macrocode} +\cs_new_protected:Npn \ShowHook { \hook_log:n } +% \end{macrocode} +% \end{macro} + +% \begin{macro}{\DebugHookOn,\DebugHookOff} +% +% \begin{macrocode} +\cs_new_protected:Npn \DebugHookOn { \hook_debug_on: } +\cs_new_protected:Npn \DebugHookOff { \hook_debug_off: } +% \end{macrocode} +% \end{macro} + + + +% \begin{macro}{\DeclareHookRule} +% +% \begin{macrocode} +\NewDocumentCommand \DeclareHookRule { m m m m } +{ \hook_gset_rule:nnnn {#1}{#2}{#3}{#4} } +% \end{macrocode} +% \end{macro} + +% \begin{macro}{\DeclareDefaultHookRule} +% This declaration is only supported before \verb=\begin{document}=. +% \begin{macrocode} +\NewDocumentCommand \DeclareDefaultHookRule { m m m } + { \hook_gset_rule:nnnn {??}{#1}{#2}{#3} } +\@onlypreamble\DeclareDefaultHookRule +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\ClearHookRule} +% A special setup rule that removes an existing relation. +% Basically {@@_rule_gclear:nnn} plus fixing the property list for debugging. +% \fmi{Need an L3 interface, or maybe it should get dropped} +% \begin{macrocode} +\NewDocumentCommand \ClearHookRule { m m m } +{ \hook_gset_rule:nnnn {#1}{#2}{unrelated}{#3} } +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\IfHookExistTF,\IfHookEmptyTF} +% \begin{macrocode} +\NewExpandableDocumentCommand \IfHookExistTF { m } + { \hook_if_exist:nTF {#1} } +\NewExpandableDocumentCommand \IfHookEmptyTF { m } + { \hook_if_empty:nTF {#1} } +% \end{macrocode} +% \end{macro} + + + + +% \begin{macro}{\AtBeginDocument} +% +% \begin{macrocode} +\renewcommand\AtBeginDocument{\AddToHook{begindocument}} +% \end{macrocode} +% \end{macro} + +% \begin{macro}{\AtEndDocument} +% +% \begin{macrocode} +\renewcommand\AtEndDocument {\AddToHook{enddocument}} +%\renewcommand\AtEndDocument {\AddToHook{env/document/end}} % alternative impl +% \end{macrocode} +% +% \end{macro} + + + +% \subsection{Set up existing \LaTeXe{} hooks} +% +% As we are in a package calling \cs{NewHook} would label any +% already set up hook code under the package name, but we want it +% under the name \hook{top-level} so we pretend that \cs{@currname} +% is empty. +% \begin{macrocode} +\begingroup + \def\@currname{} +% \end{macrocode} +% +% \begin{macrocode} + \NewHook{begindocument} + \NewHook{enddocument} +% \end{macrocode} +% We need to initialize the mechanism at \verb=\begin{document}= +% but obviously before everything else, so we sneak\footnote{This +% needs to move to \cs{document} directly.} +% \cs{@@_initialize_all:} into the \LaTeXe{} hook name. +% +% We can't use \cs{tl_gput_left:Nn} because that complains about +% \cs{@begindocumenthook} not starting with \cs{g_} so we do this +% through the backdoor. +% \begin{macrocode} +% \tex_global:D\tl_put_left:Nn \@begindocumenthook +% {\@@_initialize_all:} +% \end{macrocode} +% There aren't many other hooks at the moment: +% \begin{macrocode} + \NewHook{rmfamily} + \NewHook{sffamily} + \NewHook{ttfamily} + \NewHook{defaultfamily} +% \end{macrocode} +% Not checked what this one does and whether it should be there (or +% is a real ``hook''. +% \begin{macrocode} + \NewHook{documentclass} +% \end{macrocode} +% +% \begin{macrocode} +\endgroup +% \end{macrocode} +% +% +% +% \section{Generic hooks for environments} +% +% +% \begin{macrocode} +\let\begin\relax % avoid redeclaration message +% \end{macrocode} +% +% \begin{macrocode} +\DeclareRobustCommand*\begin[1]{% + \UseHook{env/#1/before}% + \@ifundefined{#1}% + {\def\reserved@a{\@latex@error{Environment~#1~undefined}\@eha}}% + {\def\reserved@a{\def\@currenvir{#1}% + \edef\@currenvline{\on@line}% + \@execute@begin@hook{#1}% + \csname #1\endcsname}}% + \@ignorefalse + \begingroup\@endpefalse\reserved@a} +% \end{macrocode} +% +% Before the \cs{document} code is executed we have to first undo +% the \cs{endgroup} as there should be none for this environment to +% avoid that changes on top-level unnecessarily go to \TeX's +% savestack, and we have to initialize all hooks in the hook system. +% So we need to test for this environment name. But once it has be +% found all this testing is no longer needed and so we redefine +% \cs{@execute@begin@hook} to simply use the hook +% \begin{macrocode} +\def\@execute@begin@hook #1{% + \expandafter\ifx\csname #1\endcsname\document + \endgroup + \gdef\@execute@begin@hook##1{\UseHook{env/##1/begin}}% + \@@_initialize_all: + \@execute@begin@hook{#1}% +% \end{macrocode} +% If this is an environment before \verb=\begin{document}= we just +% run the hook. +% \begin{macrocode} + \else + \UseHook{env/#1/begin}% + \fi +} +% \end{macrocode} +% +% \begin{macrocode} +\@namedef{end~}#1{% + \UseHook{env/#1/end}% + \csname end#1\endcsname\@checkend{#1}% + \expandafter\endgroup\if@endpe\@doendpe\fi + \UseHook{env/#1/after}% + \if@ignore\@ignorefalse\ignorespaces\fi}% +% \end{macrocode} +% Version that fixes tlb3722 but the change should perhaps be made in +% \pkg{tabularx} instead. +% \begin{macrocode} +\@namedef{end~}#1{% +\romannumeral +\IfHookEmptyTF{env/#1/end}% + {\expandafter\z@}% + {\z@\UseHook{env/#1/end}}% +\csname end#1\endcsname\@checkend{#1}% +\expandafter\endgroup\if@endpe\@doendpe\fi +\UseHook{env/#1/after}% +\if@ignore\@ignorefalse\ignorespaces\fi}% +% \end{macrocode} +% +% +% +% We provide 4 high-level hook interfaces directly, the others only when +% etoolbox is loaded +% \begin{macrocode} +\newcommand\AtBeginEnvironment[1] {\AddToHook{env/#1/begin}} +\newcommand\AtEndEnvironment[1] {\AddToHook{env/#1/end}} +\newcommand\BeforeBeginEnvironment[1]{\AddToHook{env/#1/before}} +\newcommand\AfterEndEnvironment[1] {\AddToHook{env/#1/after}} +% \end{macrocode} +% +% +% +% +% +% +% +% +% +% +% +% \section{Generic hooks for file loads} +% +% +% +% +% +% +% +% \section{Hooks in \cs{begin} document} +% +% Can't have \texttt{@{}@} notation here as this is \LaTeXe{} code +% \ldots{} and makes for puzzling errors if the double \texttt{@} +% signs get substituted. +% \begin{macrocode} +%<@@=> +\ExplSyntaxOff +% \end{macrocode} +% +% The \hook{begindocument} hook was already set up earlier, here is now +% the additional one (which was originally from the \pkg{etoolbox} +% package under the name \texttt{afterpreamble}. +% \begin{macrocode} +\NewHook{begindocument/end} +% \end{macrocode} +% +% + +% \begin{macro}{\document} +% +% \begin{macrocode} +\def\document{% +% \end{macrocode} +% We do cancel the grouping as part of the \cs{begin} handling +% (this is now done inside \cs{begin} instead) so that the +% \hook{env/\meta{env}/begin} hook is not hidden inside \cs{begingroup} +% \texttt{...} \cs{endgroup}. +% \begin{macrocode} +% \endgroup +% \end{macrocode} +% +% \begin{macrocode} + \@kernel@after@env@document@begin +% \end{macrocode} +% +% Added hook to load \textsf{l3backend} code: +% \begin{macrocode} + \@expl@sys@load@backend@@ + \ifx\@unusedoptionlist\@empty\else + \@latex@warning@no@line{Unused global option(s):^^J% + \@spaces[\@unusedoptionlist]}% + \fi + \@colht\textheight + \@colroom\textheight \vsize\textheight + \columnwidth\textwidth + \@clubpenalty\clubpenalty + \if@twocolumn + \advance\columnwidth -\columnsep + \divide\columnwidth\tw@ \hsize\columnwidth \@firstcolumntrue + \fi + \hsize\columnwidth \linewidth\hsize + \begingroup\@floatplacement\@dblfloatplacement + \makeatletter\let\@writefile\@gobbletwo + \global \let \@multiplelabels \relax + \@input{\jobname.aux}% + \endgroup + \if@filesw + \immediate\openout\@mainaux\jobname.aux + \immediate\write\@mainaux{\relax}% + \fi + \process@table + \let\glb@currsize\@empty % Force math initialization. + \normalsize + \everypar{}% + \ifx\normalsfcodes\@empty + \ifnum\sfcode`\.=\@m + \let\normalsfcodes\frenchspacing + \else + \let\normalsfcodes\nonfrenchspacing + \fi + \fi + \ifx\document@default@language\m@ne + \chardef\document@default@language\language + \fi + \@noskipsecfalse + \let \@refundefined \relax +% \end{macrocode} +% +% \begin{macrocode} +% \let\AtBeginDocument\@firstofone +% \@begindocumenthook + \UseOneTimeHook{begindocument}% + \@kernel@after@begindocument +% \end{macrocode} +% +% \begin{macrocode} + \ifdim\topskip<1sp\global\topskip 1sp\relax\fi + \global\@maxdepth\maxdepth + \global\let\@begindocumenthook\@undefined + \ifx\@listfiles\@undefined + \global\let\@filelist\relax + \global\let\@addtofilelist\@gobble + \fi + \gdef\do##1{\global\let ##1\@notprerr}% + \@preamblecmds + \global\let \@nodocument \relax + \global\let\do\noexpand +% \end{macrocode} +% +% \begin{macrocode} + \UseOneTimeHook{begindocument/end}% + \ignorespaces} +% \end{macrocode} +% +% \begin{macrocode} +\let\@kernel@after@begindocument\@empty +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\@kernel@after@env@document@begin,\@kernel@hook@begindocument} +% +% \begin{macrocode} +\edef \@kernel@after@env@document@begin{% + \let\expandafter\noexpand\csname + g__hook_env/document/begin_code_tl\endcsname + \noexpand\@empty} +% \end{macrocode} +% \begin{macrocode} +\let\@kernel@hook@begindocument\@empty +% \end{macrocode} +% +% \end{macro} +% +% +% \section{Hooks in \cs{enddocument}} +% +% +% +% The \hook{enddocument} hook was already set up earlier, here are now +% the additional ones: +% \begin{macrocode} +\NewHook{enddocument/afterlastpage} +\NewHook{enddocument/afteraux} +\NewHook{enddocument/info} +\NewHook{enddocument/end} +% \end{macrocode} + + + +% \begin{macro}{\enddocument} +% +% +% \begin{macrocode} +\def\enddocument{% + \UseHook{enddocument}% + \@kernel@after@enddocument + \@checkend{document}% + \clearpage + \UseHook{enddocument/afterlastpage}% + \@kernel@after@enddocument@afterlastpage + \begingroup + \if@filesw + \immediate\closeout\@mainaux + \let\@setckpt\@gobbletwo + \let\@newl@bel\@testdef + \@tempswafalse + \makeatletter \@@input\jobname.aux + \fi + \UseHook{enddocument/afteraux}% +% \end{macrocode} +% Next hook is expect to contain only code for writing info +% messages on the terminal. +% \begin{macrocode} + \UseHook{enddocument/info}% + \endgroup + \UseHook{enddocument/end}% + \deadcycles\z@\@@end} +% \end{macrocode} +% The two kernel hooks above are used by the shipout code. +% \begin{macrocode} +\let\@kernel@after@enddocument\@empty +\let\@kernel@after@enddocument@afterlastpage\@empty +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\@enddocument@kernel@warnings} +% +% \begin{macrocode} +\def\@enddocument@kernel@warnings{% + \ifdim \font@submax >\fontsubfuzz\relax + \@font@warning{Size substitutions with differences\MessageBreak + up to \font@submax\space have occurred.\@gobbletwo}% + \fi + \@defaultsubs + \@refundefined + \if@filesw + \ifx \@multiplelabels \relax + \if@tempswa + \@latex@warning@no@line{Label(s) may have changed. + Rerun to get cross-references right}% + \fi + \else + \@multiplelabels + \fi + \fi +} +% \end{macrocode} +% +% \begin{macrocode} +\AddToHook{enddocument/info}[kernel/filelist]{\@dofilelist} +\AddToHook{enddocument/info}[kernel/warnings]{\@enddocument@kernel@warnings} +\DeclareHookRule{enddocument/info}{kernel/filelist}{before}{kernel/warnings} +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Adjusting at \pkg{atveryend} interfaces} +% +% With the new hook management all of \pkg{atveryend} is taken care +% of. +% +% We therefore prevent the package from loading: +% \begin{macrocode} +\expandafter\let\csname ver@atveryend.sty\endcsname\fmtversion +% \end{macrocode} +% +% +% Here are new definitions for its interfaces now pointing to the +% hooks in \cs{enddocument} +% \begin{macrocode} +\newcommand\AfterLastShipout {\AddToHook{enddocument/afterlastpage}} +\newcommand\AtVeryEndDocument {\AddToHook{enddocument/afteraux}} +% \end{macrocode} +% Next one is a bit of a fake, but the result should normally be as +% expected. If not one needs to add a rule to sort the code chunks +% in \hook{enddocument/info}. +% \begin{macrocode} +\newcommand\AtEndAfterFileList{\AddToHook{enddocument/info}} +% \end{macrocode} +% +% \begin{macrocode} +\newcommand\AtVeryVeryEnd {\AddToHook{enddocument/end}} +% \end{macrocode} + +% \begin{macro}{\BeforeClearDocument} +% This one is the only one we don't implement or rather don't have +% a dedicated hook in the code. +% \begin{macrocode} +\ExplSyntaxOn +\newcommand\BeforeClearDocument[1] + { \AtEndDocument{#1} + \@DEPRECATED{BeforeClearDocument \tl_to_str:n{#1}} + } +\cs_new:Npn\@DEPRECATED #1 + {\iow_term:x{======~DEPRECATED~USAGE~#1~==========}} +% \end{macrocode} +% +% \begin{macrocode} +\ExplSyntaxOff +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%</2ekernel> +% \end{macrocode} + +% +% \section{A package version of the code for testing} +% + +% \begin{macrocode} +%<*package> +% \end{macrocode} + + + +% \begin{macrocode} +\RequirePackage{xparse} +\ProvidesExplPackage{lthooks}{\lthooksdate}{\lthooksversion} + {Hook management interface for LaTeX2e} +% \end{macrocode} +% +% +% \subsection{Core hook management code (kernel part)} +% +% This should run in older formats so we can't use +% \cs{IfFormatAtLeastTF} right now. +% \begin{macrocode} +\@ifl@t@r\fmtversion{2020/10/01} + {} + {\input{lthooks.ltx} + \input{ltshipout.ltx} + \input{ltfilehook.ltx} + } +% \end{macrocode} +% +% \subsection{Package options} +% +% For now we offer a simple debug option which turns on a lot of +% strange \cs{typeout} messages, nothing fancy. +% \begin{macrocode} +\ExplSyntaxOn +% \end{macrocode} +% +% \begin{macrocode} +\hook_debug_off: +\DeclareOption { debug } { \hook_debug_on: + \shipout_debug_on: } +% \end{macrocode} +% +% +% For now we offer a simple debug option which turns on a lot of +% strange \cs{typeout} messages, nothing fancy. +% \begin{macrocode} +\shipout_debug_off: +\DeclareOption { debug-shipout } { \shipout_debug_on: } +% \end{macrocode} +% +% \begin{macrocode} +\ProcessOptions +% \end{macrocode} +% +% +% \subsection{Temporarily patching package until changed} +% +% +% +% \pkg{filehook} support until that package is patched: +% \begin{macrocode} +\RequirePackage{filehook-ltx} +% \end{macrocode} +% +% +% +% \begin{macrocode} +%</package> +% \end{macrocode} +% +% +% +% \Finale +% + + diff --git a/Master/texmf-dist/source/latex-dev/base/lthooks.ins b/Master/texmf-dist/source/latex-dev/base/lthooks.ins new file mode 100644 index 00000000000..4218fb8b259 --- /dev/null +++ b/Master/texmf-dist/source/latex-dev/base/lthooks.ins @@ -0,0 +1,76 @@ +%% +%% This file will generate fast loadable files and documentation +%% driver files from the dtx file(s) in this package when run through +%% LaTeX or TeX. +%% +%% Copyright 2020 Frank Mittelbach +%% +%% +%% This file is part of the lthooks Bundle for LaTeX. +%% ------------------------------------------------------- +%% +%% It 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 2008 or later. +%% +%% In particular, NO PERMISSION is granted to modify the contents of this +%% file since it contains the legal notices that are placed in the files +%% it generates. +%% +%% +%% +%% --------------- start of docstrip commands ------------------ +%% +\input docstrip + +\keepsilent + +\preamble + +This is a generated file. + +Copyright 2020 Frank Mittelbach + +This file was generated from file(s) of the LaTeX `lthooks Bundle'. +-------------------------------------------------------------------------- + +It 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 file may only be distributed together with a copy of the LaTeX +`lthooks Bundle'. You may however distribute the `lthooks Bundle' +without such generated files. + +The newest sources can be found below + + https://github.com/FrankMittelbach/fmitex/ + +where one can also log issues in case there are any. + + +\endpreamble + + +\generate{\file{lthooks.ltx}{\from{lthooks.dtx}{2ekernel}}} +\generate{\file{ltshipout.ltx}{\from{ltshipout.dtx}{2ekernel}}} +\generate{\file{ltfilehook.ltx}{\from{ltfilehook.dtx}{2ekernel}}} + + +\generate{\file{structuredlog.sty}{\from{ltfilehook.dtx}{structuredlog}}} + +\generate{\file{lthooks.sty}{\from{lthooks.dtx}{package}}} + +\generate{\file{filehook-ltx.sty}{\from{ltfilehook.dtx}{filehook-draft}}} + +\generate{\file{srclfile-ltx.sty}{\from{ltfilehook.dtx}{scrlfile-draft}}} + +\endbatchfile diff --git a/Master/texmf-dist/source/latex-dev/base/ltluatex.dtx b/Master/texmf-dist/source/latex-dev/base/ltluatex.dtx index d7ca7d05ecd..2e692a993b9 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltluatex.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltluatex.dtx @@ -23,12 +23,12 @@ %<tex> \ProvidesFile\undefined\begingroup\def\ProvidesFile %<tex> #1#2[#3]{\endgroup\immediate\write-1{File: #1 #3}} %<tex>\fi -%<plain>\ProvidesFile{ltluatex.tex} +%<plain>\ProvidesFile{ltluatex.tex}% %<*driver> \ProvidesFile{ltluatex.dtx} %</driver> %<*tex> -[2020/03/07 v1.1m +[2020/06/10 v1.1n %</tex> %<plain> LuaTeX support for plain TeX (core) %<*tex> @@ -406,6 +406,14 @@ \fi % \end{macrocode} % +% \changes{v1.1n}{2020/06/10}{Define \cs{@gobble}/\cs{@firstofone} even for \LaTeX\ to allow early loading.} +% Two simple \LaTeX\ macros from |ltdefns.dtx| have to be defined here +% because ltdefns.dtx is not loaded yet when ltluatex.dtx is executed. +% \begin{macrocode} +\long\def\@gobble#1{} +\long\def\@firstofone#1{#1} +% \end{macrocode} +% % \subsection{Older \LaTeX{}/Plain \TeX\ setup} % % \begin{macrocode} @@ -521,12 +529,6 @@ \fi}% % \end{macrocode} % -% Two simple \LaTeX\ macros used in |ltlatex.sty|. -% \begin{macrocode} -\long\def\@gobble#1{} -\long\def\@firstofone#1{#1} -% \end{macrocode} -% % Fix up allocations not to clash with |etex.src|. % % \begin{macrocode} @@ -544,7 +546,6 @@ %</tex> % \end{macrocode} % -% % \subsection{Attributes} % % \begin{macro}{\newattribute} diff --git a/Master/texmf-dist/source/latex-dev/base/ltmiscen.dtx b/Master/texmf-dist/source/latex-dev/base/ltmiscen.dtx index 5fb4e77d903..c48384b8bdc 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltmiscen.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltmiscen.dtx @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltmiscen.dtx} - [2020/04/24 v1.1t LaTeX Kernel (Misc. Environments)] + [2020/05/31 v1.1u LaTeX Kernel (Misc. Environments)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltmiscen.dtx} @@ -780,33 +780,39 @@ % \begin{macrocode} %</2ekernel> %<*2ekernel|latexrelease> -%<latexrelease>\IncludeInRelease{2019/10/01}% -%<latexrelease> {\centering}{Make commands robust}% +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\centering}{Set finaldhypendemerits}% % \end{macrocode} % % \begin{macro}{\centering} +% \changes{v1.1u}{2020/05/31}{Added \cs{finalhyphendemerits} setting (gh/247)} % \begin{macrocode} \DeclareRobustCommand\centering{% \let\\\@centercr \rightskip\@flushglue\leftskip\@flushglue + \finalhyphendemerits=\z@ \parindent\z@\parfillskip\z@skip} % \end{macrocode} % \end{macro} % % \begin{macro}{\raggedright} +% \changes{v1.1u}{2020/05/31}{Added \cs{finalhyphendemerits} setting (gh/247)} % \begin{macrocode} \DeclareRobustCommand\raggedright{% \let\\\@centercr\@rightskip\@flushglue \rightskip\@rightskip + \finalhyphendemerits=\z@ \leftskip\z@skip \parindent\z@} % \end{macrocode} % \end{macro} % % \begin{macro}{\raggedleft} +% \changes{v1.1u}{2020/05/31}{Added \cs{finalhyphendemerits} setting (gh/247)} % \begin{macrocode} \DeclareRobustCommand\raggedleft{% \let\\\@centercr \rightskip\z@skip\leftskip\@flushglue + \finalhyphendemerits=\z@ \parindent\z@\parfillskip\z@skip} % \end{macrocode} % \end{macro} @@ -814,6 +820,23 @@ % \begin{macrocode} %</2ekernel|latexrelease> %<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2019/10/01}% +%<latexrelease> {\centering}{Make commands robust}% +%<latexrelease> +%<latexrelease>\DeclareRobustCommand\centering{% +%<latexrelease> \let\\\@centercr +%<latexrelease> \rightskip\@flushglue\leftskip\@flushglue +%<latexrelease> \parindent\z@\parfillskip\z@skip} +%<latexrelease>\DeclareRobustCommand\raggedright{% +%<latexrelease> \let\\\@centercr\@rightskip\@flushglue \rightskip\@rightskip +%<latexrelease> \leftskip\z@skip +%<latexrelease> \parindent\z@} +%<latexrelease>\DeclareRobustCommand\raggedleft{% +%<latexrelease> \let\\\@centercr +%<latexrelease> \rightskip\z@skip\leftskip\@flushglue +%<latexrelease> \parindent\z@\parfillskip\z@skip} +%<latexrelease>\EndIncludeInRelease +%<latexrelease> %<latexrelease>\IncludeInRelease{0000/00/00}% %<latexrelease> {\centering}{Make commands robust}% %<latexrelease> diff --git a/Master/texmf-dist/source/latex-dev/base/ltoutenc.dtx b/Master/texmf-dist/source/latex-dev/base/ltoutenc.dtx index 8831b5655f8..59c20f37700 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltoutenc.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltoutenc.dtx @@ -44,7 +44,7 @@ %<*driver> % \fi \ProvidesFile{ltoutenc.dtx} - [2020/04/22 v2.0p LaTeX Kernel (font encodings)] + [2021/07/04 v2.0q LaTeX Kernel (font encodings)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltoutenc.dtx} @@ -2869,28 +2869,70 @@ % \end{macrocode} % % LuaTeX. +% For Lua\TeX~1.10+, define a Lua function to disable any handing by the font code. +% Otherwise we reload the font without TeX ligatures. +% \changes{v2.0q}{2020/07/04}{% +% Implement \cs{remove@tlig} in Lua\TeX without font reloading} % \begin{macrocode} \def\UnicodeFontTeXLigatures{+tlig;} -% \end{macrocode} -% -% \begin{macrocode} - \def\reserved@a#1{% - \def\@remove@tlig##1{\@remove@tlig@##1\@nil#1\@nil\relax} - \def\@remove@tlig@##1#1{\@remove@tlig@@##1}} - \edef\reserved@b{\detokenize{+tlig;}} - \expandafter\reserved@a\expandafter{\reserved@b} - \def\@remove@tlig@@#1\@nil#2\relax{#1} -% \end{macrocode} -% -% \begin{macrocode} - \def\remove@tlig#1{% - \begingroup - \font\remove@tlig - \expandafter\@remove@tlig\expandafter{\fontname\font}% - \remove@tlig - \char#1\relax - \endgroup - } + \ifnum\luatexversion<110 +% \end{macrocode} +% +% \begin{macrocode} + \def\reserved@a#1{% + \def\@remove@tlig##1{\@remove@tlig@##1\@nil#1\@nil\relax} + \def\@remove@tlig@##1#1{\@remove@tlig@@##1}} + \edef\reserved@b{\detokenize{+tlig;}} + \expandafter\reserved@a\expandafter{\reserved@b} + \def\@remove@tlig@@#1\@nil#2\relax{#1} +% \end{macrocode} +% +% \begin{macrocode} + \def\remove@tlig#1{% + \begingroup + \font\remove@tlig + \expandafter\@remove@tlig\expandafter{\fontname\font}% + \remove@tlig + \char#1\relax + \endgroup + } + \else + \newluafunction\@remove@tlig@@@@ +% \end{macrocode} +% We are in the format and Lua functions can not be dumped, so we have to repeat +% the code during |\everyjob|. Therefore we first define a helper to both execute +% some code and same it for |\everyjob|: +% \begin{macrocode} + \def\now@and@everyjob#1{\toksapp\everyjob{#1}#1} +% \end{macrocode} +% Now we can define the function. Mostly we just have to insert a protected glyph +% node, which is a glyph node with subtype 256. But we have to keep track of the +% current mode to avoid inserting the glyph into a vlist. +% \begin{macrocode} + \now@and@everyjob{\directlua{ + local rawchar_func = token.create'@remove@tlig@@@@'.index + local forcehmode = tex.forcehmode + local put_next = token.put_next + local glyph_id = node.id'glyph' + local rawchar_token = token.new(rawchar_func, token.command_id'lua_call') + lua.get_functions_table()[rawchar_func] = function() + local mode = tex.nest.top.mode + if mode == 1 or mode == -1 then + put_next(rawchar_token) + return forcehmode(true) + end + local n = node.new(glyph_id, 256) + n.font = font.current() + n.char = token.scan_int() + return node.write(n) + end + token.set_lua('@remove@tlig@@@', rawchar_func, 'global', 'protected') + }} +% \end{macrocode} +% Now \verb+\remove@tlig+ can be implemented almost as in XeTeX. +% \begin{macrocode} + \def\remove@tlig#1{\@remove@tlig@@@#1\relax} + \fi % \end{macrocode} % % \begin{macrocode} diff --git a/Master/texmf-dist/source/latex-dev/base/ltshipout.dtx b/Master/texmf-dist/source/latex-dev/base/ltshipout.dtx new file mode 100644 index 00000000000..8d6150b5930 --- /dev/null +++ b/Master/texmf-dist/source/latex-dev/base/ltshipout.dtx @@ -0,0 +1,1425 @@ +% \iffalse meta-comment +% +%% File: ltshipout.dtx (C) Copyright 2020 Frank Mittelbach, LaTeX Team +% +% It may be distributed and/or modified under the conditions of the +% LaTeX Project Public License (LPPL), either version 1.3c of this +% license or (at your option) any later version. The latest version +% of this license is in the file +% +% https://www.latex-project.org/lppl.txt +% +% +% The development version of the bundle can be found below +% +% https://github.com/FrankMittelbach/... +% +% for those people who are interested or want to report an issue. +% +% \begin{macrocode} +\providecommand\ltshipoutversion{v0.9a} +\providecommand\ltshipoutdate{2020/07/15} +% \end{macrocode} +% +%<*driver> + +\documentclass{l3doc} + +% bug fix fo l3doc.cls +\ExplSyntaxOn +\cs_set_protected:Npn \__codedoc_macro_typeset_one:nN #1#2 + { + \vbox_set:Nn \l__codedoc_macro_box + { + \vbox_unpack_drop:N \l__codedoc_macro_box + \hbox { \llap { \__codedoc_print_macroname:nN {#1} #2 + \MacroFont % <----- without it the \ is in lmr10 if a link is made + \ + } } + } + \int_incr:N \l__codedoc_macro_int + } +\ExplSyntaxOff + +\EnableCrossrefs +\CodelineIndex +\begin{document} + \DocInput{ltshipout.dtx} +\end{document} +%</driver> +% +% \fi +% +% +% \long\def\fmi#1{\begin{quote}\itshape Todo: #1\end{quote}} +% +% \newcommand\hook[1]{\texttt{#1}} +% +% +% \title{The \texttt{ltshipout} package\thanks{This package has version +% \ltshipoutversion\ dated \ltshipoutdate, \copyright\ \LaTeX\ +% Project.}} +% +% \author{Frank Mittelbach} +% +% \maketitle +% +% +% \tableofcontents +% +% \section{Introduction} +% +% The code provides an interface to the \cs{shipout} primitive of +% \TeX{} which is called when a finished pages is finally +% \enquote{shipped out} to the target output file, e.g., the +% \texttt{.dvi} or \texttt{.pdf} file. +% A good portion of the code is based on ideas by Heiko Oberdiek +% implemented in his packages \pkg{atbegshi} and \pkg{atenddvi} +% even though the interfaces are somewhat +% different.\footnote{Heiko's interfaces are emulated by the kernel +% code, if a document requests his packages, so older documents +% will continue to work.} +% +% \subsection{Overloading the \cs{shipout} primitive} +% +% +% \begin{function}{\shipout} +% With this implementation \TeX's shipout primitive is no longer +% available for direct use. Instead \cs{shipout} is running some +% (complicated) code that picks up the box to be shipped out +% regardless of how that is done, i.e., as a constructed \cs{vbox} +% or \cs{hbox} or as a box register. +% +% It then stores it in a named box register. This box can then be +% manipulated through a set of hooks after which it is shipped out +% for real. +% \end{function} + +% \begin{variable}{\ShipoutBox,\l_shipout_box} +% This box register is called \cs{ShipoutBox} (alternatively available via the +% L3 name \cs{l_shipout_box}). +% \end{variable} +% + +% \begin{variable}{\l_shipout_box_ht_dim, +% \l_shipout_box_dp_dim,\l_shipout_box_wd_dim, +% \l_shipout_box_ht_plus_dp_dim} +% The shipout box dimensions are available in the L3 registers +% \cs{l_shipout_box_ht_dim}, etc.\ (there are no \LaTeXe{} +% names).\footnotemark{} These variables can be used +% inside the hook code for \hook{shipout/before}, +% \hook{shipout/foreground} and \hook{shipout/background} if needed. +% \end{variable} +% \footnotetext{Might need changing, but HO's version as strings +% is not really helpful I think).} +% +% +% +% +% \subsection{Provided hooks} +% +% \begin{variable}{shipout/before, +% shipout/foreground,shipout/background, +% shipout/firstpage, +% shipout/lastpage} +% The code offers a number of hooks into which packages (or the +% user) can add code to support different use cases. +% These are: +% \begin{description} +% \item[\hook{shipout/before}] +% +% This hook is executed after the finished page has been stored in +% \cs{ShipoutBox} / \cs{l_shipout_box}). +% It can be used to alter that box content or to discard it +% completely (see \cs{DiscardShipoutBox} below). +% +% \item[\hook{shipout/background}] +% +% This hook adds a picture environment into the background of +% the page (with the \texttt{(0,0)} coordinate in the top-left +% corner using a \cs{unitlength} of \texttt{1pt}. +% +% It should therefore only receive \cs{put} commands or other +% commands suitable in a \texttt{picture} environment and the +% vertical coordinate values would normally be +% negative. +% +% \fmi{Again, mainly \pkg{atbegshi} compatibility. Not +% sure it is best to have to always use negative +% coordinates.} +% +% Technically this is implemented by adding a zero-sized +% \cs{hbox} as the very first item into the \cs{ShipoutBox} +% containing that \texttt{picture} environment. Thus the rest of +% the box content will overprint what ever is typeset by that hook. +% +% +% \item[\hook{shipout/foreground}] +% +% This hook adds a picture environment into the foreground of +% the page (with the \texttt{(0,0)} coordinate in the top-left +% corner using a \cs{unitlength} of \texttt{1pt}. +% +% Technically this is implemented by adding a zero-sized +% \cs{hbox} as the very last item into the \cs{ShipoutBox} and +% raising it up so that it still has its \texttt{(0,0)} point in +% the top-left corner. +% But being placed after the main box content it will be typeset +% later and thus overprints it (i.e., is in the foreground). +% +% +% \item[\hook{shipout/firstpage}] +% +% The material from this hook is executed only once at the very +% beginning of the first output page. It should only contain +% \cs{special} commands needed to direct post processors +% handling the \texttt{.dvi} or \texttt{.pdf} output.\fmi{not +% sure it has to be that restrictive.} +% +% In \LaTeXe{} that was already existing but implemented as a box +% register \cs{@begindvibox}. +% \fmi{drop or at least mark the obsolete code in latex.ltx} +% +% +% \item[\hook{shipout/lastpage}] +% +% The corresponding hook to add \cs{special}s at the very end of +% the output file. It is only entered on the very last page. +% +% It may not be possible for \LaTeX{} to correctly determine which page is +% the last one without several reruns. If this happens and the +% hook is non-empty then \LaTeX{} will add an extra page to +% place the material and also request a rerun to get the correct +% placement sorted out. +% +% \end{description} +% \end{variable} +% +% As mentioned above the hook \hook{shipout/before} is executed +% first and can manipulate the prepared shipout box stored in +% \cs{ShipoutBox} or set things up for use in \cs{write} during the +% actual shipout. The other hooks are added inside hboxes to the +% box being shipped out in the following +% order: +% \begin{center} +% \begin{tabular}{ll} +% \hook{shipout/firstpage} & only on the first page \\ +% \hook{shipout/background} & \\ +% \meta{boxed content of \cs{ShipoutBox}} & \\ +% \hook{shipout/foreground} & \\ +% \hook{shipout/lastpage} & only on the last page \\ +% \end{tabular} +% \end{center} +% If any of the hooks has no code then that particular no box is +% added at that point. +% +% In a document that doesn't produce pages, e.g., only makes +% \cs{typeout}s, none of the hooks are executed (as there is no +% \cs{shipout}) not even the \hook{shipout/lastpage} hook. +% +% \begin{function}{\AtBeginDvi,\AtEndDvi} +% \cs{AtBeginDvi} is the existing \LaTeXe{} interface to fill the +% \hook{shipout/firstpage} hook. This is not really a good name +% as it is not just supporting \texttt{.dvi} but also \texttt{.pdf} +% output or \texttt{.dvx}. +% +% \cs{AtEndDvi} is the counterpart that was not available in the +% kernel but only through the package \pkg{atenddvi}. It fills the +% \hook{shipout/lastpage} hook. +% +% \fmi{better names? Any suggestions?} +% +% \end{function} +% +% \subsection{Special commands for use inside the hooks} +% +% \begin{function}{\DiscardShipoutBox,\shipout_discard_box:} +% \begin{syntax} +% \cs{AddToHookNext} \texttt{\{shipout/before\} \{...\cs{DiscardShipoutBox}...\}} +% \end{syntax} +% The \cs{DiscardShipoutBox} declaration (L3 name +% \cs{shipout_discard_box:}) +% requests that on the next +% shipout the page box is thrown away instead of being shipped to +% the \texttt{.dvi} or \texttt{.pdf} file. +% +% Typical applications wouldn't do this unconditionally, but have +% some processing logic that decides to use or not to use the page. +% +% Note that if this declaration is used directly in the document it +% may depend on the placement to which page it applies, given that +% \LaTeX{} output routine is called in an asynchronous manner! +% +% \fmi{Once we have a new mark mechanism available we can improve +% on that and make sure that the declaration applies to the page +% that contains it.} +% \end{function} +% +% In the \pkg{atbegshi} package there are a number of additional +% commands for use inside the \hook{shipout/before} hook. They +% should normally not be needed any more as one can instead simply +% add code to the hooks \hook{shipout/before}, +% \hook{shipout/background} or +% \hook{shipout/foreground}.\footnote{If that assumption turns out to +% be wrong it would be trivial to change them to public functions +% (right now they are private).} If \pkg{atbegshi} gets loaded then +% those commands become available as public functions with their original +% names as given below. +% +% +% \subsection{Information counters} +% +% +% \begin{variable}{\ReadonlyShipoutCounter,\g_shipout_readonly_int} +% \begin{syntax} +% \cs{ifnum}\cs{ReadOnlyShipoutCounter}\texttt{=...} +% \cs{int_use:N} \cs{g_shipout_readonly_int} \texttt{\% expl3 usage} +% \end{syntax} +% This integer holds the number of pages shipped out up to now +% (including the one to be shipped out when inside the output +% routine). More precisely, it is incremented only after it is +% clear that a page will be shipped out, i.e., after the +% \hook{shipout/before} hook (because that might discard the page)! + +% Just like with the \texttt{page} counter its value is +% only accurate within the output routine. In the body of the +% document it may be off by one as the output routine is called +% asynchronously! +% +% Also important: it \emph{must not} be set, only read. There are +% no provisions to prevent that but if you do, chaos will be the +% result. To emphasize this fact it is not provided as a \LaTeX{} +% counter but as a \TeX{} counter (i.e., a command), so +% \cs{Alph}\Arg{\cs{ReadonlyShipoutCounter}} etc, would not work. +% \end{variable} +% +% \begin{variable}{totalpages,\g_shipout_totalpages_int} +% \begin{syntax} +% \cs{arabic}\texttt{\{totalpages\}} +% \cs{int_use:N} \cs{g_shipout_totalpage_int} \texttt{\% expl3 usage} +% \end{syntax} +% In contrast to \cs{ReadonlyShipoutCounter}, the +% \texttt{totalpages} counter is a \LaTeX{} counter and incremented +% for each shipout attempt including those pages that are discarded +% for one or the other reason. Again \hook{shipout/before} sees +% the counter before it is incremented). +% +% Furthermore, while it is incremented for each page, its value is +% never used by \LaTeX. It can therefore be freely reset or changed by user +% code, for example, to additionally count a number of pages that +% are not build by \LaTeX\ but are added in a later part of the +% process, e.g., cover pages or picture pages made externally. +% +% Important: as this is a page-related counter its value is only +% reliable inside the output routine! +% \end{variable} +% + +% +% \subsection{Debugging shipout code} +% +% \begin{function}{\DebugShipoutOn,\DebugShipoutOff, +% \shipout_debug_on:,\shipout_debug_off:} +% \begin{syntax} +% \cs{DebugShipoutOn} +% \end{syntax} +% Turn the debugging of shipout code on or off. This displays +% changes made to the shipout data structures. \fmi{This needs +% some rationalizing and will probably not stay this way.} +% \end{function} +% +% + +% +% \section{Emulating commands from other packages} +% +% The packages in this section are no longer necessary but as they +% are used in other packages they are emulated when they are loaded +% via \cs{usepackage} or \cs{RequirePackage}. +% +% +% \subsection{Emulating \pkg{atbegshi}} +% +% +% \begin{function}{\AtBeginShipoutUpperLeft,\AtBeginShipoutUpperLeftForeground} +% \begin{syntax} +% \cs{AddToHook} \texttt{\{shipout/before\} \{...\cs{AtBeginShipoutUpperLeft}}\Arg{code}\texttt{...\}} +% \end{syntax} +% This adds a \texttt{picture} environment into the background of the shipout +% box expecting \meta{code} to contain \texttt{picture} +% commands. The same effect can be obtained by simply using kernel +% features as follows: +% \begin{quote} +% \cs{AddToHook}\texttt{\{shipout/background\}}\Arg{code} +% \end{quote} +% There is one technical difference: if +% \cs{AtBeginShipoutUpperLeft} is used several times each +% invocation is put into its own box inside the shipout box whereas +% all \meta{code} going into \hook{shipout/background} ends up +% all in the same box in the order it is added or sorted based on +% the rules for the hook chunks. +% +% \cs{AtBeginShipoutUpperLeftForeground} is similar with the +% difference that the \texttt{picture} environment is placed in the +% foreground. To model it with the kernel functions use the hook +% \hook{shipout/foreground} instead. +% \end{function} +% +% +% \begin{function}{\AtBeginShipoutAddToBox,\AtBeginShipoutAddToBoxForeground} +% \begin{syntax} +% \cs{AddToHook} \texttt{\{shipout/before\} \{...\cs{AtBeginShipoutAddToBox}}\Arg{code}\texttt{...\}} +% \end{syntax} +% These work like \cs{AtBeginShipoutUpperLeft} and +% \cs{AtBeginShipoutUpperLeftForeground} with the difference that +% \meta{code} is directly placed into an \cs{hbox} inside the +% shipout box and not surrounded by a \texttt{picture} environment. +% +% To emulate them using \hook{shipout/background} or +% \hook{shipout/foreground} you may have to wrap \meta{code} into +% a \cs{put} statement but if the code is not doing any typesetting +% just adding it to the hook should be sufficient. +% \end{function} +% + + +% \begin{function}{\AtBeginShipoutBox} +% This is the name of the shipout box as \pkg{atbegshi} knows it. +% \end{function} +% +% \begin{function}{\AtBeginShipoutInit} +% By default \pkg{atbegshi} delayed its action until +% \verb=\beg{document}=. This command was forcing it in an earlier +% place. With the new concept it does nothing. +% \end{function} +% +% \begin{function}{\AtBeginShipout,\AtBeginShipoutNext} +% \begin{syntax} +% \cs{AtBeginShipout}\Arg{code} $\equiv$ \cs{AddToHook}\texttt{\{shipout/before\}}\Arg{code} +% \cs{AtBeginShipoutNext}\Arg{code} $\equiv$ \cs{AddToHookNext}\texttt{\{shipout/before\}}\Arg{code} +% \end{syntax} +% This is equivalent to filling the \hook{shipout/before} hook +% by either using \cs{AddToHook} or \cs{AddToHookNext}, respectively. +% \end{function} +% +% \begin{function}{\AtBeginShipoutFirst,\AtBeginShipoutDiscard} +% The \pkg{atbegshi} names for \cs{AtBeginDvi} and \cs{DiscardShipoutBox}. +% \end{function} +% + + + +% \subsection{Emulating \pkg{everyshi}} +% + + +% \begin{function}{\EveryShipout} +% \begin{syntax} +% \cs{EveryShipout}\Arg{code} $\equiv$ \cs{AddToHook}\texttt{\{shipout/before\}}\Arg{code} +% \end{syntax} +% \end{function} +% +% \begin{function}{\AtNextShipout} +% \begin{syntax} +% \cs{AtNextShipout}\Arg{code} $\equiv$ \cs{AddToHookNext}\texttt{\{shipout/before\}}\Arg{code} +% \end{syntax} +% \end{function} +% + + +% \subsection{Emulating \pkg{atenddvi}} +% +% The \pkg{atenddvi} package implemented only a single command: +% \cs{AtEndDvi} and that is now available out of the box. + + + +% \subsection{Emulating \pkg{everypage}} +% +% This page takes over the original \cs{@begindvi} hook and replaces +% it. It should be all covered by the hooks offered here (details +% need checking) and thus could simply use the provided hooks +% rather than defining its own. +% +% +% +% \StopEventually{\setlength\IndexMin{200pt} \PrintIndex } +% +% +% \section{The Implementation} +% \begin{macrocode} +%<*2ekernel> +%<@@=shipout> +\ExplSyntaxOn +% \end{macrocode} +% +% +% \subsection{Debugging} +% +% \begin{macro}{\g_@@_debug_bool} +% Holds the current debugging state. +% \begin{macrocode} +\bool_new:N \g_@@_debug_bool +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\shipout_debug_on:,\shipout_debug_off:} +% \begin{macro}{\@@_debug:n} +% \begin{macro}{\@@_debug_gset:} +% Turns debugging on and off by redefining \cs{@@_debug:n}. +% \begin{macrocode} +\cs_new_eq:NN \@@_debug:n \use_none:n +\cs_new_protected:Npn \shipout_debug_on: + { + \bool_gset_true:N \g_@@_debug_bool + \@@_debug_gset: + } +\cs_new_protected:Npn \shipout_debug_off: + { + \bool_gset_false:N \g_@@_debug_bool + \@@_debug_gset: + } +\cs_new_protected:Npn \@@_debug_gset: + { + \cs_gset_protected:Npx \@@_debug:n ##1 + { \bool_if:NT \g_@@_debug_bool {##1} } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% + +% \begin{macro}{shipout/before, +% shipout/foreground,shipout/background, +% shipout/firstpage, +% shipout/lastpage} +% Declaring all hooks for the shipout code. +% \begin{macrocode} +\hook_new:n{shipout/before} +\hook_new:n{shipout/foreground} +\hook_new:n{shipout/background} +\hook_new:n{shipout/firstpage} +\hook_new:n{shipout/lastpage} +% \end{macrocode} +% \end{macro} + + + + +% \begin{macro}{\ShipoutBox,\l_shipout_box} +% The box filled with the page to be shipped out (both L3 and +% \LaTeXe{} name). +% \begin{macrocode} +\box_new:N \l_shipout_box +% \end{macrocode} +% +% \begin{macrocode} +\cs_set_eq:NN \ShipoutBox \l_shipout_box +% \end{macrocode} +% \end{macro} + + + + +% \begin{macro}{\@@_execute:} +% This is going to the be the code run by \cs{shipout}. The code +% follows closely the ideas from \pkg{atbegshi}, so not +% documenting that here for now. +% \begin{macrocode} +\cs_set:Npn\@@_execute: { + \tl_set:Nx \l_@@_group_level_tl + { \int_value:w \tex_currentgrouplevel:D } + \tex_afterassignment:D \@@_execute_test_level: + \tex_setbox:D \l_shipout_box +} +% \end{macrocode} +% \end{macro} + + +% \begin{macro}{\shipout} +% Overloading the \cs{shipout} primitive: +% \begin{macrocode} +\cs_gset_eq:NN \shipout \@@_execute: +% \end{macrocode} +% \end{macro} + + +% \begin{macro}{\l_@@_group_level_tl} +% Helper token list to record the group level at which +% \cs{@@_execute:} is encountered. \begin{macrocode} +\tl_new:N \l_@@_group_level_tl +% \end{macrocode} +% \end{macro} + + + +% \begin{macro}{\@@_execute_test_level:} +% If the group level has changed then we are still constructing +% \cs{l_shipout_box} and to continue we need to wait until the +% current group has finished, hence the \cs{tex_aftergroup:D}. +% \begin{macrocode} +\cs_new:Npn \@@_execute_test_level: { + \int_compare:nNnT + \l_@@_group_level_tl < \tex_currentgrouplevel:D + \tex_aftergroup:D + \@@_execute_cont: +} +% \end{macrocode} +% \end{macro} + + +% \begin{macro}{\@@_execute_cont:} +% When we have reached this point the shipout box has been +% processed and is available in \cs{l_shipout_box} and ready for +% real ship out (perhaps).. +% +% First we quickly check if it is void (can't happen in the +% standard \LaTeX{} output routine but \cs{shipout} might be called +% from a package that has some special processing logic). If it is +% void we aren't shipping anything out and processing ends.\footnote{In that +% case we don't reset the deadcyles, that would be up to the OR +% processing logic to do.} +% \begin{macrocode} +\cs_new:Npn \@@_execute_cont: { + \box_if_empty:NTF \l_shipout_box + { \PackageWarning{ltshipout}{Ignoring~ void~ shipout~ box} } + { +% \end{macrocode} +% Otherwise we assume that we will ship something and prepare for +% final adjustments (in particular setting the state of +% \cs{protect} while we are running the hook code). +% \begin{macrocode} + \bool_gset_false:N \g_@@_discard_bool + \set@typeset@protect +% \end{macrocode} +% We also store the current shipout box dimension in registers, so that +% they can be used in the hook code.\footnote{This is not really +% necessary as the code could access them via \cs{box_ht:N}, etc., +% but it is perhaps convenient.} +% \begin{macrocode} + \@@_get_box_size:N \l_shipout_box +% \end{macrocode} +% Then we execute the \hook{shipout/before} hook. +% \begin{macrocode} + \hook_use:n {shipout/before} +% \end{macrocode} +% In \cs{g_shipout_totalpages_int} we count all shipout attempts so +% we increment that counter already here (the other one is +% incremented later when we know for sure that we do a +% \cs{shipout}. +% +% We increment it after running the above hook so that the values +% for \cs{g_shipout_totalpages_int} and \cs{} are in sync while the +% hook is executed (in the case that totalpages isn't manually +% altered or through discarding pages that is). +% \begin{macrocode} + \int_gincr:N \g_shipout_totalpages_int +% \end{macrocode} +% The above hook might contain code that requests the page to be discarded so +% we now test for it. +% \begin{macrocode} + \bool_if:NTF \g_@@_discard_bool + { \PackageInfo{ltshipout}{Completed~ page~ discarded} + \bool_gset_false:N \g_@@_discard_bool +% \end{macrocode} +% As we are discarding the page box and not shipping anything out, +% we need to do some house cleaning and reset \TeX's deadcycles so +% that it doesn't complain about too many calls to the OR without +% any shipout. +% \begin{macrocode} + \tex_deadcycles:D \c_zero_int +% \end{macrocode} +% \fmi{In \pkg{atbegshi} the box was dropped but is that actually +% needed? Or the resetting of \cs{protect} to its kernel value?} +% \begin{macrocode} +% \group_begin: +% \box_set_eq_drop:NN \l_shipout_box \l_shipout_box +% \group_end: +% \cs_set_eq:NN \protect \exp_not:N + } +% \end{macrocode} +% Even if there was no explicit request to discard the box it is +% possible that the code for the hook \hook{shipout/before} has +% voided the box (by mistake or deliberately). We therefore test +% once more but this time make it a warning, because the best +% practice way is to use the request mechanism. +% \begin{macrocode} + { \box_if_empty:NTF \l_shipout_box + { \PackageWarning{ltshipout}{ + Shipout~ box~ was~ voided~ by~ hook,\MessageBreak + ignoring~ shipout~ box } + } +% \end{macrocode} +% Finally, if the box is still non-empty we are nearly ready to +% ship it out. +% First we increment the total page counter so that we can later +% test if we have reached the final page according to our available +% information.\footnote{Doing that earlier would be wrong because we +% might end up with the last page counted but discard and then we +% have no place to add the final objects into the output file.} +% \begin{macrocode} + { + \int_gincr:N \g_shipout_readonly_int + \@@_debug:n { + \typeout{Absolute~ page~ =~ \int_use:N \g_shipout_readonly_int + \space (target:~ \@abspage@last)} + } +% \end{macrocode} +% Then we store the box sizes again (as they may have +% changed) and then look at the hooks \hook{shipout/foreground} +% and \hook{shipout/background}. If either or both are non-empty +% we add a \texttt{picture} environment to the box (in the +% foreground and or in the background) and execute the hook code +% inside that environment. +% +% \begin{macrocode} + \@@_get_box_size:N \l_shipout_box + \@kernel@before@shipout@foreground + \hook_if_empty:nF {shipout/foreground} + { \@@_add_foreground_picture:n + { \hook_use:n {shipout/foreground} } } + \hook_if_empty:nF {shipout/background} + { \@@_add_background_picture:n + { \hook_use:n {shipout/background} } } +% \end{macrocode} +% We then run \cs{@@_execute_firstpage_hook:} that adds +% the content of the hook \hook{shipout/firstpage} to the +% start of the first page (if non-empty). It is then redefined to +% do nothing on later pages. +% \begin{macrocode} + \@@_execute_firstpage_hook: +% \end{macrocode} +% The we check if we have to add the \hook{shipout/lastpage} hook +% because we have reached the last page. This test will be false for +% all but one (and hopefully the correct) page. +% \begin{macrocode} + \int_compare:nNnT \@abspage@last = \g_shipout_readonly_int + { \hook_if_empty:nF {shipout/lastpage} + { \@@_debug:n { \typeout{Executing~ lastpage~ hook~ + on~ page~ \int_use:N \g_shipout_readonly_int } } + \_@@_add_foreground_box:n { \UseHook{shipout/lastpage} + \@kernel@after@shipout@lastpage } + } + \bool_gset_true:N \g_@@_lastpage_handled_bool + } +% \end{macrocode} +% Finally we run the actual \TeX{} primitive for shipout. As that will +% expand delayed \cs{write} statements inside the page in which +% protected commands should not expand we first change \cs{protect} +% to the appropriate definition for that case. +% \begin{macrocode} + \cs_set_eq:NN \protect \exp_not:N + \tex_shipout:D \box_use:N \l_shipout_box + } + } + } +} +% \end{macrocode} +% \end{macro} + + + +% \begin{macro}{\@kernel@after@shipout@lastpage,\@kernel@before@shipout@foreground} +% +% \begin{macrocode} +\let\@kernel@after@shipout@lastpage\@empty +\let\@kernel@before@shipout@foreground\@empty +% \end{macrocode} +% \end{macro} + + +% \begin{macro}{\@@_execute_firstpage_hook: } +% This command adds any specials into a box and adds that to the +% very beginning of the first box shipped out. After that we +% redefine it to do nothing on later pages. +% \begin{macrocode} +\cs_new:Npn \@@_execute_firstpage_hook: { +% \end{macrocode} +% Adding something to the beginning means adding it to the +% background as that layer is done first in the output. Of course +% that is only needed if the hook actually contains anything. +% \begin{macrocode} + \hook_if_empty:nF {shipout/firstpage} + { \@@_add_background_box:n { \UseHook{shipout/firstpage} } } +% \end{macrocode} +% Once we are here we change the definition to do nothing next time +% and we also change the command used to implement \cs{AtBeginDvi} +% to become a warning and not add further material to a hook that +% is never used again. +% \begin{macrocode} + \cs_gset_eq:NN \@@_execute_firstpage_hook: \prg_do_nothing: + \cs_gset:Npn \@@_add_firstpage_material:Nn ##1 ##2 { + \PackageWarning{ltshipout}{ + First~ page~ is~ already~ shipped~ out,~ ignoring\MessageBreak + \string##1 } + } +} +% \end{macrocode} +% \end{macro} + + +% \begin{macro}{\g_@@_lastpage_handled_bool} +% A boolean to signal if we have already handled the +% \hook{shipout/lastpage} hook. +% \begin{macrocode} +\bool_new:N \g_@@_lastpage_handled_bool +% \end{macrocode} +% \end{macro} + + + +% \begin{macro}{\@@_add_firstpage_material:Nn} +% This command adds material to the +% \hook{shipout/firstpage} hook. It is used in +% \cs{AtBeginDvi}, etc. The first argument is the +% command through which is it called. Initially this is ignored but +% once we are passed the first page it can be used to generate a +% warning message mentioning the right user command. +% \begin{macrocode} +\cs_new:Npn \@@_add_firstpage_material:Nn #1#2 { + \AddToHook{shipout/firstpage}{#2} +} +% \end{macrocode} +% \end{macro} + + + + + + + +% \begin{macro}{\@@_get_box_size:N} +% Store the box dimensions in dimen registers. +% \fmi{This could/should perhaps be generalized to set height depth and +% width given an arbitrary box.} +% \begin{macrocode} +\cs_new:Npn \@@_get_box_size:N #1 { + \dim_set:Nn \l_shipout_box_ht_dim { \box_ht:N #1 } + \dim_set:Nn \l_shipout_box_dp_dim { \box_dp:N #1 } + \dim_set:Nn \l_shipout_box_wd_dim { \box_wd:N #1 } + \dim_set:Nn \l_shipout_box_ht_plus_dp_dim { \l_shipout_box_ht_dim + + \l_shipout_box_dp_dim } +} +% \end{macrocode} +% \end{macro} + +% \begin{macro}{\l_shipout_box_ht_dim, +% \l_shipout_box_dp_dim,\l_shipout_box_wd_dim, +% \l_shipout_box_ht_plus_dp_dim} +% And here are the variables set by \cs{@@_get_box_size:N}. +% \begin{macrocode} +\dim_new:N \l_shipout_box_ht_dim +\dim_new:N \l_shipout_box_dp_dim +\dim_new:N \l_shipout_box_wd_dim +\dim_new:N \l_shipout_box_ht_plus_dp_dim +% \end{macrocode} +% \end{macro} + + + + + +% \begin{macro}{\g_@@_discard_bool} +% Indicate whether or not the current page box should be discarded +% \begin{macrocode} +\bool_new:N \g_@@_discard_bool +% \end{macrocode} +% \end{macro} + + + +% \begin{macro}{\l_@@_tmp_box,\l_@@_saved_badness_tl} +% We need a box for the background and foreground material and a +% token register to remember badness settings as we disable them +% during te buildup below. +% \begin{macrocode} +\box_new:N \l_@@_tmp_box +\tl_new:N \l_@@_saved_badness_tl +% \end{macrocode} +% \end{macro} + + +% \begin{macro}{\@@_add_background_box:n} +% In standard \LaTeX{} the shipout box is always a \cs{vbox} but +% here we are allow for other usage as well, in case some package +% has its own output routine. +% \begin{macrocode} +\cs_new:Npn \@@_add_background_box:n #1 +{ \@@_get_box_size:N \l_shipout_box +% \end{macrocode} +% But we start testing for a vertical box as that should be the +% normal case. +% \begin{macrocode} + \box_if_vertical:NTF \l_shipout_box + { +% \end{macrocode} +% Save current values of \cs{vfuzz} and \cs{vbadness} then change +% them to allow box manipulations without warnings. +% \begin{macrocode} + \tl_set:Nx \l_@@_saved_badness_tl + { \vfuzz=\the\vfuzz\relax + \vbadness=\the\vbadness\relax } + \vfuzz=\c_max_dim + \vbadness=\c_max_int +% \end{macrocode} +% Then we reconstruct \cs{l_shipout_box} \ldots +% \begin{macrocode} + \vbox_set_to_ht:Nnn \l_shipout_box \l_shipout_box_ht_plus_dp_dim + { +% \end{macrocode} +% \ldots{} the material in \verb=#1= is placed into a horizontal +% box with zero dimensions. +% \begin{macrocode} + \hbox_set:Nn \l_@@_tmp_box + { \l_@@_saved_badness_tl #1 } + \box_set_wd:Nn \l_@@_tmp_box \c_zero_dim + \box_set_ht:Nn \l_@@_tmp_box \c_zero_dim + \box_set_dp:Nn \l_@@_tmp_box \c_zero_dim +% \end{macrocode} +% The we typeset that box followed by whatever was in +% \cs{l_shipout_box} before (unpacked). +% \begin{macrocode} + \skip_zero:N \baselineskip + \skip_zero:N \lineskip + \skip_zero:N \lineskiplimit + \box_use:N \l_@@_tmp_box + \vbox_unpack:N \l_shipout_box +% \end{macrocode} +% The \cs{kern} ensures that the box has no depth which is +% afterwards explicitly corrected. +% \begin{macrocode} + \kern \c_zero_dim + } + \box_set_ht:Nn \l_shipout_box \l_shipout_box_ht_dim + \box_set_dp:Nn \l_shipout_box \l_shipout_box_dp_dim +% \end{macrocode} +% \fmi{The whole boxing maneuver looks a bit like overkill to me, but for +% the moment I leave.} +% \begin{macrocode} + \l_@@_saved_badness_tl + } + { +% \end{macrocode} +% A horizontal box is handled in a similar way. The last case would +% be a void box in which case we do nothing hence the missing +% \texttt{F} branch. +% \begin{macrocode} + \box_if_horizontal:NT \l_shipout_box + { + \tl_set:Nx \l_@@_saved_badness_tl + { \hfuzz=\the\hfuzz\relax + \hbadness=\the\hbadness\relax } + \hfuzz=\c_max_dim + \hbadness=\c_max_int + \hbox_set_to_wd:Nnn \l_shipout_box \l_shipout_box_wd_dim + { + \hbox_set:Nn \l_@@_tmp_box + { \l_@@_saved_badness_tl #1 } + \box_set_wd:Nn \l_@@_tmp_box \c_zero_dim + \box_set_ht:Nn \l_@@_tmp_box \c_zero_dim + \box_set_dp:Nn \l_@@_tmp_box \c_zero_dim + \box_move_up:nn + \l_shipout_box_ht_dim + { \box_use:N \l_@@_tmp_box } + \hbox_unpack:N \l_shipout_box + } + \l_@@_saved_badness_tl + } + } +} +% \end{macrocode} +% \end{macro} + + + + +% \begin{macro}{\@@_add_foreground_box:n} +% Foreground boxes are done in the same way, only the order and +% placement of boxes has to be done differently. +% \begin{macrocode} +\cs_new:Npn \@@_add_foreground_box:n #1 +{ + \box_if_vertical:NTF \l_shipout_box + { + \tl_set:Nx \l_@@_saved_badness_tl + { \vfuzz=\the\vfuzz\relax + \vbadness=\the\vbadness\relax } + \vfuzz=\c_max_dim + \vbadness=\c_max_int + \vbox_set_to_ht:Nnn \l_shipout_box \l_shipout_box_ht_plus_dp_dim + { + \hbox_set:Nn \l_@@_tmp_box + { \l_@@_saved_badness_tl #1 } + \box_set_wd:Nn \l_@@_tmp_box \c_zero_dim + \box_set_ht:Nn \l_@@_tmp_box \c_zero_dim + \box_set_dp:Nn \l_@@_tmp_box \c_zero_dim + \skip_zero:N \baselineskip + \skip_zero:N \lineskip + \skip_zero:N \lineskiplimit + \vbox_unpack:N \l_shipout_box + \kern -\l_shipout_box_ht_plus_dp_dim + \box_use:N \l_@@_tmp_box + \kern \l_shipout_box_ht_plus_dp_dim + } + \l_@@_saved_badness_tl + \box_set_ht:Nn \l_shipout_box \l_shipout_box_ht_dim + \box_set_dp:Nn \l_shipout_box \l_shipout_box_dp_dim + } + { + \box_if_horizontal:NT \l_shipout_box + { + \tl_set:Nx \l_@@_saved_badness_tl + { \hfuzz=\the\hfuzz\relax + \hbadness=\the\hbadness\relax } + \hfuzz=\c_max_dim + \hbadness=\c_max_int + \hbox_set_to_wd:Nnn \l_shipout_box \l_shipout_box_wd_dim + { + \hbox_unpack:N \l_shipout_box + \kern -\box_wd:N \l_shipout_box + \hbox_set:Nn \l_@@_tmp_box + { \l_@@_saved_badness_tl #1 } + \box_set_wd:Nn \l_@@_tmp_box \c_zero_dim + \box_set_ht:Nn \l_@@_tmp_box \c_zero_dim + \box_set_dp:Nn \l_@@_tmp_box \c_zero_dim + \box_move_up:nn { \box_ht:N \l_shipout_box } + { \box_use:N \l_@@_tmp_box } + \kern \box_wd:N \l_shipout_box + }% + \l_@@_saved_badness_tl + } + } +} +% \end{macrocode} +% \end{macro} + + + + +% \begin{macro}{\c_@@_horigin_tl,\c_@@_vorigin_tl} +% Two constants holding the offset of the top-left with respect to +% the media box. +% +% Setting the constants this way is courtesy of Bruno. +% \begin{macrocode} +\tl_gput_right:Nn \@kernel@after@begindocument { + \tl_const:Nx \c_@@_horigin_tl + { + \cs_if_exist_use:NTF \pdfvariable { horigin } + { \cs_if_exist_use:NF \pdfhorigin { 1in } } + } + \tl_const:Nx \c_@@_vorigin_tl + { + \cs_if_exist_use:NTF \pdfvariable { vorigin } + { \cs_if_exist_use:NF \pdfvorigin { 1in } } + } +} +% \end{macrocode} +% \end{macro} + + +% \begin{macro}{\@@_picture_overlay:n} +% Put the argument into a \texttt{picture} environment that doesn't take up +% any size and uses \texttt{1pt} for \cs{unitlength}. +% \fmi{Could perhaps be generalized as it might be useful elsewhere. For +% not it is not.} +% \begin{macrocode} +\cs_new:Npn \@@_picture_overlay:n #1 { + \kern -\c_@@_horigin_tl \scan_stop: + \vbox_to_zero:n { + \kern -\c_@@_vorigin_tl \scan_stop: + \unitlength 1pt \scan_stop: + \hbox_set_to_wd:Nnn \l_@@_tmp_box \c_zero_dim { \ignorespaces #1 } +% \box_set_wd:Nn \l_@@_tmp_box \c_zero_dim + \box_set_ht:Nn \l_@@_tmp_box \c_zero_dim + \box_set_dp:Nn \l_@@_tmp_box \c_zero_dim + \box_use:N \l_@@_tmp_box + \tex_vss:D + } +} +% \end{macrocode} +% \end{macro} + + +% \begin{macro}{\@@_add_background_picture:n} +% Put a \texttt{picture} env in the background of the shipout box +% with its reference point in the top-left corner. +% \begin{macrocode} +\cs_new:Npn \@@_add_background_picture:n #1 { + \@@_add_background_box:n { \@@_picture_overlay:n {#1} } +} +% \end{macrocode} +% \end{macro} + + + +% \begin{macro}{\@@_add_foreground_picture:n} +% +% Put a \texttt{picture} env in the foreground of the shipout box +% with its reference point in the top-left corner. +% \begin{macrocode} +\cs_new:Npn \@@_add_foreground_picture:n #1 { + \@@_add_foreground_box:n { \@@_picture_overlay:n {#1} } +} +% \end{macrocode} +% \end{macro} + + +% \begin{macro}{\shipout_discard:} +% Request that the next shipout box should be discarded. At the +% moment this is just setting a boolean, but we may want to augment +% this behavior that the position of the call is taken into account +% (in case \LaTeX{} looks ahead and is not using the position for +% on the next page). +% \begin{macrocode} +\cs_new:Npn \shipout_discard: { + \bool_gset_true:N \g_@@_discard_bool +} +% \end{macrocode} +% \end{macro} + + + + +% \subsection{Handling the end of job hook} + +% At the moment this is partly solved by using the existing hooks. +% But rather than putting the code into these hooks it should be +% moved to the right place directly as we shouldn't prefill hooks +% with material unless it needs to interact with other code. +% + +% +% \begin{macro}{\g_shipout_readonly_int,\ReadonlyShipoutCounter} +% We count every shipout activity that makes a page (but not those +% that are discarded) in order to know how many pages got produced. +% \begin{macrocode} +\int_new:N \g_shipout_readonly_int +% \end{macrocode} +% For \LaTeXe{} it is available as a command (i.e., a \TeX{} +% counter only. +% \begin{macrocode} +\cs_new_eq:NN \ReadonlyShipoutCounter \g_shipout_readonly_int +% \end{macrocode} +% \end{macro} + +% \begin{macro}{\g_shipout_totalpages_int,\c@totalpages} +% We count every shipout attempt (even those that are discarded) in +% tis counter. It is not used in the code but may get used in user +% code. +% \begin{macrocode} +\int_new:N \g_shipout_totalpages_int +% \end{macrocode} +% For \LaTeXe{} this is offered as a \LaTeX{} counter so can be +% easily typeset inside the output routine to display things like +% \enquote{\cs{thepage}\texttt{/}\cs{thetotalpages}}, etc. +% \begin{macrocode} +\cs_new_eq:NN \c@totalpages \g_shipout_totalpages_int +\cs_new:Npn \thetotalpages { \arabic{totalpages} } +% \end{macrocode} +% \end{macro} +% + + + +% \begin{macro}{\@abspage@last} +% In \cs{@abspage@last} record the number of pages from the last +% run. This is written to the \texttt{.aux} and this way made +% available to the next run. In case there is no \texttt{.aux} file +% or the statement is missing from it we initialize it with the +% largest possible number in \TeX{}. We use this a s the default +% because then we are inserting the \hook{shipout/lastpage} on +% the last page (or after the last page but not on page 1 for a +% multipage document. +% \begin{macrocode} +\xdef\@abspage@last{\number\maxdimen} +% \end{macrocode} +% \end{macro} + + +% \begin{macro}{\enddocument} +% +% Instead of using the hooks \hook{enddocument} and +% \hook{enddocument/afterlastpage} we add this code to private +% kernel hooks to be 100\% when it is executed and to avoid +% cluttering the hooks with data that is always there. +% +% Inside \cs{enddocument} there is a \cs{clearpage}. Just before +% that we execute this code here. There is a good change that we +% are on the last page. Therefore, if we don't know the value from +% the last run, we assume that the current page is the right +% one. So we set \cs{@abspage@last} and as a result the next +% shipout will run the \hook{shipout/lastpage} code. Of course, +% if there are floats that still need a placement this guess will +% be wrong but then rerunning the document will give us the correct +% value next time around. +% +% \begin{macro}{\@kernel@after@enddocument} +% \begin{macrocode} +\g@addto@macro \@kernel@after@enddocument { + \int_compare:nNnT \@abspage@last = \maxdimen + { +% \end{macrocode} +% We use \LaTeXe{} coding as \cs{@abspage@last} is not an L3 name. +% \begin{macrocode} + \xdef\@abspage@last{ \int_eval:n {\g_shipout_readonly_int + 1} } + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@kernel@after@enddocument@afterlastpage} +% Once the \cs{clearpage} has done its work inside \cs{enddocument} +% we know for sure how many pages this document has, so we record +% that in the \texttt{.aux} file for the next run. +% +% \begin{macrocode} +\g@addto@macro \@kernel@after@enddocument@afterlastpage { +% \end{macrocode} +% There is one special case: If no output is produced then there is +% no point in a) recording the number as 0 will never match the +% page number of a real page and b) adding an extra page to ran the +% \hook{shipout/lastpage} is pointless as well (as it would +% remain forever). So we test for this and run the code only if +% there have been pages. +% \begin{macrocode} + \int_compare:nNnF \g_shipout_readonly_int = 0 + { +% \end{macrocode} +% This ends up in the \texttt{.aux} so we use \LaTeXe{} names here. +% \fmi{this needs an interface for \cs{nofiles} in expl3, doesn't at the moment!} +% \begin{macrocode} + \if@filesw + \iow_now:Nx \@auxout { + \gdef\string\@abspage@last {\int_use:N \g_shipout_readonly_int}} + \fi +% \end{macrocode} +% But we may have guessed wrongly earlier and we still have to run the +% \hook{shipout/lastpage} even though there is no page to place +% it into. If that is the case we make a trivial extra page and put +% it there. This temporary page will then vanish again on the next +% run but helps to keep pdf viewers happy. +% \begin{macrocode} + \bool_if:NF \g_@@_lastpage_handled_bool + { \tex_shipout:D\vbox to\textheight{ + \hbox{\UseHook{shipout/lastpage} \@kernel@after@shipout@lastpage } +% \end{macrocode} +% This extra page could be totally empty except for the hook +% content, but to help the user understanding why it is there we +% put some text into it. +% \begin{macrocode} + \@@_excuse_extra_page: + \null + } +% \end{macrocode} +% At this point we should also signal to \LaTeX{} that a rerun is +% necessary so that an appropriate message can be shown on the +% terminal. +% +% \fmi{integrate warning ``Rerun \ldots'' } +% \begin{macrocode} + } + } +} +% \end{macrocode} +% \end{macro} +% \end{macro} + + + +% \begin{macro}{\@@_excuse_extra_page:} +% Say mea culpa \ldots +% \begin{macrocode} +\cs_new:Npn \@@_excuse_extra_page: { + \vfil + \begin{center} + \bfseries Temporary~ page! + \end{center} + \LaTeX{}~ was~ unable~ to~ guess~ the~ total~ number~ of~ pages~ + correctly.~ ~ As~ there~ was~ some~ unprocessed~ data~ that~ + should~ have~ been~ added~ to~ the~ final~ page~ this~ extra~ + page~ has~ been~ added~ to~ receive~ it. + \par + If~ you~ rerun~ the~ document~ (without~ altering~ it)~ this~ + surplus~ page~ will~ go~ away,~ because~ \LaTeX{}~ now~ knows~ + how~ many~ pages~ to~ expect~ for~ this~ document. + \vfil +} +% \end{macrocode} +% \end{macro} + + + + +% \section{Legacy \LaTeXe{} interfaces} + + + +% \begin{macro}{\DiscardShipoutBox} +% Request that the next shipout box is to be discarded. +% \begin{macrocode} +\cs_new_eq:NN \DiscardShipoutBox \shipout_discard: +% \end{macrocode} +% \end{macro} + + +% \begin{macro}{\AtBeginDvi} +% +% \begin{macrocode} +\renewcommand \AtBeginDvi {\@@_add_firstpage_material:Nn \AtBeginDvi} +% \end{macrocode} +% \end{macro} + + +% \begin{macro}{\DebugShipoutOn,\DebugShipoutOff} +% +% \begin{macrocode} +\cs_new_eq:NN \DebugShipoutOn \shipout_debug_on: +\cs_new_eq:NN \DebugShipoutOff \shipout_debug_off: +% \end{macrocode} +% \end{macro} + + + + + +% \section{Package emulation for compatibility} + + +% \subsection{Package \pkg{atbegshi} emulation} + +% \begin{macro}{\AtBeginShipoutBox} +% \begin{macrocode} +\cs_new_eq:NN \AtBeginShipoutBox \ShipoutBox +% \end{macrocode} +% \end{macro} + + + +% \begin{macro}{\AtBeginShipoutInit} +% Compatibility only, we aren't delaying \ldots +% \begin{macrocode} +\cs_set_eq:NN\AtBeginShipoutInit\@empty +% \end{macrocode} +% \end{macro} + + + +% \begin{macro}{\AtBeginShipout,\AtBeginShipoutNext} +% Filling hooks +% \begin{macrocode} +\newcommand\AtBeginShipout {\AddToHook{shipout/before}} +\newcommand\AtBeginShipoutNext {\AddToHookNext{shipout/before}} +% \end{macrocode} +% \end{macro} + + + +% \begin{macro}{\AtBeginShipoutFirst} +% Slightly more complex as we need to know the name of the command under which the +% \hook{shipout/firstpage} hook is filled. +% \begin{macrocode} +\newcommand\AtBeginShipoutFirst{\@@_add_firstpage_material:Nn \AtBeginShipoutFirst} +% \end{macrocode} +% \end{macro} + + + +% This is somewhat different from the original where +% \cs{ShipoutBoxHeight} etc.\ only holds the \verb=\the\ht<box>= value. This +% may has some implications in some use cases and if that is a problem +% then it might need changing. +% +% \begin{macrocode} +\cs_new:Npn \ShipoutBoxHeight { \dim_use:N \l_shipout_box_ht_dim } +\cs_new:Npn \ShipoutBoxDepth { \dim_use:N \l_shipout_box_dp_dim } +\cs_new:Npn \ShipoutBoxWidth { \dim_use:N \l_shipout_box_wd_dim } +% \end{macrocode} + + +% \begin{macro}{\AtBeginShipoutDiscard} +% Just a different name. +% \begin{macrocode} +\cs_new_eq:NN \AtBeginShipoutDiscard \DiscardShipoutBox +% \end{macrocode} +% \end{macro} + + +% \begin{macro}{\AtBeginShipoutAddToBox,\AtBeginShipoutAddToBoxForeground, +% \AtBeginShipoutUpperLeft,\AtBeginShipoutUpperLeftForeground} +% We don't expose them. +% \begin{macrocode} +\cs_new_eq:NN \AtBeginShipoutAddToBox \@@_add_background_box:n +\cs_new_eq:NN \AtBeginShipoutAddToBoxForeground \@@_add_foreground_box:n +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_eq:NN\AtBeginShipoutUpperLeft \@@_add_background_picture:n +\cs_new_eq:NN\AtBeginShipoutUpperLeftForeground \@@_add_foreground_picture:n +% \end{macrocode} +% \end{macro} + +% +% +% We prevent the package \pkg{atbegshi} from loading: +% \begin{macrocode} +\expandafter\cs_set_eq:NN\csname ver@atbegshi.sty\endcsname\fmtversion +% \end{macrocode} +% \pkg{hyperref} code (and \pkg{ltxcmds}) doesn't understand 2020-10-01 +% and thinks it is before 1994, so for now \ldots +% \begin{macrocode} +\@namedef {ver@atbegshi.sty}{2020/10/01} +% \end{macrocode} + + + +% \subsection{Package \pkg{everyshi} emulation} +% +% \begin{macro}{\EveryShipout,\AtNextShipout} +% This package has only two public commands to simulating it is easy: +% \begin{macrocode} +\cs_new_eq:NN\EveryShipout\AtBeginShipout +\cs_new_eq:NN\AtNextShipout\AtBeginShipoutNext +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\expandafter\cs_set_eq:NN\csname ver@everyshi.sty\endcsname\fmtversion +\@namedef {ver@everyshi.sty}{2020/10/01} +% \end{macrocode} + + + +% \subsection{Package \pkg{atenddvi} emulation} +% +% \begin{macro}{\AtEndDvi} +% This package has only one public command to simulating it is easy: +% \begin{macrocode} +\cs_new:Npn \AtEndDvi {\AddToHook{shipout/lastpage}} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macrocode} +\expandafter\cs_set_eq:NN\csname ver@atenddvi.sty\endcsname\fmtversion +\@namedef {ver@atenddvi.sty}{2020/10/01} +% \end{macrocode} + + + + +% \begin{macrocode} +\ExplSyntaxOff +%</2ekernel> +% \end{macrocode} + +% \Finale +% + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\endinput +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + diff --git a/Master/texmf-dist/source/latex-dev/base/ltvers.dtx b/Master/texmf-dist/source/latex-dev/base/ltvers.dtx index dd39a67896a..ff6c9ef2445 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltvers.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltvers.dtx @@ -115,7 +115,7 @@ {2020-10-01} %</2ekernel|latexrelease> %<*2ekernel> -\def\patch@level{-6} +\def\patch@level{-7} % \end{macrocode} % % \begin{macro}{\development@branch@name} diff --git a/Master/texmf-dist/source/latex-dev/base/ltxdoc.dtx b/Master/texmf-dist/source/latex-dev/base/ltxdoc.dtx index f250b2cb193..3b82ccd7597 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltxdoc.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltxdoc.dtx @@ -30,7 +30,7 @@ % %<class>\NeedsTeXFormat{LaTeX2e} %<class>\ProvidesClass{ltxdoc} -%<class> [2019/09/16 v2.0y Standard LaTeX documentation class] +%<class> [2020/05/17 v2.0z Standard LaTeX documentation class] % %<*driver> \documentclass{ltxdoc} @@ -422,6 +422,8 @@ \def\partname{File} % \end{macrocode} % +% \changes{v2.0z}{2020/05/17}{Support spaces \emph{within} filenames +% (gh/218)} % \begin{macrocode} \newcommand*{\DocInclude}[1]{% \relax @@ -432,13 +434,16 @@ {\def\currentfile{#1.dtx}}% \ifnum\@auxout=\@partaux \@latexerr{\string\include\space cannot be nested}\@eha - \else \@docinclude#1 \fi} + \else + \set@curr@file@trim@spaces{#1}% + \expandafter\@docinclude\expandafter{\@curr@file} + \fi} \def\@docinclude#1 {\clearpage -\if@filesw \immediate\write\@mainaux{\string\@input{#1.aux}}\fi +\if@filesw \immediate\write\@mainaux{\string\@input{"#1.aux"}}\fi \@tempswatrue\if@partsw \@tempswafalse\edef\@tempb{#1}\@for \@tempa:=\@partlist\do{\ifx\@tempa\@tempb\@tempswatrue\fi}\fi \if@tempswa \let\@auxout\@partaux \if@filesw -\immediate\openout\@partaux #1.aux +\immediate\openout\@partaux "#1.aux" \immediate\write\@partaux{\relax}\fi % \end{macrocode} % We need to save (and later restore) various index-related diff --git a/Master/texmf-dist/source/latex-dev/base/unpack.ins b/Master/texmf-dist/source/latex-dev/base/unpack.ins index b03dd5c6b1b..ed8cb572c7d 100644 --- a/Master/texmf-dist/source/latex-dev/base/unpack.ins +++ b/Master/texmf-dist/source/latex-dev/base/unpack.ins @@ -123,6 +123,7 @@ \batchinput{latexrelease.ins} +\batchinput{lthooks.ins} \Msg{} \Msg{*********************************************} diff --git a/Master/texmf-dist/source/latex-dev/graphics/lscape.dtx b/Master/texmf-dist/source/latex-dev/graphics/lscape.dtx index e14462c9d42..ac5c16d7c20 100644 --- a/Master/texmf-dist/source/latex-dev/graphics/lscape.dtx +++ b/Master/texmf-dist/source/latex-dev/graphics/lscape.dtx @@ -17,7 +17,7 @@ %<driver> \ProvidesFile{lscape.drv} % \fi % \ProvidesFile{lscape.dtx} - [2000/10/22 v3.01 Landscape Pages (DPC)] + [2020/05/28 v3.02 Landscape Pages (DPC)] % % \iffalse %<*driver> @@ -61,6 +61,7 @@ % \changes{v3.00}{1994/10/05}{Update using LaTeX2e graphics package} % \changes{v3.01}{1999/06/22}{Added better pdfTeX support % by Scott Pakin, from graphics/3063} +% \changes{v3.02}{2020/05/28}{delay saving \cs{@makefcolumn} gh340} % % % \begin{macrocode} @@ -90,8 +91,6 @@ % \end{macrocode} % % \begin{macrocode} -\let\LS@makecol=\@makecol -\let\LS@makefcolumn=\@makefcolumn \def\LS@rot{% \setbox\@outputbox\vbox{\hbox{\rotatebox{90}{\box\@outputbox}}}} % \end{macrocode} @@ -99,6 +98,8 @@ % First set up the page size for landscape. % \begin{macrocode} \def\landscape{% + \let\LS@makecol=\@makecol + \let\LS@makefcolumn=\@makefcolumn \clearpage \begingroup \vsize=\textwidth diff --git a/Master/texmf-dist/source/latex-dev/tools/array.dtx b/Master/texmf-dist/source/latex-dev/tools/array.dtx index a84d4faf510..ff963d7f514 100644 --- a/Master/texmf-dist/source/latex-dev/tools/array.dtx +++ b/Master/texmf-dist/source/latex-dev/tools/array.dtx @@ -33,7 +33,7 @@ %<+package>\DeclareCurrentRelease{}{2020-10-01} %<+package> %<+package>\ProvidesPackage{array} -%<+package> [2020/10/01 v2.5b Tabular extension package (FMi)] +%<+package> [2020/10/01 v2.5c Tabular extension package (FMi)] % % \fi % @@ -552,14 +552,16 @@ % \item rules can be placed between columns or rows thereby enlarging % the table. % \end{enumerate} -% \texttt{array.sty} implements the second possibility while the -% default implementation in the \LaTeX{} kernel implements the first -% concept. Both concepts have their merits but one has to be aware of -% the individual implications. +% For vertical rules \texttt{array.sty} implements the second +% possibility while the default implementation in the \LaTeX{} kernel +% implements the first concept. +% Both concepts have their merits but +% one has to be aware of the individual implications. % \begin{itemize} % \item -% With standard \LaTeX{} adding rules to a table will not affect the -% width or height of the table (unless double rules are used), e.g., +% With standard \LaTeX{} adding vertical rules to a table will +% not affect the +% width of the table (unless double rules are used), e.g., % changing a preamble from \verb=lll= to \verb=l|l|l= does not % affect the document other than adding rules to the table. In % contrast, with \texttt{array.sty} a table that just fit the @@ -602,6 +604,12 @@ % \end{center} % \end{itemize} % +% Horizontal rules produced with \cs{hline} add to the table height in +% both implementations but they differ in handling double \cs{hline}s. +% In contrast a \cs{cline} does not change the table +% height.\footnote{All a bit inconsistent, but nothing that can be +% changed after being 30+ years in existence.} +% % \subsection{Comparisons with older versions of \texttt{array.sty}} % % There are some differences in the way version 2.1 treats incorrect @@ -731,7 +739,11 @@ \NeedsTeXFormat{LaTeX2e}[1995/12/01] \documentclass{ltxdoc} -\AtBeginDocument{\DeleteShortVerb{\|}} % undo the default is not used +% undo the default is not used: + +\IfFormatAtLeastTF {2020/10/01} + {\AtBeginDocument[ltxdoc]{\DeleteShortVerb{\|}} } + {\AtBeginDocument{\DeleteShortVerb{\|}} } \usepackage{array} @@ -747,6 +759,7 @@ %\OnlyDescription % comment out for implementation details %\OldMakeindex % use if your MakeIndex is pre-v2.9 + \begin{document} \DocInput{array.dtx} \end{document} @@ -2210,7 +2223,7 @@ % \cs{@yargarraycr} is the same as in the \LaTeX{} kernel % (depending on the date of the kernel with one of the two % definitions below). We therefore do not define it again. -% \changes{v2.5b}{200/04/22}{Don't define \cs{@yargarraycr} unnecessarily} +% \changes{v2.5b}{2020/04/22}{Don't define \cs{@yargarraycr} unnecessarily} % \begin{macrocode} %\def\@yargarraycr#1{\cr\noalign{\@vspace@calcify{#1}}} % 2020-10-01 %\def\@yargarraycr#1{\cr\noalign{\vskip #1}} @@ -2922,10 +2935,13 @@ % % We start by producing a single tabular row without any visible % content that will produce the external reference point in case -% "[t]" is used. +% "[t]" is used. We need to suppress the \cs{tabcolsep} in the +% \cs{multicolumn} in case there wasn't any in the real column. +% +% \changes{v2.5c}{2020/07/20}{Suppress all column space (gh/322)} % \begin{macrocode} \newcommand{\firsthline}{% - \multicolumn1c{% + \multicolumn1{@{}c@{}}{% % \end{macrocode} % Within this row we calculate "\backup@length" to be the height % plus depth of a standard line. In addition we have to add the @@ -2942,6 +2958,10 @@ % \begin{macrocode} \raise\extratabsurround\copy\@arstrutbox % \end{macrocode} +% And we should also cancel the guard otherwise we end up with two. +% \begin{macrocode} + \kern-1sp% +% \end{macrocode} % Having done all this we end the line and back up by the value of % "\backup@length" and then finally place our "\hline". This should % place the line exactly at the right place but keep the reference @@ -2963,9 +2983,12 @@ % depth of this last line increased by "\extratabsurround" without % changing the placement "\hline". % -% We start by placing the rule followed by an invisible row. +% We start by placing the rule followed by an invisible row. We +% need to suppress the \cs{tabcolsep} in the multicol in case there +% wasn't any in the real column. +% \changes{v2.5c}{2020/07/20}{Suppress all column space (gh/322)} % \begin{macrocode} -\newcommand{\lasthline}{\hline\multicolumn1c{% +\newcommand{\lasthline}{\hline\multicolumn1{@{}c@{}}{% % \end{macrocode} % We now calculate "\backup@length" to be the height and depth of % two lines plus the width of the rule. @@ -2983,8 +3006,9 @@ % reference for the whole tabular). Since this row is invisible we % can enlarge its depth by the desired amount. % \begin{macrocode} - \multicolumn1c{% + \multicolumn1{@{}c@{}}{% \lower\extratabsurround\copy\@arstrutbox + \kern-1sp% }% } % \end{macrocode} diff --git a/Master/texmf-dist/source/latex-dev/tools/varioref.dtx b/Master/texmf-dist/source/latex-dev/tools/varioref.dtx index 077103eb97a..06af00bc282 100644 --- a/Master/texmf-dist/source/latex-dev/tools/varioref.dtx +++ b/Master/texmf-dist/source/latex-dev/tools/varioref.dtx @@ -40,7 +40,7 @@ %<package>\DeclareCurrentRelease{}{2019-10-01} %<package> %<package>\ProvidesPackage{varioref} -%<package> [2020/01/23 v1.6c package for extended references (FMi)] +%<package> [2020/07/20 v1.6d package for extended references (FMi)] % \fi % %% @@ -230,6 +230,11 @@ % The optional argument the command may take is the text to use in case % both labels are placed on the current page. % +% In some languages (currently only for Japanese) the generated text +% has to typeset the page range first and the reference range +% afterwards. To accomodate for this \cs{vrefrangeformat} has been +% added to allow to alter this on a per language basis. +% % % \DescribeMacro\vpagerefrange This command is similar to |\vpageref| % but takes two mandatory arguments which are two labels denoting a @@ -708,6 +713,7 @@ \def\reftextfaraway#1{op bladsy~\pageref{#1}}% \def\reftextpagerange#1#2{op bladsye~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} tot~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % @@ -723,6 +729,7 @@ \def\reftextfaraway#1{on page~\pageref{#1}}% \def\reftextpagerange#1#2{on pages~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} to~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % Arabic option text was contributed by Ihab Samir Mattar @@ -743,6 +750,7 @@ \def\reftextfaraway#1{بالصفحة رقم~\pageref{#1}}% \def\reftextpagerange#1#2{بالصفحات~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} حتى~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % \end{allowtofu} @@ -759,6 +767,7 @@ \def\reftextfaraway#1{auf Seite~\pageref{#1}}% \def\reftextpagerange#1#2{auf Seiten~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} bis~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % \changes{v1.2d}{2000/01/11}{Added naustrian defaults (identical to german)} @@ -774,6 +783,7 @@ \def\reftextfaraway#1{auf Seite~\pageref{#1}}% \def\reftextpagerange#1#2{auf Seiten~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} bis~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % Text for basque defaults was contributed by @@ -791,6 +801,7 @@ \def\reftextfaraway#1{~\pageref{#1}. orrialdean}% \def\reftextpagerange#1#2{~\pageref{#1}--\pageref{#2} orrialdeetan}% \def\reftextlabelrange#1#2{\ref{#1}.etik \ref{#2}.eraino}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % Text for the Bahasa Malaysia defaults was contributed by @@ -815,6 +826,7 @@ \def\reftextfaraway#1{pada muka surat~\pageref{#1}}% \def\reftextpagerange#1#2{pada muka surat~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1}--\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % Text for brazil defaults was contributed by @@ -837,6 +849,7 @@ \def\reftextfaraway#1{na p\'agina~\pageref{#1}}% \def\reftextpagerange#1#2{nas p\'aginas~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} a~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % Text for Breton defaults was contributed by @@ -858,6 +871,7 @@ on pages~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\vref@stringwarning\reflabelpagerange \ref{#1} to~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % Text for Bulgarian defaults was contributed by @@ -892,6 +906,7 @@ \cyrs\cyrt\cyrr\cyra\cyrn\cyri\cyrc\cyri ~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} \cyrd\cyro~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % Text for catalan defaults was contributed by Robert Fuster\\ @@ -910,6 +925,7 @@ \def\reftextpagerange#1#2{a les p\`agines~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} a~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % Text for croatian defaults was contributed by \v{S}ime Ungar @@ -926,6 +942,7 @@ \def\reftextfaraway#1{na stranici~\pageref{#1}}% \def\reftextpagerange#1#2{na stranicama~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} do~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % Defaults for the Czech option provided by Milan Vancura @@ -943,6 +960,7 @@ \def\reftextfaraway#1{na stran\v{e}~\pageref{#1}}% \def\reftextpagerange#1#2{na stran\'ach~\pageref{#1}\--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} a\v{z}~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % Defaults for Danish provided by Torsten Martinsen @@ -965,6 +983,7 @@ \def\reftextfaraway#1{p\aa{} side~\pageref{#1}}% \def\reftextpagerange#1#2{p\aa{} side~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} til~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % Default string for dutch have been contributed by Frank Poppe @@ -1004,6 +1023,7 @@ % \begin{macrocode} \def\reftextpagerange#1#2{op pagina's~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1}--\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % \changes{v1.2a}{1998/08/22}{Added english defaults for @@ -1021,6 +1041,7 @@ \def\reftextfaraway#1{on page~\pageref{#1}}% \def\reftextpagerange#1#2{on pages~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} to~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % @@ -1041,6 +1062,7 @@ \def\reftextfaraway#1{en pa\^go~\pageref{#1}}% \def\reftextpagerange#1#2{en pa\^goj~\pageref{#1} \^gis \pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} \^gis~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % The finnish strings were suggested by Matti Rintala @@ -1064,6 +1086,7 @@ % Can't combine numbers with the necessary suffix well. % \begin{macrocode} \def\reftextlabelrange#1#2{\ref{#1}--\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % French defaults are provided by Daniel Flippo @@ -1083,6 +1106,7 @@ \def\reftextfaraway#1{page~\pageref{#1}}% \def\reftextpagerange#1#2{pages~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} \`a~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % Galician defaults are provided by Matthias Moebius\\ @@ -1104,6 +1128,7 @@ \def\reftextpagerange#1#2{% nas p\'axinas~\pageref{#1}-\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} a~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % There are no good variants for German (I think and still think but @@ -1138,6 +1163,7 @@ \def\reftextfaraway#1{auf Seite~\pageref{#1}}% \def\reftextpagerange#1#2{auf den Seiten~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} bis~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % \changes{v1.2d}{2000/01/11}{Added ngerman defaults (identical to german)} @@ -1155,6 +1181,7 @@ \def\reftextfaraway#1{auf Seite~\pageref{#1}}% \def\reftextpagerange#1#2{auf den Seiten~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} bis~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % Defaults for greek suggested by Apostolos Syropoulos\\ @@ -1174,6 +1201,7 @@ \def\reftextpagerange#1#2{stis sel'ides\nobreakspace \pageref{#1}---\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} ws\nobreakspace\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % Icelandic defaults suggested by Thorhallur Sverrisson @@ -1194,6 +1222,7 @@ \def\reftextfaraway#1{\'{a} s\'{i}{\dh}u~\pageref{#1}}% \def\reftextpagerange#1#2{\'{a} s\'{i}{\dh}um~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} til~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % Defaults for Italian suggested by Giovanni Pensa @@ -1218,8 +1247,32 @@ \def\reftextfaraway#1{a pagina~\pageref{#1}}% \def\reftextpagerange#1#2{nelle pagine~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{da~\ref{#1} a~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat + }} +% \end{macrocode} +% Defaults for Japanese. It needs a special \cs{vrefrangeformat} +% for gramatical reasons. As our standard documentation +% workflow uses pdf\TeX{} the Japanese letters can't be displayed +% easily, so you will see missing glyphs below. To see the real +% letters you have to look at the source or package file. +% \changes{v1.6d}{2020/07/20}{Option japanese added (gh/352)} +% \begin{allowtofu} +% \begin{macrocode} +\DeclareOption{japanese} + {\vref@addto\extrasjapanese{% + \def\reftextfaceafter {\reftextvario{見開き}{次}頁}% + \def\reftextfacebefore{\reftextvario{見開き}{前}頁}% + \def\reftextafter {\reftextvario{直後の}{次}頁}% + \def\reftextbefore {\reftextvario{直前の}{前}頁}% + \def\reftextcurrent {\reftextvario{この}{現}頁}% + \def\reftextfaraway#1{\pageref{#1}頁}% + \def\reftextpagerange#1#2{\pageref{#1}頁から\pageref{#2}頁}% + \def\reftextlabelrange#1#2{\ref{#1}から\ref{#2}}% + \def\vrefrangeformat#1#2#3{\vpagerefrange[{#1}]{#2}{#3}の% + \reftextlabelrange{#2}{#3}}% }} % \end{macrocode} +% \end{allowtofu} % Defaults for Hungarian by Jeff Goldberg % (\verb=jeffrey@goldmark.org=). % There is a problem with the use of the definite article @@ -1264,6 +1317,7 @@ on pages~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\vref@stringwarning\reflabelpagerange \ref{#1} to~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }% % \end{macrocode} % The |\AtBeginDocument| needs to be executed when the option is @@ -1304,6 +1358,7 @@ \def\reftextfaraway#1{p\aa{} side~\pageref{#1}}% \def\reftextpagerange#1#2{p\aa{} side~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} til~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{nynorsk} {\vref@addto\extrasnynorsk{% @@ -1315,6 +1370,7 @@ \def\reftextfaraway#1{p\aa{} side~\pageref{#1}}% \def\reftextpagerange#1#2{p\aa{} side~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} til~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % The polish translations have been provided by @@ -1342,6 +1398,7 @@ \def\reftextfaraway#1{na stronie~\pageref{#1}}% \def\reftextpagerange#1#2{na stronach~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{od~\ref{#1} do~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % The portuguese default text has been provided by @@ -1362,6 +1419,7 @@ \def\reftextfaraway#1{na p\'agina~\pageref{#1}}% \def\reftextpagerange#1#2{nas p\'aginas~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} a~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % Updates to the default text for Romanian have been suggested by Florin Oprina @@ -1381,6 +1439,7 @@ \def\reftextfaraway#1{pe pagina~\pageref{#1}}% \def\reftextpagerange#1#2{pe paginile~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} la~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % The text for russian was taken from the book in Russian by @@ -1414,6 +1473,7 @@ \def\reftextpagerange#1#2{\cyrn\cyra\ \cyrs\cyrt\cyrr\cyra\cyrn \cyri\cyrc\cyra\cyrh~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\cyrs~\ref{#1}\ \cyrp\cyro~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % The text for slovak defaults was contributed by Miroslav Sedivy\\ @@ -1434,6 +1494,7 @@ \def\reftextfaraway#1{na strane~\pageref{#1}}% \def\reftextpagerange#1#2{na stran\'ach~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} a\v z~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % The text for slovene defaults was contributed by Roman Maurer\\ @@ -1450,6 +1511,7 @@ \def\reftextfaraway#1{na strani~\pageref{#1}}% \def\reftextpagerange#1#2{na straneh~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{od~\ref{#1} do~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % Text for spanish defaults was contributed by Julio Sanchez @@ -1470,6 +1532,7 @@ \def\reftextpagerange#1#2{en las p\'aginas~\pageref{#1}% -\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} a~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % The text for swedish was contributed by Mats Dahlgren @@ -1492,6 +1555,7 @@ \def\reftextpagerange#1#2{p\aa\ sidorna~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} till~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{turkish} {\vref@excuse{turkish}% @@ -1505,6 +1569,7 @@ \def\reftextfaraway#1{on page~\pageref{#1}}% \def\reftextpagerange#1#2{on pages~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} to~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % The text for Ukrainian defaults was contributed by Mykola Lyakhovych\\ @@ -1532,6 +1597,7 @@ \def\reftextpagerange#1#2{\cyrn\cyra\ \cyrs\cyrt\cyro\cyrr\cyrii \cyrn\cyrk\cyra\cyrh~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\cyrz~\ref{#1}\ \cyrd\cyro~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} % We support francais as an alternative to french since people @@ -2286,13 +2352,28 @@ % \changes{v1.2a}{1998/08/01}{Macro added} % \changes{v1.4s}{2006/08/07} % {Prevent loss of brackets} +% \changes{v1.6d}{2020/07/20}{Changed for Japanese (gh/352)} +% Argument two and three are implicitly picked up. % \begin{macrocode} -\newcommand\vrefrange[3][\reftextcurrent] - {\reftextlabelrange{#2}{#3} \vpagerefrange[{#1}]{#2}{#3}} +\newcommand\vrefrange[1][\reftextcurrent]{\vrefrangeformat{#1}} % \end{macrocode} +% % \end{macro} % % +% \begin{macro}{\vrefrangeformat,\vrefrangedefaultformat} +% Japanese needs a different word order in \cs{vrefrange} so this +% is separated out o that it can be changed on language level. +% \changes{v1.6d}{2020/07/20}{Macro added (gh/352)} +% \begin{macrocode} +\def\vrefrangedefaultformat#1#2#3{% + \reftextlabelrange{#2}{#3} \vpagerefrange[{#1}]{#2}{#3}} +% \end{macrocode} +% Most languages need the above definition. +% \begin{macrocode} +\let\vrefrangeformat\vrefrangedefaultformat +% \end{macrocode} +% \end{macro} % % \begin{macro}{\Vref} % \changes{v1.4a}{2002/02/24}{Macro added} diff --git a/Master/texmf-dist/source/latex-dev/tools/verbatim.dtx b/Master/texmf-dist/source/latex-dev/tools/verbatim.dtx index 121e2d4b39c..e62886e0033 100644 --- a/Master/texmf-dist/source/latex-dev/tools/verbatim.dtx +++ b/Master/texmf-dist/source/latex-dev/tools/verbatim.dtx @@ -69,6 +69,8 @@ %\fi % % +% \changes{v1.5u}{2020-07-07}{Typo repair and added a missing comment +% character} % \changes{v1.5q}{2003/08/22}{Reintroduced \cs{@noligs}, by popular % request.} % \changes{v1.5i}{1996/06/04}{Move setting of verbatim font and @@ -462,9 +464,12 @@ % the spacing. % Then we open the file and set the category codes of all special % characters: +% \changes{v1.5t}{2020-07-05}{Added quotes around the filename in +% order to allow a filename with spaces; also added a space and +% comment-character to allow for thespace dlimited argument.} % \begin{verbatim} % \@bsphack -% \immediate\openout \verbatim@out #1 +% \immediate\openout \verbatim@out "#1" % % \let\do\@makeother\dospecials % \catcode`\^^M\active %\end{verbatim} @@ -503,7 +508,7 @@ %<*package> \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{verbatim} - [2019/11/10 v1.5r LaTeX2e package for verbatim enhancements] + [2020-07-07 v1.5u LaTeX2e package for verbatim enhancements] \@ifundefined{verbatim@@@}{}{\endinput} % \end{macrocode} % @@ -1567,19 +1572,31 @@ % existence of file.} % |\verbatim@input| first checks whether the file exists, using % the standard macro |\IfFileExists| which leaves the name of the -% file found in |\@filef@und|. -% Then everything is set up as in the |\verbatim| macro. +% file found in |\@filef@und|. +% Then everything is set up as in the |\verbatim| macro. But, as +% |\@verbatim| contains a call to |\every@verbatim| which +% \emph{might} contain an |\input| statement, which would overwrite +% the contents of |\@filef@und|, we need to save it by expanding it +% first. The use of |\@swaptwoargs| makes it so that the +% \emph{expansion} of |\@filef@und| gets to be the second argument +% of |\verbatim@readfile|. +% \changes{v1.5t}{2020-07-06}{Expand \cs{@filef@und} before the call +% of \cs{@verbatim} (gh/222)}m % \begin{macrocode} \def\verbatim@input#1#2{% - \IfFileExists {#2}{\@verbatim #1\relax + \IfFileExists {#2}{% + \expandafter\@swaptwoargs\expandafter + {\expandafter{\@filef@und}}% + {\@verbatim #1\relax % \end{macrocode} % Then it reads in the file, finishes off the \texttt{trivlist} % environment started by |\@verbatim| and closes the group. % This restores everything to its normal settings. % \begin{macrocode} - \verbatim@readfile{\@filef@und}\endtrivlist\endgroup\@doendpe}% + \verbatim@readfile}% + \endtrivlist\endgroup\@doendpe}% % \end{macrocode} -% If the file is not found a more or less helpful message is +% If the file is not found a more or less helpful message is % printed. The final |\endgroup| is needed to close the group % started in |\verbatiminput| above. % \begin{macrocode} diff --git a/Master/texmf-dist/tex/latex-dev/base/doc.sty b/Master/texmf-dist/tex/latex-dev/base/doc.sty index 94b1a9754f2..417340cebc9 100644 --- a/Master/texmf-dist/tex/latex-dev/base/doc.sty +++ b/Master/texmf-dist/tex/latex-dev/base/doc.sty @@ -43,7 +43,7 @@ %% extension .ins) which are part of the distribution. \NeedsTeXFormat{LaTeX2e}[1994/12/01] \ProvidesPackage{doc} - [2019/12/16 v2.1l + [2020/06/15 v2.1m Standard LaTeX documentation package (FMi)] %% %% Package `doc' to use with LaTeX 2e @@ -59,6 +59,7 @@ \@beginparpenalty \predisplaypenalty \if@inlabel\leavevmode\fi \trivlist \parskip \z@ \item[]% + \global\setbox\@labels\box\voidb@x \macro@font \leftskip\@totalleftmargin \advance\leftskip\MacroIndent \rightskip\z@ \parindent\z@ \parfillskip\@flushglue diff --git a/Master/texmf-dist/tex/latex-dev/base/docstrip.tex b/Master/texmf-dist/tex/latex-dev/base/docstrip.tex index 127c7c6e371..e670198de27 100644 --- a/Master/texmf-dist/tex/latex-dev/base/docstrip.tex +++ b/Master/texmf-dist/tex/latex-dev/base/docstrip.tex @@ -44,9 +44,9 @@ \catcode`\{=1 \catcode`\}=2 \def\filename{docstrip.dtx} -\def\fileversion{v2.5h} -\def\filedate{2020/04/18} -\def\docdate {2018/05/03} +\def\fileversion{v2.6a} +\def\filedate{2020-07-07} +\def\docdate {2020-07-11} %% %% The docstrip program for use with TeX. %% Copyright (C) 1989-1991 Frank Mittelbach @@ -54,7 +54,7 @@ %% Frank Mittelbach %% Copyright (C) 1995 Marcin Woli\'nski %% Copyright (C) 1996-1997 Mark Wooding, Marcin Woli\'nski -%% Copyright (C) 1998-2003 LaTeX3 project and the above authors +%% Copyright (C) 1998-2020 LaTeX3 project and the above authors %% All rights are reserved. %% \catcode`\Z=\catcode`\% @@ -356,6 +356,7 @@ Z \advance\codeLinesPassed\@ne \maybeMsg{.}% \def\inLine{#1}% + \replaceModuleInLine \let\do\putline@do \activefiles } @@ -397,19 +398,23 @@ Z \ifcase \ifx*#10\else \ifx/#11\else \ifx+#12\else \ifx-#13\else - \ifx<#14\else 5\fi\fi\fi\fi\fi\relax + \ifx<#14\else \ifx @#15\else 6\fi\fi\fi\fi\fi\fi\relax \expandafter\starOption\or \expandafter\slashOption\or \expandafter\plusOption\or \expandafter\minusOption\or \expandafter\verbOption\or + \expandafter\moduleOption\or \expandafter\doOption\fi #1} \def\doOption#1>#2\endLine{% \maybeMsg{<#1 . >}% \Evaluate{#1}% \def\do##1##2##3{% - \if1\Expr{##2}\StreamPut##1{#2}\fi + \if1\Expr{##2}% + \def\inLine{#2}% + \replaceModuleInLine + \StreamPut##1{\inLine}\fi }% \activefiles } @@ -485,6 +490,38 @@ Z \repeat \maybeMsg{>}% }} +\def\moduleOption @@=#1>#2\endLine{% + \maybeMsg{<@@=#1>}% + \prepareActiveModule{#1}% +} +\begingroup + \catcode`\_ = 12 % + \long\gdef\prepareActiveModule#1{% + \ifx\relax#1\relax + \let\replaceModuleInLine\empty + \else + \edef\replaceModuleInLine{% + \noexpand\replaceAllIn\noexpand\inLine{@@@@}{\string aa}% + \noexpand\replaceAllIn\noexpand\inLine{__@@}{__#1}% + \noexpand\replaceAllIn\noexpand\inLine{_@@}{__#1}% + \noexpand\replaceAllIn\noexpand\inLine{@@}{__#1}% + \noexpand\replaceAllIn\noexpand\inLine{\string aa}{@@}% + }% + \fi + } +\endgroup +\let\replaceModuleInLine\empty +\long\def\replaceAllIn#1#2#3{% + \long\def\tempa##1##2#2{% + ##2\qMark\replaceAllInAuxIII#3##1% + }% + \edef#1{\expandafter\replaceAllInAuxI#1\qMark#2\qStop}% +} +\def\replaceAllInAuxI{% + \expandafter\replaceAllInAuxII\tempa\replaceAllInAuxI\empty +} +\long\def\replaceAllInAuxII#1\qMark#2{#1} +\long\def\replaceAllInAuxIII#1\qStop{} \def\generate#1{\begingroup \let\inputfiles\empty \let\filestogenerate\empty \let\file\@file diff --git a/Master/texmf-dist/tex/latex-dev/base/filehook-ltx.sty b/Master/texmf-dist/tex/latex-dev/base/filehook-ltx.sty new file mode 100644 index 00000000000..5ee890ae506 --- /dev/null +++ b/Master/texmf-dist/tex/latex-dev/base/filehook-ltx.sty @@ -0,0 +1,101 @@ +%% +%% This is file `filehook-ltx.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% ltfilehook.dtx (with options: `filehook-draft') +%% +%% This is a generated file. +%% +%% Copyright 2020 Frank Mittelbach +%% +%% This file was generated from file(s) of the LaTeX `lthooks Bundle'. +%% -------------------------------------------------------------------------- +%% +%% It 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 file may only be distributed together with a copy of the LaTeX +%% `lthooks Bundle'. You may however distribute the `lthooks Bundle' +%% without such generated files. +%% +%% The newest sources can be found below +%% +%% https://github.com/FrankMittelbach/fmitex/ +%% +%% where one can also log issues in case there are any. +%% +%% +%% File: ltfilehook.dtx (C) Copyright 2020 Frank Mittelbach, LaTeX Team +\providecommand\ltfilehookversion{v0.9a} +\providecommand\ltfilehookdate{2020/07/19} +\newcommand\AtBeginOfEveryFile [1] + {\AddToHook{file/before}{#1}} +\newcommand\AtEndOfEveryFile [1] + {\AddToHook{file/after}{#1}} +\newcommand\AtBeginOfIncludes [1] + {\AddToHook{include/before}{#1}} +\newcommand\AtEndOfIncludes [1] + {\AddToHook{include/end}{#1}} +\newcommand\AfterIncludes [1] + {\AddToHook{include/after}{#1}} +\newcommand\AtBeginOfPackages [1] + {\AddToHook{package/before}{#1}} +\newcommand\AtEndOfPackages [1] + {\AddToHook{package/after}{#1}} +\newcommand\AtBeginOfClasses [1] + {\AddToHook{class/before}{#1}} +\newcommand\AtEndOfClasses [1] + {\AddToHook{class/after}{#1}} +\newcommand\AtBeginOfFile [2] + {\AddToHook{file/before/#1}{#2}} +\newcommand\AtEndOfFile [2] + {\AddToHook{file/after/#1}{#2}} +\DeclareDocumentCommand \AtBeginOfPackageFile {smm} + {\IfBooleanTF{#1}% + {\@ifpackageloaded{#2}% + {#3}% + {\AddToHook{package/before/#2}{#3}}}% + {\AddToHook{package/before/#2}{#3}}% + } +\DeclareDocumentCommand \AtEndOfPackageFile {smm} + {\IfBooleanTF{#1}% + {\@ifpackageloaded{#2}% + {#3}% + {\AddToHook{package/after/#2}{#3}}}% + {\AddToHook{package/after/#2}{#3}}% + } +\DeclareDocumentCommand \AtBeginOfClassFile {smm} + {\IfBooleanTF{#1}% + {\@ifclassloaded{#2}% + {#3}% + {\AddToHook{class/before/#2}{#3}}}% + {\AddToHook{class/before/#2}{#3}}% + } +\DeclareDocumentCommand \AtEndOfClassFile {smm} + {\IfBooleanTF{#1}% + {\@ifclassloaded{#2}% + {#3}% + {\AddToHook{class/after/#2}{#3}}}% + {\AddToHook{class/after/#2}{#3}}% + } +\newcommand\AtBeginOfIncludeFile [2] + {\AddToHook{include/before/#1}{#2}} +\newcommand\AtEndOfIncludeFile [2] + {\AddToHook{include/end/#1}{#2}} +\newcommand\AfterIncludeFile [2] + {\AddToHook{include/after/#1}{#2}} +\expandafter\let\csname ver@filehook.sty\endcsname\fmtversion +\@namedef {ver@filehook.sty}{2020/10/01} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\endinput +%% +%% End of file `filehook-ltx.sty'. diff --git a/Master/texmf-dist/tex/latex-dev/base/latex.ltx b/Master/texmf-dist/tex/latex-dev/base/latex.ltx index fa463159956..67fea591af3 100644 --- a/Master/texmf-dist/tex/latex-dev/base/latex.ltx +++ b/Master/texmf-dist/tex/latex-dev/base/latex.ltx @@ -7,6 +7,7 @@ %% ltdirchk.dtx (with options: `initex,2ekernel,dircheck') %% ltplain.dtx (with options: `2ekernel') %% ltvers.dtx (with options: `2ekernel') +%% ltluatex.dtx (with options: `2ekernel') %% ltdefns.dtx (with options: `2ekernel') %% ltalloc.dtx (with options: `2ekernel') %% ltcntrl.dtx (with options: `2ekernel') @@ -41,7 +42,6 @@ %% ltpage.dtx (with options: `2ekernel') %% ltoutput.dtx (with options: `2ekernel') %% ltclass.dtx (with options: `2ekernel,tracerollback') -%% ltluatex.dtx (with options: `2ekernel') %% ltfinal.dtx (with options: `2ekernel') %% %% This is a generated file. @@ -710,7 +710,7 @@ \def\fmtname{LaTeX2e} \edef\fmtversion {2020-10-01} -\def\patch@level{-6} +\def\patch@level{-7} \edef\development@branch@name{develop \the\year-\the\month-\the\day} \iffalse \def\reserved@a#1/#2/#3\@nil{% @@ -808,7 +808,182 @@ \ifx\@check@IncludeInRelease#2\else \PackageError{latexrelease}{skipped IncludeInRelease for tag \string#2}{}% \fi} +%%% From File: ltluatex.dtx +\ifx\directlua\@undefined\else +\ifnum\luatexversion<60 % + \wlog{***************************************************} + \wlog{* LuaTeX version too old for ltluatex support *} + \wlog{***************************************************} + \expandafter\endinput +\fi +\long\def\@gobble#1{} +\long\def\@firstofone#1{#1} +\ifx\e@alloc@attribute@count\@undefined + \countdef\e@alloc@attribute@count=258 +\fi +\def\newattribute#1{% + \e@alloc\attribute\attributedef + \e@alloc@attribute@count\m@ne\e@alloc@top#1% +} +\e@alloc@attribute@count=\z@ +\def\setattribute#1#2{#1=\numexpr#2\relax} +\def\unsetattribute#1{#1=-"7FFFFFFF\relax} +\ifx\e@alloc@ccodetable@count\@undefined + \countdef\e@alloc@ccodetable@count=259 +\fi +\def\newcatcodetable#1{% + \e@alloc\catcodetable\chardef + \e@alloc@ccodetable@count\m@ne{"8000}#1% + \initcatcodetable\allocationnumber +} +\e@alloc@ccodetable@count=\z@ +\newcatcodetable\catcodetable@initex +\newcatcodetable\catcodetable@string +\begingroup + \def\setrangecatcode#1#2#3{% + \ifnum#1>#2 % + \expandafter\@gobble + \else + \expandafter\@firstofone + \fi + {% + \catcode#1=#3 % + \expandafter\setrangecatcode\expandafter + {\number\numexpr#1 + 1\relax}{#2}{#3} + }% + } + \@firstofone{% + \catcodetable\catcodetable@initex + \catcode0=12 % + \catcode13=12 % + \catcode37=12 % + \setrangecatcode{65}{90}{12}% + \setrangecatcode{97}{122}{12}% + \catcode92=12 % + \catcode127=12 % + \savecatcodetable\catcodetable@string + \endgroup + }% +\newcatcodetable\catcodetable@latex +\newcatcodetable\catcodetable@atletter +\begingroup + \def\parseunicodedataI#1;#2;#3;#4\relax{% + \parseunicodedataII#1;#3;#2 First>\relax + }% + \def\parseunicodedataII#1;#2;#3 First>#4\relax{% + \ifx\relax#4\relax + \expandafter\parseunicodedataIII + \else + \expandafter\parseunicodedataIV + \fi + {#1}#2\relax% + }% + \def\parseunicodedataIII#1#2#3\relax{% + \ifnum 0% + \if L#21\fi + \if M#21\fi + >0 % + \catcode"#1=11 % + \fi + }% + \def\parseunicodedataIV#1#2#3\relax{% + \read\unicoderead to \unicodedataline + \if L#2% + \count0="#1 % + \expandafter\parseunicodedataV\unicodedataline\relax + \fi + }% + \def\parseunicodedataV#1;#2\relax{% + \loop + \unless\ifnum\count0>"#1 % + \catcode\count0=11 % + \advance\count0 by 1 % + \repeat + }% + \def\storedpar{\par}% + \chardef\unicoderead=\numexpr\count16 + 1\relax + \openin\unicoderead=UnicodeData.txt % + \loop\unless\ifeof\unicoderead % + \read\unicoderead to \unicodedataline + \unless\ifx\unicodedataline\storedpar + \expandafter\parseunicodedataI\unicodedataline\relax + \fi + \repeat + \closein\unicoderead + \@firstofone{% + \catcode64=12 % + \savecatcodetable\catcodetable@latex + \catcode64=11 % + \savecatcodetable\catcodetable@atletter + } +\endgroup +\ifx\e@alloc@luafunction@count\@undefined + \countdef\e@alloc@luafunction@count=260 +\fi +\def\newluafunction{% + \e@alloc\luafunction\e@alloc@chardef + \e@alloc@luafunction@count\m@ne\e@alloc@top +} +\e@alloc@luafunction@count=\z@ +\ifx\e@alloc@whatsit@count\@undefined + \countdef\e@alloc@whatsit@count=261 +\fi +\def\newwhatsit#1{% + \e@alloc\whatsit\e@alloc@chardef + \e@alloc@whatsit@count\m@ne\e@alloc@top#1% +} +\e@alloc@whatsit@count=\z@ +\ifx\e@alloc@bytecode@count\@undefined + \countdef\e@alloc@bytecode@count=262 +\fi +\def\newluabytecode#1{% + \e@alloc\luabytecode\e@alloc@chardef + \e@alloc@bytecode@count\m@ne\e@alloc@top#1% +} +\e@alloc@bytecode@count=\z@ + +\ifx\e@alloc@luachunk@count\@undefined + \countdef\e@alloc@luachunk@count=263 +\fi +\def\newluachunkname#1{% + \e@alloc\luachunk\e@alloc@chardef + \e@alloc@luachunk@count\m@ne\e@alloc@top#1% + {\escapechar\m@ne + \directlua{lua.name[\the\allocationnumber]="\string#1"}}% +} +\e@alloc@luachunk@count=\z@ +\everyjob\expandafter{% + \the\everyjob + \begingroup + \attributedef\attributezero=0 % + \chardef \charzero =0 % + \countdef \CountZero =0 % + \dimendef \dimenzero =0 % + \mathchardef \mathcharzero =0 % + \muskipdef \muskipzero =0 % + \skipdef \skipzero =0 % + \toksdef \tokszero =0 % + \directlua{require("ltluatex")} + \endgroup +} +\everyjob\expandafter{% + \the\everyjob + \directlua{% + if xpcall(function ()% + require('luaotfload-main')% + end,texio.write_nl) then % + local _void = luaotfload.main ()% + else % + texio.write_nl('Error in luaotfload: reverting to OT1')% + tex.print('\string\\def\string\\encodingdefault{OT1}')% + end % + }% + \let\f@encoding\encodingdefault + \expandafter\let\csname ver@luaotfload.sty\endcsname\fmtversion + } +\fi %%% From File: ltdefns.dtx +\input ltexpl.ltx \def\two@digits#1{\ifnum#1<10 0\fi\number#1} \protected\long\def\typeout#1{\begingroup \set@display@protect @@ -1726,6 +1901,7 @@ Type H <return> for immediate help.}% \newcount\@clubpenalty \@clubpenalty \clubpenalty \def\document{\endgroup + \@expl@sys@load@backend@@ \ifx\@unusedoptionlist\@empty\else \@latex@warning@no@line{Unused global option(s):^^J% \@spaces[\@unusedoptionlist]}% @@ -5776,14 +5952,17 @@ Type H <return> for immediate help.}% \DeclareRobustCommand\centering{% \let\\\@centercr \rightskip\@flushglue\leftskip\@flushglue + \finalhyphendemerits=\z@ \parindent\z@\parfillskip\z@skip} \DeclareRobustCommand\raggedright{% \let\\\@centercr\@rightskip\@flushglue \rightskip\@rightskip + \finalhyphendemerits=\z@ \leftskip\z@skip \parindent\z@} \DeclareRobustCommand\raggedleft{% \let\\\@centercr \rightskip\z@skip\leftskip\@flushglue + \finalhyphendemerits=\z@ \parindent\z@\parfillskip\z@skip} \newskip\@rightskip \@rightskip \z@skip \def\flushleft{\trivlist \raggedright\item\relax} @@ -9180,13 +9359,16 @@ Type H <return> for immediate help.}% \@onlypreamble\@clsextension \@onlypreamble\@pkgextension \def\@pushfilename{% + \@expl@push@filename@@ \xdef\@currnamestack{% {\@currname}% {\@currext}% {\the\catcode`\@}% - \@currnamestack}} + \@currnamestack}% + \@expl@push@filename@aux@@} \@onlypreamble\@pushfilename -\def\@popfilename{\expandafter\@p@pfilename\@currnamestack\@nil} +\def\@popfilename{\expandafter\@p@pfilename\@currnamestack\@nil + \@expl@pop@filename@@} \@onlypreamble\@popfilename \def\@p@pfilename#1#2#3#4\@nil{% \gdef\@currname{#1}% @@ -9952,178 +10134,6 @@ Type H <return> for immediate help.}% \expandafter\@secondoftwo \fi } -%%% From File: ltluatex.dtx -\ifx\directlua\@undefined\else -\ifnum\luatexversion<60 % - \wlog{***************************************************} - \wlog{* LuaTeX version too old for ltluatex support *} - \wlog{***************************************************} - \expandafter\endinput -\fi -\ifx\e@alloc@attribute@count\@undefined - \countdef\e@alloc@attribute@count=258 -\fi -\def\newattribute#1{% - \e@alloc\attribute\attributedef - \e@alloc@attribute@count\m@ne\e@alloc@top#1% -} -\e@alloc@attribute@count=\z@ -\def\setattribute#1#2{#1=\numexpr#2\relax} -\def\unsetattribute#1{#1=-"7FFFFFFF\relax} -\ifx\e@alloc@ccodetable@count\@undefined - \countdef\e@alloc@ccodetable@count=259 -\fi -\def\newcatcodetable#1{% - \e@alloc\catcodetable\chardef - \e@alloc@ccodetable@count\m@ne{"8000}#1% - \initcatcodetable\allocationnumber -} -\e@alloc@ccodetable@count=\z@ -\newcatcodetable\catcodetable@initex -\newcatcodetable\catcodetable@string -\begingroup - \def\setrangecatcode#1#2#3{% - \ifnum#1>#2 % - \expandafter\@gobble - \else - \expandafter\@firstofone - \fi - {% - \catcode#1=#3 % - \expandafter\setrangecatcode\expandafter - {\number\numexpr#1 + 1\relax}{#2}{#3} - }% - } - \@firstofone{% - \catcodetable\catcodetable@initex - \catcode0=12 % - \catcode13=12 % - \catcode37=12 % - \setrangecatcode{65}{90}{12}% - \setrangecatcode{97}{122}{12}% - \catcode92=12 % - \catcode127=12 % - \savecatcodetable\catcodetable@string - \endgroup - }% -\newcatcodetable\catcodetable@latex -\newcatcodetable\catcodetable@atletter -\begingroup - \def\parseunicodedataI#1;#2;#3;#4\relax{% - \parseunicodedataII#1;#3;#2 First>\relax - }% - \def\parseunicodedataII#1;#2;#3 First>#4\relax{% - \ifx\relax#4\relax - \expandafter\parseunicodedataIII - \else - \expandafter\parseunicodedataIV - \fi - {#1}#2\relax% - }% - \def\parseunicodedataIII#1#2#3\relax{% - \ifnum 0% - \if L#21\fi - \if M#21\fi - >0 % - \catcode"#1=11 % - \fi - }% - \def\parseunicodedataIV#1#2#3\relax{% - \read\unicoderead to \unicodedataline - \if L#2% - \count0="#1 % - \expandafter\parseunicodedataV\unicodedataline\relax - \fi - }% - \def\parseunicodedataV#1;#2\relax{% - \loop - \unless\ifnum\count0>"#1 % - \catcode\count0=11 % - \advance\count0 by 1 % - \repeat - }% - \def\storedpar{\par}% - \chardef\unicoderead=\numexpr\count16 + 1\relax - \openin\unicoderead=UnicodeData.txt % - \loop\unless\ifeof\unicoderead % - \read\unicoderead to \unicodedataline - \unless\ifx\unicodedataline\storedpar - \expandafter\parseunicodedataI\unicodedataline\relax - \fi - \repeat - \closein\unicoderead - \@firstofone{% - \catcode64=12 % - \savecatcodetable\catcodetable@latex - \catcode64=11 % - \savecatcodetable\catcodetable@atletter - } -\endgroup -\ifx\e@alloc@luafunction@count\@undefined - \countdef\e@alloc@luafunction@count=260 -\fi -\def\newluafunction{% - \e@alloc\luafunction\e@alloc@chardef - \e@alloc@luafunction@count\m@ne\e@alloc@top -} -\e@alloc@luafunction@count=\z@ -\ifx\e@alloc@whatsit@count\@undefined - \countdef\e@alloc@whatsit@count=261 -\fi -\def\newwhatsit#1{% - \e@alloc\whatsit\e@alloc@chardef - \e@alloc@whatsit@count\m@ne\e@alloc@top#1% -} -\e@alloc@whatsit@count=\z@ -\ifx\e@alloc@bytecode@count\@undefined - \countdef\e@alloc@bytecode@count=262 -\fi -\def\newluabytecode#1{% - \e@alloc\luabytecode\e@alloc@chardef - \e@alloc@bytecode@count\m@ne\e@alloc@top#1% -} -\e@alloc@bytecode@count=\z@ - -\ifx\e@alloc@luachunk@count\@undefined - \countdef\e@alloc@luachunk@count=263 -\fi -\def\newluachunkname#1{% - \e@alloc\luachunk\e@alloc@chardef - \e@alloc@luachunk@count\m@ne\e@alloc@top#1% - {\escapechar\m@ne - \directlua{lua.name[\the\allocationnumber]="\string#1"}}% -} -\e@alloc@luachunk@count=\z@ -\everyjob\expandafter{% - \the\everyjob - \begingroup - \attributedef\attributezero=0 % - \chardef \charzero =0 % - \countdef \CountZero =0 % - \dimendef \dimenzero =0 % - \mathchardef \mathcharzero =0 % - \muskipdef \muskipzero =0 % - \skipdef \skipzero =0 % - \toksdef \tokszero =0 % - \directlua{require("ltluatex")} - \endgroup -} -\everyjob\expandafter{% - \the\everyjob - \directlua{% - if xpcall(function ()% - require('luaotfload-main')% - end,texio.write_nl) then % - local _void = luaotfload.main ()% - else % - texio.write_nl('Error in luaotfload: reverting to OT1')% - tex.print('\string\\def\string\\encodingdefault{OT1}')% - end % - }% - \let\f@encoding\encodingdefault - \expandafter\let\csname ver@luaotfload.sty\endcsname\fmtversion - } -\fi %%% From File: ltfinal.dtx \tracingstats1 \newcount\@lowpenalty @@ -10209,6 +10219,8 @@ Type H <return> for immediate help.}% \lccode 127=127 % alternate hyphen char \lccode 23 =23 % textcompwordmark in T1 \fi +\@expl@finalise@setup@@ +\def\@expl@finalise@setup@@{} \ifx\XeTeXuseglyphmetrics\@undefined \else \XeTeXuseglyphmetrics=1 % @@ -10422,7 +10434,6 @@ Type H <return> for immediate help.}% \dh\DH\dj\DJ\l\L\ng\NG\ss\SS\th\TH} \protected@edef\MakeUppercase#1{\MakeUppercase{#1}} \protected@edef\MakeLowercase#1{\MakeLowercase{#1}} -\input{ltexpl.ltx} \let\reserved@a\@filelist \let\reserved@b=\@undefined \let\reserved@c=\@undefined @@ -10441,7 +10452,12 @@ Type H <return> for immediate help.}% \endgroup} \let\@filelist\@gobble \def\@addtofilelist#1{\xdef\@filelist{\@filelist,#1}}% -\AtBeginDocument{\reinstall@nfss@defs\init@series@setup} +\input lthooks.ltx +\input ltshipout.ltx +\input ltfilehook.ltx + +\g@addto@macro\@kernel@after@env@document@begin + {\reinstall@nfss@defs\init@series@setup} \makeatother \errorstopmode \dump diff --git a/Master/texmf-dist/tex/latex-dev/base/latexrelease.sty b/Master/texmf-dist/tex/latex-dev/base/latexrelease.sty index 11831f0601c..b5ac7332d94 100644 --- a/Master/texmf-dist/tex/latex-dev/base/latexrelease.sty +++ b/Master/texmf-dist/tex/latex-dev/base/latexrelease.sty @@ -1182,6 +1182,64 @@ of this package available from CTAN} \let\noprotrusion\@undefined \EndIncludeInRelease %%% From File: ltfiles.dtx +\IncludeInRelease{2020/06/05}% + {\document}{Added hook to load l3backend code}% +\def\document{\endgroup + \@expl@sys@load@backend@@ + \ifx\@unusedoptionlist\@empty\else + \@latex@warning@no@line{Unused global option(s):^^J% + \@spaces[\@unusedoptionlist]}% + \fi + \@colht\textheight + \@colroom\textheight \vsize\textheight + \columnwidth\textwidth + \@clubpenalty\clubpenalty + \if@twocolumn + \advance\columnwidth -\columnsep + \divide\columnwidth\tw@ \hsize\columnwidth \@firstcolumntrue + \fi + \hsize\columnwidth \linewidth\hsize + \begingroup\@floatplacement\@dblfloatplacement + \makeatletter\let\@writefile\@gobbletwo + \global \let \@multiplelabels \relax + \@input{\jobname.aux}% + \endgroup + \if@filesw + \immediate\openout\@mainaux\jobname.aux + \immediate\write\@mainaux{\relax}% + \fi + \process@table + \let\glb@currsize\@empty % Force math initialization. + \normalsize + \everypar{}% + \ifx\normalsfcodes\@empty + \ifnum\sfcode`\.=\@m + \let\normalsfcodes\frenchspacing + \else + \let\normalsfcodes\nonfrenchspacing + \fi + \fi + \ifx\document@default@language\m@ne + \chardef\document@default@language\language + \fi + \@noskipsecfalse + \let \@refundefined \relax + \let\AtBeginDocument\@firstofone + \@begindocumenthook + \ifdim\topskip<1sp\global\topskip 1sp\relax\fi + \global\@maxdepth\maxdepth + \global\let\@begindocumenthook\@undefined + \ifx\@listfiles\@undefined + \global\let\@filelist\relax + \global\let\@addtofilelist\@gobble + \fi + \gdef\do##1{\global\let ##1\@notprerr}% + \@preamblecmds + \global\let \@nodocument \relax + \global\let\do\noexpand + \ignorespaces} +\EndIncludeInRelease + \IncludeInRelease{2017/04/15}% {\document}{Save language for hyphenation}% \def\document{\endgroup @@ -1238,6 +1296,7 @@ of this package available from CTAN} \global\let\do\noexpand \ignorespaces} \EndIncludeInRelease + \IncludeInRelease{0000/00/00}% {\document}{Save language for hyphenation} \def\document{\endgroup @@ -2828,6 +2887,41 @@ of this package available from CTAN} }% \EndIncludeInRelease %%% From File: ltclass.dtx + +\IncludeInRelease{2020/10/01}{\@pushfilename}% + {Add \@expl@push@filename@@ and \@expl@push@filename@aux@@}% +\def\@pushfilename{% + \@expl@push@filename@@ + \xdef\@currnamestack{% + {\@currname}% + {\@currext}% + {\the\catcode`\@}% + \@currnamestack}% + \@expl@push@filename@aux@@} +\EndIncludeInRelease + +\IncludeInRelease{0000/00/00}{\@pushfilename}% + {Add \@expl@push@filename@@ and \@expl@push@filename@aux@@}% +\def\@pushfilename{% + \xdef\@currnamestack{% + {\@currname}% + {\@currext}% + {\the\catcode`\@}% + \@currnamestack}} +\EndIncludeInRelease +\@onlypreamble\@pushfilename + +\IncludeInRelease{2020/10/01}{\@popfilename}% + {Add \@expl@pop@filename@@}% +\def\@popfilename{\expandafter\@p@pfilename\@currnamestack\@nil + \@expl@pop@filename@@} +\EndIncludeInRelease + +\IncludeInRelease{0000/00/00}{\@pushfilename}% + {Add \@expl@push@filename@@ and \@expl@push@filename@aux@@}% +\def\@popfilename{\expandafter\@p@pfilename\@currnamestack\@nil} +\EndIncludeInRelease +\@onlypreamble\@popfilename \IncludeInRelease{2020/10/01}% {\IfFormatAtLeastTF}{Test format date}% \def\IfFormatAtLeastTF{\@ifl@t@r\fmtversion} @@ -6651,8 +6745,27 @@ of this package available from CTAN} \def\@icentercr[#1]{\vskip #1\ignorespaces} \EndIncludeInRelease +\IncludeInRelease{2020/10/01}% + {\centering}{Set finaldhypendemerits}% +\DeclareRobustCommand\centering{% + \let\\\@centercr + \rightskip\@flushglue\leftskip\@flushglue + \finalhyphendemerits=\z@ + \parindent\z@\parfillskip\z@skip} +\DeclareRobustCommand\raggedright{% + \let\\\@centercr\@rightskip\@flushglue \rightskip\@rightskip + \finalhyphendemerits=\z@ + \leftskip\z@skip + \parindent\z@} +\DeclareRobustCommand\raggedleft{% + \let\\\@centercr + \rightskip\z@skip\leftskip\@flushglue + \finalhyphendemerits=\z@ + \parindent\z@\parfillskip\z@skip} +\EndIncludeInRelease \IncludeInRelease{2019/10/01}% {\centering}{Make commands robust}% + \DeclareRobustCommand\centering{% \let\\\@centercr \rightskip\@flushglue\leftskip\@flushglue @@ -6666,6 +6779,7 @@ of this package available from CTAN} \rightskip\z@skip\leftskip\@flushglue \parindent\z@\parfillskip\z@skip} \EndIncludeInRelease + \IncludeInRelease{0000/00/00}% {\centering}{Make commands robust}% @@ -6819,6 +6933,8 @@ of this package available from CTAN} \wlog{***************************************************} \expandafter\endinput \fi +\long\def\@gobble#1{} +\long\def\@firstofone#1{#1} \ifx\e@alloc@attribute@count\@undefined \countdef\e@alloc@attribute@count=258 \fi @@ -7012,38 +7128,71 @@ of this package available from CTAN} \EndIncludeInRelease \fi %%% From File: ltexpl.dtx -\IncludeInRelease{2020/02/02}% +\IncludeInRelease{2020/10/01}% {expl3}{Pre-load expl3}% \expandafter\ifx\csname tex\string _let:D\endcsname\relax - \IfFileExists{expl3.ltx} - {% - \ifnum0% - \ifdefined\pdffilesize 1\fi - \ifdefined\filesize 1\fi - \ifdefined\luatexversion\ifnum\luatexversion>94 1\fi\fi - >0 % - \expandafter\@firstofone - \else - \message{Skipping expl3-dependent extensions} - \expandafter\@gobble - \fi - } - {% - \message{Skipping expl3-dependent extensions}% - \@gobble - }% - {% - \input{expl3.ltx} - \ifdefined\NewDocumentCommand - \else - \IfFileExists{xparse.ltx} - {\input{xparse.ltx}} - {}% - \fi - }% + \expandafter\@firstofone \else - \GenericInfo{}{Skipping: expl3 code already part of the format} + \GenericInfo{}{Skipping: expl3 code already part of the format}% + \expandafter\@gobble \fi + {% + \IfFileExists{expl3.ltx} + {% + \ifnum0% + \ifdefined\pdffilesize 1\fi + \ifdefined\filesize 1\fi + \ifdefined\luatexversion\ifnum\luatexversion>94 1\fi\fi + \ifdefined\kanjiskip 1\fi + >0 % + \expandafter\@firstofone + \else + \@latex@error{% + LaTeX requires the e-TeX primitives and additional\MessageBreak + functionality available in the engines:\MessageBreak + - pdfTeX v1.40\MessageBreak + - XeTeX v0.99992\MessageBreak + - LuaTeX v0.95\MessageBreak + - e-(u)pTeX mid-2012\MessageBreak + or later% + }\@ehd \expandafter\@gobble + \fi + } + {% + \@latex@error{LaTeX requires expl3}\@ehd + \@gobble + }% + {% + \input expl3.ltx + \ifdefined\NewDocumentCommand + \else + \IfFileExists{xparse.ltx} + {\input xparse.ltx } + {}% + \fi + }% + } +\EndIncludeInRelease + +\IncludeInRelease{2020/02/02}% + {expl3}{Pre-load expl3}% +\IfFileExists{expl3.ltx} + {% + \ifnum0% + \ifdefined\pdffilesize 1\fi + \ifdefined\filesize 1\fi + \ifdefined\luatexversion\ifnum\luatexversion>94 1\fi\fi + >0 % + \else + \message{Skipping expl3-dependent extensions} + \expandafter\@gobbletwo + \fi + } + {% + \message{Skipping expl3-dependent extensions}% + \@gobbletwo + }% +\input{expl3.ltx} \EndIncludeInRelease \IncludeInRelease{2020/10/01}% {\@expl@tl@trim@spaces@apply@@nN} @@ -7318,6 +7467,211 @@ of this package available from CTAN} \let\DeclareFontEncoding@saved\@undefined \let\inputencodingname\@undefined \EndIncludeInRelease +\IncludeInRelease{2020/10/01}% + {\ShowHook}{The hook management}% +\input lthooks.ltx +\input ltshipout.ltx +\input ltfilehook.ltx +\EndIncludeInRelease +\IncludeInRelease{0000/00/00}% + {\ShowHook}{The hook management}% + + +\DeclareRobustCommand*\begin[1]{% + \@ifundefined{#1}% + {\def\reserved@a{\@latex@error{Environment #1 undefined}\@eha}}% + {\def\reserved@a{\def\@currenvir{#1}% + \edef\@currenvline{\on@line}% + \csname #1\endcsname}}% + \@ignorefalse + \begingroup\@endpefalse\reserved@a} + +\@namedef{end }#1{% + \csname end#1\endcsname\@checkend{#1}% + \expandafter\endgroup\if@endpe\@doendpe\fi + \if@ignore\@ignorefalse\ignorespaces\fi} + +\DeclareDocumentCommand \NewHook {m}{} +\DeclareDocumentCommand \NewReversedHook {m}{} +\DeclareDocumentCommand \NewMirroredHookPair {mm}{} + +\DeclareDocumentCommand \AddToHookNext {m+m}{} +\DeclareDocumentCommand \RemoveFromHook {mo}{} +\def \UseHook #1{} +\def \UseOneTimeHook #1{} +\def \ShowHook #1{} +\let \DebugHookOn \@empty +\let \DebugHookOff\@empty + +\DeclareDocumentCommand \DeclareHookRule {mmmm}{} +\DeclareDocumentCommand \DeclareDefaultHookRule {mmm}{} +\DeclareDocumentCommand \ClearHookRule {mmm}{} +\DeclareExpandableDocumentCommand \IfHookExistTF {mmm}{#3} +\DeclareExpandableDocumentCommand \IfHookEmptyTF {mmm}{#2} + +\DeclareRobustCommand\AtBeginDocument{\g@addto@macro\@begindocumenthook} +\DeclareRobustCommand\AtEndDocument{\g@addto@macro\@enddocumenthook} + +\let\AtBeginEnvironment \@undefined +\let\AtEndEnvironment \@undefined +\let\BeforeBeginEnvironment \@undefined +\let\AfterEndEnvironment \@undefined + +\def\@pushfilename{% + \@expl@push@filename@@ + \xdef\@currnamestack{% + {\@currname}% + {\@currext}% + {\the\catcode`\@}% + \@currnamestack}% + \@expl@push@filename@aux@@} +\def\@popfilename{\expandafter\@p@pfilename\@currnamestack\@nil + \@expl@pop@filename@@} + + +% next goes away again when etoolbox is updated ... +\expandafter\let\csname ver@etoolbox.sty\endcsname\@undefined + +\def\document{\endgroup + \@expl@sys@load@backend@@ + \ifx\@unusedoptionlist\@empty\else + \@latex@warning@no@line{Unused global option(s):^^J% + \@spaces[\@unusedoptionlist]}% + \fi + \@colht\textheight + \@colroom\textheight \vsize\textheight + \columnwidth\textwidth + \@clubpenalty\clubpenalty + \if@twocolumn + \advance\columnwidth -\columnsep + \divide\columnwidth\tw@ \hsize\columnwidth \@firstcolumntrue + \fi + \hsize\columnwidth \linewidth\hsize + \begingroup\@floatplacement\@dblfloatplacement + \makeatletter\let\@writefile\@gobbletwo + \global \let \@multiplelabels \relax + \@input{\jobname.aux}% + \endgroup + \if@filesw + \immediate\openout\@mainaux\jobname.aux + \immediate\write\@mainaux{\relax}% + \fi + \process@table + \let\glb@currsize\@empty % Force math initialization. + \normalsize + \everypar{}% + \ifx\normalsfcodes\@empty + \ifnum\sfcode`\.=\@m + \let\normalsfcodes\frenchspacing + \else + \let\normalsfcodes\nonfrenchspacing + \fi + \fi + \ifx\document@default@language\m@ne + \chardef\document@default@language\language + \fi + \@noskipsecfalse + \let \@refundefined \relax + \let\AtBeginDocument\@firstofone + \@begindocumenthook + \ifdim\topskip<1sp\global\topskip 1sp\relax\fi + \global\@maxdepth\maxdepth + \global\let\@begindocumenthook\@undefined + \ifx\@listfiles\@undefined + \global\let\@filelist\relax + \global\let\@addtofilelist\@gobble + \fi + \gdef\do##1{\global\let ##1\@notprerr}% + \@preamblecmds + \global\let \@nodocument \relax + \global\let\do\noexpand + \ignorespaces} + +\def\enddocument{% + \let\AtEndDocument\@firstofone + \@enddocumenthook + \@checkend{document}% + \clearpage + \begingroup + \if@filesw + \immediate\closeout\@mainaux + \let\@setckpt\@gobbletwo + \let\@newl@bel\@testdef + \@tempswafalse + \makeatletter \@@input\jobname.aux + \fi + \@dofilelist + \ifdim \font@submax >\fontsubfuzz\relax + \@font@warning{Size substitutions with differences\MessageBreak + up to \font@submax\space have occurred.\@gobbletwo}% + \fi + \@defaultsubs + \@refundefined + \if@filesw + \ifx \@multiplelabels \relax + \if@tempswa + \@latex@warning@no@line{Label(s) may have changed. + Rerun to get cross-references right}% + \fi + \else + \@multiplelabels + \fi + \fi + \endgroup + \deadcycles\z@\@@end} + +\expandafter\let\csname ver@atveryend.sty\endcsname\@undefined +\let\AfterLastShipout \@undefined +\let\AtVeryEndDocument \@undefined +\let\AtEndAfterFileList \@undefined +\let\AtVeryVeryEnd \@undefined +\let\BeforeClearDocument \@undefined + + +\expandafter\let\expandafter\shipout\csname tex_shipout:D\endcsname + +\let \ShipoutBox\@undefined +\let \ReadonlyShipoutCounter \@undefined +\let \c@totalpages \@undefined +\let \thetotalpages \@undefined + +\let \DiscardShipoutBox \@undefined +\let \DebugShipoutOn \@undefined +\let \DebugShipoutOff \@undefined + +\DeclareRobustCommand \AtBeginDvi [1]{% + \global \setbox \@begindvibox + \vbox{\unvbox \@begindvibox #1}% +} + +\let \AtBeginShipout \@undefined +\let \AtBeginShipoutNext \@undefined + +\let \AtBeginShipoutFirst \@undefined + +\let \ShipoutBoxHeight \@undefined +\let \ShipoutBoxDepth \@undefined +\let \ShipoutBoxWidth \@undefined + +\let \AtBeginShipoutDiscard \@undefined + +\let \AtBeginShipoutAddToBox \@undefined +\let \AtBeginShipoutAddToBoxForeground \@undefined +\let \AtBeginShipoutUpperLeft \@undefined +\let \AtBeginShipoutUpperLeftForeground \@undefined + +\expandafter\let\csname ver@atbegshi.sty\endcsname \@undefined + +\let \EveryShipout \@undefined +\let \AtNextShipout \@undefined +\expandafter \let \csname ver@everyshi.sty\endcsname \@undefined + +\let \AtEndDvi \@undefined +\expandafter\let \csname ver@atenddvi.sty\endcsname \@undefined + +\AtBeginDocument{\reinstall@nfss@defs\init@series@setup} + +\EndIncludeInRelease \endinput %% %% End of file `latexrelease.sty'. diff --git a/Master/texmf-dist/tex/latex-dev/base/ltexpl.ltx b/Master/texmf-dist/tex/latex-dev/base/ltexpl.ltx index b0e023f3337..64908ce7448 100644 --- a/Master/texmf-dist/tex/latex-dev/base/ltexpl.ltx +++ b/Master/texmf-dist/tex/latex-dev/base/ltexpl.ltx @@ -42,36 +42,77 @@ %% and covered by LPPL is defined by the unpacking scripts (with %% extension .ins) which are part of the distribution. %%% From File: ltexpl.dtx +\def\@expl@sys@load@backend@@{} +\def\@expl@push@filename@@{} +\def\@expl@push@filename@aux@@{} +\def\@expl@pop@filename@@{} +\def\@expl@finalise@setup@@{} +\long\def\@gobble#1{} +\long\def\@firstofone#1{#1} +\long\def\@firstoftwo#1#2{#1} +\long\def\@secondoftwo#1#2{#2} +\long\def\IfFileExists#1{% + \openin\@inputcheck"#1" % + \ifeof\@inputcheck + \expandafter\@secondoftwo + \else + \closein\@inputcheck + \expandafter\@firstoftwo + \fi} +\long\def\@ifnextchar#1#2#3{% + \let\reserved@d=#1% + \def\reserved@a{#2}% + \def\reserved@b{#3}% + \futurelet\@let@token\@ifnch} +\def\@ifnch{% + \ifx\@let@token\reserved@d + \expandafter\reserved@a + \else + \expandafter\reserved@b + \fi} \expandafter\ifx\csname tex\string _let:D\endcsname\relax - \IfFileExists{expl3.ltx} - {% - \ifnum0% - \ifdefined\pdffilesize 1\fi - \ifdefined\filesize 1\fi - \ifdefined\luatexversion\ifnum\luatexversion>94 1\fi\fi - >0 % - \expandafter\@firstofone - \else - \message{Skipping expl3-dependent extensions} - \expandafter\endinput - \fi - } - {% - \message{Skipping expl3-dependent extensions}% - \endinput - }% - {% - \input{expl3.ltx} - \ifdefined\NewDocumentCommand - \else - \IfFileExists{xparse.ltx} - {\input{xparse.ltx}} - {}% - \fi - }% + \expandafter\@firstofone \else - \GenericInfo{}{Skipping: expl3 code already part of the format} + \GenericInfo{}{Skipping: expl3 code already part of the format}% + \expandafter\endinput \fi + {% + \IfFileExists{expl3.ltx} + {% + \ifnum0% + \ifdefined\pdffilesize 1\fi + \ifdefined\filesize 1\fi + \ifdefined\luatexversion\ifnum\luatexversion>94 1\fi\fi + \ifdefined\kanjiskip 1\fi + >0 % + \expandafter\@firstofone + \else + \def~{ }\def\MessageBreak{^^J~~~~~~~~~~~~~~~}% + \errmessage{LaTeX Error: + LaTeX requires the e-TeX primitives and additional\MessageBreak + functionality available in the engines:\MessageBreak + - pdfTeX v1.40\MessageBreak + - XeTeX v0.99992\MessageBreak + - LuaTeX v0.95\MessageBreak + - e-(u)pTeX mid-2012\MessageBreak + or later% + }\batchmode \read -1 to \reserved@a + \fi + } + {% + \errmessage{LaTeX requires expl3}% + \batchmode \read -1 to \reserved@a + }% + {% + \input expl3.ltx + \ifdefined\NewDocumentCommand + \else + \IfFileExists{xparse.ltx} + {\input xparse.ltx } + {}% + \fi + }% + } \ExplSyntaxOn \cs_new_eq:NN \@expl@tl@trim@spaces@apply@@nN \tl_trim_spaces_apply:nN \ExplSyntaxOff diff --git a/Master/texmf-dist/tex/latex-dev/base/ltfilehook.ltx b/Master/texmf-dist/tex/latex-dev/base/ltfilehook.ltx new file mode 100644 index 00000000000..b164900b594 --- /dev/null +++ b/Master/texmf-dist/tex/latex-dev/base/ltfilehook.ltx @@ -0,0 +1,343 @@ +%% +%% This is file `ltfilehook.ltx', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% ltfilehook.dtx (with options: `2ekernel') +%% +%% This is a generated file. +%% +%% Copyright 2020 Frank Mittelbach +%% +%% This file was generated from file(s) of the LaTeX `lthooks Bundle'. +%% -------------------------------------------------------------------------- +%% +%% It 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 file may only be distributed together with a copy of the LaTeX +%% `lthooks Bundle'. You may however distribute the `lthooks Bundle' +%% without such generated files. +%% +%% The newest sources can be found below +%% +%% https://github.com/FrankMittelbach/fmitex/ +%% +%% where one can also log issues in case there are any. +%% +%% +%% File: ltfilehook.dtx (C) Copyright 2020 Frank Mittelbach, LaTeX Team +\providecommand\ltfilehookversion{v0.9a} +\providecommand\ltfilehookdate{2020/07/19} +\def\CurrentFile{} +\def\CurrentFilePath{} +\ExplSyntaxOn +\tl_new:N \l__filehook_internal_tl +\cs_new_protected:Npn \@filehook@set@curr@file #1 + { \exp_args:NV \__filehook_normalise_file_name:n #1 } +\cs_new_protected:Npn \__filehook_normalise_file_name:n #1 + { + \file_if_exist:nTF {#1} + { + \exp_args:Nx \file_parse_full_name:nNNN + { \file_full_name:n {#1} } + } + { \file_parse_full_name:nNNN {#1} } + \CurrentFilePath \CurrentFile \l__filehook_internal_tl + \tl_set:Nx \CurrentFile { \CurrentFile \l__filehook_internal_tl } + } +\seq_new:N \g__filehook_input_file_seq +\cs_new_protected:Npn \@filehook@file@push + { + \seq_gpush:Nx \g__filehook_input_file_seq + { { \CurrentFilePath } { \CurrentFile } } + } +\cs_new_protected:Npn \@filehook@file@pop + { + \seq_gpop:NNTF \g__filehook_input_file_seq \l__filehook_internal_tl + { \exp_after:wN \__filehook_file_pop_assign:nn \l__filehook_internal_tl } + { \ERROR_should_not_happen } + } +\cs_new_protected:Npn \__filehook_file_pop_assign:nn #1 #2 + { + \tl_set:Nn \CurrentFilePath {#1} + \tl_set:Nn \CurrentFile {#2} + } +\ExplSyntaxOff +\let\InputIfFileExists\@undefined +\DeclareRobustCommand \InputIfFileExists[3]{% + \@filehook@file@push + \IfFileExists{#1}% + {% + \edef\reserved@a{\@filef@und + \def\noexpand\CurrentFile{\CurrentFile}% + \def\noexpand\CurrentFilePath{\CurrentFilePath}% + }% + \expandafter\@swaptwoargs\expandafter + {\reserved@a}% + {% + #2% + \@addtofilelist{#1}% + \UseHook{file/before}% + \UseHook{file/before/\CurrentFile}% + \@@input + }% + \UseHook{file/after/\CurrentFile}% + \UseHook{file/after}% + \@filehook@file@pop + }% + {\@filehook@file@pop #3}% +} +\def\set@curr@file#1{% + \begingroup + \escapechar\m@ne + \xdef\@curr@file{% + \expandafter\expandafter\expandafter\unquote@name + \expandafter\expandafter\expandafter{% + \expandafter\string + \csname\@firstofone#1\@empty\endcsname}}% + \endgroup + \@filehook@set@curr@file{\@curr@file}% +} +\def\load@onefilewithoptions#1[#2][#3]#4{% + \@pushfilename + \xdef\@currname{#1}% + \global\let\@currext#4% + \let\CurrentOption\@empty + \@reset@ptions + \makeatletter + \def\reserved@a{% + \@ifl@aded\@currext{#1}% + {\@if@ptions\@currext{#1}{#2}{}% + {\@latex@error + {Option clash for \@cls@pkg\space #1}% + {The package #1 has already been loaded + with options:\MessageBreak + \space\space[\@ptionlist{#1.\@currext}]\MessageBreak + There has now been an attempt to load it + with options\MessageBreak + \space\space[#2]\MessageBreak + Adding the global options:\MessageBreak + \space\space + \@ptionlist{#1.\@currext},#2\MessageBreak + to your \noexpand\documentclass declaration may fix this.% + \MessageBreak + Try typing \space <return> \space to proceed.}}}% + {\@pass@ptions\@currext{#2}{#1}% + \global\expandafter + \let\csname ver@\@currname.\@currext\endcsname\@empty + \expandafter\let\csname\@currname.\@currext-h@@k\endcsname\@empty + \InputIfFileExists + {\@currname.\@currext}% + {% + \ifx\@currext\@pkgextension + \UseHook{package/before}% + \UseHook{package/before/\@currname}% + \else + \ifx\@currext\@clsextension + \UseHook{class/before}% + \UseHook{class/before/\@currname}% + \fi + \fi + \@filehook@file@push + }% + {\@missingfileerror\@currname\@currext}% + \let\@unprocessedoptions\@@unprocessedoptions + \csname\@currname.\@currext-h@@k\endcsname + \expandafter\let\csname\@currname.\@currext-h@@k\endcsname + \@undefined + \ifx\@currext\@pkgextension + \UseHook{package/after/\@currname}% + \UseHook{package/after}% + \else + \ifx\@currext\@clsextension + \UseHook{class/after/\@currname}% + \UseHook{class/after}% + \fi + \fi + \@filehook@file@pop + \@unprocessedoptions}% + \@ifl@ter\@currext{#1}{#3}{}% + {\@latex@warning@no@line + {You have requested,\on@line, + version\MessageBreak + `#3' of \@cls@pkg\space #1,\MessageBreak + but only version\MessageBreak + `\csname ver@#1.\@currext\endcsname'\MessageBreak + is available}}% + \ifx\@currext\@clsextension\let\LoadClass\@twoloadclasserror\fi + \@popfilename + \@reset@ptions}% + \reserved@a} +\@ifl@t@r\fmtversion{2020/10/01} +{% +\def\load@onefilewithoptions#1[#2][#3]#4{% + \@pushfilename + \xdef\@currname{#1}% + \global\let\@currext#4% + \let\CurrentOption\@empty + \@reset@ptions + \makeatletter + \def\reserved@a{% + \@ifl@aded\@currext{#1}% + {\@if@ptions\@currext{#1}{#2}{}% + {\@latex@error + {Option clash for \@cls@pkg\space #1}% + {The package #1 has already been loaded + with options:\MessageBreak + \space\space[\@ptionlist{#1.\@currext}]\MessageBreak + There has now been an attempt to load it + with options\MessageBreak + \space\space[#2]\MessageBreak + Adding the global options:\MessageBreak + \space\space + \@ptionlist{#1.\@currext},#2\MessageBreak + to your \noexpand\documentclass declaration may fix this.% + \MessageBreak + Try typing \space <return> \space to proceed.}}}% + {\@pass@ptions\@currext{#2}{#1}% + \global\expandafter + \let\csname ver@\@currname.\@currext\endcsname\@empty + \expandafter\let\csname\@currname.\@currext-h@@k\endcsname\@empty + \InputIfFileExists + {\@currname.\@currext}% + {% + \ifx\@currext\@pkgextension + \UseHook{package/before}% + \UseHook{package/before/\@currname}% + \else + \ifx\@currext\@clsextension + \UseHook{class/before}% + \UseHook{class/before/\@currname}% + \fi + \fi + \@filehook@file@push + }% + {\@missingfileerror\@currname\@currext}% + \expandafter\let\csname unprocessedoptions-\@currname.\@currext\endcsname + \@@unprocessedoptions + \csname\@currname.\@currext-h@@k\endcsname + \expandafter\let\csname\@currname.\@currext-h@@k\endcsname + \@undefined + \ifx\@unprocessedoptions\relax + \let\@unprocessedoptions\@undefined + \else + \csname unprocessedoptions-\@currname.\@currext\endcsname + \fi + \expandafter\let + \csname unprocessedoptions-\@currname.\@currext\endcsname + \@undefined + \ifx\@currext\@pkgextension + \UseHook{package/after/\@currname}% + \UseHook{package/after}% + \else + \ifx\@currext\@clsextension + \UseHook{class/after/\@currname}% + \UseHook{class/after}% + \fi + \fi + \@filehook@file@pop + }% + \@ifl@ter\@currext{#1}{#3}{}% + {\@latex@warning@no@line + {You have requested,\on@line, + version\MessageBreak + `#3' of \@cls@pkg\space #1,\MessageBreak + but only version\MessageBreak + `\csname ver@#1.\@currext\endcsname'\MessageBreak + is available}}% + \ifx\@currext\@clsextension\let\LoadClass\@twoloadclasserror\fi + \@popfilename + \@reset@ptions}% + \reserved@a} +}{}% + +\def\@include#1 {% + \clearpage + \if@filesw + \immediate\write\@mainaux{\string\@input{#1.aux}}% + \fi + \@tempswatrue + \if@partsw + \@tempswafalse + \edef\reserved@b{#1}% + \@for\reserved@a:=\@partlist\do + {\ifx\reserved@a\reserved@b\@tempswatrue\fi}% + \fi + \if@tempswa + \let\@auxout\@partaux + \if@filesw + \immediate\openout\@partaux #1.aux + \immediate\write\@partaux{\relax}% + \fi + \set@curr@file{#1}% + \UseHook{include/before}% + \UseHook{include/before/#1}% + \@input@{#1.tex}% + \UseHook{include/end/#1}% + \UseHook{include/end}% + \clearpage + \UseHook{include/after/#1}% + \UseHook{include/after}% + \clearpage + \@writeckpt{#1}% + \if@filesw + \immediate\closeout\@partaux + \fi + \else + \deadcycles\z@ + \@nameuse{cp@#1}% + \fi + \let\@auxout\@mainaux +} +\@ifl@t@r\fmtversion{2020/10/01} +{% +\def\@include#1 {% + \clearpage + \if@filesw + \immediate\write\@mainaux{\string\@input{"#1.aux"}}% + \fi + \@tempswatrue + \if@partsw + \@tempswafalse + \edef\reserved@b{#1}% + \@for\reserved@a:=\@partlist\do + {\ifx\reserved@a\reserved@b\@tempswatrue\fi}% + \fi + \if@tempswa + \let\@auxout\@partaux + \if@filesw + \immediate\openout\@partaux "#1.aux" + \immediate\write\@partaux{\relax}% + \fi + \UseHook{include/before}% + \UseHook{include/before/#1}% + \@input@{#1.tex}% + \UseHook{include/end/#1}% + \UseHook{include/end}% + \clearpage + \UseHook{include/after/#1}% + \UseHook{include/after}% + \clearpage + \@writeckpt{#1}% + \if@filesw + \immediate\closeout\@partaux + \fi + \else + \deadcycles\z@ + \@nameuse{cp@#1}% + \fi + \let\@auxout\@mainaux} +}{} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\endinput +%% +%% End of file `ltfilehook.ltx'. diff --git a/Master/texmf-dist/tex/latex-dev/base/lthooks.ltx b/Master/texmf-dist/tex/latex-dev/base/lthooks.ltx new file mode 100644 index 00000000000..e214c4d6ccb --- /dev/null +++ b/Master/texmf-dist/tex/latex-dev/base/lthooks.ltx @@ -0,0 +1,1091 @@ +%% +%% This is file `lthooks.ltx', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% lthooks.dtx (with options: `2ekernel') +%% +%% This is a generated file. +%% +%% Copyright 2020 Frank Mittelbach +%% +%% This file was generated from file(s) of the LaTeX `lthooks Bundle'. +%% -------------------------------------------------------------------------- +%% +%% It 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 file may only be distributed together with a copy of the LaTeX +%% `lthooks Bundle'. You may however distribute the `lthooks Bundle' +%% without such generated files. +%% +%% The newest sources can be found below +%% +%% https://github.com/FrankMittelbach/fmitex/ +%% +%% where one can also log issues in case there are any. +%% +%% +%% File: lthooks.dtx (C) Copyright 2020 Frank Mittelbach, LaTeX Team +\providecommand\lthooksversion{v0.9b} +\providecommand\lthooksdate{2020/07/19} + + + + + + +\ExplSyntaxOn +\bool_new:N \g__hook_debug_bool +\cs_new_eq:NN \__hook_debug:n \use_none:n +\cs_new_protected:Npn \hook_debug_on: + { + \bool_gset_true:N \g__hook_debug_bool + \__hook_debug_gset: + } +\cs_new_protected:Npn \hook_debug_off: + { + \bool_gset_false:N \g__hook_debug_bool + \__hook_debug_gset: + } +\cs_new_protected:Npn \__hook_debug_gset: + { + \cs_gset_protected:Npx \__hook_debug:n ##1 + { \bool_if:NT \g__hook_debug_bool {##1} } + } + +\cs_new_eq:NN \__hook_str_compare:nn \__str_if_eq:nn +\tl_new:N \l__hook_return_tl +\tl_new:N \l__hook_tmpa_tl +\tl_new:N \l__hook_tmpb_tl +\seq_new:N \g__hook_all_seq +\tl_new:N \g__hook_removal_list_tl +\tl_new:N \l__hook_cur_hook_tl +\prop_new:N \g__hook_code_temp_prop +\tl_new:N \g__hook_hook_curr_name_tl +\seq_new:N \g__hook_name_stack_seq +\cs_new_eq:NN \__hook_tmp:w ? +\cs_generate_variant:Nn \tl_gremove_once:Nn { Nx } +\scan_new:N \s__hook_mark + +\cs_new_protected:Npn \hook_new:n #1 + { + \exp_args:Nx \__hook_new:n + { \__hook_parse_label_default:nn {#1} { top-level } } + } +\cs_new_protected:Npn \__hook_new:n #1 { + \hook_if_exist:nTF {#1} + { \ErrorHookExists } + { \seq_gput_right:Nn \g__hook_all_seq {#1} + \tl_new:c { g__hook_#1_code_tl } + \__hook_declare:n {#1} + \clist_new:c {g__hook_#1_labels_clist} + \tl_new:c { g__hook_#1_reversed_tl } + \__hook_provide_legacy_interface:n {#1} + } +} + +\cs_new_protected:Npn \__hook_declare:n #1 + { + \__hook_if_exist:nF {#1} + { + \prop_new:c { g__hook_#1_code_prop } + \tl_new:c { g__hook_#1_next_code_tl } + \prop_new:c { g__hook_#1_rules_prop } % only for debugging + } + } + +\cs_new_protected:Npn \hook_new_reversed:n #1 { + \hook_new:n {#1} + \tl_gset:cn { g__hook_#1_reversed_tl } { - } +} + +\cs_new_protected:Npn \hook_new_pair:nn #1#2 { + \hook_new:n {#1} \hook_new_reversed:n {#2} +} + +\cs_new_protected:Npn \__hook_provide_legacy_interface:n #1 + { + \debug_suspend: + \tl_if_exist:cT { @#1hook } + { + \tl_if_empty:cF { @#1hook } + { + \__hook_gput_code:nxv {#1} + { \__hook_parse_label_default:Vn \c_novalue_tl { legacy } } + { @#1hook } + } + } + \tl_gset:co{@#1hook}{\cs:w g__hook_#1_code_tl\cs_end:} + \debug_resume: + } +\cs_new:Npn \__hook_parse_label_default:nn #1 #2 + { + \tl_if_novalue:nTF {#1} + { \__hook_currname_or_default:n {#2} } + { \tl_trim_spaces_apply:nN {#1} \__hook_parse_dot_label:nn {#2} } + } +\cs_generate_variant:Nn \__hook_parse_label_default:nn { V } +\cs_new:Npn \__hook_parse_dot_label:nn #1 #2 + { + \tl_if_empty:nTF {#1} + { + \msg_expandable_error:nnn { hooks } { empty-label } {#2} + #2 + } + { + \str_if_eq:nnTF {#1} { . } + { \__hook_currname_or_default:n {#1} } + { \__hook_parse_dot_label:nw {#2} #1 ./ \s__hook_mark } + } + } +\cs_new:Npn \__hook_parse_dot_label:nw #1 #2 ./ #3 \s__hook_mark + { + \tl_if_empty:nTF {#2} + { \__hook_parse_dot_label_aux:nw {#1} #3 \s__hook_mark } + { + \tl_if_empty:nTF {#3} + {#2} + { \__hook_parse_dot_label_cleanup:w #2 ./ #3 \s__hook_mark } + } + } +\cs_new:Npn \__hook_parse_dot_label_cleanup:w #1 ./ \s__hook_mark {#1} +\cs_new:Npn \__hook_parse_dot_label_aux:nw #1 #2 ./ \s__hook_mark + { \__hook_currname_or_default:n {#1} / #2 } +\cs_new:Npn \__hook_currname_or_default:n #1 + { + \tl_if_empty:NTF \g__hook_hook_curr_name_tl + { + \tl_if_empty:NTF \@currname + {#1} + { \@currname } + } + { \g__hook_hook_curr_name_tl } + } + +\cs_new_protected:Npn \hook_gput_code:nnn #1 #2 + { + \exp_args:Nxx \__hook_gput_code:nnn + { \__hook_parse_label_default:nn {#1} { top-level } } + { \__hook_parse_label_default:nn {#2} { top-level } } + } +\cs_new_protected:Npn \__hook_gput_code:nnn #1 #2 #3 + { + \__hook_if_marked_removal:nnTF {#1} {#2} + { \__hook_unmark_removal:nn {#1} {#2} } + { + \hook_if_exist:nTF {#1} + { + \__hook_hook_gput_code_do:nnn {#1} {#2} {#3} + \__hook_update_hook_code:n {#1} + } + { \__hook_try_declaring_generic_hook:nnn {#1} {#2} {#3} } + } + } +\cs_generate_variant:Nn \__hook_gput_code:nnn { nxv } +\cs_new_protected:Npn \__hook_hook_gput_code_do:nnn #1 #2 #3 + { + \__hook_debug:n{\iow_term:x{****~ Add~ to~ + \hook_if_exist:nF {#1} { undeclared~ } + hook~ #1~ (#2) + \on@line\space <-~ \tl_to_str:n{#3}} } + \prop_get:cnNTF { g__hook_#1_code_prop } {#2} \l__hook_return_tl + { + \prop_gput:cno { g__hook_#1_code_prop } {#2} + { \l__hook_return_tl #3 } + } + { \prop_gput:cnn { g__hook_#1_code_prop } {#2} {#3} } + } +\cs_new_protected:Npn \__hook_gput_undeclared_hook:nnn #1 #2 #3 + { + \__hook_declare:n {#1} + \__hook_hook_gput_code_do:nnn {#1} {#2} {#3} + } +\cs_new_protected:Npn \__hook_try_declaring_generic_hook:nnn #1 + { + \__hook_try_declaring_generic_hook:nNNnn {#1} + \hook_gput_code:nnn \__hook_gput_undeclared_hook:nnn + } +\cs_new_protected:Npn \__hook_try_declaring_generic_next_hook:nn #1 + { + \__hook_try_declaring_generic_hook:nNNnn {#1} + \hook_gput_next_code:nn \__hook_gput_next_do:nn + } +\cs_new_protected:Npn \__hook_try_declaring_generic_hook:nNNnn #1 + { + \__hook_if_file_hook:wTF #1 / / \s__hook_mark + { + \exp_args:Ne \__hook_try_declaring_generic_hook_split:nNNnn + { \exp_args:Ne \__hook_file_hook_normalise:n {#1} } + } + { \__hook_try_declaring_generic_hook_split:nNNnn {#1} } + } +\cs_new_protected:Npn \__hook_try_declaring_generic_hook_split:nNNnn #1 #2 #3 + { + \__hook_try_declaring_generic_hook:wnTF #1 / / / \scan_stop: {#1} + { #2 } + { #3 } {#1} + } +\prg_new_protected_conditional:Npnn \__hook_try_declaring_generic_hook:wn + #1 / #2 / #3 / #4 \scan_stop: #5 { TF } + { + \tl_if_empty:nTF {#2} + { \prg_return_false: } + { + \prop_if_in:NnTF \c__hook_generics_prop {#1} + { + \hook_if_exist:nF {#5} { \hook_new:n {#5} } + \prop_if_in:NnTF \c__hook_generics_reversed_ii_prop {#2} + { \tl_gset:cn { g__hook_#5_reversed_tl } { - } } + { + \prop_if_in:NnT \c__hook_generics_reversed_iii_prop {#3} + { \tl_gset:cn { g__hook_#5_reversed_tl } { - } } + } + \prg_return_true: + } + { \prg_return_false: } + } + } +\prg_new_conditional:Npnn \__hook_if_file_hook:w + #1 / #2 / #3 \s__hook_mark { TF } + { + \str_if_eq:nnTF {#1} { file } + { + \bool_lazy_or:nnTF + { \tl_if_empty_p:n {#3} } + { \str_if_eq_p:nn {#3} { / } } + { \prg_return_false: } + { + \prop_if_in:NnTF \c__hook_generics_file_prop {#2} + { \prg_return_true: } + { \prg_return_false: } + } + } + { \prg_return_false: } + } +\cs_new:Npn \__hook_file_hook_normalise:n #1 + { \__hook_strip_double_slash:n {#1} } +\cs_new:Npn \__hook_strip_double_slash:n #1 + { \__hook_strip_double_slash:w #1 // \s__hook_mark } +\cs_new:Npn \__hook_strip_double_slash:w #1 // #2 \s__hook_mark + { + \tl_if_empty:nTF {#2} + {#1} + { \__hook_strip_double_slash:w #1 / #2 \s__hook_mark } + } + +\prop_const_from_keyval:Nn \c__hook_generics_prop + {env=,file=,package=,class=,include=} +\prop_const_from_keyval:Nn \c__hook_generics_reversed_ii_prop {after=,end=} +\prop_const_from_keyval:Nn \c__hook_generics_reversed_iii_prop {after=} +\prop_const_from_keyval:Nn \c__hook_generics_file_prop {before=,after=} + +\cs_new_eq:NN \__hook_update_hook_code:n \use_none:n + +\cs_new_protected:Npn \hook_gremove_code:nn #1 #2 + { + \exp_args:Nxx \__hook_gremove_code:nn + { \__hook_parse_label_default:nn {#1} { top-level } } + { \__hook_parse_label_default:nn {#2} { top-level } } + } +\cs_new_protected:Npn \__hook_gremove_code:nn #1 #2 + { + \__hook_if_exist:nTF {#1} + { + \str_if_eq:nnTF {#2} {*} + { + \prop_gclear:c { g__hook_#1_code_prop } + \clist_gclear:c { g__hook_#1_labels_clist } % for debugging only + } + { + \prop_get:cnNTF { g__hook_#1_code_prop } {#2} \l__hook_return_tl + { \__hook_gremove_code_do:nn } + { \__hook_mark_removal:nn } + {#1} {#2} + } + \hook_if_exist:nT {#1} + { \__hook_update_hook_code:n {#1} } + } + { \__hook_mark_removal:nn {#1} {#2} } + } +\cs_new_protected:Npn \__hook_gremove_code_do:nn #1 #2 + { + \prop_gremove:cn { g__hook_#1_code_prop } {#2} + \exp_args:Nco \clist_gremove_all:Nn + { g__hook_#1_labels_clist } { \tl_to_str:n {#2} } % for debugging only + } + +\cs_new_protected:Npn \__hook_mark_removal:nn #1 #2 + { + \tl_gput_right:Nx \g__hook_removal_list_tl + { \__hook_removal_tl:nn {#1} {#2} } + } +\cs_new_protected:Npn \__hook_unmark_removal:nn #1 #2 + { + \tl_gremove_once:Nx \g__hook_removal_list_tl + { \__hook_removal_tl:nn {#1} {#2} } + } +\prg_new_protected_conditional:Npnn \__hook_if_marked_removal:nn #1 #2 { TF } + { + \exp_args:NNx \tl_if_in:NnTF \g__hook_removal_list_tl + { \__hook_removal_tl:nn {#1} {#2} } + { \prg_return_true: } { \prg_return_false: } + } +\cs_new:Npn \__hook_removal_tl:nn #1 #2 + { & \tl_to_str:n {#2} $ \tl_to_str:n {#1} $ } + +\prop_new:c {g__hook_??_rules_prop} +\prop_new:c {g__hook_??_code_prop} +\prop_new:c {g__hook_??_code_tl} +\tl_new:c {g__hook_??_reversed_tl} + +\cs_new_protected:Npn \__hook_debug_gset_rule:nnnn #1#2#3#4 + { + \prop_gremove:cn{g__hook_#1_rules_prop}{#2|#4} + \prop_gremove:cn{g__hook_#1_rules_prop}{#4|#2} + \str_case_e:nnF {#3} + { + {before} { \prop_gput:cnn {g__hook_#1_rules_prop}{#2|#4}{<} } + {after} { \prop_gput:cnn {g__hook_#1_rules_prop}{#4|#2}{<} } + {incompatible-error} { \prop_gput:cnn {g__hook_#1_rules_prop}{#2|#4}{xE} } + {incompatible-warning} { \prop_gput:cnn {g__hook_#1_rules_prop}{#2|#4}{xW} } + {removes} { \prop_gput:cnn {g__hook_#1_rules_prop}{#2|#4}{->} } + {unrelated}{ \prop_gremove:cn {g__hook_#1_rules_prop}{#2|#4} + \prop_gremove:cn {g__hook_#1_rules_prop}{#4|#2} } + } + { \ERRORunknownrule } + } +\cs_new_protected:Npn \hook_gset_rule:nnnn #1#2#3#4 + { + \use:x + { + \__hook_gset_rule:nnnn + { \__hook_parse_label_default:nn {#1} { top-level } } + { \__hook_parse_label_default:nn {#2} { top-level } } + {#3} + { \__hook_parse_label_default:nn {#4} { top-level } } + } + } +\cs_new_protected:Npn \__hook_gset_rule:nnnn #1#2#3#4 + { + \__hook_declare:n {#1} + \__hook_rule_gclear:nnn {#1} {#2} {#4} + \debug_suspend: + \cs_if_exist_use:cTF { __hook_rule_#3_gset:nnn } + { + {#1} {#2} {#4} + \__hook_update_hook_code:n {#1} + } + { \ERRORunknownrule } + \debug_resume: + \__hook_debug_gset_rule:nnnn {#1} {#2} {#3} {#4} % for debugging + } +\cs_new_protected:Npn \__hook_rule_before_gset:nnn #1#2#3 + { + \tl_gset:cx { g__hook_#1_rule_ \__hook_label_pair:nn {#2} {#3} _tl } + { \__hook_label_ordered:nnTF {#2} {#3} { < } { > } } + } +\cs_new_eq:cN { __hook_rule_<_gset:nnn } \__hook_rule_before_gset:nnn +\cs_new_protected:Npn \__hook_rule_after_gset:nnn #1#2#3 + { + \tl_gset:cx { g__hook_#1_rule_ \__hook_label_pair:nn {#3} {#2} _tl } + { \__hook_label_ordered:nnTF {#3} {#2} { < } { > } } + } +\cs_new_eq:cN { __hook_rule_>_gset:nnn } \__hook_rule_after_gset:nnn +\cs_new_protected:Npn \__hook_rule_removes_gset:nnn #1#2#3 + { + \tl_gset:cx { g__hook_#1_rule_ \__hook_label_pair:nn {#2} {#3} _tl } + { \__hook_label_ordered:nnTF {#2} {#3} { -> } { <- } } + } +\cs_new_protected:cpn { __hook_rule_incompatible-error_gset:nnn } #1#2#3 + { \tl_gset:cn { g__hook_#1_rule_ \__hook_label_pair:nn {#2} {#3} _tl } { xE } } +\cs_new_protected:cpn { __hook_rule_incompatible-warning_gset:nnn } #1#2#3 + { \tl_gset:cn { g__hook_#1_rule_ \__hook_label_pair:nn {#2} {#3} _tl } { xW } } +\cs_new_protected:Npn \__hook_rule_unrelated_gset:nnn #1#2#3 { } +\cs_new_protected:Npn \__hook_rule_gclear:nnn #1#2#3 + { \cs_undefine:c { g__hook_#1_rule_ \__hook_label_pair:nn {#2} {#3} _tl } } +\cs_new:Npn \__hook_label_pair:nn #1#2 + { + \if_case:w \__hook_str_compare:nn {#1} {#2} \exp_stop_f: + #1 | #1 % 0 + \or: #1 | #2 % +1 + \else: #2 | #1 % -1 + \fi: + } +\prg_new_conditional:Npnn \__hook_label_ordered:nn #1#2 { TF } + { + \if_int_compare:w \__hook_str_compare:nn {#1} {#2} > 0 \exp_stop_f: + \prg_return_true: + \else + \prg_return_false: + \fi: + } +\cs_new:Npn \__hook_if_label_case:nnnnn #1#2 + { + \cs:w use_ + \if_case:w \__hook_str_compare:nn {#1} {#2} + i \or: ii \else: iii \fi: :nnn + \cs_end: + } + +\cs_new_protected:Npn \__hook_initialize_all: { + \cs_gset_eq:NN \__hook_update_hook_code:n \__hook_initialize_hook_code:n + \__hook_debug:n { \prop_gclear:N \g__hook_used_prop } + \seq_map_inline:Nn \g__hook_all_seq + { + \__hook_update_hook_code:n {##1} + } + \__hook_debug:n + { \iow_term:x{^^JAll~ initialized~ (non-empty)~ hooks:} + \prop_map_inline:Nn \g__hook_used_prop + { \iow_term:x{^^J~ ##1~ ->~ + \exp_not:v {g__hook_##1_code_tl}~ } + } + } + \cs_gset_eq:NN \hook_use:n \__hook_use_initialized:n + \cs_gset_eq:NN \__hook_preamble_hook:n \use_none:n +} + +\cs_new_protected:Npn \__hook_initialize_hook_code:n #1 { + \__hook_debug:n{ \iow_term:x{^^JUpdate~ code~ for~ hook~ + '#1' \on@line :^^J} } + \hook_if_exist:nT {#1} + { + \prop_if_empty:cTF {g__hook_#1_code_prop} + { \tl_gset:co {g__hook_#1_code_tl} + {\cs:w g__hook_#1_next_code_tl \cs_end: } } + { + \__hook_if_reversed:nTF {#1} + { \cs_set_eq:NN \__hook_tl_gput:NV \tl_gput_left:NV + \cs_set_eq:NN \__hook_clist_gput:NV \clist_gput_left:NV } + { \cs_set_eq:NN \__hook_tl_gput:NV \tl_gput_right:NV + \cs_set_eq:NN \__hook_clist_gput:NV \clist_gput_right:NV } + \prop_gset_eq:Nc \g__hook_code_temp_prop { g__hook_#1_code_prop } + \__hook_initialize_single:ccccn + { g__hook_#1_code_prop } { g__hook_#1_code_tl } + { g__hook_#1_next_code_tl } { g__hook_#1_labels_clist } + {#1} + \prop_gset_eq:cN { g__hook_#1_code_prop } \g__hook_code_temp_prop + \__hook_debug:n{ \exp_args:NNx \prop_gput:Nnn \g__hook_used_prop {#1}{} } + } + } +} + +\prop_new:N\g__hook_used_prop + +\cs_new:Npn \__hook_tl_csname:n #1 { l__hook_label_#1_tl } +\cs_new:Npn \__hook_seq_csname:n #1 { l__hook_label_#1_seq } + +\seq_new:N \l__hook_labels_seq +\int_new:N \l__hook_labels_int +\tl_new:N \l__hook_front_tl +\tl_new:N \l__hook_rear_tl +\tl_new:c { \__hook_tl_csname:n { 0 } } + +\cs_new_protected:Npn \__hook_initialize_single:NNNNn #1#2#3#4#5 { + \debug_suspend: + \seq_clear:N \l__hook_labels_seq + \int_zero:N \l__hook_labels_int + \tl_set:Nn \l__hook_cur_hook_tl {#5} + \prop_map_inline:Nn #1 + { + \int_incr:N \l__hook_labels_int + \seq_put_right:Nn \l__hook_labels_seq {##1} + \tl_set:cn { \__hook_tl_csname:n {##1} }{0} % the counter k for number of + % j before k rules + \seq_clear_new:c { \__hook_seq_csname:n {##1} } % sequence of successors to k + % i.e., k before j rules (stores + % the names of the j's) + } + \prop_map_inline:Nn #1 + { + \prop_map_inline:Nn #1 + { + \__hook_if_label_case:nnnnn {##1} {####1} + { \prop_map_break: } + { \__hook_apply_label_pair:nnn {##1} {####1} } + { \__hook_apply_label_pair:nnn {####1} {##1} } + {#5} + } + } + \__hook_debug:n { \__hook_debug_label_data:N #1 } + \tl_set:Nn \l__hook_rear_tl { 0 } + \tl_set:cn { \__hook_tl_csname:n { 0 } } { 0 } % really {l__hook_label_ \l__hook_rear_tl _tl} + \seq_map_inline:Nn \l__hook_labels_seq + { + \int_compare:nNnT { \cs:w \__hook_tl_csname:n {##1} \cs_end: } = 0 + { + \tl_set:cn { \__hook_tl_csname:n { \l__hook_rear_tl } }{##1} + \tl_set:Nn \l__hook_rear_tl {##1} + } + } + \tl_set_eq:Nc \l__hook_front_tl { \__hook_tl_csname:n { 0 } } + \tl_gclear:N #2 + \clist_gclear:N #4 + \bool_while_do:nn { ! \str_if_eq_p:Vn \l__hook_front_tl { 0 } } + { + \int_decr:N \l__hook_labels_int + \prop_get:NVN #1 \l__hook_front_tl \l__hook_return_tl + \__hook_tl_gput:NV #2 \l__hook_return_tl + \__hook_clist_gput:NV #4 \l__hook_front_tl + \__hook_debug:n{ \iow_term:x{Handled~ code~ for~ \l__hook_front_tl} } + \seq_map_inline:cn { \__hook_seq_csname:n { \l__hook_front_tl } } + { + \tl_set:cx { \__hook_tl_csname:n {##1} } + { \int_eval:n { \cs:w \__hook_tl_csname:n {##1} \cs_end: - 1 } } + \int_compare:nNnT { \cs:w \__hook_tl_csname:n {##1} \cs_end: } = 0 + { + \tl_set:cn { \__hook_tl_csname:n { \l__hook_rear_tl } } {##1} + \tl_set:Nn \l__hook_rear_tl {##1} + } + } + \tl_set_eq:Nc \l__hook_front_tl { \__hook_tl_csname:n { \l__hook_front_tl } } + } + \int_compare:nNnF \l__hook_labels_int = 0 + { + \iow_term:x{====================} + \iow_term:x{Error:~ label~ rules~ are~ incompatible:} + \__hook_debug_label_data:N #1 + \iow_term:x{====================} + } + \tl_gput_right:Nn #2 {#3} + \debug_resume: +} +\cs_generate_variant:Nn \__hook_initialize_single:NNNNn {cccc} + +\cs_new:Npn \__hook_tl_gput:NV {\ERROR} +\cs_new:Npn \__hook_clist_gput:NV {\ERROR} + +\cs_new_protected:Npn \__hook_apply_label_pair:nnn #1#2#3 + { + \__hook_label_if_exist_apply:nnnF {#1} {#2} {#3} + { + \__hook_label_if_exist_apply:nnnF {#1} {#2} { ?? } { } + } + } +\cs_new_protected:Npn \__hook_label_if_exist_apply:nnnF #1#2#3 + { + \if_cs_exist:w g__hook_ #3 _rule_ #1 | #2 _tl \cs_end: + \__hook_apply_rule:nnn {#1} {#2} {#3} + \exp_after:wN \use_none:n + \else: + \use:nn + \fi: + } + +\cs_new_protected:Npn \__hook_apply_rule:nnn #1#2#3 + { + \cs:w __hook_apply_ + \cs:w g__hook_#3_reversed_tl \cs_end: rule_ + \cs:w g__hook_ #3 _rule_ #1 | #2 _tl \cs_end: :nnn \cs_end: + {#1} {#2} {#3} + } +\cs_new_protected:cpn { __hook_apply_rule_<:nnn } #1#2#3 + { + \__hook_debug:n { \__hook_msg_pair_found:nnn {#1} {#2} {#3} } + \tl_set:cx { \__hook_tl_csname:n {#2} } + { \int_eval:n{ \cs:w \__hook_tl_csname:n {#2} \cs_end: + 1 } } + \seq_put_right:cn{ \__hook_seq_csname:n {#1} }{#2} + } +\cs_new_protected:cpn { __hook_apply_rule_>:nnn } #1#2#3 + { + \__hook_debug:n { \__hook_msg_pair_found:nnn {#1} {#2} {#3} } + \tl_set:cx { \__hook_tl_csname:n {#1} } + { \int_eval:n{ \cs:w \__hook_tl_csname:n {#1} \cs_end: + 1 } } + \seq_put_right:cn{ \__hook_seq_csname:n {#2} }{#1} + } +\cs_new_protected:cpn { __hook_apply_rule_xE:nnn } #1#2#3 + { + \__hook_debug:n { \__hook_msg_pair_found:nnn {#1} {#2} {#3} } + \msg_error:nnnnnn { hooks } { labels-incompatible } + {#1} {#2} {#3} { 1 } + \use:c { __hook_apply_rule_->:nnn } {#1} {#2} {#3} + \use:c { __hook_apply_rule_<-:nnn } {#1} {#2} {#3} + } +\cs_new_protected:cpn { __hook_apply_rule_xW:nnn } #1#2#3 + { + \__hook_debug:n { \__hook_msg_pair_found:nnn {#1} {#2} {#3} } + \msg_warning:nnnnnn { hooks } { labels-incompatible } + {#1} {#2} {#3} { 0 } + } +\cs_new_protected:cpn { __hook_apply_rule_->:nnn } #1#2#3 + { + \__hook_debug:n + { + \__hook_msg_pair_found:nnn {#1} {#2} {#3} + \iow_term:x{--->~ Drop~ '#2'~ code~ from~ + \iow_char:N \\ g__hook_ \l__hook_cur_hook_tl _code_prop ~ because~ of~ '#1' } + } + \prop_gput:cnn { g__hook_ \l__hook_cur_hook_tl _code_prop } {#2} { } + } +\cs_new_protected:cpn { __hook_apply_rule_<-:nnn } #1#2#3 + { + \__hook_debug:n + { + \__hook_msg_pair_found:nnn {#1} {#2} {#3} + \iow_term:x{--->~ Drop~ '#1'~ code~ from~ + \iow_char:N \\ g__hook_ \l__hook_cur_hook_tl _code_prop ~ because~ of~ '#2' } + } + \prop_gput:cnn { g__hook_ \l__hook_cur_hook_tl _code_prop } {#1} { } + } + +\cs_new_eq:cc { __hook_apply_-rule_<:nnn } { __hook_apply_rule_>:nnn } +\cs_new_eq:cc { __hook_apply_-rule_>:nnn } { __hook_apply_rule_<:nnn } +\cs_new_eq:cc { __hook_apply_-rule_<-:nnn } { __hook_apply_rule_<-:nnn } +\cs_new_eq:cc { __hook_apply_-rule_->:nnn } { __hook_apply_rule_->:nnn } +\cs_new_eq:cc { __hook_apply_-rule_xE:nnn } { __hook_apply_rule_xE:nnn } +\cs_new_eq:cc { __hook_apply_-rule_xW:nnn } { __hook_apply_rule_xW:nnn } + +\cs_new_protected:Npn \__hook_msg_pair_found:nnn #1#2#3 + { + \iow_term:x{~ \str_if_eq:nnTF {#3} {??} {default} {~normal} ~ + rule~ \__hook_label_pair:nn {#1} {#2}:~ + \use:c { g__hook_#3_rule_ \__hook_label_pair:nn {#1} {#2} _tl } ~ found} + } + +\cs_new_protected:Npn \__hook_debug_label_data:N #1 { + \iow_term:x{Code~ labels~ for~ sorting:} + \iow_term:x{~ \seq_use:Nnnn\l__hook_labels_seq {~and~}{,~}{~and~} } % fix name! + \iow_term:x{^^J Data~ structure~ for~ label~ rules:} + \prop_map_inline:Nn #1 + { + \iow_term:x{~ ##1~ =~ \tl_use:c{ \__hook_tl_csname:n {##1} }~ ->~ + \seq_use:cnnn{ \__hook_seq_csname:n {##1} }{~->~}{~->~}{~->~} + } + } + \iow_term:x{} +} + +\cs_new_protected:Npn \hook_log:n #1 + { + \exp_args:Nx \__hook_log:n + { \__hook_parse_label_default:nn {#1} { top-level } } + } +\cs_new_protected:Npn \__hook_log:n #1 + { + \iow_term:x{^^JThe~ hook~ '#1':} + \hook_if_exist:nF {#1} + { \iow_term:x {~Hook~ is~ not~ declared!} } + \__hook_if_exist:nTF {#1} + { + \iow_term:x{~Code~ chunks:} + \prop_if_empty:cTF {g__hook_#1_code_prop} + { \iow_term:x{\@spaces ---} } + { + \prop_map_inline:cn {g__hook_#1_code_prop} + { \iow_term:x{\@spaces ##1~ ->~ \tl_to_str:n{##2} } } + } + \iow_term:x{~Extra~ code~ next~ invocation:} + \iow_term:x{\@spaces + \tl_if_empty:cTF { g__hook_#1_next_code_tl } + {---} {->~ \str_use:c{g__hook_#1_next_code_tl} } } + \iow_term:x{~Rules:} + \prop_if_empty:cTF {g__hook_#1_rules_prop} + { \iow_term:x{\@spaces ---} } + { \prop_map_inline:cn {g__hook_#1_rules_prop} + { \iow_term:x{\@spaces ##1~ with~ relation~ ##2} } + } + \hook_if_exist:nT {#1} + { \iow_term:x { ~Execution~ order + \prop_if_empty:cTF {g__hook_#1_rules_prop} + { \__hook_if_reversed:nT {#1} + { ~ (after~ reversal) } + } + { ~ (after~ + \__hook_if_reversed:nT {#1} {reversal~ and~} + applying~ rules) + } + : + } + \iow_term:x { \@spaces + \clist_if_empty:cTF{g__hook_#1_labels_clist} + {not~ set~ yet} + { \clist_use:cnnn {g__hook_#1_labels_clist} + { ,~ } { ,~ } { ,~ } } + } + } + } + { \iow_term:n { ~The~hook~is~empty. } } + \iow_term:n { } + } + +\cs_new_protected:Npn \hook_gput_next_code:nn #1 + { + \exp_args:Nx \__hook_gput_next_code:nn + { \__hook_parse_label_default:nn {#1} { top-level } } + } +\cs_new_protected:Npn \__hook_gput_next_code:nn #1 #2 + { + \__hook_declare:n {#1} + \hook_if_exist:nTF {#1} + { \__hook_gput_next_do:nn {#1} {#2} } + { \__hook_try_declaring_generic_next_hook:nn {#1} {#2} } + } +\cs_new_protected:Npn \__hook_gput_next_do:nn #1 #2 + { + \tl_gput_right:cn { g__hook_#1_next_code_tl } + { #2 \tl_gclear:c { g__hook_#1_next_code_tl } } + } +\cs_new_protected:Npn \hook_use:n #1 + { + \tl_if_exist:cTF { g__hook_#1_code_tl } + { + \__hook_preamble_hook:n {#1} + \cs:w g__hook_#1_code_tl \cs_end: + } + { \__hook_use:wn #1 / \s__hook_mark {#1} } + } +\cs_new:Npn \__hook_use_initialized:n #1 + { + \tl_if_exist:cTF { g__hook_#1_code_tl } + { \cs:w g__hook_#1_code_tl \cs_end: } + { \__hook_use:wn #1 / \s__hook_mark {#1} } + } +\cs_new_protected:Npn \__hook_preamble_hook:n #1 + { \__hook_initialize_hook_code:n {#1} } +\cs_new:Npn \__hook_use:wn #1 / #2 \s__hook_mark #3 + { + \str_if_eq:nnTF {#1} { file } + { \__hook_try_file_hook:n {#3} } + { } % Hook doesn't exist + } +\cs_new_protected:Npn \__hook_try_file_hook:n #1 + { + \__hook_if_file_hook:wTF #1 / / \s__hook_mark + { + \exp_args:Ne \__hook_if_exist_use:n + { \exp_args:Ne \__hook_file_hook_normalise:n {#1} } + } + { \__hook_if_exist_use:n {#1} } % file/ generic hook (e.g. file/before) + } +\cs_new_protected:Npn \__hook_if_exist_use:n #1 + { + \tl_if_exist:cT { g__hook_#1_code_tl } + { + \__hook_preamble_hook:n {#1} + \cs:w g__hook_#1_code_tl \cs_end: + } + } +\cs_new_protected:Npn \hook_use_once:n #1 + { + \tl_if_exist:cT { g__hook_#1_code_tl } + { + \clist_gput_left:Nn \g__hook_execute_immediately_clist {#1} + \hook_use:n {#1} + } + } + +\prg_new_conditional:Npnn \hook_if_empty:n #1 { p , T , F , TF } + { + \__hook_if_exist:nTF {#1} + { + \bool_lazy_and:nnTF + { \prop_if_empty_p:c { g__hook_#1_code_prop } } + { \tl_if_empty_p:c { g__hook_#1_next_code_tl } } + { \prg_return_true: } + { \prg_return_false: } + } + { \prg_return_true: } + } + +\prg_new_conditional:Npnn \hook_if_exist:n #1 { p , T , F , TF } + { + \tl_if_exist:cTF { g__hook_#1_code_tl } + { \prg_return_true: } + { \prg_return_false: } + } + +\prg_new_conditional:Npnn \__hook_if_exist:n #1 { p , T , F , TF } + { + \prop_if_exist:cTF { g__hook_#1_code_prop } + { \prg_return_true: } + { \prg_return_false: } + } +\prg_new_conditional:Npnn \__hook_if_reversed:n #1 { p , T , F , TF } + { + \if_int_compare:w \cs:w g__hook_#1_reversed_tl \cs_end: 1 < 0 \exp_stop_f: + \prg_return_true: + \else: + \prg_return_false: + \fi: + } + +\clist_new:N \g__hook_execute_immediately_clist +\msg_new:nnnn { hooks } { labels-incompatible } + { + Labels~`#1'~and~`#2'~are~incompatible + \str_if_eq:nnF {#3} {??} { ~in~hook~`#3' } .~ + \int_compare:nNnT {#4} = { 1 } + { The~code~for~both~labels~will~be~dropped. } + } + { + LaTeX~found~two~incompatible~labels~in~the~same~hook.~ + This~indicates~an~incompatibility~between~packages. + } +\msg_new:nnn { hooks } { empty-label } + { Empty~code~label~\msg_line_context:.~Using~`#1'~instead. } + +\NewDocumentCommand \NewHook { m }{ \hook_new:n {#1} } +\NewDocumentCommand \NewReversedHook { m }{ \hook_new_reversed:n {#1} } +\NewDocumentCommand \NewMirroredHookPair { mm }{ \hook_new_pair:nn {#1}{#2} } + +\NewDocumentCommand \AddToHook { m o +m } + { + \clist_if_in:NnTF \g__hook_execute_immediately_clist {#1} + {#3} + { \hook_gput_code:nnn {#1} {#2} {#3} } + } + +\NewDocumentCommand \AddToHookNext { m +m } + { \hook_gput_next_code:nn {#1} {#2} } + +\NewDocumentCommand \RemoveFromHook { m o } + { \hook_gremove_code:nn {#1} {#2} } +\str_if_eq:VnTF \@currname { lthooks } + { + \seq_gpush:Nn \g__hook_name_stack_seq { lthooks } + \cs_set_protected:Npn \__hook_tmp:w #1 #2 #3 + { + \quark_if_recursion_tail_stop:n {#1} + \seq_gput_right:Nn \g__hook_name_stack_seq { } + \__hook_tmp:w + } + \exp_after:wN \__hook_tmp:w + \@currnamestack + \q_recursion_tail \q_recursion_tail + \q_recursion_tail \q_recursion_stop + } + { \seq_gpush:Nn \g__hook_name_stack_seq { } } +\cs_new_protected:Npn \__hook_curr_name_push:n #1 + { + \seq_gpush:Nn \g__hook_name_stack_seq {#1} + \tl_gset:Nn \g__hook_hook_curr_name_tl {#1} + } +\cs_new_protected:Npn \__hook_curr_name_pop: + { + \seq_gpop:NN \g__hook_name_stack_seq \l__hook_return_tl + \seq_get:NNTF \g__hook_name_stack_seq \l__hook_return_tl + { \tl_gset_eq:NN \g__hook_hook_curr_name_tl \l__hook_return_tl } + { \ERROR_should_not_happen } + } +\NewDocumentCommand \DeclareDefaultHookLabel { m } + { + \seq_gpop:NN \g__hook_name_stack_seq \l__hook_return_tl + \__hook_curr_name_push:n {#1} + } +\tl_gput_left:Nn \@pushfilename { \__hook_curr_name_push:n { } } +\tl_gput_left:Nn \@popfilename { \__hook_curr_name_pop: } +\newcommand \UseHook { \hook_use:n } +\cs_new_protected:Npn \UseOneTimeHook { \hook_use_once:n } + +\cs_new_protected:Npn \ShowHook { \hook_log:n } + +\cs_new_protected:Npn \DebugHookOn { \hook_debug_on: } +\cs_new_protected:Npn \DebugHookOff { \hook_debug_off: } + +\NewDocumentCommand \DeclareHookRule { m m m m } +{ \hook_gset_rule:nnnn {#1}{#2}{#3}{#4} } + +\NewDocumentCommand \DeclareDefaultHookRule { m m m } + { \hook_gset_rule:nnnn {??}{#1}{#2}{#3} } +\@onlypreamble\DeclareDefaultHookRule +\NewDocumentCommand \ClearHookRule { m m m } +{ \hook_gset_rule:nnnn {#1}{#2}{unrelated}{#3} } +\NewExpandableDocumentCommand \IfHookExistTF { m } + { \hook_if_exist:nTF {#1} } +\NewExpandableDocumentCommand \IfHookEmptyTF { m } + { \hook_if_empty:nTF {#1} } + +\renewcommand\AtBeginDocument{\AddToHook{begindocument}} + +\renewcommand\AtEndDocument {\AddToHook{enddocument}} + +\begingroup + \def\@currname{} + \NewHook{begindocument} + \NewHook{enddocument} + \NewHook{rmfamily} + \NewHook{sffamily} + \NewHook{ttfamily} + \NewHook{defaultfamily} + \NewHook{documentclass} +\endgroup +\let\begin\relax % avoid redeclaration message +\DeclareRobustCommand*\begin[1]{% + \UseHook{env/#1/before}% + \@ifundefined{#1}% + {\def\reserved@a{\@latex@error{Environment~#1~undefined}\@eha}}% + {\def\reserved@a{\def\@currenvir{#1}% + \edef\@currenvline{\on@line}% + \@execute@begin@hook{#1}% + \csname #1\endcsname}}% + \@ignorefalse + \begingroup\@endpefalse\reserved@a} +\def\@execute@begin@hook #1{% + \expandafter\ifx\csname #1\endcsname\document + \endgroup + \gdef\@execute@begin@hook##1{\UseHook{env/##1/begin}}% + \__hook_initialize_all: + \@execute@begin@hook{#1}% + \else + \UseHook{env/#1/begin}% + \fi +} +\@namedef{end~}#1{% + \UseHook{env/#1/end}% + \csname end#1\endcsname\@checkend{#1}% + \expandafter\endgroup\if@endpe\@doendpe\fi + \UseHook{env/#1/after}% + \if@ignore\@ignorefalse\ignorespaces\fi}% +\@namedef{end~}#1{% +\romannumeral +\IfHookEmptyTF{env/#1/end}% + {\expandafter\z@}% + {\z@\UseHook{env/#1/end}}% +\csname end#1\endcsname\@checkend{#1}% +\expandafter\endgroup\if@endpe\@doendpe\fi +\UseHook{env/#1/after}% +\if@ignore\@ignorefalse\ignorespaces\fi}% +\newcommand\AtBeginEnvironment[1] {\AddToHook{env/#1/begin}} +\newcommand\AtEndEnvironment[1] {\AddToHook{env/#1/end}} +\newcommand\BeforeBeginEnvironment[1]{\AddToHook{env/#1/before}} +\newcommand\AfterEndEnvironment[1] {\AddToHook{env/#1/after}} +\ExplSyntaxOff +\NewHook{begindocument/end} + +\def\document{% + \@kernel@after@env@document@begin + \@expl@sys@load@backend@@ + \ifx\@unusedoptionlist\@empty\else + \@latex@warning@no@line{Unused global option(s):^^J% + \@spaces[\@unusedoptionlist]}% + \fi + \@colht\textheight + \@colroom\textheight \vsize\textheight + \columnwidth\textwidth + \@clubpenalty\clubpenalty + \if@twocolumn + \advance\columnwidth -\columnsep + \divide\columnwidth\tw@ \hsize\columnwidth \@firstcolumntrue + \fi + \hsize\columnwidth \linewidth\hsize + \begingroup\@floatplacement\@dblfloatplacement + \makeatletter\let\@writefile\@gobbletwo + \global \let \@multiplelabels \relax + \@input{\jobname.aux}% + \endgroup + \if@filesw + \immediate\openout\@mainaux\jobname.aux + \immediate\write\@mainaux{\relax}% + \fi + \process@table + \let\glb@currsize\@empty % Force math initialization. + \normalsize + \everypar{}% + \ifx\normalsfcodes\@empty + \ifnum\sfcode`\.=\@m + \let\normalsfcodes\frenchspacing + \else + \let\normalsfcodes\nonfrenchspacing + \fi + \fi + \ifx\document@default@language\m@ne + \chardef\document@default@language\language + \fi + \@noskipsecfalse + \let \@refundefined \relax + \UseOneTimeHook{begindocument}% + \@kernel@after@begindocument + \ifdim\topskip<1sp\global\topskip 1sp\relax\fi + \global\@maxdepth\maxdepth + \global\let\@begindocumenthook\@undefined + \ifx\@listfiles\@undefined + \global\let\@filelist\relax + \global\let\@addtofilelist\@gobble + \fi + \gdef\do##1{\global\let ##1\@notprerr}% + \@preamblecmds + \global\let \@nodocument \relax + \global\let\do\noexpand + \UseOneTimeHook{begindocument/end}% + \ignorespaces} +\let\@kernel@after@begindocument\@empty +\edef \@kernel@after@env@document@begin{% + \let\expandafter\noexpand\csname + g__hook_env/document/begin_code_tl\endcsname + \noexpand\@empty} +\let\@kernel@hook@begindocument\@empty +\NewHook{enddocument/afterlastpage} +\NewHook{enddocument/afteraux} +\NewHook{enddocument/info} +\NewHook{enddocument/end} + +\def\enddocument{% + \UseHook{enddocument}% + \@kernel@after@enddocument + \@checkend{document}% + \clearpage + \UseHook{enddocument/afterlastpage}% + \@kernel@after@enddocument@afterlastpage + \begingroup + \if@filesw + \immediate\closeout\@mainaux + \let\@setckpt\@gobbletwo + \let\@newl@bel\@testdef + \@tempswafalse + \makeatletter \@@input\jobname.aux + \fi + \UseHook{enddocument/afteraux}% + \UseHook{enddocument/info}% + \endgroup + \UseHook{enddocument/end}% + \deadcycles\z@\@@end} +\let\@kernel@after@enddocument\@empty +\let\@kernel@after@enddocument@afterlastpage\@empty +\def\@enddocument@kernel@warnings{% + \ifdim \font@submax >\fontsubfuzz\relax + \@font@warning{Size substitutions with differences\MessageBreak + up to \font@submax\space have occurred.\@gobbletwo}% + \fi + \@defaultsubs + \@refundefined + \if@filesw + \ifx \@multiplelabels \relax + \if@tempswa + \@latex@warning@no@line{Label(s) may have changed. + Rerun to get cross-references right}% + \fi + \else + \@multiplelabels + \fi + \fi +} +\AddToHook{enddocument/info}[kernel/filelist]{\@dofilelist} +\AddToHook{enddocument/info}[kernel/warnings]{\@enddocument@kernel@warnings} +\DeclareHookRule{enddocument/info}{kernel/filelist}{before}{kernel/warnings} +\expandafter\let\csname ver@atveryend.sty\endcsname\fmtversion +\newcommand\AfterLastShipout {\AddToHook{enddocument/afterlastpage}} +\newcommand\AtVeryEndDocument {\AddToHook{enddocument/afteraux}} +\newcommand\AtEndAfterFileList{\AddToHook{enddocument/info}} +\newcommand\AtVeryVeryEnd {\AddToHook{enddocument/end}} + +\ExplSyntaxOn +\newcommand\BeforeClearDocument[1] + { \AtEndDocument{#1} + \@DEPRECATED{BeforeClearDocument \tl_to_str:n{#1}} + } +\cs_new:Npn\@DEPRECATED #1 + {\iow_term:x{======~DEPRECATED~USAGE~#1~==========}} +\ExplSyntaxOff + + + +\endinput +%% +%% End of file `lthooks.ltx'. diff --git a/Master/texmf-dist/tex/latex-dev/base/lthooks.sty b/Master/texmf-dist/tex/latex-dev/base/lthooks.sty new file mode 100644 index 00000000000..3ee2120eab5 --- /dev/null +++ b/Master/texmf-dist/tex/latex-dev/base/lthooks.sty @@ -0,0 +1,67 @@ +%% +%% This is file `lthooks.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% lthooks.dtx (with options: `package') +%% +%% This is a generated file. +%% +%% Copyright 2020 Frank Mittelbach +%% +%% This file was generated from file(s) of the LaTeX `lthooks Bundle'. +%% -------------------------------------------------------------------------- +%% +%% It 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 file may only be distributed together with a copy of the LaTeX +%% `lthooks Bundle'. You may however distribute the `lthooks Bundle' +%% without such generated files. +%% +%% The newest sources can be found below +%% +%% https://github.com/FrankMittelbach/fmitex/ +%% +%% where one can also log issues in case there are any. +%% +%% +%% File: lthooks.dtx (C) Copyright 2020 Frank Mittelbach, LaTeX Team +\providecommand\lthooksversion{v0.9b} +\providecommand\lthooksdate{2020/07/19} + + + + + + + + + +\RequirePackage{xparse} +\ProvidesExplPackage{lthooks}{\lthooksdate}{\lthooksversion} + {Hook management interface for LaTeX2e} +\@ifl@t@r\fmtversion{2020/10/01} + {} + {\input{lthooks.ltx} + \input{ltshipout.ltx} + \input{ltfilehook.ltx} + } +\ExplSyntaxOn +\hook_debug_off: +\DeclareOption { debug } { \hook_debug_on: + \shipout_debug_on: } +\shipout_debug_off: +\DeclareOption { debug-shipout } { \shipout_debug_on: } +\ProcessOptions +\RequirePackage{filehook-ltx} + +\endinput +%% +%% End of file `lthooks.sty'. diff --git a/Master/texmf-dist/tex/latex-dev/base/ltluatex.tex b/Master/texmf-dist/tex/latex-dev/base/ltluatex.tex index 2930f1876e6..e73c4ef2c88 100644 --- a/Master/texmf-dist/tex/latex-dev/base/ltluatex.tex +++ b/Master/texmf-dist/tex/latex-dev/base/ltluatex.tex @@ -46,8 +46,8 @@ \ProvidesFile\undefined\begingroup\def\ProvidesFile #1#2[#3]{\endgroup\immediate\write-1{File: #1 #3}} \fi -\ProvidesFile{ltluatex.tex} -[2020/03/07 v1.1m +\ProvidesFile{ltluatex.tex}% +[2020/06/10 v1.1n LuaTeX support for plain TeX (core) ] \edef\etatcatcode{\the\catcode`\@} @@ -58,6 +58,8 @@ \wlog{***************************************************} \expandafter\endinput \fi +\long\def\@gobble#1{} +\long\def\@firstofone#1{#1} \directlua{tex.enableprimitives("",tex.extraprimitives("luatex"))} \ifx\e@alloc\@undefined \ifx\documentclass\@undefined @@ -109,8 +111,6 @@ \errmessage{No room for a new \string#4}% \fi \fi}% -\long\def\@gobble#1{} -\long\def\@firstofone#1{#1} \expandafter\csname newcount\endcsname\e@alloc@attribute@count \expandafter\csname newcount\endcsname\e@alloc@ccodetable@count \expandafter\csname newcount\endcsname\e@alloc@luafunction@count diff --git a/Master/texmf-dist/tex/latex-dev/base/ltnews.cls b/Master/texmf-dist/tex/latex-dev/base/ltnews.cls index 08f098515b7..632f0681175 100644 --- a/Master/texmf-dist/tex/latex-dev/base/ltnews.cls +++ b/Master/texmf-dist/tex/latex-dev/base/ltnews.cls @@ -608,6 +608,10 @@ % That's it! +%FMi temp addition until etoolbox is updated +%\RequirePackage{etoolbox-ltx} +%\AddToHook{env/document/begin}{\RemoveFromHook{env/document/begin}[*]} % done in \document + \endinput % CHANGELOG diff --git a/Master/texmf-dist/tex/latex-dev/base/ltshipout.ltx b/Master/texmf-dist/tex/latex-dev/base/ltshipout.ltx new file mode 100644 index 00000000000..c473f64fae7 --- /dev/null +++ b/Master/texmf-dist/tex/latex-dev/base/ltshipout.ltx @@ -0,0 +1,424 @@ +%% +%% This is file `ltshipout.ltx', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% ltshipout.dtx (with options: `2ekernel') +%% +%% This is a generated file. +%% +%% Copyright 2020 Frank Mittelbach +%% +%% This file was generated from file(s) of the LaTeX `lthooks Bundle'. +%% -------------------------------------------------------------------------- +%% +%% It 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 file may only be distributed together with a copy of the LaTeX +%% `lthooks Bundle'. You may however distribute the `lthooks Bundle' +%% without such generated files. +%% +%% The newest sources can be found below +%% +%% https://github.com/FrankMittelbach/fmitex/ +%% +%% where one can also log issues in case there are any. +%% +%% +%% File: ltshipout.dtx (C) Copyright 2020 Frank Mittelbach, LaTeX Team +\providecommand\ltshipoutversion{v0.9a} +\providecommand\ltshipoutdate{2020/07/15} + + + + + + + + + + +\ExplSyntaxOn +\bool_new:N \g__shipout_debug_bool +\cs_new_eq:NN \__shipout_debug:n \use_none:n +\cs_new_protected:Npn \shipout_debug_on: + { + \bool_gset_true:N \g__shipout_debug_bool + \__shipout_debug_gset: + } +\cs_new_protected:Npn \shipout_debug_off: + { + \bool_gset_false:N \g__shipout_debug_bool + \__shipout_debug_gset: + } +\cs_new_protected:Npn \__shipout_debug_gset: + { + \cs_gset_protected:Npx \__shipout_debug:n ##1 + { \bool_if:NT \g__shipout_debug_bool {##1} } + } + +\hook_new:n{shipout/before} +\hook_new:n{shipout/foreground} +\hook_new:n{shipout/background} +\hook_new:n{shipout/firstpage} +\hook_new:n{shipout/lastpage} + +\box_new:N \l_shipout_box +\cs_set_eq:NN \ShipoutBox \l_shipout_box + +\cs_set:Npn\__shipout_execute: { + \tl_set:Nx \l__shipout_group_level_tl + { \int_value:w \tex_currentgrouplevel:D } + \tex_afterassignment:D \__shipout_execute_test_level: + \tex_setbox:D \l_shipout_box +} + +\cs_gset_eq:NN \shipout \__shipout_execute: + +\tl_new:N \l__shipout_group_level_tl + +\cs_new:Npn \__shipout_execute_test_level: { + \int_compare:nNnT + \l__shipout_group_level_tl < \tex_currentgrouplevel:D + \tex_aftergroup:D + \__shipout_execute_cont: +} + +\cs_new:Npn \__shipout_execute_cont: { + \box_if_empty:NTF \l_shipout_box + { \PackageWarning{ltshipout}{Ignoring~ void~ shipout~ box} } + { + \bool_gset_false:N \g__shipout_discard_bool + \set@typeset@protect + \__shipout_get_box_size:N \l_shipout_box + \hook_use:n {shipout/before} + \int_gincr:N \g_shipout_totalpages_int + \bool_if:NTF \g__shipout_discard_bool + { \PackageInfo{ltshipout}{Completed~ page~ discarded} + \bool_gset_false:N \g__shipout_discard_bool + \tex_deadcycles:D \c_zero_int + } + { \box_if_empty:NTF \l_shipout_box + { \PackageWarning{ltshipout}{ + Shipout~ box~ was~ voided~ by~ hook,\MessageBreak + ignoring~ shipout~ box } + } + { + \int_gincr:N \g_shipout_readonly_int + \__shipout_debug:n { + \typeout{Absolute~ page~ =~ \int_use:N \g_shipout_readonly_int + \space (target:~ \@abspage@last)} + } + \__shipout_get_box_size:N \l_shipout_box + \@kernel@before@shipout@foreground + \hook_if_empty:nF {shipout/foreground} + { \__shipout_add_foreground_picture:n + { \hook_use:n {shipout/foreground} } } + \hook_if_empty:nF {shipout/background} + { \__shipout_add_background_picture:n + { \hook_use:n {shipout/background} } } + \__shipout_execute_firstpage_hook: + \int_compare:nNnT \@abspage@last = \g_shipout_readonly_int + { \hook_if_empty:nF {shipout/lastpage} + { \__shipout_debug:n { \typeout{Executing~ lastpage~ hook~ + on~ page~ \int_use:N \g_shipout_readonly_int } } + \__shipout_add_foreground_box:n { \UseHook{shipout/lastpage} + \@kernel@after@shipout@lastpage } + } + \bool_gset_true:N \g__shipout_lastpage_handled_bool + } + \cs_set_eq:NN \protect \exp_not:N + \tex_shipout:D \box_use:N \l_shipout_box + } + } + } +} + +\let\@kernel@after@shipout@lastpage\@empty +\let\@kernel@before@shipout@foreground\@empty + +\cs_new:Npn \__shipout_execute_firstpage_hook: { + \hook_if_empty:nF {shipout/firstpage} + { \__shipout_add_background_box:n { \UseHook{shipout/firstpage} } } + \cs_gset_eq:NN \__shipout_execute_firstpage_hook: \prg_do_nothing: + \cs_gset:Npn \__shipout_add_firstpage_material:Nn ##1 ##2 { + \PackageWarning{ltshipout}{ + First~ page~ is~ already~ shipped~ out,~ ignoring\MessageBreak + \string##1 } + } +} + +\bool_new:N \g__shipout_lastpage_handled_bool + +\cs_new:Npn \__shipout_add_firstpage_material:Nn #1#2 { + \AddToHook{shipout/firstpage}{#2} +} + +\cs_new:Npn \__shipout_get_box_size:N #1 { + \dim_set:Nn \l_shipout_box_ht_dim { \box_ht:N #1 } + \dim_set:Nn \l_shipout_box_dp_dim { \box_dp:N #1 } + \dim_set:Nn \l_shipout_box_wd_dim { \box_wd:N #1 } + \dim_set:Nn \l_shipout_box_ht_plus_dp_dim { \l_shipout_box_ht_dim + + \l_shipout_box_dp_dim } +} + +\dim_new:N \l_shipout_box_ht_dim +\dim_new:N \l_shipout_box_dp_dim +\dim_new:N \l_shipout_box_wd_dim +\dim_new:N \l_shipout_box_ht_plus_dp_dim + +\bool_new:N \g__shipout_discard_bool + +\box_new:N \l__shipout_tmp_box +\tl_new:N \l__shipout_saved_badness_tl + +\cs_new:Npn \__shipout_add_background_box:n #1 +{ \__shipout_get_box_size:N \l_shipout_box + \box_if_vertical:NTF \l_shipout_box + { + \tl_set:Nx \l__shipout_saved_badness_tl + { \vfuzz=\the\vfuzz\relax + \vbadness=\the\vbadness\relax } + \vfuzz=\c_max_dim + \vbadness=\c_max_int + \vbox_set_to_ht:Nnn \l_shipout_box \l_shipout_box_ht_plus_dp_dim + { + \hbox_set:Nn \l__shipout_tmp_box + { \l__shipout_saved_badness_tl #1 } + \box_set_wd:Nn \l__shipout_tmp_box \c_zero_dim + \box_set_ht:Nn \l__shipout_tmp_box \c_zero_dim + \box_set_dp:Nn \l__shipout_tmp_box \c_zero_dim + \skip_zero:N \baselineskip + \skip_zero:N \lineskip + \skip_zero:N \lineskiplimit + \box_use:N \l__shipout_tmp_box + \vbox_unpack:N \l_shipout_box + \kern \c_zero_dim + } + \box_set_ht:Nn \l_shipout_box \l_shipout_box_ht_dim + \box_set_dp:Nn \l_shipout_box \l_shipout_box_dp_dim + \l__shipout_saved_badness_tl + } + { + \box_if_horizontal:NT \l_shipout_box + { + \tl_set:Nx \l__shipout_saved_badness_tl + { \hfuzz=\the\hfuzz\relax + \hbadness=\the\hbadness\relax } + \hfuzz=\c_max_dim + \hbadness=\c_max_int + \hbox_set_to_wd:Nnn \l_shipout_box \l_shipout_box_wd_dim + { + \hbox_set:Nn \l__shipout_tmp_box + { \l__shipout_saved_badness_tl #1 } + \box_set_wd:Nn \l__shipout_tmp_box \c_zero_dim + \box_set_ht:Nn \l__shipout_tmp_box \c_zero_dim + \box_set_dp:Nn \l__shipout_tmp_box \c_zero_dim + \box_move_up:nn + \l_shipout_box_ht_dim + { \box_use:N \l__shipout_tmp_box } + \hbox_unpack:N \l_shipout_box + } + \l__shipout_saved_badness_tl + } + } +} + +\cs_new:Npn \__shipout_add_foreground_box:n #1 +{ + \box_if_vertical:NTF \l_shipout_box + { + \tl_set:Nx \l__shipout_saved_badness_tl + { \vfuzz=\the\vfuzz\relax + \vbadness=\the\vbadness\relax } + \vfuzz=\c_max_dim + \vbadness=\c_max_int + \vbox_set_to_ht:Nnn \l_shipout_box \l_shipout_box_ht_plus_dp_dim + { + \hbox_set:Nn \l__shipout_tmp_box + { \l__shipout_saved_badness_tl #1 } + \box_set_wd:Nn \l__shipout_tmp_box \c_zero_dim + \box_set_ht:Nn \l__shipout_tmp_box \c_zero_dim + \box_set_dp:Nn \l__shipout_tmp_box \c_zero_dim + \skip_zero:N \baselineskip + \skip_zero:N \lineskip + \skip_zero:N \lineskiplimit + \vbox_unpack:N \l_shipout_box + \kern -\l_shipout_box_ht_plus_dp_dim + \box_use:N \l__shipout_tmp_box + \kern \l_shipout_box_ht_plus_dp_dim + } + \l__shipout_saved_badness_tl + \box_set_ht:Nn \l_shipout_box \l_shipout_box_ht_dim + \box_set_dp:Nn \l_shipout_box \l_shipout_box_dp_dim + } + { + \box_if_horizontal:NT \l_shipout_box + { + \tl_set:Nx \l__shipout_saved_badness_tl + { \hfuzz=\the\hfuzz\relax + \hbadness=\the\hbadness\relax } + \hfuzz=\c_max_dim + \hbadness=\c_max_int + \hbox_set_to_wd:Nnn \l_shipout_box \l_shipout_box_wd_dim + { + \hbox_unpack:N \l_shipout_box + \kern -\box_wd:N \l_shipout_box + \hbox_set:Nn \l__shipout_tmp_box + { \l__shipout_saved_badness_tl #1 } + \box_set_wd:Nn \l__shipout_tmp_box \c_zero_dim + \box_set_ht:Nn \l__shipout_tmp_box \c_zero_dim + \box_set_dp:Nn \l__shipout_tmp_box \c_zero_dim + \box_move_up:nn { \box_ht:N \l_shipout_box } + { \box_use:N \l__shipout_tmp_box } + \kern \box_wd:N \l_shipout_box + }% + \l__shipout_saved_badness_tl + } + } +} + +\tl_gput_right:Nn \@kernel@after@begindocument { + \tl_const:Nx \c__shipout_horigin_tl + { + \cs_if_exist_use:NTF \pdfvariable { horigin } + { \cs_if_exist_use:NF \pdfhorigin { 1in } } + } + \tl_const:Nx \c__shipout_vorigin_tl + { + \cs_if_exist_use:NTF \pdfvariable { vorigin } + { \cs_if_exist_use:NF \pdfvorigin { 1in } } + } +} + +\cs_new:Npn \__shipout_picture_overlay:n #1 { + \kern -\c__shipout_horigin_tl \scan_stop: + \vbox_to_zero:n { + \kern -\c__shipout_vorigin_tl \scan_stop: + \unitlength 1pt \scan_stop: + \hbox_set_to_wd:Nnn \l__shipout_tmp_box \c_zero_dim { \ignorespaces #1 } + \box_set_ht:Nn \l__shipout_tmp_box \c_zero_dim + \box_set_dp:Nn \l__shipout_tmp_box \c_zero_dim + \box_use:N \l__shipout_tmp_box + \tex_vss:D + } +} + +\cs_new:Npn \__shipout_add_background_picture:n #1 { + \__shipout_add_background_box:n { \__shipout_picture_overlay:n {#1} } +} + +\cs_new:Npn \__shipout_add_foreground_picture:n #1 { + \__shipout_add_foreground_box:n { \__shipout_picture_overlay:n {#1} } +} + +\cs_new:Npn \shipout_discard: { + \bool_gset_true:N \g__shipout_discard_bool +} + + + +\int_new:N \g_shipout_readonly_int +\cs_new_eq:NN \ReadonlyShipoutCounter \g_shipout_readonly_int + +\int_new:N \g_shipout_totalpages_int +\cs_new_eq:NN \c@totalpages \g_shipout_totalpages_int +\cs_new:Npn \thetotalpages { \arabic{totalpages} } + +\xdef\@abspage@last{\number\maxdimen} + +\g@addto@macro \@kernel@after@enddocument { + \int_compare:nNnT \@abspage@last = \maxdimen + { + \xdef\@abspage@last{ \int_eval:n {\g_shipout_readonly_int + 1} } + } +} +\g@addto@macro \@kernel@after@enddocument@afterlastpage { + \int_compare:nNnF \g_shipout_readonly_int = 0 + { + \if@filesw + \iow_now:Nx \@auxout { + \gdef\string\@abspage@last {\int_use:N \g_shipout_readonly_int}} + \fi + \bool_if:NF \g__shipout_lastpage_handled_bool + { \tex_shipout:D\vbox to\textheight{ + \hbox{\UseHook{shipout/lastpage} \@kernel@after@shipout@lastpage } + \__shipout_excuse_extra_page: + \null + } + } + } +} + +\cs_new:Npn \__shipout_excuse_extra_page: { + \vfil + \begin{center} + \bfseries Temporary~ page! + \end{center} + \LaTeX{}~ was~ unable~ to~ guess~ the~ total~ number~ of~ pages~ + correctly.~ ~ As~ there~ was~ some~ unprocessed~ data~ that~ + should~ have~ been~ added~ to~ the~ final~ page~ this~ extra~ + page~ has~ been~ added~ to~ receive~ it. + \par + If~ you~ rerun~ the~ document~ (without~ altering~ it)~ this~ + surplus~ page~ will~ go~ away,~ because~ \LaTeX{}~ now~ knows~ + how~ many~ pages~ to~ expect~ for~ this~ document. + \vfil +} + + +\cs_new_eq:NN \DiscardShipoutBox \shipout_discard: + +\renewcommand \AtBeginDvi {\__shipout_add_firstpage_material:Nn \AtBeginDvi} + +\cs_new_eq:NN \DebugShipoutOn \shipout_debug_on: +\cs_new_eq:NN \DebugShipoutOff \shipout_debug_off: + + + +\cs_new_eq:NN \AtBeginShipoutBox \ShipoutBox + +\cs_set_eq:NN\AtBeginShipoutInit\@empty + +\newcommand\AtBeginShipout {\AddToHook{shipout/before}} +\newcommand\AtBeginShipoutNext {\AddToHookNext{shipout/before}} + +\newcommand\AtBeginShipoutFirst{\__shipout_add_firstpage_material:Nn \AtBeginShipoutFirst} + +\cs_new:Npn \ShipoutBoxHeight { \dim_use:N \l_shipout_box_ht_dim } +\cs_new:Npn \ShipoutBoxDepth { \dim_use:N \l_shipout_box_dp_dim } +\cs_new:Npn \ShipoutBoxWidth { \dim_use:N \l_shipout_box_wd_dim } + +\cs_new_eq:NN \AtBeginShipoutDiscard \DiscardShipoutBox + +\cs_new_eq:NN \AtBeginShipoutAddToBox \__shipout_add_background_box:n +\cs_new_eq:NN \AtBeginShipoutAddToBoxForeground \__shipout_add_foreground_box:n +\cs_new_eq:NN\AtBeginShipoutUpperLeft \__shipout_add_background_picture:n +\cs_new_eq:NN\AtBeginShipoutUpperLeftForeground \__shipout_add_foreground_picture:n + +\expandafter\cs_set_eq:NN\csname ver@atbegshi.sty\endcsname\fmtversion +\@namedef {ver@atbegshi.sty}{2020/10/01} + +\cs_new_eq:NN\EveryShipout\AtBeginShipout +\cs_new_eq:NN\AtNextShipout\AtBeginShipoutNext +\expandafter\cs_set_eq:NN\csname ver@everyshi.sty\endcsname\fmtversion +\@namedef {ver@everyshi.sty}{2020/10/01} + +\cs_new:Npn \AtEndDvi {\AddToHook{shipout/lastpage}} +\expandafter\cs_set_eq:NN\csname ver@atenddvi.sty\endcsname\fmtversion +\@namedef {ver@atenddvi.sty}{2020/10/01} + +\ExplSyntaxOff + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\endinput +%% +%% End of file `ltshipout.ltx'. diff --git a/Master/texmf-dist/tex/latex-dev/base/ltxdoc.cls b/Master/texmf-dist/tex/latex-dev/base/ltxdoc.cls index 18ca996958a..09520e6cfd2 100644 --- a/Master/texmf-dist/tex/latex-dev/base/ltxdoc.cls +++ b/Master/texmf-dist/tex/latex-dev/base/ltxdoc.cls @@ -43,7 +43,7 @@ %% extension .ins) which are part of the distribution. \NeedsTeXFormat{LaTeX2e} \ProvidesClass{ltxdoc} - [2019/09/16 v2.0y Standard LaTeX documentation class] + [2020/05/17 v2.0z Standard LaTeX documentation class] \DeclareOption{a5paper}{\@latexerr{Option not supported}% {}} \DeclareOption*{% @@ -158,13 +158,16 @@ {\def\currentfile{#1.dtx}}% \ifnum\@auxout=\@partaux \@latexerr{\string\include\space cannot be nested}\@eha - \else \@docinclude#1 \fi} + \else + \set@curr@file@trim@spaces{#1}% + \expandafter\@docinclude\expandafter{\@curr@file} + \fi} \def\@docinclude#1 {\clearpage -\if@filesw \immediate\write\@mainaux{\string\@input{#1.aux}}\fi +\if@filesw \immediate\write\@mainaux{\string\@input{"#1.aux"}}\fi \@tempswatrue\if@partsw \@tempswafalse\edef\@tempb{#1}\@for \@tempa:=\@partlist\do{\ifx\@tempa\@tempb\@tempswatrue\fi}\fi \if@tempswa \let\@auxout\@partaux \if@filesw -\immediate\openout\@partaux #1.aux +\immediate\openout\@partaux "#1.aux" \immediate\write\@partaux{\relax}\fi \let\@ltxdoc@PrintIndex\PrintIndex \let\PrintIndex\relax diff --git a/Master/texmf-dist/tex/latex-dev/base/shortvrb.sty b/Master/texmf-dist/tex/latex-dev/base/shortvrb.sty index 804f54aa0d0..adeae1eca9d 100644 --- a/Master/texmf-dist/tex/latex-dev/base/shortvrb.sty +++ b/Master/texmf-dist/tex/latex-dev/base/shortvrb.sty @@ -43,7 +43,7 @@ %% extension .ins) which are part of the distribution. \NeedsTeXFormat{LaTeX2e}[1994/12/01] \ProvidesPackage{shortvrb} - [2019/12/16 v2.1l + [2020/06/15 v2.1m Standard LaTeX documentation package (FMi)] %% %% Package `doc' to use with LaTeX 2e diff --git a/Master/texmf-dist/tex/latex-dev/base/srclfile-ltx.sty b/Master/texmf-dist/tex/latex-dev/base/srclfile-ltx.sty new file mode 100644 index 00000000000..1e7ca0773cf --- /dev/null +++ b/Master/texmf-dist/tex/latex-dev/base/srclfile-ltx.sty @@ -0,0 +1,65 @@ +%% +%% This is file `srclfile-ltx.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% ltfilehook.dtx (with options: `scrlfile-draft') +%% +%% This is a generated file. +%% +%% Copyright 2020 Frank Mittelbach +%% +%% This file was generated from file(s) of the LaTeX `lthooks Bundle'. +%% -------------------------------------------------------------------------- +%% +%% It 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 file may only be distributed together with a copy of the LaTeX +%% `lthooks Bundle'. You may however distribute the `lthooks Bundle' +%% without such generated files. +%% +%% The newest sources can be found below +%% +%% https://github.com/FrankMittelbach/fmitex/ +%% +%% where one can also log issues in case there are any. +%% +%% +%% File: ltfilehook.dtx (C) Copyright 2020 Frank Mittelbach, LaTeX Team +\providecommand\ltfilehookversion{v0.9a} +\providecommand\ltfilehookdate{2020/07/19} +\newcommand\BeforeClass[2] + {\AddToHook{file/before/#1.cls}{#2}} +\newcommand\AfterClass [2] + {\AddToHook{file/after/#1.cls}{#2}} +\newcommand\AfterAtEndOfClass [2] + {\AddToHook{class/after/#1}{#2}} +\newcommand\BeforePackage [2] + {\AddToHook{package/before/#1.sty}{#2}} +\newcommand\AfterPackage [2] + {\AddToHook{file/after/#1.sty}{#2}} +\newcommand\AfterEndOfPackage [2] + {\AddToHook{package/after/#1}{#2}} +\newcommand\BeforeFile [2] + {% + \typeout{BeforeFile: #1!!!}% + \AddToHook{file/before/#1}{#2}} +\newcommand\AfterFile [2] + {% + \typeout{AfterFile: #1!!!}% + \AddToHook{file/after/#1}{#2}} +\expandafter\let\csname ver@scrlfile.sty\endcsname\fmtversion +\@namedef {ver@scrlfile.sty}{2020/10/01} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\endinput +%% +%% End of file `srclfile-ltx.sty'. diff --git a/Master/texmf-dist/tex/latex-dev/base/structuredlog.sty b/Master/texmf-dist/tex/latex-dev/base/structuredlog.sty new file mode 100644 index 00000000000..84faaeb8b54 --- /dev/null +++ b/Master/texmf-dist/tex/latex-dev/base/structuredlog.sty @@ -0,0 +1,72 @@ +%% +%% This is file `structuredlog.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% ltfilehook.dtx (with options: `structuredlog') +%% +%% This is a generated file. +%% +%% Copyright 2020 Frank Mittelbach +%% +%% This file was generated from file(s) of the LaTeX `lthooks Bundle'. +%% -------------------------------------------------------------------------- +%% +%% It 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 file may only be distributed together with a copy of the LaTeX +%% `lthooks Bundle'. You may however distribute the `lthooks Bundle' +%% without such generated files. +%% +%% The newest sources can be found below +%% +%% https://github.com/FrankMittelbach/fmitex/ +%% +%% where one can also log issues in case there are any. +%% +%% +%% File: ltfilehook.dtx (C) Copyright 2020 Frank Mittelbach, LaTeX Team +\providecommand\ltfilehookversion{v0.9a} +\providecommand\ltfilehookdate{2020/07/19} +\ProvidesExplPackage + {structuredlog}{\ltfilehookdate}{\ltfilehookversion} + {Structuring the TeX transcript file} + +\int_new:N \g__filehook_nesting_level_int + +\tl_new:N \g__filehook_nesting_prefix_tl +\tl_gset:Nn \g__filehook_nesting_prefix_tl { } +\AddToHook{file/before}{ + \int_gincr:N \g__filehook_nesting_level_int + \tl_gput_right:Nn\g__filehook_nesting_prefix_tl {=} + \iow_term:x { + \g__filehook_nesting_prefix_tl \space + ( LEVEL~ \int_use:N \g__filehook_nesting_level_int \space START )~ + \CurrentFile ^^J + } +} +\AddToHookNext{file/after}{ + \AddToHook{file/after}{ + \iow_term:x { + \g__filehook_nesting_prefix_tl \space + ( LEVEL~ \int_use:N \g__filehook_nesting_level_int \space STOP )~ + \CurrentFile ^^J + } + \int_gdecr:N \g__filehook_nesting_level_int + \tl_gset:Nx \g__filehook_nesting_prefix_tl + {\exp_after:wN \use_none:n \g__filehook_nesting_prefix_tl} + } +} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\endinput +%% +%% End of file `structuredlog.sty'. diff --git a/Master/texmf-dist/tex/latex-dev/base/tuenc.def b/Master/texmf-dist/tex/latex-dev/base/tuenc.def index 7305cc90dca..c7e3b1fded1 100644 --- a/Master/texmf-dist/tex/latex-dev/base/tuenc.def +++ b/Master/texmf-dist/tex/latex-dev/base/tuenc.def @@ -58,20 +58,45 @@ \expandafter\expandafter\expandafter\endinput \else \def\UnicodeFontTeXLigatures{+tlig;} - \def\reserved@a#1{% - \def\@remove@tlig##1{\@remove@tlig@##1\@nil#1\@nil\relax} - \def\@remove@tlig@##1#1{\@remove@tlig@@##1}} - \edef\reserved@b{\detokenize{+tlig;}} - \expandafter\reserved@a\expandafter{\reserved@b} - \def\@remove@tlig@@#1\@nil#2\relax{#1} - \def\remove@tlig#1{% - \begingroup - \font\remove@tlig - \expandafter\@remove@tlig\expandafter{\fontname\font}% - \remove@tlig - \char#1\relax - \endgroup - } + \ifnum\luatexversion<110 + \def\reserved@a#1{% + \def\@remove@tlig##1{\@remove@tlig@##1\@nil#1\@nil\relax} + \def\@remove@tlig@##1#1{\@remove@tlig@@##1}} + \edef\reserved@b{\detokenize{+tlig;}} + \expandafter\reserved@a\expandafter{\reserved@b} + \def\@remove@tlig@@#1\@nil#2\relax{#1} + \def\remove@tlig#1{% + \begingroup + \font\remove@tlig + \expandafter\@remove@tlig\expandafter{\fontname\font}% + \remove@tlig + \char#1\relax + \endgroup + } + \else + \newluafunction\@remove@tlig@@@@ + \def\now@and@everyjob#1{\toksapp\everyjob{#1}#1} + \now@and@everyjob{\directlua{ + local rawchar_func = token.create'@remove@tlig@@@@'.index + local forcehmode = tex.forcehmode + local put_next = token.put_next + local glyph_id = node.id'glyph' + local rawchar_token = token.new(rawchar_func, token.command_id'lua_call') + lua.get_functions_table()[rawchar_func] = function() + local mode = tex.nest.top.mode + if mode == 1 or mode == -1 then + put_next(rawchar_token) + return forcehmode(true) + end + local n = node.new(glyph_id, 256) + n.font = font.current() + n.char = token.scan_int() + return node.write(n) + end + token.set_lua('@remove@tlig@@@', rawchar_func, 'global', 'protected') + }} + \def\remove@tlig#1{\@remove@tlig@@@#1\relax} + \fi \fi \else \def\UnicodeFontTeXLigatures{mapping=tex-text;} diff --git a/Master/texmf-dist/tex/latex-dev/graphics/lscape.sty b/Master/texmf-dist/tex/latex-dev/graphics/lscape.sty index e4ece0f218d..d9f2daee5a8 100644 --- a/Master/texmf-dist/tex/latex-dev/graphics/lscape.sty +++ b/Master/texmf-dist/tex/latex-dev/graphics/lscape.sty @@ -21,7 +21,7 @@ %% \NeedsTeXFormat{LaTeX2e}[1994/06/01] \ProvidesPackage{lscape} - [2000/10/22 v3.01 Landscape Pages (DPC)] + [2020/05/28 v3.02 Landscape Pages (DPC)] \newif\ifGin@pdftex \Gin@pdftexfalse \DeclareOption{pdftex}{% @@ -31,11 +31,11 @@ \DeclareOption*{\PassOptionsToPackage\CurrentOption{graphics}} \ProcessOptions \RequirePackage{graphics} -\let\LS@makecol=\@makecol -\let\LS@makefcolumn=\@makefcolumn \def\LS@rot{% \setbox\@outputbox\vbox{\hbox{\rotatebox{90}{\box\@outputbox}}}} \def\landscape{% + \let\LS@makecol=\@makecol + \let\LS@makefcolumn=\@makefcolumn \clearpage \begingroup \vsize=\textwidth diff --git a/Master/texmf-dist/tex/latex-dev/tools/array.sty b/Master/texmf-dist/tex/latex-dev/tools/array.sty index cbf82052b2c..28162839cb1 100644 --- a/Master/texmf-dist/tex/latex-dev/tools/array.sty +++ b/Master/texmf-dist/tex/latex-dev/tools/array.sty @@ -46,7 +46,7 @@ \DeclareCurrentRelease{}{2020-10-01} \ProvidesPackage{array} - [2020/10/01 v2.5b Tabular extension package (FMi)] + [2020/10/01 v2.5c Tabular extension package (FMi)] %% \def\@addtopreamble#1{\xdef\@preamble{\@preamble #1}} @@ -330,20 +330,22 @@ \setlength{\extratabsurround}{2pt} \newlength{\backup@length} \newcommand{\firsthline}{% - \multicolumn1c{% + \multicolumn1{@{}c@{}}{% \global\backup@length\ht\@arstrutbox \global\advance\backup@length\dp\@arstrutbox \global\advance\backup@length\arrayrulewidth \raise\extratabsurround\copy\@arstrutbox + \kern-1sp% }\\[-\backup@length]\hline } -\newcommand{\lasthline}{\hline\multicolumn1c{% +\newcommand{\lasthline}{\hline\multicolumn1{@{}c@{}}{% \global\backup@length2\ht\@arstrutbox \global\advance\backup@length2\dp\@arstrutbox \global\advance\backup@length\arrayrulewidth }\\[-\backup@length]% - \multicolumn1c{% + \multicolumn1{@{}c@{}}{% \lower\extratabsurround\copy\@arstrutbox + \kern-1sp% }% } \CheckCommand*\@xhline{\ifx\reserved@a\hline diff --git a/Master/texmf-dist/tex/latex-dev/tools/varioref.sty b/Master/texmf-dist/tex/latex-dev/tools/varioref.sty index 532d7fa572d..57c3227b5b3 100644 --- a/Master/texmf-dist/tex/latex-dev/tools/varioref.sty +++ b/Master/texmf-dist/tex/latex-dev/tools/varioref.sty @@ -52,7 +52,7 @@ \DeclareCurrentRelease{}{2019-10-01} \ProvidesPackage{varioref} - [2020/01/23 v1.6c package for extended references (FMi)] + [2020/07/20 v1.6d package for extended references (FMi)] %% @@ -108,6 +108,7 @@ \def\reftextfaraway#1{op bladsy~\pageref{#1}}% \def\reftextpagerange#1#2{op bladsye~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} tot~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{american} {\vref@addto\extrasamerican{% @@ -120,6 +121,7 @@ \def\reftextfaraway#1{on page~\pageref{#1}}% \def\reftextpagerange#1#2{on pages~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} to~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{arabic} {\vref@addto\extrasarabic{% @@ -131,6 +133,7 @@ \def\reftextfaraway#1{بالصفحة رقم~\pageref{#1}}% \def\reftextpagerange#1#2{بالصفحات~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} حتى~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{austrian} {\vref@addto\extrasaustrian{% @@ -142,6 +145,7 @@ \def\reftextfaraway#1{auf Seite~\pageref{#1}}% \def\reftextpagerange#1#2{auf Seiten~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} bis~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{naustrian} {\vref@addto\extrasnaustrian{% @@ -153,6 +157,7 @@ \def\reftextfaraway#1{auf Seite~\pageref{#1}}% \def\reftextpagerange#1#2{auf Seiten~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} bis~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{basque} {\vref@addto\extrasbasque{% @@ -164,6 +169,7 @@ \def\reftextfaraway#1{~\pageref{#1}. orrialdean}% \def\reftextpagerange#1#2{~\pageref{#1}--\pageref{#2} orrialdeetan}% \def\reftextlabelrange#1#2{\ref{#1}.etik \ref{#2}.eraino}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{bahasam} {\vref@addto\extrasbahasam{% @@ -175,6 +181,7 @@ \def\reftextfaraway#1{pada muka surat~\pageref{#1}}% \def\reftextpagerange#1#2{pada muka surat~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1}--\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{brazil} {\vref@addto\extrasbrazil{% @@ -189,6 +196,7 @@ \def\reftextfaraway#1{na p\'agina~\pageref{#1}}% \def\reftextpagerange#1#2{nas p\'aginas~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} a~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{breton} {\vref@excuse{breton}% @@ -204,6 +212,7 @@ on pages~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\vref@stringwarning\reflabelpagerange \ref{#1} to~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{bulgarian}% {\vref@addto\extrasbulgarian{% @@ -233,6 +242,7 @@ \cyrs\cyrt\cyrr\cyra\cyrn\cyri\cyrc\cyri ~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} \cyrd\cyro~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{catalan} {\vref@addto\extrascatalan{% @@ -245,6 +255,7 @@ \def\reftextpagerange#1#2{a les p\`agines~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} a~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{croatian} {\vref@addto\extrascroatian{% @@ -256,6 +267,7 @@ \def\reftextfaraway#1{na stranici~\pageref{#1}}% \def\reftextpagerange#1#2{na stranicama~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} do~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{czech} {%\vref@excuse{czech}% @@ -268,6 +280,7 @@ \def\reftextfaraway#1{na stran\v{e}~\pageref{#1}}% \def\reftextpagerange#1#2{na stran\'ach~\pageref{#1}\--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} a\v{z}~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{danish} {\vref@addto\extrasdanish{% @@ -283,6 +296,7 @@ \def\reftextfaraway#1{p\aa{} side~\pageref{#1}}% \def\reftextpagerange#1#2{p\aa{} side~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} til~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{dutch} {\vref@addto\extrasdutch{% @@ -299,6 +313,7 @@ \def\reftextfaraway#1{op \refpagename~\pageref{#1}}% \def\reftextpagerange#1#2{op pagina's~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1}--\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{english} {\vref@addto\extrasenglish{% @@ -311,6 +326,7 @@ \def\reftextfaraway#1{on page~\pageref{#1}}% \def\reftextpagerange#1#2{on pages~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} to~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{esperanto} {\vref@addto\extrasesperanto{% @@ -325,6 +341,7 @@ \def\reftextfaraway#1{en pa\^go~\pageref{#1}}% \def\reftextpagerange#1#2{en pa\^goj~\pageref{#1} \^gis \pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} \^gis~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{finnish} {\vref@addto\extrasfinnish{% @@ -338,6 +355,7 @@ \def\reftextfaraway#1{sivulla~\pageref{#1}}% \def\reftextpagerange#1#2{sivuilla~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1}--\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{french} {\vref@addto\extrasfrench{% @@ -350,6 +368,7 @@ \def\reftextfaraway#1{page~\pageref{#1}}% \def\reftextpagerange#1#2{pages~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} \`a~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{galician} {\vref@addto\extrasgalician{% @@ -362,6 +381,7 @@ \def\reftextpagerange#1#2{% nas p\'axinas~\pageref{#1}-\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} a~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{german} {\vref@addto\extrasgerman{% @@ -373,6 +393,7 @@ \def\reftextfaraway#1{auf Seite~\pageref{#1}}% \def\reftextpagerange#1#2{auf den Seiten~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} bis~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{ngerman} {\vref@addto\extrasngerman{% @@ -384,6 +405,7 @@ \def\reftextfaraway#1{auf Seite~\pageref{#1}}% \def\reftextpagerange#1#2{auf den Seiten~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} bis~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{greek} {\vref@addto\extrasgreek{% @@ -398,6 +420,7 @@ \def\reftextpagerange#1#2{stis sel'ides\nobreakspace \pageref{#1}---\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} ws\nobreakspace\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{icelandic} {\vref@addto\extrasicelandic{% @@ -413,6 +436,7 @@ \def\reftextfaraway#1{\'{a} s\'{i}{\dh}u~\pageref{#1}}% \def\reftextpagerange#1#2{\'{a} s\'{i}{\dh}um~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} til~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{italian} {\vref@addto\extrasitalian{% @@ -427,6 +451,20 @@ \def\reftextfaraway#1{a pagina~\pageref{#1}}% \def\reftextpagerange#1#2{nelle pagine~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{da~\ref{#1} a~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat + }} +\DeclareOption{japanese} + {\vref@addto\extrasjapanese{% + \def\reftextfaceafter {\reftextvario{見開き}{次}頁}% + \def\reftextfacebefore{\reftextvario{見開き}{前}頁}% + \def\reftextafter {\reftextvario{直後の}{次}頁}% + \def\reftextbefore {\reftextvario{直前の}{前}頁}% + \def\reftextcurrent {\reftextvario{この}{現}頁}% + \def\reftextfaraway#1{\pageref{#1}頁}% + \def\reftextpagerange#1#2{\pageref{#1}頁から\pageref{#2}頁}% + \def\reftextlabelrange#1#2{\ref{#1}から\ref{#2}}% + \def\vrefrangeformat#1#2#3{\vpagerefrange[{#1}]{#2}{#3}の% + \reftextlabelrange{#2}{#3}}% }} \DeclareOption{magyar} {\vref@addto\extrasmagyar{% @@ -442,6 +480,7 @@ on pages~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\vref@stringwarning\reflabelpagerange \ref{#1} to~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }% \AtBeginDocument{\providecommand\aza[1]{a/az% \PackageError{varioref}{% @@ -463,6 +502,7 @@ \def\reftextfaraway#1{p\aa{} side~\pageref{#1}}% \def\reftextpagerange#1#2{p\aa{} side~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} til~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{nynorsk} {\vref@addto\extrasnynorsk{% @@ -474,6 +514,7 @@ \def\reftextfaraway#1{p\aa{} side~\pageref{#1}}% \def\reftextpagerange#1#2{p\aa{} side~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} til~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{polish} {\vref@addto\extraspolish{% @@ -488,6 +529,7 @@ \def\reftextfaraway#1{na stronie~\pageref{#1}}% \def\reftextpagerange#1#2{na stronach~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{od~\ref{#1} do~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{portuges} {\vref@addto\extrasportuges{% @@ -501,6 +543,7 @@ \def\reftextfaraway#1{na p\'agina~\pageref{#1}}% \def\reftextpagerange#1#2{nas p\'aginas~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} a~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{romanian} {\vref@addto\extrasromanian{% @@ -514,6 +557,7 @@ \def\reftextfaraway#1{pe pagina~\pageref{#1}}% \def\reftextpagerange#1#2{pe paginile~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} la~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{russian} {\vref@addto\extrasrussian{% @@ -538,6 +582,7 @@ \def\reftextpagerange#1#2{\cyrn\cyra\ \cyrs\cyrt\cyrr\cyra\cyrn \cyri\cyrc\cyra\cyrh~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\cyrs~\ref{#1}\ \cyrp\cyro~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{slovak} {\vref@addto\extrasslovak{% @@ -553,6 +598,7 @@ \def\reftextfaraway#1{na strane~\pageref{#1}}% \def\reftextpagerange#1#2{na stran\'ach~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} a\v z~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{slovene} {\vref@addto\extrasslovene{% @@ -564,6 +610,7 @@ \def\reftextfaraway#1{na strani~\pageref{#1}}% \def\reftextpagerange#1#2{na straneh~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{od~\ref{#1} do~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{spanish} {\vref@addto\extrasspanish{% @@ -576,6 +623,7 @@ \def\reftextpagerange#1#2{en las p\'aginas~\pageref{#1}% -\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} a~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{swedish} {\vref@addto\extrasswedish{% @@ -591,6 +639,7 @@ \def\reftextpagerange#1#2{p\aa\ sidorna~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} till~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{turkish} {\vref@excuse{turkish}% @@ -604,6 +653,7 @@ \def\reftextfaraway#1{on page~\pageref{#1}}% \def\reftextpagerange#1#2{on pages~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} to~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{ukrainian} {\vref@addto\extrasukrainian{% @@ -626,6 +676,7 @@ \def\reftextpagerange#1#2{\cyrn\cyra\ \cyrs\cyrt\cyro\cyrr\cyrii \cyrn\cyrk\cyra\cyrh~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\cyrz~\ref{#1}\ \cyrd\cyro~\ref{#2}}% + \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{francais}{% \typeout{Please use `french' instead of `francais'}% @@ -798,8 +849,10 @@ \fi } \newcommand\vpagerefrange{\@ifstar\@svpagerefrange\@vpagerefrange} -\newcommand\vrefrange[3][\reftextcurrent] - {\reftextlabelrange{#2}{#3} \vpagerefrange[{#1}]{#2}{#3}} +\newcommand\vrefrange[1][\reftextcurrent]{\vrefrangeformat{#1}} +\def\vrefrangedefaultformat#1#2#3{% + \reftextlabelrange{#2}{#3} \vpagerefrange[{#1}]{#2}{#3}} +\let\vrefrangeformat\vrefrangedefaultformat \DeclareRobustCommand\Vref{\@ifstar {\Vref@star}% {\Vr@f}} diff --git a/Master/texmf-dist/tex/latex-dev/tools/verbatim.sty b/Master/texmf-dist/tex/latex-dev/tools/verbatim.sty index ab0f603ba5d..647fe064567 100644 --- a/Master/texmf-dist/tex/latex-dev/tools/verbatim.sty +++ b/Master/texmf-dist/tex/latex-dev/tools/verbatim.sty @@ -39,7 +39,7 @@ %% Copyright (C) 1989--2003 by Rainer Sch\"opf. All rights reserved. \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{verbatim} - [2019/11/10 v1.5r LaTeX2e package for verbatim enhancements] + [2020-07-07 v1.5u LaTeX2e package for verbatim enhancements] \@ifundefined{verbatim@@@}{}{\endinput} \newtoks\every@verbatim \every@verbatim={} @@ -206,8 +206,12 @@ \@ifstar{\verbatim@input\relax}% {\verbatim@input{\frenchspacing\@vobeyspaces}}} \def\verbatim@input#1#2{% - \IfFileExists {#2}{\@verbatim #1\relax - \verbatim@readfile{\@filef@und}\endtrivlist\endgroup\@doendpe}% + \IfFileExists {#2}{% + \expandafter\@swaptwoargs\expandafter + {\expandafter{\@filef@und}}% + {\@verbatim #1\relax + \verbatim@readfile}% + \endtrivlist\endgroup\@doendpe}% {\typeout {No file #2.}\endgroup}} \endinput %% |