[latex3-commits] [git/LaTeX3-latex3-latex2e] zref: Starting on a zref-replacement (8bb419d4)
Joseph Wright
joseph.wright at morningstar2.co.uk
Fri Oct 2 09:55:45 CEST 2020
Repository : https://github.com/latex3/latex2e
On branch : zref
Link : https://github.com/latex3/latex2e/commit/8bb419d435e50a20637c7f9a2a00eea4212843a9
>---------------------------------------------------------------
commit 8bb419d435e50a20637c7f9a2a00eea4212843a9
Author: Joseph Wright <joseph.wright at morningstar2.co.uk>
Date: Wed Sep 30 15:17:55 2020 +0100
Starting on a zref-replacement
>---------------------------------------------------------------
8bb419d435e50a20637c7f9a2a00eea4212843a9
base/ltzref.dtx | 296 ++++++++++++++++++++++++++++++++++++++++
base/{ifthen.ins => ltzref.ins} | 13 +-
2 files changed, 299 insertions(+), 10 deletions(-)
diff --git a/base/ltzref.dtx b/base/ltzref.dtx
new file mode 100644
index 00000000..0d556d13
--- /dev/null
+++ b/base/ltzref.dtx
@@ -0,0 +1,296 @@
+% \iffalse meta-comment
+%
+% Copyright (C) 2020
+% The LaTeX3 Project and any individual authors listed elsewhere
+% in this file.
+%
+% This file is part of the LaTeX base system.
+% -------------------------------------------
+%
+% 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
+% https://www.latex-project.org/lppl.txt
+% and version 1.3c or later is part of all distributions of LaTeX
+% version 2008 or later.
+%
+% This file has the LPPL maintenance status "maintained".
+%
+% The list of all files belonging to the LaTeX base distribution is
+% given in the file `manifest.txt'. See also `legal.txt' for additional
+% information.
+%
+% The list of derived (unpacked) files belonging to the distribution
+% and covered by LPPL is defined by the unpacking scripts (with
+% extension .ins) which are part of the distribution.
+%
+% \fi
+%
+% \iffalse
+%%% From File: ltzref.dtx
+%
+%<*driver>
+% \fi
+\ProvidesFile{ltzref.dtx}
+ [2020-09-28 v0.1 LaTeX Kernel (flexible labels/references)]
+% \iffalse
+\documentclass{l3doc}
+\EnableCrossrefs
+\CodelineIndex
+\begin{document}
+ \DocInput{ltzref.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \section{Flexible labels and references}
+%
+% The reference module uses the ideas of attributes and labels. A label is
+% a document reference point: a name for the user. An attribute is something
+% that \LaTeX{} can track, such as a page number, section number or name.
+% The names of labels and attributes may be arbitrary. Note that there is
+% a single namespace for each.
+%
+% \subsection{Code interfaces}
+%
+% \begin{function}{\ref_attribute_gset:nnnn}
+% \begin{syntax}
+% \cs{ref_attribute_gset:nnnn} \Arg{attribute} \Arg{default} \Arg{setpoint} \Arg{code}
+% \end{syntax}
+% Sets the \meta{attribute} to have the \meta{default} specified, and at the
+% \meta{setpoint} (either |now| or |shipout|) to write the result of the
+% \meta{code} as part of a label. The \meta{code} should be expandable.
+% \end{function}
+%
+% \begin{function}{\ref_label:nN, \ref_label:nn, \ref_label:nV}
+% \begin{syntax}
+% \cs{ref_label:nN} \Arg{label} \Arg{clist var}
+% \cs{ref_label:nn} \Arg{label} \Arg{clist}
+% \end{syntax}
+% Writes the list of attributes given by the \meta{clist} to the |.aux|
+% file with the \meta{label} specified.
+% \end{function}
+%
+% \begin{function}[EXP]{\ref_value:nn}
+% \begin{syntax}
+% \cs{ref_value:nn} \Arg{label} \Arg{attribute}
+% \end{syntax}
+% Expands to the value of the \meta{attribute} for the \meta{label}, if
+% available, and the default value otherwise.
+% \end{function}
+%
+% \subsection{Auxiliary file interfaces}
+%
+% \begin{function}{\newlabeldata}
+% \begin{syntax}
+% \cs{newlabeldata} \Arg{attribute} \Arg{data}
+% \end{syntax}
+% This is a command only for use in the |.aux| file. It loads the key--value
+% list of \meta{data} to be available for the \meta{attribute}.
+% \end{function}
+%
+% \subsection{Pre-declared attributes}
+%
+% \begin{variable}{abspage}
+% The absolute value of the current page: starts at $1$ and increases
+% monotonically at each shipout.
+% \end{variable}
+%
+% \begin{variable}{page}
+% The current page as given by \cs{thepage}: this may or may not
+% be a numerical value, depending on the current style. Contrast with
+% \cs{abspage}.
+% \end{variable}
+%
+% \subsection{The main label list}
+%
+% \begin{variable}{\g_ref_main_clist}
+% A list of the attributes set by the main label (\cs{label}):
+% contains \texttt{page}.
+% \end{variable}
+%
+% \section{Implementation}
+%
+% \begin{macrocode}
+%<*2ekernel>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=ref>
+% \end{macrocode}
+%
+% \begin{macrocode}
+\ExplSyntaxOn
+% \end{macrocode}
+%
+% The approach here is based closely on that from \pkg{zref}; separate out
+% lists of attributes and the attributes themselves, so the latter can be
+% used multiple times. However, not everything is a straight copy. Firstly,
+% we treat lists of attributes as simple comma lists: that allows us to have
+% either saved or dynamic lists and to avoid another data structure. The cost
+% is that errors are detected at point-of-use, but in any real case that should
+% be true anyway (and is true for \tn{zref at labelbyprop} already). Secondly,
+% we allow attributes (called \enquote{properties} by \pkg{zref}) to have
+% arbitrary names, as the code does not require them to tokenize as control
+% sequences.
+%
+% \begin{macro}{\ref_attribute_gset:nnnn, \@@_attribute_gset:nnnn}
+% As attributes can be reset, they are not constants. But they also have
+% various pieces of required data. So we use the same approach as color and
+% make them declarations. Data-wise, we need the detail of the implementation,
+% the default and a flag to show if the code works now or at shipout. This
+% last entry is done using text so needs a check. We could use a set of
+% |prop| here, but as we never need to map or copy the lists, we can gain
+% performance using the hash table approach.
+% \begin{macrocode}
+\cs_new_protected:Npn \ref_attribute_gset:nnnn #1#2#3#4
+ {
+ \exp_args:Nx \@@_attribute_gset:nnnn { \tl_to_str:n {#1} }
+ {#2} {#3} {#4}
+ }
+\cs_new_protected:Npn \@@_attribute_gset:nnnn #1#2#3#4
+ {
+ \cs_gset:cpn { @@_attribute_ #1 : } {#4}
+ \tl_gclear_new:c { g_@@_default_ #1 _tl }
+ \tl_gset:cn { g_@@_default_ #1 _tl } {#2}
+ \bool_if_exist:cF { g_@@_shipout_ #1 _tl }
+ { \bool_new:c { g_@@_shipout_ #1 _tl } }
+ \str_case:nnF {#3}
+ {
+ { now } { { \bool_gset_false:c { g_@@_shipout_ #1 _tl } } }
+ { shipout }
+ { \bool_gset_true:c { g_@@_shipout_ #1 _tl } }
+ }
+ { \msg_error:nnnn { ref } { unknown-setpoint } {#1} {#3} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\ref_label:nN}
+% \begin{macro}{\ref_label:nn, \ref_label:nV, \@@_label:nn}
+% \begin{macro}[EXP]{\@@_label_attribute:n, \@@_label_attribute_aux:n}
+% Writing data when it is labelled means expanding at this stage and possibly
+% later too. That is all pretty easy using \pkg{expl3}: we accept a stray
+% comma at the end of the list as that is easier to deal with than trying
+% to tidy up, and there is no real downside.
+% \begin{macrocode}
+\cs_new_protected:Npn \ref_label:nN #1#2
+ { \ref_label:nV {#1} #2 }
+\cs_new_protected:Npn \ref_label:nn #1#2
+ { \exp_args:Nx \@@_label:nn { \tl_to_str:n {#1} } {#2} }
+\cs_generate_variant:Nn \ref_label:nn { nV }
+\cs_new_protected:Npn \@@_label:nn #1#2
+ {
+ \legacy_if:nT { @filesw }
+ {
+ \iow_shipout_x:Nx \@auxout
+ {
+ \token_to_str:N \newlabeldata
+ {#1}
+ { \clist_map_function:nN {#2} \@@_label_attribute:n }
+ }
+ }
+ }
+\cs_new:Npn \@@_label_attribute:n #1
+ { \exp_args:Ne \@@_label_attribute_aux:n { \tl_to_str:n {#1} } }
+\cs_new:Npn \@@_label_attribute_aux:n #1
+ {
+ \cs_if_exist:cTF { @@_attribute_ #1 : }
+ {
+ {#1}
+ {
+ \bool_if:cTF { g_@@_shipout_ #1 _tl }
+ { \exp_not:c }
+ { \use:c }
+ { @@_attribute_ #1 : }
+ }
+ }
+ { \msg_expandable_error:nnn { ref } { attribute-not-defined } {#1} }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\ref_value:nn, \@@_value:nn, \@@_value_aux:nn}
+% Search for the label/attribute combination, and if not found fall back.
+% \begin{macrocode}
+\cs_new:Npn \ref_value:nn #1#2
+ {
+ \exp_args:Nee \@@_value:nn { \tl_to_str:n {#1} } { \tl_to_str:n {#2} }
+ }
+\cs_new:Npn \@@_value:nn #1#2
+ {
+ \tl_if_exist:cTF { g_@@_label_ #1 _ #2 _tl }
+ { \tl_use:c { g_@@_label_ #1 _ #2 _tl } }
+ {
+ \tl_if_exist:cTF { g_@@_default_ #2 _tl }
+ { \tl_use:c { g_@@_default_ #2 _tl } }
+ { \exp_not:n { \textbf { ?? } } }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\newlabeldata}
+% \begin{macro}{\@@_data:nnn}
+% A standard recursion loop.
+% \begin{macrocode}
+\cs_new_protected:Npn \newlabeldata #1#2
+ {
+ \@@_load:nnn {#1} #2 { \q_recursion_tail } { ? } \q_recursion_stop
+ }
+\cs_new_protected:Npn \@@_data:nnn #1#2#3
+ {
+ \quark_if_recursion_tail_stop:n {#2}
+ \tl_clear_new:c { g_@@_label_ #1 _ #2 _tl }
+ \tl_gset:cn { g_@@_label_ #1 _ #2 _tl } {#3}
+ \@@_load:nnn {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}{abspage}
+% \begin{macrocode}
+\ref_attribute_gset:nnnn { abspage } { 0 } { shipout }
+ { \int_use:N \g_shipout_readonly_int }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{page}
+% \begin{macrocode}
+\ref_attribute_gset:nnnn { page } { 0 } { shipout } { \thepage }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_ref_main_clist}
+% \begin{macrocode}
+\clist_new:N \g_ref_main_clist
+\clist_gput_right:Nn \g_ref_main_clist { page }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macrocode}
+\msg_new:nnnn { ref } { attribute-not-defined }
+ { Attribute~'#1'~not~defined. }
+ {
+ LaTeX~has~been~asked~to~use~attribute~'#1',~but~this~
+ name~has~not~been~defined.
+ }
+\msg_new:nnnn { ref } { unknown-setpoint }
+ { Unknown~keyword~'#3'~for~setting~attribute~'#1'. }
+ {
+ LaTeX~has~been~asked~to~set~the~attribute~'#1',~but~the~keyword~
+ '#3'~is~not~one~of~the~two~known~values:~'now'~or~'shipout'.
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\ExplSyntaxOff
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</2ekernel>
+% \end{macrocode}
diff --git a/base/ifthen.ins b/base/ltzref.ins
similarity index 83%
copy from base/ifthen.ins
copy to base/ltzref.ins
index 0e813cd5..b2ea2246 100644
--- a/base/ifthen.ins
+++ b/base/ltzref.ins
@@ -3,7 +3,7 @@
%% driver files from the doc files in this package when run through
%% LaTeX or TeX.
%%
-%% Copyright (C) 1993-2020
+%% Copyright (C) 2020
%% The LaTeX3 Project and any individual authors listed elsewhere
%% in this file.
%%
@@ -20,13 +20,6 @@
%%
%% This file has the LPPL maintenance status "maintained".
%%
-%% As this file contains legal notices, it is NOT PERMITTED to modify
-%% this file in any way that the legal information placed into
-%% generated files is changed (i.e., the files generated when the
-%% original file is executed). This restriction does not apply if
-%% (parts of) the content is reused in a different WORK producing its
-%% own generated files.
-%%
%% The list of all files belonging to the LaTeX base distribution is
%% given in the file `manifest.txt'. See also `legal.txt' for additional
%% information.
@@ -48,7 +41,7 @@ reports for it can be opened at https://latex-project.org/bugs.html
(but please observe conditions on bug reports sent to that address!)
-Copyright (C) 1993-2020
+Copyright (C) 2020
The LaTeX3 Project and any individual authors listed elsewhere
in this file.
@@ -81,6 +74,6 @@ extension .ins) which are part of the distribution.
\keepsilent
\usedir{tex/latex/base}
-\generateFile{ifthen.sty}{t}{\from{ifthen.dtx}{package}}
+\generate{\file{ltzref.sty}{\from{ltzref.dtx}{2ekernel}}}
\endbatchfile
More information about the latex3-commits
mailing list.