From 52b787d36c60fda90673669dd2809c95c1fdfca5 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Wed, 19 Oct 2016 20:38:20 +0000 Subject: l3 (19oct16) git-svn-id: svn://tug.org/texlive/trunk@42306 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/source/latex/l3kernel/expl3.dtx | 7 +- .../texmf-dist/source/latex/l3kernel/l3basics.dtx | 232 +-- .../source/latex/l3kernel/l3bootstrap.dtx | 6 +- Master/texmf-dist/source/latex/l3kernel/l3box.dtx | 9 +- .../source/latex/l3kernel/l3candidates.dtx | 160 +- .../texmf-dist/source/latex/l3kernel/l3clist.dtx | 39 +- .../texmf-dist/source/latex/l3kernel/l3coffins.dtx | 10 +- .../texmf-dist/source/latex/l3kernel/l3color.dtx | 14 +- Master/texmf-dist/source/latex/l3kernel/l3doc.dtx | 2051 +++++++++++++------- .../texmf-dist/source/latex/l3kernel/l3drivers.dtx | 1160 ++++++++++- .../texmf-dist/source/latex/l3kernel/l3expan.dtx | 157 +- Master/texmf-dist/source/latex/l3kernel/l3file.dtx | 64 +- .../texmf-dist/source/latex/l3kernel/l3final.dtx | 10 +- .../source/latex/l3kernel/l3fp-assign.dtx | 14 +- .../texmf-dist/source/latex/l3kernel/l3fp-aux.dtx | 22 +- .../source/latex/l3kernel/l3fp-basics.dtx | 8 +- .../source/latex/l3kernel/l3fp-convert.dtx | 10 +- .../source/latex/l3kernel/l3fp-extended.dtx | 10 +- .../source/latex/l3kernel/l3fp-logic.dtx | 8 +- .../source/latex/l3kernel/l3fp-parse.dtx | 50 +- .../source/latex/l3kernel/l3fp-traps.dtx | 30 +- .../texmf-dist/source/latex/l3kernel/l3fp-trig.dtx | 18 +- Master/texmf-dist/source/latex/l3kernel/l3fp.dtx | 12 +- Master/texmf-dist/source/latex/l3kernel/l3int.dtx | 96 +- Master/texmf-dist/source/latex/l3kernel/l3keys.dtx | 665 ++++--- .../texmf-dist/source/latex/l3kernel/l3luatex.dtx | 8 +- Master/texmf-dist/source/latex/l3kernel/l3msg.dtx | 29 +- .../texmf-dist/source/latex/l3kernel/l3names.dtx | 22 +- Master/texmf-dist/source/latex/l3kernel/l3prg.dtx | 58 +- Master/texmf-dist/source/latex/l3kernel/l3prop.dtx | 25 +- .../texmf-dist/source/latex/l3kernel/l3quark.dtx | 11 +- Master/texmf-dist/source/latex/l3kernel/l3seq.dtx | 49 +- Master/texmf-dist/source/latex/l3kernel/l3skip.dtx | 27 +- Master/texmf-dist/source/latex/l3kernel/l3str.dtx | 51 +- Master/texmf-dist/source/latex/l3kernel/l3tl.dtx | 92 +- .../texmf-dist/source/latex/l3kernel/l3token.dtx | 226 ++- 36 files changed, 3652 insertions(+), 1808 deletions(-) (limited to 'Master/texmf-dist/source/latex/l3kernel') diff --git a/Master/texmf-dist/source/latex/l3kernel/expl3.dtx b/Master/texmf-dist/source/latex/l3kernel/expl3.dtx index 5a97f7632e7..4a37d2c3c4e 100644 --- a/Master/texmf-dist/source/latex/l3kernel/expl3.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/expl3.dtx @@ -36,8 +36,8 @@ %<*driver|generic|package> \def\ExplFileName{expl3}% \def\ExplFileDescription{L3 programming layer}% -\def\ExplFileDate{2016/05/18}% -\def\ExplFileVersion{6512}% +\def\ExplFileDate{2016/10/19}% +\def\ExplFileVersion{6730}% % %<*driver> \documentclass[full]{l3doc} @@ -896,8 +896,7 @@ % repository. % \item At an internal level, most functions should be generated % \tn{long} (using \cs{cs_new:Npn}) rather than \enquote{short} (using -% \cs{cs_new_nopar:Npn}). However, functions which take no arguments -% should be set \enquote{short}. +% \cs{cs_new_nopar:Npn}). % \item Where possible, declare all variables and functions (using % \cs{cs_new:Npn}, \cs{tl_new:N}, etc.) before use. % \item Prefer \enquote{higher-level} functions over \enquote{lower-level}, diff --git a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx index 3e2faf912cf..84e6a2c9086 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -%% File: l3basics.dtx Copyright (C) 1990-2015 The LaTeX3 project +%% File: l3basics.dtx Copyright (C) 1990-2016 The LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -37,7 +37,7 @@ \documentclass[full]{l3doc} % %<*driver|package> -\GetIdInfo$Id: l3basics.dtx 6315 2015-11-22 22:49:22Z bruno $ +\GetIdInfo$Id: l3basics.dtx 6696 2016-09-01 16:09:52Z bruno $ {L3 Basic definitions} % %<*driver> @@ -147,7 +147,7 @@ % Declaring a function before setting up the code means that the name % chosen will be checked and an error raised if it is already in use. % The name of a function can be checked at the point of definition using -% the \cs{cs_new\ldots} functions: this is recommended for all +% the \cs[no-index]{cs_new\ldots} functions: this is recommended for all % functions which are defined for the first time. % % There are three ways to define new functions. @@ -558,7 +558,7 @@ % \cs_gset_nopar:Nx, \cs_gset_nopar:cx % } % \begin{syntax} -% \cs{cs_gset_nopar:Nn} \meta{function} \Arg{code} +% \cs{cs_git cogset_nopar:Nn} \meta{function} \Arg{code} % \end{syntax} % Sets \meta{function} to expand to \meta{code} as replacement text. % Within the \meta{code}, the number of \meta{parameters} is detected @@ -743,25 +743,16 @@ % \end{verbatim} % after two expansions of \cs{use:c}. % -% \begin{function}[EXP,added = 2012-11-10] +% \begin{function}[noTF, EXP, added = 2012-11-10] % {\cs_if_exist_use:N, \cs_if_exist_use:c} % \begin{syntax} % \cs{cs_if_exist_use:N} \meta{control sequence} -% \end{syntax} -% Tests whether the \meta{control sequence} is currently defined -% (whether as a function or another control sequence type), and if it -% does inserts the \meta{control sequence} into the input stream. -% \end{function} -% -% \begin{function}[TF,EXP, added = 2012-11-10] -% {\cs_if_exist_use:N, \cs_if_exist_use:c} -% \begin{syntax} % \cs{cs_if_exist_use:NTF} \meta{control sequence} \Arg{true code} \Arg{false code} % \end{syntax} % Tests whether the \meta{control sequence} is currently defined % (whether as a function or another control sequence type), and if it -% does inserts the \meta{control sequence} into the input stream followed -% by the \meta{true code}. +% is inserts the \meta{control sequence} into the input stream followed +% by the \meta{true code}. Otherwise the \meta{false code} is used. % \end{function} % % \begin{function}[EXP]{\cs:w, \cs_end:} @@ -1306,7 +1297,7 @@ % These will be defined as needed in the appropriate modules, but % do a few now, just to get started.\footnote{This renaming gets expensive % in terms of csname usage, an alternative scheme would be to just use -% the \cs{tex\ldots:D} name in the cases where no good alternative exists.} +% the \cs[no-index]{tex_\ldots:D} name in the cases where no good alternative exists.} % % \begin{macro}[EXP] % { @@ -1418,7 +1409,8 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[EXP]{\token_to_meaning:c, \token_to_str:c, \cs_meaning:c} +% \begin{macro}[EXP, documented-as=\token_to_meaning:N] +% {\token_to_meaning:c, \token_to_str:c, \cs_meaning:c} % A small number of variants defined by hand. % Some of the necessary functions % (\cs{use_i:nn}, \cs{use_ii:nn}, and \cs{exp_args:NNc}) are not @@ -1497,18 +1489,18 @@ % \begin{macrocode} \tex_let:D \cs_set_nopar:Npn \tex_def:D \tex_let:D \cs_set_nopar:Npx \tex_edef:D -\etex_protected:D \cs_set_nopar:Npn \cs_set:Npn - { \tex_long:D \cs_set_nopar:Npn } -\etex_protected:D \cs_set_nopar:Npn \cs_set:Npx - { \tex_long:D \cs_set_nopar:Npx } -\etex_protected:D \cs_set_nopar:Npn \cs_set_protected_nopar:Npn - { \etex_protected:D \cs_set_nopar:Npn } -\etex_protected:D \cs_set_nopar:Npn \cs_set_protected_nopar:Npx - { \etex_protected:D \cs_set_nopar:Npx } -\cs_set_protected_nopar:Npn \cs_set_protected:Npn - { \etex_protected:D \tex_long:D \cs_set_nopar:Npn } -\cs_set_protected_nopar:Npn \cs_set_protected:Npx - { \etex_protected:D \tex_long:D \cs_set_nopar:Npx } +\etex_protected:D \tex_long:D \tex_def:D \cs_set:Npn + { \tex_long:D \tex_def:D } +\etex_protected:D \tex_long:D \tex_def:D \cs_set:Npx + { \tex_long:D \tex_edef:D } +\etex_protected:D \tex_long:D \tex_def:D \cs_set_protected_nopar:Npn + { \etex_protected:D \tex_def:D } +\etex_protected:D \tex_long:D \tex_def:D \cs_set_protected_nopar:Npx + { \etex_protected:D \tex_edef:D } +\etex_protected:D \tex_long:D \tex_def:D \cs_set_protected:Npn + { \etex_protected:D \tex_long:D \tex_def:D } +\etex_protected:D \tex_long:D \tex_def:D \cs_set_protected:Npx + { \etex_protected:D \tex_long:D \tex_edef:D } % \end{macrocode} % \end{macro} % @@ -1523,18 +1515,18 @@ % \begin{macrocode} \tex_let:D \cs_gset_nopar:Npn \tex_gdef:D \tex_let:D \cs_gset_nopar:Npx \tex_xdef:D -\cs_set_protected_nopar:Npn \cs_gset:Npn - { \tex_long:D \cs_gset_nopar:Npn } -\cs_set_protected_nopar:Npn \cs_gset:Npx - { \tex_long:D \cs_gset_nopar:Npx } -\cs_set_protected_nopar:Npn \cs_gset_protected_nopar:Npn - { \etex_protected:D \cs_gset_nopar:Npn } -\cs_set_protected_nopar:Npn \cs_gset_protected_nopar:Npx - { \etex_protected:D \cs_gset_nopar:Npx } -\cs_set_protected_nopar:Npn \cs_gset_protected:Npn - { \etex_protected:D \tex_long:D \cs_gset_nopar:Npn } -\cs_set_protected_nopar:Npn \cs_gset_protected:Npx - { \etex_protected:D \tex_long:D \cs_gset_nopar:Npx } +\cs_set_protected:Npn \cs_gset:Npn + { \tex_long:D \tex_gdef:D } +\cs_set_protected:Npn \cs_gset:Npx + { \tex_long:D \tex_xdef:D } +\cs_set_protected:Npn \cs_gset_protected_nopar:Npn + { \etex_protected:D \tex_gdef:D } +\cs_set_protected:Npn \cs_gset_protected_nopar:Npx + { \etex_protected:D \tex_xdef:D } +\cs_set_protected:Npn \cs_gset_protected:Npn + { \etex_protected:D \tex_long:D \tex_gdef:D } +\cs_set_protected:Npn \cs_gset_protected:Npx + { \etex_protected:D \tex_long:D \tex_xdef:D } % \end{macrocode} % \end{macro} % @@ -1703,9 +1695,9 @@ % at least two tokens: see how the logical tests are actually implemented % to see this. % \begin{macrocode} -\cs_set_nopar:Npn \prg_return_true: +\cs_set:Npn \prg_return_true: { \exp_after:wN \use_i:nn \exp:w } -\cs_set_nopar:Npn \prg_return_false: +\cs_set:Npn \prg_return_false: { \exp_after:wN \use_ii:nn \exp:w} % \end{macrocode} % An extended state space could be implemented by including a more @@ -1731,13 +1723,13 @@ % \Arg{code} to the auxiliary function responsible for defining all % conditionals. % \begin{macrocode} -\cs_set_protected_nopar:Npn \prg_set_conditional:Npnn +\cs_set_protected:Npn \prg_set_conditional:Npnn { \__prg_generate_conditional_parm:nnNpnn { set } { } } -\cs_set_protected_nopar:Npn \prg_new_conditional:Npnn +\cs_set_protected:Npn \prg_new_conditional:Npnn { \__prg_generate_conditional_parm:nnNpnn { new } { } } -\cs_set_protected_nopar:Npn \prg_set_protected_conditional:Npnn +\cs_set_protected:Npn \prg_set_protected_conditional:Npnn { \__prg_generate_conditional_parm:nnNpnn { set } { _protected } } -\cs_set_protected_nopar:Npn \prg_new_protected_conditional:Npnn +\cs_set_protected:Npn \prg_new_protected_conditional:Npnn { \__prg_generate_conditional_parm:nnNpnn { new } { _protected } } \cs_set_protected:Npn \__prg_generate_conditional_parm:nnNpnn #1#2#3#4# { @@ -1773,13 +1765,13 @@ % erroneous case where the function name contains no colon is captured % later. % \begin{macrocode} -\cs_set_protected_nopar:Npn \prg_set_conditional:Nnn +\cs_set_protected:Npn \prg_set_conditional:Nnn { \__prg_generate_conditional_count:nnNnn { set } { } } -\cs_set_protected_nopar:Npn \prg_new_conditional:Nnn +\cs_set_protected:Npn \prg_new_conditional:Nnn { \__prg_generate_conditional_count:nnNnn { new } { } } -\cs_set_protected_nopar:Npn \prg_set_protected_conditional:Nnn +\cs_set_protected:Npn \prg_set_protected_conditional:Nnn { \__prg_generate_conditional_count:nnNnn { set } { _protected } } -\cs_set_protected_nopar:Npn \prg_new_protected_conditional:Nnn +\cs_set_protected:Npn \prg_new_protected_conditional:Nnn { \__prg_generate_conditional_count:nnNnn { new } { _protected } } \cs_set_protected:Npn \__prg_generate_conditional_count:nnNnn #1#2#3 { @@ -1926,9 +1918,9 @@ % |,| \cs{q_recursion_stop} % to a first auxiliary. % \begin{macrocode} -\cs_set_protected_nopar:Npn \prg_set_eq_conditional:NNn +\cs_set_protected:Npn \prg_set_eq_conditional:NNn { \__prg_set_eq_conditional:NNNn \cs_set_eq:cc } -\cs_set_protected_nopar:Npn \prg_new_eq_conditional:NNn +\cs_set_protected:Npn \prg_new_eq_conditional:NNn { \__prg_set_eq_conditional:NNNn \cs_new_eq:cc } \cs_set_protected:Npn \__prg_set_eq_conditional:NNNn #1#2#3#4 { @@ -2084,7 +2076,7 @@ % In all three cases, \cs{cs_to_str:N} takes two expansion steps % to be fully expanded. % \begin{macrocode} -\cs_set_nopar:Npn \cs_to_str:N +\cs_set:Npn \cs_to_str:N { % \end{macrocode} % We implement the expansion scheme using \cs{tex_romannumeral:D} @@ -2101,6 +2093,10 @@ \cs_set:Npn \__cs_to_str:w #1 \__cs_to_str:N { - \__int_value:w \fi: \exp_after:wN \c_zero } % \end{macrocode} +% If speed is a concern we could use \tn{csstring} in \LuaTeX{}. For +% the empty csname that primitive gives an empty result while the +% current \cs{cs_to_str:N} gives incorrect results in all engines +% (this is impossible to fix without huge performance hit). % \end{macro} % \end{macro} % @@ -2250,15 +2246,15 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[EXP,TF,added=2011-10-10] +% \begin{macro}[EXP,noTF,added=2011-10-10] % {\cs_if_exist_use:N, \cs_if_exist_use:c} -% \begin{macro}[EXP,added=2011-10-10] -% {\cs_if_exist_use:N, \cs_if_exist_use:c} -% The \cs{cs_if_exist_use:\ldots{}} functions cannot be implemented +% The \cs[index=cs_if_exist_use:N]{cs_if_exist_use:\ldots{}} +% functions cannot be implemented % as conditionals because the true branch must leave both the control % sequence itself and the true code in the input stream. % For the \texttt{c} variants, we are careful not to put the control % sequence in the hash table if it does not exist. +% In \LuaTeX{} we could use the \tn{lastnamedcs} primitive. % \begin{macrocode} \cs_set:Npn \cs_if_exist_use:NTF #1#2 { \cs_if_exist:NTF #1 { #1 #2 } } @@ -2278,7 +2274,6 @@ { \cs_if_exist:cTF {#1} { \use:c {#1} } { } } % \end{macrocode} % \end{macro} -% \end{macro} % % \subsection{Defining and checking (new) functions} % @@ -2292,14 +2287,14 @@ % allow us to generate error messages. The definitions here are % only temporary, they will be redefined later on. % -% \begin{macro}{\iow_log:x, \iow_term:x} +% \begin{macro}[documented-as=\iow_log:n]{\iow_log:x, \iow_term:x} % We define a routine to write only to the log file. And a % similar one for writing to both the log file and the terminal. % These will be redefined later by \pkg{l3io}. % \begin{macrocode} -\cs_set_protected_nopar:Npn \iow_log:x +\cs_set_protected:Npn \iow_log:x { \tex_immediate:D \tex_write:D \c_minus_one } -\cs_set_protected_nopar:Npn \iow_term:x +\cs_set_protected:Npn \iow_term:x { \tex_immediate:D \tex_write:D \c_sixteen } % \end{macrocode} % \end{macro} @@ -2317,29 +2312,29 @@ % before that point. % \begin{macrocode} %<*initex> -\cs_set_protected_nopar:Npn \__chk_log:x { \use_none:n } -\cs_set_protected_nopar:Npn \__chk_suspend_log: { } -\cs_set_protected_nopar:Npn \__chk_resume_log: { } +\cs_set_protected:Npn \__chk_log:x { \use_none:n } +\cs_set_protected:Npn \__chk_suspend_log: { } +\cs_set_protected:Npn \__chk_resume_log: { } % %<*package> \tex_ifodd:D \l@expl@log@functions@bool - \cs_set_protected_nopar:Npn \__chk_log:x { \iow_log:x } - \cs_set_protected_nopar:Npn \__chk_suspend_log: + \cs_set_protected:Npn \__chk_log:x { \iow_log:x } + \cs_set_protected:Npn \__chk_suspend_log: { - \cs_set_protected_nopar:Npx \__chk_resume_log: + \cs_set_protected:Npx \__chk_resume_log: { - \cs_set_protected_nopar:Npn \__chk_resume_log: + \cs_set_protected:Npn \__chk_resume_log: { \exp_not:o { \__chk_resume_log: } } - \cs_set_protected_nopar:Npn \__chk_log:x + \cs_set_protected:Npn \__chk_log:x { \exp_not:o { \__chk_log:x } } } - \cs_set_protected_nopar:Npn \__chk_log:x { \use_none:n } + \cs_set_protected:Npn \__chk_log:x { \use_none:n } } - \cs_set_protected_nopar:Npn \__chk_resume_log: { } + \cs_set_protected:Npn \__chk_resume_log: { } \else: - \cs_set_protected_nopar:Npn \__chk_log:x { \use_none:n } - \cs_set_protected_nopar:Npn \__chk_suspend_log: { } - \cs_set_protected_nopar:Npn \__chk_resume_log: { } + \cs_set_protected:Npn \__chk_log:x { \use_none:n } + \cs_set_protected:Npn \__chk_suspend_log: { } + \cs_set_protected:Npn \__chk_resume_log: { } \fi: % % \end{macrocode} @@ -2376,7 +2371,7 @@ % \begin{macro}[rEXP]{\msg_line_context:} % Another one from \pkg{l3msg} which will be altered later. % \begin{macrocode} -\cs_set_nopar:Npn \msg_line_context: +\cs_set:Npn \msg_line_context: { on~line~ \tex_the:D \tex_inputlineno:D } % \end{macrocode} % \end{macro} @@ -2411,7 +2406,7 @@ } \fi: % -\cs_set_protected_nopar:Npn \__chk_if_free_cs:c +\cs_set_protected:Npn \__chk_if_free_cs:c { \exp_args:Nc \__chk_if_free_cs:N } % \end{macrocode} % \end{macro} @@ -2447,7 +2442,7 @@ { \token_to_str:N #1 } } } -\cs_set_protected_nopar:Npn \__chk_if_exist_cs:c +\cs_set_protected:Npn \__chk_if_exist_cs:c { \exp_args:Nc \__chk_if_exist_cs:N } % \end{macrocode} % \end{macro} @@ -2485,7 +2480,7 @@ % \end{macro} % \end{macro} % -% \begin{macro} +% \begin{macro}[documented-as=\cs_set_nopar:Npn] % { % \cs_set_nopar:cpn , \cs_set_nopar:cpx , % \cs_gset_nopar:cpn , \cs_gset_nopar:cpx , @@ -2513,7 +2508,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro} +% \begin{macro}[documented-as=\cs_set:Npn] % { % \cs_set:cpn , \cs_set:cpx , % \cs_gset:cpn , \cs_gset:cpx , @@ -2531,7 +2526,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro} +% \begin{macro}[documented-as=\cs_set_protected_nopar:Npn] % { % \cs_set_protected_nopar:cpn , \cs_set_protected_nopar:cpx , % \cs_gset_protected_nopar:cpn , \cs_gset_protected_nopar:cpx , @@ -2549,7 +2544,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro} +% \begin{macro}[documented-as=\cs_set_protected:Npn] % { % \cs_set_protected:cpn , \cs_set_protected:cpx , % \cs_gset_protected:cpn , \cs_gset_protected:cpx , @@ -2589,21 +2584,21 @@ % \enquote{runaway argument}. % \begin{macrocode} \cs_new_protected:Npn \cs_set_eq:NN #1 { \tex_let:D #1 =~ } -\cs_new_protected_nopar:Npn \cs_set_eq:cN { \exp_args:Nc \cs_set_eq:NN } -\cs_new_protected_nopar:Npn \cs_set_eq:Nc { \exp_args:NNc \cs_set_eq:NN } -\cs_new_protected_nopar:Npn \cs_set_eq:cc { \exp_args:Ncc \cs_set_eq:NN } -\cs_new_protected_nopar:Npn \cs_gset_eq:NN { \tex_global:D \cs_set_eq:NN } -\cs_new_protected_nopar:Npn \cs_gset_eq:Nc { \exp_args:NNc \cs_gset_eq:NN } -\cs_new_protected_nopar:Npn \cs_gset_eq:cN { \exp_args:Nc \cs_gset_eq:NN } -\cs_new_protected_nopar:Npn \cs_gset_eq:cc { \exp_args:Ncc \cs_gset_eq:NN } +\cs_new_protected:Npn \cs_set_eq:cN { \exp_args:Nc \cs_set_eq:NN } +\cs_new_protected:Npn \cs_set_eq:Nc { \exp_args:NNc \cs_set_eq:NN } +\cs_new_protected:Npn \cs_set_eq:cc { \exp_args:Ncc \cs_set_eq:NN } +\cs_new_protected:Npn \cs_gset_eq:NN { \tex_global:D \cs_set_eq:NN } +\cs_new_protected:Npn \cs_gset_eq:Nc { \exp_args:NNc \cs_gset_eq:NN } +\cs_new_protected:Npn \cs_gset_eq:cN { \exp_args:Nc \cs_gset_eq:NN } +\cs_new_protected:Npn \cs_gset_eq:cc { \exp_args:Ncc \cs_gset_eq:NN } \cs_new_protected:Npn \cs_new_eq:NN #1 { \__chk_if_free_cs:N #1 \tex_global:D \cs_set_eq:NN #1 } -\cs_new_protected_nopar:Npn \cs_new_eq:cN { \exp_args:Nc \cs_new_eq:NN } -\cs_new_protected_nopar:Npn \cs_new_eq:Nc { \exp_args:NNc \cs_new_eq:NN } -\cs_new_protected_nopar:Npn \cs_new_eq:cc { \exp_args:Ncc \cs_new_eq:NN } +\cs_new_protected:Npn \cs_new_eq:cN { \exp_args:Nc \cs_new_eq:NN } +\cs_new_protected:Npn \cs_new_eq:Nc { \exp_args:NNc \cs_new_eq:NN } +\cs_new_protected:Npn \cs_new_eq:cc { \exp_args:Ncc \cs_new_eq:NN } % \end{macrocode} % \end{macro} % @@ -2700,7 +2695,7 @@ \c_minus_one \fi: } -\cs_new_nopar:Npn \__cs_count_signature:c +\cs_new:Npn \__cs_count_signature:c { \exp_args:Nc \__cs_count_signature:N } % \end{macrocode} % \end{macro} @@ -2737,9 +2732,9 @@ % A variant form we need right away, plus one which is used elsewhere but % which is most logically created here. % \begin{macrocode} -\cs_new_protected_nopar:Npn \cs_generate_from_arg_count:cNnn +\cs_new_protected:Npn \cs_generate_from_arg_count:cNnn { \exp_args:Nc \cs_generate_from_arg_count:NNnn } -\cs_new_protected_nopar:Npn \cs_generate_from_arg_count:Ncnn +\cs_new_protected:Npn \cs_generate_from_arg_count:Ncnn { \exp_args:NNc \cs_generate_from_arg_count:NNnn } % \end{macrocode} % \end{macro} @@ -2781,7 +2776,7 @@ % \begin{macrocode} \cs_set:Npn \__cs_tmp:w #1#2#3 { - \cs_new_protected_nopar:cpx { cs_ #1 : #2 } + \cs_new_protected:cpx { cs_ #1 : #2 } { \exp_not:N \__cs_generate_from_signature:NNn \exp_after:wN \exp_not:N \cs:w cs_ #1 : #3 \cs_end: @@ -2796,6 +2791,12 @@ { \bool_if:NTF #3 { + \str_if_eq_x:nnF { } + { \tl_map_function:nN {#2} \__cs_generate_from_signature:n } + { + \__msg_kernel_error:nnx { kernel } { non-base-function } + { \token_to_str:N #5 } + } \cs_generate_from_arg_count:NNnn #5 #4 { \tl_count:n {#2} } {#6} } @@ -2804,6 +2805,11 @@ { \token_to_str:N #5 } } } +\cs_new:Npn \__cs_generate_from_signature:n #1 + { + \if:w n #1 \else: \if:w N #1 \else: + \if:w T #1 \else: \if:w F #1 \else: #1 \fi: \fi: \fi: \fi: + } % \end{macrocode} % Then we define the 24 variants beginning with |N|. % \begin{macrocode} @@ -2834,7 +2840,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro} +% \begin{macro}[documented-as=\cs_set:Nn] % { % \cs_set:cn , \cs_set:cx , % \cs_set_nopar:cn , \cs_set_nopar:cx , @@ -2853,7 +2859,7 @@ % \begin{macrocode} \cs_set:Npn \__cs_tmp:w #1#2 { - \cs_new_protected_nopar:cpx { cs_ #1 : c #2 } + \cs_new_protected:cpx { cs_ #1 : c #2 } { \exp_not:N \exp_args:Nc \exp_after:wN \exp_not:N \cs:w cs_ #1 : N #2 \cs_end: @@ -2897,18 +2903,18 @@ \if_meaning:w #1#2 \prg_return_true: \else: \prg_return_false: \fi: } -\cs_new_nopar:Npn \cs_if_eq_p:cN { \exp_args:Nc \cs_if_eq_p:NN } -\cs_new_nopar:Npn \cs_if_eq:cNTF { \exp_args:Nc \cs_if_eq:NNTF } -\cs_new_nopar:Npn \cs_if_eq:cNT { \exp_args:Nc \cs_if_eq:NNT } -\cs_new_nopar:Npn \cs_if_eq:cNF { \exp_args:Nc \cs_if_eq:NNF } -\cs_new_nopar:Npn \cs_if_eq_p:Nc { \exp_args:NNc \cs_if_eq_p:NN } -\cs_new_nopar:Npn \cs_if_eq:NcTF { \exp_args:NNc \cs_if_eq:NNTF } -\cs_new_nopar:Npn \cs_if_eq:NcT { \exp_args:NNc \cs_if_eq:NNT } -\cs_new_nopar:Npn \cs_if_eq:NcF { \exp_args:NNc \cs_if_eq:NNF } -\cs_new_nopar:Npn \cs_if_eq_p:cc { \exp_args:Ncc \cs_if_eq_p:NN } -\cs_new_nopar:Npn \cs_if_eq:ccTF { \exp_args:Ncc \cs_if_eq:NNTF } -\cs_new_nopar:Npn \cs_if_eq:ccT { \exp_args:Ncc \cs_if_eq:NNT } -\cs_new_nopar:Npn \cs_if_eq:ccF { \exp_args:Ncc \cs_if_eq:NNF } +\cs_new:Npn \cs_if_eq_p:cN { \exp_args:Nc \cs_if_eq_p:NN } +\cs_new:Npn \cs_if_eq:cNTF { \exp_args:Nc \cs_if_eq:NNTF } +\cs_new:Npn \cs_if_eq:cNT { \exp_args:Nc \cs_if_eq:NNT } +\cs_new:Npn \cs_if_eq:cNF { \exp_args:Nc \cs_if_eq:NNF } +\cs_new:Npn \cs_if_eq_p:Nc { \exp_args:NNc \cs_if_eq_p:NN } +\cs_new:Npn \cs_if_eq:NcTF { \exp_args:NNc \cs_if_eq:NNTF } +\cs_new:Npn \cs_if_eq:NcT { \exp_args:NNc \cs_if_eq:NNT } +\cs_new:Npn \cs_if_eq:NcF { \exp_args:NNc \cs_if_eq:NNF } +\cs_new:Npn \cs_if_eq_p:cc { \exp_args:Ncc \cs_if_eq_p:NN } +\cs_new:Npn \cs_if_eq:ccTF { \exp_args:Ncc \cs_if_eq:NNTF } +\cs_new:Npn \cs_if_eq:ccT { \exp_args:Ncc \cs_if_eq:NNT } +\cs_new:Npn \cs_if_eq:ccF { \exp_args:Ncc \cs_if_eq:NNF } % \end{macrocode} % \end{macro} % @@ -2926,7 +2932,7 @@ \__msg_show_variable:NNNnn #1 \cs_if_exist:NTF ? { } { > ~ \token_to_str:N #1 = \tex_the:D #1 } } -\cs_new_protected_nopar:Npn \__kernel_register_show:c +\cs_new_protected:Npn \__kernel_register_show:c { \exp_args:Nc \__kernel_register_show:N } % \end{macrocode} % \end{macro} @@ -2942,7 +2948,7 @@ % \begin{macrocode} \cs_new_protected:Npn \cs_show:N #1 { \__msg_show_wrap:n { > ~ \token_to_str:N #1 = \cs_meaning:N #1 } } -\cs_new_protected_nopar:Npn \cs_show:c +\cs_new_protected:Npn \cs_show:c { \group_begin: \exp_args:NNc \group_end: \cs_show:N } % \end{macrocode} % \end{macro} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx b/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx index dafec8604da..903202b7da2 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx @@ -145,7 +145,7 @@ % \end{macro} % \end{macro} % \end{macro} -\GetIdInfo$Id: l3bootstrap.dtx 6412 2016-02-12 21:45:29Z joseph $ +\GetIdInfo$Id: l3bootstrap.dtx 6596 2016-06-13 21:29:58Z joseph $ {L3 Bootstrap code}% % %<*driver> @@ -666,7 +666,7 @@ { \bool_if:NF \l__kernel_expl_bool { - \cs_set_protected_nopar:Npx \ExplSyntaxOff + \cs_set_protected:Npx \ExplSyntaxOff { \char_set_catcode:nn { 9 } { \char_value_catcode:n { 9 } } \char_set_catcode:nn { 32 } { \char_value_catcode:n { 32 } } @@ -680,7 +680,7 @@ \tex_endlinechar:D = \tex_the:D \tex_endlinechar:D \scan_stop: \bool_set_false:N \l__kernel_expl_bool - \cs_set_protected_nopar:Npn \ExplSyntaxOff { } + \cs_set_protected:Npn \ExplSyntaxOff { } } } \char_set_catcode_ignore:n { 9 } % tab diff --git a/Master/texmf-dist/source/latex/l3kernel/l3box.dtx b/Master/texmf-dist/source/latex/l3kernel/l3box.dtx index 6be9b6f8d57..8bca5327b64 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3box.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3box.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -%% File: l3box.dtx Copyright (C) 2005-2015 The LaTeX3 Project +%% File: l3box.dtx Copyright (C) 2005-2016 The LaTeX3 Project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -37,7 +37,7 @@ \documentclass[full]{l3doc} % %<*driver|package> -\GetIdInfo$Id: l3box.dtx 5822 2015-08-09 16:41:04Z joseph $ +\GetIdInfo$Id: l3box.dtx 6685 2016-08-19 16:26:52Z bruno $ {L3 Experimental boxes} % %<*driver> @@ -97,7 +97,8 @@ % \cs{box_clear_new:N} \meta{box} % \end{syntax} % Ensures that the \meta{box} exists globally by applying -% \cs{box_new:N} if necessary, then applies \cs{box_(g)clear:N} to leave +% \cs{box_new:N} if necessary, then applies +% \cs[index=box_clear:N]{box_(g)clear:N} to leave % the \meta{box} empty. % \end{function} % @@ -932,7 +933,7 @@ \cs_new_protected:Npn \box_show:N #1 { \box_show:Nnn #1 \c_max_int \c_max_int } \cs_generate_variant:Nn \box_show:N { c } -\cs_new_protected_nopar:Npn \box_show:Nnn +\cs_new_protected:Npn \box_show:Nnn { \@@_show:NNnn \c_one } \cs_generate_variant:Nn \box_show:Nnn { c } % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx b/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx index e98af99edcb..d3ef2708afc 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx @@ -38,7 +38,7 @@ \documentclass[full]{l3doc} % %<*driver|package> -\GetIdInfo$Id: l3candidates.dtx 6484 2016-05-13 19:08:30Z joseph $ +\GetIdInfo$Id: l3candidates.dtx 6688 2016-08-19 19:21:48Z bruno $ {L3 Experimental additions to l3kernel} % %<*driver> @@ -405,7 +405,7 @@ % \begin{syntax} % \cs{ior_map_break:} % \end{syntax} -% Used to terminate a \cs{ior_map_\ldots} function before all +% Used to terminate a \cs[no-index]{ior_map_\ldots} function before all % lines from the \meta{stream} have been processed. This will % normally take place within a conditional statement, for example % \begin{verbatim} @@ -418,7 +418,7 @@ % } % } % \end{verbatim} -% Use outside of a \cs{ior_map_\ldots} scenario will lead to low +% Use outside of a \cs[no-index]{ior_map_\ldots} scenario will lead to low % level \TeX{} errors. % \begin{texnote} % When the mapping is broken, additional tokens may be inserted by the @@ -432,7 +432,7 @@ % \begin{syntax} % \cs{ior_map_break:n} \Arg{tokens} % \end{syntax} -% Used to terminate a \cs{ior_map_\ldots} function before all +% Used to terminate a \cs[no-index]{ior_map_\ldots} function before all % lines in the \meta{stream} have been processed, inserting % the \meta{tokens} after the mapping has ended. This will % normally take place within a conditional statement, for example @@ -446,7 +446,7 @@ % } % } % \end{verbatim} -% Use outside of a \cs{ior_map_\ldots} scenario will lead to low +% Use outside of a \cs[no-index]{ior_map_\ldots} scenario will lead to low % level \TeX{} errors. % \begin{texnote} % When the mapping is broken, additional tokens may be inserted by the @@ -640,6 +640,14 @@ % % \section{Additions to \pkg{l3prop}} % +% \begin{function}[EXP]{\prop_count:N, \prop_count:c} +% \begin{syntax} +% \cs{prop_count:N} \meta{property list} +% \end{syntax} +% Leaves the number of key--value pairs in the \meta{property list} in +% the input stream as an \meta{integer denotation}. +% \end{function} +% % \begin{function}[rEXP] % {\prop_map_tokens:Nn, \prop_map_tokens:cn} % \begin{syntax} @@ -830,7 +838,7 @@ % giving an \meta{integer denotation}. % \end{function} % -% \begin{function}[EXP, added = 2014-06-30, updated = 2016-01-12]^^A +% \begin{function}[EXP, added = 2014-06-30, updated = 2016-01-12] % { % \tl_lower_case:n, \tl_upper_case:n, \tl_mixed_case:n, % \tl_lower_case:nn, \tl_upper_case:nn, \tl_mixed_case:nn @@ -949,7 +957,8 @@ % case. However, the process is more complex than this as there are some % situations where a single lower case character maps to a special form, for % example \texttt{ij} in Dutch which becomes \texttt{IJ}. As such, -% \cs{tl_mixed_case:n(n)} implement a more sophisticated mapping which accounts +% \cs[index=tl_mixed_case:n]{tl_mixed_case:n(n)} +% implement a more sophisticated mapping which accounts % for this and for modifying accents on the first letter. Spaces at the start % of the \meta{tokens} are ignored when finding the first \enquote{letter} for % conversion. @@ -1023,7 +1032,7 @@ % to add these to the kernel where they are well-documented % (\emph{e.g.}~in Unicode Consortium or relevant government publications). % -% \begin{function}[added = 2014-06-25]^^A +% \begin{function}[added = 2014-06-25] % { % \tl_set_from_file:Nnn, \tl_set_from_file:cnn, % \tl_gset_from_file:Nnn, \tl_gset_from_file:cnn @@ -1036,7 +1045,7 @@ % argument. % \end{function} % -% \begin{function}[added = 2014-06-25]^^A +% \begin{function}[added = 2014-06-25] % { % \tl_set_from_file_x:Nnn, \tl_set_from_file_x:cnn, % \tl_gset_from_file_x:Nnn, \tl_gset_from_file_x:cnn @@ -1111,9 +1120,9 @@ % the csname should be turned to a control sequence within a group % (see \cs{cs_show:c}). % \begin{macrocode} -\cs_new_protected_nopar:Npn \cs_log:N +\cs_new_protected:Npn \cs_log:N { \__msg_log_next: \cs_show:N } -\cs_new_protected_nopar:Npn \cs_log:c +\cs_new_protected:Npn \cs_log:c { \__msg_log_next: \cs_show:c } % \end{macrocode} % \end{macro} @@ -1121,7 +1130,7 @@ % \begin{macro}[int]{\__kernel_register_log:N, \__kernel_register_log:c} % Redirect the output of \cs{__kernel_register_show:N} to the log. % \begin{macrocode} -\cs_new_protected_nopar:Npn \__kernel_register_log:N +\cs_new_protected:Npn \__kernel_register_log:N { \__msg_log_next: \__kernel_register_show:N } \cs_generate_variant:Nn \__kernel_register_log:N { c } % \end{macrocode} @@ -1782,9 +1791,9 @@ % \begin{macro}{\clist_log:N, \clist_log:c, \clist_log:n} % Redirect output of \cs{clist_show:N} to the log. % \begin{macrocode} -\cs_new_protected_nopar:Npn \clist_log:N +\cs_new_protected:Npn \clist_log:N { \__msg_log_next: \clist_show:N } -\cs_new_protected_nopar:Npn \clist_log:n +\cs_new_protected:Npn \clist_log:n { \__msg_log_next: \clist_show:n } \cs_generate_variant:Nn \clist_log:N { c } % \end{macrocode} @@ -2050,7 +2059,7 @@ % that for the corners. However, there is only one value needed here and % a fixed input property list, so things are a bit clearer. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_find_bounding_shift: +\cs_new_protected:Npn \@@_find_bounding_shift: { \dim_set:Nn \l_@@_bounding_shift_dim { \c_max_dim } \prop_map_inline:Nn \l_@@_bounding_prop @@ -2255,7 +2264,7 @@ % \begin{macro}{\coffin_log_structure:N, \coffin_log_structure:c} % Redirect output of \cs{coffin_show_structure:N} to the log. % \begin{macrocode} -\cs_new_protected_nopar:Npn \coffin_log_structure:N +\cs_new_protected:Npn \coffin_log_structure:N { \__msg_log_next: \coffin_show_structure:N } \cs_generate_variant:Nn \coffin_log_structure:N { c } % \end{macrocode} @@ -2308,9 +2317,9 @@ % Usual map breaking functions. Those are not yet in \pkg{l3kernel} % proper since the mapping below is the first of its kind. % \begin{macrocode} -\cs_new_nopar:Npn \ior_map_break: +\cs_new:Npn \ior_map_break: { \__prg_map_break:Nn \ior_map_break: { } } -\cs_new_nopar:Npn \ior_map_break:n +\cs_new:Npn \ior_map_break:n { \__prg_map_break:Nn \ior_map_break: } % \end{macrocode} % \end{macro} @@ -2326,11 +2335,11 @@ % This mapping cannot be nested as the stream has only one \enquote{current % line}. % \begin{macrocode} -\cs_new_protected_nopar:Npn \ior_map_inline:Nn +\cs_new_protected:Npn \ior_map_inline:Nn { \@@_map_inline:NNn \ior_get:NN } -\cs_new_protected_nopar:Npn \ior_str_map_inline:Nn +\cs_new_protected:Npn \ior_str_map_inline:Nn { \@@_map_inline:NNn \ior_get_str:NN } -\cs_new_protected_nopar:Npn \@@_map_inline:NNn +\cs_new_protected:Npn \@@_map_inline:NNn { \int_gincr:N \g__prg_map_int \exp_args:Nc \@@_map_inline:NNNn @@ -2363,7 +2372,7 @@ % \begin{macro}{\ior_log_streams:} % Redirect output of \cs{ior_list_streams:} to the log. % \begin{macrocode} -\cs_new_protected_nopar:Npn \ior_log_streams: +\cs_new_protected:Npn \ior_log_streams: { \__msg_log_next: \ior_list_streams: } % \end{macrocode} % \end{macro} @@ -2375,7 +2384,7 @@ % \begin{macro}{\iow_log_streams:} % Redirect output of \cs{iow_list_streams:} to the log. % \begin{macrocode} -\cs_new_protected_nopar:Npn \iow_log_streams: +\cs_new_protected:Npn \iow_log_streams: { \__msg_log_next: \iow_list_streams: } % \end{macrocode} % \end{macro} @@ -2389,9 +2398,9 @@ % \begin{macro}{\fp_log:N, \fp_log:c, \fp_log:n} % Redirect output of \cs{fp_show:N} to the log. % \begin{macrocode} -\cs_new_protected_nopar:Npn \fp_log:N +\cs_new_protected:Npn \fp_log:N { \__msg_log_next: \fp_show:N } -\cs_new_protected_nopar:Npn \fp_log:n +\cs_new_protected:Npn \fp_log:n { \__msg_log_next: \fp_show:n } \cs_generate_variant:Nn \fp_log:N { c } % \end{macrocode} @@ -2405,7 +2414,7 @@ % involving \tn{currentgrouplevel} and \tn{currentgrouptype}. See % \cs{int_show:N} for details. % \begin{macrocode} -\cs_new_protected_nopar:Npn \int_log:N +\cs_new_protected:Npn \int_log:N { \__msg_log_next: \int_show:N } \cs_generate_variant:Nn \int_log:N { c } % \end{macrocode} @@ -2414,7 +2423,7 @@ % \begin{macro}{\int_log:n} % Redirect output of \cs{int_show:n} to the log. % \begin{macrocode} -\cs_new_protected_nopar:Npn \int_log:n +\cs_new_protected:Npn \int_log:n { \__msg_log_next: \int_show:n } % \end{macrocode} % \end{macro} @@ -2428,7 +2437,7 @@ % \begin{macro}{\keys_log:nn} % Redirect output of \cs{keys_show:nn} to the log. % \begin{macrocode} -\cs_new_protected_nopar:Npn \keys_log:nn +\cs_new_protected:Npn \keys_log:nn { \__msg_log_next: \keys_show:nn } % \end{macrocode} % \end{macro} @@ -2556,9 +2565,9 @@ % \begin{macro}{\bool_log:N, \bool_log:c, \bool_log:n} % Redirect output of \cs{bool_show:N} to the log. % \begin{macrocode} -\cs_new_protected_nopar:Npn \bool_log:N +\cs_new_protected:Npn \bool_log:N { \__msg_log_next: \bool_show:N } -\cs_new_protected_nopar:Npn \bool_log:n +\cs_new_protected:Npn \bool_log:n { \__msg_log_next: \bool_show:n } \cs_generate_variant:Nn \bool_log:N { c } % \end{macrocode} @@ -2570,6 +2579,27 @@ %<@@=prop> % \end{macrocode} % +% \begin{macro}[EXP]{\prop_count:N, \prop_count:c} +% \begin{macro}[aux,EXP]{\@@_count:nn} +% Counting the key--value pairs in a property list is done using the +% same approach as for other count functions: turn each entry into a +% \texttt{+1} then use integer evaluation to actually do the +% mathematics. +% \begin{macrocode} +\cs_new:Npn \prop_count:N #1 + { + \int_eval:n + { + \c_zero + \prop_map_function:NN #1 \@@_count:nn + } + } +\cs_new:Npn \@@_count:nn #1#2 { + \c_one } +\cs_generate_variant:Nn \prop_count:N { c } +% \end{macrocode} +% \end{macro} +% \end{macro} +% % \begin{macro}[rEXP]{\prop_map_tokens:Nn, \prop_map_tokens:cn} % \begin{macro}[aux]{\@@_map_tokens:nwwn} % The mapping is very similar to \cs{prop_map_function:NN}. It grabs @@ -2602,7 +2632,7 @@ % \begin{macro}{\prop_log:N, \prop_log:c} % Redirect output of \cs{prop_show:N} to the log. % \begin{macrocode} -\cs_new_protected_nopar:Npn \prop_log:N +\cs_new_protected:Npn \prop_log:N { \__msg_log_next: \prop_show:N } \cs_generate_variant:Nn \prop_log:N { c } % \end{macrocode} @@ -2672,9 +2702,9 @@ % \cs{@@_item:n} without expansion in the input stream, % hence in the \texttt{x}-expanding assignment. % \begin{macrocode} -\cs_new_protected_nopar:Npn \seq_set_filter:NNn +\cs_new_protected:Npn \seq_set_filter:NNn { \@@_set_filter:NNNn \tl_set:Nx } -\cs_new_protected_nopar:Npn \seq_gset_filter:NNn +\cs_new_protected:Npn \seq_gset_filter:NNn { \@@_set_filter:NNNn \tl_gset:Nx } \cs_new_protected:Npn \@@_set_filter:NNNn #1#2#3#4 { @@ -2692,9 +2722,9 @@ % merge the two within a single function, but it would have weird % semantics. % \begin{macrocode} -\cs_new_protected_nopar:Npn \seq_set_map:NNn +\cs_new_protected:Npn \seq_set_map:NNn { \@@_set_map:NNNn \tl_set:Nx } -\cs_new_protected_nopar:Npn \seq_gset_map:NNn +\cs_new_protected:Npn \seq_gset_map:NNn { \@@_set_map:NNNn \tl_gset:Nx } \cs_new_protected:Npn \@@_set_map:NNNn #1#2#3#4 { @@ -2709,7 +2739,7 @@ % \begin{macro}{\seq_log:N, \seq_log:c} % Redirect output of \cs{seq_show:N} to the log. % \begin{macrocode} -\cs_new_protected_nopar:Npn \seq_log:N +\cs_new_protected:Npn \seq_log:N { \__msg_log_next: \seq_show:N } \cs_generate_variant:Nn \seq_log:N { c } % \end{macrocode} @@ -2750,7 +2780,7 @@ % \begin{macrocode} \cs_new_eq:NN \dim_log:N \__kernel_register_log:N \cs_new_eq:NN \dim_log:c \__kernel_register_log:c -\cs_new_protected_nopar:Npn \dim_log:n +\cs_new_protected:Npn \dim_log:n { \__msg_log_next: \dim_show:n } % \end{macrocode} % \end{macro} @@ -2760,7 +2790,7 @@ % \begin{macrocode} \cs_new_eq:NN \skip_log:N \__kernel_register_log:N \cs_new_eq:NN \skip_log:c \__kernel_register_log:c -\cs_new_protected_nopar:Npn \skip_log:n +\cs_new_protected:Npn \skip_log:n { \__msg_log_next: \skip_show:n } % \end{macrocode} % \end{macro} @@ -2770,7 +2800,7 @@ % \begin{macrocode} \cs_new_eq:NN \muskip_log:N \__kernel_register_log:N \cs_new_eq:NN \muskip_log:c \__kernel_register_log:c -\cs_new_protected_nopar:Npn \muskip_log:n +\cs_new_protected:Npn \muskip_log:n { \__msg_log_next: \muskip_show:n } % \end{macrocode} % \end{macro} @@ -2872,7 +2902,7 @@ % \end{macro} % \end{macro} % -% \begin{macro}^^A +% \begin{macro} % { % \tl_set_from_file:Nnn, \tl_set_from_file:cnn, % \tl_gset_from_file:Nnn, \tl_gset_from_file:cnn @@ -2885,9 +2915,9 @@ % This plus \cs{exp_not:N} allows the primitive to be used to carry out % a set operation. % \begin{macrocode} -\cs_new_protected_nopar:Npn \tl_set_from_file:Nnn +\cs_new_protected:Npn \tl_set_from_file:Nnn { \@@_set_from_file:NNnn \tl_set:Nn } -\cs_new_protected_nopar:Npn \tl_gset_from_file:Nnn +\cs_new_protected:Npn \tl_gset_from_file:Nnn { \@@_set_from_file:NNnn \tl_gset:Nn } \cs_generate_variant:Nn \tl_set_from_file:Nnn { c } \cs_generate_variant:Nn \tl_gset_from_file:Nnn { c } @@ -2915,7 +2945,7 @@ % \end{macro} % \end{macro} % -% \begin{macro}^^A +% \begin{macro} % { % \tl_set_from_file_x:Nnn, \tl_set_from_file_x:cnn, % \tl_gset_from_file_x:Nnn, \tl_gset_from_file_x:cnn @@ -2927,9 +2957,9 @@ % Once the business is done using some scratch space, the tokens can be % transferred to the real target. % \begin{macrocode} -\cs_new_protected_nopar:Npn \tl_set_from_file_x:Nnn +\cs_new_protected:Npn \tl_set_from_file_x:Nnn { \@@_set_from_file_x:NNnn \tl_set:Nn } -\cs_new_protected_nopar:Npn \tl_gset_from_file_x:Nnn +\cs_new_protected:Npn \tl_gset_from_file_x:Nnn { \@@_set_from_file_x:NNnn \tl_gset:Nn } \cs_generate_variant:Nn \tl_set_from_file_x:Nnn { c } \cs_generate_variant:Nn \tl_gset_from_file_x:Nnn { c } @@ -2957,7 +2987,8 @@ % appropriate data extracted from the Unicode documentation (either manually % or automatically). % -% \begin{macro}[EXP]{\tl_if_head_eq_catcode:oNTF} +% \begin{macro}[EXP, documented-as=\tl_if_head_eq_catcode:nNTF] +% {\tl_if_head_eq_catcode:oNTF} % Extra variants. % \begin{macrocode} \cs_generate_variant:Nn \tl_if_head_eq_catcode:nNTF { o } @@ -2971,12 +3002,12 @@ % done without an internal, but this way the logic is slightly clearer as % everything essentially follows the same path. % \begin{macrocode} -\cs_new_nopar:Npn \tl_lower_case:n { \@@_change_case:nnn { lower } { } } -\cs_new_nopar:Npn \tl_upper_case:n { \@@_change_case:nnn { upper } { } } -\cs_new_nopar:Npn \tl_mixed_case:n { \@@_mixed_case:nn { } } -\cs_new_nopar:Npn \tl_lower_case:nn { \@@_change_case:nnn { lower } } -\cs_new_nopar:Npn \tl_upper_case:nn { \@@_change_case:nnn { upper } } -\cs_new_nopar:Npn \tl_mixed_case:nn { \@@_mixed_case:nn } +\cs_new:Npn \tl_lower_case:n { \@@_change_case:nnn { lower } { } } +\cs_new:Npn \tl_upper_case:n { \@@_change_case:nnn { upper } { } } +\cs_new:Npn \tl_mixed_case:n { \@@_mixed_case:nn { } } +\cs_new:Npn \tl_lower_case:nn { \@@_change_case:nnn { lower } } +\cs_new:Npn \tl_upper_case:nn { \@@_change_case:nnn { upper } } +\cs_new:Npn \tl_mixed_case:nn { \@@_mixed_case:nn } % \end{macrocode} % \end{macro} % \end{macro} @@ -3018,6 +3049,7 @@ % \begin{macro}[aux, EXP]{\@@_change_case_cs:N} % \begin{macro}[aux, EXP]{\@@_change_case_cs:NN} % \begin{macro}[aux, EXP]{\@@_change_case_cs:NNn} +% \begin{macro}[aux, EXP]{\@@_change_case_protect:wNN} % \begin{macro}[aux, EXP]{\@@_change_case_if_expandable:NTF} % \begin{macro}[aux, EXP]{\@@_change_case_cs_expand:Nnw} % \begin{macro}[aux, EXP]{\@@_change_case_cs_expand:NN} @@ -3339,10 +3371,15 @@ % on the list which indicate that case changing should be skipped. That's % done using a loop as for the other special cases. If a hit is found then % the argument is grabbed: that comes \emph{after} the loop function which -% is therefore rearranged. +% is therefore rearranged. In a \LaTeXe{} context, \tn{protect} needs +% to be treated specially, to prevent expansion of the next token but +% output it without braces. % \begin{macrocode} \cs_new:Npn \@@_change_case_cs:N #1 { +%<*package> + \str_if_eq:nnTF {#1} { \protect } { \@@_change_case_protect:wNN } +% \exp_after:wN \@@_change_case_cs:NN \exp_after:wN #1 \l_tl_case_change_exclude_tl \q_recursion_tail \q_recursion_stop @@ -3366,6 +3403,10 @@ \@@_change_case_output:nwn { #1 {#3} } #2 } +%<*package> +\cs_new:Npn \@@_change_case_protect:wNN #1 \q_recursion_stop #2 #3 + { \@@_change_case_output:nwn { \protect #3 } #2 } +% % \end{macrocode} % When a control sequence is not on the exclude list the other test if % to see if it is expandable. Once again, if there is a hit then the loop @@ -3430,6 +3471,7 @@ % \end{macro} % \end{macro} % \end{macro} +% \end{macro} % % \begin{macro}[aux, EXP]{\@@_change_case_lower_sigma:Nnw} % \begin{macro}[aux, EXP]{\@@_change_case_lower_sigma:w} @@ -4386,7 +4428,7 @@ % \begin{macro}{\tl_log:N, \tl_log:c} % Redirect output of \cs{tl_show:N} to the log. % \begin{macrocode} -\cs_new_protected_nopar:Npn \tl_log:N +\cs_new_protected:Npn \tl_log:N { \__msg_log_next: \tl_show:N } \cs_generate_variant:Nn \tl_log:N { c } % \end{macrocode} @@ -4395,7 +4437,7 @@ % \begin{macro}{\tl_log:n} % Redirect output of \cs{tl_show:n} to the log. % \begin{macrocode} -\cs_new_protected_nopar:Npn \tl_log:n +\cs_new_protected:Npn \tl_log:n { \__msg_log_next: \tl_show:n } % \end{macrocode} % \end{macro} @@ -4435,7 +4477,7 @@ \group_begin: \cs_set_protected:Npn \@@_tmp:w #1 \q_stop { - \cs_new_protected_nopar:Npn \@@_execute_branches_N_type: + \cs_new_protected:Npn \@@_execute_branches_N_type: { \if_int_odd:w \if_catcode:w \exp_not:N \l_peek_token { \c_two \fi: @@ -4464,11 +4506,11 @@ { \@@_true:w } { \tl_if_empty:nTF {#2} { \@@_true:w } { \@@_false:w } } } -\cs_new_protected_nopar:Npn \peek_N_type:TF +\cs_new_protected:Npn \peek_N_type:TF { \@@_token_generic:NNTF \@@_execute_branches_N_type: \scan_stop: } -\cs_new_protected_nopar:Npn \peek_N_type:T +\cs_new_protected:Npn \peek_N_type:T { \@@_token_generic:NNT \@@_execute_branches_N_type: \scan_stop: } -\cs_new_protected_nopar:Npn \peek_N_type:F +\cs_new_protected:Npn \peek_N_type:F { \@@_token_generic:NNF \@@_execute_branches_N_type: \scan_stop: } % \end{macrocode} % \end{macro} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx b/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx index 51ff7dc3082..b9987de422b 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx @@ -2,7 +2,7 @@ % %% File: l3clist.dtx Copyright (C) 2004-2011 Frank Mittelbach, %% The LaTeX3 project -%% (C) 2012-2015 The LaTeX3 Project +%% (C) 2012-2016 The LaTeX3 Project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -39,7 +39,7 @@ \documentclass[full]{l3doc} % %<*driver|package> -\GetIdInfo$Id: l3clist.dtx 5901 2015-09-02 05:59:23Z joseph $ +\GetIdInfo$Id: l3clist.dtx 6685 2016-08-19 16:26:52Z bruno $ {L3 Comma separated lists} % %<*driver> @@ -135,7 +135,8 @@ % \cs{clist_clear_new:N} \meta{comma list} % \end{syntax} % Ensures that the \meta{comma list} exists globally by applying -% \cs{clist_new:N} if necessary, then applies \cs{clist_(g)clear:N} to leave +% \cs{clist_new:N} if necessary, then applies +% \cs[index=clist_clear:N]{clist_(g)clear:N} to leave % the list empty. % \end{function} % @@ -877,9 +878,9 @@ % there needs to be the correct addition of a comma to the output. So % a little work to do. % \begin{macrocode} -\cs_new_protected_nopar:Npn \clist_concat:NNN +\cs_new_protected:Npn \clist_concat:NNN { \@@_concat:NNNN \tl_set:Nx } -\cs_new_protected_nopar:Npn \clist_gconcat:NNN +\cs_new_protected:Npn \clist_gconcat:NNN { \@@_concat:NNNN \tl_gset:Nx } \cs_new_protected:Npn \@@_concat:NNNN #1#2#3#4 { @@ -1014,9 +1015,9 @@ % Comma lists cannot hold empty values: there are therefore a couple % of sanity checks to avoid accumulating commas. % \begin{macrocode} -\cs_new_protected_nopar:Npn \clist_put_left:Nn +\cs_new_protected:Npn \clist_put_left:Nn { \@@_put_left:NNNn \clist_concat:NNN \clist_set:Nn } -\cs_new_protected_nopar:Npn \clist_gput_left:Nn +\cs_new_protected:Npn \clist_gput_left:Nn { \@@_put_left:NNNn \clist_gconcat:NNN \clist_set:Nn } \cs_new_protected:Npn \@@_put_left:NNNn #1#2#3#4 { @@ -1050,9 +1051,9 @@ % \UnitTested % \begin{macro}[aux]{\@@_put_right:NNNn} % \begin{macrocode} -\cs_new_protected_nopar:Npn \clist_put_right:Nn +\cs_new_protected:Npn \clist_put_right:Nn { \@@_put_right:NNNn \clist_concat:NNN \clist_set:Nn } -\cs_new_protected_nopar:Npn \clist_gput_right:Nn +\cs_new_protected:Npn \clist_gput_right:Nn { \@@_put_right:NNNn \clist_gconcat:NNN \clist_set:Nn } \cs_new_protected:Npn \@@_put_right:NNNn #1#2#3#4 { @@ -1105,9 +1106,9 @@ % either \cs{exp_not:n} or \cs{use_none:n} as |#2|, ensuring that the % result can safely be an empty comma list. % \begin{macrocode} -\cs_new_protected_nopar:Npn \clist_pop:NN +\cs_new_protected:Npn \clist_pop:NN { \@@_pop:NNN \tl_set:Nx } -\cs_new_protected_nopar:Npn \clist_gpop:NN +\cs_new_protected:Npn \clist_gpop:NN { \@@_pop:NNN \tl_gset:Nx } \cs_new_protected:Npn \@@_pop:NNN #1#2#3 { @@ -1338,15 +1339,15 @@ % \begin{macro}[aux, EXP]{\@@_reverse:wwNww, \@@_reverse_end:ww} % The reversed token list is built one item at a time, and stored % between \cs{q_stop} and \cs{q_mark}, in the form of |?| followed by -% zero or more instances of ``\meta{item}|,|''. We start from a comma -% list ``\meta{item_1}|,|\ldots|,|\meta{item_n}''. During the loop, -% the auxiliary \cs{@@_reverse:wwNww} receives ``|?|\meta{item_i}'' as -% |#1|, ``\meta{item_{i+1}}|,|\ldots|,|\meta{item_n}'' as |#2|, +% zero or more instances of \enquote{\meta{item}\texttt{,}}. We start from a comma +% list \enquote{\meta{item_1}\texttt{,\ldots,}\meta{item_n}}. During the loop, +% the auxiliary \cs{@@_reverse:wwNww} receives \enquote{\texttt{?}\meta{item_i}} as +% |#1|, \enquote{\meta{item_{i+1}}\texttt{,\ldots,}\meta{item_n}} as |#2|, % \cs{@@_reverse:wwNww} as |#3|, what remains until \cs{q_stop} as -% |#4|, and ``\meta{item_{i-1}}|,|\ldots|,|\meta{item_1}|,|'' as |#5|. +% |#4|, and \enquote{\meta{item_{i-1}}\texttt{,\ldots,}\meta{item_1}\texttt{,}} as |#5|. % The auxiliary moves |#1| just before |#5|, with a comma, and calls % itself (|#3|). After the last item is moved, \cs{@@_reverse:wwNww} -% receives ``\cs{q_mark} \cs{@@_reverse:wwNww} |!|'' as its argument +% receives \enquote{\cs{q_mark} \cs{@@_reverse:wwNww} \texttt{!}} as its argument % |#1|, thus \cs{@@_reverse_end:ww} as its argument |#3|. This second % auxiliary cleans up until the marker~|!|, removes the trailing comma % (introduced when the first item was moved after \cs{q_stop}), and @@ -1601,9 +1602,9 @@ % \begin{macro}{\clist_map_break:, \clist_map_break:n} % The break statements use the general \cs{__prg_map_break:Nn} mechanism. % \begin{macrocode} -\cs_new_nopar:Npn \clist_map_break: +\cs_new:Npn \clist_map_break: { \__prg_map_break:Nn \clist_map_break: { } } -\cs_new_nopar:Npn \clist_map_break:n +\cs_new:Npn \clist_map_break:n { \__prg_map_break:Nn \clist_map_break: } % \end{macrocode} % \end{macro} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx b/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx index 7923f0f1695..6a19c51d7ee 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx @@ -38,7 +38,7 @@ \documentclass[full]{l3doc} % %<*driver|package> -\GetIdInfo$Id: l3coffins.dtx 6508 2016-05-17 17:00:42Z joseph $ +\GetIdInfo$Id: l3coffins.dtx 6685 2016-08-19 16:26:52Z bruno $ {L3 Coffin code layer} % %<*driver> @@ -518,7 +518,7 @@ % Creating a new coffin means making the underlying box and adding the % data structures. These are created globally, as there is a need to % avoid any strange effects if the coffin is created inside a group. -% This means that the usual rule about \cs{l_\ldots} variables has +% This means that the usual rule about \cs[no-index]{l_\ldots} variables has % to be broken. % \begin{macrocode} \cs_new_protected:Npn \coffin_new:N #1 @@ -616,7 +616,7 @@ \@@_if_exist:NT #1 { \hbox_set:Nw #1 \color_group_begin: \color_ensure_current: - \cs_set_protected_nopar:Npn \hcoffin_set_end: + \cs_set_protected:Npn \hcoffin_set_end: { \color_group_end: \hbox_set_end: @@ -626,7 +626,7 @@ } } } -\cs_new_protected_nopar:Npn \hcoffin_set_end: { } +\cs_new_protected:Npn \hcoffin_set_end: { } \cs_generate_variant:Nn \hcoffin_set:Nw { c } % \end{macrocode} % @@ -669,7 +669,7 @@ } } } -\cs_new_protected_nopar:Npn \vcoffin_set_end: { } +\cs_new_protected:Npn \vcoffin_set_end: { } \cs_generate_variant:Nn \vcoffin_set:Nnw { c } % \end{macrocode} % \end{macro} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3color.dtx b/Master/texmf-dist/source/latex/l3kernel/l3color.dtx index ed538b5ecce..731789745b2 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3color.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3color.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -%% File: l3color.dtx Copyright(C) 2011,2012,2014 The LaTeX3 Project +%% File: l3color.dtx Copyright(C) 2011,2012,2014,2016 The LaTeX3 Project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -38,7 +38,7 @@ \documentclass[full]{l3doc} % %<*driver|package> -\GetIdInfo$Id: l3color.dtx 5354 2014-08-23 01:35:39Z bruno $ +\GetIdInfo$Id: l3color.dtx 6596 2016-06-13 21:29:58Z joseph $ {L3 Experimental color support} % %<*driver> @@ -114,7 +114,7 @@ % needs a \tn{par}, which in horizontal mode does nothing. % \begin{macrocode} \cs_new_eq:NN \color_group_begin: \group_begin: -\cs_new_protected_nopar:Npn \color_group_end: +\cs_new_protected:Npn \color_group_end: { \tex_par:D \group_end: @@ -127,7 +127,7 @@ % current color \enquote{now}. % \begin{macrocode} %<*initex> -\cs_new_protected_nopar:Npn \color_ensure_current: +\cs_new_protected:Npn \color_ensure_current: { \__driver_color_ensure_current: } % % \end{macrocode} @@ -136,18 +136,18 @@ % then color is not in use and this function can be a no-op. % \begin{macrocode} %<*package> -\cs_new_protected_nopar:Npn \color_ensure_current: { } +\cs_new_protected:Npn \color_ensure_current: { } \AtBeginDocument { \cs_if_exist:NTF \__driver_color_ensure_current: { - \cs_set_protected_nopar:Npn \color_ensure_current: + \cs_set_protected:Npn \color_ensure_current: { \__driver_color_ensure_current: } } { \cs_if_exist:NT \set@color { - \cs_set_protected_nopar:Npn \color_ensure_current: + \cs_set_protected:Npn \color_ensure_current: { \set@color } } } diff --git a/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx b/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx index c7148f54747..c4638af4fc2 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx @@ -75,7 +75,7 @@ Do not distribute a modified version of this file. % %<*driver|class> \RequirePackage{expl3,xparse,calc} -\GetIdInfo$Id: l3doc.dtx 6474 2016-04-11 18:09:21Z qinglee $ +\GetIdInfo$Id: l3doc.dtx 6701 2016-09-08 13:56:52Z qinglee $ {L3 Experimental documentation class} % % @@ -282,7 +282,7 @@ Do not distribute a modified version of this file. % \end{syntax} % These commands are provided to typeset control sequences. % |\cmd\foo| produces \enquote{\cmd\foo} and |\cs{foo}| produces the -% same (\enquote{\texttt{\string\foo|}}). In general, \cs{cs} is more robust since +% same. In general, \cs{cs} is more robust since % it doesn't rely on catcodes being \enquote{correct} and is therefore % recommended. % @@ -297,7 +297,10 @@ Do not distribute a modified version of this file. % The \meta{options} are a key--value list which can contain the % following keys: % \begin{itemize} -% \item |index=|\meta{module}: the \meta{csname} will be indexed in +% \item |index=|\meta{name}: the \meta{csname} will be indexed as if +% one had written \cs{cs}\Arg{name}. +% \item |no-index|: the \meta{csname} will not be indexed. +% \item |module=|\meta{module}: the \meta{csname} will be indexed in % the list of commands from the \meta{module}; the \meta{module} % can in particular be |TeX| for \enquote{\TeX{} and \LaTeXe{}} % commands, or empty for commands which should be placed in the @@ -308,13 +311,14 @@ Do not distribute a modified version of this file. % \end{itemize} % \end{function} % +% % \begin{function}{\tn} % \begin{syntax} % \cs{tn} \oarg{options} \marg{csname} % \end{syntax} % Analoguous to \cs{cs} but intended for \enquote{traditional} \TeX{} % or \LaTeXe{} commands; they will be indexed accordingly. This is in -% fact equivalent to \cs{cs} |[index=TeX, replace=false,| +% fact equivalent to \cs{cs} |[module=TeX, replace=false,| % \meta{options}|]| \Arg{csname}. % \end{function} % @@ -383,9 +387,10 @@ Do not distribute a modified version of this file. % % Function environments take an optional argument to indicate whether % the function(s) it describes are expandable or restricted-expandable -% or defined in conditional forms. Use |EXP|, |rEXP|, |TF|, or |pTF| for +% or defined in conditional forms. Use |EXP|, |rEXP|, |TF|, |pTF|, or |noTF| for % this; note that |pTF| implies |EXP| since predicates must always be -% expandable. As an example: +% expandable, and that |noTF| means that the function without |TF| +% should be documented in addition to |TF|. As an example: % \begin{framed} % \vspace{-\baselineskip} % \begin{verbatim} @@ -426,6 +431,7 @@ Do not distribute a modified version of this file. % environment. Some changes in \pkg{l3doc}: it now accepts % comma-separated lists of functions, to avoid a very large number of % consecutive |\end{macro}| statements. +% Spaces and new lines are ignored (the option |[verb]| prevents this). % \begin{verbatim} % % \begin{macro}{\foo:N, \foo:c} % % \begin{macrocode} @@ -564,175 +570,6 @@ Do not distribute a modified version of this file. %<@@=codedoc> % \end{macrocode} % -% \subsection{Variants and helpers} -% -% \begin{macro} -% { -% \tl_count:f, -% \tl_greplace_all:Nxn, -% \tl_if_head_eq_charcode:oNTF, -% \tl_if_head_eq_charcode:oNT, -% \tl_if_head_eq_charcode:oNF, -% \tl_if_in:NoTF, -% \tl_if_in:NoT, -% \tl_if_in:NoF, -% \tl_remove_all:Nx, -% \tl_replace_all:Nxn, -% \tl_replace_all:Nnx, -% \tl_replace_all:Non, -% \tl_replace_all:Nno, -% \tl_replace_once:Noo, -% \prop_get:NxNTF, -% \prop_put:Nxn, -% \prop_gput:NVx, -% } -% A few missing variants. -% \begin{macrocode} -\cs_generate_variant:Nn \tl_count:n { f } -\cs_generate_variant:Nn \tl_greplace_all:Nnn { Nx } -\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNTF { o } -\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNT { o } -\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNF { o } -\cs_generate_variant:Nn \tl_if_in:NnTF { No } -\cs_generate_variant:Nn \tl_if_in:NnT { No } -\cs_generate_variant:Nn \tl_if_in:NnF { No } -\cs_generate_variant:Nn \tl_remove_all:Nn { Nx } -\cs_generate_variant:Nn \tl_replace_all:Nnn { Nx , Nnx, No , Nno } -\cs_generate_variant:Nn \tl_replace_once:Nnn { Noo } -\cs_generate_variant:Nn \prop_get:NnNTF { Nx } -\cs_generate_variant:Nn \prop_put:Nnn { Nx } -\cs_generate_variant:Nn \prop_gput:Nnn { NVx } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[int]{\@@_replace_at_at:N} -% \begin{macro}[aux]{\@@_replace_at_at_aux:Nn} -% If there is no \meta{module~name}, do nothing. Otherwise replace -% all other-|@| by letter-|@| and all other-|_| by letter-|_|, then -% replace |_@@| by |__|\meta{module~name} and |@@| by -% |__|\meta{module~name} too. The result contains |_| with category -% code letter because this is what the |macrocode| environment -% expects. Other use cases can apply \cs{tl_to_str:n} if needed. -% Note that we include spaces between the -% |@| in the code below, since it is also processed through the same -% replacement rules. -% \begin{macrocode} -\cs_new_protected:Npn \@@_replace_at_at:N #1 - { - \tl_if_empty:NF \g_@@_module_name_tl - { - \exp_args:NNo \@@_replace_at_at_aux:Nn - #1 \g_@@_module_name_tl - } - } -\cs_new_protected:Npn \@@_replace_at_at_aux:Nn #1#2 - { - \tl_replace_all:Non #1 { \token_to_str:N @ } { @ } - \tl_replace_all:Non #1 { \token_to_str:N _ } { _ } - \tl_replace_all:Nnn #1 { _ @ @ } { _ _ #2 } - \tl_replace_all:Nnn #1 { @ @ } { _ _ #2 } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}[aux]{\@@_verb_get_seq:nN} -% The argument~|#1| is given with catcodes $10$ (space), $12$ (other) -% and $13$ (active). Turn active characters to other. Remove any -% \enquote{\%} character at the beginning of a line. Remove tabs and -% newlines. Finally, convert |_@@| and |@@| to |__|\meta{module name} -% (if it is non-empty). At this point, \cs{l_@@_tmpa_tl} contains a -% comma-delimited list of names, where |@| and~|_| have category code -% letter. Turn it to a string, parse it as a comma-delimited list, -% and turn the result into a sequence of function/macro names. -% \begin{macrocode} -\cs_new_protected:Npn \@@_verb_get_seq:nN #1#2 - { - \tl_set:Nx \l_@@_tmpa_tl { \tl_to_str:n {#1} } - \tl_remove_all:Nx \l_@@_tmpa_tl - { \iow_char:N \^^M \iow_char:N \% } - \tl_remove_all:Nx \l_@@_tmpa_tl { \tl_to_str:n { ^ ^ A } } - \tl_remove_all:Nx \l_@@_tmpa_tl { \iow_char:N \^^I } - \tl_remove_all:Nx \l_@@_tmpa_tl { \iow_char:N \^^M } - \@@_replace_at_at:N \l_@@_tmpa_tl - \exp_args:NNx \seq_set_from_clist:Nn #2 - { \tl_to_str:N \l_@@_tmpa_tl } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[aux,rEXP] -% {\@@_signature_base_form:n, \@@_signature_base_form_aux:n} -% Expands to the \enquote{base form} of the signature. For instance, -% given |noxcfvV| it would obtain |nnnNnnn|, or given |ow| it would -% obtain |nw|. The loop stops at the first token that is not -% recognized. -% \begin{macrocode} -\cs_new:Npn \@@_signature_base_form:n #1 - { \@@_signature_base_form_aux:n #1 \c_empty_tl } -\cs_new:Npn \@@_signature_base_form_aux:n #1 - { - \str_case:nnTF {#1} - { - { N } { N } - { c } { N } - { n } { n } - { o } { n } - { f } { n } - { x } { n } - { V } { n } - { v } { n } - } - { \@@_signature_base_form_aux:n } - {#1} - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[aux]{\@@_predicate_from_base:N} -% Get predicate from a function's base name. This \enquote{works} for -% functions with no signature too. -% \begin{macrocode} -\cs_new:Npn \@@_predicate_from_base:N #1 - { - \__cs_get_function_name:N #1 _p: - \__cs_get_function_signature:N #1 - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[int]{\CodedocUseCs} -% To implement commands which can be used in bookmarks and moving -% arguments, it appears necessary to have an analogue of \cs{use:c} -% using only user-level category codes, or to make all auxiliaries -% user-level. -% \begin{macrocode} -\cs_new_protected:Npn \CodedocUseCs #1 { \use:c { \tl_to_str:n {#1} } } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[int]{\CodedocUnexpandedTokens} -% \begin{macro}[aux]{\CodedocUnexpandedTokens } -% \begin{macro}[aux]{\@@_exp_not:n} -% Function used as \cs{CodedocUnexpandedTokens} \meta{junk} -% \Arg{argument}. The braces are necessary, and \meta{junk}, ignored, -% must not contain braces. When used in a typesetting context, the -% function calls an auxiliary (whose name has a trailing space) which -% leaves the \meta{argument} in the input stream. When used in an -% \texttt{x}-expansion context instead, the auxiliary does not expand, -% and \cs{@@_exp_not:n} \Arg{argument} expands to itself. If this is -% written into a file and read back, the result has the original form -% \cs{CodedocUnexpandedTokens} \meta{junk} \Arg{argument}. -% \begin{macrocode} -\cs_new:Npn \CodedocUnexpandedTokens #1 # - { \use:c { CodedocUnexpandedTokens ~ } \@@_exp_not:n } -\cs_new_protected:cpn { CodedocUnexpandedTokens ~ } #1#2 {#2} -\cs_new:Npn \@@_exp_not:n #1 { \exp_not:n { \@@_exp_not:n {#1} } } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% % \subsection{Variables} % % \begin{variable}{\g_docinput_clist} @@ -762,13 +599,13 @@ Do not distribute a modified version of this file. % \end{variable} % % \begin{variable}[int] -% {\l_@@_names_coffin, \l_@@_descr_coffin, \l_@@_syntax_coffin} +% {\l_@@_functions_coffin, \l_@@_descr_coffin, \l_@@_syntax_coffin} % These coffins contain respectively the list of function names % (argument of the \env{function} environment), the text between % |\begin{function}| and |\end{function}|, and the syntax given in the % \env{syntax} environment. % \begin{macrocode} -\coffin_new:N \l_@@_names_coffin +\coffin_new:N \l_@@_functions_coffin \coffin_new:N \l_@@_descr_coffin \coffin_new:N \l_@@_syntax_coffin % \end{macrocode} @@ -784,7 +621,7 @@ Do not distribute a modified version of this file. % % \begin{variable}[int]{\l_@@_long_name_bool, \l_@@_trial_width_dim} % The boolean \cs{l_@@_long_name_bool} is \texttt{true} if the width -% \cs{l_@@_trial_width_dim} of the coffin \cs{l_@@_names_coffin} +% \cs{l_@@_trial_width_dim} of the coffin \cs{l_@@_functions_coffin} % (containing the current function names) is bigger than the space % available in the margin. % \begin{macrocode} @@ -825,20 +662,28 @@ Do not distribute a modified version of this file. % \l_@@_macro_aux_bool, % \l_@@_macro_TF_bool, % \l_@@_macro_pTF_bool, +% \l_@@_macro_noTF_bool, % \l_@@_macro_EXP_bool, % \l_@@_macro_rEXP_bool, % \l_@@_macro_var_bool, +% \l_@@_override_module_tl, +% \l_@@_macro_documented_tl, % } % Contain information about some options of function/macro -% environments: +% environments. We initialize \cs{l_@@_override_module_tl} to avoid +% overriding module names by an empty name (meaning no module). % \begin{macrocode} \bool_new:N \l_@@_macro_internal_bool \bool_new:N \l_@@_macro_aux_bool \bool_new:N \l_@@_macro_TF_bool \bool_new:N \l_@@_macro_pTF_bool +\bool_new:N \l_@@_macro_noTF_bool \bool_new:N \l_@@_macro_EXP_bool \bool_new:N \l_@@_macro_rEXP_bool \bool_new:N \l_@@_macro_var_bool +\tl_new:N \l_@@_override_module_tl +\tl_set:Nn \l_@@_override_module_tl { \q_no_value } +\tl_new:N \l_@@_macro_documented_tl % \end{macrocode} % \end{variable} % @@ -856,32 +701,62 @@ Do not distribute a modified version of this file. % \end{macrocode} % \end{variable} % -% \begin{variable}[int]{\l_@@_tmpa_tl, \l_@@_tmpb_tl, \l_@@_tmpa_int} +% \begin{variable}[int]{\l_@@_tmpa_tl, \l_@@_tmpb_tl, \l_@@_tmpa_int, \l_@@_tmpa_seq} % Some temporary variables. % \begin{macrocode} \tl_new:N \l_@@_tmpa_tl \tl_new:N \l_@@_tmpb_tl \int_new:N \l_@@_tmpa_int +\int_new:N \l_@@_tmpa_seq % \end{macrocode} % \end{variable} % -% \begin{variable}[int]{\l_@@_functions_block_prop} -% Contains information about the functions to typeset and their -% variants. +% \begin{variable}[int]{\l_@@_names_block_tl} +% List of local sequence variables (produced through +% \cs{@@_lseq_name:n}), one for each set of variants in a +% \env{function} or \env{macro} environment. More precisely these +% sequences are named after the base forms, such as \cs{clist_count:n} +% or \cs{clist_count:N} (which are not variants). Each of these +% sequences have the base name (without any signature) as their first +% item, followed by the list of variant's signatures, or +% \cs{scan_stop:} to denote the absence of signature (no colon). % \begin{macrocode} -\prop_new:N \l_@@_functions_block_prop +\tl_new:N \l_@@_names_block_tl % \end{macrocode} % \end{variable} % -% \begin{variable}[int]{\l_@@_function_input_seq, \l_@@_macro_input_seq} -% Both the \env{function} and the \env{macro} environments read their -% argument verbatim, then remove percent signs (at the beginning of -% lines), tabs and new lines, convert |_@@| and |@@| by -% |__|\meta{module name} if appropriate, and interpret the result as a -% comma list, which they store in these two sequences. +% \begin{variable}[int]{\g_@@_variants_seq} +% Stores rather temporarily the list of variants (signatures only) of +% a function/macro that is being documented. It is global because we +% need it to keep its value throughout cells of an alignment. % \begin{macrocode} -\seq_new:N \l_@@_function_input_seq -\seq_new:N \l_@@_macro_input_seq +\seq_new:N \g_@@_variants_seq +% \end{macrocode} +% \end{variable} +% +% \begin{variable}[int]{\l_@@_names_verb_bool} +% Set to |true| if the main argument of a macro/function environment +% should be used as is, without removing any comma or space. +% \begin{macrocode} +\bool_new:N \l_@@_names_verb_bool +% \end{macrocode} +% \end{variable} +% +% \begin{variable}[int]{\l_@@_names_seq} +% List of functions/environments/\ldots{} appearing as arguments of a +% given \env{function} or \env{macro} environment. These are the +% names after conversion of |_@@| and |@@| to |__|\meta{module name} +% and other sanitizing. +% \begin{macrocode} +\seq_new:N \l_@@_names_seq +% \end{macrocode} +% \end{variable} +% +% \begin{variable}[int]{\g_@@_nested_names_seq} +% Collects all macros in nested \env{macro} environments, to use them +% in the \enquote{End definition} text. +% \begin{macrocode} +\seq_new:N \g_@@_nested_names_seq % \end{macrocode} % \end{variable} % @@ -895,25 +770,23 @@ Do not distribute a modified version of this file. % \end{macrocode} % \end{variable} % -% \begin{variable}[int]{\g_@@_function_name_prefix_tl} -% The \enquote{prefix} of the current function is a backslash if the -% function starts with it, and otherwise is empty. -% \begin{macrocode} -\tl_new:N \g_@@_function_name_prefix_tl -% \end{macrocode} -% \end{variable} -% % \begin{variable} -% {\l_@@_index_macro_tl, \l_@@_index_key_tl, \l_@@_index_module_tl} +% { +% \l_@@_index_macro_tl, \l_@@_index_key_tl, +% \l_@@_index_module_tl, \l_@@_index_internal_bool +% } % When analyzing a control sequence found within a \env{macrocode} % environment, \cs{l_@@_index_macro_tl} holds the control sequence % (partially a string), \cs{l_@@_index_key_tl} holds what will be used % as a sort key in the index, and \cs{l_@@_index_module_tl} is the -% subindex in which the control sequence will be listed. +% subindex in which the control sequence will be listed. Finally, +% \cs{l_@@_index_internal_bool} indicates when the control sequence is +% internal and should be indexed in a slightly different subindex. % \begin{macrocode} \tl_new:N \l_@@_index_macro_tl \tl_new:N \l_@@_index_key_tl \tl_new:N \l_@@_index_module_tl +\bool_new:N \l_@@_index_internal_bool % \end{macrocode} % \end{variable} % @@ -941,8 +814,8 @@ Do not distribute a modified version of this file. % indexing commands, and the number of macros so far (including those % from surrounding \env{macro} environments). % \begin{macrocode} -\box_new:N \l_@@_macro_index_box \box_new:N \l_@@_macro_box +\box_new:N \l_@@_macro_index_box \int_new:N \l_@@_macro_int % \end{macrocode} % \end{variable} @@ -951,6 +824,8 @@ Do not distribute a modified version of this file. % { % \l_@@_cmd_tl, % \l_@@_cmd_index_tl, +% \l_@@_cmd_module_tl, +% \l_@@_cmd_noindex_bool, % \l_@@_cmd_replace_bool, % } % Variables used to control the behaviour of \cs{cmd}, \cs{cs} and @@ -958,6 +833,8 @@ Do not distribute a modified version of this file. % \begin{macrocode} \tl_new:N \l_@@_cmd_tl \tl_new:N \l_@@_cmd_index_tl +\tl_new:N \l_@@_cmd_module_tl +\bool_new:N \l_@@_cmd_noindex_bool \bool_new:N \l_@@_cmd_replace_bool % \end{macrocode} % \end{variable} @@ -995,17 +872,40 @@ Do not distribute a modified version of this file. % \end{macrocode} % \end{variable} % -% \begin{variable}[int]{\l_@@_no_label_bool} -% This boolean prevents the insertions of \tn{label}s in a -% \env{function} environment. This is only useful when a function's -% documentation appears multiple times, for instance in -% \file{source3body.tex} some examples repeat the documentation from -% actual functions. +% \begin{variable}[int]{\l_@@_function_label_clist, \l_@@_no_label_bool} +% Option of a \env{function} environment which replaces the label that +% would normally be inserted by labels for the given list of control +% sequences. This is only useful to avoid duplicate labels when a +% function's documentation appears multiple times. % \begin{macrocode} +\clist_new:N \l_@@_function_label_clist \bool_new:N \l_@@_no_label_bool % \end{macrocode} % \end{variable} % +% \begin{variable}[int]{\l_@@_date_added_tl, \l_@@_date_updated_tl} +% Values of some options of the \env{function} environment. +% \begin{macrocode} +\tl_new:N \l_@@_date_added_tl +\tl_new:N \l_@@_date_updated_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}[int]{\l_@@_macro_argument_tl} +% Save the argument of a \env{macro} or \env{function} environment for +% use in error messages. +% \begin{macrocode} +\tl_new:N \l_@@_macro_argument_tl +% \end{macrocode} +% \end{variable} +% +% ^^A Bruno: what does the next line do? +% \begin{macrocode} +% \int_new:N \c@CodelineNo +% \end{macrocode} +% +% \subsection{Variants and helpers} +% % \begin{macro}[aux]{\@@_tmpa:w, \@@_tmpb:w} % Auxiliary macros for temporary use. % \begin{macrocode} @@ -1014,9 +914,334 @@ Do not distribute a modified version of this file. % \end{macrocode} % \end{macro} % -% Bruno: can I delete this next line? +% \begin{macro} +% { +% \seq_set_split:NoV, +% \str_case:fn, +% \tl_count:f, +% \tl_greplace_all:Nxn, +% \tl_greplace_all:Nno, +% \tl_if_head_eq_charcode:oNTF, +% \tl_if_head_eq_charcode:oNT, +% \tl_if_head_eq_charcode:oNF, +% \tl_if_head_eq_meaning:VNF, +% \tl_if_in:noTF, +% \tl_if_in:NoTF, +% \tl_if_in:NoT, +% \tl_if_in:NoF, +% \tl_remove_all:Nx, +% \tl_replace_all:Nxn, +% \tl_replace_all:Nnx, +% \tl_replace_all:Non, +% \tl_replace_all:Nno, +% \tl_replace_once:Noo, +% \tl_to_str:f, +% \tl_to_str:o, +% \prop_get:NxNTF, +% \prop_put:Nxn, +% \prop_gput:NVx, +% } +% A few missing variants. % \begin{macrocode} -% \int_new:N \c@CodelineNo +\cs_generate_variant:Nn \seq_set_split:Nnn { NoV } +\cs_generate_variant:Nn \str_case:nn { fn } +\cs_generate_variant:Nn \tl_count:n { f } +\cs_generate_variant:Nn \tl_greplace_all:Nnn { Nx , Nno } +\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNTF { o } +\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNT { o } +\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNF { o } +\cs_generate_variant:Nn \tl_if_head_eq_meaning:nNF { V } +\cs_generate_variant:Nn \tl_if_in:nnTF { no } +\cs_generate_variant:Nn \tl_if_in:NnTF { No } +\cs_generate_variant:Nn \tl_if_in:NnT { No } +\cs_generate_variant:Nn \tl_if_in:NnF { No } +\cs_generate_variant:Nn \tl_remove_all:Nn { Nx } +\cs_generate_variant:Nn \tl_replace_all:Nnn { Nx , Nnx, No , Nno } +\cs_generate_variant:Nn \tl_replace_once:Nnn { Noo } +\cs_generate_variant:Nn \tl_to_str:n { f , o } +\cs_generate_variant:Nn \prop_get:NnNTF { Nx } +\cs_generate_variant:Nn \prop_put:Nnn { Nx } +\cs_generate_variant:Nn \prop_gput:Nnn { NVx } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int,TF]{\@@_if_almost_str:n} +% Used to test if the argument of |\cmd| or other macros to be indexed +% is almost a string or not: for instance this will be wrong if |#1| +% contains |\meta{...}|. The surprising |f|-expansion are there to +% cope with the case of |#1| starting with \cs{c_@@_backslash_tl} +% which should be expanded and considered to be \enquote{normal}. +% \begin{macrocode} +\prg_new_protected_conditional:Npnn \@@_if_almost_str:n #1 { TF , T , F } + { + \int_compare:nNnTF + { \tl_count:n {#1} } + < { \tl_count:f { \tl_to_str:f {#1} } } + { \prg_return_false: } + { \prg_return_true: } + } +\cs_generate_variant:Nn \@@_if_almost_str:nT { V } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\@@_replace_at_at:N} +% \begin{macro}[aux]{\@@_replace_at_at_aux:Nn} +% The goal is to replace |@@| by the current module name. If there is +% no \meta{module~name}, do nothing. Otherwise, sanitize the catcodes +% of |@| and~|_| and replace both |_@@| and |@@| by +% |__|\meta{module~name}. The result contains |_| with category +% code letter because this is what the |macrocode| environment +% expects. Other use cases can apply \cs{tl_to_str:n} if needed. +% Note that we include spaces between the +% |@| in the code below, since it is also processed through the same +% replacement rules. +% \begin{macrocode} +\cs_new_protected:Npn \@@_replace_at_at:N #1 + { + \tl_if_empty:NF \g_@@_module_name_tl + { + \exp_args:NNo \@@_replace_at_at_aux:Nn + #1 \g_@@_module_name_tl + } + } +\cs_new_protected:Npn \@@_replace_at_at_aux:Nn #1#2 + { + \tl_replace_all:Non #1 { \token_to_str:N @ } { @ } + \tl_replace_all:Non #1 { \token_to_str:N _ } { _ } + \tl_replace_all:Nnn #1 { _ @ @ } { _ _ #2 } + \tl_replace_all:Nnn #1 { @ @ } { _ _ #2 } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[aux,rEXP]{\@@_signature_base_form:n} +% \begin{macro}[aux] +% {\@@_signature_base_form_aux:n, \@@_signature_base_form_aux:w} +% Expands to the \enquote{base form} of the signature. For instance, +% given |noxcfvV| it would obtain |nnnNnnn|, or given |ow| it would +% obtain |nw|. The loop stops at the first token that is not +% recognized; the rest is enclosed in \cs{exp_not:n}. +% \begin{macrocode} +\cs_new:Npn \@@_signature_base_form:n #1 + { \@@_signature_base_form_aux:n #1 \q_stop } +\cs_new:Npn \@@_signature_base_form_aux:n #1 + { + \str_case:nnTF {#1} + { + { N } { N } + { c } { N } + { n } { n } + { o } { n } + { f } { n } + { x } { n } + { V } { n } + { v } { n } + } + { \@@_signature_base_form_aux:n } + { \@@_signature_base_form_aux:w #1 } + } +\cs_new:Npn \@@_signature_base_form_aux:w #1 \q_stop + { \exp_not:n {#1} } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[aux]{\@@_predicate_from_base:n} +% Get predicate from a function's base name. The code is not broken +% by functions with no signature. The |n|-type version can be used +% for keys and other non-control sequences. The output after +% |x|-expansion is a string. +% \begin{macrocode} +\cs_new:Npn \@@_predicate_from_base:n #1 + { + \@@_get_function_name:n {#1} + \tl_to_str:n { _p: } + \@@_get_function_signature:n {#1} + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\@@_split_function_do:nn, \@@_split_function_do:on} +% \begin{macro}[aux]{\@@_get_function_name:n, \@@_get_function_signature:n} +% \begin{macro}[aux]{\@@_split_function_auxi:w, \@@_split_function_auxii:w} +% Similar to internal functions defined in \pkg{l3basics}, but here we +% operate on strings directly rather than control sequences. +% \begin{macrocode} +\cs_new:Npn \@@_get_function_name:n #1 + { \@@_split_function_do:nn {#1} { \use_i:nnn } } +\cs_new:Npn \@@_get_function_signature:n #1 + { \@@_split_function_do:nn {#1} { \use_ii:nnn } } +\cs_set_protected:Npn \@@_tmpa:w #1 + { + \cs_new:Npn \@@_split_function_do:nn ##1 + { + \exp_after:wN \@@_split_function_auxi:w + \tl_to_str:n {##1} \q_mark \c_true_bool + #1 \q_mark \c_false_bool + \q_stop + } + \cs_new:Npn \@@_split_function_auxi:w + ##1 #1 ##2 \q_mark ##3##4 \q_stop ##5 + { \@@_split_function_auxii:w {##5} ##1 \q_mark \q_stop {##2} ##3 } + \cs_new:Npn \@@_split_function_auxii:w + ##1##2 \q_mark ##3 \q_stop + { ##1 {##2} } + } +\exp_args:No \@@_tmpa:w { \token_to_str:N : } +\cs_generate_variant:Nn \@@_split_function_do:nn { o } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[aux, rEXP]{\@@_key_get_base:nN} +% Get the base form of a function and store it. As part of getting +% the base form, change trailing |T| or |F| to |TF|. +% \begin{macrocode} +\cs_new_protected:Npn \@@_key_get_base:nN #1#2 + { + \@@_if_almost_str:nTF {#1} + { + \@@_key_get_base_TF:nN {#1} \l_@@_tmpa_tl + \tl_set:Nx #2 + { \@@_split_function_do:on \l_@@_tmpa_tl { \@@_base_form_aux:nnN } } + } + { \tl_set:Nn #2 {#1} } + } +\cs_new:Npx \@@_key_get_base_TF:nN #1#2 + { + \tl_set:Nx #2 { \exp_not:N \tl_to_str:n {#1} \scan_stop: } + \tl_if_in:NnTF #2 { \tl_to_str:n { F } \scan_stop: } + { + \tl_if_in:NnF #2 { \tl_to_str:n { TF } \scan_stop: } + { + \tl_replace_once:Nnn #2 + { \tl_to_str:n { F } \scan_stop: } + { \tl_to_str:n { TF } \scan_stop: } + } + } + { + \tl_replace_once:Nnn #2 + { \tl_to_str:n { T } \scan_stop: } + { \tl_to_str:n { TF } \scan_stop: } + } + \tl_remove_once:Nn #2 { \scan_stop: } + } +\cs_new:Npn \@@_base_form_aux:nnN #1#2#3 + { + \exp_not:n {#1} + \bool_if:NT #3 + { + \token_to_str:N : + \str_if_eq:nnTF { #1 ~ } { \exp_args } + { \exp_not:n {#2} } + { \@@_signature_base_form:n {#2} } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\@@_base_form_signature_do:nnn} +% Do |#2{#1}| if there is no signature, or if |#1| contains two colons +% in a row (this covers the weird function |\::N| and so on). +% Otherwise apply |#3| with the following two arguments: the base form +% of |#1|, and the original signature with an extra pair of braces. +% \begin{macrocode} +\cs_new_protected:Npn \@@_base_form_signature_do:nnn #1#2#3 + { + \@@_split_function_do:nn {#1} + { \@@_base_form_aux:nnnnnN {#1} {#2} {#3} } + } +\cs_new_protected:Npn \@@_base_form_aux:nnnnnN #1#2#3#4#5#6 + { + \bool_if:NTF #6 + { + \tl_if_head_eq_charcode:nNTF {#4} : + { #2 {#1} } + { + \use:x + { + \exp_not:n {#3} + { \@@_base_form_aux:nnN {#4} {#5} #6 } + } + {#4} {#5} + } + } + { #2 {#1} } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int, pTF]{\@@_date_compare:nNn} +% \begin{macro}[aux]{\@@_date_compare_aux:nnnNnnn, \@@_date_compare_aux:w} +% \begin{macrocode} +\prg_new_conditional:Npnn \@@_date_compare:nNn #1#2#3 { TF , T , F , p } + { \@@_date_compare_aux:w #1--- \q_mark #2 #3--- \q_stop } +\cs_new:Npn \@@_date_compare_aux:w + #1 - #2 - #3 - #4 \q_mark #5 #6 - #7 - #8 - #9 \q_stop + { + \@@_date_compare_aux:nnnNnnn + { \tl_if_empty:nTF {#1} { 0 } {#1} } + { \tl_if_empty:nTF {#2} { 0 } {#2} } + { \tl_if_empty:nTF {#3} { 0 } {#3} } + #5 + { \tl_if_empty:nTF {#6} { 0 } {#6} } + { \tl_if_empty:nTF {#7} { 0 } {#7} } + { \tl_if_empty:nTF {#8} { 0 } {#8} } + } +\cs_new:Npn \@@_date_compare_aux:nnnNnnn #1#2#3#4#5#6#7 + { + \int_compare:nNnTF {#1} = {#5} + { + \int_compare:nNnTF {#2} = {#6} + { + \int_compare:nNnTF {#3} #4 {#7} + { \prg_return_true: } { \prg_return_false: } + } + { + \int_compare:nNnTF {#2} #4 {#6} + { \prg_return_true: } { \prg_return_false: } + } + } + { + \int_compare:nNnTF {#1} #4 {#5} + { \prg_return_true: } { \prg_return_false: } + } + \use_none:n + \q_stop + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[aux]{\@@_gprop_name:n, \@@_lseq_name:n} +% We need to keep track of some information about control sequences +% (and other strings) that are being (or have been) documented. Some +% is stored into global props and some into local seqs, whose name +% does not follow conventions: it is \cs[no-index]{g_@@} or +% \cs[no-index]{l_@@} followed by a space and by the string, which can +% be arbitrary. We cannot reasonably use a single big |prop| for +% speed reasons. +% \begin{macrocode} +\cs_new:Npn \@@_gprop_name:n #1 { g_@@ ~ \tl_to_str:n {#1} } +\cs_new:Npn \@@_lseq_name:n #1 { l_@@ ~ \tl_to_str:n {#1} } +% \end{macrocode} +% \end{macro} +% +% \subsection{Messages} +% +% \begin{macrocode} +\msg_new:nnnn { l3doc } { no-signature-TF } + { Function/macro~'#1'~cannot~be~turned~into~a~conditional. } + { + A~function~or~macro~environment~with~option~pTF,~TF~or~noTF~ + received~the~argument~'#1'.~This~function's~name~has~no~ + ':'~hence~it~is~not~clear~where~to~add~'_p'~or~'TF'.~ + Please~follow~expl3~naming~conventions. + } +\msg_new:nnn { l3doc } { deprecated-function } + { The~deprecated~function(s)~'#1'~should~have~been~removed~on~#2. } % \end{macrocode} % % \subsection{Options and configuration} @@ -1061,7 +1286,8 @@ Do not distribute a modified version of this file. % % \begin{macrocode} \DeclareOption* { \PassOptionsToClass { \CurrentOption } { article } } -\ExecuteOptions { full, a4paper, nocheck, nochecktest, lm-default } +\ExecuteOptions { full, nocheck, nochecktest, lm-default } +\PassOptionsToClass { a4paper } { article } % \end{macrocode} % % Input a local configuration file, if it exists, with a message to the @@ -1141,7 +1367,7 @@ Do not distribute a modified version of this file. % A few more letters are \enquote{private} in a \LaTeX3 programming % environment. % \begin{macrocode} -\cs_gset_nopar:Npn \MakePrivateLetters +\cs_gset:Npn \MakePrivateLetters { \char_set_catcode_letter:N \@ \char_set_catcode_letter:N \_ @@ -1172,6 +1398,40 @@ Do not distribute a modified version of this file. % \end{macrocode} % \end{macro} % +% \begin{macro}[int]{\ifnot@excluded} +% This function tests whether a macro name stored in +% \tn{macro@namepart} was excluded from indexing by \tn{DoNotIndex}. +% Rather than trying to fix catcodes that come into here, turn +% everything to string catcodes. This is somewhat inefficient as we +% could have ensured that \tn{index@excludelist} has string catcodes +% in the first place. +% \begin{macrocode} +\cs_set_protected:Npn \ifnot@excluded + { + \exp_args:Nxx \expanded@notin + { \c_@@_backslash_tl \tl_to_str:N \macro@namepart , } + { \exp_args:NV \tl_to_str:n \index@excludelist } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\pdfstringnewline} +% \begin{macro}[aux]{\@@_pdfstring_newline:w} +% We avoid some hyperref warnings by making |\\| (almost) trivial in +% bookmarks: more precisely it might be used with a star and an +% optional argument, which we thus remove using an \pkg{xparse} +% expandable command. Since there cannot be trailing optional +% arguments, pick up an extra mandatory one and put it back. +% \begin{macrocode} +\cs_new:Npn \pdfstringnewline { : ~ } +\DeclareExpandableDocumentCommand + { \@@_pdfstring_newline:w } { s o m } { \pdfstringnewline #3 } +\pdfstringdefDisableCommands + { \cs_set_eq:NN \\ \@@_pdfstring_newline:w } +% \end{macrocode} +% \end{macro} +% \end{macro} +% % \subsection{Design} % % Increase the text width slightly so that width the standard fonts @@ -1193,7 +1453,7 @@ Do not distribute a modified version of this file. % Customise lists. % \begin{macrocode} \cs_new_eq:NN \@@_oldlist:nn \list -\cs_gset_nopar:Npn \list #1 #2 +\cs_gset:Npn \list #1 #2 { \@@_oldlist:nn {#1} { #2 \dim_zero:N \listparindent } } \setlength \parindent { 2em } \setlength \itemindent { 0pt } @@ -1214,7 +1474,7 @@ Do not distribute a modified version of this file. % Different design and/or structure is called for). % \begin{macrocode} \@addtoreset{section}{part} -\cs_gset_nopar:Npn \l@section #1#2 +\cs_gset:Npn \l@section #1#2 { \ifnum \c@tocdepth >\z@ \addpenalty\@secpenalty @@ -1230,7 +1490,7 @@ Do not distribute a modified version of this file. \endgroup \fi } -\cs_gset_nopar:Npn \l@subsection +\cs_gset:Npn \l@subsection { \@dottedtocline{2}{2.5em}{2.3em} } % #2 = 1.5em % \end{macrocode} % \end{macro} @@ -1273,33 +1533,56 @@ Do not distribute a modified version of this file. % \end{macro} % % \begin{macro}{\cmd, \cs, \tn} -% To work within bookmarks, these commands must be expandable. They -% rely on a common auxiliary \cs{@@_cmd:nn} which receives as +% They rely on a common auxiliary \cs{@@_cmd:nn} which receives as % arguments the options and some tokens whose string representation % starts with a backslash (to support cases such as |\cs{pkg_\ldots}|, % we do not turn the whole argument into a string). % \begin{macrocode} -\DeclareExpandableDocumentCommand \cmd { O{} m } +\DeclareDocumentCommand \cmd { O{} m } { \@@_cmd:no {#1} { \token_to_str:N #2 } } -\DeclareExpandableDocumentCommand \cs { O{} m } +\DeclareDocumentCommand \cs { O{} m } { \@@_cmd:no {#1} { \c_@@_backslash_tl #2 } } -\DeclareExpandableDocumentCommand \tn { O{} m } +\DeclareDocumentCommand \tn { O{} m } { \@@_cmd:no - { index = TeX , replace = false , #1 } + { module = TeX , replace = false , #1 } { \c_@@_backslash_tl #2 } } % \end{macrocode} % \end{macro} % % \begin{macro}{\meta} -% To work within a bookmark, this command must be expandable. +% A document-level command. % \begin{macrocode} -\DeclareExpandableDocumentCommand { \meta } { m } +\DeclareDocumentCommand \meta { m } { \@@_meta:n {#1} } % \end{macrocode} % \end{macro} % +% \begin{macro}[aux] +% { +% \@@_pdfstring_cmd:w, +% \@@_pdfstring_cs:w, +% \@@_pdfstring_meta:w +% } +% To work within a bookmark, these commands must be expandable. +% \begin{macrocode} +\DeclareExpandableDocumentCommand + { \@@_pdfstring_cmd:w } { o m } { \token_to_str:N #2 } +\DeclareExpandableDocumentCommand + { \@@_pdfstring_cs:w } { o m } { \textbackslash \tl_to_str:n {#2} } +\cs_new:Npn \@@_pdfstring_meta:w #1 + { < \tl_to_str:n {#1} > } +\pdfstringdefDisableCommands + { + \cs_set_eq:NN \cmd \@@_pdfstring_cmd:w + \cs_set_eq:NN \cs \@@_pdfstring_cs:w + \cs_set_eq:NN \tn \@@_pdfstring_cs:w + \cs_set_eq:NN \meta \@@_pdfstring_meta:w + } +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\Arg, \marg, \oarg, \parg} % |\marg{text}| prints \marg{text}, \enquote{mandatory argument}.\\ % |\oarg{text}| prints \oarg{text}, \enquote{optional argument}.\\ @@ -1447,24 +1730,54 @@ Do not distribute a modified version of this file. % \end{macrocode} % \end{environment} % -% \subsubsection{Implementing text markup} +% \begin{macro}{\CodedocExplain, \CodedocExplainEXP, \CodedocExplainREXP, \CodedocExplainTF} +% Explanation of stars and |TF| notations, for use in third-party +% packages. +% \begin{macrocode} +\NewDocumentCommand { \CodedocExplain } { } + { \CodedocExplainEXP \ \CodedocExplainREXP \ \CodedocExplainTF } +\NewDocumentCommand { \CodedocExplainEXP } { } + { + \raisebox{\baselineskip}[0pt][0pt]{\hypertarget{expstar}{}}% + \@@_typeset_exp:\ indicates~fully~expandable~functions,~which~ + can~be~used~within~an~\texttt{x}-type~argument~(in~plain~ + \TeX{}~terms,~inside~an~\cs{edef}),~as~well~as~within~an~ + \texttt{f}-type~argument. + } +\NewDocumentCommand { \CodedocExplainREXP } { } + { + \raisebox{\baselineskip}[0pt][0pt]{\hypertarget{rexpstar}{}}% + \@@_typeset_rexp:\ indicates~ + restricted~expandable~functions,~which~can~be~used~within~an~ + \texttt{x}-type~argument~but~cannot~be~fully~expanded~within~an~ + \texttt{f}-type~argument. + } +\NewDocumentCommand { \CodedocExplainTF } { } + { + \raisebox{\baselineskip}[0pt][0pt]{\hypertarget{explTF}{}}% + \@@_typeset_TF:\ indicates~conditional~(\texttt{if})~functions~ + whose~variants~with~\texttt{T},~\texttt{F}~and~\texttt{TF}~ + argument~specifiers~expect~different~ + \enquote{true}/\enquote{false}~branches. + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Implementing text markup} % % Keys for \cs{cmd}, \cs{cs} and \cs{tn}. % \begin{macrocode} \keys_define:nn { l3doc/cmd } { index .tl_set:N = \l_@@_cmd_index_tl , + module .tl_set:N = \l_@@_cmd_module_tl , + no-index .bool_set:N = \l_@@_cmd_noindex_bool , replace .bool_set:N = \l_@@_cmd_replace_bool , } % \end{macrocode} % % \begin{macro}[int]{\@@_cmd:nn, \@@_cmd:no} -% \begin{macro}[aux]{\@@_cmd_aux:nn} -% Within a |pdfstring|, use the second argument directly. Otherwise -% call \cs{@@_cmd_aux:nn}: the indirection through -% \cs{CodedocUnexpandedTokens} and \cs{CodedocUseCs} makes things -% work when they pass through a -% file. Apply the key--value \meta{options}~|#1| after setting some +% Apply the key--value \meta{options}~|#1| after setting some % default values. Then (unless |replace=false|) replace |@@| in~|#2|, % which is a bit tricky: the |_| must be given the catcode expected by % \cs{@@_replace_at_at:N}, but should be reverted to their original @@ -1473,23 +1786,16 @@ Do not distribute a modified version of this file. % \tn{verbatim@font}, after turning it to harmless characters if % needed (and keeping the underscore breakable); in any case, spaces % must be turned into \tn{@xobeysp}. Finally, produce an index entry. +% Indexing is suppressed when \cs{l_@@_cmd_noindex_bool} is true. % \begin{macrocode} -\cs_new:Npn \@@_cmd:nn #1#2 - { - \texorpdfstring - { - \CodedocUnexpandedTokens - { \CodedocUseCs { @@_cmd_aux:nn } {#1} {#2} } - } - {#2} - } -\cs_generate_variant:Nn \@@_cmd:nn { no } -\cs_new_protected:Npn \@@_cmd_aux:nn #1#2 +\cs_new_protected:Npn \@@_cmd:nn #1#2 { + \bool_set_false:N \l_@@_cmd_noindex_bool \bool_set_true:N \l_@@_cmd_replace_bool \tl_set:Nn \l_@@_cmd_index_tl { \q_no_value } + \tl_set:Nn \l_@@_cmd_module_tl { \q_no_value } \keys_set:nn { l3doc/cmd } {#1} - \tl_set:No \l_@@_cmd_tl { \token_to_str:N #2 } + \tl_set:Nn \l_@@_cmd_tl {#2} \bool_if:NT \l_@@_cmd_replace_bool { \tl_set_rescan:Nnn \l_@@_tmpb_tl { } { _ } @@ -1500,9 +1806,7 @@ Do not distribute a modified version of this file. \mode_if_math:T { \mbox } { \verbatim@font - \int_compare:nNnF - { \tl_count:N \l_@@_cmd_tl } - < { \tl_count:f { \tl_to_str:N \l_@@_cmd_tl } } + \@@_if_almost_str:VT \l_@@_cmd_tl { \tl_set:Nx \l_@@_cmd_tl { \tl_to_str:N \l_@@_cmd_tl } \tl_replace_all:Non \l_@@_cmd_tl @@ -1511,23 +1815,31 @@ Do not distribute a modified version of this file. \tl_replace_all:Nnn \l_@@_cmd_tl { ~ } { \@xobeysp } \l_@@_cmd_tl } - \exp_args:No \@@_key_get:n { \l_@@_cmd_tl } - \quark_if_no_value:NF \l_@@_cmd_index_tl - { \tl_set_eq:NN \l_@@_index_module_tl \l_@@_cmd_index_tl } - \@@_special_index_module:ooon - { \l_@@_index_key_tl } - { \l_@@_index_macro_tl } - { \l_@@_index_module_tl } - { } + \bool_if:NF \l_@@_cmd_noindex_bool + { + \quark_if_no_value:NF \l_@@_cmd_index_tl + { \tl_set_eq:NN \l_@@_cmd_tl \l_@@_cmd_index_tl } + \exp_args:No \@@_key_get:n { \l_@@_cmd_tl } + \quark_if_no_value:NF \l_@@_cmd_module_tl + { + \tl_set:Nx \l_@@_index_module_tl + { \tl_to_str:N \l_@@_cmd_module_tl } + } + \@@_special_index_module:ooonN + { \l_@@_index_key_tl } + { \l_@@_index_macro_tl } + { \l_@@_index_module_tl } + { } + \l_@@_index_internal_bool + } } +\cs_generate_variant:Nn \@@_cmd:nn { no } % \end{macrocode} % \end{macro} -% \end{macro} % % \begin{macro} % { % \@@_meta:n, -% \@@_meta_aux:n, % \@@_ensuremath_sb:n, % \@@_meta_original:n % } @@ -1538,16 +1850,7 @@ Do not distribute a modified version of this file. % \cs{@@_ensuremath_sb:n} (which creates math subscripts), then runs % the code used for \tn{meta} in \pkg{doc.sty}. % \begin{macrocode} -\cs_new:Npn \@@_meta:n #1 - { - \texorpdfstring - { - \CodedocUnexpandedTokens - { \CodedocUseCs { @@_meta_aux:n } {#1} } - } - { < #1 > } - } -\cs_new_protected:Npn \@@_meta_aux:n #1 +\cs_new_protected:Npn \@@_meta:n #1 { \tl_set:Nn \l_@@_tmpa_tl {#1} \tl_map_inline:nn @@ -1564,19 +1867,247 @@ Do not distribute a modified version of this file. { \ensuremath { \sb {#1} } } \cs_new_protected:Npn \@@_meta_original:n #1 { - \ensuremath \langle - \mode_if_math:T { \nfss@text } - { - \meta@font@select - \edef \meta@hyphen@restore - { \hyphenchar \the \font \the \hyphenchar \font } - \hyphenchar \font \m@ne - \language \l@nohyphenation - #1 \/ - \meta@hyphen@restore - } - \ensuremath \rangle + \ensuremath \langle + \mode_if_math:T { \nfss@text } + { + \meta@font@select + \edef \meta@hyphen@restore + { \hyphenchar \the \font \the \hyphenchar \font } + \hyphenchar \font \m@ne + \language \l@nohyphenation + #1 \/ + \meta@hyphen@restore + } + \ensuremath \rangle + } +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Common between \env{macro} and \env{function}} +% +% \begin{macro} +% { +% \@@_typeset_exp:, \@@_typeset_rexp:, +% \@@_typeset_TF:, \@@_typeset_aux:n +% } +% Used by \cs{@@_macro_single:nNN} and in the \env{function} environment +% to typeset conditionals and auxiliary functions. +% \begin{macrocode} +\cs_new_protected:Npn \@@_typeset_exp: + { \hyperlink{expstar} {$\star$} } +\cs_new_protected:Npn \@@_typeset_rexp: + { \hyperlink{rexpstar} {\ding{73}} } % hollow star +\cs_new_protected:Npn \@@_typeset_TF: + { + \hyperlink{explTF} + { + \color{black} + \itshape TF + \makebox[0pt][r] + { + \color{red} + \underline { \phantom{\itshape TF} \kern-0.1em } + } + } + } +\cs_new_protected:Npn \@@_typeset_aux:n #1 + { + { \color[gray]{0.7} #1 } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int] +% {\@@_get_hyper_target:nN, \@@_get_hyper_target:oN, \@@_get_hyper_target:xN} +% Create a \pkg{hyperref} anchor from a macro name~|#1| and stores it +% in the token list variable~|#2|. For instance, |\prg_replicate:nn| +% gives |doc/function//prg/replicate:nn|. +% \begin{macrocode} +\cs_new_protected:Npn \@@_get_hyper_target:nN #1#2 + { + \tl_set:Nx #2 { \tl_to_str:n {#1} } + \tl_replace_all:Nxn #2 { \iow_char:N \_ } { / } + \tl_remove_all:Nx #2 { \iow_char:N \\ } + \tl_put_left:Nn #2 { doc/function// } + } +\cs_generate_variant:Nn \@@_get_hyper_target:nN { o , x } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\@@_names_get_seq:nN} +% The argument~|#1| (argument of a |function| or |macro| environment) +% has catcodes $10$ (space), $12$ (other) and $13$ (active). Sanitize +% catcodes. If the |verb| option was used, output a one-item +% sequence. Otherwise, remove any \enquote{\%} character at the +% beginning of a line. Remove tabs and newlines. Finally, convert +% |_@@| and |@@| to |__|\meta{module name} (if it is non-empty). At +% this point, \cs{l_@@_tmpa_tl} contains a comma-delimited list of +% names, where |@| and~|_| have category code letter. Turn it to a +% string, parse it as a comma-delimited list (in particular this +% removes spaces), and output a sequence of function/macro names. +% \begin{macrocode} +\cs_new_protected:Npn \@@_names_get_seq:nN #1#2 + { + \tl_set:Nx \l_@@_tmpa_tl { \tl_to_str:n {#1} } + \bool_if:NTF \l_@@_names_verb_bool + { + \seq_clear:N #2 + \seq_put_right:NV #2 \l_@@_tmpa_tl + } + { + \tl_remove_all:Nx \l_@@_tmpa_tl + { \iow_char:N \^^M \iow_char:N \% } + \tl_remove_all:Nx \l_@@_tmpa_tl { \tl_to_str:n { ^ ^ A } } + \tl_remove_all:Nx \l_@@_tmpa_tl { \iow_char:N \^^I } + \tl_remove_all:Nx \l_@@_tmpa_tl { \iow_char:N \^^M } + \@@_replace_at_at:N \l_@@_tmpa_tl + \exp_args:NNx \seq_set_from_clist:Nn #2 + { \tl_to_str:N \l_@@_tmpa_tl } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\@@_names_parse:, \@@_names_parse_one:n} +% The goal is to group variants together. We populate +% \cs{l_@@_names_block_tl} with local sequence variable named with +% \cs{@@_lseq_name:n} after the base forms. When encountering a new +% base form, set the corresponding local sequence to hold the +% \meta{base name} (stripped of the signature) and add the local +% sequence to the list \cs{l_@@_names_block_tl}. In all cases append +% the signature to the local sequence, which thus takes the form +% \meta{base name}, \meta{signature_1}, \meta{signature_2} and so on. +% If the original function had no signature (no colon) then use +% \cs{scan_stop:} as the signature (there can be no variant). We +% special case commands |#1| starting with |\::|, namely weird +% functions named |\::N| and the like. +% \begin{macrocode} +\cs_new_protected:Npn \@@_names_parse: + { + \tl_clear:N \l_@@_names_block_tl + \seq_map_function:NN + \l_@@_names_seq + \@@_names_parse_one:n + } +\cs_new_protected:Npn \@@_names_parse_one:n #1 + { + \@@_split_function_do:nn {#1} + { \@@_names_parse_one_aux:nnNn } + {#1} + } +\cs_new_protected:Npn \@@_names_parse_one_aux:nnNn #1#2#3#4 + { + \bool_if:NTF #3 + { + \tl_if_head_eq_charcode:nNTF {#2} : + { \@@_names_parse_aux:nnn {#4} {#4} { \scan_stop: } } + { + \exp_args:Nx \@@_names_parse_aux:nnn + { \@@_base_form_aux:nnN {#1} {#2} #3 } + {#1} {#2} + } + } + { + \bool_if:NT \l_@@_macro_TF_bool + { \msg_error:nnx { l3doc } { no-signature-TF } {#4} } + \@@_names_parse_aux:nnn {#4} {#4} { \scan_stop: } + } + } +\cs_new_protected:Npn \@@_names_parse_aux:nnn #1 + { \exp_args:Nc \@@_names_parse_aux:Nnn { \@@_lseq_name:n {#1} } } +\cs_new_protected:Npn \@@_names_parse_aux:Nnn #1#2#3 + { + \tl_if_in:NnF \l_@@_names_block_tl {#1} + { + \tl_put_right:Nn \l_@@_names_block_tl {#1} + \seq_clear_new:N #1 + \seq_put_right:Nn #1 {#2} + } + \seq_put_right:Nn #1 {#3} + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\@@_names_typeset:} +% \begin{macro}[aux]{\@@_names_typeset_auxi:n} +% This code is in particular used when typesetting function names in a +% \env{function} environment. The mapping to \cs{l_@@_names_block_tl} +% cannot use \cs{tl_map_inline:Nn} because the code following |\\| +% would not be expandable, thus breaking \tn{bottomrule}. +% +% Call \cs{@@_names_typeset_auxi:n} on each local sequence (which +% holds a set of variants). The first step is to pop the base form +% and change spaces to category other so +% that they get displayed eventually. Then store the variants in +% \cs{g_@@_variants_seq}, remove the first, which will be displayed +% more prominently, and reconstruct the actual name, passing it to +% \cs{@@_names_typeset_auxii:n}. +% \begin{macrocode} +\cs_new_protected:Npn \@@_names_typeset: + { + \tl_map_function:NN \l_@@_names_block_tl + \@@_names_typeset_auxi:n + } +\cs_new_protected:Npn \@@_names_typeset_auxi:n #1 + { + \seq_pop:NN #1 \l_@@_tmpa_tl + \tl_gset_eq:NN \g_@@_base_name_tl \l_@@_tmpa_tl + \tl_greplace_all:Nno \g_@@_base_name_tl + { ~ } { \c_catcode_other_space_tl } + \seq_get:NN #1 \l_@@_tmpa_tl + \str_if_eq_x:nnTF { \l_@@_tmpa_tl } { \scan_stop: } + { + \seq_gclear:N \g_@@_variants_seq + \@@_names_typeset_auxii:x { \g_@@_base_name_tl } + } + { + \seq_gset_eq:NN \g_@@_variants_seq #1 + \seq_gpop:NN \g_@@_variants_seq \l_@@_tmpb_tl + \@@_names_typeset_auxii:x + { \g_@@_base_name_tl : \l_@@_tmpb_tl } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[aux] +% {\@@_names_typeset_auxii:n, \@@_names_typeset_auxii:x} +% In case the option |pTF| was given, typeset predicates before the +% |TF| functions. In case the option |noTF| was given, typeset the +% non-|TF| function as well. Pass the relevant boolean in both cases +% to control whether to append |TF|. +% \begin{macrocode} +\cs_new_protected:Npn \@@_names_typeset_auxii:n #1 + { + \bool_if:NT \l_@@_macro_pTF_bool + { + \@@_names_typeset_block:xN + { \@@_predicate_from_base:n {#1} } + \c_false_bool + } + \bool_if:NT \l_@@_macro_noTF_bool + { \@@_names_typeset_block:nN {#1} \c_false_bool } + \@@_names_typeset_block:nN {#1} \l_@@_macro_TF_bool + } +\cs_generate_variant:Nn \@@_names_typeset_auxii:n { x } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\@@_names_typeset_block:nN, \@@_names_typeset_block:xN} +% Names in \env{function} and \env{macro} environments are typeset +% differently. To distinguish the two note that +% \cs{l_@@_nested_macro_int} is at least one when in an \env{macro} +% environment (we assume \env{function} is not nested inside it). A +% block is a function with all its variants. +% \begin{macrocode} +\cs_new_protected:Npn \@@_names_typeset_block:nN + { + \int_compare:nNnTF \l_@@_nested_macro_int = 0 + { \@@_typeset_function_block:nN } + { \@@_macro_typeset_block:nN } } +\cs_generate_variant:Nn \@@_names_typeset_block:nN { x } % \end{macrocode} % \end{macro} % @@ -1585,20 +2116,24 @@ Do not distribute a modified version of this file. % \begin{macrocode} \keys_define:nn { l3doc/function } { + TF .value_forbidden:n = true , TF .code:n = { \bool_set_true:N \l_@@_macro_TF_bool } , + EXP .value_forbidden:n = true , EXP .code:n = { \bool_set_true:N \l_@@_macro_EXP_bool \bool_set_false:N \l_@@_macro_rEXP_bool } , + rEXP .value_forbidden:n = true , rEXP .code:n = { \bool_set_false:N \l_@@_macro_EXP_bool \bool_set_true:N \l_@@_macro_rEXP_bool } , + pTF .value_forbidden:n = true , pTF .code:n = { \bool_set_true:N \l_@@_macro_pTF_bool @@ -1606,13 +2141,43 @@ Do not distribute a modified version of this file. \bool_set_true:N \l_@@_macro_EXP_bool \bool_set_false:N \l_@@_macro_rEXP_bool } , + noTF .value_forbidden:n = true , + noTF .code:n = + { + \bool_set_true:N \l_@@_macro_noTF_bool + \bool_set_true:N \l_@@_macro_TF_bool + } , added .tl_set:N = \l_@@_date_added_tl , updated .tl_set:N = \l_@@_date_updated_tl , + deprecated .code:n = { \@@_deprecated_on:n {#1} } , tested .code:n = { } , - no-label .bool_set:N = \l_@@_no_label_bool , + label .code:n = + { + \clist_set:Nn \l_@@_function_label_clist {#1} + \bool_set_true:N \l_@@_no_label_bool + } , + verb .value_forbidden:n = true , + verb .bool_set:N = \l_@@_names_verb_bool , + module .tl_set:N = \l_@@_override_module_tl , } % \end{macrocode} % +% \begin{macro}[aux]{\@@_deprecated_on:n} +% Complain if a deprecated function should have been removed earlier. +% In any case, mark it as internal to suppress the text +% \enquote{documented on page \ldots{}}. +% \begin{macrocode} +\cs_new_protected:Npn \@@_deprecated_on:n #1 + { + \@@_date_compare:nNnT {#1} < { \tex_year:D / \tex_month:D / \tex_day:D } + { + \msg_error:nnxx { l3doc } { deprecated-function } + { \tl_to_str:N \l_@@_macro_argument_tl } {#1} + } + \bool_set_true:N \l_@@_macro_internal_bool + } +% \end{macrocode} +% \end{macro} % % \begin{macro}[int]{\@@_function:nnw} % \begin{arguments} @@ -1626,7 +2191,7 @@ Do not distribute a modified version of this file. % Initialize some variables. Parse the key--value list. Clean up the % list of functions, then go through them to extract some data. After % this, typeset the function names in the coffin -% \cs{l_@@_names_coffin} and measure it to know if it fits in the +% \cs{l_@@_functions_coffin} and measure it to know if it fits in the % margin. Finally, start a vertical coffin for the main part of the % environment. This coffin stops when the environment ends, then all % the pieces are assembled into a single coffin, which is typeset. @@ -1635,13 +2200,15 @@ Do not distribute a modified version of this file. { \@@_function_typeset_start: \@@_function_init: + \tl_set:Nn \l_@@_macro_argument_tl {#2} \keys_set:nn { l3doc/function } {#1} - \@@_verb_get_seq:nN {#2} \l_@@_function_input_seq - \@@_function_parse: + \@@_names_get_seq:nN {#2} \l_@@_names_seq + \@@_names_parse: \@@_function_typeset: + \@@_function_reset: \@@_function_descr_start:w } -\cs_new_protected_nopar:Npn \@@_function_end: +\cs_new_protected:Npn \@@_function_end: { \@@_function_descr_stop: \@@_function_assemble: @@ -1658,12 +2225,11 @@ Do not distribute a modified version of this file. % scene. Further code typesets a coffin, so we end the paragraph and % allow a page break. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_function_typeset_start: +\cs_new_protected:Npn \@@_function_typeset_start: { \par \bigskip \noindent - \phantomsection } -\cs_new_protected_nopar:Npn \@@_function_typeset_stop: +\cs_new_protected:Npn \@@_function_typeset_stop: { \par \allowbreak @@ -1682,102 +2248,46 @@ Do not distribute a modified version of this file. \coffin_clear:N \l_@@_descr_coffin \box_gclear:N \g_@@_syntax_box \coffin_clear:N \l_@@_syntax_coffin - \coffin_clear:N \l_@@_names_coffin + \coffin_clear:N \l_@@_functions_coffin \bool_set_false:N \l_@@_macro_TF_bool \bool_set_false:N \l_@@_macro_pTF_bool + \bool_set_false:N \l_@@_macro_noTF_bool \bool_set_false:N \l_@@_macro_EXP_bool \bool_set_false:N \l_@@_macro_rEXP_bool \bool_set_false:N \l_@@_no_label_bool + \bool_set_false:N \l_@@_names_verb_bool + \clist_clear:N \l_@@_function_label_clist + \tl_set:Nn \l_@@_override_module_tl { \q_no_value } \char_set_catcode_active:N \< - \cs_set_protected_nopar:Npn < ##1 > { \meta {##1} } + \cs_set_protected:Npn < ##1 > { \meta {##1} } } \group_end: % \end{macrocode} % \end{macro} % -% \begin{macro}[aux] -% { -% \@@_function_parse:, -% \@@_function_parse_one:n, -% \@@_function_parse_cs_aux:nnN -% } -% The idea here is to populate \cs{l_@@_functions_block_prop} with -% information about the functions being typeset and their variants. -% The property list uses a specific format: the keys contained are the -% function \enquote{names} (stripped of signature) with values -% specified by a comma-separated list of (braced) signatures: -% \begin{center} -% |> {my_function} => {| \meta{sig_1} |,| \meta{sig_2} |, ... }| -% \end{center} -% In the case where the function has no signature (no colon), we use -% a \meta{sig} equal to \cs{scan_stop:}. -% This somewhat arcane syntax is chosen to distinguish between all -% variants of control sequence that may be being documented -% here. (With or without \pkg{expl3} function syntax.) -% -% If |#1| does not start with |\| then the \enquote{name prefix} is -% empty and we store \cs{scan_stop:} as the value for the key |#1|, not -% bothering with variants. If instead |#1| starts with |\| then the -% \enquote{name prefix} is |\| and we omit the first character of |#1| -% subsequently. If the next character is |:| then we have one of the -% weird functions named |\::N| and so on, and we ignore variants, -% putting \cs{scan_stop:} directly as the value for the key |::N|. -% Otherwise, we have a regular control sequence, which we decompose -% using \cs{@@_function_parse_cs_aux:nnN}. -% \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_function_parse: - { - \seq_map_function:NN - \l_@@_function_input_seq - \@@_function_parse_one:n - } -\cs_new_protected:Npn \@@_function_parse_one:n #1 - { - \tl_if_head_eq_charcode:nNTF {#1} \c_@@_backslash_token - { - \tl_gset_eq:NN \g_@@_function_name_prefix_tl \c_@@_backslash_tl - \exp_args:No \tl_if_head_eq_charcode:nNTF { \use_none:n #1 } : - { - \prop_put:Nxn \l_@@_functions_block_prop - { \use_none:n #1 } { \scan_stop: } - } - { - \exp_args:Nc \__cs_split_function:NN { \use_none:n #1 } - \@@_function_parse_cs_aux:nnN - } - } - { - \tl_gclear:N \g_@@_function_name_prefix_tl - \prop_put:Nnn \l_@@_functions_block_prop {#1} { \scan_stop: } - } - } -\cs_new_protected:Npn \@@_function_parse_cs_aux:nnN #1#2#3 +% \begin{macro}[aux]{\@@_function_reset:} +% Clear some variables. +% \begin{macrocode} +\cs_new_protected:Npn \@@_function_reset: { - \prop_get:NnNF - \l_@@_functions_block_prop {#1} \l_@@_tmpb_tl - { \tl_clear:N \l_@@_tmpb_tl } - \prop_put:Nnx \l_@@_functions_block_prop {#1} - { - \l_@@_tmpb_tl , - \bool_if:NTF #3 { {#2} } { \scan_stop: } - } + \tl_set:Nn \l_@@_override_module_tl { \q_no_value } } % \end{macrocode} % \end{macro} % % \begin{macro}[aux]{\@@_function_typeset:} -% Typeset in the coffin \cs{l_@@_names_coffin} the functions listed in -% \cs{l_@@_functions_block_prop} and the relevant dates, then set +% Typeset in the coffin \cs{l_@@_functions_coffin} the functions listed in +% \cs{l_@@_names_block_tl} and the relevant dates, then set % \cs{l_@@_long_name_bool} to be \texttt{true} if this coffin is % larger than the available width in the margin. The function -% \cs{@@_typeset_names:} is quite involved hence given later. +% \cs{@@_typeset_functions:} is quite involved hence given later. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_function_typeset: +\cs_new_protected:Npn \@@_function_typeset: { \dim_zero:N \l_@@_trial_width_dim - \hcoffin_set:Nn \l_@@_names_coffin { \@@_typeset_names: } + \hcoffin_set:Nn \l_@@_functions_coffin { \@@_typeset_functions: } \dim_set:Nn \l_@@_trial_width_dim - { \box_wd:N \l_@@_names_coffin } + { \box_wd:N \l_@@_functions_coffin } \bool_set:Nn \l_@@_long_name_bool { \dim_compare_p:nNn \l_@@_trial_width_dim > \marginparwidth } } @@ -1792,12 +2302,12 @@ Do not distribute a modified version of this file. % \env{function} environment. This is closed by \cs{@@_function_end:} % (the end of a \env{function} environment). % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_function_descr_start:w +\cs_new_protected:Npn \@@_function_descr_start:w { \vcoffin_set:Nnw \l_@@_descr_coffin { \textwidth } \noindent \ignorespaces } -\cs_new_protected_nopar:Npn \@@_function_descr_stop: +\cs_new_protected:Npn \@@_function_descr_stop: { \vcoffin_set_end: } % \end{macrocode} % \end{macro} @@ -1809,7 +2319,7 @@ Do not distribute a modified version of this file. % coffin. The relative positions depend on whether the names coffin % fits in the margin. Then typeset the combination. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_function_assemble: +\cs_new_protected:Npn \@@_function_assemble: { \hcoffin_set:Nn \l_@@_syntax_coffin { \box_use:N \g_@@_syntax_box } @@ -1821,7 +2331,7 @@ Do not distribute a modified version of this file. {0pt} {0pt} \coffin_join:NnnNnnnn \l_@@_output_coffin {l} {t} - \l_@@_names_coffin {r} {t} + \l_@@_functions_coffin {r} {t} {-\marginparsep} {0pt} \coffin_join:NnnNnnnn \l_@@_output_coffin {l} {b} @@ -1842,7 +2352,7 @@ Do not distribute a modified version of this file. {0pt} {-\medskipamount} \coffin_join:NnnNnnnn \l_@@_output_coffin {l} {t} - \l_@@_names_coffin {r} {t} + \l_@@_functions_coffin {r} {t} {-\marginparsep} {0pt} \coffin_typeset:Nnnnn \l_@@_output_coffin {\l_@@_syntax_coffin-l} {\l_@@_syntax_coffin-T} @@ -1852,20 +2362,24 @@ Do not distribute a modified version of this file. % \end{macrocode} % \end{macro} % -% \begin{macro}[aux]{\@@_typeset_names:} -% This function builds the \cs{l_@@_names_coffin} by typesetting the +% \begin{macro}[aux]{\@@_typeset_functions:} +% This function builds the \cs{l_@@_functions_coffin} by typesetting the % function names (with variants) and the relevant dates in a % \env{tabular} environment. The use of rules \tn{toprule}, % \tn{midrule} and \tn{bottomrule} requires whatever lies between the % last |\\| and the rule to be expandable, making our lives a bit % complicated. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_typeset_names: +\cs_new_protected:Npn \@@_typeset_functions: { \small\ttfamily - \begin{tabular} { @{} l @{} r @{} } + \HD@savedestfalse + \HD@target + \Hy@MakeCurrentHref { HD. \int_use:N \c@HD@hypercount } + \begin{tabular} [t] { @{} l @{} >{\hspace{\tabcolsep}} r @{} } \toprule - \@@_typeset_functions: + \@@_function_extra_labels: + \@@_names_typeset: \@@_typeset_dates: \bottomrule \end{tabular} @@ -1874,152 +2388,54 @@ Do not distribute a modified version of this file. % \end{macrocode} % \end{macro} % -% \begin{macro}[aux]{\@@_typeset_functions:} -% \begin{macro}[aux] -% {\@@_typeset_functions_auxi:nn, \@@_typeset_functions_auxii:nn} -% \begin{arguments} -% \item Function/macro/variable name (stripped of signature in the -% first case, if any) -% \item Comma-list containing information about the signature -% variants being documented (if any) -% \end{arguments} -% The mapping to \cs{l_@@_functions_block_prop} cannot use -% \cs{prop_map_inline:Nn} because the code following |\\| would not be -% expandable, thus breaking \tn{bottomrule}. The loop goes as -% follows: go through the list of variants |#2|, and collect them by -% \enquote{base form} in a \cs{l_@@_variants_prop} whose keys are the -% base form and whose values are the variants which can be obtained -% from that base form using \cs{cs_generate_variant:Nn}. Then start a -% nested loop through these base forms, calling -% \cs{@@_typeset_functions_auxii:nn}. This auxiliary does not care -% about the base form. It stores the variants it receives in -% \cs{g_@@_variants_clist}, remove the first, which will be displayed -% more prominently, and reconstructs its actual name, passing it to -% the \cs{@@_typeset_functions_auxiii:N} auxiliary. -% -% Braces around |##1| are crucial since this item can be empty. -% \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_typeset_functions: - { - \prop_map_function:NN \l_@@_functions_block_prop - \@@_typeset_functions_auxi:nn - } -\cs_new_protected:Npn \@@_typeset_functions_auxi:nn #1#2 - { - \tl_gset:Nn \g_@@_base_name_tl {#1} - \prop_clear:N \l_@@_variants_prop - \clist_map_inline:nn {#2} - { - \tl_set:Nx \l_@@_tmpa_tl - { \@@_signature_base_form:n {##1} } - \prop_get:NoNTF \l_@@_variants_prop - \l_@@_tmpa_tl \l_@@_tmpb_tl - { \tl_put_right:Nn \l_@@_tmpb_tl { , {##1} } } - { \tl_set:Nn \l_@@_tmpb_tl { {##1} } } - \prop_put:Noo \l_@@_variants_prop - \l_@@_tmpa_tl \l_@@_tmpb_tl - } - \prop_map_function:NN \l_@@_variants_prop - \@@_typeset_functions_auxii:nn - } -\cs_new_protected:Npn \@@_typeset_functions_auxii:nn #1#2 - { - \clist_gset:Nn \g_@@_variants_clist {#2} - \clist_gpop:NN \g_@@_variants_clist \l_@@_tmpb_tl - \exp_args:Nc \@@_typeset_functions_auxiii:N - { - \g_@@_base_name_tl - \exp_last_unbraced:Nf \token_if_eq_meaning:NNF - { \tl_head:f { \l_@@_tmpb_tl ? } } - \scan_stop: - { : \l_@@_tmpb_tl } - } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}[aux]{\@@_typeset_functions_auxiii:N} +% ^^A TODO: collect all index targets from a given function environment in a box and stick it at the top. +% \begin{macro}[int] +% {\@@_typeset_function_block:nN, \@@_typeset_function_block:xN} +% \begin{macro}[aux]{\@@_function_index:n, \@@_function_index:x} +% |#1| is a csname, |#2| a boolean indicating whether to add |TF| or not. % \begin{macrocode} -\cs_new_protected:Npn \@@_typeset_functions_auxiii:N #1 +\cs_new_protected:Npn \@@_typeset_function_block:nN #1#2 { - \bool_if:NT \l_@@_macro_pTF_bool - { - \tl_set:Nx \l_@@_pTF_name_tl - { \@@_predicate_from_base:N #1 } - \@@_function_index:x { \l_@@_pTF_name_tl } - } \@@_function_index:x - { - \cs_to_str:N #1 - \bool_if:NT \l_@@_macro_TF_bool { \tl_to_str:n {TF} } - } - \bool_if:NT \l_@@_macro_pTF_bool - { - \exp_args:Nc \@@_typeset_function_block:NN - { \l_@@_pTF_name_tl } \c_false_bool - } - \@@_typeset_function_block:NN #1 \l_@@_macro_TF_bool - } -\cs_new_protected:Npn \@@_function_index:x #1 - { - \tl_set:Nx \l_@@_tmpa_tl - { \g_@@_function_name_prefix_tl #1 } - \seq_gput_right:No \g_doc_functions_seq { \l_@@_tmpa_tl } - \@@_special_index:on { \l_@@_tmpa_tl } { usage } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[internal]{\@@_typeset_function_block:NN} -% The first argument is a control sequence, the second a boolean which -% controls whether to typeset |TF| or not. -% \begin{macrocode} -\cs_new_protected:Npn \@@_typeset_function_block:NN #1#2 - { - \@@_function_label:x - { \g_@@_function_name_prefix_tl \cs_to_str:N #1 } - \g_@@_function_name_prefix_tl \cs_to_str:N #1 + { #1 \bool_if:NT #2 { \tl_to_str:n {TF} } } + \@@_function_label:xN {#1} #2 + #1 \bool_if:NT #2 { \@@_typeset_TF: } \@@_typeset_expandability: - \clist_if_empty:NF \g_@@_variants_clist - { \@@_typeset_variant_list:NN #1#2 } + \seq_if_empty:NF \g_@@_variants_seq + { \@@_typeset_variant_list:nN {#1} #2 } \\ } +\cs_generate_variant:Nn \@@_typeset_function_block:nN { x } +\cs_new_protected:Npn \@@_function_index:n #1 + { + \seq_gput_right:Nn \g_doc_functions_seq {#1} + \@@_special_index:nn {#1} { usage } + } +\cs_generate_variant:Nn \@@_function_index:n { x } % \end{macrocode} % % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_typeset_expandability: +\cs_new_protected:Npn \@@_typeset_expandability: { & - \bool_if:NT \l_@@_macro_EXP_bool - { - \hspace{\tabcolsep} - \hyperlink{expstar} {$\star$} - } - \bool_if:NT \l_@@_macro_rEXP_bool - { - \hspace{\tabcolsep} - \hyperlink{rexpstar} {\ding{73}} % hollow star - } + \bool_if:NT \l_@@_macro_EXP_bool { \@@_typeset_exp: } + \bool_if:NT \l_@@_macro_rEXP_bool { \@@_typeset_rexp: } } % \end{macrocode} % +% |#1| is the function, |#2| whether to add |TF|. % \begin{macrocode} -\cs_new_protected:Npn \@@_typeset_variant_list:NN #1#2 +\cs_new_protected:Npn \@@_typeset_variant_list:nN #1#2 { \\ - \@@_typeset_aux:n - { - \g_@@_function_name_prefix_tl - \__cs_get_function_name:N #1 - } + \@@_typeset_aux:n { \@@_get_function_name:n {#1} } : - \int_compare:nTF { \clist_count:N \g_@@_variants_clist == 1 } - { \clist_use:Nn \g_@@_variants_clist { } } + \int_compare:nTF { \seq_count:N \g_@@_variants_seq == 1 } + { \seq_use:Nn \g_@@_variants_seq { } } { \textrm( - \clist_use:Nn \g_@@_variants_clist { \textrm| } + \seq_use:Nn \g_@@_variants_seq { \textrm| } \textrm) } \bool_if:NT #2 { \@@_typeset_TF: } @@ -2027,30 +2443,44 @@ Do not distribute a modified version of this file. } % \end{macrocode} % -% TODO: understand whether we need one more boolean to only -% put labels if the whole document is typeset. +% |#1| is the function name, |#2| whether to add |TF|. % \begin{macrocode} -\cs_new_protected:Npn \@@_function_label:n #1 +\cs_new_protected:Npn \@@_function_extra_labels: + { + \bool_if:NT \l_@@_no_label_bool + { + \clist_map_inline:Nn \l_@@_function_label_clist + { + \@@_get_hyper_target:oN { \token_to_str:N ##1 } + \l_@@_tmpa_tl + \exp_args:No \label { \l_@@_tmpa_tl } + } + } + } +\cs_new_protected:Npn \@@_function_label:nN #1#2 { - % \bool_if:NT \g_@@_typeset_implementation_bool - % { \bool_if:NF \l_@@_no_label_bool { - \@@_get_hyper_target:nN {#1} \l_@@_tmpa_tl + \@@_get_hyper_target:xN + { + \exp_not:n {#1} + \bool_if:NT #2 { \tl_to_str:n {TF} } + } + \l_@@_tmpa_tl \exp_args:No \label { \l_@@_tmpa_tl } } - % } } -\cs_generate_variant:Nn \@@_function_label:n { x } +\cs_generate_variant:Nn \@@_function_label:nN { x } % \end{macrocode} % \end{macro} +% \end{macro} % % \begin{macro}[internal]{\@@_typeset_dates:} % To display metadata for when functions are added/modified. % This function must be expandable since it produces rules for use in % alignments. % \begin{macrocode} -\cs_new_nopar:Npn \@@_typeset_dates: +\cs_new:Npn \@@_typeset_dates: { \bool_if:nF { @@ -2090,7 +2520,7 @@ Do not distribute a modified version of this file. \arrayrulecolor{white} \begin{tabular} { @{} l @{} } \toprule - \begin{minipage}{\l_@@_syntax_dim} + \begin{minipage}[t]{\l_@@_syntax_dim} \raggedright \obeyspaces \obeylines @@ -2107,22 +2537,27 @@ Do not distribute a modified version of this file. % % \subsubsection{The \env{macro} environment} % -% Keyval for the \env{macro} environment. TODO: use -% |.value_forbidden:|. TODO: provide document command for talking about -% keys. +% Keyval for the \env{macro} environment. +% TODO: provide document command for documenting keys. % \begin{macrocode} \keys_define:nn { l3doc/macro } { + aux .value_forbidden:n = true , aux .code:n = { \bool_set_true:N \l_@@_macro_aux_bool } , + internal .value_forbidden:n = true , internal .code:n = { \bool_set_true:N \l_@@_macro_internal_bool } , + int .value_forbidden:n = true , int .code:n = { \bool_set_true:N \l_@@_macro_internal_bool } , + var .value_forbidden:n = true , var .code:n = { \bool_set_true:N \l_@@_macro_var_bool } , + TF .value_forbidden:n = true , TF .code:n = { \bool_set_true:N \l_@@_macro_TF_bool } , + pTF .value_forbidden:n = true , pTF .code:n = { \bool_set_true:N \l_@@_macro_TF_bool @@ -2130,11 +2565,19 @@ Do not distribute a modified version of this file. \bool_set_true:N \l_@@_macro_EXP_bool \bool_set_false:N \l_@@_macro_rEXP_bool } , + noTF .value_forbidden:n = true , + noTF .code:n = + { + \bool_set_true:N \l_@@_macro_TF_bool + \bool_set_true:N \l_@@_macro_noTF_bool + } , + EXP .value_forbidden:n = true , EXP .code:n = { \bool_set_true:N \l_@@_macro_EXP_bool \bool_set_false:N \l_@@_macro_rEXP_bool } , + rEXP .value_forbidden:n = true , rEXP .code:n = { \bool_set_false:N \l_@@_macro_EXP_bool @@ -2146,6 +2589,10 @@ Do not distribute a modified version of this file. } , added .code:n = {} , % TODO updated .code:n = {} , % TODO + deprecated .code:n = { \@@_deprecated_on:n {#1} } , + verb .bool_set:N = \l_@@_names_verb_bool , + module .tl_set:N = \l_@@_override_module_tl , + documented-as .tl_set:N = \l_@@_macro_documented_tl , } % \end{macrocode} % @@ -2154,17 +2601,22 @@ Do not distribute a modified version of this file. % comma-list of \meta{names}, read verbatim by \pkg{xparse}. First % initialize some variables before applying the \meta{options}, then % parse the \meta{names} to get a sequence of macro names, then apply -% \cs{@@_macro_single:n} to each (this step is more subtle than -% \cs{seq_map_function:NN} because of |TF|/|pTF|). Finally typeset +% \cs{@@_macro_single:nNN} to each (this step is more subtle than +% \cs{seq_map_function:NN} because of |TF|/|pTF|/|noTF|). Finally typeset % the macro names in the margin. % \begin{macrocode} \cs_new_protected:Npn \@@_macro:nnw #1#2 { \@@_macro_init: + \tl_set:Nn \l_@@_macro_argument_tl {#2} \keys_set:nn { l3doc/macro } {#1} - \@@_verb_get_seq:nN {#2} \l_@@_macro_input_seq - \@@_macro_map:N \@@_macro_single:n - \@@_macro_typeset: + \@@_names_get_seq:nN {#2} \l_@@_names_seq + \@@_names_parse: + \@@_macro_adjust_internal: + \@@_macro_save_names: + \@@_names_typeset: + \@@_macro_dump: + \@@_macro_reset: } % \end{macrocode} % \end{macro} @@ -2174,56 +2626,98 @@ Do not distribute a modified version of this file. % \cs{l_@@_nested_macro_int} counts the number of \env{macro} % environments around the current point (is $0$ outside). % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_macro_init: +\cs_new_protected:Npn \@@_macro_init: { \int_incr:N \l_@@_nested_macro_int \bool_set_false:N \l_@@_macro_aux_bool \bool_set_false:N \l_@@_macro_internal_bool \bool_set_false:N \l_@@_macro_TF_bool \bool_set_false:N \l_@@_macro_pTF_bool + \bool_set_false:N \l_@@_macro_noTF_bool \bool_set_false:N \l_@@_macro_EXP_bool \bool_set_false:N \l_@@_macro_rEXP_bool \bool_set_false:N \l_@@_macro_var_bool \bool_set_false:N \l_@@_macro_tested_bool + \bool_set_false:N \l_@@_names_verb_bool + \tl_set:Nn \l_@@_override_module_tl { \q_no_value } + \tl_clear:N \l_@@_macro_documented_tl \cs_set_eq:NN \testfile \@@_print_testfile:n \box_clear:N \l_@@_macro_index_box \vbox_set:Nn \l_@@_macro_box { - \hbox:n { \strut } + \hbox:n + { + \strut + \int_compare:nNnT \l_@@_macro_int = \c_zero + { \HD@target } + } \vskip \int_eval:n { \l_@@_macro_int - 1 } \baselineskip } } % \end{macrocode} % \end{macro} % -% \begin{macro}[aux]{\@@_macro_map:N} -% Applies |#1| to all macros. In the |pTF| case, this means going -% twice through the sequence \cs{l_@@_macro_input_seq}, once for the -% predicates and once for the |TF| variants. +% \begin{macro}[aux]{\@@_macro_reset:} +% We ensure that \cs{cs} commands nested inside a macro whose module +% is imposed are not affected. % \begin{macrocode} -\cs_new_protected:Npn \@@_macro_map:N #1 +\cs_new_protected:Npn \@@_macro_reset: { - \bool_if:NT \l_@@_macro_pTF_bool + \tl_set:Nn \l_@@_override_module_tl { \q_no_value } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\@@_macro_adjust_internal:} +% If the macros are neither marked as internal nor auxiliary, and all +% macros in \cs{l_@@_names_seq} contain |__| then mark them as being +% internal. +% \begin{macrocode} +\cs_new_protected:Npn \@@_macro_adjust_internal: + { + \bool_if:NF \l_@@_macro_internal_bool { - \bool_set_false:N \l_@@_macro_TF_bool - \seq_map_inline:Nn \l_@@_macro_input_seq + \bool_if:NF \l_@@_macro_aux_bool { - \tl_set:Nn \l_@@_tmpa_tl {##1} - \tl_replace_once:Noo \l_@@_tmpa_tl - { \tl_to_str:n { : } } { \tl_to_str:n { _p: } } - \exp_args:No #1 \l_@@_tmpa_tl + \bool_set_true:N \l_@@_macro_internal_bool + \seq_map_inline:Nn \l_@@_names_seq + { + \tl_if_in:noF {##1} { \tl_to_str:n { __ } } + { \bool_set_false:N \l_@@_macro_internal_bool } + } + } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\@@_macro_save_names:} +% The list of names defined in a set of \env{macro} environments is +% eventually used to display on which page they are documented. +% \begin{macrocode} +\cs_new_protected:Npn \@@_macro_save_names: + { + \tl_map_inline:Nn \l_@@_names_block_tl + { + \seq_set_eq:NN \l_@@_tmpa_seq ##1 + \seq_pop:NN \l_@@_tmpa_seq \l_@@_tmpa_tl + \seq_get:NN \l_@@_tmpa_seq \l_@@_tmpb_tl + \seq_gput_right:Nx \g_@@_nested_names_seq + { + \l_@@_tmpa_tl + \str_if_eq_x:nnF { \l_@@_tmpb_tl } { \scan_stop: } + { : \l_@@_tmpb_tl } + \bool_if:NT \l_@@_macro_TF_bool { TF } } - \bool_set_true:N \l_@@_macro_TF_bool } - \seq_map_function:NN \l_@@_macro_input_seq #1 } % \end{macrocode} % \end{macro} % -% \begin{macro}[aux]{\@@_macro_typeset:} +% \begin{macro}[aux]{\@@_macro_dump:} % This calls |\makelabel{}| % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_macro_typeset: +\cs_new_protected:Npn \@@_macro_dump: { \topsep\MacroTopsep \trivlist @@ -2244,7 +2738,32 @@ Do not distribute a modified version of this file. % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_macro_single:n} +% \begin{macro}[aux]{\@@_macro_typeset_block:nN} +% Used to typeset a macro and its variants. |#1| is the macro name, +% |#2| is a boolean controlling whether to add |TF|. +% \begin{macrocode} +\cs_new_protected:Npn \@@_macro_typeset_block:nN #1#2 + { + \@@_macro_single:nNN {#1} \c_true_bool #2 + \seq_if_empty:NF \g_@@_variants_seq + { + \@@_macro_typeset_variant_list:xN + { \@@_get_function_name:n {#1} } #2 + } + } +\cs_generate_variant:Nn \@@_macro_typeset_block:nN { x } +\cs_new_protected:Npn \@@_macro_typeset_variant_list:nN #1#2 + { + \seq_map_inline:Nn \g_@@_variants_seq + { \@@_macro_single:nNN { #1 : ##1 } \c_false_bool #2 } + } +\cs_generate_variant:Nn \@@_macro_typeset_variant_list:nN { x } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_macro_single:nNN} +% The arguments are |#1| a macro name (without |TF|), |#2| a boolean +% determining whether or not to index, and |#3| whether or not to add |TF|. % Let's start to mess around with \cls{doc}'s \env{macro} environment. % See \file{doc.dtx} for a full explanation of the original % environment. It's rather \emph{enthusiastically} commented. @@ -2255,71 +2774,78 @@ Do not distribute a modified version of this file. % The assignments to \cs{saved@macroname} and \cs{saved@indexname} % are used by \pkg{doc}'s \cs{changes} mechanism. % \begin{macrocode} -\cs_new_protected:Npn \@@_macro_single:n #1 +\cs_new_protected:Npn \@@_macro_single:nNN #1#2#3 { \tl_set:Nn \saved@macroname {#1} - \@@_macro_typeset_one:n {#1} - \exp_args:Nx \@@_macro_index:n - { - #1 - \bool_if:NT \l_@@_macro_TF_bool { \tl_to_str:n { TF } } - } + \@@_macro_typeset_one:nN {#1} #3 + \bool_if:NT #3 { \DoNotIndex {#1} } + \exp_args:Nx \@@_macro_index:nN + { #1 \bool_if:NT #3 { \tl_to_str:n { TF } } } + #2 } -\cs_new_protected:Npn \@@_macro_index:n #1 +\cs_new_protected:Npn \@@_macro_index:nN #1#2 { - \bool_if:NF \l_@@_macro_aux_bool - { \seq_gput_right:Nn \g_doc_macros_seq {#1} } - \hbox_set:Nw \l_@@_macro_index_box - % This box only contains targets... it seems inefficient. - \hbox_unpack_clear:N \l_@@_macro_index_box - \int_gincr:N \c@CodelineNo - \@@_special_index:nn {#1} { main } - \DoNotIndex {#1} - \int_gdecr:N \c@CodelineNo - \exp_args:NNNo \hbox_set_end: - \tl_set:Nn \saved@indexname { \l_@@_index_key_tl } + \DoNotIndex {#1} + \bool_if:NT #2 + { + \bool_if:NF \l_@@_macro_aux_bool + { \seq_gput_right:Nn \g_doc_macros_seq {#1} } + \hbox_set:Nw \l_@@_macro_index_box + \hbox_unpack_clear:N \l_@@_macro_index_box + \int_gincr:N \c@CodelineNo + \@@_special_index:nn {#1} { main } + \int_gdecr:N \c@CodelineNo + \exp_args:NNNo \hbox_set_end: + \tl_set:Nn \saved@indexname { \l_@@_index_key_tl } + } } % \end{macrocode} % \end{macro} % -% \begin{macro}[aux]{\@@_macro_typeset_one:n} +% \begin{macro}[aux]{\@@_macro_typeset_one:nN} % For a long time, \cls{l3doc} collected the macro names as labels in % the first items of nested \tn{trivlist}, but these were not closed % properly with \tn{endtrivlist}. Also, it interacted in surprising % ways with \pkg{hyperref} targets. Now, we collect typeset macro % names by hand in the box \cs{l_@@_macro_box}. Note the space |\ |. +% |#1| is the macro name, |#2| whether to add |TF|. % \begin{macrocode} -\cs_new_protected:Npn \@@_macro_typeset_one:n #1 +\cs_new_protected:Npn \@@_macro_typeset_one:nN #1#2 { \vbox_set:Nn \l_@@_macro_box { \vbox_unpack_clear:N \l_@@_macro_box - \hbox { \llap { \@@_print_macroname:n {#1} \ } } + \hbox { \llap { \@@_print_macroname:nN {#1} #2 \ } } } \int_incr:N \l_@@_macro_int } % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_print_macroname:n} +% \begin{macro}{\@@_print_macroname:nN} +% In the name, spaces are replaced by other spaces to ensure they get +% displayed in case there are any. % \begin{macrocode} -\cs_new_protected:Npn \@@_print_macroname:n #1 +\cs_new_protected:Npn \@@_print_macroname:nN #1#2 { \strut - \HD@target - - % TODO: INEFFICIENT(!) - \exp_args:NNx \seq_if_in:NnTF \g_doc_functions_seq - { #1 \bool_if:NT \l_@@_macro_TF_bool { \tl_to_str:n {TF} } } + \@@_get_hyper_target:xN { - \@@_get_hyper_target:nN {#1} \l_@@_tmpa_tl - \exp_last_unbraced:NNo \hyperref [ \l_@@_tmpa_tl ] + \exp_not:n {#1} + \bool_if:NT #2 { \tl_to_str:n {TF} } } + \l_@@_tmpa_tl + \cs_if_exist:cTF { r@ \l_@@_tmpa_tl } + { \exp_last_unbraced:NNo \hyperref [ \l_@@_tmpa_tl ] } { \use:n } { - \int_compare:nTF { \tl_count:n {#1} <= 28 } + \int_compare:nTF { \str_count:n {#1} <= 28 } { \MacroFont } { \MacroLongFont } - \@@_macroname_prefix:n {#1} \@@_macroname_suffix: + \tl_set:Nn \l_@@_tmpa_tl {#1} + \tl_replace_all:Nno \l_@@_tmpa_tl + { ~ } { \c_catcode_other_space_tl } + \@@_macroname_prefix:o \l_@@_tmpa_tl + \@@_macroname_suffix:N #2 } } \cs_new_protected:Npn \@@_macroname_prefix:n #1 @@ -2327,8 +2853,9 @@ Do not distribute a modified version of this file. \bool_if:NTF \l_@@_macro_aux_bool { \@@_typeset_aux:n {#1} } {#1} } -\cs_new_protected_nopar:Npn \@@_macroname_suffix: - { \bool_if:NTF \l_@@_macro_TF_bool { \@@_typeset_TF: } { } } +\cs_generate_variant:Nn \@@_macroname_prefix:n { o } +\cs_new_protected:Npn \@@_macroname_suffix:N #1 + { \bool_if:NTF #1 { \@@_typeset_TF: } { } } % \end{macrocode} % \end{macro} % @@ -2401,23 +2928,24 @@ Do not distribute a modified version of this file. % % \begin{macro}[aux]{\@@_test_missing:n} % Keys in \cs{g_@@_missing_tests_prop} are lists of macros given as -% arguments of one \env{macro} environment. Values are comma lists of -% filenames (Bruno thinks). +% arguments of one \env{macro} environment. Values are pairs of a +% file name and a comment about the missing tests. % \begin{macrocode} \cs_new_protected:Npn \@@_test_missing:n #1 { - \tl_set:Nx \l_@@_tmpb_tl - { \seq_use:Nn \l_@@_macro_input_seq { , } } - \prop_if_in:NVTF \g_@@_missing_tests_prop \l_@@_tmpb_tl - { - \prop_get:NVN \g_@@_missing_tests_prop \l_@@_tmpb_tl - \l_@@_tmpa_tl - } - { \tl_clear:N \l_@@_tmpa_tl } - \clist_set:Nx \l_@@_tmpa_clist { \l_@@_tmpa_tl , #1 } - \prop_gput:NVV \g_@@_missing_tests_prop \l_@@_tmpb_tl - \l_@@_tmpa_clist + \@@_test_missing_aux:Nxn + \g_@@_missing_tests_prop + { \seq_use:Nn \l_@@_names_seq { , } } + { { \g_file_current_name_tl \iow_char:N \ (#1) } } + } +\cs_new_protected:Npn \@@_test_missing_aux:Nnn #1#2#3 + { + \prop_get:NnNTF #1 {#2} \l_@@_tmpa_tl + { \tl_put_right:Nn \l_@@_tmpa_tl { , #3 } } + { \tl_set:Nn \l_@@_tmpa_tl {#3} } + \prop_put:Nno #1 {#2} \l_@@_tmpa_tl } +\cs_generate_variant:Nn \@@_test_missing_aux:Nnn { Nx } % \end{macrocode} % \end{macro} % @@ -2435,11 +2963,8 @@ Do not distribute a modified version of this file. \@@_macro_end_check_tested: \int_compare:nNnT \l_@@_nested_macro_int = 1 { - \@@_macro_end_style:n - { - \@@_print_end_definition: - \@@_print_documented: - } + \@@_macro_end_style:n { \@@_print_end_definition: } + \seq_gclear:N \g_@@_nested_names_seq } } % \end{macrocode} @@ -2450,7 +2975,7 @@ Do not distribute a modified version of this file. % auxiliary nor a variable (and it does not have a test), then add it % to the sequence of non-tested macros. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_macro_end_check_tested: +\cs_new_protected:Npn \@@_macro_end_check_tested: { \bool_if:nT { @@ -2462,7 +2987,7 @@ Do not distribute a modified version of this file. { \seq_gput_right:Nx \g_@@_not_tested_seq { - \seq_use:Nn \l_@@_macro_input_seq { , } + \seq_use:Nn \l_@@_names_seq { , } \bool_if:NTF \l_@@_macro_pTF_bool {~(pTF)} { \bool_if:NT \l_@@_macro_TF_bool {~(TF)} } } @@ -2486,45 +3011,38 @@ Do not distribute a modified version of this file. % \begin{macro}[aux] % { % \@@_print_end_definition:, -% \@@_macro_end_wrap_items:N, +% \@@_macro_end_wrap_item:n, % \@@_print_documented: % } -% Surround each item by \tn{texttt} and |TF| if needed, replacing |_| +% Surround each item by \tn{texttt}, replacing |_| % by \tn{_} as well. Then list the % macro names through \cs{seq_use:Nnnn}, unless there are too many. % Finally, if the macro is neither auxiliary nor internal, add a link % to where it is documented. % \begin{macrocode} -\cs_new_protected:Npn \@@_macro_end_wrap_items:N #1 +\cs_new_protected:Npn \@@_macro_end_wrap_item:n #1 { - \bool_if:NT \l_@@_macro_TF_bool - { \seq_set_map:NNn #1 #1 { ##1 TF } } - \seq_set_map:NNn #1 #1 - { - \exp_not:n - { - \tl_set:Nn \l_@@_tmpa_tl {##1} - \tl_replace_all:Non \l_@@_tmpa_tl - { \token_to_str:N _ } { \_ } - \texttt { \l_@@_tmpa_tl } - } - } + \tl_set:Nn \l_@@_tmpa_tl {#1} + \tl_replace_all:Non \l_@@_tmpa_tl + { \token_to_str:N _ } { \_ } + \texttt { \l_@@_tmpa_tl } } -\cs_new_protected_nopar:Npn \@@_print_end_definition: +\cs_new_protected:Npn \@@_print_end_definition: { - \group_begin: - \@@_macro_end_wrap_items:N \l_@@_macro_input_seq + \seq_set_map:NNn \l_@@_tmpa_seq + \g_@@_nested_names_seq + { \exp_not:n { \@@_macro_end_wrap_item:n {##1} } } End~ definition~ for~ - \int_compare:nTF { \seq_count:N \l_@@_macro_input_seq <= 3 } + \int_compare:nTF { \seq_count:N \l_@@_tmpa_seq <= 3 } { - \seq_use:Nnnn \l_@@_macro_input_seq + \seq_use:Nnnn \l_@@_tmpa_seq { \,~and~ } { \,,~ } { \,,~and~ } - \@. } - { \seq_item:Nn \l_@@_macro_input_seq {1}\,~and~others. } - \group_end: + { \seq_item:Nn \l_@@_tmpa_seq {1}\,~and~others } + \@. + \@@_print_documented: } -\cs_new_protected_nopar:Npn \@@_print_documented: +\cs_new_protected:Npn \@@_print_documented: { \bool_if:nT { @@ -2533,13 +3051,25 @@ Do not distribute a modified version of this file. } { \int_set:Nn \l_@@_tmpa_int - { \seq_count:N \l_@@_macro_input_seq } + { \seq_count:N \g_@@_nested_names_seq } + \tl_if_empty:NTF \l_@@_macro_documented_tl + { + \tl_set:Nx \l_@@_macro_documented_tl + { \seq_item:Nn \g_@@_nested_names_seq { 1 } } + } + { + \tl_set:Nf \l_@@_macro_documented_tl + { + \exp_after:wN \token_to_str:N + \l_@@_macro_documented_tl + } + } \int_compare:nNnTF \l_@@_tmpa_int = 1 {~This~} {~These~} \bool_if:NTF \l_@@_macro_var_bool {variable} {function} \int_compare:nNnTF \l_@@_tmpa_int = 1 {~is~} {s~are~} documented~on~page~ - \exp_args:Nx \@@_get_hyper_target:nN - { \seq_item:Nn \l_@@_macro_input_seq { 1 } } + \@@_get_hyper_target:oN + \l_@@_macro_documented_tl \l_@@_tmpa_tl \exp_args:Nx \pageref { \l_@@_tmpa_tl } . } @@ -2547,51 +3077,6 @@ Do not distribute a modified version of this file. % \end{macrocode} % \end{macro} % -% \subsubsection{Common between \env{macro} and \env{function}} -% -% \begin{macro}{\@@_typeset_TF:, \@@_typeset_aux:n} -% Used by \cs{@@_macro_single:n} and in the \env{function} environment -% to typeset conditionals and auxiliary functions. -% \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_typeset_TF: - { - \hyperlink{explTF} - { - \color{black} - \itshape TF - \makebox[0pt][r] - { - \color{red} - \underline { \phantom{\itshape TF} \kern-0.1em } - } - } - } -\cs_new_protected:Npn \@@_typeset_aux:n #1 - { - { \color[gray]{0.7} #1 } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_get_hyper_target:nN} -% Create a \pkg{hyperref} anchor from a macro name~|#1| and stores it -% in the token list variable~|#2|. For instance, |\prg_replicate:nn| -% gives |doc/function//prg/replicate:nn|. -% \begin{macrocode} -\cs_new_protected:Npn \@@_get_hyper_target:nN #1#2 - { - \tl_set:Nx #2 - { - \tl_to_str:n {#1} - \bool_if:NT \l_@@_macro_TF_bool { \tl_to_str:n {TF} } - } - \tl_replace_all:Nxn #2 { \iow_char:N \_ } { / } - \tl_remove_all:Nx #2 { \iow_char:N \\ } - \tl_put_left:Nn #2 { doc/function// } - } -% \end{macrocode} -% \end{macro} -% % \subsubsection{Misc} % % \begin{macro}{\DescribeOption} @@ -2665,7 +3150,7 @@ Do not distribute a modified version of this file. % The actual character from the font |manfnt|: % \begin{macrocode} \font \manual = manfnt \scan_stop: -\cs_gset_nopar:Npn \dbend { {\manual\char127} } +\cs_gset:Npn \dbend { {\manual\char127} } % \end{macrocode} % % Defines the single danger bend. Use it whenever there is a feature in @@ -2676,7 +3161,7 @@ Do not distribute a modified version of this file. { \begin{trivlist}\item[]\noindent \begingroup\hangindent=2pc\hangafter=-2 - \cs_set_nopar:Npn \par{\endgraf\endgroup} + \cs_set:Npn \par{\endgraf\endgroup} \hbox to0pt{\hskip-\hangindent\dbend\hfill}\ignorespaces } { @@ -2694,7 +3179,7 @@ Do not distribute a modified version of this file. { \begin{trivlist}\item[]\noindent \begingroup\hangindent=3.5pc\hangafter=-2 - \cs_set_nopar:Npn \par{\endgraf\endgroup} + \cs_set:Npn \par{\endgraf\endgroup} \hbox to0pt{\hskip-\hangindent\dbend\kern2pt\dbend\hfill}\ignorespaces }{ \par\end{trivlist} @@ -2851,8 +3336,8 @@ Do not distribute a modified version of this file. \relax\clearpage \docincludeaux \IfFileExists{#1.fdd} - { \cs_set_nopar:Npn \currentfile{#1.fdd} } - { \cs_set_nopar:Npn \currentfile{#1.dtx} } + { \cs_set:Npn \currentfile{#1.fdd} } + { \cs_set:Npn \currentfile{#1.dtx} } \int_compare:nNnTF \@auxout = \@partaux { \@latexerr{\string\include\space cannot~be~nested}\@eha } { \@docinclude #1 } @@ -2867,7 +3352,7 @@ Do not distribute a modified version of this file. \@tempswatrue \if@partsw \@tempswafalse - \cs_set_nopar:Npx \@tempb{#1} + \cs_set:Npx \@tempb{#1} \@for\@tempa:=\@partlist\do { \ifx\@tempa\@tempb\@tempswatrue\fi @@ -2886,7 +3371,7 @@ Do not distribute a modified version of this file. \part{\currentfile} { \cs_set_eq:NN \ttfamily\relax - \cs_gset_nopar:Npx \filekey + \cs_gset:Npx \filekey { \filekey, \thepart = { \ttfamily \currentfile } } } \DocInput{\currentfile} @@ -2919,14 +3404,14 @@ Do not distribute a modified version of this file. % % \begin{macro}{\docincludeaux} % \begin{macrocode} -\cs_gset_nopar:Npn \docincludeaux +\cs_gset:Npn \docincludeaux { \tl_set:Nn \thepart { \alphalph { part } } \tl_set:Nn \filesep { \thepart - } \cs_set_eq:NN \filekey \use_none:n \tl_gput_right:Nn \index@prologue { - \cs_gset_nopar:Npn \@oddfoot + \cs_gset:Npn \@oddfoot { \parbox { \textwidth } { @@ -2937,7 +3422,7 @@ Do not distribute a modified version of this file. \cs_set_eq:NN \@evenfoot \@oddfoot } \cs_gset_eq:NN \docincludeaux \relax - \cs_gset_nopar:Npn \@oddfoot + \cs_gset:Npn \@oddfoot { \cs_if_exist:cTF { ver @ \currentfile } { File~\thepart :~{\ttfamily\currentfile}~ } @@ -3035,7 +3520,7 @@ Do not distribute a modified version of this file. % \end{macrocode} % % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_show_functions_defined: +\cs_new_protected:Npn \@@_show_functions_defined: { \bool_if:nT { \g_@@_typeset_implementation_bool && \g_@@_checkfunc_bool } @@ -3108,7 +3593,7 @@ Do not distribute a modified version of this file. % \end{macrocode} % % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_show_not_tested: +\cs_new_protected:Npn \@@_show_not_tested: { \bool_if:NT \g_@@_checktest_bool { @@ -3229,26 +3714,31 @@ Do not distribute a modified version of this file. { \use:x { - \@@_special_index_module:nnnn + \@@_special_index_module:nnnnN { \quotechar #1 } { \quotechar \bslash \quotechar #1 } { } { } + \c_false_bool } } % \end{macrocode} % \end{macro} % % \begin{macro}[aux]{\@@_special_index:nn} +% ^^A TODO this override is somewhat a hack % \begin{macrocode} \cs_new_protected:Npn \@@_special_index:nn #1#2 { \@@_key_get:n {#1} - \@@_special_index_module:ooon + \quark_if_no_value:NF \l_@@_override_module_tl + { \tl_set_eq:NN \l_@@_index_module_tl \l_@@_override_module_tl } + \@@_special_index_module:ooonN { \l_@@_index_key_tl } { \l_@@_index_macro_tl } { \l_@@_index_module_tl } {#2} + \l_@@_index_internal_bool } \cs_generate_variant:Nn \@@_special_index:nn { o } % \end{macrocode} @@ -3256,45 +3746,57 @@ Do not distribute a modified version of this file. % % \begin{macro} % { -% \@@_special_index_module:nnnn, -% \@@_special_index_module:ooon, -% \@@_special_index_aux:nnnnn, -% \@@_special_index_aux:onnnn, +% \@@_special_index_module:nnnnN, +% \@@_special_index_module:ooonN, +% \@@_special_index_aux:nnnnnn, % \@@_special_index_set:Nn, % } % Remotely based on Heiko's replacement to play nicely with % \pkg{hypdoc}. We use \tn{verb} or a \tn{verbatim@font} construction % depending on whether the number of tokens in |#2| is equal to its -% number of characters. +% number of characters: if it is not then that suggests that there is +% a construct such as |\meta{...}|. % \begin{macrocode} \tl_new:N \l_@@_index_escaped_macro_tl -\cs_new_protected:Npn \@@_special_index_module:nnnn #1#2#3#4 +\cs_new_protected:Npn \@@_special_index_module:nnnnN #1#2#3#4#5 { \use:x { - \exp_not:n { \@@_special_index_aux:nnnnn {#1} {#2} } - \str_case_x:nnF {#3} + \exp_not:n { \@@_special_index_aux:nnnnnn {#1} {#2} } + \tl_if_empty:nTF {#3} + { { } { } { } } { - { } { { } { } } - { TeX } + \str_if_eq_x:nnTF {#3} { TeX } + { + { TeX~and~LaTeX2e } + { \string\TeX{}~and~\string\LaTeXe{} } + } { - { TeX~and~LaTeX2e~commands } - { \string\TeX{}~and~\string\LaTeXe{}~commands: } + {#3} + { \string\pkg{#3} } } + { \bool_if:NT #5 { ~internal } ~commands: } } - { { #3~commands } { \string\pkg{#3}~commands: } } } {#4} } -\cs_generate_variant:Nn \@@_special_index_module:nnnn { ooo } -\cs_new_protected:Npn \@@_special_index_aux:nnnnn #1#2#3#4#5 +\cs_generate_variant:Nn \@@_special_index_module:nnnnN { ooo } +\cs_new_protected:Npn \@@_special_index_aux:nnnnnn #1#2#3#4#5#6 { - \HD@target \@@_special_index_set:Nn \l_@@_index_escaped_macro_tl {#2} - \index + \str_if_eq:onTF { \@currenvir } { macrocode } + { \codeline@wrindex } + { + \str_case:nnF {#6} + { + { main } { \codeline@wrindex } + { usage } { \index } + } + { \HD@target \index } + } { - \tl_if_empty:nF { #3 #4 } - { #3 \actualchar #4 \levelchar } + \tl_if_empty:nF { #3 #4 #5 } + { #3 #5 \actualchar #4 #5 \levelchar } #1 \actualchar { @@ -3302,20 +3804,13 @@ Do not distribute a modified version of this file. \l_@@_index_escaped_macro_tl } \encapchar - hdclindex{\the\c@HD@hypercount}{#5} + hdclindex{\the\c@HD@hypercount}{#6} } } -\cs_generate_variant:Nn \@@_special_index_aux:nnnnn { o } \cs_new_protected:Npn \@@_special_index_set:Nn #1#2 { \tl_set:Nx #1 { \tl_to_str:n {#2} } - \int_compare:nNnTF { \tl_count:n {#2} } < { \tl_count:N #1 } - { - \tl_set:Nn #1 {#2} - \tl_replace_all:Non #1 - { \c_@@_backslash_tl } - { \token_to_str:N \bslash \c_space_tl } - } + \@@_if_almost_str:nTF {#2} { \exp_args:Nx \tl_map_inline:nn { \tl_to_str:N \verbatimchar \token_to_str:N _ } @@ -3337,6 +3832,12 @@ Do not distribute a modified version of this file. #1 \verbatimchar } } + { + \tl_set:Nn #1 {#2} + \tl_replace_all:Non #1 + { \c_@@_backslash_tl } + { \token_to_str:N \bslash \c_space_tl } + } } % \end{macrocode} % \end{macro} @@ -3345,90 +3846,136 @@ Do not distribute a modified version of this file. % % \begin{macro}[aux]{\@@_key_get:n} % Sets \cs{l_@@_index_macro_tl}, \cs{l_@@_index_key_tl}, and -% \cs{l_@@_index_module_tl} from |#1|. The \cs{l_@@_index_macro_tl} -% contains~|#1| directly. The starting point for the \meta{key} is -% |#1| as a string. If it the first character is a backslash, remove +% \cs{l_@@_index_module_tl} from |#1|. The base function is stored by +% \cs{@@_key_get_base:nN} in \cs{l_@@_index_macro_tl}, falling back to +% |#1| if it contains markup or has no signature. +% +% The starting point for the \meta{key} is \cs{l_@@_index_key_tl} as a +% string. If it the first character is a backslash, remove % it. Then recognize |expl| functions and variables by the presence % of |:| or~|_| and \TeX{}/\LaTeXe{} commands by the presence of~|@|. -% For |expl| names, we call \cs{@@_key_expl:}, which is responsible -% for removing some characters and finding the module name, while for -% \TeX{}/\LaTeXe{} commands the module name is |TeX|, and others have -% an empty module name. The function \cs{@@_key_expl:} detects a -% leading~|.| and removes it (key property), and otherwise does the -% following: if the second character is~|_| and the first is as well, -% then remove both (internal |expl| function); if the second character -% is~|_| but the first is not (the case of an |expl| variable), then -% remove both and remove a subsequent~|_| character (for internal -% variables). In all cases, call \cs{@@_key_get_module:}, which sets -% \cs{l_@@_index_module_tl} by removing anything after |_| or~|:| in -% \cs{l_@@_index_key_tl}. +% For |expl| names, we call \cs{@@_key_func:} or \cs{@@_key_var:}, +% which are responsible for removing some characters and finding the +% module name, while for \TeX{}/\LaTeXe{} commands the module name is +% |TeX|, and others have an empty module name. % \begin{macrocode} \cs_new_protected:Npn \@@_key_get:n #1 { - \tl_set:Nn \l_@@_index_macro_tl {#1} - \tl_set:Nx \l_@@_index_key_tl { \tl_to_str:n {#1} } + \@@_key_get_base:nN {#1} \l_@@_index_macro_tl + \tl_set:Nx \l_@@_index_key_tl + { \tl_to_str:N \l_@@_index_macro_tl } \tl_clear:N \l_@@_index_module_tl + \tl_if_in:NoTF \l_@@_index_key_tl { \tl_to_str:n { __ } } + { \bool_set_true:N \l_@@_index_internal_bool } + { \bool_set_false:N \l_@@_index_internal_bool } \tl_if_head_eq_charcode:oNT { \l_@@_index_key_tl } \c_@@_backslash_token { \@@_key_pop: } \tl_if_in:NoTF \l_@@_index_key_tl { \token_to_str:N : } - { \@@_key_expl: } + { \@@_key_func: } { \tl_if_in:NoTF \l_@@_index_key_tl { \token_to_str:N _ } - { \@@_key_expl: } + { \@@_key_var: } { \tl_if_in:NoT \l_@@_index_key_tl { \token_to_str:N @ } { \tl_set:Nn \l_@@_index_module_tl { TeX } } } } } -\cs_new_protected_nopar:Npn \@@_key_pop: +\cs_new_protected:Npn \@@_key_pop: { \tl_set:Nx \l_@@_index_key_tl { \tl_tail:N \l_@@_index_key_tl } } -\cs_new_protected_nopar:Npn \@@_key_expl: +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\@@_key_trim_module:n, \@@_key_drop_underscores:} +% Helper that removes from \cs{l_@@_index_module_tl} everything after +% the first occurence of |#1|. Helper that removes any leading +% underscore from \cs{l_@@_index_key_tl}. +% \begin{macrocode} +\cs_set:Npn \@@_key_trim_module:n #1 + { + \cs_set:Npn \@@_tmpa:w ##1 #1 ##2 \q_stop + { \exp_not:n {##1} } + \tl_set:Nx \l_@@_index_module_tl + { \exp_after:wN \@@_tmpa:w \l_@@_index_module_tl #1 \q_stop } + } +\cs_new_protected:Npn \@@_key_drop_underscores: { - \tl_if_head_eq_charcode:oNTF { \l_@@_index_key_tl } . - { \@@_key_pop: } - { - \exp_args:Nx \tl_if_head_eq_charcode:nNT - { \exp_args:No \str_tail:n \l_@@_index_key_tl } _ - { - \tl_if_head_eq_charcode:oNTF { \l_@@_index_key_tl } _ - { - \@@_key_pop: - \@@_key_pop: - } - { - \@@_key_pop: - \@@_key_pop: - \tl_if_head_eq_charcode:oNT { \l_@@_index_key_tl } _ - { \@@_key_pop: } - } - } - } - \@@_key_get_module: + \tl_if_head_eq_charcode:oNT { \l_@@_index_key_tl } _ + { \@@_key_pop: \@@_key_drop_underscores: } } % \end{macrocode} % \end{macro} % -% \begin{macro}[aux]{\@@_key_get_module:, \@@_key_get_module_aux:n} -% Sets \cs{l_@@_index_module_tl} from \cs{l_@@_index_key_tl}, by -% removing anything after |:| or |_|, taking care of not expanding the -% rest for cases such as |\cs{\meta{name}:\meta{signature}}|. +% \begin{macro}[aux]{\@@_key_func:} +% The function \cs{@@_key_func:} is used if there is a colon, so +% either for usual \pkg{expl3} functions or for keys from +% \pkg{l3keys}. After removing from the key a leading dot (for the +% latter case), and any leading underscore, the module name is the +% part before any colon or underscore. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_key_get_module: +\cs_new_protected:Npn \@@_key_func: { + \tl_if_head_eq_charcode:oNT { \l_@@_index_key_tl } . + { \@@_key_pop: } + \@@_key_drop_underscores: \tl_set_eq:NN \l_@@_index_module_tl \l_@@_index_key_tl - \exp_args:No \@@_key_get_module_aux:n { \token_to_str:N : } - \exp_args:No \@@_key_get_module_aux:n { \token_to_str:N _ } + \exp_args:No \@@_key_trim_module:n { \token_to_str:N : } + \exp_args:No \@@_key_trim_module:n { \token_to_str:N _ } } -\cs_new_protected:Npn \@@_key_get_module_aux:n #1 +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\@@_key_var:, \@@_key_get_module:} +% The function \cs{@@_key_var:} covers cases with no~|:| but with~|_|, +% typically variables but occasionally non-\pkg{expl3} functions such +% as \Lua{} function with underscores. First test the second +% character: if that is~|_| then assume we have a proper variable, +% otherwise use the part before any underscore as the module name. +% For variables, distinguish quarks and scan marks (starting with |q| +% and~|s|), then drop the first letter (local/global/constant marker) +% and underscores. If there is no underscore left we had something +% like \cs{c_zero} which we assume is an integer constant. If there +% is one underscore we assume it is a variable like \cs{c_empty_tl} +% whose module name is the last part. Otherwise the module name is +% the part before any underscore. +% \begin{macrocode} +\cs_new_protected:Npn \@@_key_var: { - \cs_set:Npn \@@_tmpa:w ##1 #1 ##2 \q_stop { \exp_not:n {##1} } - \tl_set:Nx \l_@@_index_module_tl - { \exp_after:wN \@@_tmpa:w \l_@@_index_module_tl #1 \q_stop } + \exp_args:Nx \tl_if_head_eq_charcode:nNTF + { \exp_args:No \str_tail:n \l_@@_index_key_tl } _ + { + \str_case:fn { \str_head:N \l_@@_index_key_tl } + { + { q } { \tl_set:Nn \l_@@_index_module_tl { quark } } + { s } { \tl_set:Nn \l_@@_index_module_tl { quark } } + } + \@@_key_pop: + \@@_key_pop: + \@@_key_drop_underscores: + \tl_if_empty:NT \l_@@_index_module_tl + { + \seq_set_split:NoV \l_@@_tmpa_seq + { \token_to_str:N _ } \l_@@_index_key_tl + \tl_set:Nx \l_@@_index_module_tl + { + \int_case:nnF { \seq_count:N \l_@@_tmpa_seq } + { + { 0 } { } + { 1 } { int } + { 2 } { \seq_item:Nn \l_@@_tmpa_seq { 2 } } + } + { \seq_item:Nn \l_@@_tmpa_seq { 1 } } + } + } + } + { + \tl_set_eq:NN \l_@@_index_module_tl \l_@@_index_key_tl + \exp_args:No \@@_key_trim_module:n { \token_to_str:N _ } + } } % \end{macrocode} % \end{macro} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx b/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx index cfbcb9bdce3..fc30245ded9 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3drivers.dtx @@ -38,7 +38,7 @@ \documentclass[full]{l3doc} % %<*driver|package> -\GetIdInfo$Id: l3drivers.dtx 6511 2016-05-17 20:20:23Z joseph $ +\GetIdInfo$Id: l3drivers.dtx 6644 2016-08-13 20:22:11Z bruno $ {L3 Experimental drivers} % %<*driver> @@ -167,8 +167,6 @@ % but still require an appreciation of the concepts of PostScript/PDF/SVG % graphic creation. % -% At present \emph{not all drivers are covered} by the following. -% % \begin{function} % { \__driver_draw_begin:, \__driver_draw_end:} % \begin{syntax} @@ -195,7 +193,8 @@ % state and concepts such as color or linewidth are localised to a scope. % This function pair must never be used if an partial path is under % construction: such paths must be entirely contained at one unbroken -% scope level. +% scope level. Note that scopes do not form \TeX{} groups and may not +% be aligned with them. % \end{function} % % \subsection{Path construction} @@ -231,6 +230,16 @@ % without appearing itself. % \end{function} % +% \begin{function}{\__driver_draw_rectangle:nnnn} +% \begin{syntax} +% \cs{__driver_draw_rectangle:nnnn} \Arg{x} \Arg{y} \Arg{width} \Arg{height} +% \end{syntax} +% Adds rectangular path from (\meta{x_1}, \meta{y_1}) of \meta{height} +% and \meta{width}; any active transformation matrix will apply. Note that +% nothing is drawn until a fill or stroke operation is applied, and that the +% path may be discarded or used as a clip without appearing itself. +% \end{function} +% % \begin{function}{\__driver_draw_closepath:} % \begin{syntax} % \cs{__driver_draw_closepath:} @@ -273,9 +282,18 @@ % influenced by the setting for fill color (or the current color if no % specific stroke color is set). The path may also be used for clipping. % For paths which are self-intersecting or comprising multiple parts, the -% determination of which areas are inside the path is made using the nonzero -% winding rule number unless \cs{__driver_draw_eor_bool} is \texttt{true}, -% in which case the even-odd rule is used. +% determination of which areas are inside the path is made using the non-zero +% winding number rule unless the even-odd rule is active. +% \end{function} +% +% \begin{function}{\__driver_draw_nonzero_rule:, \__driver_draw_evenodd_rule:} +% \begin{syntax} +% \cs{__driver_draw_nonzero_rule:} +% \end{syntax} +% Active either the non-zero winding number or the even-odd rule, +% respectively, for determining what is inside a fill or clip area. +% For technical reasons, these command are not influenced by scoping +% and apply on an ongoing basis. % \end{function} % % \begin{function}{\__driver_draw_clip:} @@ -286,7 +304,9 @@ % Indicates that the current path should be used for clipping, such that % any subsequent material outside of the path (but within the current % scope) will not be shown. This command should be given once a path is -% complete but before it is stroked or filled (if appropriate). +% complete but before it is stroked or filled (if appropriate). This +% command is \emph{not} affected by scoping: it applies to exactly one +% path as shown. % \end{function} % % \begin{function}{\__driver_draw_discardpath:} @@ -321,7 +341,7 @@ % $1$\,pt on, $2$\,pt off, $3$\,pt on, and so on. An odd number of entries % means that the last is repeated, for example \texttt{3pt} is equal to % \texttt{3pt, 3pt}. An empty pattern yields a solid line. -% +% % The \meta{phase} specifies an offset at the start of the cycle. For % example, with a pattern \texttt{3pt} a phase of \texttt{1pt} will mean % that the output is $2$\,pt on, $3$\,pt off, $3$\,pt on, $3$\,pt on, @@ -361,6 +381,85 @@ % PDF and PostScript manuals. % \end{function} % +% \subsection{Color} +% +% \begin{function} +% { +% \__driver_draw_color_cmyk:nnnn , +% \__driver_draw_color_cmyk_fill:nnnn , +% \__driver_draw_color_cmyk_stroke:nnnn +% } +% \begin{syntax} +% \cs{__driver_draw_color_cmyk:nnnn} \Arg{cyan} \Arg{magneta} \Arg{yellow} +% \Arg{black} +% \end{syntax} +% Sets the color for drawing to the CMYK values specified, all of which are +% fp expressions which should evaluate to between $0$ and $1$. The +% \texttt{fill} and \texttt{stroke} versions set only the color for those +% operations. Note that the general setting is more efficient with some +% drivers so should in most cases be preferred. +% \end{function} +% +% \begin{function} +% { +% \__driver_draw_color_gray:n , +% \__driver_draw_color_gray_fill:n , +% \__driver_draw_color_gray_stroke:n +% } +% \begin{syntax} +% \cs{__driver_draw_color_gray:n} \Arg{gray} +% \end{syntax} +% Sets the color for drawing to the grayscale value specified, which is +% fp expressions which should evaluate to between $0$ and $1$. The +% \texttt{fill} and \texttt{stroke} versions set only the color for those +% operations. Note that the general setting is more efficient with some +% drivers so should in most cases be preferred. +% \end{function} +% +% \begin{function} +% { +% \__driver_draw_color_rgb:nnn , +% \__driver_draw_color_rgb_fill:nnn , +% \__driver_draw_color_rgb_stroke:nnn +% } +% \begin{syntax} +% \cs{__driver_draw_color_gray:n} \Arg{red} \Arg{green} \Arg{blue} +% \end{syntax} +% Sets the color for drawing to the RGB values specified, all of which are +% fp expressions which should evaluate to between $0$ and $1$. The +% \texttt{fill} and \texttt{stroke} versions set only the color for those +% operations. Note that the general setting is more efficient with some +% drivers so should in most cases be preferred. +% \end{function} +% +% \subsection{Inserting \TeX{} material} +% +% \begin{function}{\__driver_draw_hbox:nnnnnn} +% \begin{syntax} +% \cs{__driver_draw_hbox:Nnnnnnn} \meta{box} +% \Arg{a} \Arg{b} \Arg{c} \Arg{d} \Arg{x} \Arg{y} +% \end{syntax} +% Inserts the \meta{box} as an hbox with the box reference point placed +% at ($x$, $y$). The transformation matrix $[a b c d]$ will be applied +% to the box, allowing it to be in synchronisation with any scaling, rotation +% or skewing applying more generally. Note that \TeX{} material should not +% be inserted directly into a drawing as it will not be in the correct +% location. Also note that as for other drawing elements the box here will +% have no size from a \TeX{} perspective. +% \end{function} +% +% \subsection{Coordinate system transformations} +% +% \begin{function}{\__driver_draw_transformcm:nnnnnn} +% \begin{syntax} +% \cs{__driver_draw_transformcm:nnnnnn} \Arg{a} \Arg{b} \Arg{c} \Arg{d} +% \Arg{x} \Arg{y} +% \end{syntax} +% Applies the transformation matrix $[a b c d]$ and offset vector +% ($x$, $y$) to the current graphic state. This will affect any subsequent +% items in the same scope but not those already given. +% \end{function} +% % \end{documentation} % % \begin{implementation} @@ -440,13 +539,13 @@ % \begin{macro}[int]{\@@_scope_begin:, \@@_scope_end:} % Higher-level interfaces for saving and restoring the graphic state. % \begin{macrocode} -\cs_new_protected_nopar:Npx \@@_scope_begin: +\cs_new_protected:Npx \@@_scope_begin: { \cs_if_exist:NTF \luatex_pdfextension:D { \luatex_pdfextension:D save \scan_stop: } { \pdftex_pdfsave:D } } -\cs_new_protected_nopar:Npx \@@_scope_end: +\cs_new_protected:Npx \@@_scope_end: { \cs_if_exist:NTF \luatex_pdfextension:D { \luatex_pdfextension:D restore \scan_stop: } @@ -502,7 +601,7 @@ % There is a dedicated primitive/primitive interface for setting colors. % As with scoping, this approach is not suitable for cached operations. % \begin{macrocode} -\cs_new_protected_nopar:Npx \@@_color_ensure_current: +\cs_new_protected:Npx \@@_color_ensure_current: { \cs_if_exist:NTF \luatex_pdfextension:D { \luatex_pdfextension:D colorstack } @@ -511,7 +610,7 @@ { \exp_not:N \l_@@_current_color_tl } \group_insert_after:N \exp_not:N \@@_color_reset: } -\cs_new_protected_nopar:Npx \@@_color_reset: +\cs_new_protected:Npx \@@_color_reset: { \cs_if_exist:NTF \luatex_pdfextension:D { \luatex_pdfextension:D colorstack } @@ -552,9 +651,9 @@ % \begin{macro}[int]{\@@_scope_begin:, \@@_scope_end:} % Scoping is done using direct PDF operations here. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_scope_begin: +\cs_new_protected:Npn \@@_scope_begin: { \@@_literal:n { q } } -\cs_new_protected_nopar:Npn \@@_scope_end: +\cs_new_protected:Npn \@@_scope_end: { \@@_literal:n { Q } } % \end{macrocode} % \end{macro} @@ -591,12 +690,12 @@ % \begin{macro}[aux]{\@@_color_reset:} % Directly set the color using the specials with optimisation support. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_color_ensure_current: +\cs_new_protected:Npn \@@_color_ensure_current: { \tex_special:D { pdf:bcolor~\l_@@_current_color_tl } \group_insert_after:N \@@_color_reset: } -\cs_new_protected_nopar:Npn \@@_color_reset: +\cs_new_protected:Npn \@@_color_reset: { \tex_special:D { pdf:ecolor } } % \end{macrocode} % \end{macro} @@ -624,12 +723,12 @@ { \@ifpackageloaded { color } { - \cs_set_protected_nopar:Npn \@@_color_ensure_current: + \cs_set_protected:Npn \@@_color_ensure_current: { \tex_special:D { color~push~\l_@@_current_color_tl } \group_insert_after:N \@@_color_reset: } - \cs_set_protected_nopar:Npn \@@_color_reset: + \cs_set_protected:Npn \@@_color_reset: { \tex_special:D { color~pop } } } { } @@ -753,9 +852,9 @@ % \begin{macro}[int]{\@@_draw_begin:, \@@_draw_end:} % No special requirements here, so simply set up a drawing scope. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_draw_begin: +\cs_new_protected:Npn \@@_draw_begin: { \@@_draw_scope_begin: } -\cs_new_protected_nopar:Npn \@@_draw_end: +\cs_new_protected:Npn \@@_draw_end: { \@@_draw_scope_end: } % \end{macrocode} % \end{macro} @@ -764,15 +863,16 @@ % In contrast to a general scope, a drawing scope is always done using % the PDF operators so is the same for all relevant drivers. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_draw_scope_begin: +\cs_new_protected:Npn \@@_draw_scope_begin: { \@@_draw_literal:n { q } } -\cs_new_protected_nopar:Npn \@@_draw_scope_end: +\cs_new_protected:Npn \@@_draw_scope_end: { \@@_draw_literal:n { Q } } % \end{macrocode} % \end{macro} % % \begin{macro}[int]{\@@_draw_moveto:nn, \@@_draw_lineto:nn} % \begin{macro}[int]{\@@_draw_curveto:nnnnnn} +% \begin{macro}[int]{\@@_draw_rectangle:nnnn} % Path creation operations all resolve directly to PDF primitive steps, with % only the need to convert to \texttt{bp}. Notice that \texttt{x}-type % expansion is included here to ensure that any variable values are @@ -798,16 +898,32 @@ c } } +\cs_new_protected:Npn \@@_draw_rectangle:nnnn #1#2#3#4 + { + \@@_draw_literal:x + { + \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~ + \dim_to_decimal_in_bp:n {#3} ~ \dim_to_decimal_in_bp:n {#4} ~ + re + } + } % \end{macrocode} % \end{macro} % \end{macro} +% \end{macro} % -% \begin{variable}[int]{\@@_draw_eor_bool} +% \begin{macro}[int]{\@@_draw_evenodd_rule:, \@@_draw_nonzero_rule:} +% \begin{variable}[aux]{\g_@@_draw_eor_bool} % The even-odd rule here can be implemented as a simply switch. % \begin{macrocode} -\bool_new:N \@@_draw_eor_bool +\cs_new_protected:Npn \@@_draw_evenodd_rule: + { \bool_gset_true:N \g_@@_draw_eor_bool } +\cs_new_protected:Npn \@@_draw_nonzero_rule: + { \bool_gset_false:N \g_@@_draw_eor_bool } +\bool_new:N \g_@@_draw_eor_bool % \end{macrocode} % \end{variable} +% \end{macro} % % \begin{macro}[int] % { @@ -822,28 +938,28 @@ % Converting paths to output is again a case of mapping directly to % PDF operations. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_draw_closepath: +\cs_new_protected:Npn \@@_draw_closepath: { \@@_draw_literal:n { h } } -\cs_new_protected_nopar:Npn \@@_draw_stroke: +\cs_new_protected:Npn \@@_draw_stroke: { \@@_draw_literal:n { S } } -\cs_new_protected_nopar:Npn \@@_draw_closestroke: +\cs_new_protected:Npn \@@_draw_closestroke: { \@@_draw_literal:n { s } } -\cs_new_protected_nopar:Npn \@@_draw_fill: +\cs_new_protected:Npn \@@_draw_fill: { \@@_draw_literal:x - { f \bool_if:NT \@@_draw_eor_bool * } + { f \bool_if:NT \g_@@_draw_eor_bool * } } -\cs_new_protected_nopar:Npn \@@_draw_fillstroke: +\cs_new_protected:Npn \@@_draw_fillstroke: { \@@_draw_literal:x - { B \bool_if:NT \@@_draw_eor_bool * } + { B \bool_if:NT \g_@@_draw_eor_bool * } } -\cs_new_protected_nopar:Npn \@@_draw_clip: +\cs_new_protected:Npn \@@_draw_clip: { \@@_draw_literal:x - { W \bool_if:NT \@@_draw_eor_bool * } + { W \bool_if:NT \g_@@_draw_eor_bool * } } -\cs_new_protected_nopar:Npn \@@_draw_discardpath: +\cs_new_protected:Npn \@@_draw_discardpath: { \@@_draw_literal:n { n } } % \end{macrocode} % \end{macro} @@ -852,7 +968,7 @@ % \begin{macro}[aux]{\@@_draw_dash:n} % \begin{macro}[int]{\@@_draw_linewidth:n} % \begin{macro}[int]{\@@_draw_miterlimit:n} -% \begin{macro}[int]^^A +% \begin{macro}[int] % { % \@@_draw_cap_butt:, \@@_draw_cap_round:, \@@_draw_cap_rectangle:, % \@@_draw_join_miter:, \@@_draw_join_round:, \@@_draw_join_bevel: @@ -879,17 +995,17 @@ } \cs_new_protected:Npn \@@_draw_miterlimit:n #1 { \@@_draw_literal:x { \fp_eval:n {#1} ~ M } } -\cs_new_protected_nopar:Npn \@@_draw_cap_butt: +\cs_new_protected:Npn \@@_draw_cap_butt: { \@@_draw_literal:n { 0 ~ J } } -\cs_new_protected_nopar:Npn \@@_draw_cap_round: +\cs_new_protected:Npn \@@_draw_cap_round: { \@@_draw_literal:n { 1 ~ J } } -\cs_new_protected_nopar:Npn \@@_draw_cap_rectangle: +\cs_new_protected:Npn \@@_draw_cap_rectangle: { \@@_draw_literal:n { 2 ~ J } } -\cs_new_protected_nopar:Npn \@@_draw_join_miter: +\cs_new_protected:Npn \@@_draw_join_miter: { \@@_draw_literal:n { 0 ~ j } } -\cs_new_protected_nopar:Npn \@@_draw_join_round: +\cs_new_protected:Npn \@@_draw_join_round: { \@@_draw_literal:n { 1 ~ j } } -\cs_new_protected_nopar:Npn \@@_draw_join_bevel: +\cs_new_protected:Npn \@@_draw_join_bevel: { \@@_draw_literal:n { 2 ~ j } } % \end{macrocode} % \end{macro} @@ -899,14 +1015,45 @@ % \end{macro} % % \begin{macro}[int] -% {\@@_draw_color_cmyk_fill:nnnn, \@@_draw_color_cmyk_stroke:nnnn} +% { +% \@@_draw_color_cmyk:nnnn , +% \@@_draw_color_cmyk_fill:nnnn , +% \@@_draw_color_cmyk_stroke:nnnn +% } +% \begin{macro}[aux]{\@@_draw_color_cmyk_aux:nnnn} % \begin{macro}[int] -% {\@@_draw_color_gray_fill:n, \@@_draw_color_gray_stroke:n} +% { +% \@@_draw_color_gray:n , +% \@@_draw_color_gray_fill:n , +% \@@_draw_color_gray_stroke:n +% } +% \begin{macro}[aux]{\@@_draw_color_gray_aux:n} % \begin{macro}[int] -% {\@@_draw_color_rgb_fill:nnn, \@@_draw_color_rgb_stroke:nnn} +% { +% \@@_draw_color_rgb:nnn , +% \@@_draw_color_rgb_fill:nnn , +% \@@_draw_color_rgb_stroke:nnn +% } +% \begin{macro}[aux]{\@@_draw_color_rgb_aux:nnn} % Yet more fast conversion, all using the FPU to allow for expressions % in numerical input. % \begin{macrocode} +\cs_new_protected:Npn \@@_draw_color_cmyk:nnnn #1#2#3#4 + { + \use:x + { + \@@_draw_color_cmyk_aux:nnnn + { \fp_eval:n {#1} } + { \fp_eval:n {#2} } + { \fp_eval:n {#3} } + { \fp_eval:n {#4} } + } + } +\cs_new_protected:Npn \@@_draw_color_cmyk_aux:nnnn #1#2#3#4 + { + \@@_draw_literal:n + { #1 ~ #2 ~ #3 ~ #4 ~ k ~ #1 ~ #2 ~ #3 ~ #4 ~ K } + } \cs_new_protected:Npn \@@_draw_color_cmyk_fill:nnnn #1#2#3#4 { \@@_draw_literal:x @@ -925,10 +1072,34 @@ K } } +\cs_new_protected:Npn \@@_draw_color_gray:n #1 + { + \use:x + { \@@_draw_color_gray_aux:n { \fp_eval:n {#1} } } + } +\cs_new_protected:Npn \@@_draw_color_gray_aux:n #1 + { + \@@_draw_literal:n { #1 ~ g ~ #1 ~ G } + } \cs_new_protected:Npn \@@_draw_color_gray_fill:n #1 { \@@_draw_literal:x { \fp_eval:n {#1} ~ g } } \cs_new_protected:Npn \@@_draw_color_gray_stroke:n #1 { \@@_draw_literal:x { \fp_eval:n {#1} ~ G } } +\cs_new_protected:Npn \@@_draw_color_rgb:nnn #1#2#3 + { + \use:x + { + \@@_draw_color_rgb_aux:nnn + { \fp_eval:n {#1} } + { \fp_eval:n {#2} } + { \fp_eval:n {#3} } + } + } +\cs_new_protected:Npn \@@_draw_color_rgb_aux:nnn #1#2#3 + { + \@@_draw_literal:n + { #1 ~ #2 ~ #3 ~ rg ~ #1 ~ #2 ~ #3 ~ RG } + } \cs_new_protected:Npn \@@_draw_color_rgb_fill:nnn #1#2#3 { \@@_draw_literal:x @@ -943,6 +1114,9 @@ % \end{macro} % \end{macro} % \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % % \begin{macro}[int]{\@@_draw_transformcm:nnnnnn} % The first four arguments here are floats (the affine matrix), the last @@ -1027,11 +1201,12 @@ % % \begin{macro}{\@@_scope_begin:, \@@_scope_end:} % Scope saving/restoring is done directly with no need to worry about the -% transformation matrix. +% transformation matrix. General scoping is only for the graphics stack so +% the lower-cost |gsave|/|grestore| pair are used. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_scope_begin: +\cs_new_protected:Npn \@@_scope_begin: { \tex_special:D { ps:gsave } } -\cs_new_protected_nopar:Npn \@@_scope_end: +\cs_new_protected:Npn \@@_scope_end: { \tex_special:D { ps:grestore } } % \end{macrocode} % \end{macro} @@ -1145,17 +1320,442 @@ % \begin{macro}[aux]{\@@_color_reset:} % Directly set the color using the specials: no optimisation here. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_color_ensure_current: +\cs_new_protected:Npn \@@_color_ensure_current: { \tex_special:D { color~push~\l_@@_current_color_tl } \group_insert_after:N \@@_color_reset: } -\cs_new_protected_nopar:Npn \@@_color_reset: +\cs_new_protected:Npn \@@_color_reset: { \tex_special:D { color~pop } } % \end{macrocode} % \end{macro} % \end{macro} % +% \subsection{Drawing} +% +% \begin{macro}[aux]{\@@_draw_literal:n, \@@_draw_literal:x} +% Literals with no positioning (using |ps:| each one is positioned but +% cut of from everything else, so no good for the stepwise approach needed +% here). +% \begin{macrocode} +\cs_new_protected:Npn \@@_draw_literal:n #1 + { \tex_special:D { ps:: ~ #1 } } +\cs_generate_variant:Nn \@@_draw_literal:n { x } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\@@_draw_begin:, \@@_draw_end:} +% The |ps::[begin]| special here deals with positioning but allows us to +% continue on to a matching |ps::[end]|: contrast with |ps:|, which positions +% but where we can't split material between separate calls. The +% |@beginspecial|/|@endspecial| pair are from |special.pro| and correct the +% scale and $y$-axis direction. The reference point at the start of the box +% is saved (as |l3x|/|l3y|) as it is needed when inserting various items. +% \begin{macrocode} +\cs_new_protected:Npn \@@_draw_begin: + { + \tex_special:D { ps::[begin] } + \tex_special:D { ps::~save } + \tex_special:D { ps::~/l3x~currentpoint~/l3y~exch~def~def } + \tex_special:D { ps::~@beginspecial } + } +\cs_new_protected:Npn \@@_draw_end: + { + \tex_special:D { ps::~@endspecial } + \tex_special:D { ps::~restore } + \tex_special:D { ps::[end] } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\@@_draw_scope_begin:, \@@_draw_scope_end:} +% Scope here may need to contain saved definitions, so the entire memory +% rather than just the graphic state has to be sent to the stack. +% \begin{macrocode} +\cs_new_protected:Npn \@@_draw_scope_begin: + { \@@_draw_literal:n { save } } +\cs_new_protected:Npn \@@_draw_scope_end: + { \@@_draw_literal:n { restore } } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\@@_draw_moveto:nn, \@@_draw_lineto:nn} +% \begin{macro}[int]{\@@_draw_rectangle:nnnn} +% \begin{macro}[int]{\@@_draw_curveto:nnnnnn} +% Path creation operations mainly resolve directly to PostScript primitive +% steps, with only the need to convert to \texttt{bp}. Notice that +% \texttt{x}-type expansion is included here to ensure that any variable +% values are forced to literals before any possible caching. There is +% no native rectangular path command (without also clipping, filling or +% stroking), so that task is done using a small amount of PostScript. +% \begin{macrocode} +\cs_new_protected:Npn \@@_draw_moveto:nn #1#2 + { + \@@_draw_literal:x + { \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~ moveto } + } +\cs_new_protected:Npn \@@_draw_lineto:nn #1#2 + { + \@@_draw_literal:x + { \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~ lineto } + } +\cs_new_protected:Npn \@@_draw_rectangle:nnnn #1#2#3#4 + { + \@@_draw_literal:x + { + \dim_to_decimal_in_bp:n {#4} ~ \dim_to_decimal_in_bp:n {#3} ~ + \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~ + moveto~dup~0~rlineto~exch~0~exch~rlineto~neg~0~rlineto~clospath + } + } +\cs_new_protected:Npn \@@_draw_curveto:nnnnnn #1#2#3#4#5#6 + { + \@@_draw_literal:x + { + \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~ + \dim_to_decimal_in_bp:n {#3} ~ \dim_to_decimal_in_bp:n {#4} ~ + \dim_to_decimal_in_bp:n {#5} ~ \dim_to_decimal_in_bp:n {#6} ~ + curveto + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[int]{\@@_draw_evenodd_rule:, \@@_draw_nonzero_rule:} +% \begin{variable}[aux]{\g_@@_draw_eor_bool} +% The even-odd rule here can be implemented as a simply switch. +% \begin{macrocode} +\cs_new_protected:Npn \@@_draw_evenodd_rule: + { \bool_gset_true:N \g_@@_draw_eor_bool } +\cs_new_protected:Npn \@@_draw_nonzero_rule: + { \bool_gset_false:N \g_@@_draw_eor_bool } +\bool_new:N \g_@@_draw_eor_bool +% \end{macrocode} +% \end{variable} +% \end{macro} +% +% \begin{macro}[int] +% { +% \@@_draw_closepath: , +% \@@_draw_stroke: , +% \@@_draw_closestroke: , +% \@@_draw_fill: , +% \@@_draw_fillstroke: , +% \@@_draw_clip: , +% \@@_draw_discardpath: +% } +% \begin{variable}[aux]{\g_@@_draw_clip_bool} +% Unlike PDF, PostScript doesn't track separate colors for strokes and other +% elements. It is also desirable to have the |clip| keyword after a stroke or +% fill. To achieve those outcomes, there is some work to do. For color, if a +% stroke or fill color is defined it is used for the relevant operation, with +% a graphic scope inserted as required. That does mean that once such a color +% is set all further uses inside the same scope have to use scoping: see also +% the color set up functions. For clipping, the required ordering is achieved +% using a \TeX{} switch. All of the operations end with a new path instruction +% as they do not terminate (again in contrast to PDF). +% \begin{macrocode} +\cs_new_protected:Npn \@@_draw_closepath: + { \@@_draw_literal:n { closepath } } +\cs_new_protected:Npn \@@_draw_stroke: + { + \@@_draw_literal:n { currentdict~/l3sc~known~{gsave~l3sc}~if } + \@@_draw_literal:n { stroke } + \@@_draw_literal:n { currentdict~/l3sc~known~{grestore}~if } + \bool_if:NT \g_@@_draw_clip_bool + { + \@@_draw_literal:x + { + \bool_if:NT \g_@@_draw_eor_bool { eo } + clip + } + } + \@@_draw_literal:n { newpath } + \bool_gset_false:N \g_@@_draw_clip_bool + } +\cs_new_protected:Npn \@@_draw_closestroke: + { + \@@_draw_closepath: + \@@_draw_stroke: + } +\cs_new_protected:Npn \@@_draw_fill: + { + \@@_draw_literal:n { currentdict~/l3fc~known~{gsave~l3fc}~if } + \@@_draw_literal:x + { + \bool_if:NT \g_@@_draw_eor_bool { eo } + fill + } + \@@_draw_literal:n { currentdict~/l3fc~known~{grestore}~if } + \bool_if:NT \g_@@_draw_clip_bool + { + \@@_draw_literal:x + { + \bool_if:NT \g_@@_draw_eor_bool { eo } + clip + } + } + \@@_draw_literal:n { newpath } + \bool_gset_false:N \g_@@_draw_clip_bool + } +\cs_new_protected:Npn \@@_draw_fillstroke: + { + \@@_draw_literal:n { currentdict~/l3fc~known~{gsave~l3fc}~if } + \@@_draw_literal:x + { + \bool_if:NT \g_@@_draw_eor_bool { eo } + fill + } + \@@_draw_literal:n { currentdict~/l3fc~known~{grestore}~if } + \@@_draw_literal:n { currentdict~/l3sc~known~{gsave~l3sc}~if } + \@@_draw_literal:n { stroke } + \@@_draw_literal:n { currentdict~/l3sc~known~{grestore}~if } + \bool_if:NT \g_@@_draw_clip_bool + { + \@@_draw_literal:x + { + \bool_if:NT \g_@@_draw_eor_bool { eo } + clip + } + } + \@@_draw_literal:n { newpath } + \bool_gset_false:N \g_@@_draw_clip_bool + } +\cs_new_protected:Npn \@@_draw_clip: + { \bool_gset_true:N \g_@@_draw_clip_bool } +\bool_new:N \g_@@_draw_clip_bool +\cs_new_protected:Npn \@@_draw_discardpath: + { + \bool_if:NT \g_@@_draw_clip_bool + { + \@@_draw_literal:x + { + \bool_if:NT \g_@@_draw_eor_bool { eo } + clip + } + } + \@@_draw_literal:n { newpath } + \bool_gset_false:N \g_@@_draw_clip_bool + } +% \end{macrocode} +% \end{variable} +% \end{macro} +% +% \begin{macro}[int]{\@@_draw_dash:nn} +% \begin{macro}[aux]{\@@_draw_dash:n} +% \begin{macro}[int]{\@@_draw_linewidth:n} +% \begin{macro}[int]{\@@_draw_miterlimit:n} +% \begin{macro}[int] +% { +% \@@_draw_cap_butt:, \@@_draw_cap_round:, \@@_draw_cap_rectangle:, +% \@@_draw_join_miter:, \@@_draw_join_round:, \@@_draw_join_bevel: +% } +% Converting paths to output is again a case of mapping directly to +% PostScript operations. +% \begin{macrocode} +\cs_new_protected:Npn \@@_draw_dash:nn #1#2 + { + \@@_draw_literal:x + { + [ ~ + \clist_map_function:nN {#1} \@@_draw_dash:n + ] ~ + \dim_to_decimal_in_bp:n {#2} ~ setdash + } + } +\cs_new:Npn \@@_draw_dash:n #1 + { \dim_to_decimal_in_bp:n {#1} ~ } +\cs_new_protected:Npn \@@_draw_linewidth:n #1 + { + \@@_draw_literal:x + { \dim_to_decimal_in_bp:n {#1} ~ setlinewidth } + } +\cs_new_protected:Npn \@@_draw_miterlimit:n #1 + { \@@_draw_literal:x { \fp_eval:n {#1} ~ setmiterlimit } } +\cs_new_protected:Npn \@@_draw_cap_butt: + { \@@_draw_literal:n { 0 ~ setlinecap } } +\cs_new_protected:Npn \@@_draw_cap_round: + { \@@_draw_literal:n { 1 ~ setlinecap } } +\cs_new_protected:Npn \@@_draw_cap_rectangle: + { \@@_draw_literal:n { 2 ~ setlinecap } } +\cs_new_protected:Npn \@@_draw_join_miter: + { \@@_draw_literal:n { 0 ~ setlinejoin } } +\cs_new_protected:Npn \@@_draw_join_round: + { \@@_draw_literal:n { 1 ~ setlinejoin } } +\cs_new_protected:Npn \@@_draw_join_bevel: + { \@@_draw_literal:n { 2 ~ setlinejoin } } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[aux]{\_@@_draw_color_reset:} +% \begin{macro}[int] +% { +% \@@_draw_color_cmyk:nnnn , +% \@@_draw_color_cmyk_fill:nnnn , +% \@@_draw_color_cmyk_stroke:nnnn +% } +% \begin{macro}[int] +% { +% \@@_draw_color_gray:n , +% \@@_draw_color_gray_fill:n , +% \@@_draw_color_gray_stroke:n +% } +% \begin{macro}[int] +% { +% \@@_draw_color_rgb:nnn , +% \@@_draw_color_rgb_fill:nnn , +% \@@_draw_color_rgb_stroke:nnn +% } +% To allow color to be defined for strokes and fills separately and to +% respect scoping, the data needs to be stored at the PostScript level. +% We cannot undefine (local) fill/stroke colors once set up but we can +% set them blank to improve performance slightly. +% \begin{macrocode} +\cs_new_protected:Npn \@@_draw_color_reset: + { + \@@_draw_literal:n { currentdic~/l3fc~known~{ /l3fc~ { } ~def }~if } + \@@_draw_literal:n { currentdic~/l3sc~known~{ /l3sc~ { } ~def }~if } + } +\cs_new_protected:Npn \@@_draw_color_cmyk:nnnn #1#2#3#4 + { + \@@_draw_literal:x + { + \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ + \fp_eval:n {#3} ~ \fp_eval:n {#4} ~ + setcmykcolor ~ + } + \@@_draw_color_reset: + } +\cs_new_protected:Npn \@@_draw_color_cmyk_fill:nnnn #1#2#3#4 + { + \@@_draw_literal:x + { + /l3fc ~ + { + \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ + \fp_eval:n {#3} ~ \fp_eval:n {#4} ~ + setcmykcolor + } ~ + def + } + } +\cs_new_protected:Npn \@@_draw_color_cmyk_stroke:nnnn #1#2#3#4 + { + \__driver_draw_literal:x + { + /l3sc ~ + { + \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ + \fp_eval:n {#3} ~ \fp_eval:n {#4} ~ + setcmykcolor + } ~ + def + } + } +\cs_new_protected:Npn \@@_draw_color_gray:n #1 + { + \@@_draw_literal:x { fp_eval:n {#1} ~ setgray } + \@@_draw_color_reset: + } +\cs_new_protected:Npn \@@_draw_color_gray_fill:n #1 + { \@@_draw_literal:x { /l3fc ~ { \fp_eval:n {#1} ~ setgray } ~ def } } +\cs_new_protected:Npn \@@_draw_color_gray_stroke:n #1 + { \@@_draw_literal:x { /l3sc ~ { \fp_eval:n {#1} ~ setgray } ~ def } } +\cs_new_protected:Npn \@@_draw_color_rgb:nnn #1#2#3 + { + \@@_draw_literal:x + { + \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ \fp_eval:n {#3} ~ + setrgbcolor + } + \@@_draw_color_reset: + } +\cs_new_protected:Npn \@@_draw_color_rgb_fill:nnn #1#2#3 + { + \@@_draw_literal:x + { + /l3fc ~ + { + \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ \fp_eval:n {#3} ~ + setrgbcolor + } ~ + def + } + } +\cs_new_protected:Npn \@@_draw_color_rgb_stroke:nnn #1#2#3 + { + \@@_draw_literal:x + { + /l3sc ~ + { + \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ \fp_eval:n {#3} ~ + setrgbcolor + } ~ + def + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[int]{\@@_draw_transformcm:nnnnnn} +% The first four arguments here are floats (the affine matrix), the last +% two are a displacement vector. Once again, force evaluation to allow for +% caching. +% \begin{macrocode} +\cs_new_protected:Npn \@@_draw_transformcm:nnnnnn #1#2#3#4#5#6 + { + \@@_draw_literal:x + { + [ + \fp_eval:n {#1} ~ \fp_eval:n {#2} ~ + \fp_eval:n {#3} ~ \fp_eval:n {#4} ~ + \dim_to_decimal_in_bp:n {#5} ~ \dim_to_decimal_in_bp:n {#6} ~ + ] ~ + concat + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\@@_draw_hbox:Nnnnnnn} +% Inside a picture |@beginspecial|/|@endspecial| are active, which is +% normally a good thing but means that the position and scaling will be off +% if the box is inserted directly. Instead, we need to reverse the effect of +% the (normally desirable) shift/scaling within the box. That requires +% knowing where the reference point for the drawing is: saved as |l3x|/|l3y| +% at the start of the picture. Transformation here is relative to the +% drawing origin so has to be done purely in driver code not using \TeX{} +% offsets. +% \begin{macrocode} +\cs_new_protected:Npn \@@_draw_hbox:Nnnnnnn #1#2#3#4#5#6#7 + { + \@@_scope_begin: + \tex_special:D { ps::[end] } + \@@_draw_transformcm:nnnnnn {#2} {#3} {#4} {#5} {#6} {#7} + \tex_special:D { ps::~72~Resolution~div~72~VResolution~div~neg~scale } + \tex_special:D { ps::~magscale~{1~DVImag~div~dup~scale}~if } + \tex_special:D { ps::~l3x~neg~l3y~neg~translate } + \group_begin: + \box_set_wd:Nn #1 { 0pt } + \box_set_ht:Nn #1 { 0pt } + \box_set_dp:Nn #1 { 0pt } + \box_use:N #1 + \group_end: + \tex_special:D { ps::[begin] } + \@@_scope_end: + } +% \end{macrocode} +% \end{macro} +% % \begin{macrocode} % % \end{macrocode} @@ -1184,9 +1784,9 @@ % A scope in SVG terms is slightly different to the other drivers as % operations have to be \enquote{tied} to these not simply inside them. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_scope_begin: +\cs_new_protected:Npn \@@_scope_begin: { \@@_literal:n { } } -\cs_new_protected_nopar:Npn \@@_scope_end: +\cs_new_protected:Npn \@@_scope_end: { \@@_literal:n { } } % \end{macrocode} % \end{macro} @@ -1352,17 +1952,469 @@ % \begin{macro}[aux]{\@@_color_reset:} % Directly set the color: same as \texttt{dvips}. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_color_ensure_current: +\cs_new_protected:Npn \@@_color_ensure_current: { \tex_special:D { color~push~\l_@@_current_color_tl } \group_insert_after:N \@@_color_reset: } -\cs_new_protected_nopar:Npn \@@_color_reset: +\cs_new_protected:Npn \@@_color_reset: { \tex_special:D { color~pop } } % \end{macrocode} % \end{macro} % \end{macro} % +% \subsection{Drawing} +% +% \begin{macro}[aux]{\@@_draw_literal:n, \@@_draw_literal:x} +% The same as the more general literal call. +% \begin{macrocode} +\cs_new_eq:NN \@@_draw_literal:n \@@_literal:n +\cs_generate_variant:Nn \@@_draw_literal:n { x } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\@@_draw_begin:, \@@_draw_end:} +% A drawing needs to be set up such that the co-ordinate system is +% translated. That is done inside a scope, which as described below +% \begin{macrocode} +\cs_new_protected:Npn \@@_draw_begin: + { + \@@_draw_scope_begin: + \@@_draw_scope:n { transform="translate({?x},{?y})~scale(1,-1)" } + } +\cs_new_protected:Npn \@@_draw_end: + { \@@_draw_scope_end: } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\@@_draw_scope_begin:, \@@_draw_scope_end:} +% \begin{macro}[aux]{\@@_draw_scope:n, \@@_draw_scope:x} +% \begin{variable}[aux]{\g_@@_draw_scope_int, \l_@@_draw_scope_int} +% Several settings that with other drivers are \enquote{stand alone} have +% to be given as part of a scope in SVG. As a result, there is a need to +% provide a mechanism to automatically close these extra scopes. That is +% done using a dedicated function and a pair of tracking variables. Within +% each graphics scope we use a global variable to do the work, with a group +% used to save the value between scopes. The result is that no direct action +% is needed when creating a scope. +% \begin{macrocode} +\cs_new_protected:Npn \@@_draw_scope_begin: + { + \int_set_eq:NN + \l_@@_draw_scope_int + \g_@@_draw_scope_int + \group_begin: + \int_gset:Nn \g_@@_draw_scope_int { 0 } + } +\cs_new_protected:Npn \@@_draw_scope_end: + { + \prg_replicate:nn + { \g_@@_draw_scope_int } + { \@@_draw_literal:n { } } + \group_end: + \int_gset_eq:NN + \g_@@_draw_scope_int + \l_@@_draw_scope_int + } +\cs_new_protected:Npn \@@_draw_scope:n #1 + { + \@@_draw_literal:n { } + \int_gincr:N \g_@@_draw_scope_int + } +\cs_generate_variant:Nn \@@_draw_scope:n { x } +\int_new:N \g_@@_draw_scope_int +\int_new:N \l_@@_draw_scope_int +% \end{macrocode} +% \end{variable} +% \end{macro} +% \end{macro} +% +% \begin{macro}[int]{\@@_draw_moveto:nn, \@@_draw_lineto:nn} +% \begin{macro}[int]{\@@_draw_rectangle:nnnn} +% \begin{macro}[int]{\@@_draw_curveto:nnnnnn} +% \begin{macro}[aux]{\@@_draw_add_to_path:n} +% \begin{variable}[aux]{\g_@@_draw_path_tl} +% Once again, some work is needed to get path constructs correct. Rather +% then write the values as they are given, the entire path needs to be +% collected up before being output in one go. For that we use a dedicated +% storage routine, which will add spaces as required. Since paths should +% be fully expanded there is no need to worry about the internal +% \texttt{x}-type expansion. +% \begin{macrocode} +\cs_new_protected:Npn \@@_draw_moveto:nn #1#2 + { + \@@_draw_add_to_path:n + { M ~ \dim_to_decimal:n {#1} ~ \dim_to_decimal:n {#2} } + } +\cs_new_protected:Npn \@@_draw_lineto:nn #1#2 + { + \@@_draw_add_to_path:n + { L ~ \dim_to_decimal:n {#1} ~ \dim_to_decimal:n {#2} } + } +\cs_new_protected:Npn \@@_draw_rectangle:nnnn #1#2#3#4 + { + \@@_draw_add_to_path:n + { + M ~ \dim_to_decimal:n {#1} ~ \dim_to_decimal:n {#2} + h ~ \dim_to_decimal:n {#3} ~ + v ~ \dim_to_decimal:n {#4} ~ + h ~ \dim_to_decimal:n { -#3 } ~ + Z + } + } +\cs_new_protected:Npn \@@_draw_curveto:nnnnnn #1#2#3#4#5#6 + { + \@@_draw_add_to_path:n + { + C ~ + \dim_to_decimal:n {#1} ~ \dim_to_decimal:n {#2} ~ + \dim_to_decimal:n {#3} ~ \dim_to_decimal:n {#4} ~ + \dim_to_decimal:n {#5} ~ \dim_to_decimal:n {#6} + } + } +\cs_new_protected:Npn \@@_draw_add_to_path:n #1 + { + \tl_gset:Nx \g_@@_draw_path_tl + { + \g_@@_draw_path_tl + \tl_if_empty:NF \g_@@_draw_path_tl { \c_space_tl } + #1 + } + } +\tl_new:N \g_@@_draw_path_tl +% \end{macrocode} +% \end{variable} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[int]{\@@_draw_evenodd_rule:, \@@_draw_nonzero_rule:} +% The fill rules here have to be handled as scopes. +% \begin{macrocode} +\cs_new_protected:Npn \@@_draw_evenodd_rule: + { \@@_draw_scope:n { fill-rule="evenodd" } } +\cs_new_protected:Npn \@@_draw_nonzero_rule: + { \@@_draw_scope:n { fill-rule="nonzero" } } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\@@_draw_path:n} +% \begin{macro}[int] +% { +% \@@_draw_closepath: , +% \@@_draw_stroke: , +% \@@_draw_closestroke: , +% \@@_draw_fill: , +% \@@_draw_fillstroke: , +% \@@_draw_clip: , +% \@@_draw_discardpath: +% } +% \begin{variable}[aux]{\g_@@_draw_clip_bool} +% \begin{variable}[aux]{\g_@@_draw_path_int} +% Setting fill and stroke effects and doing clipping all has to be done using +% scopes. This means setting up the various requirements in a shared +% auxiliary which deals with the bits and pieces. Clipping paths are reused +% for path drawing: not essential but avoids constructing them twice. +% Discarding a path needs a separate function as it's not quite the same. +% \begin{macrocode} +\cs_new_protected:Npn \@@_draw_closepath: + { \@@_draw_add_to_path:n { Z } } +\cs_new_protected:Npn \@@_draw_path:n #1 + { + \bool_if:NTF \g_@@_draw_clip_bool + { + \int_gincr:N \g_@@_clip_path_int + \@@_draw_literal:x + { + < clipPath~id = " l3cp \int_use:N \g_@@_clip_path_int " > + { ?nl } + { ?nl } + < /clipPath > { ? nl } + < + use~xlink:href = + "\c_hash_str l3path \int_use:N \g_@@_path_int " ~ + #1 + /> + } + \@@_draw_scope:x + { + clip-path = + "url( \c_hash_str l3cp \int_use:N \g_@@_clip_path_int)" + } + } + { + \@@_draw_literal:x + { } + } + \tl_gclear:N \g_@@_draw_path_tl + \bool_gset_false:N \g_@@_draw_clip_bool + } +\int_new:N \g_@@_path_int +\cs_new_protected:Npn \@@_draw_stroke: + { \@@_draw_path:n { style="fill:none" } } +\cs_new_protected:Npn \@@_draw_closestroke: + { + \@@_draw_closepath: + \@@_draw_stroke: + } +\cs_new_protected:Npn \@@_draw_fill: + { \@@_draw_path:n { style="stroke:none" } } +\cs_new_protected:Npn \@@_draw_fillstroke: + { \@@_draw_path:n { } } +\cs_new_protected:Npn \@@_draw_clip: + { \bool_gset_true:N \g_@@_draw_clip_bool } +\bool_new:N \g_@@_draw_clip_bool +\cs_new_protected:Npn \@@_draw_discardpath: + { + \bool_if:NT \g_@@_draw_clip_bool + { + \int_gincr:N \g_@@_clip_path_int + \@@_draw_literal:x + { + < clipPath~id = " l3cp \int_use:N \g_@@_clip_path_int " > + { ?nl } + { ?nl } + < /clipPath > + } + \@@_draw_scope:x + { + clip-path = + "url( \c_hash_str l3cp \int_use:N \g_@@_clip_path_int)" + } + } + \tl_gclear:N \g_@@_draw_path_tl + \bool_gset_false:N \g_@@_draw_clip_bool + } +% \end{macrocode} +% \end{variable} +% \end{variable} +% \end{macro} +% \end{macro} +% +% \begin{macro}[int]{\@@_draw_dash:nn} +% \begin{macro}[aux]{\@@_draw_dash:n} +% \begin{macro}[aux]{\@@_draw_dash_aux:nn} +% \begin{macro}[int]{\@@_draw_linewidth:n} +% \begin{macro}[int]{\@@_draw_miterlimit:n} +% \begin{macro}[int] +% { +% \@@_draw_cap_butt:, \@@_draw_cap_round:, \@@_draw_cap_rectangle:, +% \@@_draw_join_miter:, \@@_draw_join_round:, \@@_draw_join_bevel: +% } +% All of these ideas are properties of scopes in SVG. The only slight +% complexity is converting the dash array properly (doing any required +% maths). +% \begin{macrocode} +\cs_new_protected:Npn \@@_draw_dash:nn #1#2 + { + \use:x + { + \@@_draw_dash_aux:nn + { \clist_map_function:nn {#1} \@@_draw_dash:n } + { \dim_to_decimal:n {#2} } + } + } +\cs_new:Npn \@@_draw_dash:n #1 + { , \dim_to_decimal_in_bp:n {#1} } +\cs_new_protected:Npn \@@_draw_dash_aux:nn #1#2 + { + \@@_draw_scope:x + { + stroke-dasharray = + " + \tl_if_empty:oTF { \use_none:n #1 } + { none } + { \use_none:n #1 } + " ~ + stroke-offset=" #2 " + } + } +\cs_new_protected:Npn \@@_draw_linewidth:n #1 + { \@@_draw_scope:x { stroke-width=" \dim_to_decimal:n {#1} " } } +\cs_new_protected:Npn \@@_draw_miterlimit:n #1 + { \@@_draw_scope:x { stroke-miterlimit=" \fp_eval:n {#1} " } } +\cs_new_protected:Npn \@@_draw_cap_butt: + { \@@_draw_scope:n { stroke-linecap="butt" } } +\cs_new_protected:Npn \@@_draw_cap_round: + { \@@_draw_scope:n { stroke-linecap="round" } } +\cs_new_protected:Npn \@@_draw_cap_rectangle: + { \@@_draw_scope:n { stroke-linecap="square" } } +\cs_new_protected:Npn \@@_draw_join_miter: + { \@@_draw_scope:n { stroke-linejoin="miter" } } +\cs_new_protected:Npn \@@_draw_join_round: + { \@@_draw_scope:n { stroke-linejoin="round" } } +\cs_new_protected:Npn \@@_draw_join_bevel: + { \@@_draw_scope:n { stroke-linejoin="bevel" } } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[int] +% { +% \@@_draw_color_cmyk:nnnn , +% \@@_draw_color_cmyk_fill:nnnn , +% \@@_draw_color_cmyk_stroke:nnnn +% } +% \begin{macro}[int] +% { +% \@@_draw_color_gray:n , +% \@@_draw_color_gray_fill:n , +% \@@_draw_color_gray_stroke:n +% } +% \begin{macro}[int] +% { +% \@@_draw_color_rgb:nnn , +% \@@_draw_color_rgb_fill:nnn , +% \@@_draw_color_rgb_stroke:nnn +% } +% SVG only works with RGB colors, so there is some conversion to +% do. The values also need to be given as percentages, which means a +% little more maths. +% \begin{macrocode} +\cs_new_protected:Npn \@@_draw_color_cmyk_aux:NNnnnnn #1#2#3#4#5#6 + { + \use:x + { + \@@_draw_color_rgb_auxii:nnn + { \fp_eval:n { -100 * ( (#3) * ( 1 - (#6) ) - 1 ) } } + { \fp_eval:n { -100 * ( (#4) * ( 1 - (#6) ) + #6 - 1 ) } } + { \fp_eval:n { -100 * ( (#5) * ( 1 - (#6) ) + #6 - 1 ) } } + } + #1 #2 + } +\cs_new_protected:Npn \@@_draw_color_cmyk:nnnn + { \@@_draw_color_cmyk_aux:NNnnnnn \c_true_bool \c_true_bool } +\cs_new_protected:Npn \@@_draw_color_cmyk_fill:nnnn + { \@@_draw_color_cmyk_aux:NNnnnnn \c_false_bool \c_true_bool } +\cs_new_protected:Npn \@@_draw_color_cmyk_stroke:nnnn + { \@@_draw_color_cmyk_aux:NNnnnnn \c_true_bool \c_false_bool } +\cs_new_protected:Npn \@@_draw_color_gray_aux:NNn #1#2#3 + { + \use:x + { + \@@_draw_color_gray_aux:nNN + { \fp_eval:n { 100 * (#3)} } + } + #1 #2 + } +\cs_new_protected:Npn \@@_draw_color_gray_aux:nNN #1 + { \@@_draw_color_rgb_auxii:nnnNN {#1} {#1} {#1} } +\cs_generate_variant:Nn \@@_draw_color_gray_aux:nNN { x } +\cs_new_protected:Npn \@@_draw_color_gray:n + { \@@_draw_color_gray_aux:NNn \c_true_bool \c_true_bool } +\cs_new_protected:Npn \@@_draw_color_gray_fill:n + { \@@_draw_color_gray_aux:NNn \c_false_bool \c_true_bool } +\cs_new_protected:Npn \@@_draw_color_gray_stroke:n + { \@@_draw_color_gray_aux:NNn \c_true_bool \c_false_bool } +\cs_new_protected:Npn \@@_draw_color_rgb_auxi:NNnnn #1#2#3#4#5 + { + \use:x + { + \@@_draw_color_rgb_auxii:nnnNN + { \fp_eval:n { 100 * (#3) } } + { \fp_eval:n { 100 * (#4) } } + { \fp_eval:n { 100 * (#5) } } + } + #1 #2 + } +\cs_new_protected:Npn \@@_draw_color_rgb_auxii:nnnNN #1#2#3#4#5 + { + \@@_draw_scope:x + { + \bool_if:NT #4 + { + fill = + " + rgb + ( + #1 \c_percent_str , + #2 \c_percent_str , + #3 \c_percent_str + ) + " + \bool_if:NT #5 { ~ } + } + \bool_if:NT #5 + { + stroke = + " + rgb + ( + #1 \c_percent_str , + #2 \c_percent_str , + #3 \c_percent_str + ) + " + } + } + } +\cs_new_protected:Npn \@@_draw_color_rgb:nnn + { \@@_draw_color_rgb_auxi:NNnnn \c_true_bool \c_true_bool } +\cs_new_protected:Npn \@@_draw_color_rgb_fill:nnn + { \@@_draw_color_rgb_auxi:NNnnn \c_false_bool \c_true_bool } +\cs_new_protected:Npn \@@_draw_color_rgb_stroke:nnn + { \@@_draw_color_rgb_auxi:NNnnn \c_true_bool \c_false_bool } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[int]{\@@_draw_transformcm:nnnnnn} +% The first four arguments here are floats (the affine matrix), the last +% two are a displacement vector. Once again, force evaluation to allow for +% caching. +% \begin{macrocode} +\cs_new_protected:Npn \@@_draw_transformcm:nnnnnn #1#2#3#4#5#6 + { + \@@_draw_scope:x + { + transform = + " + matrix + ( + \fp_eval:n {#1} , \fp_eval:n {#2} , + \fp_eval:n {#3} , \fp_eval:n {#4} , + \dim_to_decimal:n {#5} , \dim_to_decimal:n {#6} + ) + " + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\@@_draw_hbox:Nnnnnnn} +% No special savings can be made here: simply displace the box inside +% a scope. As there is nothing to re-box, just make the box passed of +% zero size. +% \begin{macrocode} +\cs_new_protected:Npn \@@_draw_hbox:Nnnnnnn #1#2#3#4#5#6#7 + { + \@@_scope_begin: + \@@_draw_transformcm:nnnnnn {#2} {#3} {#4} {#5} {#6} {#7} + \@@_literal:n + { + < g~ + stroke="none"~ + transform="scale(-1,1)~translate({?x},{?y})~scale(-1,-1)" + > + } + \group_begin: + \box_set_wd:Nn #1 { 0pt } + \box_set_ht:Nn #1 { 0pt } + \box_set_dp:Nn #1 { 0pt } + \box_use:N #1 + \group_end: + \@@_literal:n { } + \@@_scope_end: + } +% \end{macrocode} +% \end{macro} +% % \begin{macrocode} % % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx b/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx index c96720f149b..ba6f3b4eb7a 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -%% File: l3expan.dtx Copyright (C) 1990-2015 The LaTeX3 project +%% File: l3expan.dtx Copyright (C) 1990-2016 The LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -37,7 +37,7 @@ \documentclass[full]{l3doc} % %<*driver|package> -\GetIdInfo$Id: l3expan.dtx 5983 2015-09-10 18:57:56Z joseph $ +\GetIdInfo$Id: l3expan.dtx 6684 2016-08-19 15:21:49Z bruno $ {L3 Argument expansion} % %<*driver> @@ -105,11 +105,15 @@ % how the variants are defined. They just expand into the appropriate % |\exp_| function followed by the desired base function, \emph{e.g.} % \begin{quote} -% |\cs_new_nopar:Npn \seq_gpush:No { \exp_args:NNo \seq_gpush:Nn }| +% |\cs_generate_variant:Nn \seq_gpush:Nn { No } | +% \end{quote} +% results in the definition of |\seq_gpush:No| +% \begin{quote} +% |\cs_new:Npn \seq_gpush:No { \exp_args:NNo \seq_gpush:Nn }| % \end{quote} % Providing variants in this way in style files is uncritical as the -% \cs{cs_new_nopar:Npn} function will silently accept definitions whenever the -% new definition is identical to an already given one. Therefore adding +% \cs{cs_generate_variant:Nn} function will only create new definitions if +% there is not already one available. Therefore adding % such definition to later releases of the kernel will not make such % style files obsolete. % @@ -119,6 +123,10 @@ % \section{Methods for defining variants} % \label{sec:l3expan:variants-method} % +% ^^A Bruno: Should we put a table of variant types (N, c, n, V, v, o, f, x) for reference here? +% +% ^^A Bruno: Should \cs_generate_variant:Nn \foo:n { c } and \foo:N { o } really be ok? +% % \begin{function}[updated = 2015-08-06]{\cs_generate_variant:Nn} % \begin{syntax} % \cs{cs_generate_variant:Nn} \meta{parent control sequence} \Arg{variant argument specifiers} @@ -143,19 +151,22 @@ % \begin{verbatim} % \cs_generate_variant:Nn \foo:Nn { NV , cV } % \end{verbatim} -% would generate the functions |\foo:NV| and |\foo:cV| in the -% same way. The \cs{cs_generate_variant:Nn} function can only be -% applied if the \meta{parent control sequence} is already defined. If -% the \meta{parent control sequence} is protected then the new sequence -% will also be protected. The \meta{variant} is created globally, as -% is any \cs{exp_args:N\meta{variant}} function needed to carry out -% the expansion. +% would generate the functions |\foo:NV| and |\foo:cV| in the same +% way. The \cs{cs_generate_variant:Nn} function can only be applied if +% the \meta{parent control sequence} is already defined. Only |n|~and +% |N| arguments can be changed to other types. If the \meta{parent +% control sequence} is protected or if the \meta{variant} involves +% |x|~arguments, then the \meta{variant control sequence} will also be +% protected. The \meta{variant} is created globally, as is any +% \cs{exp_args:N\meta{variant}} function needed to carry out the +% expansion. % \end{function} % % \section{Introducing the variants} % % The available internal functions for argument expansion come in two -% flavours, some of them are faster then others. Therefore it is usually +% flavours, some of them are faster then others. Therefore +% (when speed is important) it is usually % best to follow the following guidelines when defining new functions % that are supposed to come with variant forms: % \begin{itemize} @@ -180,15 +191,11 @@ % not expanded. % \end{itemize} % -% ^^A Bruno: We should drop part of that paragraph eventually. % The |V| type returns the value of a register, which can be one of -% |tl|, |num|, |int|, |skip|, |dim|, |toks|, or built-in \TeX{} +% |tl|, |int|, |skip|, |dim|, |toks|, or built-in \TeX{} % registers. The |v| type is the same except it first creates a % control sequence out of its argument before returning the -% value. This recent addition to the argument specifiers may shake -% things up a bit as most places where |o| is used will be replaced by -% |V|. The documentation you are currently reading will therefore -% require a fair bit of re-writing. +% value. % % In general, the programmer should not need to be concerned with % expansion control. When simply using the content of a variable, @@ -238,13 +245,13 @@ % At the same time, \texttt{f}-type expansion stops at the emph{first} % non-expandable token. This means for example that both % \begin{verbatim} -% \tl_set:No \l_tmpa_tl { { \l_tmpa_tl } } +% \tl_set:No \l_tmpa_tl { { \g_tmpb_tl } } % \end{verbatim} % and % \begin{verbatim} -% \tl_set:Nf \l_tmpa_tl { { \l_tmpa_tl } } +% \tl_set:Nf \l_tmpa_tl { { \g_tmpb_tl } } % \end{verbatim} -% leave |\l_tmpa_tl| unchanged: |{| is the first token in the +% leave |\g_tmpb_tl| unchanged: |{| is the first token in the % argument and is non-expandable. % % \section{Manipulating the first argument} @@ -455,8 +462,8 @@ % % \begin{function}[EXP, updated = 2012-02-12] % { -% \exp_last_unbraced:Nf, % \exp_last_unbraced:NV, +% \exp_last_unbraced:Nf, % \exp_last_unbraced:No, % \exp_last_unbraced:Nv, % \exp_last_unbraced:Nco, @@ -625,7 +632,7 @@ % % The \pkg{expl3} language makes all efforts to hide the complexity of % \TeX{} expansion from the programmer by providing concepts that -% evaluate/expand arguments of functions prior to calling the ``base'' +% evaluate/expand arguments of functions prior to calling the \enquote{base} % functions. Thus, instead of using many \tn{expandafter} calls and % other trickery it is usually a matter of choosing the right variant % of a function to achieve a desired result. @@ -674,10 +681,10 @@ % \cs{exp_end:} gets generated. % \end{function} % \footnotetext{Due to the implementation you might get the character -% in position 0 in the current font (typically ``\texttt`'') +% in position 0 in the current font (typically \enquote{\texttt{`}}) % in the output without any error message!} % -% \begin{function}[added=2015-08-23,EXP] +% \begin{function}[added=2015-08-23, EXP, label = \exp_end_continue_f:w] % { % \exp:w , % \exp_end_continue_f:w @@ -729,7 +736,7 @@ % \footnotetext{In this particular case you may get a character into % the output as well as an error message.} % -% \begin{function}[added=2015-08-23,EXP] +% \begin{function}[added=2015-08-23, EXP, label = \exp_end_continue_f:nw] % { % \exp:w , % \exp_end_continue_f:nw @@ -755,7 +762,7 @@ % % \begin{function}{\::n, \::N, \::p, \::c, \::o, \::f, \::x, \::v, \::V, \:::} % \begin{syntax} -% |\cs_set_nopar:Npn \exp_args:Ncof { \::c \::o \::f \::: }| +% |\cs_set:Npn \exp_args:Ncof { \::c \::o \::f \::: }| % \end{syntax} % Internal forms for the base expansion types. These names do \emph{not} % conform to the general \LaTeX3 approach as this makes them more readily @@ -789,7 +796,7 @@ % In this section a general mechanism for defining functions to handle % argument handling is defined. These general expansion functions are % expandable unless |x| is used. (Any version of |x| is going to have -% to use one of the \LaTeX3 names for \cs{cs_set_nopar:Npx} at some +% to use one of the \LaTeX3 names for \cs{cs_set:Npx} at some % point, and so is never going to be expandable.) % % The definition of expansion functions with this technique happens @@ -1180,7 +1187,7 @@ % % \begin{macro}{\exp_args:Nx} % \begin{macrocode} -\cs_new_protected_nopar:Npn \exp_args:Nx { \::x \::: } +\cs_new_protected:Npn \exp_args:Nx { \::x \::: } % \end{macrocode} % \end{macro} % @@ -1198,21 +1205,21 @@ % Here are the actual function definitions, using the helper functions % above. % \begin{macrocode} -\cs_new_nopar:Npn \exp_args:Nnc { \::n \::c \::: } -\cs_new_nopar:Npn \exp_args:Nfo { \::f \::o \::: } -\cs_new_nopar:Npn \exp_args:Nff { \::f \::f \::: } -\cs_new_nopar:Npn \exp_args:Nnf { \::n \::f \::: } -\cs_new_nopar:Npn \exp_args:Nno { \::n \::o \::: } -\cs_new_nopar:Npn \exp_args:NnV { \::n \::V \::: } -\cs_new_nopar:Npn \exp_args:Noo { \::o \::o \::: } -\cs_new_nopar:Npn \exp_args:Nof { \::o \::f \::: } -\cs_new_nopar:Npn \exp_args:Noc { \::o \::c \::: } -\cs_new_protected_nopar:Npn \exp_args:NNx { \::N \::x \::: } -\cs_new_protected_nopar:Npn \exp_args:Ncx { \::c \::x \::: } -\cs_new_protected_nopar:Npn \exp_args:Nnx { \::n \::x \::: } -\cs_new_protected_nopar:Npn \exp_args:Nox { \::o \::x \::: } -\cs_new_protected_nopar:Npn \exp_args:Nxo { \::x \::o \::: } -\cs_new_protected_nopar:Npn \exp_args:Nxx { \::x \::x \::: } +\cs_new:Npn \exp_args:Nnc { \::n \::c \::: } +\cs_new:Npn \exp_args:Nfo { \::f \::o \::: } +\cs_new:Npn \exp_args:Nff { \::f \::f \::: } +\cs_new:Npn \exp_args:Nnf { \::n \::f \::: } +\cs_new:Npn \exp_args:Nno { \::n \::o \::: } +\cs_new:Npn \exp_args:NnV { \::n \::V \::: } +\cs_new:Npn \exp_args:Noo { \::o \::o \::: } +\cs_new:Npn \exp_args:Nof { \::o \::f \::: } +\cs_new:Npn \exp_args:Noc { \::o \::c \::: } +\cs_new_protected:Npn \exp_args:NNx { \::N \::x \::: } +\cs_new_protected:Npn \exp_args:Ncx { \::c \::x \::: } +\cs_new_protected:Npn \exp_args:Nnx { \::n \::x \::: } +\cs_new_protected:Npn \exp_args:Nox { \::o \::x \::: } +\cs_new_protected:Npn \exp_args:Nxo { \::x \::o \::: } +\cs_new_protected:Npn \exp_args:Nxx { \::x \::x \::: } % \end{macrocode} % \end{macro} % \end{macro} @@ -1229,19 +1236,19 @@ % \exp_args:Nccx, \exp_args:Ncnx, \exp_args:Noox, % } % \begin{macrocode} -\cs_new_nopar:Npn \exp_args:NNno { \::N \::n \::o \::: } -\cs_new_nopar:Npn \exp_args:NNoo { \::N \::o \::o \::: } -\cs_new_nopar:Npn \exp_args:Nnnc { \::n \::n \::c \::: } -\cs_new_nopar:Npn \exp_args:Nnno { \::n \::n \::o \::: } -\cs_new_nopar:Npn \exp_args:Nooo { \::o \::o \::o \::: } -\cs_new_protected_nopar:Npn \exp_args:NNNx { \::N \::N \::x \::: } -\cs_new_protected_nopar:Npn \exp_args:NNnx { \::N \::n \::x \::: } -\cs_new_protected_nopar:Npn \exp_args:NNox { \::N \::o \::x \::: } -\cs_new_protected_nopar:Npn \exp_args:Nnnx { \::n \::n \::x \::: } -\cs_new_protected_nopar:Npn \exp_args:Nnox { \::n \::o \::x \::: } -\cs_new_protected_nopar:Npn \exp_args:Nccx { \::c \::c \::x \::: } -\cs_new_protected_nopar:Npn \exp_args:Ncnx { \::c \::n \::x \::: } -\cs_new_protected_nopar:Npn \exp_args:Noox { \::o \::o \::x \::: } +\cs_new:Npn \exp_args:NNno { \::N \::n \::o \::: } +\cs_new:Npn \exp_args:NNoo { \::N \::o \::o \::: } +\cs_new:Npn \exp_args:Nnnc { \::n \::n \::c \::: } +\cs_new:Npn \exp_args:Nnno { \::n \::n \::o \::: } +\cs_new:Npn \exp_args:Nooo { \::o \::o \::o \::: } +\cs_new_protected:Npn \exp_args:NNNx { \::N \::N \::x \::: } +\cs_new_protected:Npn \exp_args:NNnx { \::N \::n \::x \::: } +\cs_new_protected:Npn \exp_args:NNox { \::N \::o \::x \::: } +\cs_new_protected:Npn \exp_args:Nnnx { \::n \::n \::x \::: } +\cs_new_protected:Npn \exp_args:Nnox { \::n \::o \::x \::: } +\cs_new_protected:Npn \exp_args:Nccx { \::c \::c \::x \::: } +\cs_new_protected:Npn \exp_args:Ncnx { \::c \::n \::x \::: } +\cs_new_protected:Npn \exp_args:Noox { \::o \::o \::x \::: } % \end{macrocode} % \end{macro} % \end{macro} @@ -1338,11 +1345,11 @@ } \cs_new:Npn \exp_last_unbraced:NNNo #1#2#3#4 { \exp_after:wN #1 \exp_after:wN #2 \exp_after:wN #3 #4 } -\cs_new_nopar:Npn \exp_last_unbraced:Nno { \::n \::o_unbraced \::: } -\cs_new_nopar:Npn \exp_last_unbraced:Noo { \::o \::o_unbraced \::: } -\cs_new_nopar:Npn \exp_last_unbraced:Nfo { \::f \::o_unbraced \::: } -\cs_new_nopar:Npn \exp_last_unbraced:NnNo { \::n \::N \::o_unbraced \::: } -\cs_new_protected_nopar:Npn \exp_last_unbraced:Nx { \::x_unbraced \::: } +\cs_new:Npn \exp_last_unbraced:Nno { \::n \::o_unbraced \::: } +\cs_new:Npn \exp_last_unbraced:Noo { \::o \::o_unbraced \::: } +\cs_new:Npn \exp_last_unbraced:Nfo { \::f \::o_unbraced \::: } +\cs_new:Npn \exp_last_unbraced:NnNo { \::n \::N \::o_unbraced \::: } +\cs_new_protected:Npn \exp_last_unbraced:Nx { \::x_unbraced \::: } % \end{macrocode} % \end{macro} % \end{macro} @@ -1414,7 +1421,7 @@ % \begin{macro}{\exp_end_continue_f:w} % \begin{macro}{\exp_end_continue_f:nw} % -% To trigger a sequence of ``arbitrary'' many expansions we need a +% To trigger a sequence of \enquote{arbitrary} many expansions we need a % method to invoke \TeX's expansion mechanism in such a way that a) % we are able to stop it in a controlled manner and b) that the % result of what triggered the expansion in the first place is @@ -1441,7 +1448,7 @@ % (Note that according to our specification all tokens we expand % initiated by \cs{exp:w} are supposed to be expandable (as well as % their replacement text in the expansion) so we will not encounter -% a ``number'' that actually result in a roman numeral being +% a \enquote{number} that actually result in a roman numeral being % generated. Or if we do then the programmer made a mistake.) % % If on the other hand we want to stop the initial expansion @@ -1485,7 +1492,7 @@ % \end{arguments} % After making sure that the base form exists, test whether it is % protected or not and define \cs{@@_tmp:w} as either -% \cs{cs_new_nopar:Npx} or \cs{cs_new_protected_nopar:Npx}, which is +% \cs{cs_new:Npx} or \cs{cs_new_protected:Npx}, which is % then used to define all the variants (except those involving % \texttt{x}-expansion, always protected). Split up the original base % function only once, to grab its name and signature. Then we wish to @@ -1526,21 +1533,21 @@ % |\bot|, |\splittop|, or |\splitbot|, with |\| replaced by the % appropriate escape character. If |pr| appears in the part before % |ma|, the first \cs{q_mark} is taken as an argument of the |wwNw| -% auxiliary, and |#3| is \cs{cs_new_protected_nopar:Npx}, otherwise it -% is \cs{cs_new_nopar:Npx}. +% auxiliary, and |#3| is \cs{cs_new_protected:Npx}, otherwise it +% is \cs{cs_new:Npx}. % \begin{macrocode} \cs_new_protected:Npx \@@_generate_variant:N #1 { \exp_not:N \exp_after:wN \exp_not:N \if_meaning:w \exp_not:N \exp_not:N #1 #1 - \cs_set_eq:NN \exp_not:N \@@_tmp:w \cs_new_protected_nopar:Npx + \cs_set_eq:NN \exp_not:N \@@_tmp:w \cs_new_protected:Npx \exp_not:N \else: \exp_not:N \exp_after:wN \exp_not:N \@@_generate_variant:ww \exp_not:N \token_to_meaning:N #1 \tl_to_str:n { ma } \exp_not:N \q_mark - \exp_not:N \q_mark \cs_new_protected_nopar:Npx + \exp_not:N \q_mark \cs_new_protected:Npx \tl_to_str:n { pr } - \exp_not:N \q_mark \cs_new_nopar:Npx + \exp_not:N \q_mark \cs_new:Npx \exp_not:N \q_stop \exp_not:N \fi: } @@ -1800,7 +1807,7 @@ % If the variant form has already been defined, log its existence. % Otherwise, make sure that the |\exp_args:N #3| form is defined, and % if it contains |x|, change \cs{@@_tmp:w} locally to -% \cs{cs_new_protected_nopar:Npx}. Then define the variant by +% \cs{cs_new_protected:Npx}. Then define the variant by % combining the |\exp_args:N #3| variant and the base function. % \begin{macrocode} \cs_new_protected:Npn \@@_generate_variant:wwNN @@ -1839,11 +1846,11 @@ { \exp_not:N \@@_generate_internal_variant:wwnNwnn #1 \exp_not:N \q_mark - { \cs_set_eq:NN \exp_not:N \@@_tmp:w \cs_new_protected_nopar:Npx } - \cs_new_protected_nopar:cpx + { \cs_set_eq:NN \exp_not:N \@@_tmp:w \cs_new_protected:Npx } + \cs_new_protected:cpx \token_to_str:N x \exp_not:N \q_mark { } - \cs_new_nopar:cpx + \cs_new:cpx \exp_not:N \q_stop { exp_args:N #1 } { diff --git a/Master/texmf-dist/source/latex/l3kernel/l3file.dtx b/Master/texmf-dist/source/latex/l3kernel/l3file.dtx index a60bb8819b0..aca87c16595 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3file.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3file.dtx @@ -37,7 +37,7 @@ \documentclass[full]{l3doc} % %<*driver|package> -\GetIdInfo$Id: l3file.dtx 6458 2016-03-25 21:19:04Z joseph $ +\GetIdInfo$Id: l3file.dtx 6685 2016-08-19 16:26:52Z bruno $ {L3 File and I/O operations} % %<*driver> @@ -69,9 +69,9 @@ % \begin{documentation} % % This module provides functions for working with external files. Some of these -% functions apply to an entire file, and have prefix \cs{file_\ldots}, while +% functions apply to an entire file, and have prefix \cs[no-index]{file_\ldots}, while % others are used to work with files on a line by line basis and have prefix -% \cs{ior_\ldots} (reading) or \cs{iow_\ldots} (writing). +% \cs[no-index]{ior_\ldots} (reading) or \cs[no-index]{iow_\ldots} (writing). % % It is important to remember that when reading external files \TeX{} will % attempt to locate them both the operating system path and entries in the @@ -178,9 +178,9 @@ % \end{syntax} % Globally reserves the name of the \meta{stream}, either for reading % or for writing as appropriate. The \meta{stream} is not opened until -% the appropriate \cs{\ldots_open:Nn} function is used. Attempting to +% the appropriate \cs[no-index]{\ldots_open:Nn} function is used. Attempting to % use a \meta{stream} which has not been opened is an error, and the -% \meta{stream} will behave as the corresponding \cs{c_term_\ldots}. +% \meta{stream} will behave as the corresponding \cs[no-index]{c_term_\ldots}. % \end{function} % % \begin{function}[updated = 2012-02-10]{\ior_open:Nn, \ior_open:cn} @@ -528,7 +528,7 @@ % % \begin{variable}{\l__file_internal_name_tl} % Used to return the full name of a file for internal use. This is -% set by \cs{file_if_exist:n(TF)} and \cs{__file_if_exist:nT}, and +% set by \cs{file_if_exist:nTF} and \cs{__file_if_exist:nT}, and % the value may then be used to load a file directly provided no % further operations intervene. % \end{variable} @@ -887,7 +887,7 @@ % (we capture it \cs{AtBeginDocument} into % \cs{g_@@_record_seq}), turning each file name into a string. % \begin{macrocode} -\cs_new_protected_nopar:Npn \file_list: +\cs_new_protected:Npn \file_list: { \seq_set_eq:NN \l_@@_internal_seq \g_@@_record_seq %<*package> @@ -1058,7 +1058,7 @@ % being \tn{outer}. % \begin{macrocode} %<*package> -\exp_args:NNf \cs_new_protected_nopar:Npn \@@_new:N +\exp_args:NNf \cs_new_protected:Npn \@@_new:N { \exp_args:NNc \exp_after:wN \exp_stop_f: { newread } } % % \end{macrocode} @@ -1133,7 +1133,7 @@ % translating |ior|/|iow| to English. The list of streams is % formatted using \cs{__msg_show_item_unbraced:nn}. % \begin{macrocode} -\cs_new_protected_nopar:Npn \ior_list_streams: +\cs_new_protected:Npn \ior_list_streams: { \@@_list_streams:Nn \g_@@_streams_prop { ior } } \cs_new_protected:Npn \@@_list_streams:Nn #1#2 { @@ -1298,7 +1298,7 @@ % that it is not \tn{outer}. % \begin{macrocode} %<*package> -\exp_args:NNf \cs_new_protected_nopar:Npn \@@_new:N +\exp_args:NNf \cs_new_protected:Npn \@@_new:N { \exp_args:NNc \exp_after:wN \exp_stop_f: { newwrite } } % % \end{macrocode} @@ -1366,7 +1366,7 @@ % \begin{macro}{\@@_list_streams:Nn} % Done as for input, but with a copy of the auxiliary so the name is correct. % \begin{macrocode} -\cs_new_protected_nopar:Npn \iow_list_streams: +\cs_new_protected:Npn \iow_list_streams: { \@@_list_streams:Nn \g_@@_streams_prop { iow } } \cs_new_eq:NN \@@_list_streams:Nn \__ior_list_streams:Nn % \end{macrocode} @@ -1443,10 +1443,10 @@ % \begin{macro}{\iow_term:n, \iow_term:x} % Writing to the log and the terminal directly are relatively easy. % \begin{macrocode} -\cs_set_protected_nopar:Npn \iow_log:x { \iow_now:Nx \c_log_iow } -\cs_new_protected_nopar:Npn \iow_log:n { \iow_now:Nn \c_log_iow } -\cs_set_protected_nopar:Npn \iow_term:x { \iow_now:Nx \c_term_iow } -\cs_new_protected_nopar:Npn \iow_term:n { \iow_now:Nn \c_term_iow } +\cs_set_protected:Npn \iow_log:x { \iow_now:Nx \c_log_iow } +\cs_new_protected:Npn \iow_log:n { \iow_now:Nn \c_log_iow } +\cs_set_protected:Npn \iow_term:x { \iow_now:Nx \c_term_iow } +\cs_new_protected:Npn \iow_term:n { \iow_now:Nn \c_term_iow } % \end{macrocode} %\end{macro} %\end{macro} @@ -1457,7 +1457,7 @@ % Global variable holding the character that forces a new line when % something is written to an output stream. % \begin{macrocode} -\cs_new_nopar:Npn \iow_newline: { ^^J } +\cs_new:Npn \iow_newline: { ^^J } % \end{macrocode} % \end{macro} % @@ -1612,7 +1612,7 @@ \__msg_kernel_expandable_error:nn { kernel } { indent-outside-wrapping-code } #1 } -\cs_new_protected_nopar:Npn \iow_indent:n { \@@_indent_error:n } +\cs_new_protected:Npn \iow_indent:n { \@@_indent_error:n } % \end{macrocode} % \end{macro} % \end{macro} @@ -1639,11 +1639,11 @@ { \group_begin: \int_set_eq:NN \tex_escapechar:D \c_minus_one - \cs_set_nopar:Npx \{ { \token_to_str:N \{ } - \cs_set_nopar:Npx \# { \token_to_str:N \# } - \cs_set_nopar:Npx \} { \token_to_str:N \} } - \cs_set_nopar:Npx \% { \token_to_str:N \% } - \cs_set_nopar:Npx \~ { \token_to_str:N \~ } + \cs_set:Npx \{ { \token_to_str:N \{ } + \cs_set:Npx \# { \token_to_str:N \# } + \cs_set:Npx \} { \token_to_str:N \} } + \cs_set:Npx \% { \token_to_str:N \% } + \cs_set:Npx \~ { \token_to_str:N \~ } \int_set:Nn \tex_escapechar:D { 92 } \cs_set_eq:NN \\ \c_@@_wrap_newline_marker_tl \cs_set_eq:NN \ \c_catcode_other_space_tl @@ -1719,11 +1719,11 @@ % be replaced once the string module is finalised with something a little % cleaner. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_wrap_set_target: +\cs_new_protected:Npn \@@_wrap_set_target: { - \cs_set_protected_nopar:Npn \@@_wrap_set_target: + \cs_set_protected:Npn \@@_wrap_set_target: { - \cs_set_protected_nopar:Npn \@@_wrap_set_target: { } + \cs_set_protected:Npn \@@_wrap_set_target: { } \tl_replace_all:Nnn \l_@@_newline_tl { ~ } { \c_space_tl } \int_set:Nn \l_@@_target_count_int { \l_iow_line_count_int - \tl_count:N \l_@@_newline_tl + \c_one } @@ -1756,7 +1756,7 @@ % Otherwise, the current line is added to the result, with the run-on text. % The current word (and its character count) are then put in the new line. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_wrap_word: +\cs_new_protected:Npn \@@_wrap_word: { \int_set:Nn \l_@@_current_word_int { \exp_args:No \str_count_ignore_spaces:n \l_@@_current_word_tl } @@ -1766,7 +1766,7 @@ { \@@_wrap_word_newline: } \@@_wrap_loop:w } -\cs_new_protected_nopar:Npn \@@_wrap_word_fits: +\cs_new_protected:Npn \@@_wrap_word_fits: { \bool_if:NTF \l_@@_line_start_bool { @@ -1782,7 +1782,7 @@ \int_incr:N \l_@@_current_line_int } } -\cs_new_protected_nopar:Npn \@@_wrap_word_newline: +\cs_new_protected:Npn \@@_wrap_word_newline: { \@@_wrap_set_target: \tl_put_right:Nx \l_@@_wrap_tl @@ -1826,7 +1826,7 @@ { \@@_wrap_special:w } { \@@_wrap_loop:w #2 ~ #3 ~ } } -\cs_new_protected_nopar:Npn \@@_wrap_newline: +\cs_new_protected:Npn \@@_wrap_newline: { \@@_wrap_set_target: \tl_put_right:Nx \l_@@_wrap_tl @@ -1835,19 +1835,19 @@ \tl_clear:N \l_@@_current_line_tl \bool_set_true:N \l_@@_line_start_bool } -\cs_new_protected_nopar:Npx \@@_wrap_indent: +\cs_new_protected:Npx \@@_wrap_indent: { \int_add:Nn \l_@@_current_indentation_int \c_four \tl_put_right:Nx \exp_not:N \l_@@_current_indentation_tl { \c_space_tl \c_space_tl \c_space_tl \c_space_tl } } -\cs_new_protected_nopar:Npn \@@_wrap_unindent: +\cs_new_protected:Npn \@@_wrap_unindent: { \int_sub:Nn \l_@@_current_indentation_int \c_four \tl_set:Nx \l_@@_current_indentation_tl { \prg_replicate:nn \l_@@_current_indentation_int { ~ } } } -\cs_new_protected_nopar:Npn \@@_wrap_end: +\cs_new_protected:Npn \@@_wrap_end: { \tl_put_right:Nx \l_@@_wrap_tl { \l_@@_current_line_tl } diff --git a/Master/texmf-dist/source/latex/l3kernel/l3final.dtx b/Master/texmf-dist/source/latex/l3kernel/l3final.dtx index 2a62d525d4a..c5217673bb7 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3final.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3final.dtx @@ -35,7 +35,7 @@ % %<*driver> \documentclass[full]{l3doc} -\GetIdInfo$Id: l3final.dtx 6411 2016-02-12 21:06:00Z joseph $ +\GetIdInfo$Id: l3final.dtx 6596 2016-06-13 21:29:58Z joseph $ {L3 Experimental format finalisation} \begin{document} \DocInput{\jobname.dtx} @@ -141,7 +141,7 @@ % \end{macrocode} % The actual mappings: these are kept low-level for performance reasons. % \begin{macrocode} - \cs_new_nopar:cpn { __char_active_C3:N } #1 + \cs_new:cpn { __char_active_C3:N } #1 { \if_meaning:w #1 ^^9f ^^ff \else: % ß - U+00DF - germandbls \if_meaning:w #1 ^^a0 ^^e0 \else: % à - U+00E0 - agrave @@ -179,7 +179,7 @@ \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: } - \cs_new_nopar:cpn { __char_active_C4:N } #1 + \cs_new:cpn { __char_active_C4:N } #1 { \if_meaning:w #1 ^^83 ^^a0 \else: % ă - U+0103 - abreve \if_meaning:w #1 ^^85 ^^a1 \else: % ą - U+0105 - aogonek @@ -197,7 +197,7 @@ \__msg_kernel_expandable_error:nn { kernel } { encoding-failure } \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: } - \cs_new_nopar:cpn { __char_active_C5:N } #1 + \cs_new:cpn { __char_active_C5:N } #1 { \if_meaning:w #1 ^^82 ^^aa \else: % ł - U+0142 - lslash \if_meaning:w #1 ^^84 ^^ab \else: % ń - U+0144 - nacute @@ -220,7 +220,7 @@ \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: \fi: } - \cs_new_nopar:cpn { __char_active_C8:N } #1 + \cs_new:cpn { __char_active_C8:N } #1 { \if_meaning:w #1 ^^99 ^^b3 \else: % ș - U+0219 - scommaaccent \if_meaning:w #1 ^^9b ^^b5 \else: % ț - U+021B - tcommaaccent diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx index 80d4f418671..265613f9025 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment %% -%% File: l3fp-assign.dtx Copyright (C) 2011-2015 The LaTeX3 project +%% File: l3fp-assign.dtx Copyright (C) 2011-2016 The LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -36,7 +36,7 @@ % %<*driver> \documentclass[full]{l3doc} -\GetIdInfo$Id: l3fp-assign.dtx 5804 2015-08-08 05:05:02Z bruno $ +\GetIdInfo$Id: l3fp-assign.dtx 6596 2016-06-13 21:29:58Z joseph $ {L3 Floating-point assignments} \begin{document} \DocInput{\jobname.dtx} @@ -164,10 +164,10 @@ % \cs{fp_eval:n}, which would convert the result away from the % internal representation and back. % \begin{macrocode} -\cs_new_protected_nopar:Npn \fp_add:Nn { \@@_add:NNNn \fp_set:Nn + } -\cs_new_protected_nopar:Npn \fp_gadd:Nn { \@@_add:NNNn \fp_gset:Nn + } -\cs_new_protected_nopar:Npn \fp_sub:Nn { \@@_add:NNNn \fp_set:Nn - } -\cs_new_protected_nopar:Npn \fp_gsub:Nn { \@@_add:NNNn \fp_gset:Nn - } +\cs_new_protected:Npn \fp_add:Nn { \@@_add:NNNn \fp_set:Nn + } +\cs_new_protected:Npn \fp_gadd:Nn { \@@_add:NNNn \fp_gset:Nn + } +\cs_new_protected:Npn \fp_sub:Nn { \@@_add:NNNn \fp_set:Nn - } +\cs_new_protected:Npn \fp_gsub:Nn { \@@_add:NNNn \fp_gset:Nn - } \cs_new_protected:Npn \@@_add:NNNn #1#2#3#4 { #1 #3 { #3 #2 \@@_parse:n {#4} } } \cs_generate_variant:Nn \fp_add:Nn { c } @@ -189,7 +189,7 @@ \__msg_show_variable:NNNnn #1 \fp_if_exist:NTF ? { } { > ~ \token_to_str:N #1 = \fp_to_tl:N #1 } } -\cs_new_protected_nopar:Npn \fp_show:n +\cs_new_protected:Npn \fp_show:n { \__msg_show_wrap:Nn \fp_to_tl:n } \cs_generate_variant:Nn \fp_show:N { c } % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx index 0c60dc96abe..ce51a27a8d5 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx @@ -36,7 +36,7 @@ % %<*driver> \documentclass[full]{l3doc} -\GetIdInfo$Id: l3fp-aux.dtx 6441 2016-03-24 10:11:59Z joseph $ +\GetIdInfo$Id: l3fp-aux.dtx 6685 2016-08-19 16:26:52Z bruno $ {L3 Floating-point support functions} \documentclass[full]{l3doc} \begin{document} @@ -125,9 +125,9 @@ % % Special floating point numbers have the form % \begin{quote} -% \cs{s_@@} \cs{@@_chk:w} \meta{case} \meta{sign} \cs{s_@@_...} |;| +% \cs{s_@@} \cs{@@_chk:w} \meta{case} \meta{sign} \cs[no-index]{s_@@_\ldots} |;| % \end{quote} -% where \cs{s_@@_...} is a scan mark carrying information about how the +% where \cs[no-index]{s_@@_\ldots} is a scan mark carrying information about how the % number was formed (useful for debugging). % % Normal floating point numbers ($\meta{case} = 1$) have the form @@ -156,16 +156,16 @@ % \toprule % \multicolumn{1}{c}{Representation} & Meaning \\ % \midrule -% 0 0 \cs{s_@@_...} \texttt{;} & Positive zero. \\ -% 0 2 \cs{s_@@_...} \texttt{;} & Negative zero. \\ +% 0 0 \cs[no-index]{s_@@_\ldots} \texttt{;} & Positive zero. \\ +% 0 2 \cs[no-index]{s_@@_\ldots} \texttt{;} & Negative zero. \\ % 1 0 \Arg{exponent} \Arg{X_1} \Arg{X_2} \Arg{X_3} \Arg{X_4} \texttt{;} % & Positive floating point. \\ % 1 2 \Arg{exponent} \Arg{X_1} \Arg{X_2} \Arg{X_3} \Arg{X_4} \texttt{;} % & Negative floating point. \\ -% 2 0 \cs{s_@@_...} \texttt{;} & Positive infinity. \\ -% 2 2 \cs{s_@@_...} \texttt{;} & Negative infinity. \\ -% 3 1 \cs{s_@@_...} \texttt{;} & Quiet \texttt{nan}. \\ -% 3 1 \cs{s_@@_...} \texttt{;} & Signalling \texttt{nan}. \\ +% 2 0 \cs[no-index]{s_@@_\ldots} \texttt{;} & Positive infinity. \\ +% 2 2 \cs[no-index]{s_@@_\ldots} \texttt{;} & Negative infinity. \\ +% 3 1 \cs[no-index]{s_@@_\ldots} \texttt{;} & Quiet \texttt{nan}. \\ +% 3 1 \cs[no-index]{s_@@_\ldots} \texttt{;} & Signalling \texttt{nan}. \\ % \bottomrule % \end{tabular} % \end{table} @@ -300,9 +300,9 @@ % {\c_zero_fp, \c_minus_zero_fp, \c_inf_fp, \c_minus_inf_fp, \c_nan_fp} % The special floating points. All of them have the form % \begin{quote} -% \cs{s_@@} \cs{@@_chk:w} \meta{case} \meta{sign} \cs{s_@@_...} |;| +% \cs{s_@@} \cs{@@_chk:w} \meta{case} \meta{sign} \cs[no-index]{s_@@_\ldots} |;| % \end{quote} -% where the dots in \cs{s_@@_...} are one of \texttt{invalid}, +% where the dots in \cs[no-index]{s_@@_\ldots} are one of \texttt{invalid}, % \texttt{underflow}, \texttt{overflow}, \texttt{division}, % \texttt{exact}, describing how the floating point was created. We % define the floating points here as \enquote{exact}. diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx index cc540f60ee4..81fa321e1b2 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx @@ -36,7 +36,7 @@ % %<*driver> \documentclass[full]{l3doc} -\GetIdInfo$Id: l3fp-basics.dtx 6441 2016-03-24 10:11:59Z joseph $ +\GetIdInfo$Id: l3fp-basics.dtx 6596 2016-06-13 21:29:58Z joseph $ {L3 Floating-point arithmetic} \begin{document} \DocInput{\jobname.dtx} @@ -181,7 +181,7 @@ % \cs{@@_+_o:ww} can still check that it was followed by \cs{s_@@} and % not arbitrary junk. % \begin{macrocode} -\cs_new_nopar:cpx { @@_-_o:ww } \s_@@ +\cs_new:cpx { @@_-_o:ww } \s_@@ { \exp_not:c { @@_+_o:ww } \exp_not:n { \s_@@ \@@_neg_sign:N } @@ -777,7 +777,7 @@ % is the operation for normal floating points. The fourth is there % for extra cases needed in \cs{@@_/_o:ww}. % \begin{macrocode} -\cs_new_nopar:cpn { @@_*_o:ww } +\cs_new:cpn { @@_*_o:ww } { \@@_mul_cases_o:NnNnww * @@ -1020,7 +1020,7 @@ % \cs{if_case:w} construction in \cs{@@_mul_cases_o:NnNnww} are % provided as the fourth argument here. % \begin{macrocode} -\cs_new_nopar:cpn { @@_/_o:ww } +\cs_new:cpn { @@_/_o:ww } { \@@_mul_cases_o:NnNnww / diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx index 69c8a7dc71a..0a300cd1341 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx @@ -36,7 +36,7 @@ % %<*driver> \documentclass[full]{l3doc} -\GetIdInfo$Id: l3fp-convert.dtx 6441 2016-03-24 10:11:59Z joseph $ +\GetIdInfo$Id: l3fp-convert.dtx 6596 2016-06-13 21:29:58Z joseph $ {L3 Floating-point conversion} \begin{document} \DocInput{\jobname.dtx} @@ -113,7 +113,7 @@ \cs_new:Npn \fp_to_scientific:N #1 { \exp_after:wN \@@_to_scientific_dispatch:w #1 } \cs_generate_variant:Nn \fp_to_scientific:N { c } -\cs_new_nopar:Npn \fp_to_scientific:n +\cs_new:Npn \fp_to_scientific:n { \exp_after:wN \@@_to_scientific_dispatch:w \exp:w \exp_end_continue_f:w \@@_parse:n @@ -195,7 +195,7 @@ \cs_new:Npn \fp_to_decimal:N #1 { \exp_after:wN \@@_to_decimal_dispatch:w #1 } \cs_generate_variant:Nn \fp_to_decimal:N { c } -\cs_new_nopar:Npn \fp_to_decimal:n +\cs_new:Npn \fp_to_decimal:n { \exp_after:wN \@@_to_decimal_dispatch:w \exp:w \exp_end_continue_f:w \@@_parse:n @@ -296,7 +296,7 @@ % \begin{macrocode} \cs_new:Npn \fp_to_tl:N #1 { \exp_after:wN \@@_to_tl_dispatch:w #1 } \cs_generate_variant:Nn \fp_to_tl:N { c } -\cs_new_nopar:Npn \fp_to_tl:n +\cs_new:Npn \fp_to_tl:n { \exp_after:wN \@@_to_tl_dispatch:w \exp:w \exp_end_continue_f:w \@@_parse:n @@ -366,7 +366,7 @@ % \begin{macrocode} \cs_new:Npn \fp_to_int:N #1 { \exp_after:wN \@@_to_int_dispatch:w #1 } \cs_generate_variant:Nn \fp_to_int:N { c } -\cs_new_nopar:Npn \fp_to_int:n +\cs_new:Npn \fp_to_int:n { \exp_after:wN \@@_to_int_dispatch:w \exp:w \exp_end_continue_f:w \@@_parse:n diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx index ea40a707007..6900fcc0ba2 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx @@ -36,7 +36,7 @@ % %<*driver> \documentclass[full]{l3doc} -\GetIdInfo$Id: l3fp-extended.dtx 6441 2016-03-24 10:11:59Z joseph $ +\GetIdInfo$Id: l3fp-extended.dtx 6684 2016-08-19 15:21:49Z bruno $ {L3 Floating-points with extended precision} \begin{document} \DocInput{\jobname.dtx} @@ -349,8 +349,8 @@ % \meta{continuation} (|#8|, then |#7|) from the end of the argument % list to its start. % \begin{macrocode} -\cs_new_nopar:Npn \@@_fixed_add:wwn { \@@_fixed_add:Nnnnnwnn + } -\cs_new_nopar:Npn \@@_fixed_sub:wwn { \@@_fixed_add:Nnnnnwnn - } +\cs_new:Npn \@@_fixed_add:wwn { \@@_fixed_add:Nnnnnwnn + } +\cs_new:Npn \@@_fixed_sub:wwn { \@@_fixed_add:Nnnnnwnn - } \cs_new:Npn \@@_fixed_add:Nnnnnwnn #1 #2#3#4#5 #6; #7#8 { \exp_after:wN \@@_fixed_add_after:NNNNNwn @@ -634,8 +634,8 @@ % \subsection{Extended-precision floating point numbers} % % In this section we manipulate floating point numbers with roughly $24$ -% significant figures (``extended-precision'' numbers, in short, -% ``ep''), which take the form of an integer exponent, followed by a +% significant figures (\enquote{extended-precision} numbers, in short, +% \enquote{ep}), which take the form of an integer exponent, followed by a % comma, then six groups of digits, ending with a semicolon. The first % group of digit may be any non-negative integer, while other groups of % digits have $4$~digits. In other words, an extended-precision number diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx index 6730b126cb9..40691eeeff3 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -%% File: l3fp-logic.dtx Copyright (C) 2011-2014 The LaTeX3 Project +%% File: l3fp-logic.dtx Copyright (C) 2011-2014,2016 The LaTeX3 Project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -36,7 +36,7 @@ % %<*driver> \documentclass[full]{l3doc} -\GetIdInfo$Id: l3fp-logic.dtx 5893 2015-08-26 16:16:52Z mittelba $ +\GetIdInfo$Id: l3fp-logic.dtx 6659 2016-08-15 15:37:48Z bruno $ {L3 Floating-point conditionals} \begin{document} \DocInput{\jobname.dtx} @@ -426,7 +426,7 @@ % same sign). Otherwise, return the second one. For \texttt{or}, the % logic is reversed: if the first number is non-zero, return it, % otherwise return the second number: we achieve that by hi-jacking -% \cs{@@_\&_o:ww}, inserting an extra argument, \cs{else:}, before +% \cs{@@_&_o:ww}, inserting an extra argument, \cs{else:}, before % \cs{s_@@}. In all cases, expand after the floating point number. % \begin{macrocode} \group_begin: @@ -439,7 +439,7 @@ \fi: \@@_exp_after_o:w } - \cs_new_nopar:Npn \@@_|_o:ww { \@@_&_o:ww \else: } + \cs_new:Npn \@@_|_o:ww { \@@_&_o:ww \else: } \group_end: \cs_new:Npn \@@_and_return:wNw #1; \fi: #2#3; { \fi: #2 #1; } % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx index 9c3d53d797d..d3dbf085569 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx @@ -36,7 +36,7 @@ % %<*driver> \documentclass[full]{l3doc} -\GetIdInfo$Id: l3fp-parse.dtx 6441 2016-03-24 10:11:59Z joseph $ +\GetIdInfo$Id: l3fp-parse.dtx 6685 2016-08-19 16:26:52Z bruno $ {L3 Floating-point expression parsing} \begin{document} \DocInput{\jobname.dtx} @@ -195,7 +195,7 @@ % \cs{exp_after:wN}~|;| expanded what follows once, we need |\add:ww| % to do the calculation, and in the process to expand the following % once. This is also true in our real application: all the functions of -% the form \cs{@@_..._o:ww} expand what follows once. This comes at the +% the form \cs[no-index]{@@_\ldots_o:ww} expand what follows once. This comes at the % cost of leaving tokens in the input stack, and we will need to be % careful not to waste this memory. All of our discussion above is nice % but simplistic, as operations should not simply be performed in the @@ -688,7 +688,7 @@ \@@_tmp:w {iii} \@@_parse_digits_ii:N { 000 ; 3 } \@@_tmp:w {ii} \@@_parse_digits_i:N { 00 ; 2 } \@@_tmp:w {i} \@@_parse_digits_:N { 0 ; 1 } -\cs_new_nopar:Npn \@@_parse_digits_:N { ; ; 0 } +\cs_new:Npn \@@_parse_digits_:N { ; ; 0 } % \end{macrocode} % \end{macro} % @@ -1839,7 +1839,7 @@ % \begin{macrocode} \cs_set_protected:Npn \@@_tmp:w #1 #2 { - \cs_new_nopar:cpn { @@_parse_word_#1:N } + \cs_new:cpn { @@_parse_word_#1:N } { \exp_after:wN #2 \exp:w \exp_end_continue_f:w \@@_parse_infix:NN } } \@@_tmp:w { inf } \c_inf_fp @@ -1864,7 +1864,7 @@ % \begin{macrocode} \cs_set_protected:Npn \@@_tmp:w #1 #2 { - \cs_new_nopar:cpn { @@_parse_word_#1:N } + \cs_new:cpn { @@_parse_word_#1:N } { \@@_exp_after_f:nw { \@@_parse_infix:NN } \s_@@ \@@_chk:w 10 #2 ; @@ -1890,7 +1890,7 @@ % \begin{macrocode} \tl_map_inline:nn { {em} {ex} } { - \cs_new_nopar:cpn { @@_parse_word_#1:N } + \cs_new:cpn { @@_parse_word_#1:N } { \exp_after:wN \@@_from_dim_test:ww \exp_after:wN 0 \exp_after:wN , @@ -1943,17 +1943,17 @@ % Those functions are also unary (not binary), but may receive a % variable number of arguments. % \begin{macrocode} -\cs_new_nopar:Npn \@@_parse_word_acot:N +\cs_new:Npn \@@_parse_word_acot:N { \@@_parse_function:NNN \@@_acot_o:Nw \use_i:nn } -\cs_new_nopar:Npn \@@_parse_word_acotd:N +\cs_new:Npn \@@_parse_word_acotd:N { \@@_parse_function:NNN \@@_acot_o:Nw \use_ii:nn } -\cs_new_nopar:Npn \@@_parse_word_atan:N +\cs_new:Npn \@@_parse_word_atan:N { \@@_parse_function:NNN \@@_atan_o:Nw \use_i:nn } -\cs_new_nopar:Npn \@@_parse_word_atand:N +\cs_new:Npn \@@_parse_word_atand:N { \@@_parse_function:NNN \@@_atan_o:Nw \use_ii:nn } -\cs_new_nopar:Npn \@@_parse_word_max:N +\cs_new:Npn \@@_parse_word_max:N { \@@_parse_function:NNN \@@_minmax_o:Nw 2 } -\cs_new_nopar:Npn \@@_parse_word_min:N +\cs_new:Npn \@@_parse_word_min:N { \@@_parse_function:NNN \@@_minmax_o:Nw 0 } % \end{macrocode} % \end{macro} @@ -1969,11 +1969,11 @@ % \begin{macrocode} \cs_new:Npn \@@_parse_word_abs:N { \@@_parse_unary_function:nNN { set_sign } 0 } -\cs_new_nopar:Npn \@@_parse_word_exp:N +\cs_new:Npn \@@_parse_word_exp:N { \@@_parse_unary_function:nNN {exp} ? } -\cs_new_nopar:Npn \@@_parse_word_ln:N +\cs_new:Npn \@@_parse_word_ln:N { \@@_parse_unary_function:nNN {ln} ? } -\cs_new_nopar:Npn \@@_parse_word_sqrt:N +\cs_new:Npn \@@_parse_word_sqrt:N { \@@_parse_unary_function:nNN {sqrt} ? } % \end{macrocode} % \end{macro} @@ -2009,9 +2009,9 @@ {cos} {cot} {csc} {sec} {sin} {tan} } { - \cs_new_nopar:cpn { @@_parse_word_#1:N } + \cs_new:cpn { @@_parse_word_#1:N } { \@@_parse_unary_function:nNN {#1} \use_i:nn } - \cs_new_nopar:cpn { @@_parse_word_#1d:N } + \cs_new:cpn { @@_parse_word_#1d:N } { \@@_parse_unary_function:nNN {#1} \use_ii:nn } } % \end{macrocode} @@ -2024,11 +2024,11 @@ % \@@_parse_word_ceil:N % } % \begin{macrocode} -\cs_new_nopar:Npn \@@_parse_word_trunc:N +\cs_new:Npn \@@_parse_word_trunc:N { \@@_parse_function:NNN \@@_round_o:Nw \@@_round_to_zero:NNN } -\cs_new_nopar:Npn \@@_parse_word_floor:N +\cs_new:Npn \@@_parse_word_floor:N { \@@_parse_function:NNN \@@_round_o:Nw \@@_round_to_ninf:NNN } -\cs_new_nopar:Npn \@@_parse_word_ceil:N +\cs_new:Npn \@@_parse_word_ceil:N { \@@_parse_function:NNN \@@_round_o:Nw \@@_round_to_pinf:NNN } % \end{macrocode} % \end{macro} @@ -2231,7 +2231,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[aux, EXP]+\@@_parse_infix_,:N+ +% \begin{macro}[aux, verb, EXP]{\__fp_parse_infix_,:N} % \begin{macrocode} \group_begin: \char_set_catcode_letter:N \, @@ -2286,7 +2286,7 @@ % \begin{macrocode} \group_begin: %<*package> - \cs_set_nopar:Npn \+ { } + \cs_set:Npn \+ { } % \char_set_catcode_other:N \& \char_set_catcode_letter:N \^ @@ -2611,7 +2611,7 @@ % % \subsection{Candidate: defining new \pkg{l3fp} functions} % -% \begin{macro}[EXP]{\fp_function:Nw} +% \begin{macro}[EXP,int]{\fp_function:Nw} % Parse the argument of the function~|#1| using % \cs{@@_parse_operand:Nw} with a precedence of~$16$, and pass the % function and argument to \cs{@@_function_apply:nw}. @@ -2626,7 +2626,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\fp_new_function:Npn} +% \begin{macro}[int]{\fp_new_function:Npn} % \begin{macro}[aux]{\@@_new_function:NNnnn, \@@_new_function:Ncfnn} % \begin{macro}[aux]{\@@_function_args:Nwn} % Save the code provided by the user in the control sequence @@ -2648,7 +2648,7 @@ } \cs_new_protected:Npn \@@_new_function:NNnnn #1#2#3#4#5 { - \cs_new_nopar:Npn #1 + \cs_new:Npn #1 { \exp_after:wN \@@_function_apply:nw \exp_after:wN { diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx index 3e7e396c902..d273a3e7cba 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment %% -%% File: l3fp-traps.dtx Copyright (C) 2011-2014 The LaTeX3 Project +%% File: l3fp-traps.dtx Copyright (C) 2011-2014,2016 The LaTeX3 Project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -36,7 +36,7 @@ % %<*driver> \documentclass[full]{l3doc} -\GetIdInfo$Id: l3fp-traps.dtx 5354 2014-08-23 01:35:39Z bruno $ +\GetIdInfo$Id: l3fp-traps.dtx 6596 2016-06-13 21:29:58Z joseph $ {L3 Floating-point exception trapping} \begin{document} \DocInput{\jobname.dtx} @@ -200,11 +200,11 @@ % produces as a result its first argument, possibly with % post-expansion. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_trap_invalid_operation_set_error: +\cs_new_protected:Npn \@@_trap_invalid_operation_set_error: { \@@_trap_invalid_operation_set:N \prg_do_nothing: } -\cs_new_protected_nopar:Npn \@@_trap_invalid_operation_set_flag: +\cs_new_protected:Npn \@@_trap_invalid_operation_set_flag: { \@@_trap_invalid_operation_set:N \use_none:nnnnn } -\cs_new_protected_nopar:Npn \@@_trap_invalid_operation_set_none: +\cs_new_protected:Npn \@@_trap_invalid_operation_set_none: { \@@_trap_invalid_operation_set:N \use_none:nnnnnnn } \cs_new_protected:Npn \@@_trap_invalid_operation_set:N #1 { @@ -250,11 +250,11 @@ % cases, the function must produce a result, namely its first % argument, $\pm\infty$ or \nan{}. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_trap_division_by_zero_set_error: +\cs_new_protected:Npn \@@_trap_division_by_zero_set_error: { \@@_trap_division_by_zero_set:N \prg_do_nothing: } -\cs_new_protected_nopar:Npn \@@_trap_division_by_zero_set_flag: +\cs_new_protected:Npn \@@_trap_division_by_zero_set_flag: { \@@_trap_division_by_zero_set:N \use_none:nnnnn } -\cs_new_protected_nopar:Npn \@@_trap_division_by_zero_set_none: +\cs_new_protected:Npn \@@_trap_division_by_zero_set_none: { \@@_trap_division_by_zero_set:N \use_none:nnnnnnn } \cs_new_protected:Npn \@@_trap_division_by_zero_set:N #1 { @@ -308,19 +308,19 @@ % receive $\pm 0$); then we cannot do better than simply say an % overflow or underflow occurred. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_trap_overflow_set_error: +\cs_new_protected:Npn \@@_trap_overflow_set_error: { \@@_trap_overflow_set:N \prg_do_nothing: } -\cs_new_protected_nopar:Npn \@@_trap_overflow_set_flag: +\cs_new_protected:Npn \@@_trap_overflow_set_flag: { \@@_trap_overflow_set:N \use_none:nnnnn } -\cs_new_protected_nopar:Npn \@@_trap_overflow_set_none: +\cs_new_protected:Npn \@@_trap_overflow_set_none: { \@@_trap_overflow_set:N \use_none:nnnnnnn } \cs_new_protected:Npn \@@_trap_overflow_set:N #1 { \@@_trap_overflow_set:NnNn #1 { overflow } \@@_inf_fp:N { inf } } -\cs_new_protected_nopar:Npn \@@_trap_underflow_set_error: +\cs_new_protected:Npn \@@_trap_underflow_set_error: { \@@_trap_underflow_set:N \prg_do_nothing: } -\cs_new_protected_nopar:Npn \@@_trap_underflow_set_flag: +\cs_new_protected:Npn \@@_trap_underflow_set_flag: { \@@_trap_underflow_set:N \use_none:nnnnn } -\cs_new_protected_nopar:Npn \@@_trap_underflow_set_none: +\cs_new_protected:Npn \@@_trap_underflow_set_none: { \@@_trap_underflow_set:N \use_none:nnnnnnn } \cs_new_protected:Npn \@@_trap_underflow_set:N #1 { \@@_trap_overflow_set:NnNn #1 { underflow } \@@_zero_fp:N { 0 } } @@ -375,7 +375,7 @@ % Convenient short-hands for returning \cs{c_nan_fp} for a unary or % binary operation, and expanding after. % \begin{macrocode} -\cs_new_nopar:Npn \@@_invalid_operation_o:nw +\cs_new:Npn \@@_invalid_operation_o:nw { \@@_invalid_operation:nnw { \exp_after:wN \c_nan_fp } } \cs_generate_variant:Nn \@@_invalid_operation_o:nw { f } % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx index 54509f57b54..85d8ce0c05f 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx @@ -36,7 +36,7 @@ % %<*driver> \documentclass[full]{l3doc} -\GetIdInfo$Id: l3fp-trig.dtx 6441 2016-03-24 10:11:59Z joseph $ +\GetIdInfo$Id: l3fp-trig.dtx 6723 2016-10-17 16:42:15Z bruno $ {L3 Floating-point trigonometric functions} \begin{document} \DocInput{\jobname.dtx} @@ -476,7 +476,7 @@ % control sequence name, and convert it to a token list when required: % strings take up less memory than their token list representation. % \begin{macrocode} -\cs_new_nopar:Npx \@@_trig_inverse_two_pi: +\cs_new:Npx \@@_trig_inverse_two_pi: { \exp_not:n { \exp_after:wN \use_none:n \token_to_str:N } \cs:w , , ! @@ -778,7 +778,7 @@ \exp_after:wN + \fi: } -\cs_new_nopar:Npn \@@_trig_large_auxix:Nw +\cs_new:Npn \@@_trig_large_auxix:Nw { \exp_after:wN \@@_use_i_until_s:nw \exp_after:wN \@@_trig_large_auxxi:w @@ -1004,7 +1004,7 @@ % $\operatorname{atan}(y, x)$ is argument reduction. The sign of~$y$ will give that % of the result. We distinguish eight regions where the point $(x, % \lvert y\rvert)$ can lie, of angular size roughly $\pi/8$, -% characterized by their ``octant'', between $0$ and~$7$ included. In +% characterized by their \enquote{octant}, between $0$ and~$7$ included. In % each region, we compute an arctangent as a Taylor series, then shift % this arctangent by the appropriate multiple of $\pi/4$ and sign to get % the result. Here is a list of octants, and how we compute the @@ -1053,12 +1053,12 @@ % ones: $\operatorname{atan}(y) = \operatorname{atan}(y, 1) = \operatorname{acot}(1, y)$ and % $\operatorname{acot}(x) = \operatorname{atan}(1, x) = \operatorname{acot}(x, 1)$. % \begin{macrocode} -\cs_new_nopar:Npn \@@_atan_o:Nw +\cs_new:Npn \@@_atan_o:Nw { \@@_atan_dispatch_o:NNnNw \@@_acotii_o:Nww \@@_atanii_o:Nww { atan } } -\cs_new_nopar:Npn \@@_acot_o:Nw +\cs_new:Npn \@@_acot_o:Nw { \@@_atan_dispatch_o:NNnNw \@@_atanii_o:Nww \@@_acotii_o:Nww { acot } @@ -1075,7 +1075,7 @@ { kernel } { fp-num-args } { #3() } { 1 } { 2 } \exp_after:wN \c_nan_fp \exp:w \fi: - \exp_after:wN \c_zero + \exp_after:wN \exp_end: } % \end{macrocode} % \end{macro} @@ -1200,7 +1200,7 @@ % This receives two positive numbers $a$ and~$b$ (equal to $\lvert % x\rvert$ and~$\lvert y\rvert$ in some order), each as an exponent % and $6$~blocks of $4$~digits, such that $0 %<*driver|package> -\GetIdInfo$Id: l3fp.dtx 6465 2016-03-26 16:15:09Z joseph $ +\GetIdInfo$Id: l3fp.dtx 6685 2016-08-19 16:26:52Z bruno $ {L3 Floating points} % %<*driver> @@ -125,7 +125,7 @@ % \item Constants: \texttt{pi}, \texttt{deg} (one degree in radians). % \item Dimensions, automatically expressed in points, \emph{e.g.}, % \texttt{pc} is~$12$. -% \item Automatic conversion (no need for \cs{\meta{type}_use:N}) of +% \item Automatic conversion (no need for \cs[no-index]{\meta{type}_use:N}) of % integer, dimension, and skip variables to floating points, % expressing dimensions in points and ignoring the stretch and % shrink components of skips. @@ -193,7 +193,7 @@ % \end{syntax} % Ensures that the \meta{fp~var} exists globally % by applying \cs{fp_new:N} if necessary, then applies -% \cs{fp_(g)zero:N} to leave the \meta{fp~var} set to~$+0$. +% \cs[index=fp_zero:N]{fp_(g)zero:N} to leave the \meta{fp~var} set to~$+0$. % \end{function} % % \section{Setting floating point variables} @@ -793,7 +793,7 @@ % a truth value, a floating point expression is \texttt{false} if it is % $\pm 0$, and \texttt{true} otherwise, including when it is \nan{}. % -% \begin{function}[tested = m3fp-logic002]{?:} +% \begin{function}[tested = m3fp-logic002, module = ]{?:} % \begin{syntax} % \cs{fp_eval:n} \{ \meta{operand_1} |?| \meta{operand_2} |:| \meta{operand_3} \} % \end{syntax} @@ -876,7 +876,7 @@ % and \enquote{overflow} occur when appropriate. % \end{function} % -% \begin{function}[tested = m3fp-basics004]{+, -, !} +% \begin{function}[tested = m3fp-basics004, label = !]{+, -, !} % \begin{syntax} % \cs{fp_eval:n} \{ |+| \meta{operand} \} % \cs{fp_eval:n} \{ |-| \meta{operand} \} @@ -942,7 +942,7 @@ % \nan{}. Those operations do not raise exceptions. % \end{function} % -% \begin{function}^^A +% \begin{function} % [tested = {m3fp-round001, m3fp-round002}, added = 2013-12-14, updated = 2015-08-08] % {round, trunc, ceil, floor} % \begin{syntax} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3int.dtx b/Master/texmf-dist/source/latex/l3kernel/l3int.dtx index 9eb4b79cc34..c2e913ef444 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3int.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3int.dtx @@ -37,7 +37,7 @@ \documentclass[full]{l3doc} % %<*driver|package> -\GetIdInfo$Id: l3int.dtx 6441 2016-03-24 10:11:59Z joseph $ +\GetIdInfo$Id: l3int.dtx 6700 2016-09-07 22:16:49Z bruno $ {L3 Integers} % %<*driver> @@ -205,7 +205,8 @@ % \cs{int_zero_new:N} \meta{integer} % \end{syntax} % Ensures that the \meta{integer} exists globally by applying -% \cs{int_new:N} if necessary, then applies \cs{int_(g)zero:N} to leave +% \cs{int_new:N} if necessary, then applies +% \cs[index=int_zero:N]{int_(g)zero:N} to leave % the \meta{integer} set to zero. % \end{function} % @@ -355,7 +356,7 @@ % \end{center} % \end{function} % -% \begin{function}[added = 2013-07-24, EXP, TF]{\int_case:nn} +% \begin{function}[added = 2013-07-24, EXP, noTF]{\int_case:nn} % \begin{syntax} % \cs{int_case:nnTF} \Arg{test integer expression} \\ % ~~|{| \\ @@ -831,6 +832,10 @@ % Maximum number of registers. % \end{variable} % +% \begin{variable}{\c_max_char_int} +% Maximum character code completely supported by the engine. +% \end{variable} +% % \section{Scratch integers} % % \begin{variable}{\l_tmpa_int, \l_tmpb_int} @@ -949,7 +954,7 @@ % \cs{__prg_compare_error:} % \cs{__prg_compare_error:Nw} \meta{token} % \end{syntax} -% These are used within \cs{int_compare:n(TF)}, \cs{dim_compare:n(TF)} +% These are used within \cs{int_compare:nTF}, \cs{dim_compare:nTF} % and so on to recover correctly if the \texttt{n}-type argument does not % contain a properly-formed relation. % \end{function} @@ -1172,7 +1177,11 @@ % \begin{macrocode} \cs_new_protected:Npn \int_const:Nn #1#2 { - \int_compare:nNnTF {#2} > \c_minus_one + \int_compare:nNnTF {#2} < \c_zero + { + \int_new:N #1 + \int_gset:Nn #1 {#2} + } { \int_compare:nNnTF {#2} > \c__max_constdef_int { @@ -1185,10 +1194,6 @@ \@@_eval:w #2 \@@_eval_end: } } - { - \int_new:N #1 - \int_gset:Nn #1 {#2} - } } \cs_generate_variant:Nn \int_const:Nn { c } \if_int_odd:w 0 @@ -1280,9 +1285,9 @@ { \tex_advance:D #1 by \@@_eval:w #2 \@@_eval_end: } \cs_new_protected:Npn \int_sub:Nn #1#2 { \tex_advance:D #1 by - \@@_eval:w #2 \@@_eval_end: } -\cs_new_protected_nopar:Npn \int_gadd:Nn +\cs_new_protected:Npn \int_gadd:Nn { \tex_global:D \int_add:Nn } -\cs_new_protected_nopar:Npn \int_gsub:Nn +\cs_new_protected:Npn \int_gsub:Nn { \tex_global:D \int_sub:Nn } \cs_generate_variant:Nn \int_add:Nn { c } \cs_generate_variant:Nn \int_gadd:Nn { c } @@ -1309,9 +1314,9 @@ { \tex_advance:D #1 \c_one } \cs_new_protected:Npn \int_decr:N #1 { \tex_advance:D #1 \c_minus_one } -\cs_new_protected_nopar:Npn \int_gincr:N +\cs_new_protected:Npn \int_gincr:N { \tex_global:D \int_incr:N } -\cs_new_protected_nopar:Npn \int_gdecr:N +\cs_new_protected:Npn \int_gdecr:N { \tex_global:D \int_decr:N } \cs_generate_variant:Nn \int_incr:N { c } \cs_generate_variant:Nn \int_decr:N { c } @@ -1333,7 +1338,7 @@ % \begin{macrocode} \cs_new_protected:Npn \int_set:Nn #1#2 { #1 ~ \@@_eval:w #2\@@_eval_end: } -\cs_new_protected_nopar:Npn \int_gset:Nn { \tex_global:D \int_set:Nn } +\cs_new_protected:Npn \int_gset:Nn { \tex_global:D \int_set:Nn } \cs_generate_variant:Nn \int_set:Nn { c } \cs_generate_variant:Nn \int_gset:Nn { c } % \end{macrocode} @@ -1371,7 +1376,7 @@ % cleaning up the end of the test and telling the user what the % problem was. % \begin{macrocode} -\cs_new_protected_nopar:Npn \__prg_compare_error: +\cs_new_protected:Npn \__prg_compare_error: { \if_int_compare:w \c_zero \c_zero \fi: = @@ -1546,8 +1551,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[EXP]{\int_case:nn} -% \begin{macro}[EXP, TF]{\int_case:nn} +% \begin{macro}[EXP, noTF]{\int_case:nn} % \begin{macro}[aux]{\@@_case:nnTF} % \begin{macro}[aux]{\@@_case:nw, \@@_case_end:nw} % For integer cases, the first task to fully expand the check @@ -1587,7 +1591,6 @@ % \end{macro} % \end{macro} % \end{macro} -% \end{macro} % % \begin{macro}[pTF]{\int_if_odd:n} % \UnitTested @@ -1765,18 +1768,18 @@ % \cs{scan_stop:}, so no breaking function will recognize this break % point as its own. % \begin{macrocode} -\cs_new_protected_nopar:Npn \int_step_inline:nnnn +\cs_new_protected:Npn \int_step_inline:nnnn { \int_gincr:N \g__prg_map_int \exp_args:NNc \@@_step:NNnnnn - \cs_gset_nopar:Npn + \cs_gset:Npn { __prg_map_ \int_use:N \g__prg_map_int :w } } \cs_new_protected:Npn \int_step_variable:nnnNn #1#2#3#4#5 { \int_gincr:N \g__prg_map_int \exp_args:NNc \@@_step:NNnnnn - \cs_gset_nopar:Npx + \cs_gset:Npx { __prg_map_ \int_use:N \g__prg_map_int :w } {#1}{#2}{#3} { @@ -2128,21 +2131,21 @@ \use:c { @@_to_Roman_ #1 :w } \@@_to_Roman_aux:N } -\cs_new_nopar:Npn \@@_to_roman_i:w { i } -\cs_new_nopar:Npn \@@_to_roman_v:w { v } -\cs_new_nopar:Npn \@@_to_roman_x:w { x } -\cs_new_nopar:Npn \@@_to_roman_l:w { l } -\cs_new_nopar:Npn \@@_to_roman_c:w { c } -\cs_new_nopar:Npn \@@_to_roman_d:w { d } -\cs_new_nopar:Npn \@@_to_roman_m:w { m } -\cs_new_nopar:Npn \@@_to_roman_Q:w #1 { } -\cs_new_nopar:Npn \@@_to_Roman_i:w { I } -\cs_new_nopar:Npn \@@_to_Roman_v:w { V } -\cs_new_nopar:Npn \@@_to_Roman_x:w { X } -\cs_new_nopar:Npn \@@_to_Roman_l:w { L } -\cs_new_nopar:Npn \@@_to_Roman_c:w { C } -\cs_new_nopar:Npn \@@_to_Roman_d:w { D } -\cs_new_nopar:Npn \@@_to_Roman_m:w { M } +\cs_new:Npn \@@_to_roman_i:w { i } +\cs_new:Npn \@@_to_roman_v:w { v } +\cs_new:Npn \@@_to_roman_x:w { x } +\cs_new:Npn \@@_to_roman_l:w { l } +\cs_new:Npn \@@_to_roman_c:w { c } +\cs_new:Npn \@@_to_roman_d:w { d } +\cs_new:Npn \@@_to_roman_m:w { m } +\cs_new:Npn \@@_to_roman_Q:w #1 { } +\cs_new:Npn \@@_to_Roman_i:w { I } +\cs_new:Npn \@@_to_Roman_v:w { V } +\cs_new:Npn \@@_to_Roman_x:w { X } +\cs_new:Npn \@@_to_Roman_l:w { L } +\cs_new:Npn \@@_to_Roman_c:w { C } +\cs_new:Npn \@@_to_Roman_d:w { D } +\cs_new:Npn \@@_to_Roman_m:w { M } \cs_new:Npn \@@_to_Roman_Q:w #1 { } % \end{macrocode} % \end{macro} @@ -2362,7 +2365,7 @@ % We don't use the \TeX{} primitive \tn{showthe} to show integer % expressions: this gives a more unified output. % \begin{macrocode} -\cs_new_protected_nopar:Npn \int_show:n +\cs_new_protected:Npn \int_show:n { \__msg_show_wrap:Nn \int_eval:n } % \end{macrocode} % \end{macro} @@ -2435,6 +2438,25 @@ % \end{macrocode} % \end{variable} % +% \begin{variable}{\c_max_char_int} +% The largest character code is $1114111$ (hexadecimal |10FFFF|) in +% \XeTeX{} and \LuaTeX{} and $255$ in other engines. In many places +% \pTeX{} and \upTeX{} support larger character codes but for instance +% the values of \tn{lccode} are restricted to $[0,255]$. +% \begin{macrocode} +\int_const:Nn \c_max_char_int + { + \if_int_odd:w 0 + \cs_if_exist:NT \luatex_luatexversion:D { 1 } + \cs_if_exist:NT \xetex_XeTeXversion:D { 1 } ~ + "10FFFF + \else: + "FF + \fi: + } +% \end{macrocode} +% \end{variable} +% % \subsection{Scratch integers} % % \begin{variable}{\l_tmpa_int, \l_tmpb_int} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx b/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx index 7b834f6c7a7..0f109a3d695 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -%% File: l3keys.dtx Copyright (C) 2006-2015 The LaTeX3 Project +%% File: l3keys.dtx Copyright (C) 2006-2016 The LaTeX3 Project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -37,7 +37,7 @@ \documentclass[full]{l3doc} % %<*driver|package> -\GetIdInfo$Id: l3keys.dtx 6284 2015-11-17 10:10:56Z bruno $ +\GetIdInfo$Id: l3keys.dtx 6711 2016-09-21 07:04:35Z joseph $ {L3 Key-value interfaces} % %<*driver> @@ -179,7 +179,7 @@ % Some other properties are mutually exclusive, notably |.value_required:n| % and |.value_forbidden:n|, and so will replace one another. However, % properties covering non-exclusive behaviours may be given in any order. Thus -% for example the following defintions are equivalent. +% for example the following definitions are equivalent. % \begin{verbatim} % \keys_define:nn { mymodule } % { @@ -873,20 +873,18 @@ % % \subsection{Low-level interface} % +% The low-level key parser is based heavily on \pkg{keyval}, but with a number +% of additional \enquote{safety} requirements and with the idea that the +% parsed list of key--value pairs can be processed in a variety of ways. +% The net result is that this code needs around twice the amount of time +% as \pkg{keyval} to parse the same list of keys. To optimise speed as far +% as reasonably practical, a number of lower-level approaches are taken +% rather than using the higher-level \pkg{expl3} interfaces. +% % \begin{macrocode} %<@@=keyval> % \end{macrocode} % -% For historical reasons this code uses the `keyval' module prefix. -% -% \begin{variable}{\g_@@_level_int} -% To allow nesting of \cs{keyval_parse:NNn}, an integer is needed for -% the current level. -% \begin{macrocode} -\int_new:N \g_@@_level_int -% \end{macrocode} -% \end{variable} -% % \begin{variable}{\l_@@_key_tl, \l_@@_value_tl} % The current key name and value. % \begin{macrocode} @@ -896,166 +894,206 @@ % \end{variable} % % \begin{variable}{\l_@@_sanitise_tl} -% \begin{variable}{\l_@@_parse_tl} -% Token list variables for dealing with awkward category codes in the +% A token list variable for dealing with awkward category codes in the % input. % \begin{macrocode} \tl_new:N \l_@@_sanitise_tl -\tl_new:N \l_@@_parse_tl % \end{macrocode} % \end{variable} -% \end{variable} % -% \begin{macro}{\@@_parse:n} -% The parsing function first deals with the category codes for -% |=| and |,|, so that there are no odd events. The input is then -% handed off to the element by element system. +% \begin{macro}{\keyval_parse:NNn} +% The main function starts off by normalising category codes in package mode. +% That's relatively \enquote{expensive} so is skipped (hopefully) in format +% mode. We then hand off to the parser. The use of \cs{q_mark} here prevents +% loss of braces from the key argument. This particular quark is chosen as +% it fits in with \cs{__tl_trim_spaces:nn} and allows a performance enhancement +% as the token can be carried through. Notice that by passing the two +% processor commands along the input stack we avoid the need to track these +% at all. +% \begin{macrocode} +\cs_new_protected:Npn \keyval_parse:NNn #1#2#3 + { +%<*initex> + \@@_loop:NNw #1#2 \q_mark #3 , \q_recursion_tail , +% +%<*package> + \tl_set:Nn \l_@@_sanitise_tl {#3} + \@@_sanitise_equals: + \@@_sanitise_comma: + \exp_after:wN \@@_loop:NNw \exp_after:wN #1 \exp_after:wN #2 + \exp_after:wN \q_mark \l_@@_sanitise_tl , \q_recursion_tail , +% + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\@@_sanitise_equals:, \@@_sanitise_comma:} +% \begin{macro}[aux] +% { +% \@@_sanitise_equals_auxi:w, \@@_sanitise_equals_auxii:w, +% \@@_sanitise_comma_auxi:w, \@@_sanitise_comma_auxii:w, +% \@@_sanitise_aux:w +% } +% A reasonably fast search and replace set up specifically for the active +% tokens. The nature of the input is known so everything is hard-coded. +% With only two tokens to cover, the speed gain from using dedicated +% functions is worth it. % \begin{macrocode} +%<*package> \group_begin: \char_set_catcode_active:n { `\= } \char_set_catcode_active:n { `\, } - \cs_new_protected:Npx \@@_parse:n #1 + \cs_new_protected:Npn \@@_sanitise_equals: { - \group_begin: - \tl_set:Nn \exp_not:N \l_@@_sanitise_tl {#1} - \tl_replace_all:Nnn \exp_not:N \l_@@_sanitise_tl - { \exp_not:N = } { \token_to_str:N = } - \tl_replace_all:Nnn \exp_not:N \l_@@_sanitise_tl - { \exp_not:N , } { \token_to_str:N , } - \tl_clear:N \exp_not:N \l_@@_parse_tl - \exp_not:N \exp_after:wN - \exp_not:N \@@_parse_elt:w \exp_not:N \exp_after:wN - \exp_not:N \q_nil \exp_not:N \l_@@_sanitise_tl - \token_to_str:N , \exp_not:N \q_recursion_tail - \token_to_str:N , \exp_not:N \q_recursion_stop - \exp_not:N \exp_after:wN \group_end: - \exp_not:N \l_@@_parse_tl + \exp_after:wN \@@_sanitise_equals_auxi:w \l_@@_sanitise_tl + \q_mark = \q_nil = + \exp_after:wN \@@_sanitise_aux:w \l_@@_sanitise_tl } + \cs_new_protected:Npn \@@_sanitise_equals_auxi:w #1 = + { + \tl_set:Nn \l_@@_sanitise_tl {#1} + \@@_sanitise_equals_auxii:w + } + \cs_new_protected:Npn \@@_sanitise_equals_auxii:w #1 = + { + \if_meaning:w \q_nil #1 \scan_stop: + \else: + \tl_set:Nx \l_@@_sanitise_tl + { + \exp_not:o \l_@@_sanitise_tl + \token_to_str:N = + \exp_not:n {#1} + } + \exp_after:wN \@@_sanitise_equals_auxii:w + \fi: + } + \cs_new_protected:Npn \@@_sanitise_comma: + { + \exp_after:wN \@@_sanitise_comma_auxi:w \l_@@_sanitise_tl + \q_mark , \q_nil , + \exp_after:wN \@@_sanitise_aux:w \l_@@_sanitise_tl + } + \cs_new_protected:Npn \@@_sanitise_comma_auxi:w #1 , + { + \tl_set:Nn \l_@@_sanitise_tl {#1} + \@@_sanitise_comma_auxii:w + } + \cs_new_protected:Npn \@@_sanitise_comma_auxii:w #1 , + { + \if_meaning:w \q_nil #1 \scan_stop: + \else: + \tl_set:Nx \l_@@_sanitise_tl + { + \exp_not:o \l_@@_sanitise_tl + \token_to_str:N , + \exp_not:n {#1} + } + \exp_after:wN \@@_sanitise_comma_auxii:w + \fi: + } \group_end: +\cs_new_protected:Npn \@@_sanitise_aux:w #1 \q_mark + { \tl_set:Nn \l_@@_sanitise_tl {#1} } +% % \end{macrocode} % \end{macro} +% \end{macro} % -% \begin{macro}{\@@_parse_elt:w} -% Each item to be parsed will have \cs{q_nil} added to the front. -% Hence the blank test here can always be used to find a totally -% empty argument. To allow rapid matching for an |=| while not stripping -% any braces, another \cs{q_nil} needed before the next phase of the -% parser. Finally, loop around for the next item, adding in the -% \cs{q_nil}: this happens whatever the nature of the current argument -% as the end-of-recursion will clear up in all cases. +% \begin{macro}[aux]{\@@_loop:NNw} +% A fast test for the end of the loop, remembering to remove the leading +% quark first. Assuming that is not the case, look for a key and value then +% loop around, re-inserting a leading quark in front of the next position. % \begin{macrocode} -\cs_new_protected:Npn \@@_parse_elt:w #1 , +\cs_new_protected:Npn \@@_loop:NNw #1#2#3 , { - \tl_if_blank:oF { \use_none:n #1 } - { - \quark_if_recursion_tail_stop:o { \use_none:n #1 } - \@@_split_key_value:w #1 \q_nil = = \q_stop - } - \@@_parse_elt:w \q_nil + \exp_after:wN \if_meaning:w \exp_after:wN \q_recursion_tail + \use_none:n #3 \prg_do_nothing: + \else: + \@@_split:NNw #1#2#3 == \q_stop + \exp_after:wN \@@_loop:NNw \exp_after:wN #1 \exp_after:wN #2 + \exp_after:wN \q_mark + \fi: } % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_split_key_value:w} -% \begin{macro}[aux]{\@@_split_key:w} -% Split the key and value using a delimited argument. The \cs{q_nil} -% values added earlier ensure that no braces will be stripped as part -% of this process. A blank test can then be used on |#3|: it is only -% empty if there was no |=| in the original input. In that case, strip -% a \cs{q_nil} from the end of the key name then hand on to remove other -% things and store as \cs{l_@@_key_tl} before adding to the output token -% list. In the case where there is an |=|, first tidy up the key, this time -% without a trailing \cs{q_nil}, then do a check to ensure that |#3| is -% exactly one token (|=|). With that done, the final stage is to hand off -% to tidy up the value. +% \begin{macro}[aux]{\@@_split:NNw, \@@_split_value:NNw} +% \begin{macro}[aux]{\@@_split_tidy:w} +% \begin{macro}[aux]{\@@_action:} +% The value is picked up separately from the key so there can be another +% quark inserted at the front, keeping braces and allowing both parts to +% share the same code paths. The key is found first then there's a check +% that there is something there: this is biased to the common case of there +% actually being a key. For the value, we first need to see if there is +% anything to do: if there is, extract it. The appropriate action is then +% inserted in front of the key and value. Doing this using an assignment is +% marginally faster than an an expansion chain. % \begin{macrocode} -\cs_new_protected:Npn \@@_split_key_value:w #1 = #2 = #3 \q_stop +\cs_new_protected:Npn \@@_split:NNw #1#2#3 = { - \tl_if_blank:nTF {#3} - { - \@@_split_key:w #1 \q_stop - \tl_put_right:Nx \l_@@_parse_tl + \@@_def:Nn \l_@@_key_tl {#3} + \if_meaning:w \l_@@_key_tl \c_empty_tl + \exp_after:wN \@@_split_tidy:w + \else: + \exp_after:wN \@@_split_value:NNw \exp_after:wN #1 \exp_after:wN #2 + \exp_after:wN \q_mark + \fi: + } +\cs_new_protected:Npn \@@_split_value:NNw #1#2#3 = #4 \q_stop + { + \if:w \scan_stop: \tl_to_str:n {#4} \scan_stop: + \cs_set:Npx \@@_action: + { \exp_not:N #1 { \exp_not:o \l_@@_key_tl } } + \else: + \if:w \scan_stop: \etex_detokenize:D \exp_after:wN { \use_none:n #4 } + \scan_stop: + \@@_def:Nn \l_@@_value_tl {#3} + \cs_set:Npx \@@_action: { - \exp_not:c - { - @@_key_no_value_elt_ - \int_use:N \g_@@_level_int - :n - } + \exp_not:N #2 { \exp_not:o \l_@@_key_tl } + { \exp_not:o \l_@@_value_tl } } - } - { - \@@_split:Nn \l_@@_key_tl {#1} - \tl_if_blank:oTF { \use_none:n #3 } - { \@@_split_value:w \q_nil #2 \q_stop } + \else: + \cs_set:Npn \@@_action: { \__msg_kernel_error:nn { kernel } { misplaced-equals-sign } } - } + \fi: + \fi: + \@@_action: } -\cs_new_protected:Npn \@@_split_key:w #1 \q_nil \q_stop - { \@@_split:Nn \l_@@_key_tl {#1} } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\@@_split:Nn} -% \begin{macro}[aux]{\@@_split:Nw} -% There are two possible cases here. The first case is that |#1| is -% surrounded by braces, in which case the |\use_none:nnn #1 \q_nil \q_nil| -% will yield \cs{q_nil}. There, we can remove the leading \cs{q_nil}, the -% braces and any spaces around the outside with \cs{use_ii:nnn}. On the -% other hand, if there are no braces then the second branch removes the -% leading \cs{q_nil} and any surrounding spaces. -% \begin{macrocode} -\cs_new_protected:Npn \@@_split:Nn #1#2 +\cs_new_protected:Npn \@@_split_tidy:w #1 \q_stop { - \quark_if_nil:oTF { \use_none:nnn #2 \q_nil \q_nil } - { \tl_set:Nx #1 { \exp_not:o { \use_ii:nnn #2 \q_nil } } } - { \@@_split:Nw #1 #2 \q_stop } + \if:w \scan_stop: \etex_detokenize:D \exp_after:wN { \use_none:n #1 } + \scan_stop: + \else: + \exp_after:wN \@@_empty_key: + \fi: } -\cs_new_protected:Npn \@@_split:Nw #1 \q_nil #2 \q_stop - { \tl_set:Nx #1 { \tl_trim_spaces:n {#2} } } +\cs_new:Npn \@@_action: { } +\cs_new_protected:Npn \@@_empty_key: + { \__msg_kernel_error:nn { kernel } { misplaced-equals-sign } } % \end{macrocode} % \end{macro} % \end{macro} -% -% \begin{macro}{\@@_split_value:w} -% As this stage there is just the value to deal with. The leading and -% trailing \cs{q_nil} tokens are removed in two steps before storing the -% value with spaces stripped (see \cs{@@_split:Nn}). Doing the storage -% of key and value in one shot will put exactly the right number of -% brace groups into the output. -% \begin{macrocode} -\cs_new_protected:Npn \@@_split_value:w #1 \q_nil \q_stop - { - \@@_split:Nn \l_@@_value_tl {#1} - \tl_put_right:Nx \l_@@_parse_tl - { - \exp_not:c - { @@_key_value_elt_ \int_use:N \g_@@_level_int :nn } - { \exp_not:o \l_@@_key_tl } - { \exp_not:o \l_@@_value_tl } - } - } -% \end{macrocode} % \end{macro} % -% \begin{macro}{\keyval_parse:NNn} -% The outer parsing routine just sets up the processing functions and -% hands off. +% \begin{macro}[aux]{\@@_def:Nn} +% \begin{macro}[aux, EXP]{\@@_def_aux:n} +% \begin{macro}[aux, EXP]{\@@_def_aux:w} +% First trim spaces off, then potentially remove a set of braces. By using +% the internal interface |\__tl_trim_spaces:nn| we can take advantage of the +% fact it needs a leading |\q_mark| in this process. The |\exp_after:wN| +% removes the quark, the delimited argument deals with any braces. % \begin{macrocode} -\cs_new_protected:Npn \keyval_parse:NNn #1#2#3 - { - \int_gincr:N \g_@@_level_int - \cs_gset_eq:cN - { @@_key_no_value_elt_ \int_use:N \g_@@_level_int :n } #1 - \cs_gset_eq:cN - { @@_key_value_elt_ \int_use:N \g_@@_level_int :nn } #2 - \@@_parse:n {#3} - \int_gdecr:N \g_@@_level_int - } +\cs_new_protected:Npn \@@_def:Nn #1#2 + { \tl_set:Nx #1 { \__tl_trim_spaces:nn {#2} \@@_def_aux:n } } +\cs_new:Npn \@@_def_aux:n #1 + { \exp_after:wN \@@_def_aux:w #1 \q_stop } +\cs_new:Npn \@@_def_aux:w #1 \q_stop { \exp_not:n {#1} } % \end{macrocode} % \end{macro} +% \end{macro} +% \end{macro} % % One message for the low level parsing system. % \begin{macrocode} @@ -1073,11 +1111,21 @@ %<@@=keys> % \end{macrocode} % -% \begin{variable}{\c_@@_code_root_tl, \c_@@_info_root_tl} -% The prefixes for the code and variables of the keys themselves. +% \begin{variable} +% { +% \c_@@_code_root_tl , +% \c_@@_default_root_tl , +% \c_@@_groups_root_tl, +% \c_@@_info_root_tl , +% \c_@@_validate_root_tl +% } +% Various storage areas for the different data which make up keys. % \begin{macrocode} -\tl_const:Nn \c_@@_code_root_tl { key~code~>~ } -\tl_const:Nn \c_@@_info_root_tl { key~info~>~ } +\tl_const:Nn \c_@@_code_root_tl { key~code~>~ } +\tl_const:Nn \c_@@_default_root_tl { key~default~>~ } +\tl_const:Nn \c_@@_groups_root_tl { key~groups~>~ } +\tl_const:Nn \c_@@_info_root_tl { key~info~>~ } +\tl_const:Nn \c_@@_validate_root_tl { key~validate~>~ } % \end{macrocode} % \end{variable} % @@ -1203,7 +1251,7 @@ \cs_new_protected:Npn \@@_define:nnn #1#2#3 { \tl_set:Nx \l_@@_module_tl { \@@_remove_spaces:n {#2} } - \keyval_parse:NNn \@@_define_elt:n \@@_define_elt:nn {#3} + \keyval_parse:NNn \@@_define:n \@@_define:nn {#3} \tl_set:Nn \l_@@_module_tl {#1} } \cs_generate_variant:Nn \@@_define:nnn { o } @@ -1211,33 +1259,33 @@ % \end{macro} % \end{macro} % -% \begin{macro}[int]{\@@_define_elt:n} -% \begin{macro}[int]{\@@_define_elt:nn} -% \begin{macro}[aux]{\@@_define_elt_aux:nn} +% \begin{macro}[int]{\@@_define:n} +% \begin{macro}[int]{\@@_define:nn} +% \begin{macro}[aux]{\@@_define_aux:nn} % The outer functions here record whether a value was given and then % converge on a common internal mechanism. There is first a search for % a property in the current key name, then a check to make sure it is % known before the code hands off to the next step. % \begin{macrocode} -\cs_new_protected:Npn \@@_define_elt:n #1 +\cs_new_protected:Npn \@@_define:n #1 { \bool_set_true:N \l_@@_no_value_bool - \@@_define_elt_aux:nn {#1} { } + \@@_define_aux:nn {#1} { } } -\cs_new_protected:Npn \@@_define_elt:nn #1#2 +\cs_new_protected:Npn \@@_define:nn #1#2 { \bool_set_false:N \l_@@_no_value_bool - \@@_define_elt_aux:nn {#1} {#2} + \@@_define_aux:nn {#1} {#2} } -\cs_new_protected:Npn \@@_define_elt_aux:nn #1#2 +\cs_new_protected:Npn \@@_define_aux:nn #1#2 { \@@_property_find:n {#1} \cs_if_exist:cTF { \c_@@_props_root_tl \l_@@_property_tl } - { \@@_define_key:n {#2} } + { \@@_define_code:n {#2} } { - \str_if_eq_x:nnF { \l_@@_property_tl } { .abort: } - { - \__msg_kernel_error:nnxx { kernel } { property-unknown } + \tl_if_empty:NF \l_@@_property_tl + { + \__msg_kernel_error:nnxx { kernel } { property-unknown } { \l_@@_property_tl } { \l_keys_path_tl } } } @@ -1255,45 +1303,57 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_property_find:n #1 { - \tl_set:Nx \l_keys_path_tl { \l_@@_module_tl / } - \tl_if_in:nnTF {#1} { . } - { \@@_property_find:w #1 \q_stop } + \tl_set:Nx \l_@@_property_tl { \@@_remove_spaces:n {#1} } + \exp_after:wN \@@_property_find:w \l_@@_property_tl . . \q_stop {#1} + } +\cs_new_protected:Npn \@@_property_find:w #1 . #2 . #3 \q_stop #4 + { + \tl_if_blank:nTF {#3} + { + \tl_clear:N \l_@@_property_tl + \__msg_kernel_error:nnn { kernel } { key-no-property } {#4} + } { - \__msg_kernel_error:nnx { kernel } { key-no-property } {#1} - \tl_set:Nn \l_@@_property_tl { .abort: } + \str_if_eq:nnTF {#3} { . } + { + \tl_set:Nx \l_keys_path_tl { \l_@@_module_tl / #1 } + \tl_set:Nn \l_@@_property_tl { . #2 } + } + { + \tl_set:Nx \l_keys_path_tl { \l_@@_module_tl / #1 . #2 } + \@@_property_search:w #3 \q_stop + } } } -\cs_new_protected:Npn \@@_property_find:w #1 . #2 \q_stop +\cs_new_protected:Npn \@@_property_search:w #1 . #2 \q_stop { - \tl_set:Nx \l_keys_path_tl + \str_if_eq:nnTF {#2} { . } { - \l_keys_path_tl - \@@_remove_spaces:n {#1} + \tl_set:Nx \l_keys_path_tl { \l_keys_path_tl } + \tl_set:Nn \l_@@_property_tl { . #1 } } - \tl_if_in:nnTF {#2} { . } { - \tl_set:Nx \l_keys_path_tl { \l_keys_path_tl . } - \@@_property_find:w #2 \q_stop + \tl_set:Nx \l_keys_path_tl { \l_keys_path_tl . #1 } + \@@_property_search:w #2 \q_stop } - { \tl_set:Nn \l_@@_property_tl { . #2 } } } % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}[int]{\@@_define_key:n} -% \begin{macro}[aux]{\@@_define_key:w} +% \begin{macro}[int]{\@@_define_code:n} +% \begin{macro}[aux, EXP]{\@@_define_code:w} % Two possible cases. If there is a value for the key, then just use % the function. If not, then a check to make sure there is no need for % a value with the property. If there should be one then complain, % otherwise execute it. There is no need to check for a |:| as if it % is missing the earlier tests will have failed. % \begin{macrocode} -\cs_new_protected:Npn \@@_define_key:n #1 +\cs_new_protected:Npn \@@_define_code:n #1 { \bool_if:NTF \l_@@_no_value_bool { - \exp_after:wN \@@_define_key:w + \exp_after:wN \@@_define_code:w \l_@@_property_tl \q_stop { \use:c { \c_@@_props_root_tl \l_@@_property_tl } } { @@ -1304,7 +1364,11 @@ } { \use:c { \c_@@_props_root_tl \l_@@_property_tl } {#1} } } -\cs_new_protected:Npn \@@_define_key:w #1 : #2 \q_stop +\use:x + { + \cs_new:Npn \exp_not:N \__keys_define_code:w + ##1 \c_colon_str ##2 \exp_not:N \q_stop + } { \tl_if_empty:nTF {#2} } % \end{macrocode} % \end{macro} @@ -1322,7 +1386,7 @@ % current scope but exists at a higher level, we do not use \cs{prop_new:c} % but rather \cs{prop_set_eq:cN}. The function \cs{__chk_log:x} only % writes to the log file if logging all new functions is active: without -% it keys would not show up (as we are not using \cs{..._new}). +% it keys would not show up (as we are not using \cs[no-index]{..._new}). % \begin{macrocode} \cs_new_protected:Npn \@@_ensure_exist:n #1 { @@ -1330,6 +1394,7 @@ { \prop_set_eq:cN { \c_@@_info_root_tl #1 } \c_empty_prop } + \cs_if_exist:cF { \c_@@_code_root_tl #1 } { \__chk_log:x { Defining~key~#1~ \msg_line_context: } @@ -1396,11 +1461,11 @@ % nested! As multichoices and choices are essentially the same bar one % function, the code is given together. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_choice_make: +\cs_new_protected:Npn \@@_choice_make: { \@@_choice_make:N \@@_choice_find:n } -\cs_new_protected_nopar:Npn \@@_multichoice_make: +\cs_new_protected:Npn \@@_multichoice_make: { \@@_choice_make:N \@@_multichoice_find:n } -\cs_new_protected_nopar:Npn \@@_choice_make:N #1 +\cs_new_protected:Npn \@@_choice_make:N #1 { \prop_if_exist:cTF { \c_@@_info_root_tl \@@_parent:o \l_keys_path_tl } @@ -1416,7 +1481,7 @@ } { \@@_choice_make_aux:N #1 } } -\cs_new_protected_nopar:Npn \@@_choice_make_aux:N #1 +\cs_new_protected:Npn \@@_choice_make_aux:N #1 { \@@_cmd_set:nn { \l_keys_path_tl } { #1 {##1} } \prop_put:cnn { \c_@@_info_root_tl \l_keys_path_tl } { choice } @@ -1450,9 +1515,9 @@ % Auto-generating choices means setting up the root key as a choice, then % defining each choice in turn. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_choices_make:nn +\cs_new_protected:Npn \@@_choices_make:nn { \@@_choices_make:Nnn \@@_choice_make: } -\cs_new_protected_nopar:Npn \@@_multichoices_make:nn +\cs_new_protected:Npn \@@_multichoices_make:nn { \@@_choices_make:Nnn \@@_multichoice_make: } \cs_new_protected:Npn \@@_choices_make:Nnn #1#2#3 { @@ -1489,19 +1554,21 @@ % \end{macro} % % \begin{macro}[int]{\@@_default_set:n} -% Setting a default value is easy. +% Setting a default value is easy. These are stored using \cs{cs_set:cpx} as this +% avoids any worries about whether a token list exists. % \begin{macrocode} \cs_new_protected:Npn \@@_default_set:n #1 { - \@@_ensure_exist:V \l_keys_path_tl \tl_if_empty:nTF {#1} { - \prop_remove:cn { \c_@@_info_root_tl \l_keys_path_tl } - { default } + \cs_set_eq:cN + { \c_@@_default_root_tl \l_keys_path_tl } + \tex_undefined:D } { - \prop_put:cnn { \c_@@_info_root_tl \l_keys_path_tl } - { default } {#1} + \cs_set:cpx + { \c_@@_default_root_tl \l_keys_path_tl } + { \exp_not:n {#1} } } } % \end{macrocode} @@ -1530,21 +1597,14 @@ % \end{macro} % % \begin{macro}[int]{\@@_initialise:n} -% \begin{macro}[aux]{\@@_initialise:wn} -% A set up for initialisation from which the key system requires that -% the path is split up into a module and a key name. At this stage, -% \cs{l_keys_path_tl} will contain \texttt{/} so a split is easy to do. +% A set up for initialisation: just run the code if it exists. % \begin{macrocode} \cs_new_protected:Npn \@@_initialise:n #1 { - \@@_ensure_exist:V \l_keys_path_tl - \exp_after:wN \@@_initialise:wn \l_keys_path_tl \q_stop {#1} + \cs_if_exist_use:cT { \c_@@_code_root_tl \l_keys_path_tl } { {#1} } } -\cs_new_protected:Npn \@@_initialise:wn #1 / #2 \q_stop #3 - { \keys_set:nn {#1} { #2 = {#3} } } % \end{macrocode} % \end{macro} -% \end{macro} % % \begin{macro}[int]{\@@_meta_make:n} % \begin{macro}[int]{\@@_meta_make:nn} @@ -1568,40 +1628,78 @@ % Undefining a key has to be done without \cs{cs_undefine:c} as that % function acts globally. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_undefine: +\cs_new_protected:Npn \@@_undefine: { - \cs_set_eq:cN { \c_@@_code_root_tl \l_keys_path_tl } \tex_undefined:D - \cs_set_eq:cN { \c_@@_info_root_tl \l_keys_path_tl } \tex_undefined:D + \clist_map_inline:nn + { code , default , groups , info , validate } + { + \cs_set_eq:cN + { \tl_use:c { c_@@_ ##1 _root_tl } \l_keys_path_tl } + \tex_undefined:D + } } % \end{macrocode} % \end{macro} % % \begin{macro}[int]{\@@_value_requirement:nn} -% Values can be required or forbidden by having the appropriate marker -% set. First, both the required and forbidden ones are clear, just in case! +% \begin{macro}[aux]{\@@_validate_forbidden:, \@@_validate_required:} +% \begin{macro}[aux]{\@@_validate_cleanup:w} +% Validating key input is done using a second function which runs before +% the main key code. Setting that up means setting it equal to a generic +% stub which does the check. This approach makes the lookup very fast at +% the cost of one additional csname per key that needs it. The cleanup here +% has to know the structure of the following code. % \begin{macrocode} \cs_new_protected:Npn \@@_value_requirement:nn #1#2 { - \@@_ensure_exist:V \l_keys_path_tl - \prop_remove:cn { \c_@@_info_root_tl \l_keys_path_tl } - { required } - \prop_remove:cn { \c_@@_info_root_tl \l_keys_path_tl } - { forbidden } - \str_if_eq:nnTF {#2} { true } - { - \prop_put:cnn { \c_@@_info_root_tl \l_keys_path_tl } - {#1} { true } - } + \str_case:nnF {#2} { - \str_if_eq:nnF {#2} { false } + { true } { - \__msg_kernel_error:nnx { kernel } { property-boolean-values-only } - { .value_ #1 :n } + \cs_set_eq:cc + { \c_@@_validate_root_tl \l_keys_path_tl } + { @@_validate_ #1 : } } + { false } + { + \cs_if_eq:ccT + { \c_@@_validate_root_tl \l_keys_path_tl } + { @@_validate_ #1 : } + { + \cs_set_eq:cN + { \c_@@_validate_root_tl \l_keys_path_tl } + \tex_undefined:D + } + } + } + { + \__msg_kernel_error:nnx { kernel } { property-boolean-values-only } + { .value_ #1 :n } } } +\cs_new_protected:Npn \@@_validate_forbidden: + { + \bool_if:NF \l_@@_no_value_bool + { + \__msg_kernel_error:nnxx { kernel } { value-forbidden } + { \l_keys_path_tl } { \l_keys_value_tl } + \@@_validate_cleanup:w + } + } +\cs_new_protected:Npn \@@_validate_required: + { + \bool_if:NT \l_@@_no_value_bool + { + \__msg_kernel_error:nnx { kernel } { value-required } + { \l_keys_path_tl } + \@@_validate_cleanup:w + } + } +\cs_new_protected:Npn \@@_validate_cleanup:w #1 \cs_end: #2#3 { } % \end{macrocode} % \end{macro} +% \end{macro} +% \end{macro} % % \begin{macro}[int]{\@@_variable_set:NnnN, \@@_variable_set:cnnN} % Setting a variable takes the type and scope separately so that @@ -1668,7 +1766,7 @@ % Making a choice is handled internally, as it is also needed by % \texttt{.generate_choices:n}. % \begin{macrocode} -\cs_new_protected_nopar:cpn { \c_@@_props_root_tl .choice: } +\cs_new_protected:cpn { \c_@@_props_root_tl .choice: } { \@@_choice_make: } % \end{macrocode} % \end{macro} @@ -1824,7 +1922,7 @@ % The same idea as \texttt{.choice:} and \texttt{.choices:nn}, but % where more than one choice is allowed. % \begin{macrocode} -\cs_new_protected_nopar:cpn { \c_@@_props_root_tl .multichoice: } +\cs_new_protected:cpn { \c_@@_props_root_tl .multichoice: } { \@@_multichoice_make: } \cs_new_protected:cpn { \c_@@_props_root_tl .multichoices:nn } #1 { \@@_multichoices_make:nn #1 } @@ -1854,7 +1952,6 @@ % \end{macro} % \end{macro} % -% % \begin{macro}{.tl_set:N, .tl_set:c} % \begin{macro}{.tl_gset:N, .tl_gset:c} % \begin{macro}{.tl_set_x:N, .tl_set_x:c} @@ -1886,7 +1983,7 @@ % \begin{macro}{.undefine:} % Another simple wrapper. % \begin{macrocode} -\cs_new_protected_nopar:cpn { \c_@@_props_root_tl .undefine: } +\cs_new_protected:cpn { \c_@@_props_root_tl .undefine: } { \@@_undefine: } % \end{macrocode} % \end{macro} @@ -1909,12 +2006,12 @@ % \begin{macro}[aux]{\@@_set:nnn, \@@_set:onn} % A simple wrapper again. % \begin{macrocode} -\cs_new_protected_nopar:Npn \keys_set:nn +\cs_new_protected:Npn \keys_set:nn { \@@_set:onn { \l_@@_module_tl } } \cs_new_protected:Npn \@@_set:nnn #1#2#3 { \tl_set:Nx \l_@@_module_tl { \@@_remove_spaces:n {#2} } - \keyval_parse:NNn \@@_set_elt:n \@@_set_elt:nn {#3} + \keyval_parse:NNn \@@_set:n \@@_set:nn {#3} \tl_set:Nn \l_@@_module_tl {#1} } \cs_generate_variant:Nn \keys_set:nn { nV , nv , no } @@ -1937,10 +2034,10 @@ % Setting known keys simply means setting the appropriate flag, then % running the standard code. To allow for nested setting, any existing % value of \cs{l_@@_unused_clist} is saved on the stack and reset -% afterwards.Note that for speed/simplicity reasons we use a \texttt{tl} +% afterwards. Note that for speed/simplicity reasons we use a \texttt{tl} % operation to set the \texttt{clist} here! % \begin{macrocode} -\cs_new_protected_nopar:Npn \keys_set_known:nnN +\cs_new_protected:Npn \keys_set_known:nnN { \@@_set_known:onnN \l_@@_unused_clist } \cs_generate_variant:Nn \keys_set_known:nnN { nV , nv , no } \cs_new_protected:Npn \@@_set_known:nnnN #1#2#3#4 @@ -1965,25 +2062,25 @@ % % \begin{macro} % { -% \keys_set_filter:nnnN, \keys_set_filter:nnVN, \keys_set_filter:nnvN +% \keys_set_filter:nnnN, \keys_set_filter:nnVN, \keys_set_filter:nnvN, % \keys_set_filter:nnoN % } % \begin{macro}[aux]{\@@_set_filter:nnnnN, \@@_set_filter:onnnN} % \begin{macro} % { -% \keys_set_filter:nnn, \keys_set_filter:nnV, \keys_set_filter:nnv +% \keys_set_filter:nnn, \keys_set_filter:nnV, \keys_set_filter:nnv, % \keys_set_filter:nno % } % \begin{macro} % { -% \keys_set_groups:nnn, \keys_set_groups:nnV, \keys_set_groups:nnv +% \keys_set_groups:nnn, \keys_set_groups:nnV, \keys_set_groups:nnv, % \keys_set_groups:nno % } % The idea of setting keys in a selective manner again uses flags % wrapped around the basic code. The comments on \cs{keys_set_known:nnN} % also apply here. % \begin{macrocode} -\cs_new_protected_nopar:Npn \keys_set_filter:nnnN +\cs_new_protected:Npn \keys_set_filter:nnnN { \@@_set_filter:onnnN \l_@@_unused_clist } \cs_generate_variant:Nn \keys_set_filter:nnnN { nnV , nnv , nno } \cs_new_protected:Npn \@@_set_filter:nnnnN #1#2#3#4#5 @@ -2018,24 +2115,24 @@ % \end{macro} % \end{macro} % -% \begin{macro}[int]{\@@_set_elt:n, \@@_set_elt:nn} -% \begin{macro}[aux]{\@@_set_elt_aux:nnn, \@@_set_elt_aux:onn} +% \begin{macro}[int]{\@@_set:n, \@@_set:nn} +% \begin{macro}[aux]{\@@_set_aux:nnn, \@@_set_aux:onn} % \begin{macro}[aux]{\@@_find_key_module:w} -% \begin{macro}[aux]{\@@_set_elt_aux:, \@@_set_elt_selective:} +% \begin{macro}[aux]{\@@_set_aux:, \@@_set_selective:} % A shared system once again. First, set the current path and add a % default if needed. There are then checks to see if the a value is % required or forbidden. If everything passes, move on to execute the % code. % \begin{macrocode} -\cs_new_protected:Npn \@@_set_elt:n #1 +\cs_new_protected:Npn \@@_set:n #1 { \bool_set_true:N \l_@@_no_value_bool - \@@_set_elt_aux:onn \l_@@_module_tl {#1} { } + \@@_set_aux:onn \l_@@_module_tl {#1} { } } -\cs_new_protected:Npn \@@_set_elt:nn #1#2 +\cs_new_protected:Npn \@@_set:nn #1#2 { \bool_set_false:N \l_@@_no_value_bool - \@@_set_elt_aux:onn \l_@@_module_tl {#1} {#2} + \@@_set_aux:onn \l_@@_module_tl {#1} {#2} } % \end{macrocode} % The key path here can be fully defined, after which there is a search @@ -2044,19 +2141,18 @@ % that happens on a per-key basis, we use the stack approach to restore % the module name without a group. % \begin{macrocode} -\cs_new_protected:Npn \@@_set_elt_aux:nnn #1#2#3 +\cs_new_protected:Npn \@@_set_aux:nnn #1#2#3 { - \tl_set:Nx \l_keys_path_tl - { \l_@@_module_tl / \@@_remove_spaces:n {#2} } + \tl_set:Nx \l_keys_path_tl { #1 / \@@_remove_spaces:n {#2} } \tl_clear:N \l_@@_module_tl \exp_after:wN \@@_find_key_module:w \l_keys_path_tl / \q_stop \@@_value_or_default:n {#3} \bool_if:NTF \l_@@_selective_bool - { \@@_set_elt_selective: } - { \@@_set_elt_aux: } + { \@@_set_selective: } + { \@@_execute: } \tl_set:Nn \l_@@_module_tl {#1} } -\cs_generate_variant:Nn \@@_set_elt_aux:nnn { o } +\cs_generate_variant:Nn \@@_set_aux:nnn { o } \cs_new_protected:Npn \@@_find_key_module:w #1 / #2 \q_stop { \tl_if_blank:nTF {#2} @@ -2070,37 +2166,13 @@ \@@_find_key_module:w #2 \q_stop } } -\cs_new_protected_nopar:Npn \@@_set_elt_aux: - { - \bool_if:nTF - { - \@@_if_value_p:n { required } && - \l_@@_no_value_bool - } - { - \__msg_kernel_error:nnx { kernel } { value-required } - { \l_keys_path_tl } - } - { - \bool_if:nTF - { - \@@_if_value_p:n { forbidden } && - ! \l_@@_no_value_bool - } - { - \__msg_kernel_error:nnxx { kernel } { value-forbidden } - { \l_keys_path_tl } { \l_keys_value_tl } - } - { \@@_execute: } - } - } % \end{macrocode} % If selective setting is active, there are a number of possible sub-cases % to consider. The key name may not be known at all or if it is, it may not % have any groups assigned. There is then the question of whether the % selection is opt-in or opt-out. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_set_elt_selective: +\cs_new_protected:Npn \@@_set_selective: { \prop_if_exist:cTF { \c_@@_info_root_tl \l_keys_path_tl } { @@ -2109,13 +2181,13 @@ { \@@_check_groups: } { \bool_if:NTF \l_@@_filtered_bool - { \@@_set_elt_aux: } + { \@@_execute: } { \@@_store_unused: } } } { \bool_if:NTF \l_@@_filtered_bool - { \@@_set_elt_aux: } + { \@@_execute: } { \@@_store_unused: } } } @@ -2125,7 +2197,7 @@ % set active. That requires two mappings, and again a different outcome % depending on whether opt-in or opt-out is set. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_check_groups: +\cs_new_protected:Npn \@@_check_groups: { \bool_set_false:N \l_@@_tmp_bool \seq_map_inline:Nn \l_@@_selective_seq @@ -2143,11 +2215,11 @@ { \bool_if:NTF \l_@@_filtered_bool { \@@_store_unused: } - { \@@_set_elt_aux: } + { \@@_execute: } } { \bool_if:NTF \l_@@_filtered_bool - { \@@_set_elt_aux: } + { \@@_execute: } { \@@_store_unused: } } } @@ -2165,8 +2237,12 @@ { \bool_if:NTF \l_@@_no_value_bool { - \prop_get:cnNF { \c_@@_info_root_tl \l_keys_path_tl } - { default } \l_keys_value_tl + \cs_if_exist:cTF { \c_@@_default_root_tl \l_keys_path_tl } + { + \tl_set_eq:Nc + \l_keys_value_tl + { \c_@@_default_root_tl \l_keys_path_tl } + } { \tl_clear:N \l_keys_value_tl } } { \tl_set:Nn \l_keys_value_tl {#1} } @@ -2174,25 +2250,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\@@_if_value_p:n} -% To test if a value is required or forbidden. A simple check for -% the existence of the appropriate marker. -% \begin{macrocode} -\prg_new_conditional:Npnn \@@_if_value:n #1 { p } - { - \prop_if_exist:cTF { \c_@@_info_root_tl \l_keys_path_tl } - { - \prop_if_in:cnTF { \c_@@_info_root_tl \l_keys_path_tl } {#1} - { \prg_return_true: } - { \prg_return_false: } - } - { \prg_return_false: } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[int]{\@@_execute:} -% \begin{macro}[aux]{\@@_execute_unknown:} +% \begin{macro}[aux]{\@@_execute:, \@@_execute_unknown:} % \begin{macro}[aux, EXP]{\@@_execute:nn} % \begin{macro}[aux]{\@@_store_unused:} % Actually executing a key is done in two parts. First, look for the @@ -2201,14 +2259,26 @@ % is unknown depends on whether unknown keys are being skipped or if % an error should be raised. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_execute: - { \@@_execute:nn { \l_keys_path_tl } { \@@_execute_unknown: } } -\cs_new_protected_nopar:Npn \@@_execute_unknown: +\cs_new_protected:Npn \@@_execute: + { + \cs_if_exist:cTF { \c_@@_code_root_tl \l_keys_path_tl } + { + \cs_if_exist_use:c { \c_@@_validate_root_tl \l_keys_path_tl } + \cs:w \c_@@_code_root_tl \l_keys_path_tl \exp_after:wN \cs_end: + \exp_after:wN { \l_keys_value_tl } + } + { \@@_execute_unknown: } + } +\cs_new_protected:Npn \@@_execute_unknown: { \bool_if:NTF \l_@@_only_known_bool { \@@_store_unused: } { - \@@_execute:nn { \l_@@_module_tl / unknown } + \cs_if_exist:cTF { \c_@@_code_root_tl \l_@@_module_tl / unknown } + { + \cs:w \c_@@_code_root_tl \l_@@_module_tl / unknown \exp_after:wN + \cs_end: \exp_after:wN { \l_keys_value_tl } + } { \__msg_kernel_error:nnxx { kernel } { key-unknown } { \l_keys_path_tl } { \l_@@_module_tl } @@ -2224,7 +2294,7 @@ } {#2} } -\cs_new_protected_nopar:Npn \@@_store_unused: +\cs_new_protected:Npn \@@_store_unused: { \clist_put_right:Nx \l_@@_unused_clist { @@ -2237,7 +2307,6 @@ % \end{macro} % \end{macro} % \end{macro} -% \end{macro} % % \begin{macro}[int, EXP]{\@@_choice_find:n} % \begin{macro}[int, EXP]{\@@_multichoice_find:n} @@ -2292,7 +2361,7 @@ % \end{macro} % % \begin{macro}[EXP,pTF]{\keys_if_choice_exist:nnn} -% Just an alternative view on \cs{keys_if_exist:nn(TF)}. +% Just an alternative view on \cs{keys_if_exist:nnTF}. % \begin{macrocode} \prg_new_conditional:Npnn \keys_if_choice_exist:nnn #1#2#3 { p , T , F , TF } @@ -2354,12 +2423,6 @@ \__msg_kernel_new:nnnn { kernel } { boolean-values-only } { Key~'#1'~accepts~boolean~values~only. } { The~key~'#1'~only~accepts~the~values~'true'~and~'false'. } -\__msg_kernel_new:nnnn { kernel } { choice-unknown } - { Choice~'#2'~unknown~for~key~'#1'. } - { - The~key~'#1'~takes~a~limited~number~of~values.\\ - The~input~given,~'#2',~is~not~on~the~list~accepted. - } \__msg_kernel_new:nnnn { kernel } { key-choice-unknown } { Key~'#1'~accepts~only~a~fixed~set~of~choices. } { @@ -2430,13 +2493,13 @@ % % \subsection{Deprecated functions} % -% \begin{macro}{.value_forbidden:} +% \begin{macro}[deprecated = 2017]{.value_forbidden:} % \begin{macro}{.value_required:} % Deprecated 2015-07-14. % \begin{macrocode} -\cs_new_protected_nopar:cpn { \c_@@_props_root_tl .value_forbidden: } +\cs_new_protected:cpn { \c_@@_props_root_tl .value_forbidden: } { \@@_value_requirement:nn { forbidden } { true } } -\cs_new_protected_nopar:cpn { \c_@@_props_root_tl .value_required: } +\cs_new_protected:cpn { \c_@@_props_root_tl .value_required: } { \@@_value_requirement:nn { required } { true } } % \end{macrocode} % \end{macro} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx b/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx index 48d7446d71e..4b751fca13a 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx @@ -37,7 +37,7 @@ \documentclass[full]{l3doc} % %<*driver|package&tex> -\GetIdInfo$Id: l3luatex.dtx 6465 2016-03-26 16:15:09Z joseph $ +\GetIdInfo$Id: l3luatex.dtx 6679 2016-08-18 20:54:06Z bruno $ {L3 Experimental LuaTeX-specific functions} % %<*driver> @@ -242,7 +242,7 @@ %<*lua> % \end{macrocode} % -% \begin{macro}{l3kernel} +% \begin{macro}[int]{l3kernel} % Create a table for the kernel's own use. % \begin{macrocode} l3kernel = l3kernel or { } @@ -258,7 +258,7 @@ local tex_write = tex.write local unicode_utf8_char = unicode.utf8.char % \end{macrocode} % -% \begin{macro}{l3kernel.strcmp} +% \begin{macro}[int]{l3kernel.strcmp} % String comparison which gives the same results as \pdfTeX{}'s % \tn{pdfstrcmp}, although the ordering should likely not be relied upon! % \begin{macrocode} @@ -275,7 +275,7 @@ l3kernel.strcmp = strcmp % \end{macrocode} % \end{macro} % -% \begin{macro}{l3kernel.charcat} +% \begin{macro}[int]{l3kernel.charcat} % Creating arbitrary chars needs a category code table. As set up here, % one may have been assigned earlier (see \pkg{l3bootstrap}) or a hard-coded % one is used. The latter is intended for format mode and should be adjusted diff --git a/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx b/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx index d3054544bdb..0900a2a71b0 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx @@ -37,7 +37,7 @@ \documentclass[full]{l3doc} % %<*driver|package> -\GetIdInfo$Id: l3msg.dtx 6464 2016-03-26 13:03:37Z bruno $ +\GetIdInfo$Id: l3msg.dtx 6691 2016-08-19 22:14:26Z bruno $ {L3 Messages} % %<*driver> @@ -301,7 +301,7 @@ % \begin{texnote} % The \TeX{} \tn{endinput} primitive is used to exit the file. In % particular, the rest of the current line remains in the input -% stream. ^^A Can we fix that? +% stream. % \end{texnote} % \end{function} % @@ -966,8 +966,8 @@ % For writing the line number nicely. \cs{msg_line_context:} was set up % earlier, so this is not \texttt{new}. % \begin{macrocode} -\cs_new_nopar:Npn \msg_line_number: { \int_use:N \tex_inputlineno:D } -\cs_gset_nopar:Npn \msg_line_context: +\cs_new:Npn \msg_line_number: { \int_use:N \tex_inputlineno:D } +\cs_gset:Npn \msg_line_context: { \c_@@_on_line_text_tl \c_space_tl @@ -1077,7 +1077,7 @@ \__iow_with:Nnn \tex_errorcontextlines:D \c_minus_one { \group_begin: - \cs_set_protected_nopar:Npn & + \cs_set_protected:Npn & { \tex_errmessage:D { @@ -1463,7 +1463,7 @@ \@@_class_chk_exist:nT {#1} { \tl_set:Nn \l_@@_current_class_tl {#1} - \cs_set_protected_nopar:Npx \@@_use_code: + \cs_set_protected:Npx \@@_use_code: { \exp_not:n { @@ -1476,7 +1476,7 @@ } { \@@_kernel_error:nnxx { kernel } { message-unknown } {#2} {#3} } } -\cs_new_protected_nopar:Npn \@@_use_code: { } +\cs_new_protected:Npn \@@_use_code: { } % \end{macrocode} % The first check is for a individual message redirection. If this % applies then no further redirection is attempted. Otherwise, split @@ -1573,7 +1573,7 @@ % for a loop: as an initialization, we start by storing the initial % class in \cs{l_@@_current_class_tl}. % \begin{macrocode} -\cs_new_protected_nopar:Npn \msg_redirect_class:nn +\cs_new_protected:Npn \msg_redirect_class:nn { \@@_redirect:nnn { } } \cs_new_protected:Npn \msg_redirect_module:nnn #1 { \@@_redirect:nnn { / #1 } } @@ -1872,6 +1872,15 @@ of~each~type.~All~the~#1~registers~have~been~used.~ This~run~will~be~aborted~now. } +\@@_kernel_new:nnnn { kernel } { non-base-function } + { Function~'#1'~is~not~a~base~function } + { + \c_@@_coding_error_text_tl + Functions~defined~through~\iow_char:N\\cs_new:Nn~must~have~ + a~signature~consisting~of~only~normal~arguments~'N'~and~'n'.~ + To~define~variants~use~\iow_char:N\\cs_generate_variant:Nn~ + and~to~define~other~functions~use~\iow_char:N\\cs_new:Npn. + } \@@_kernel_new:nnnn { kernel } { missing-colon } { Function~'#1'~contains~no~':'. } { @@ -2093,7 +2102,7 @@ % \begin{macro}[int]{\@@_log_next:} % \begin{macrocode} \bool_new:N \g_@@_log_next_bool -\cs_new_protected_nopar:Npn \@@_log_next: +\cs_new_protected:Npn \@@_log_next: { \bool_gset_true:N \g_@@_log_next_bool } % \end{macrocode} % \end{macro} @@ -2123,7 +2132,7 @@ { \exp_not:n { \@@_show_pre:nnnnnn {#1} {#2} } {#3} {#4} {#5} {#6} } } \cs_generate_variant:Nn \@@_show_pre:nnnnnn { nnnnnV } -\cs_new_protected_nopar:Npn \@@_show_pre_aux:n +\cs_new_protected:Npn \@@_show_pre_aux:n { \bool_if:NTF \g_@@_log_next_bool { \iow_log:n } { \iow_term:n } } % \end{macrocode} % \end{macro} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3names.dtx b/Master/texmf-dist/source/latex/l3kernel/l3names.dtx index d27ab75c171..8cb7f99d6c3 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3names.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3names.dtx @@ -37,7 +37,7 @@ \documentclass[full]{l3doc} % %<*driver|package> -\GetIdInfo$Id: l3names.dtx 6433 2016-03-11 20:04:27Z joseph $ +\GetIdInfo$Id: l3names.dtx 6722 2016-10-13 10:22:35Z joseph $ {L3 Namespace for primitives} % %<*driver> @@ -112,7 +112,7 @@ % names. In format mode, it also deletes all of the existing names (although % some do come back later). % -% \begin{macro}{\tex_undefined:D} +% \begin{macro}[int]{\tex_undefined:D} % This function does not exist at all, but is the name used by the % plain \TeX{} format for an undefined function. So it should % be marked here as \enquote{taken}. @@ -564,7 +564,7 @@ % based on those also available in \LuaTeX{} or used in \pkg{expl3}. % In the case of the \pdfTeX{} primitives, we retain |pdf| at the start % of the names \emph{only} for directly PDF-related primitives, as -% there are a lot of \pdfTeX{} primitives that start \cs{pdf\ldots} but +% there are a lot of \pdfTeX{} primitives that start \cs[no-index]{pdf\ldots} but % are not related to PDF output. These ones related to PDF output or only % work in PDF mode. % \begin{macrocode} @@ -780,7 +780,7 @@ % Primitives from \pdfTeX{} that \XeTeX{} renames: also helps with % \LuaTeX{}. % \begin{macrocode} - \__kernel_primitive:NN \ifprimitive \pdftex_primitive:D + \__kernel_primitive:NN \ifprimitive \pdftex_ifprimitive:D \__kernel_primitive:NN \primitive \pdftex_primitive:D \__kernel_primitive:NN \shellescape \pdftex_shellescape:D % \end{macrocode} @@ -811,7 +811,8 @@ \__kernel_primitive:NN \formatname \luatex_formatname:D \__kernel_primitive:NN \hjcode \luatex_hjcode:D \__kernel_primitive:NN \hpack \luatex_hpack:D - \__kernel_primitive:NN \hyphenationmin \luatex_hypenationmin:D + \__kernel_primitive:NN \hyphenationbounds \luatex_hyphenationbounds:D + \__kernel_primitive:NN \hyphenationmin \luatex_hyphenationmin:D \__kernel_primitive:NN \gleaders \luatex_gleaders:D \__kernel_primitive:NN \initcatcodetable \luatex_initcatcodetable:D \__kernel_primitive:NN \lastnamedcs \luatex_lastnamedcs:D @@ -819,12 +820,15 @@ \__kernel_primitive:NN \letcharcode \luatex_letcharcode:D \__kernel_primitive:NN \luaescapestring \luatex_luaescapestring:D \__kernel_primitive:NN \luafunction \luatex_luafunction:D + \__kernel_primitive:NN \luatexbanner \luatex_luatexbanner:D \__kernel_primitive:NN \luatexdatestamp \luatex_luatexdatestamp:D \__kernel_primitive:NN \luatexrevision \luatex_luatexrevision:D \__kernel_primitive:NN \luatexversion \luatex_luatexversion:D \__kernel_primitive:NN \mathdisplayskipmode \luatex_mathdisplayskipmode:D \__kernel_primitive:NN \matheqnogapstep \luatex_matheqnogapstep:D \__kernel_primitive:NN \mathoption \luatex_mathoption:D + \__kernel_primitive:NN \mathnolimitsmode \luatex_mathnolimitsmode:D + \__kernel_primitive:NN \mathrulesfam \luatex_mathrulesfam:D \__kernel_primitive:NN \mathscriptsmode \luatex_mathscriptsmode:D \__kernel_primitive:NN \mathstyle \luatex_mathstyle:D \__kernel_primitive:NN \mathsurroundskip \luatex_mathsurroundskip:D @@ -846,6 +850,7 @@ \__kernel_primitive:NN \savecatcodetable \luatex_savecatcodetable:D \__kernel_primitive:NN \scantextokens \luatex_scantextokens:D \__kernel_primitive:NN \setfontid \luatex_setfontid:D + \__kernel_primitive:NN \shapemode \luatex_shapemode:D \__kernel_primitive:NN \suppressifcsnameerror \luatex_suppressifcsnameerror:D \__kernel_primitive:NN \suppresslongerror \luatex_suppresslongerror:D \__kernel_primitive:NN \suppressmathparerror \luatex_suppressmathparerror:D @@ -858,7 +863,7 @@ % Slightly more awkward are the directional primitives in \LuaTeX{}. These % come from Omega/Aleph, but we do not support those engines and % so it seems most sensible to treat them as \LuaTeX{} primitives for prefix -% purposes. +% purposes. One here is \enquote{new} but fits into the general set. % \begin{macrocode} \__kernel_primitive:NN \bodydir \luatex_bodydir:D \__kernel_primitive:NN \boxdir \luatex_boxdir:D @@ -868,6 +873,7 @@ \__kernel_primitive:NN \localleftbox \luatex_localleftbox:D \__kernel_primitive:NN \localrightbox \luatex_localrightbox:D \__kernel_primitive:NN \mathdir \luatex_mathdir:D + \__kernel_primitive:NN \linedir \luatex_linedir:D \__kernel_primitive:NN \pagebottomoffset \luatex_pagebottomoffset:D \__kernel_primitive:NN \pagedir \luatex_pagedir:D \__kernel_primitive:NN \pagerightoffset \luatex_pagerightoffset:D @@ -970,6 +976,8 @@ \__kernel_primitive:NN \Umathlimitbelowbgap \utex_limitbelowbgap:D \__kernel_primitive:NN \Umathlimitbelowkern \utex_limitbelowkern:D \__kernel_primitive:NN \Umathlimitbelowvgap \utex_limitbelowvgap:D + \__kernel_primitive:NN \Umathnolimitsubfactor \utex_nolimitsubfactor:D + \__kernel_primitive:NN \Umathnolimitsupfactor \utex_nolimitsupfactor:D \__kernel_primitive:NN \Umathopbinspacing \utex_opbinspacing:D \__kernel_primitive:NN \Umathopclosespacing \utex_opclosespacing:D \__kernel_primitive:NN \Umathopenbinspacing \utex_openbinspacing:D @@ -1130,7 +1138,7 @@ \tex_let:D \tex_italiccorrection:D \@@italiccorr \tex_let:D \tex_underline:D \@@underline % \end{macrocode} -% Some tidying up is needed for \tn{(pdf)tracingfonts}. Newer \LuaTeX{} has +% Some tidying up is needed for \tn[index=tracingfonts]{(pdf)tracingfonts}. Newer \LuaTeX{} has % this simply as \tn{tracingfonts}, but that will have been overwritten by % the \LaTeXe{} kernel. So any spurious definition has to be removed, then % the real version saved either from the \pdfTeX{} name or from \LuaTeX{}. diff --git a/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx b/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx index 08cd5acc89d..abe03c06261 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -%% File: l3prg.dtx Copyright (C) 2005-2015 The LaTeX3 Project +%% File: l3prg.dtx Copyright (C) 2005-2016 The LaTeX3 Project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -37,7 +37,7 @@ \documentclass[full]{l3doc} % %<*driver|package> -\GetIdInfo$Id: l3prg.dtx 6216 2015-11-01 23:32:43Z bruno $ +\GetIdInfo$Id: l3prg.dtx 6679 2016-08-18 20:54:06Z bruno $ {L3 Control structures} % %<*driver> @@ -101,8 +101,8 @@ % \prg_new_conditional:Nnn, \prg_set_conditional:Nnn % } % \begin{syntax} -% \cs{prg_new_conditional:Npnn} \cs{\meta{name}:\meta{arg spec}} \meta{parameters} \Arg{conditions} \Arg{code} \\ -% \cs{prg_new_conditional:Nnn} \cs{\meta{name}:\meta{arg spec}} \Arg{conditions} \Arg{code} +% \cs{prg_new_conditional:Npnn} \cs[no-index]{\meta{name}:\meta{arg spec}} \meta{parameters} \Arg{conditions} \Arg{code} \\ +% \cs{prg_new_conditional:Nnn} \cs[no-index]{\meta{name}:\meta{arg spec}} \Arg{conditions} \Arg{code} % \end{syntax} % These functions create a family of conditionals using the same % \Arg{code} to perform the test created. Those conditionals are @@ -121,8 +121,8 @@ % \prg_new_protected_conditional:Nnn, \prg_set_protected_conditional:Nnn % } % \begin{syntax} -% \cs{prg_new_protected_conditional:Npnn} \cs{\meta{name}:\meta{arg spec}} \meta{parameters} \Arg{conditions} \Arg{code} \\ -% \cs{prg_new_protected_conditional:Nnn} \cs{\meta{name}:\meta{arg spec}} \Arg{conditions} \Arg{code} +% \cs{prg_new_protected_conditional:Npnn} \cs[no-index]{\meta{name}:\meta{arg spec}} \meta{parameters} \Arg{conditions} \Arg{code} \\ +% \cs{prg_new_protected_conditional:Nnn} \cs[no-index]{\meta{name}:\meta{arg spec}} \Arg{conditions} \Arg{code} % \end{syntax} % These functions create a family of protected conditionals using the % same \Arg{code} to perform the test created. The \meta{code} does @@ -138,21 +138,21 @@ % The conditionals are defined by \cs{prg_new_conditional:Npnn} and % friends as: % \begin{itemize} -% \item \cs{\meta{name}_p:\meta{arg spec}} --- a predicate function +% \item \cs[no-index]{\meta{name}_p:\meta{arg spec}} --- a predicate function % which will supply either a logical \texttt{true} or logical % \texttt{false}. This function is intended for use in cases where % one or more logical tests are combined to lead to a final outcome. % This function cannot be defined for \texttt{protected} % conditionals. -% \item \cs{\meta{name}:\meta{arg spec}T} --- a function with one more +% \item \cs[no-index]{\meta{name}:\meta{arg spec}T} --- a function with one more % argument than the original \meta{arg spec} demands. The \meta{true % branch} code in this additional argument will be left on the % input stream only if the test is \texttt{true}. -% \item \cs{\meta{name}:\meta{arg spec}F} --- a function with one more +% \item \cs[no-index]{\meta{name}:\meta{arg spec}F} --- a function with one more % argument than the original \meta{arg spec} demands. The % \meta{false branch} code in this additional argument will be left % on the input stream only if the test is \texttt{false}. -% \item \cs{\meta{name}:\meta{arg spec}TF} --- a function with two +% \item \cs[no-index]{\meta{name}:\meta{arg spec}TF} --- a function with two % more argument than the original \meta{arg spec} demands. The % \meta{true branch} code in the first additional argument will be % left on the input stream if the test is \texttt{true}, while the @@ -192,7 +192,7 @@ % % \begin{function}{\prg_new_eq_conditional:NNn, \prg_set_eq_conditional:NNn} % \begin{syntax} -% \cs{prg_new_eq_conditional:NNn} \cs{\meta{name_1}:\meta{arg spec_1}} \cs{\meta{name_2}:\meta{arg spec_2}} \Arg{conditions} +% \cs{prg_new_eq_conditional:NNn} \cs[no-index]{\meta{name_1}:\meta{arg spec_1}} \cs[no-index]{\meta{name_2}:\meta{arg spec_2}} \Arg{conditions} % \end{syntax} % These functions copy a family of conditionals. The \texttt{new} version % will check for existing definitions (\emph{cf.}~\cs{cs_new:Npn}) whereas @@ -297,7 +297,7 @@ % \cs{bool_set:Nn} \meta{boolean} \Arg{boolexpr} % \end{syntax} % Evaluates the \meta{boolean expression} as described for -% \cs{bool_if:n(TF)}, and sets the \meta{boolean} variable to +% \cs{bool_if:nTF}, and sets the \meta{boolean} variable to % the logical truth of this evaluation. % \end{function} % @@ -594,10 +594,10 @@ % % \begin{function}[EXP]{\__prg_break_point:Nn} % \begin{syntax} -% \cs{__prg_break_point:Nn} \cs{\meta{type}_map_break:} \meta{tokens} +% \cs{__prg_break_point:Nn} \cs[no-index]{\meta{type}_map_break:} \meta{tokens} % \end{syntax} % Used to mark the end of a recursion or mapping: the functions -% \cs{\meta{type}_map_break:} and \cs{\meta{type}_map_break:n} use +% \cs[no-index]{\meta{type}_map_break:} and \cs[no-index]{\meta{type}_map_break:n} use % this to break out of the loop. After the loop ends, the % \meta{tokens} are inserted into the input stream. This occurs even % if the break functions are \emph{not} applied: @@ -607,15 +607,15 @@ % % \begin{function}[EXP]{\__prg_map_break:Nn} % \begin{syntax} -% \cs{__prg_map_break:Nn} \cs{\meta{type}_map_break:} \Arg{user code} +% \cs{__prg_map_break:Nn} \cs[no-index]{\meta{type}_map_break:} \Arg{user code} % \ldots{} -% \cs{__prg_break_point:Nn} \cs{\meta{type}_map_break:} \Arg{ending code} +% \cs{__prg_break_point:Nn} \cs[no-index]{\meta{type}_map_break:} \Arg{ending code} % \end{syntax} % Breaks a recursion in mapping contexts, inserting in the input % stream the \meta{user code} after the \meta{ending code} for the % loop. The function breaks loops, inserting their \meta{ending % code}, until reaching a loop with the same \meta{type} as its -% first argument. This \cs{\meta{type}_map_break:} argument is simply +% first argument. This \cs[no-index]{\meta{type}_map_break:} argument is simply % used as a recognizable marker for the \meta{type}. % \end{function} % @@ -853,7 +853,7 @@ \__msg_show_variable:NNNnn #1 \bool_if_exist:NTF ? { } { > ~ \token_to_str:N #1 = \@@_to_str:n {#1} } } -\cs_new_protected_nopar:Npn \bool_show:n +\cs_new_protected:Npn \bool_show:n { \__msg_show_wrap:Nn \@@_to_str:n } \cs_new:Npn \@@_to_str:n #1 { \bool_if:nTF {#1} { true } { false } } @@ -1103,10 +1103,10 @@ % operation is similar except it closes the special alignment group % before returning the boolean. % \begin{macrocode} -\cs_new_nopar:cpn { @@_)_0:w } { \c_false_bool } -\cs_new_nopar:cpn { @@_)_1:w } { \c_true_bool } -\cs_new_nopar:cpn { @@_S_0:w } { \group_align_safe_end: \c_false_bool } -\cs_new_nopar:cpn { @@_S_1:w } { \group_align_safe_end: \c_true_bool } +\cs_new:cpn { @@_)_0:w } { \c_false_bool } +\cs_new:cpn { @@_)_1:w } { \c_true_bool } +\cs_new:cpn { @@_S_0:w } { \group_align_safe_end: \c_false_bool } +\cs_new:cpn { @@_S_1:w } { \group_align_safe_end: \c_true_bool } % \end{macrocode} % \end{macro} % @@ -1115,8 +1115,8 @@ % Two cases where we simply continue scanning. We must remove the % second |&| or \verb"|". % \begin{macrocode} -\cs_new_nopar:cpn { @@_&_1:w } & { \@@_get_next:NN \use_i:nn } -\cs_new_nopar:cpn { @@_|_0:w } | { \@@_get_next:NN \use_i:nn } +\cs_new:cpn { @@_&_1:w } & { \@@_get_next:NN \use_i:nn } +\cs_new:cpn { @@_|_0:w } | { \@@_get_next:NN \use_i:nn } % \end{macrocode} % \end{macro} % \end{macro} @@ -1134,9 +1134,9 @@ % evaluation. This is slightly tricky as there are no braces so we % have to play match the |()| manually. % \begin{macrocode} -\cs_new_nopar:cpn { @@_&_0:w } & +\cs_new:cpn { @@_&_0:w } & { \@@_eval_skip_to_end_auxi:Nw \c_false_bool } -\cs_new_nopar:cpn { @@_|_1:w } | +\cs_new:cpn { @@_|_1:w } | { \@@_eval_skip_to_end_auxi:Nw \c_true_bool } % \end{macrocode} % There is always at least one |)| waiting, namely the outer @@ -1521,9 +1521,9 @@ % that the successive expansions of \cs{group_align_safe_begin/end:} % are always brace balanced. % \begin{macrocode} -\cs_new_nopar:Npn \group_align_safe_begin: +\cs_new:Npn \group_align_safe_begin: { \if_int_compare:w \if_false: { \fi: `} = \c_zero \fi: } -\cs_new_nopar:Npn \group_align_safe_end: +\cs_new:Npn \group_align_safe_end: { \if_int_compare:w `{ = \c_zero } \fi: } % \end{macrocode} % \end{macro} @@ -1558,7 +1558,7 @@ % \begin{macro}[int]{\scan_align_safe_stop:} % Deprecated 2015-08-01 for removal after 2016-12-31. % \begin{macrocode} -\cs_new_protected_nopar:Npn \scan_align_safe_stop: { } +\cs_new_protected:Npn \scan_align_safe_stop: { } % \end{macrocode} % \end{macro} % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx b/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx index a30c9b30b85..5513946feef 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx @@ -37,7 +37,7 @@ \documentclass[full]{l3doc} % %<*driver|package> -\GetIdInfo$Id: l3prop.dtx 6366 2016-01-05 22:18:59Z joseph $ +\GetIdInfo$Id: l3prop.dtx 6685 2016-08-19 16:26:52Z bruno $ {L3 Property lists} % %<*driver> @@ -112,7 +112,8 @@ % \cs{prop_clear_new:N} \meta{property list} % \end{syntax} % Ensures that the \meta{property list} exists globally by applying -% \cs{prop_new:N} if necessary, then applies \cs{prop_(g)clear:N} to leave +% \cs{prop_new:N} if necessary, then applies +% \cs[index=prop_clear:N]{prop_(g)clear:N} to leave % the list empty. % \end{function} % @@ -378,7 +379,7 @@ % \begin{syntax} % \cs{prop_map_break:} % \end{syntax} -% Used to terminate a \cs{prop_map_\ldots} function before all +% Used to terminate a \cs[no-index]{prop_map_\ldots} function before all % entries in the \meta{property list} have been processed. This will % normally take place within a conditional statement, for example % \begin{verbatim} @@ -391,7 +392,7 @@ % } % } % \end{verbatim} -% Use outside of a \cs{prop_map_\ldots} scenario will lead to low +% Use outside of a \cs[no-index]{prop_map_\ldots} scenario will lead to low % level \TeX{} errors. % \end{function} % @@ -399,7 +400,7 @@ % \begin{syntax} % \cs{prop_map_break:n} \Arg{tokens} % \end{syntax} -% Used to terminate a \cs{prop_map_\ldots} function before all +% Used to terminate a \cs[no-index]{prop_map_\ldots} function before all % entries in the \meta{property list} have been processed, inserting % the \meta{tokens} after the mapping has ended. This will % normally take place within a conditional statement, for example @@ -413,7 +414,7 @@ % } % } % \end{verbatim} -% Use outside of a \cs{prop_map_\ldots} scenario will lead to low +% Use outside of a \cs[no-index]{prop_map_\ldots} scenario will lead to low % level \TeX{} errors. % \end{function} % @@ -853,8 +854,8 @@ % updated entry is placed at the same spot as the original \meta{key} % in the property list, preserving the order of entries. % \begin{macrocode} -\cs_new_protected_nopar:Npn \prop_put:Nnn { \@@_put:NNnn \tl_set:Nx } -\cs_new_protected_nopar:Npn \prop_gput:Nnn { \@@_put:NNnn \tl_gset:Nx } +\cs_new_protected:Npn \prop_put:Nnn { \@@_put:NNnn \tl_set:Nx } +\cs_new_protected:Npn \prop_gput:Nnn { \@@_put:NNnn \tl_gset:Nx } \cs_new_protected:Npn \@@_put:NNnn #1#2#3#4 { \tl_set:Nn \l_@@_internal_tl @@ -889,9 +890,9 @@ % If the key is new, then the value is added, being careful to % convert the key to a string using \cs{tl_to_str:n}. % \begin{macrocode} -\cs_new_protected_nopar:Npn \prop_put_if_new:Nnn +\cs_new_protected:Npn \prop_put_if_new:Nnn { \@@_put_if_new:NNnn \tl_set:Nx } -\cs_new_protected_nopar:Npn \prop_gput_if_new:Nnn +\cs_new_protected:Npn \prop_gput_if_new:Nnn { \@@_put_if_new:NNnn \tl_gset:Nx } \cs_new_protected:Npn \@@_put_if_new:NNnn #1#2#3#4 { @@ -1101,9 +1102,9 @@ % \begin{macro}[tested = m3prop003]{\prop_map_break:n} % The break statements are based on the general \cs{__prg_map_break:Nn}. % \begin{macrocode} -\cs_new_nopar:Npn \prop_map_break: +\cs_new:Npn \prop_map_break: { \__prg_map_break:Nn \prop_map_break: { } } -\cs_new_nopar:Npn \prop_map_break:n +\cs_new:Npn \prop_map_break:n { \__prg_map_break:Nn \prop_map_break: } % \end{macrocode} % \end{macro} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx b/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx index 32d2fc4540e..7fb44625dd3 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx @@ -37,7 +37,7 @@ \documentclass[full]{l3doc} % %<*driver|package> -\GetIdInfo$Id: l3quark.dtx 5855 2015-08-17 17:22:56Z mittelba $ +\GetIdInfo$Id: l3quark.dtx 6685 2016-08-19 16:26:52Z bruno $ {L3 Quarks} % %<*driver> @@ -323,12 +323,12 @@ % \__quark_if_recursion_tail_break:nN % } % \begin{syntax} -% \cs{__quark_if_recursion_tail_break:nN} \Arg{token list} \cs{\meta{type}_map_break:} +% \cs{__quark_if_recursion_tail_break:nN} \Arg{token list} \cs[no-index]{\meta{type}_map_break:} % \end{syntax} % Tests if \meta{token list} contains only \cs{q_recursion_tail}, and -% if so terminates the recursion using \cs{\meta{type}_map_break:}. +% if so terminates the recursion using \cs[no-index]{\meta{type}_map_break:}. % The recursion end should be marked by \cs{prg_break_point:Nn} -% \cs{\meta{type}_map_break:}. +% \cs[no-index]{\meta{type}_map_break:}. % \end{function} % % \section{Scan marks} @@ -487,7 +487,8 @@ % % \begin{macro}{\__quark_if_recursion_tail_break:NN} % \begin{macro}{\__quark_if_recursion_tail_break:nN} -% Analogs of the \cs{quark_if_recursion_tail_stop\ldots{}} functions. +% Analogs of the \cs[index=quark_if_recursion_tail_stop:n] +% {quark_if_recursion_tail_stop\ldots{}} functions. % Break the mapping using |#2|. % \begin{macrocode} \cs_new:Npn \__quark_if_recursion_tail_break:NN #1#2 diff --git a/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx b/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx index cce3edcd256..942b6fcdb35 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -%% File: l3seq.dtx Copyright (C) 1990-2015 The LaTeX3 Project +%% File: l3seq.dtx Copyright (C) 1990-2016 The LaTeX3 Project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -37,7 +37,7 @@ \documentclass[full]{l3doc} % %<*driver|package> -\GetIdInfo$Id: l3seq.dtx 5777 2015-08-05 02:32:21Z bruno $ +\GetIdInfo$Id: l3seq.dtx 6685 2016-08-19 16:26:52Z bruno $ {L3 Sequences and stacks} % %<*driver> @@ -100,7 +100,8 @@ % \cs{seq_clear_new:N} \meta{sequence} % \end{syntax} % Ensures that the \meta{sequence} exists globally by applying -% \cs{seq_new:N} if necessary, then applies \cs{seq_(g)clear:N} to leave +% \cs{seq_new:N} if necessary, then applies +% \cs[index=seq_clear:N]{seq_(g)clear:N} to leave % the \meta{sequence} empty. % \end{function} % @@ -422,7 +423,7 @@ % \end{syntax} % Removes duplicate items from the \meta{sequence}, leaving the % left most copy of each item in the \meta{sequence}. The \meta{item} -% comparison takes place on a token basis, as for \cs{tl_if_eq:nn(TF)}. +% comparison takes place on a token basis, as for \cs{tl_if_eq:nnTF}. % \begin{texnote} % This function iterates through every item in the \meta{sequence} and % does a comparison with the \meta{items} already checked. It is therefore @@ -440,12 +441,12 @@ % \end{syntax} % Removes every occurrence of \meta{item} from the \meta{sequence}. % The \meta{item} comparison takes place on a token basis, as for -% \cs{tl_if_eq:nn(TF)}. +% \cs{tl_if_eq:nnTF}. % \end{function} % % -% \begin{function}[added = 2014-07-18]^^A -% {^^A +% \begin{function}[added = 2014-07-18] +% { % \seq_reverse:N, \seq_reverse:c, % \seq_greverse:N, \seq_greverse:c % } @@ -524,7 +525,7 @@ % \begin{syntax} % \cs{seq_map_break:} % \end{syntax} -% Used to terminate a \cs{seq_map_\ldots} function before all +% Used to terminate a \cs[no-index]{seq_map_\ldots} function before all % entries in the \meta{sequence} have been processed. This will % normally take place within a conditional statement, for example % \begin{verbatim} @@ -537,7 +538,7 @@ % } % } % \end{verbatim} -% Use outside of a \cs{seq_map_\ldots} scenario will lead to low +% Use outside of a \cs[no-index]{seq_map_\ldots} scenario will lead to low % level \TeX{} errors. % \begin{texnote} % When the mapping is broken, additional tokens may be inserted by the @@ -551,7 +552,7 @@ % \begin{syntax} % \cs{seq_map_break:n} \Arg{tokens} % \end{syntax} -% Used to terminate a \cs{seq_map_\ldots} function before all +% Used to terminate a \cs[no-index]{seq_map_\ldots} function before all % entries in the \meta{sequence} have been processed, inserting % the \meta{tokens} after the mapping has ended. This will % normally take place within a conditional statement, for example @@ -565,7 +566,7 @@ % } % } % \end{verbatim} -% Use outside of a \cs{seq_map_\ldots} scenario will lead to low +% Use outside of a \cs[no-index]{seq_map_\ldots} scenario will lead to low % level \TeX{} errors. % \begin{texnote} % When the mapping is broken, additional tokens may be inserted by the @@ -755,7 +756,7 @@ % % Some operations on a set \meta{seq~var} are straightforward. For % instance, \cs{seq_count:N} \meta{seq~var} expands to the number of -% items, while \cs{seq_if_in:Nn(TF)} \meta{seq~var} \Arg{item} tests if +% items, while \cs{seq_if_in:NnTF} \meta{seq~var} \Arg{item} tests if % the \meta{item} is in the set. % % Adding an \meta{item} to a set \meta{seq~var} can be done by appending @@ -1102,9 +1103,9 @@ % lost braces. The second step is solely there to strip % braces which are outermost after space trimming. % \begin{macrocode} -\cs_new_protected_nopar:Npn \seq_set_split:Nnn +\cs_new_protected:Npn \seq_set_split:Nnn { \@@_set_split:NNnn \tl_set:Nx } -\cs_new_protected_nopar:Npn \seq_gset_split:Nnn +\cs_new_protected:Npn \seq_gset_split:Nnn { \@@_set_split:NNnn \tl_gset:Nx } \cs_new_protected:Npn \@@_set_split:NNnn #1#2#3#4 { @@ -1380,9 +1381,9 @@ % of \cs{exp_not:n}. The previous calls are cleanly removed % from the stack, and the memory consumption becomes linear. % \begin{macrocode} -\cs_new_protected_nopar:Npn \seq_reverse:N +\cs_new_protected:Npn \seq_reverse:N { \@@_reverse:NN \tl_set:Nx } -\cs_new_protected_nopar:Npn \seq_greverse:N +\cs_new_protected:Npn \seq_greverse:N { \@@_reverse:NN \tl_gset:Nx } \cs_new_protected:Npn \@@_reverse:NN #1 #2 { @@ -1457,7 +1458,7 @@ \prg_return_false: \__prg_break_point: } -\cs_new_nopar:Npn \@@_if_in: +\cs_new:Npn \@@_if_in: { \__prg_break:n { \group_end: \prg_return_true: } } \cs_generate_variant:Nn \seq_if_in:NnT { NV , Nv , No , Nx } \cs_generate_variant:Nn \seq_if_in:NnT { c , cV , cv , co , cx } @@ -1529,9 +1530,9 @@ % to be redefined. This makes it more sensible to use an auxiliary % function for the local and global cases. % \begin{macrocode} -\cs_new_protected_nopar:Npn \seq_pop_left:NN +\cs_new_protected:Npn \seq_pop_left:NN { \@@_pop:NNNN \@@_pop_left:NNN \tl_set:Nn } -\cs_new_protected_nopar:Npn \seq_gpop_left:NN +\cs_new_protected:Npn \seq_gpop_left:NN { \@@_pop:NNNN \@@_pop_left:NNN \tl_gset:Nn } \cs_new_protected:Npn \@@_pop_left:NNN #1#2#3 { \exp_after:wN \@@_pop_left:wnwNNN #2 \q_stop #1#2#3 } @@ -1599,9 +1600,9 @@ % is performed, with an empty argument and \cs{use_none:nn}, which % finally stops the loop. % \begin{macrocode} -\cs_new_protected_nopar:Npn \seq_pop_right:NN +\cs_new_protected:Npn \seq_pop_right:NN { \@@_pop:NNNN \@@_pop_right:NNN \tl_set:Nx } -\cs_new_protected_nopar:Npn \seq_gpop_right:NN +\cs_new_protected:Npn \seq_gpop_right:NN { \@@_pop:NNNN \@@_pop_right:NNN \tl_gset:Nx } \cs_new_protected:Npn \@@_pop_right:NNN #1#2#3 { @@ -1728,9 +1729,9 @@ % used to find the end of the code. Any ending code is then inserted % before the return value of \cs{seq_map_break:n} is inserted. % \begin{macrocode} -\cs_new_nopar:Npn \seq_map_break: +\cs_new:Npn \seq_map_break: { \__prg_map_break:Nn \seq_map_break: { } } -\cs_new_nopar:Npn \seq_map_break:n +\cs_new:Npn \seq_map_break:n { \__prg_map_break:Nn \seq_map_break: } % \end{macrocode} % \end{macro} @@ -1789,7 +1790,7 @@ \cs_gset_eq:cN { __prg_map_ \int_use:N \g__prg_map_int :w } \@@_item:n } -\cs_new_protected_nopar:Npn \@@_pop_item_def: +\cs_new_protected:Npn \@@_pop_item_def: { \cs_gset_eq:Nc \@@_item:n { __prg_map_ \int_use:N \g__prg_map_int :w } diff --git a/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx b/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx index 404b24bef11..e22e024ef16 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx @@ -38,7 +38,7 @@ \documentclass[full]{l3doc} % %<*driver|package> -\GetIdInfo$Id: l3skip.dtx 6366 2016-01-05 22:18:59Z joseph $ +\GetIdInfo$Id: l3skip.dtx 6692 2016-08-19 22:29:47Z bruno $ {L3 Dimensions and skips} % %<*driver> @@ -112,7 +112,8 @@ % \cs{dim_zero_new:N} \meta{dimension} % \end{syntax} % Ensures that the \meta{dimension} exists globally by applying -% \cs{dim_new:N} if necessary, then applies \cs{dim_(g)zero:N} to leave +% \cs{dim_new:N} if necessary, then applies +% \cs[index=dim_zero:N]{dim_(g)zero:N} to leave % the \meta{dimension} set to zero. % \end{function} % @@ -272,7 +273,7 @@ % \end{center} % \end{function} % -% \begin{function}[added = 2013-07-24, EXP, TF]{\dim_case:nn} +% \begin{function}[added = 2013-07-24, EXP, noTF]{\dim_case:nn} % \begin{syntax} % \cs{dim_case:nnTF} \Arg{test dimension expression} \\ % ~~|{| \\ @@ -598,7 +599,8 @@ % \cs{skip_zero_new:N} \meta{skip} % \end{syntax} % Ensures that the \meta{skip} exists globally by applying -% \cs{skip_new:N} if necessary, then applies \cs{skip_(g)zero:N} to leave +% \cs{skip_new:N} if necessary, then applies +% \cs[index=skip_zero:N]{skip_(g)zero:N} to leave % the \meta{skip} set to zero. % \end{function} % @@ -816,7 +818,8 @@ % \cs{muskip_zero_new:N} \meta{muskip} % \end{syntax} % Ensures that the \meta{muskip} exists globally by applying -% \cs{muskip_new:N} if necessary, then applies \cs{muskip_(g)zero:N} +% \cs{muskip_new:N} if necessary, then applies +% \cs[index=muskip_zero:N]{muskip_(g)zero:N} % to leave the \meta{muskip} set to zero. % \end{function} % @@ -1268,13 +1271,12 @@ % \end{macro} % \end{macro} % -% \begin{macro}[EXP]{\dim_case:nn} -% \begin{macro}[EXP, TF]{\dim_case:nn} +% \begin{macro}[EXP, noTF]{\dim_case:nn} % \begin{macro}[aux]{\@@_case:nnTF} % \begin{macro}[aux]{\@@_case:nw, \@@_case_end:nw} % For dimension cases, the first task to fully expand the check % condition. The over all idea is then much the same as for -% \cs{str_case:nn(TF)} as described in \pkg{l3basics}. +% \cs[index=str_case:nnTF]{str_case:nn(TF)} as described in \pkg{l3basics}. % \begin{macrocode} \cs_new:Npn \dim_case:nnTF #1 { @@ -1309,7 +1311,6 @@ % \end{macro} % \end{macro} % \end{macro} -% \end{macro} % % \subsection{Dimension expression loops} % @@ -1499,7 +1500,7 @@ % Diagnostics. We don't use the \TeX{} primitive \tn{showthe} to show % dimension expressions: this gives a more unified output. % \begin{macrocode} -\cs_new_protected_nopar:Npn \dim_show:n +\cs_new_protected:Npn \dim_show:n { \__msg_show_wrap:Nn \dim_eval:n } % \end{macrocode} % \end{macro} @@ -1507,7 +1508,7 @@ % \subsection{Constant dimensions} % % \begin{variable}{\c_zero_dim, \c_max_dim} -% Constant dimensions: in package mode, a couple of registers can be saved. +% Constant dimensions. % \begin{macrocode} \dim_const:Nn \c_zero_dim { 0 pt } \dim_const:Nn \c_max_dim { 16383.99999 pt } @@ -1741,7 +1742,7 @@ % Diagnostics. We don't use the \TeX{} primitive \tn{showthe} to show % skip expressions: this gives a more unified output. % \begin{macrocode} -\cs_new_protected_nopar:Npn \skip_show:n +\cs_new_protected:Npn \skip_show:n { \__msg_show_wrap:Nn \skip_eval:n } % \end{macrocode} % \end{macro} @@ -1931,7 +1932,7 @@ % Diagnostics. We don't use the \TeX{} primitive \tn{showthe} to show % muskip expressions: this gives a more unified output. % \begin{macrocode} -\cs_new_protected_nopar:Npn \muskip_show:n +\cs_new_protected:Npn \muskip_show:n { \__msg_show_wrap:Nn \muskip_eval:n } % \end{macrocode} % \end{macro} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3str.dtx b/Master/texmf-dist/source/latex/l3kernel/l3str.dtx index 05b327cf286..376bcb729fe 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3str.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3str.dtx @@ -37,7 +37,7 @@ \documentclass[full]{l3doc} % %<*driver|package> -\GetIdInfo$Id: l3str.dtx 6441 2016-03-24 10:11:59Z joseph $ +\GetIdInfo$Id: l3str.dtx 6692 2016-08-19 22:29:47Z bruno $ {L3 Strings} % %<*driver> @@ -91,8 +91,8 @@ % representation differently. % % Note that as string variables are a special case of token list variables -% the coverage of \cs{str_\ldots{}:N} functions is somewhat smaller than -% \cs{tl_\ldots{}:N}. +% the coverage of \cs[no-index]{str_\ldots{}:N} functions is somewhat smaller than +% \cs[no-index]{tl_\ldots{}:N}. % % The functions \cs{cs_to_str:N}, \cs{tl_to_str:n}, \cs{tl_to_str:N} and % \cs{token_to_str:N} (and variants) will generate strings from the appropriate @@ -101,11 +101,11 @@ % % Most expandable functions in this module come in three flavours: % \begin{itemize} -% \item \cs{str_...:N}, which expect a token list or string +% \item \cs[no-index]{str_\ldots{}:N}, which expect a token list or string % variable as their argument; -% \item \cs{str_...:n}, taking any token list (or string) as an +% \item \cs[no-index]{str_\ldots{}:n}, taking any token list (or string) as an % argument; -% \item \cs{str_..._ignore_spaces:n}, which ignores any space +% \item \cs[no-index]{str_\ldots{}_ignore_spaces:n}, which ignores any space % encountered during the operation: these functions are typically % faster than those which take care of escaping spaces % appropriately. @@ -145,7 +145,8 @@ % \cs{str_clear_new:N} \meta{str~var} % \end{syntax} % Ensures that the \meta{str~var} exists globally by applying -% \cs{str_new:N} if necessary, then applies \cs{str_(g)clear:N} to leave +% \cs{str_new:N} if necessary, then applies +% \cs[index=str_clear:N]{str_(g)clear:N} to leave % the \meta{str~var} empty. % \end{function} % @@ -269,7 +270,7 @@ % is logically \texttt{true}. % \end{function} % -% \begin{function}[added = 2013-07-24, updated = 2015-02-28, EXP, TF] +% \begin{function}[added = 2013-07-24, updated = 2015-02-28, EXP, noTF] % {\str_case:nn, \str_case:on, \str_case:nV, \str_case:nv} % \begin{syntax} % \cs{str_case:nnTF} \Arg{test string} \\ @@ -295,7 +296,7 @@ % % \begin{function}[added = 2013-07-24, EXP, TF]{\str_case_x:nn} % \begin{syntax} -% \cs{str_case_x:nnF} \Arg{test string} \\ +% \cs{str_case_x:nnTF} \Arg{test string} \\ % ~~|{| \\ % ~~~~\Arg{string case_1} \Arg{code case_1} \\ % ~~~~\Arg{string case_2} \Arg{code case_2} \\ @@ -478,8 +479,10 @@ % \begin{itemize} % \item Caseless comparisons: use \cs{str_fold_case:n} for this % situation (case folding is district from lower casing). -% \item Case changing text for typesetting: see the \cs{tl_lower_case:n(n)}, -% \cs{tl_upper_case:n(n)} and \cs{tl_mixed_case:n(n)} functions which +% \item Case changing text for typesetting: see the +% \cs[index=tl_lower_case:n]{tl_lower_case:n(n)}, +% \cs[index=tl_upper_case:n]{tl_upper_case:n(n)} and +% \cs[index=tl_mixed_case:n]{tl_mixed_case:n(n)} functions which % correctly deal with context-dependence and other factors appropriate % to text case changing. % \end{itemize} @@ -608,7 +611,7 @@ % character basis, and is \texttt{true} if the two lists contain the same % characters in the same order. Either \cs{prg_return_true:} or % \cs{prg_return_false:} is then left in the input stream. This is a version -% of \cs{str_if_eq_x:nn(TF)} coded for speed. +% of \cs{str_if_eq_x:nnTF} coded for speed. % \end{function} % % \begin{function}[EXP]{\__str_to_other:n} @@ -764,7 +767,7 @@ % % \begin{macro}[int, EXP]{\@@_if_eq_x:nn} % \begin{macro}[aux, EXP]{\@@_escape_x:n} -% String comparisons rely on the primitive \cs{(pdf)strcmp} if available: +% String comparisons rely on the primitive \cs[index=pdfstrcmp]{(pdf)strcmp} if available: % \LuaTeX{} does not have it, so emulation is required. As the net result % is that we do not \emph{always} use the primitive, the correct approach % is to wrap up in a function with defined behaviour. That's done by @@ -872,15 +875,13 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[EXP] -% {\str_case:nn, \str_case:on, \str_case:nV, \str_case:nv, \str_case_x:nn} -% \begin{macro}[EXP, TF] +% \begin{macro}[EXP, noTF] % {\str_case:nn, \str_case:on, \str_case:nV, \str_case:nv, \str_case_x:nn} % \begin{macro}[EXP, aux]{\@@_case:nnTF, \@@_case_x:nnTF} % \begin{macro}[aux, EXP] % {\@@_case:nw, \@@_case_x:nw, \@@_case_end:nw} -% Much the same as \cs{tl_case:nn(TF)} here: just a change in the internal -% comparison. +% Much the same as \cs[index=tl_case:nn]{tl_case:nn(TF)} here: +% just a change in the internal comparison. % \begin{macrocode} \cs_new:Npn \str_case:nn #1#2 { @@ -947,7 +948,6 @@ % \end{macro} % \end{macro} % \end{macro} -% \end{macro} % % \subsection{Accessing specific characters in a string} % @@ -1009,7 +1009,7 @@ % brace group before the string in that case: that brace group also % covers the case where the \meta{index} is zero. % \begin{macrocode} -\cs_new_nopar:Npn \str_item:Nn { \exp_args:No \str_item:nn } +\cs_new:Npn \str_item:Nn { \exp_args:No \str_item:nn } \cs_generate_variant:Nn \str_item:Nn { c } \cs_new:Npn \str_item:nn #1#2 { @@ -1105,7 +1105,7 @@ % Afterwards, skip characters, then keep some more, and finally drop % the end of the string. % \begin{macrocode} -\cs_new_nopar:Npn \str_range:Nnn { \exp_args:No \str_range:nnn } +\cs_new:Npn \str_range:Nnn { \exp_args:No \str_range:nnn } \cs_generate_variant:Nn \str_range:Nnn { c } \cs_new:Npn \str_range:nnn #1#2#3 { @@ -1226,7 +1226,7 @@ % \meta{number} is added to the sum of $9$ that precedes, to adjust % the result. % \begin{macrocode} -\cs_new_nopar:Npn \str_count_spaces:N +\cs_new:Npn \str_count_spaces:N { \exp_args:No \str_count_spaces:n } \cs_generate_variant:Nn \str_count_spaces:N { c } \cs_new:Npn \str_count_spaces:n #1 @@ -1268,7 +1268,7 @@ % \cs{str_count_ignore_spaces:n} but expects its argument to already % be a string or a string with spaces escaped. % \begin{macrocode} -\cs_new_nopar:Npn \str_count:N { \exp_args:No \str_count:n } +\cs_new:Npn \str_count:N { \exp_args:No \str_count:n } \cs_generate_variant:Nn \str_count:N { c } \cs_new:Npn \str_count:n #1 { @@ -1331,7 +1331,7 @@ % gives an empty result after passing through % \cs{use_i_delimit_by_q_stop:nw}. % \begin{macrocode} -\cs_new_nopar:Npn \str_head:N { \exp_args:No \str_head:n } +\cs_new:Npn \str_head:N { \exp_args:No \str_head:n } \cs_generate_variant:Nn \str_head:N { c } \cs_set:Npn \str_head:n #1 { @@ -1368,7 +1368,7 @@ % One can check that an empty (or blank) string yields an empty % tail. % \begin{macrocode} -\cs_new_nopar:Npn \str_tail:N { \exp_args:No \str_tail:n } +\cs_new:Npn \str_tail:N { \exp_args:No \str_tail:n } \cs_generate_variant:Nn \str_tail:N { c } \cs_set:Npn \str_tail:n #1 { @@ -1623,7 +1623,6 @@ \@@_map_loop: } } - \cs_set_nopar:Npn \l_@@_tmp_tl { } % \end{macrocode} % The lead-off parser for each line is common for all of the files. If % the line starts with a |#| it's a comment. There's one special comment diff --git a/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx b/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx index 829f45c6201..d22763484f9 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx @@ -37,7 +37,7 @@ \documentclass[full]{l3doc} % %<*driver|package> -\GetIdInfo$Id: l3tl.dtx 6465 2016-03-26 16:15:09Z joseph $ +\GetIdInfo$Id: l3tl.dtx 6692 2016-08-19 22:29:47Z bruno $ {L3 Token lists} % %<*driver> @@ -105,30 +105,6 @@ % Functions which act on items are often faster than their analogue acting % directly on tokens. % -% ^^A todo: perhaps move to another module, l3token or l3basics? -% \begin{texnote} -% When \TeX{} fetches an undelimited argument from the input stream, -% explicit character tokens with character code $32$ (space) and -% category code $10$ (space), which we here call \enquote{explicit -% space characters}, are ignored. If the following token is an -% explicit character token with category code $1$ (begin-group) and an -% arbitrary character code, then \TeX{} scans ahead to obtain an equal -% number of explicit character tokens with category code $1$ -% (begin-group) and $2$ (end-group), and the resulting list of tokens -% (with outer braces removed) becomes the argument. Otherwise, a -% single token is taken as the argument for the macro: we call such -% single tokens \enquote{N-type}, as they are suitable to be used as -% an argument for a function with the signature~\texttt{:N}. -% -% When \TeX{} reads a character of category code $10$ for the first -% time, it is converted to an explicit space character, with character -% code $32$, regardless of the initial character code. -% \enquote{Funny} spaces with a different category code, can be -% produced using \tn{tex_lowercase:D} or \tn{tex_uppercase:D}. -% Explicit space characters are also produced as a result of -% \cs{token_to_str:N}, \cs{tl_to_str:n}, etc. -% \end{texnote} -% % \section{Creating and initialising token list variables} % % \begin{function}{\tl_new:N, \tl_new:c} @@ -163,7 +139,7 @@ % \cs{tl_clear_new:N} \meta{tl~var} % \end{syntax} % Ensures that the \meta{tl~var} exists globally by applying -% \cs{tl_new:N} if necessary, then applies \cs{tl_(g)clear:N} to leave +% \cs{tl_new:N} if necessary, then applies \cs[index=tl_clear:N]{tl_(g)clear:N} to leave % the \meta{tl~var} empty. % \end{function} % @@ -504,7 +480,7 @@ % token count $1$ according to \cs{tl_count:n}. % \end{function} % -% \begin{function}[added = 2013-07-24, EXP, TF]{\tl_case:Nn, \tl_case:cn} +% \begin{function}[added = 2013-07-24, EXP, noTF]{\tl_case:Nn, \tl_case:cn} % \begin{syntax} % \cs{tl_case:NnTF} \meta{test token list variable} \\ % ~~"{" \\ @@ -601,7 +577,7 @@ % \begin{syntax} % \cs{tl_map_break:} % \end{syntax} -% Used to terminate a \cs{tl_map_\ldots} function before all +% Used to terminate a \cs[no-index]{tl_map_\ldots} function before all % entries in the \meta{token list variable} have been processed. This % will normally take place within a conditional statement, for example % \begin{verbatim} @@ -612,7 +588,7 @@ % } % \end{verbatim} % See also \cs{tl_map_break:n}. -% Use outside of a \cs{tl_map_\ldots} scenario will lead to low +% Use outside of a \cs[no-index]{tl_map_\ldots} scenario will lead to low % level \TeX{} errors. % \begin{texnote} % When the mapping is broken, additional tokens may be inserted by the @@ -626,7 +602,7 @@ % \begin{syntax} % \cs{tl_map_break:n} \Arg{tokens} % \end{syntax} -% Used to terminate a \cs{tl_map_\ldots} function before all +% Used to terminate a \cs[no-index]{tl_map_\ldots} function before all % entries in the \meta{token list variable} have been processed, inserting % the \meta{tokens} after the mapping has ended. This will % normally take place within a conditional statement, for example @@ -638,7 +614,7 @@ % % Do something useful % } % \end{verbatim} -% Use outside of a \cs{tl_map_\ldots} scenario will lead to low +% Use outside of a \cs[no-index]{tl_map_\ldots} scenario will lead to low % level \TeX{} errors. % \begin{texnote} % When the mapping is broken, additional tokens may be inserted by the @@ -1334,7 +1310,7 @@ % check definitions exist. This part of the process is done now, so that % variable types based on |tl| (for example |clist|, |seq| and |prop|) will % inherit the appropriate definitions. -% No \cs{tl_map_\ldots} yet as the mechanisms are not fully in place. Thus +% No \cs[no-index]{tl_map_\ldots} yet as the mechanisms are not fully in place. Thus % instead do a more low level set up for a mapping, as in \pkg{l3basics}. % \begin{macrocode} %<*package> @@ -1462,11 +1438,11 @@ % The difference between single-line and multiple-line files % complicates the story, as explained below. % \begin{macrocode} -\cs_new_protected_nopar:Npn \tl_set_rescan:Nnn +\cs_new_protected:Npn \tl_set_rescan:Nnn { \@@_set_rescan:NNnn \tl_set:Nn } -\cs_new_protected_nopar:Npn \tl_gset_rescan:Nnn +\cs_new_protected:Npn \tl_gset_rescan:Nnn { \@@_set_rescan:NNnn \tl_gset:Nn } -\cs_new_protected_nopar:Npn \tl_rescan:nn +\cs_new_protected:Npn \tl_rescan:nn { \@@_set_rescan:NNnn \prg_do_nothing: \use:n } \cs_new_protected:Npn \@@_set_rescan:NNnn #1#2#3#4 { @@ -1654,13 +1630,13 @@ % describing the auxiliary functions below, we denote the contents of % the \meta{tl~var} by \meta{token list}. % \begin{macrocode} -\cs_new_protected_nopar:Npn \tl_replace_once:Nnn +\cs_new_protected:Npn \tl_replace_once:Nnn { \@@_replace:NnNNNnn \q_mark ? \@@_replace_wrap:w \tl_set:Nx } -\cs_new_protected_nopar:Npn \tl_greplace_once:Nnn +\cs_new_protected:Npn \tl_greplace_once:Nnn { \@@_replace:NnNNNnn \q_mark ? \@@_replace_wrap:w \tl_gset:Nx } -\cs_new_protected_nopar:Npn \tl_replace_all:Nnn +\cs_new_protected:Npn \tl_replace_all:Nnn { \@@_replace:NnNNNnn \q_mark ? \@@_replace_next:w \tl_set:Nx } -\cs_new_protected_nopar:Npn \tl_greplace_all:Nnn +\cs_new_protected:Npn \tl_greplace_all:Nnn { \@@_replace:NnNNNnn \q_mark ? \@@_replace_next:w \tl_gset:Nx } \cs_generate_variant:Nn \tl_replace_once:Nnn { c } \cs_generate_variant:Nn \tl_greplace_once:Nnn { c } @@ -1873,6 +1849,7 @@ \cs_generate_variant:Nn \tl_gremove_all:Nn { c } % \end{macrocode} % \end{macro} +% \end{macro} % % \subsection{Token list conditionals} % @@ -1898,7 +1875,6 @@ % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} % % \begin{macro}[pTF]{\tl_if_empty:N, \tl_if_empty:c} % These functions check whether the token list in the argument is @@ -1949,13 +1925,13 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[pTF]{\tl_if_empty:o} +% \begin{macro}[pTF,documented-as=\tl_if_empty:nTF]{\tl_if_empty:o} % \begin{macro}[EXP,aux]{\@@_if_empty_return:o} % The auxiliary function \cs{@@_if_empty_return:o} is for use % in various token list conditionals which reduce to testing % if a given token list is empty after applying a simple function % to it. -% The test for emptiness is based on \cs{tl_if_empty:n(TF)}, but +% The test for emptiness is based on \cs{tl_if_empty:nTF}, but % the expansion is hard-coded for efficiency, as this auxiliary % function is used in many places. % Note that this works because \cs{etex_detokenize:D} expands tokens @@ -2019,12 +1995,12 @@ % \end{macro} % % \begin{macro}[TF]{\tl_if_in:Nn, \tl_if_in:cn} -% See \cs{tl_if_in:nn(TF)} for further comments. Here we simply -% expand the token list variable and pass it to \cs{tl_if_in:nn(TF)}. +% See \cs{tl_if_in:nnTF} for further comments. Here we simply +% expand the token list variable and pass it to \cs{tl_if_in:nnTF}. % \begin{macrocode} -\cs_new_protected_nopar:Npn \tl_if_in:NnT { \exp_args:No \tl_if_in:nnT } -\cs_new_protected_nopar:Npn \tl_if_in:NnF { \exp_args:No \tl_if_in:nnF } -\cs_new_protected_nopar:Npn \tl_if_in:NnTF { \exp_args:No \tl_if_in:nnTF } +\cs_new_protected:Npn \tl_if_in:NnT { \exp_args:No \tl_if_in:nnT } +\cs_new_protected:Npn \tl_if_in:NnF { \exp_args:No \tl_if_in:nnF } +\cs_new_protected:Npn \tl_if_in:NnTF { \exp_args:No \tl_if_in:nnTF } \cs_generate_variant:Nn \tl_if_in:NnT { c } \cs_generate_variant:Nn \tl_if_in:NnF { c } \cs_generate_variant:Nn \tl_if_in:NnTF { c } @@ -2036,7 +2012,7 @@ % The function \cs{@@_tmp:w} removes tokens until the first occurrence % of |#2|. If this does not appear in |#1|, then the final |#2| is removed, % leaving an empty token list. Otherwise some tokens remain, and the -% test is \texttt{false}. See \cs{tl_if_empty:n(TF)} for details on +% test is \texttt{false}. See \cs{tl_if_empty:nTF} for details on % the emptiness test. % % Treating correctly cases like @@ -2106,8 +2082,7 @@ % \end{macro} % \end{macro} % -% \begin{macro}[EXP]{\tl_case:Nn, \tl_case:cn} -% \begin{macro}[EXP, TF]{\tl_case:Nn, \tl_case:cn} +% \begin{macro}[EXP, noTF]{\tl_case:Nn, \tl_case:cn} % \begin{macro}[EXP, aux]{\@@_case:nnTF} % \begin{macro}[aux, EXP]{\@@_case:Nw} % \begin{macro}[int, EXP]{\__prg_case_end:nw} @@ -2173,7 +2148,6 @@ % \end{macro} % \end{macro} % \end{macro} -% \end{macro} % % \subsection{Mapping to token lists} % @@ -2190,7 +2164,7 @@ \q_recursion_tail \__prg_break_point:Nn \tl_map_break: { } } -\cs_new_nopar:Npn \tl_map_function:NN +\cs_new:Npn \tl_map_function:NN { \exp_args:No \tl_map_function:nN } \cs_new:Npn \@@_map_function:Nn #1#2 { @@ -2239,7 +2213,7 @@ \q_recursion_tail \__prg_break_point:Nn \tl_map_break: { } } -\cs_new_protected_nopar:Npn \tl_map_variable:NNn +\cs_new_protected:Npn \tl_map_variable:NNn { \exp_args:No \tl_map_variable:nNn } \cs_new_protected:Npn \@@_map_variable:Nnn #1#2#3 { @@ -2258,9 +2232,9 @@ % \begin{macro}{\tl_map_break:n} % The break statements use the general \cs{__prg_map_break:Nn}. % \begin{macrocode} -\cs_new_nopar:Npn \tl_map_break: +\cs_new:Npn \tl_map_break: { \__prg_map_break:Nn \tl_map_break: { } } -\cs_new_nopar:Npn \tl_map_break:n +\cs_new:Npn \tl_map_break:n { \__prg_map_break:Nn \tl_map_break: } % \end{macrocode} % \end{macro} @@ -2634,7 +2608,7 @@ } \cs_generate_variant:Nn \tl_head:n { V , v , f } \cs_new:Npn \tl_head:w #1#2 \q_stop {#1} -\cs_new_nopar:Npn \tl_head:N { \exp_args:No \tl_head:n } +\cs_new:Npn \tl_head:N { \exp_args:No \tl_head:n } % \end{macrocode} % To corrected leave the tail of a token list, it's important \emph{not} to % absorb any of the tail part as an argument. For example, the simple @@ -2659,7 +2633,7 @@ { \exp_after:wN { \use_none:n #1 } } } \cs_generate_variant:Nn \tl_tail:n { V , v , f } -\cs_new_nopar:Npn \tl_tail:N { \exp_args:No \tl_tail:n } +\cs_new:Npn \tl_tail:N { \exp_args:No \tl_tail:n } % \end{macrocode} % \end{macro} % \end{macro} @@ -2914,7 +2888,7 @@ { \__prg_break:n { \exp_not:n {#2} } } { \exp_args:Nf \@@_item:nn { \int_eval:n { #1 - 1 } } } } -\cs_new_nopar:Npn \tl_item:Nn { \exp_args:No \tl_item:nn } +\cs_new:Npn \tl_item:Nn { \exp_args:No \tl_item:nn } \cs_generate_variant:Nn \tl_item:Nn { c } % \end{macrocode} % \end{macro} @@ -2972,7 +2946,7 @@ % % \subsection{Deprecated functions} % -% \begin{macro}{\tl_to_lowercase:n, \tl_to_uppercase:n} +% \begin{macro}[deprecated=2017-12-31]{\tl_to_lowercase:n, \tl_to_uppercase:n} % For removal after 2017-12-31. % \begin{macrocode} \cs_new_protected:Npn \tl_to_lowercase:n #1 diff --git a/Master/texmf-dist/source/latex/l3kernel/l3token.dtx b/Master/texmf-dist/source/latex/l3kernel/l3token.dtx index ac7ed290c36..98aedaa038e 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3token.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3token.dtx @@ -37,7 +37,7 @@ \documentclass[full]{l3doc} % %<*driver|package> -\GetIdInfo$Id: l3token.dtx 6470 2016-04-03 11:29:18Z joseph $ +\GetIdInfo$Id: l3token.dtx 6695 2016-09-01 15:38:50Z bruno $ {L3 Experimental token manipulation} % %<*driver> @@ -82,28 +82,32 @@ % categories: |\token_| for anything that deals with tokens and % |\peek_| for looking ahead in the token stream. % -% Most of the time we will be using the term \enquote{token} but most of the -% time the function we're describing can equally well by used on a -% control sequence as such one is one token as well. +% Most functions we will describe here can be used on control sequences, +% as those are tokens as well. % -% \section{All possible tokens} -% -% Let us start by reviewing every case that a given token can fall into. -% It is very important to distinguish two aspects of a token: its meaning, -% and what it looks like. +% It is important to distinguish two aspects of a token: its +% \enquote{shape} (for lack of a better word), which affects the +% matching of delimited arguments and the comparison of token lists +% containing this token, and its \enquote{meaning}, which affects +% whether the token expands or what operation it performs. One can have +% tokens of different shapes with the same meaning, but not the +% converse. % % For instance, \cs{if:w}, \cs{if_charcode:w}, and \cs{tex_if:D} are -% three names for the same internal operation of \TeX{}, namely the primitive -% testing the next two characters for equality of their character code. -% They behave identically in many situations. However, \TeX{} -% distinguishes them when searching for a delimited argument. Namely, the -% example function |\show_until_if:w| defined below will take everything -% until \cs{if:w} as an argument, despite the presence of other copies of -% \cs{if:w} under different names. +% three names for the same internal operation of \TeX{}, namely the +% primitive testing the next two characters for equality of their +% character code. They have the same meaning hence behave identically +% in many situations. However, \TeX{} distinguishes them when searching +% for a delimited argument. Namely, the example function +% |\show_until_if:w| defined below will take everything until \cs{if:w} +% as an argument, despite the presence of other copies of \cs{if:w} +% under different names. % \begin{verbatim} % \cs_new:Npn \show_until_if:w #1 \if:w { \tl_show:n {#1} } % \show_until_if:w \tex_if:D \if_charcode:w \if:w % \end{verbatim} +% A list of all possible shapes and a list of all possible meanings are +% given in section~\ref{sec:l3token:all-tokens}. % % \section{Creating character tokens} % @@ -416,11 +420,6 @@ % This will be an implicit representation of \meta{token_2}. % \end{function} % -% ^^A Because it's late I can't figure out a better way to handle this: -% \ExplSyntaxOn -% \cs_set_eq:NN \c_alignment_token @ -% \cs_set_eq:NN \c_parameter_token @ -% \ExplSyntaxOff % \begin{variable} % { % \c_group_begin_token, @@ -436,10 +435,6 @@ % by their name. They are used internally for test purposes but % are also available to the programmer for other uses. % \end{variable} -% \ExplSyntaxOn -% \cs_set_eq:NN \c_alignment_token & -% \cs_set_eq:NN \c_parameter_token # -% \ExplSyntaxOff % % \begin{variable} % { @@ -1007,6 +1002,117 @@ % not a macro then \cs{scan_stop:} will be left in the input stream % \end{function} % +% \section{Description of all possible tokens} +% \label{sec:l3token:all-tokens} +% +% Let us end by reviewing every case that a given token can fall into. +% This section is quite technical and some details are only meant for +% completeness. We distinguish the meaning of the token, which controls +% the expansion of the token and its effect on \TeX{}'s state, and its +% shape, which is used when comparing token lists such as for delimited +% arguments. Two tokens of the same shape must have the same meaning, +% but the converse does not hold. +% +% A token has one of the following shapes. +% \begin{itemize} +% \item A control sequence, characterized by the sequence of +% characters that constitute its name: for instance, \cs{use:n} is a +% five-letter control sequence. +% \item An active character token, characterized by its character code +% (between $0$ and $1114111$ for \LuaTeX{} and \XeTeX{} and less for +% other engines) and category code~$13$. +% \item A character token, characterized by its character code and +% category code (one of $1$, $2$, $3$, $4$, $6$, $7$, $8$, $10$, +% $11$ or~$12$ whose meaning is described below).\footnote{In +% \LuaTeX{}, there is also the case of \enquote{bytes}, which behave as +% character tokens of category code $12$~(other) and character code +% between $1114112$ and~$1114366$. They are used to output +% individual bytes to files, rather than UTF-8.} +% \end{itemize} +% There are also a few internal tokens. The following list may be +% incomplete in some engines. +% \begin{itemize} +% \item Expanding \tn{the}\th{font} results in a token that looks +% identical to the command that was used to select the current font +% (such as \tn{tenrm}) but it differs from it in shape. +% \item A \enquote{frozen} |\relax|, which differs from the primitive in +% both shape and meaning, is inserted when the closing \tn{fi} of a +% conditional is encountered before the conditional is evaluated. +% \item An |\endtemplate| (which expands to |\outer endtemplate:|) +% can be enountered when peeking ahead at the next token. +% \item Tricky programming might access a frozen |\endwrite|. +% \item Some frozen tokens can only be accessed in interactive +% sessions: |\cr|, |\right|, |\endgroup|, |\fi|, |\inaccessible|. +% \end{itemize} +% +% The meaning of a (non-active) character token is fixed by its category +% code (and character code) and cannot be changed. We will call these +% tokens \emph{explicit} character tokens. Category codes that a +% character token can have are listed below by giving a sample output of +% the \TeX{} primitive \tn{meaning}, together with their \LaTeX3 names +% and most common example: +% \begin{itemize} +% \item[1] begin-group character (|group_begin|, often |{|), +% \item[2] end-group character (|group_end|, often |}|), +% \item[3] math shift character (|math_toggle|, often |$|), +% \item[4] alignment tab character (|alignment|, often |&|), +% \item[6] macro parameter character (|parameter|, often |#|), +% \item[7] superscript character (|math_superscript|, often |^|), +% \item[8] subscript character (|math_subscript|, often |_|), +% \item[10] blank space (|space|, often character code~$32$), +% \item[11] the letter (|letter|, such as |A|), +% \item[12] the character (|other|, such as |0|). +% \end{itemize} +% Category code~$13$ (|active|) is discussed below. Input characters +% can also have several other category codes which do not lead to +% character tokens for later processing: $0$~(|escape|), +% $5$~(|end_line|), $9$~(|ignore|), $14$~(|comment|), and +% $15$~(|invalid|). +% +% The meaning of a control sequence or active character can be identical +% to that of any character token listed above (with any character code), +% and we will call such tokens \emph{implicit} character tokens. The +% meaning is otherwise in the following list: +% \begin{itemize} +% \item a macro, used in \LaTeX3 for most functions and some variables +% (|tl|, |fp|, |seq|, \ldots{}), +% \item a primitive such as \tn{def} or \tn{topmark}, used in \LaTeX3 +% for some functions, +% \item a register such as \tn{count}|123|, used in \LaTeX3{} for the +% implementation of some variables (|int|, |dim|, \ldots{}), +% \item a constant integer such as \tn{char}|"56| or \tn{mathchar}|"121|, +% \item a font selection command, +% \item undefined. +% \end{itemize} +% Macros be \tn{protected} or not, \tn{long} or not (the opposite of +% what \LaTeX3 calls |nopar|), and \tn{outer} or not (unused in +% \LaTeX3). Their \tn{meaning} takes the form +% \begin{quote} +% \meta{properties} |macro:|\meta{parameters}|->|\meta{replacement} +% \end{quote} +% where \meta{properties} is among \tn{protected}\tn{long}\tn{outer}, +% \meta{parameters} describes parameters that the macro expects, such as +% |#1#2#3|, and \meta{replacement} describes how the parameters are +% manipulated, such as~|#2/#1/#3|. +% +% ^^A todo Bruno: discuss here some other subtleties of space tokens? when looking for numbers, when looking for equal signs in let, in expressions, etc. +% +% Now is perhaps a good time to mention some subtleties relating to +% tokens with category code $10$ (space). Any input character with this +% category code (normally, space and tab characters) becomes a normal +% space, with character code~$32$ and category code~$10$. +% +% When a macro takes an undelimited argument, explicit space characters +% (with character code $32$ and category code $10$) are ignored. If the +% following token is an explicit character token with category code $1$ +% (begin-group) and an arbitrary character code, then \TeX{} scans ahead +% to obtain an equal number of explicit character tokens with category +% code $1$ (begin-group) and $2$ (end-group), and the resulting list of +% tokens (with outer braces removed) becomes the argument. Otherwise, a +% single token is taken as the argument for the macro: we call such +% single tokens \enquote{N-type}, as they are suitable to be used as an +% argument for a function with the signature~\texttt{:N}. +% % \section{Internal functions} % % \begin{function}[EXP, added = 2016-03-25]{\__char_generate:nn} @@ -1016,7 +1122,8 @@ % This function is identical in operation to the public % \cs{char_generate:nn} but omits various sanity tests. In particular, this % means it is used in certain places where engine variations need to be -% accounted for by the kernel. +% accounted for by the kernel. The \meta{catcode} must give an explicit +% integer after a single expansion. % \end{function} % % \end{documentation} @@ -1033,7 +1140,7 @@ %<@@=char> % \end{macrocode} % -% \section{Manipulating and interrogating character tokens} +% \subsection{Manipulating and interrogating character tokens} % % \begin{macro}{\char_set_catcode:nn} % \begin{macro}{\char_value_catcode:n} @@ -1245,10 +1352,10 @@ % \end{macrocode} % \end{variable} % -% \section{Creating character tokens} +% \subsection{Creating character tokens} % % \begin{macro} -% {^^A +% { % \char_set_active_eq:NN, \char_gset_active_eq:NN, % \char_set_active_eq:Nc, \char_gset_active_eq:Nc, % \char_set_active_eq:nN, \char_gset_active_eq:nN, @@ -1256,6 +1363,7 @@ % } % Four simple functions with very similar definitions, so set up using % an auxiliary. +% These are similar to \LuaTeX{}'s \tn{letcharcode} primitive. % \begin{macrocode} \group_begin: \char_set_catcode_active:N \^^@ @@ -1303,7 +1411,7 @@ \cs_new:Npn \__char_generate:nn #1#2 { \exp:w \exp_after:wN - \@@_generate_aux:nnw \exp_after:wN + \@@_generate_aux:nnw \exp_after:wN { \__int_value:w \__int_eval:w #1 \exp_after:wN } {#2} \exp_end: } @@ -1341,7 +1449,7 @@ \if_int_compare:w #1 < \c_zero 1 \fi: \if_int_compare:w #1 > \c_@@_max_int 1 \fi: \exp_stop_f: \__msg_kernel_expandable_error:nn { kernel } - { char-out-of-range } + { char-out-of-range } \else: \@@_generate_aux:nnw {#1} {#2} \fi: @@ -1362,7 +1470,7 @@ \group_begin: %<*package> \char_set_catcode_active:N \^^L - \cs_set_nopar:Npn ^^L { } + \cs_set:Npn ^^L { } % \char_set_catcode_other:n { 0 } \if_int_odd:w 0 @@ -1396,11 +1504,7 @@ % low-level conditional. There are a few things to notice here. % As |^^L| is |\outer| we need to locally set it to avoid a problem. % To get open/close braces into the list, they are set up using |\if_false:| -% pairing here and will later be |x|-type expanded into the desired form. -% For making spaces, there needs to be an |o|-type expansion of a |\use:n| -% (or some other tokenization) to avoid dropping the space. We also -% set up active tokens although they are (currently) filtered out by the -% interface layer (\tn{Ucharcat} cannot make active tokens). +% pairing and are then |x|-type expanded together into the desired form. % \begin{macrocode} \int_const:Nn \c_@@_max_int { 255 } \tl_set:Nn \l_@@_tmp_tl { \exp_not:N \or: } @@ -1434,6 +1538,12 @@ \char_set_catcode_math_subscript:n { 0 } \tl_put_right:Nn \l_@@_tmp_tl { \or: ^^@ } \tl_put_right:Nn \l_@@_tmp_tl { \or: } +% \end{macrocode} +% For making spaces, there needs to be an |o|-type expansion of a |\use:n| +% (or some other tokenization) to avoid dropping the space. We also +% set up active tokens although they are (currently) filtered out by the +% interface layer (\tn{Ucharcat} cannot make active tokens). +% \begin{macrocode} \char_set_catcode_space:n { 0 } \tl_put_right:No \l_@@_tmp_tl { \use:n { \or: } ^^@ } \char_set_catcode_letter:n { 0 } @@ -1445,10 +1555,10 @@ % \end{macrocode} % Convert the above temporary list into a series of constant token % lists, one for each character code, using \tn{tex_lowercase:D} to -% convert |^^@| in each case. The \texttt{x}-type expansion deals with -% the |\if_false:| stuff introduced earlier. This is done in three parts -% as |^^L| is awkward. Notice that at this stage |^^@| is active. In -% format mode this is not needed. +% convert |^^@| in each case. The \texttt{x}-type expansion ensures +% that \tn{tex_lowercase:D} receives the contents of the token list. +% In package mode, |^^L| is awkward hence this is done in three parts. +% Notice that at this stage |^^@| is active. % \begin{macrocode} \cs_set_protected:Npn \@@_tmp:n #1 { @@ -1748,7 +1858,7 @@ % When a token is a macro, \cs{token_to_meaning:N} will always output % something like |\long macro:#1->#1| so we could naively check to % see if the meaning contains |->|. However, this can fail the five -% \tn{...mark} primitives, whose meaning has the form +% \tn[no-index]{...mark} primitives, whose meaning has the form % |...mark:|\meta{user material}. The problem is that the % \meta{user material} can contain |->|. % @@ -2132,9 +2242,9 @@ % {\@@_true:w, \@@_true_aux:w, \@@_false:w, \@@_tmp:w} % Functions used by the branching and space-stripping code. % \begin{macrocode} -\cs_new_nopar:Npn \@@_true:w { } -\cs_new_nopar:Npn \@@_true_aux:w { } -\cs_new_nopar:Npn \@@_false:w { } +\cs_new:Npn \@@_true:w { } +\cs_new:Npn \@@_true_aux:w { } +\cs_new:Npn \@@_false:w { } \cs_new:Npn \@@_tmp:w { } % \end{macrocode} % \end{macro} @@ -2144,9 +2254,9 @@ % Simple wrappers for \tn{futurelet}: no arguments absorbed % here. % \begin{macrocode} -\cs_new_protected_nopar:Npn \peek_after:Nw +\cs_new_protected:Npn \peek_after:Nw { \tex_futurelet:D \l_peek_token } -\cs_new_protected_nopar:Npn \peek_gafter:Nw +\cs_new_protected:Npn \peek_gafter:Nw { \tex_global:D \tex_futurelet:D \g_peek_token } % \end{macrocode} % \end{macro} @@ -2174,12 +2284,12 @@ { \cs_set_eq:NN \l_@@_search_token #2 \tl_set:Nn \l_@@_search_tl {#2} - \cs_set_nopar:Npx \@@_true:w + \cs_set:Npx \@@_true:w { \exp_not:N \group_align_safe_end: \exp_not:n {#3} } - \cs_set_nopar:Npx \@@_false:w + \cs_set:Npx \@@_false:w { \exp_not:N \group_align_safe_end: \exp_not:n {#4} @@ -2203,8 +2313,8 @@ \cs_set_eq:NN \l_@@_search_token #2 \tl_set:Nn \l_@@_search_tl {#2} \cs_set_eq:NN \@@_true:w \@@_true_remove:w - \cs_set_nopar:Npx \@@_true_aux:w { \exp_not:n {#3} } - \cs_set_nopar:Npx \@@_false:w + \cs_set:Npx \@@_true_aux:w { \exp_not:n {#3} } + \cs_set:Npx \@@_false:w { \exp_not:N \group_align_safe_end: \exp_not:n {#4} @@ -2222,7 +2332,7 @@ % \begin{macro}{\@@_execute_branches_meaning:} % The meaning test is straight forward. % \begin{macrocode} -\cs_new_nopar:Npn \@@_execute_branches_meaning: +\cs_new:Npn \@@_execute_branches_meaning: { \if_meaning:w \l_peek_token \l_@@_search_token \exp_after:wN \@@_true:w @@ -2266,11 +2376,11 @@ % search token may be of any of the three types above, hence the need % to use the explicit token that was given to the peek function. % \begin{macrocode} -\cs_new_nopar:Npn \@@_execute_branches_catcode: +\cs_new:Npn \@@_execute_branches_catcode: { \if_catcode:w \@@_execute_branches_catcode_aux: } -\cs_new_nopar:Npn \@@_execute_branches_charcode: +\cs_new:Npn \@@_execute_branches_charcode: { \if_charcode:w \@@_execute_branches_catcode_aux: } -\cs_new_nopar:Npn \@@_execute_branches_catcode_aux: +\cs_new:Npn \@@_execute_branches_catcode_aux: { \if_catcode:w \exp_not:N \l_peek_token \scan_stop: \exp_after:wN \exp_after:wN @@ -2290,7 +2400,7 @@ \fi: #1 } -\cs_new_nopar:Npn \@@_execute_branches_catcode_auxiii: +\cs_new:Npn \@@_execute_branches_catcode_auxiii: { \exp_not:N \l_peek_token \exp_after:wN \exp_not:N \l_@@_search_tl @@ -2312,7 +2422,7 @@ % using a side-effect of \texttt{f}-expansion: % |\exp:w \exp_end_continue_f:w| removes one space. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_ignore_spaces_execute_branches: +\cs_new_protected:Npn \@@_ignore_spaces_execute_branches: { \if_meaning:w \l_peek_token \c_space_token \exp_after:wN \peek_after:Nw @@ -2341,7 +2451,7 @@ } \cs_set:Npn \@@_def:nnnnn #1#2#3#4#5 { - \cs_new_protected_nopar:cpx { #1 #5 } + \cs_new_protected:cpx { #1 #5 } { \tl_if_empty:nF {#2} { \exp_not:n { \cs_set_eq:NN \@@_execute_branches: #2 } } -- cgit v1.2.3