diff options
Diffstat (limited to 'macros/latex')
123 files changed, 2845 insertions, 1479 deletions
diff --git a/macros/latex/contrib/easybook/easybook.dtx b/macros/latex/contrib/easybook/easybook.dtx index 6917c83e8b..e2bbfaa746 100644 --- a/macros/latex/contrib/easybook/easybook.dtx +++ b/macros/latex/contrib/easybook/easybook.dtx @@ -24,11 +24,11 @@ % \changes{v1.20}{2021/01/09}{修改和完善用户文档。} % \changes{v1.20}{2021/01/09}{模板更改为使用 CC-BY 许可协议。} % \changes{v1.23}{2021/03/19}{修复在 \pkg{ctex} v2.5.6 更新后 \cls{easybook} 与 \pkg{hyperref} 冲突问题。} -% \changes{v1.25c}{2021/05/03}{取消附带的示例文件,可查看历史版本及其它来源的使用样例。} +% \changes{v1.25d}{2021/05/03}{取消附带的示例文件,可查看历史版本及其它来源的使用样例。} % % \title{\sffamily easybook 文档类手册} % \author{瞿毅} -% \date{2021/05/06\hskip\ccwd\relax v1.25c\thanks{\url{https://gitee.com/texl3/easybook}}} +% \date{2021/05/07\hskip\ccwd\relax v1.25d\thanks{\url{https://gitee.com/texl3/easybook}}} % % \maketitle % \begin{abstract} @@ -118,7 +118,7 @@ % \end{syntax} % 传递给 \cls{ctexbook} 设置字体,最好不要使用原有的 \opt{fontset} 选项,默认情况下使用自定义字体而不开启这个选项,可根据安装的字体及电脑系统选取。\opt{noto} 与 \opt{none} 选项的相关描述见小节 \ref{subsec:font settings},\opt{overleaf} 是一个各系统通用选项,会检测系统环境选取对应字体。 % \changes{v1.21}{2021/01/12}{默认字体与 \CTeX 一致,不再是自定义字体。} -% \changes{v1.25c}{2021/05/04}{修复使用 \pkg{xeCJK} 与 \pkg{fontspec} 宏包的字体设置命令在 \hologo{LuaLaTeX} 下失效的问题。} +% \changes{v1.25d}{2021/05/04}{修复使用 \pkg{xeCJK} 与 \pkg{fontspec} 宏包的字体设置命令在 \hologo{LuaLaTeX} 下失效的问题。} % \end{function} % % \begin{function}[rEXP,added = 2021-01-05,updated = 2021-01-13]{paper} @@ -169,15 +169,20 @@ % \tn{listoflistings*+}\oarg{键值列表} % \end{syntax} % \tn{listoffigures} 命令输出图片目录,\tn{listoftables} 输出表格目录,\tn{listoflistings} 输出代码目录。带有星号的目录命令不将标题添加进主文档目录,带有+号的目录命令可以使当前标题编号。\tn{tableofcontents+} 与其它命令不同是用于输出双语目录,需要与双语目录标题命令 \tn{bichapter} 等或设置图片、表格和代码等英文目录的标题配合使用,附加代码是中文与英文目录之间的代码,可以插入文本和换页命令等。目录的键值列表选项如下 -% \changes{v1.25c}{2021/05/05}{命令 \tn{tableofcontents} 可以输出双语目录。} +% \changes{v1.25d}{2021/05/05}{命令 \tn{tableofcontents} 可以输出双语目录。} % \end{function} % -% \begin{function}{multoc,title,book,article} +% \begin{function}{multoc,title,format,aftertitle,pagestyle,book,article} % \begin{syntax} % multoc = <true|(false)> % title = \{<中文目录标题>,<英文目录标题>\} +% format = <目录标题格式> +% aftertitle = <目录标题后的代码> +% pagestyle = <标题页的页面格式> % \end{syntax} -% \opt{multoc} 与 \opt{style/multoc} 选项具有相同的效果,但是具有优先性且可单独设置不同目录是否双栏排版。\opt{title} 选项用于更改目录的标题,标题之间用一个半角逗号分开,也可以只有一部分,表示中文目录的标题。当设置了英文目录标题时,英文目录标题将会自动加入主文档目录,与 \tn{tableofcontents+} 配合输出。\opt{book} 选项使目录标题按照 \opt{chapter} 级别输出,\opt{article} 选项使目录标题按照 \opt{article} 级别输出,默认为 \opt{chapter} 级别。 +% \opt{multoc} 与 \opt{style/multoc} 选项具有相同的效果,但是具有优先性且可单独设置不同目录是否双栏排版。\opt{title} 选项用于更改目录的标题,标题之间用一个半角逗号分开,也可以只有一部分,表示中文目录的标题。当设置了英文目录标题时,英文目录标题将会自动加入主文档目录,与 \tn{tableofcontents+} 配合输出。 +% +% 在书籍模式且 \opt{book} 选项开启或者文章模式的情况下,\opt{format} 用于设置目录标题的格式,\opt{aftertitle} 选项的代码将被插入到目录标题内容之后,\opt{pagestyle} 是目录标题所在页的页面格式,除此之外还支持 \opt{ctexset/chapter} 或 \opt{ctexset/section} 所有的章节标题样式选项。\opt{book} 选项使目录标题按照 chapter 级别输出,\opt{article} 选项使目录标题按照 section 级别输出,默认为 chapter 级别。 % \changes{v1.23}{2021/03/15}{为几个目录增加键值列表的选项,可设置标题输出级别以及是否加入主目录。} % \changes{v1.24}{2021/04/04}{目录命令的可选参数增加标题键值。} % \end{function} @@ -195,7 +200,7 @@ % 双语目录的标题命令目前设置了常用的三个级别,它们将中文标题正常输出,并使中英文标题加入双语目录,这个功能是为国内一些大学的学位论文模板的要求设计,在一般情况和英文模式下不需要使用。 % % 它们的星号变体命令使文中标题不编号,但是仍然加入双语目录,若英文标题参数空置那么仅加入中文目录而不加入英文目录,这一特点与 \tn{chapter*} 等命令的行为不太一样,在一些情况下会用到。可选参数是目录中的中文标题,默认与中文标题一致,正文标题过长时可用它设置在目录中显示的标题。双语目录的格式是一致的,共享使用 \tn{tocset} 的设置,英文目录的章级别标题名及编号的修改方式如下 -% \changes{v1.25c}{2021/05/05}{增加与双语目录配合的标题命令。} +% \changes{v1.25d}{2021/05/05}{增加与双语目录配合的标题命令。} % \end{function} % % \begin{function}{biname,binmuber} @@ -208,9 +213,9 @@ % % \begin{function}[added = 2021-05-05]{\appendix} % \begin{syntax} -% \tn{appendix}\oarg{英文附录目录前名字}\parg{英文附录目录数字输出命令}\oarg{英文附录目录后名字} +% \tn{appendix}[<英文附录目录前名字>,<英文附录目录后名字>]\parg{英文附录目录数字输出命令} % \end{syntax} -% \tn{appendix} 命令后的章节标题变为附录形式。英文目录中附录标题的格式用可选参数修改,英文附录目录前名字默认为 Appendix\tn{space},英文附录目录数字输出命令默认为 \tn{Alph}\{chapter\},英文附录目录后名字默认为空。 +% \tn{appendix} 命令后的章节标题变为附录形式。英文目录中附录标题的格式用可选参数修改,英文附录目录前名字默认为 Appendix\tn{space},后名字默认为空,名字之间用一个半角逗号分开,也可以只有一部分,表示英文附录目录前名字。英文附录目录数字输出命令默认为 \tn{Alph}\{chapter\}。 % \end{function} % % \section{接口选项} @@ -294,7 +299,7 @@ % \opt{refset} 将超链接选项(包括以上选项)交给 \pkg{hyperref} 处理,除了一些关于 pdf 书签的选项可能会失效,其它由键值选项命令 \tn{hypersetup} 支持的多数选项可用。 % \changes{v1.10}{2021/01/08}{修复了 \opt{linktopage} 选项关闭时目录中标题编号无超链接的问题。} % \changes{v1.24}{2021/04/05}{增加 \pkg{hyperref} 超链接选项完整的支持。} -% \changes{v1.25c}{2021/05/06}{模块名 \opt{link} 改为 \opt{refset},\opt{link} 作为兼容性保留。} +% \changes{v1.25d}{2021/05/06}{模块名 \opt{link} 改为 \opt{refset},\opt{link} 作为兼容性保留。} % \end{function} % % \begin{optdesc} @@ -946,7 +951,7 @@ %<*class> \NeedsTeXFormat{LaTeX2e}[2020/10/01] \RequirePackage{l3keys2e,etoolbox} -\ProvidesExplClass{easybook}{2021/05/06}{1.25c}{beta} +\ProvidesExplClass{easybook}{2021/05/07}{1.25d}{beta} \cs_generate_variant:Nn \eb_ctex_define:nn { nx } \cs_generate_variant:Nn \int_to_arabic:n { v } @@ -1446,7 +1451,7 @@ { \CTEXifname { - \use:c { CTEXthe #1 } + \use:c { CTEXthe#1 } \hspace{\use:c { eb@toc@#1@numsep }} }{} } @@ -1692,6 +1697,9 @@ multoc .initial:n = false, title .code:n = \eb_assign_toc_title:n {#1} } +\bool_if:NTF \l__eb_class_book_bool + { \keys_define:nn { } { eb/listoc .inherit:n = ctex/chapter } } + { \keys_define:nn { } { eb/listoc .inherit:n = ctex/section } } \NewDocumentCommand{\eb_assign_toc_title:n} {>{\SplitArgument{1}{,}}m} {\eb_assign_toc_title_judge:nn #1} @@ -1886,8 +1894,9 @@ binmuber .initial:n = \arabic{chapter} } \RenewDocumentCommand{\appendix} - {O{Appendix\space}D(){\Alph{chapter}}O{}} + {O{Appendix\space}D(){\Alph{chapter}}} { + \ctex_assign_heading_name:nn { biappendix } {#1} \int_compare:nNnTF { \c@chapter } > { 0 } { \ExplSyntaxOn\char_set_catcode_letter:N \@ @@ -1898,9 +1907,9 @@ \def\CTEX@postchapter{\CTEX@postbichapter} } { - \def\CTEX@prechapter{#1} + \def\CTEX@prechapter{\CTEX@prebiappendix} \def\CTEX@thechapter{#2} - \def\CTEX@postchapter{#3} + \def\CTEX@postchapter{\CTEX@postbiappendix} } \ExplSyntaxOff\char_set_catcode_other:N \@ \setcounter{chapter}{0} @@ -2740,43 +2749,44 @@ \eb_allow_urlbreak: \ctex_hypersetup:n { pdfstartview = FitH } \exp_args:NV \hypersetup \l__eb_hyperref_clist - \labelformat{part}{\CTEXthepart} - \labelformat{chapter}{\CTEXthechapter} - \labelformat{figure}{\figurename~#1} - \labelformat{table}{\tablename~#1} - \tl_if_eq:NnTF \l__ctex_scheme_tl { chinese } + } + +\labelformat{part}{\CTEXthepart} +\labelformat{chapter}{\CTEXthechapter} +\labelformat{figure}{\figurename~#1} +\labelformat{table}{\tablename~#1} +\tl_if_eq:NnTF \l__ctex_scheme_tl { chinese } + { + \keys_set_known:nn { ctex } { - \keys_set_known:nn { ctex } - { - contentsname = 目\hspace{\ccwd}录, - indexname = 索\hspace{\ccwd}引, - listfigurename = 图片索引, - listtablename = 表格索引, - abstractname = 摘\hspace{\ccwd}要, - lstlistlistingname = 代码索引, - lstlistingname = 代码 - } - \labelformat{equation}{式(#1)} - \labelformat{align}{式(#1)} - \labelformat{multline}{式(#1)} - \labelformat{gather}{式(#1)} - \labelformat{section}{节#1} - \labelformat{subsection}{小节#1} + contentsname = 目\hspace{\ccwd}录, + indexname = 索\hspace{\ccwd}引, + listfigurename = 图片索引, + listtablename = 表格索引, + abstractname = 摘\hspace{\ccwd}要, + lstlistlistingname = 代码索引, + lstlistingname = 代码 } + \labelformat{equation}{式(#1)} + \labelformat{align}{式(#1)} + \labelformat{multline}{式(#1)} + \labelformat{gather}{式(#1)} + \labelformat{section}{节#1} + \labelformat{subsection}{小节#1} + } + { + \keys_set_known:nn { ctex } { - \keys_set_known:nn { ctex } - { - abstractname = Abstract, - lstlistlistingname = List~of~Codes, - lstlistingname = Code - } - \labelformat{equation}{Equation~(#1)} - \labelformat{align}{Equation~(#1)} - \labelformat{multline}{Equation~(#1)} - \labelformat{gather}{Equation~(#1)} - \labelformat{section}{Section~#1} - \labelformat{subsection}{Subsection~#1} + abstractname = Abstract, + lstlistlistingname = List~of~Codes, + lstlistingname = Code } + \labelformat{equation}{Equation~(#1)} + \labelformat{align}{Equation~(#1)} + \labelformat{multline}{Equation~(#1)} + \labelformat{gather}{Equation~(#1)} + \labelformat{section}{Section~#1} + \labelformat{subsection}{Subsection~#1} } \ctex_set:n diff --git a/macros/latex/contrib/easybook/easybook.ins b/macros/latex/contrib/easybook/easybook.ins index af8f3f8134..ffe304d2af 100644 --- a/macros/latex/contrib/easybook/easybook.ins +++ b/macros/latex/contrib/easybook/easybook.ins @@ -22,4 +22,4 @@ The latest version of this license is in \generate{\file{\jobname.cls}{\from{\jobname.dtx}{class}}} -\endbatchfile
\ No newline at end of file +\endbatchfile diff --git a/macros/latex/contrib/easybook/easybook.pdf b/macros/latex/contrib/easybook/easybook.pdf Binary files differindex d273043128..059d644933 100644 --- a/macros/latex/contrib/easybook/easybook.pdf +++ b/macros/latex/contrib/easybook/easybook.pdf diff --git a/macros/latex/contrib/l3backend/CHANGELOG.md b/macros/latex/contrib/l3backend/CHANGELOG.md index 093a2f8c58..1ec53b4d8b 100644 --- a/macros/latex/contrib/l3backend/CHANGELOG.md +++ b/macros/latex/contrib/l3backend/CHANGELOG.md @@ -6,6 +6,13 @@ this project uses date-based 'snapshot' version identifiers. ## [Unreleased] +## [2021-05-07] + +### Changed +- `\pdf_version_gset:n` in `dvips` now sets `\pdf_version_minor:` and + `\pdf_version_major:`. This doesn't set the PDF version but allows to test + which version the user intents to create. + ## [2021-03-18] ### Fixed @@ -173,7 +180,8 @@ this project uses date-based 'snapshot' version identifiers. - Include `l3backend` in file names - Moved backend code to internal for each 'parent' module -[Unreleased]: https://github.com/latex3/latex3/compare/2021-03-18...HEAD +[Unreleased]: https://github.com/latex3/latex3/compare/2021-05-07...HEAD +[2021-05-07]: https://github.com/latex3/latex3/compare/2021-03-18...2021-05-07 [2021-03-18]: https://github.com/latex3/latex3/compare/2021-03-02...2021-03-18 [2021-03-02]: https://github.com/latex3/latex3/compare/2021-02-18...2021-03-02 [2021-02-18]: https://github.com/latex3/latex3/compare/2021-02-06...2021-02-18 diff --git a/macros/latex/contrib/l3backend/README.md b/macros/latex/contrib/l3backend/README.md index 93ff4b33f7..b4b156dee9 100644 --- a/macros/latex/contrib/l3backend/README.md +++ b/macros/latex/contrib/l3backend/README.md @@ -1,7 +1,7 @@ LaTeX3 Backend Drivers ====================== -Release 2021-03-18 +Release 2021-05-07 This package forms parts of `expl3`, and contains the code used to interface with backends (drivers) across the `expl3` codebase. The functions here are diff --git a/macros/latex/contrib/l3backend/l3backend-basics.dtx b/macros/latex/contrib/l3backend/l3backend-basics.dtx index 787232cc30..446178138e 100644 --- a/macros/latex/contrib/l3backend/l3backend-basics.dtx +++ b/macros/latex/contrib/l3backend/l3backend-basics.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-03-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -70,27 +70,27 @@ % \begin{macrocode} \ProvidesExplFile %<*dvipdfmx> - {l3backend-dvipdfmx.def}{2021-03-18}{} + {l3backend-dvipdfmx.def}{2021-05-07}{} {L3 backend support: dvipdfmx} %</dvipdfmx> %<*dvips> - {l3backend-dvips.def}{2021-03-18}{} + {l3backend-dvips.def}{2021-05-07}{} {L3 backend support: dvips} %</dvips> %<*dvisvgm> - {l3backend-dvisvgm.def}{2021-03-18}{} + {l3backend-dvisvgm.def}{2021-05-07}{} {L3 backend support: dvisvgm} %</dvisvgm> %<*luatex> - {l3backend-luatex.def}{2021-03-18}{} + {l3backend-luatex.def}{2021-05-07}{} {L3 backend support: PDF output (LuaTeX)} %</luatex> %<*pdftex> - {l3backend-pdftex.def}{2021-03-18}{} + {l3backend-pdftex.def}{2021-05-07}{} {L3 backend support: PDF output (pdfTeX)} %</pdftex> %<*xetex> - {l3backend-xetex.def}{2021-03-18}{} + {l3backend-xetex.def}{2021-05-07}{} {L3 backend support: XeTeX} %</xetex> % \end{macrocode} @@ -104,7 +104,7 @@ % \begin{macrocode} \cs_if_exist:NTF \__kernel_dependency_version_check:nn { - \__kernel_dependency_version_check:nn {2020-09-01} + \__kernel_dependency_version_check:nn {2021-02-18} %<dvipdfmx> {l3backend-dvipdfmx.def} %<dvips> {l3backend-dvips.def} %<dvisvgm> {l3backend-dvisvgm.def} @@ -151,6 +151,16 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\__kernel_backend_first_shipout:n} +% We need to write at first shipout in a few places. As we want to use the +% most up-to-date method, +% \begin{macrocode} +\cs_if_exist:NTF \@ifl@t@r + { \cs_new_eq:NN \__kernel_backend_first_shipout:n \AtBeginDvi } + { \cs_new_eq:NN \__kernel_backend_first_shipout:n \use:n } +% \end{macrocode} +% \end{macro} +% % \subsection{\texttt{dvips} backend} % % \begin{macrocode} @@ -187,10 +197,8 @@ % \begin{macrocode} \bool_if:NT \g__kernel_backend_header_bool { - \cs_if_exist:NTF \AtBeginDvi - { \AtBeginDvi } - { \use:n } - { \__kernel_backend_literal:n { header = l3backend-dvips.pro } } + \__kernel_backend_first_shipout:n + { \__kernel_backend_literal:n { header = l3backend-dvips.pro } } } % \end{macrocode} % diff --git a/macros/latex/contrib/l3backend/l3backend-box.dtx b/macros/latex/contrib/l3backend/l3backend-box.dtx index 7ecbfc81e3..e45df7604b 100644 --- a/macros/latex/contrib/l3backend/l3backend-box.dtx +++ b/macros/latex/contrib/l3backend/l3backend-box.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-03-18} +% \date{Released 2021-05-07} % % \maketitle % diff --git a/macros/latex/contrib/l3backend/l3backend-code.pdf b/macros/latex/contrib/l3backend/l3backend-code.pdf Binary files differindex 71b71a28c6..c87ef2dc38 100644 --- a/macros/latex/contrib/l3backend/l3backend-code.pdf +++ b/macros/latex/contrib/l3backend/l3backend-code.pdf diff --git a/macros/latex/contrib/l3backend/l3backend-color.dtx b/macros/latex/contrib/l3backend/l3backend-color.dtx index d5cd5b0428..7979b2d8e6 100644 --- a/macros/latex/contrib/l3backend/l3backend-color.dtx +++ b/macros/latex/contrib/l3backend/l3backend-color.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-03-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -213,9 +213,7 @@ \int_const:Nn #1 { \exp_not:N \g_@@_backend_stack_int } \use:x { - \cs_if_exist:NTF \AtBeginDvi - { \exp_not:N \AtBeginDvi } - { \exp_not:N \use:n } + \__kernel_backend_first_shipout:n { \__kernel_backend_literal:n { @@ -530,13 +528,11 @@ { \bool_if:NT \g__kernel_backend_header_bool { - \cs_if_exist:NTF \AtBeginDvi - { \exp_not:N \AtBeginDvi } - { \use:n } - { - \exp_not:N \@@_backend_separation_init_aux:nnnnn - {#1} {#2} {#3} {#4} {#5} - } + \__kernel_backend_first_shipout:n + { + \exp_not:N \@@_backend_separation_init_aux:nnnnn + {#1} {#2} {#3} {#4} {#5} + } } } \cs_generate_variant:Nn \@@_backend_separation_init:nnnnn { nxx } @@ -858,11 +854,6 @@ { 100 ~ 0 ~ 0 } {#3} } -\cs_if_exist:NF \pdf_object_unnamed_write:nn - { - \cs_gset_protected:Npn \@@_backend_separation_init_CIELAB:nnn #1#2#3 - { } - } % \end{macrocode} % \end{macro} % \end{macro} diff --git a/macros/latex/contrib/l3backend/l3backend-draw.dtx b/macros/latex/contrib/l3backend/l3backend-draw.dtx index 3c818933e7..449b7f9c93 100644 --- a/macros/latex/contrib/l3backend/l3backend-draw.dtx +++ b/macros/latex/contrib/l3backend/l3backend-draw.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-03-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -127,7 +127,7 @@ { \@@_backend_literal:x { - \dim_to_decimal_in_bp:n {#1} ~ + \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~ moveto } } @@ -295,7 +295,7 @@ { \@@_backend_literal:x { - [ + [ \exp_args:Nf \use:n { \clist_map_function:nN {#1} \@@_backend_dash:n } ] ~ @@ -646,7 +646,7 @@ % \end{bmatrix} % \begin{bmatrix} % \cos\gamma & \sin\gamma \\ -\sin\gamma & \cos\gamma -% \end{bmatrix} +% \end{bmatrix} % \] % The parent matrix can be converted to % \[ @@ -1008,7 +1008,7 @@ % % \begin{macro}{\@@_backend_cm:nnnn} % The four arguments here are floats (the affine matrix), the last -% two are a displacement vector. +% two are a displacement vector. % \begin{macrocode} \cs_new_protected:Npn \@@_backend_cm:nnnn #1#2#3#4 { diff --git a/macros/latex/contrib/l3backend/l3backend-graphics.dtx b/macros/latex/contrib/l3backend/l3backend-graphics.dtx index c4d052f713..1448ecddc1 100644 --- a/macros/latex/contrib/l3backend/l3backend-graphics.dtx +++ b/macros/latex/contrib/l3backend/l3backend-graphics.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-03-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -583,9 +583,9 @@ % sizes here. (This is the same as the \texttt{dvips} code.) % \begin{macrocode} \cs_new_protected:Npn \@@_backend_include_eps:n #1 - { @@_backend_include:nn { PSfile } {#1} } + { @@_backend_include:nn { PSfile } {#1} } \cs_new_protected:Npn \@@_backend_include_pdf:n #1 - { @@_backend_include:nn { pdffile } {#1} } + { @@_backend_include:nn { pdffile } {#1} } \cs_new_protected:Npn \@@_backend_include:nn #1#2 { \__kernel_backend_literal:x diff --git a/macros/latex/contrib/l3backend/l3backend-header.dtx b/macros/latex/contrib/l3backend/l3backend-header.dtx index 80270ae47c..1d01b18928 100644 --- a/macros/latex/contrib/l3backend/l3backend-header.dtx +++ b/macros/latex/contrib/l3backend/l3backend-header.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-03-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -71,7 +71,7 @@ % things work with the color stack. % \begin{macrocode} TeXDict begin -/TeXcolorseparation { setcolor } def +/TeXcolorseparation { setcolor } def end % \end{macrocode} % \end{macro} diff --git a/macros/latex/contrib/l3backend/l3backend-opacity.dtx b/macros/latex/contrib/l3backend/l3backend-opacity.dtx index d19d3ade67..a600defcc0 100644 --- a/macros/latex/contrib/l3backend/l3backend-opacity.dtx +++ b/macros/latex/contrib/l3backend/l3backend-opacity.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-03-18} +% \date{Released 2021-05-07} % % \maketitle % diff --git a/macros/latex/contrib/l3backend/l3backend-pdf.dtx b/macros/latex/contrib/l3backend/l3backend-pdf.dtx index 936d7a72dc..11456302a2 100644 --- a/macros/latex/contrib/l3backend/l3backend-pdf.dtx +++ b/macros/latex/contrib/l3backend/l3backend-pdf.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-03-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -722,10 +722,15 @@ % % \begin{macro} % {\@@_backend_version_major_gset:n, \@@_backend_version_minor_gset:n} -% Data not available! % \begin{macrocode} -\cs_new_protected:Npn \@@_backend_version_major_gset:n #1 { } -\cs_new_protected:Npn \@@_backend_version_minor_gset:n #1 { } +\cs_new_protected:Npn \@@_backend_version_major_gset:n #1 + { + \cs_gset:Npx \@@_backend_version_major: { \int_eval:n {#1} } + } +\cs_new_protected:Npn \@@_backend_version_minor_gset:n #1 + { + \cs_gset:Npx \@@_backend_version_minor: { \int_eval:n {#1} } + } % \end{macrocode} % \end{macro} % diff --git a/macros/latex/contrib/l3build/CHANGELOG.md b/macros/latex/contrib/l3build/CHANGELOG.md index 7a1a7862b2..e46a935c3f 100644 --- a/macros/latex/contrib/l3build/CHANGELOG.md +++ b/macros/latex/contrib/l3build/CHANGELOG.md @@ -7,6 +7,11 @@ this project uses date-based 'snapshot' version identifiers. ## [Unreleased] +## [2021-05-06] + +### Fixed +- Issue when running PDF-based tests + ## [2021-05-05] ### Changed @@ -487,7 +492,8 @@ this project uses date-based 'snapshot' version identifiers. - Rationalise short option names: removed `-d`, `-E`, `-r` - Target `cmdcheck`: specific to LaTeX kernel work -[Unreleased]: https://github.com/latex3/l3build/compare/2021-05-05...HEAD +[Unreleased]: https://github.com/latex3/l3build/compare/2021-05-06...HEAD +[2021-05-06]: https://github.com/latex3/l3build/compare/2021-05-05...2021-05-06 [2021-05-05]: https://github.com/latex3/l3build/compare/2020-06-04...2021-05-05 [2020-06-04]: https://github.com/latex3/l3build/compare/2020-03-25...2020-06-04 [2020-03-25]: https://github.com/latex3/l3build/compare/2020-03-16...2020-03-25 diff --git a/macros/latex/contrib/l3build/README.md b/macros/latex/contrib/l3build/README.md index a5f4913712..219b1ad36c 100644 --- a/macros/latex/contrib/l3build/README.md +++ b/macros/latex/contrib/l3build/README.md @@ -1,7 +1,7 @@ l3build: a testing and building system for LaTeX ================================================= -Release 2021-05-05 +Release 2021-05-06 Overview -------- diff --git a/macros/latex/contrib/l3build/l3build-check.lua b/macros/latex/contrib/l3build/l3build-check.lua index dce9e68c6a..47ab19ced6 100644 --- a/macros/latex/contrib/l3build/l3build-check.lua +++ b/macros/latex/contrib/l3build/l3build-check.lua @@ -1007,7 +1007,7 @@ function save(names) return 1 end local test_type = test_types[kind] - if locate({unpackdir, testfiledir}, {name .. test_type.expectation}) then + if test_type.expectation and locate({unpackdir, testfiledir}, {name .. test_type.expectation}) then print("Saved " .. test_type.test .. " file would override a " .. test_type.expectation .. " file of the same name") return 1 diff --git a/macros/latex/contrib/l3build/l3build.1 b/macros/latex/contrib/l3build/l3build.1 index 2bb47c3068..8e21697dab 100644 --- a/macros/latex/contrib/l3build/l3build.1 +++ b/macros/latex/contrib/l3build/l3build.1 @@ -1,4 +1,4 @@ -.TH l3build 1 "2021-05-05" +.TH l3build 1 "2021-05-06" .SH NAME l3build \- Checking and building packages .SH SYNOPSIS diff --git a/macros/latex/contrib/l3build/l3build.dtx b/macros/latex/contrib/l3build/l3build.dtx index 9359b941b1..5171f10972 100644 --- a/macros/latex/contrib/l3build/l3build.dtx +++ b/macros/latex/contrib/l3build/l3build.dtx @@ -237,7 +237,7 @@ % }^^A % } % -% \date{Released 2021-05-05} +% \date{Released 2021-05-06} % % \maketitle % \tableofcontents diff --git a/macros/latex/contrib/l3build/l3build.lua b/macros/latex/contrib/l3build/l3build.lua index 0b68ee1617..8299439764 100644 --- a/macros/latex/contrib/l3build/l3build.lua +++ b/macros/latex/contrib/l3build/l3build.lua @@ -25,7 +25,7 @@ for those people who are interested. --]] -- Version information -release_date = "2021-05-05" +release_date = "2021-05-06" -- File operations are aided by the LuaFileSystem module local lfs = require("lfs") diff --git a/macros/latex/contrib/l3build/l3build.pdf b/macros/latex/contrib/l3build/l3build.pdf Binary files differindex 709314feef..447ba668a8 100644 --- a/macros/latex/contrib/l3build/l3build.pdf +++ b/macros/latex/contrib/l3build/l3build.pdf diff --git a/macros/latex/contrib/l3kernel/CHANGELOG.md b/macros/latex/contrib/l3kernel/CHANGELOG.md index 9663dc0551..447668b7bf 100644 --- a/macros/latex/contrib/l3kernel/CHANGELOG.md +++ b/macros/latex/contrib/l3kernel/CHANGELOG.md @@ -7,6 +7,42 @@ this project uses date-based 'snapshot' version identifiers. ## [Unreleased] +## [2021-05-07] + +### Added +- Color export in comma-separated format +- `\ur{...}` escape in `l3regex` to compose regexes +- `\seq_set_split_keep_spaces:Nnn` (see #784) +- `\seq_set_item:Nnn(TF)` and `\seq_pop_item:NnN(TF)` +- `\box_ht_plus_dp:N` (issue #899) +- `\clist_map_tokens:nn`, `\clist_map_tokens:Nn`, + `\str_map_tokens:nn`, `\str_map_tokens:Nn` + +### Changed +- Use prevailing catcodes instead of string in regex replacement (issue #621) + (*Breaking change*) +- `\__kernel_file_name_sanitize:n` now uses a faster `\csname`-based + approach to expand the file name +- Improved performance for basic conditionals +- `\pdf_version_gset:n` support for `dvips` +- Improve handling of `\exp_not:n` in `\text_expand:n` (issue #875) +- `\file_full_name:n` now avoids calling `\pdffilesize` primitive multiple times + on the same file +- Show printable characters explicitly in `\regex_show:n` +- Regex replacement now errors when using a submatch (`\1` etc) for which + the regex has too few groups +- Showing complex datatypes now validates their internal structure (issue #884) +- Indexing in l3doc: all page references before codeline references, + improve target placement, solve pdfTeX and makeindex warnings + +### Fixed +- Evalutate integer constants only once (issue #861) +- Detect `\ior_map_inline:Nn` calls on undefined streams (issue #194) + +### Deprecated +- `l3docstrip` converted to a stub which simply loads DocStrip: use + the latter directly + ## [2021-02-18] ### Added @@ -298,7 +334,7 @@ this project uses date-based 'snapshot' version identifiers. ## [2020-01-12] ### Added -- `bool_case_true:n(TF)` and `\bool_case_false:n(TF)` +- `\bool_case_true:n(TF)` and `\bool_case_false:n(TF)` - `\file_hex_dump:n(nn)` and `\file_get_hex_dump:n(nn)N(TF)` - `\str_<type>case:n` - `\text_<type>case:n(n)` @@ -847,7 +883,8 @@ this project uses date-based 'snapshot' version identifiers. - Step functions have been added for dim variables, e.g. `\dim_step_inline:nnnn` -[Unreleased]: https://github.com/latex3/latex3/compare/2021-02-18...HEAD +[Unreleased]: https://github.com/latex3/latex3/compare/2021-05-07...HEAD +[2021-05-07]: https://github.com/latex3/latex3/compare/2021-02-18...2021-05-07 [2021-02-18]: https://github.com/latex3/latex3/compare/2021-02-06...2021-02-18 [2021-02-06]: https://github.com/latex3/latex3/compare/2021-02-02...2021-02-06 [2021-02-02]: https://github.com/latex3/latex3/compare/2021-01-09...2021-02-02 diff --git a/macros/latex/contrib/l3kernel/README.md b/macros/latex/contrib/l3kernel/README.md index 42b975abcc..5acfbb5d3b 100644 --- a/macros/latex/contrib/l3kernel/README.md +++ b/macros/latex/contrib/l3kernel/README.md @@ -1,7 +1,7 @@ LaTeX3 Programming Conventions ============================== -Release 2021-02-18 +Release 2021-05-07 Overview -------- diff --git a/macros/latex/contrib/l3kernel/expl3.dtx b/macros/latex/contrib/l3kernel/expl3.dtx index 23bbb5a808..a2f5c86cbe 100644 --- a/macros/latex/contrib/l3kernel/expl3.dtx +++ b/macros/latex/contrib/l3kernel/expl3.dtx @@ -24,7 +24,7 @@ % %<*driver|generic|package|2ekernel> %</driver|generic|package|2ekernel> -\def\ExplFileDate{2021-02-18}% +\def\ExplFileDate{2021-05-07}% %<*driver> \documentclass[full]{l3doc} \usepackage{graphicx} @@ -51,7 +51,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -866,7 +866,7 @@ % \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}, -% where possible. So for example use \cs{cs_if_exist:N(TF)} and not +% where possible. So for example use \cs{cs_if_exist:NTF} and not % \cs{if_cs_exist:N}. % \item Use space to make code readable. In general, we recommend % a layout such as: diff --git a/macros/latex/contrib/l3kernel/expl3.pdf b/macros/latex/contrib/l3kernel/expl3.pdf Binary files differindex 14921ac34f..7e9a3d01ba 100644 --- a/macros/latex/contrib/l3kernel/expl3.pdf +++ b/macros/latex/contrib/l3kernel/expl3.pdf diff --git a/macros/latex/contrib/l3kernel/interface3.pdf b/macros/latex/contrib/l3kernel/interface3.pdf Binary files differindex f07ab43a0b..e73bc3462c 100644 --- a/macros/latex/contrib/l3kernel/interface3.pdf +++ b/macros/latex/contrib/l3kernel/interface3.pdf diff --git a/macros/latex/contrib/l3kernel/interface3.tex b/macros/latex/contrib/l3kernel/interface3.tex index 10449fd474..0108f11ddd 100644 --- a/macros/latex/contrib/l3kernel/interface3.tex +++ b/macros/latex/contrib/l3kernel/interface3.tex @@ -54,7 +54,7 @@ for those people who are interested. {latex-team@latex-project.org}% }% } -\date{Released 2021-02-18} +\date{Released 2021-05-07} \pagenumbering{roman} \maketitle diff --git a/macros/latex/contrib/l3kernel/l3.ins b/macros/latex/contrib/l3kernel/l3.ins index 91c471e75e..34a46aaed5 100644 --- a/macros/latex/contrib/l3kernel/l3.ins +++ b/macros/latex/contrib/l3kernel/l3.ins @@ -30,7 +30,7 @@ license information is placed in the derived files. \fi \let\jobname\relax -\input l3docstrip.dtx +\input docstrip % \askforoverwritefalse \preamble diff --git a/macros/latex/contrib/l3kernel/l3basics.dtx b/macros/latex/contrib/l3kernel/l3basics.dtx index 9a82102634..83c8f2b20f 100644 --- a/macros/latex/contrib/l3kernel/l3basics.dtx +++ b/macros/latex/contrib/l3kernel/l3basics.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -1510,7 +1510,7 @@ % This is here as this particular integer is needed both in package % mode and to bootstrap \pkg{l3alloc}, and is documented in \pkg{l3int}. % \LuaTeX{} and those which contain parts of the Omega extensions have -% more registers available than \eTeX{}. +% more registers available than \eTeX{}. % \begin{macrocode} \tex_ifdefined:D \tex_luatexversion:D \tex_chardef:D \c_max_register_int = 65 535 ~ @@ -1765,12 +1765,12 @@ % \begin{macrocode} \cs_set_protected:Npn \debug_on:n #1 { - \__kernel_msg_error:nnx { kernel } { enable-debug } + \__kernel_msg_error:nnx { debug } { enable-debug } { \tl_to_str:n { \debug_on:n {#1} } } } \cs_set_protected:Npn \debug_off:n #1 { - \__kernel_msg_error:nnx { kernel } { enable-debug } + \__kernel_msg_error:nnx { debug } { enable-debug } { \tl_to_str:n { \debug_off:n {#1} } } } % \end{macrocode} @@ -2085,7 +2085,7 @@ #8 { \exp_args:Nc #2 { #4 : #5 T } #6 } { { #7 \exp_end: \use:n \use_none:n } } - { #7 \exp_after:wN \use_ii:nn \fi: \use_none:n } + { #7 \@@_T_true:w \fi: \use_none:n } } \cs_set_protected:Npn \@@_generate_F_form:wNNnnnnN #1 \s_@@_stop #2#3#4#5#6#7#8 @@ -2093,7 +2093,7 @@ #8 { \exp_args:Nc #2 { #4 : #5 F } #6 } { { #7 \exp_end: { } } } - { #7 \exp_after:wN \use_none:nn \fi: \use:n } + { #7 \@@_F_true:w \fi: \use:n } } \cs_set_protected:Npn \@@_generate_TF_form:wNNnnnnN #1 \s_@@_stop #2#3#4#5#6#7#8 @@ -2101,9 +2101,12 @@ #8 { \exp_args:Nc #2 { #4 : #5 TF } #6 } { { #7 \exp_end: } } - { #7 \exp_after:wN \use_ii:nnn \fi: \use_ii:nn } + { #7 \@@_TF_true:w \fi: \use_ii:nn } } -\cs_set:Npn \@@_p_true:w \fi: \c_false_bool { \fi: \c_true_bool } +\cs_set:Npn \@@_p_true:w \fi: \c_false_bool { \fi: \c_true_bool } +\cs_set:Npn \@@_T_true:w \fi: \use_none:n { \fi: \use:n } +\cs_set:Npn \@@_F_true:w \fi: \use:n { \fi: \use_none:n } +\cs_set:Npn \@@_TF_true:w \fi: \use_ii:nn { \fi: \use_i:nn } % \end{macrocode} % \end{macro} % \end{macro} diff --git a/macros/latex/contrib/l3kernel/l3bootstrap.dtx b/macros/latex/contrib/l3kernel/l3bootstrap.dtx index 81fb06a579..2897f94237 100644 --- a/macros/latex/contrib/l3kernel/l3bootstrap.dtx +++ b/macros/latex/contrib/l3kernel/l3bootstrap.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -63,11 +63,18 @@ % \cs{ExplSyntaxOn} \meta{code} \cs{ExplSyntaxOff} % \end{syntax} % The \cs{ExplSyntaxOn} function switches to a category code -% r\'{e}gime in which spaces are ignored and in which the colon (|:|) +% regime in which spaces and new lines are ignored, and in which the colon (|:|) % and underscore (|_|) are treated as \enquote{letters}, thus allowing % access to the names of code functions and variables. Within this % environment, |~| is used to input a space. The \cs{ExplSyntaxOff} -% reverts to the document category code r\'{e}gime. +% reverts to the document category code regime. +% \begin{texnote} +% Spaces introduced by~|~| behave much in the same way as normal +% space characters in the standard category code regime: they are +% ignored after a control word or at the start of a line, and +% multiple consecutive~|~| are equivalent to a single one. However, +% |~|~is \emph{not} ignored at the end of a line. +% \end{texnote} % \end{function} % % \begin{function}[updated = 2017-03-19] @@ -84,7 +91,8 @@ % end of the file, \cs{ExplSyntaxOff} will be called to reverse this. % (This is the same concept as \LaTeXe{} provides in turning on % \tn{makeatletter} within package and class code.) The \meta{date} should -% be given in the format \meta{year}/\meta{month}/\meta{day}. If the +% be given in the format \meta{year}/\meta{month}/\meta{day} or in the ISO +% date format \meta{year}-\meta{month}-\meta{day}. If the % \meta{version} is given then it will be prefixed with \texttt{v} in % the package identifier line. % \end{function} @@ -362,7 +370,7 @@ % \end{macrocode} % % \begin{variable}{\l_@@_expl_bool} -% The status for experimental code syntax: this is on at present. +% The status for code syntax: this is on at present. % \begin{macrocode} \chardef\l_@@_expl_bool = 1\relax % \end{macrocode} diff --git a/macros/latex/contrib/l3kernel/l3box.dtx b/macros/latex/contrib/l3kernel/l3box.dtx index 5dcf864f73..d83fdb914e 100644 --- a/macros/latex/contrib/l3kernel/l3box.dtx +++ b/macros/latex/contrib/l3kernel/l3box.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -179,6 +179,14 @@ % \end{texnote} % \end{function} % +% \begin{function}[added = 2021-05-05]{\box_ht_plus_dp:N, \box_ht_plus_dp:c} +% \begin{syntax} +% \cs{box_ht_plus_dp:N} \meta{box} +% \end{syntax} +% Calculates the total vertical size (height plus depth) of the \meta{box} +% in a form suitable for use in a \meta{dimension expression}. +% \end{function} +% % \begin{function}[updated = 2019-01-22] % { % \box_set_dp:Nn, \box_set_dp:cn, @@ -917,7 +925,7 @@ % \end{macro} % \end{macro} % -% \begin{macro}{'\__kernel_kern:n} +% \begin{macro}{\__kernel_kern:n} % We need kerns in a few places. At present, we don't have a module for % this concept, so it goes in at first use: here. The idea is to avoid % repeated use of the bare primitive. @@ -1043,6 +1051,19 @@ % \end{macro} % \end{macro} % +% \begin{macro}{\box_ht_plus_dp:N} +% The \cs{box_ht:N} and \cs{box_dp:N} primitives do not expand but +% rather are suitable for use after \tn{the} or inside dimension +% expressions. Here we obtain the same behaviour by using +% \cs{@@_dim_eval:n} (basically \tn{dimexpr}) rather than +% \cs{dim_eval:n} (basically \tn{the} \tn{dimexpr}). +% \begin{macrocode} +\cs_new_protected:Npn \box_ht_plus_dp:N #1 + { \@@_dim_eval:n { \box_ht:N #1 + \box_dp:N #1 } } +\cs_generate_variant:Nn \box_ht_plus_dp:N { c } +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\box_set_ht:Nn, \box_set_ht:cn, \box_gset_ht:Nn, \box_gset_ht:cn} % \begin{macro}{\box_set_dp:Nn, \box_set_dp:cn, \box_gset_dp:Nn, \box_gset_dp:cn} % \begin{macro}{\box_set_wd:Nn, \box_set_wd:cn, \box_gset_wd:Nn, \box_gset_wd:cn} diff --git a/macros/latex/contrib/l3kernel/l3candidates.dtx b/macros/latex/contrib/l3kernel/l3candidates.dtx index aa0f4e1f8a..b03b3831c5 100644 --- a/macros/latex/contrib/l3kernel/l3candidates.dtx +++ b/macros/latex/contrib/l3kernel/l3candidates.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -216,7 +216,7 @@ % If piped system calls are disabled an error is raised. % % For details of handling of the \meta{shell command}, see -% \cs{sys_get_shell:nnN(TF)}. +% \cs{sys_get_shell:nnNTF}. % \end{function} % % \section{Additions to \pkg{l3flag}} @@ -434,6 +434,42 @@ % mappings. % \end{function} % +% \begin{function}[added = 2021-04-29, noTF] +% {\seq_set_item:Nnn, \seq_set_item:cnn, \seq_gset_item:Nnn, \seq_gset_item:cnn} +% \begin{syntax} +% \cs{seq_set_item:Nnn} \meta{seq~var} \Arg{intexpr} \Arg{item} +% \cs{seq_set_item:NnnTF} \meta{seq~var} \Arg{intexpr} \Arg{item} \Arg{true code} \Arg{false code} +% \end{syntax} +% Removes the item of \meta{sequence} at the position given by +% evaluating the \meta{integer expression} and replaces it by +% \meta{item}. Items are indexed from $1$ on the left/top of the +% \meta{sequence}, or from $-1$ on the right/bottom. If the +% \meta{integer expression} is zero or is larger (in absolute value) +% than the number of items in the sequence, the \meta{sequence} is not +% modified. In these cases, \cs{seq_set_item:Nnn} raises an error +% while \cs{seq_set_item:NnnTF} runs the \meta{false code}. In cases +% where the assignment was successful, \meta{true code} is run +% afterwards. +% \end{function} +% +% \begin{function}[added = 2021-04-28, noTF] +% {\seq_pop_item:NnN, \seq_pop_item:cnN, \seq_gpop_item:NnN, \seq_gpop_item:cnN} +% \begin{syntax} +% \cs{seq_pop_item:NnN} \meta{seq~var} \Arg{intexpr} \Arg{tl~var} +% \cs{seq_pop_item:NnNTF} \meta{seq~var} \Arg{intexpr} \Arg{tl~var} \Arg{true code} \Arg{false code} +% \end{syntax} +% Removes the \meta{item} at position \meta{integer expression} in the +% \meta{sequence}, and places it in the \meta{token list variable}. +% Items are indexed from $1$ on the left/top of the \meta{sequence}, +% or from $-1$ on the right/bottom. If the position is zero or is +% larger (in absolute value) than the number of items in the sequence, +% the \meta{seq~var} is not modified, the \meta{token list} is set to +% the special marker \cs{q_no_value}, and the \meta{false code} is +% left in the input stream; otherwise the \meta{true code} is. The +% \meta{token list} assignment is local while the \meta{sequence} is +% assigned locally for |pop| or globally for |gpop| functions. +% \end{function} +% % \section{Additions to \pkg{l3sys}} % % \begin{variable}[added = 2018-05-02]{\c_sys_engine_version_str} @@ -936,7 +972,7 @@ % \begin{macro}{\@@_case:NnTF} % \begin{macro}{\@@_case_true:w, \@@_case_false:w, \@@_case_end:nw} % For boolean cases the overall idea is the same as for -% \cs{tl_case:nn(TF)} as described in \pkg{l3tl}. +% \cs{tl_case:nnTF} as described in \pkg{l3tl}. % \begin{macrocode} \cs_new:Npn \bool_case_true:nTF { \exp:w \@@_case:NnTF \c_true_bool } @@ -1126,6 +1162,177 @@ % \end{macrocode} % \end{macro} % +% +% \begin{macro}{\@@_int_eval:w} +% Useful to more quickly go through items. +% \begin{macrocode} +\cs_new_eq:NN \@@_int_eval:w \tex_numexpr:D +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[noTF]{\seq_set_item:Nnn, \seq_set_item:cnn, \seq_gset_item:Nnn, \seq_gset_item:cnn} +% \begin{macro}{\@@_set_item:NnnNN, \@@_set_item:nnNNNN, \@@_set_item_false:nnNNNN, \@@_set_item:nNnnNNNN} +% \begin{macro}[rEXP]{\@@_set_item:wn, \@@_set_item_end:w} +% The conditionals are distinguished from the |Nnn| versions by the +% last argument \cs{use_ii:nn} vs \cs{use_i:nn}. +% \begin{macrocode} +\cs_new_protected:Npn \seq_set_item:Nnn #1#2#3 + { \@@_set_item:NnnNN #1 {#2} {#3} \__kernel_tl_set:Nx \use_i:nn } +\cs_new_protected:Npn \seq_gset_item:Nnn #1#2#3 + { \@@_set_item:NnnNN #1 {#2} {#3} \__kernel_tl_gset:Nx \use_i:nn } +\cs_generate_variant:Nn \seq_set_item:Nnn { c } +\cs_generate_variant:Nn \seq_gset_item:Nnn { c } +\prg_new_protected_conditional:Npnn \seq_set_item:Nnn #1#2#3 { TF , T , F } + { \@@_set_item:NnnNN #1 {#2} {#3} \__kernel_tl_set:Nx \use_ii:nn } +\prg_new_protected_conditional:Npnn \seq_gset_item:Nnn #1#2#3 { TF , T , F } + { \@@_set_item:NnnNN #1 {#2} {#3} \__kernel_tl_gset:Nx \use_ii:nn } +\prg_generate_conditional_variant:Nnn \seq_set_item:Nnn { c } { TF , T , F } +\prg_generate_conditional_variant:Nnn \seq_gset_item:Nnn { c } { TF , T , F } +% \end{macrocode} +% Save the item to be stored and evaluate the position and the sequence +% length only once. Then depending on the sign of the position, check +% that it is not bigger than the length (in absolute value) nor zero. +% \begin{macrocode} +\cs_new_protected:Npn \@@_set_item:NnnNN #1#2#3 + { + \tl_set:Nn \l_@@_internal_a_tl { \@@_item:n {#3} } + \exp_args:Nff \@@_set_item:nnNNNN + { \int_eval:n {#2} } { \seq_count:N #1 } #1 \use_none:nn + } +\cs_new_protected:Npn \@@_set_item:nnNNNN #1#2 + { + \int_compare:nNnTF {#1} > 0 + { \int_compare:nNnF {#1} > {#2} { \@@_set_item:nNnnNNNN { #1 - 1 } } } + { + \int_compare:nNnF {#1} < {-#2} + { + \int_compare:nNnF {#1} = 0 + { \@@_set_item:nNnnNNNN { #2 + #1 } } + } + } + \@@_set_item_false:nnNNNN {#1} {#2} + } +% \end{macrocode} +% If the position is not ok, \cs{@@_set_item_false:nnNNNN} calls an +% error or returns \texttt{false} (depending on the \cs{use_i:nn} vs +% \cs{use_ii:nn} argument mentioned above). +% \begin{macrocode} +\cs_new_protected:Npn \@@_set_item_false:nnNNNN #1#2#3#4#5#6 + { + #6 + { + \__kernel_msg_error:nnxxx { seq } { item-too-large } + { \token_to_str:N #3 } {#2} {#1} + } + { \prg_return_false: } + } +\__kernel_msg_new:nnnn { seq } { item-too-large } + { Sequence~'#1'~does~not~have~an~item~#3 } + { + An~attempt~was~made~to~push~or~pop~the~item~at~position~#3~ + of~'#1',~but~this~ + \int_compare:nTF { #3 = 0 } + { position~does~not~exist. } + { sequence~only~has~#2~item \int_compare:nF { #2 = 1 } {s}. } + } +% \end{macrocode} +% If the position is ok, \cs{@@_set_item:nNnnNNNN} makes the assignment +% and returns \texttt{true} (in the case of conditionnals). Here |#1| +% is an integer expression (position minus one), it needs to be +% evaluated. The sequence |#5| starts with \cs{s_@@} (even if empty), +% which stops the integer expression and is absorbed by it. The +% \cs{if_meaning:w} test is slightly faster than an integer test (but +% only works when testing against zero, hence the offset we chose in +% the position). When we are done skipping items, insert the saved +% item \cs{l_@@_internal_a_tl}. For |put| functions the last argument +% of \cs{@@_set_item_end:w} is \cs{use_none:nn} and it absorbs the +% item |#2| that we are removing: this is only useful for the |pop| +% functions. +% \begin{macrocode} +\cs_new_protected:Npn \@@_set_item:nNnnNNNN #1#2#3#4#5#6#7#8 + { + #7 #5 + { + \s_@@ + \exp_after:wN \@@_set_item:wn + \int_value:w \@@_int_eval:w #1 + #5 \s_@@_stop #6 + } + #8 { } { \prg_return_true: } + } +\cs_new:Npn \@@_set_item:wn #1 \@@_item:n #2 + { + \if_meaning:w 0 #1 \@@_set_item_end:w \fi: + \exp_not:n { \@@_item:n {#2} } + \exp_after:wN \@@_set_item:wn + \int_value:w \@@_int_eval:w #1 - 1 \s_@@ + } +\cs_new:Npn \@@_set_item_end:w #1 \exp_not:n #2 #3 \s_@@ #4 \s_@@_stop #5 + { + #1 + \exp_not:o \l_@@_internal_a_tl + \exp_not:n {#4} + #5 #2 + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[noTF]{\seq_pop_item:NnN, \seq_pop_item:cnN, \seq_gpop_item:NnN, \seq_gpop_item:cnN} +% \begin{macro}{\@@_pop_item:NnNNN} +% The |NnN| versions simply call the conditionals, for which we will +% rely on the internals of \cs{seq_set_item:Nnn}. +% \begin{macrocode} +\cs_new_protected:Npn \seq_pop_item:NnN #1#2#3 + { \seq_pop_item:NnNTF #1 {#2} #3 { } { } } +\cs_new_protected:Npn \seq_gpop_item:NnN #1#2#3 + { \seq_gpop_item:NnNTF #1 {#2} #3 { } { } } +\cs_generate_variant:Nn \seq_pop_item:NnN { c } +\cs_generate_variant:Nn \seq_gpop_item:NnN { c } +\prg_new_protected_conditional:Npnn \seq_pop_item:NnN #1#2#3 { TF , T , F } + { \@@_pop_item:NnNN #1 {#2} #3 \__kernel_tl_set:Nx } +\prg_new_protected_conditional:Npnn \seq_gpop_item:NnN #1#2#3 { TF , T , F } + { \@@_pop_item:NnNN #1 {#2} #3 \__kernel_tl_gset:Nx } +\prg_generate_conditional_variant:Nnn \seq_pop_item:NnN { c } { TF , T , F } +\prg_generate_conditional_variant:Nnn \seq_gpop_item:NnN { c } { TF , T , F } +% \end{macrocode} +% Save in \cs{l_@@_internal_b_tl} the token list variable |#3| in +% which we will store the item. The \cs{@@_set_item:nnNNNN} auxiliary +% eventually inserts \cs{l_@@_internal_a_tl} in place of the item +% found in the sequence, so we empty that. Instead of the last +% argument \cs{use_i:nn} or \cs{use_ii:nn} used for |put| functions, +% we introduce \cs{@@_pop_item:nn}, which stores \cs{q_no_value} +% before calling its second argument +% (\cs{prg_return_true:}/\texttt{false:}) to end the conditional. The +% item found is passed to \cs{@@_pop_item_aux:w}, which interrupts the +% |x|-expanding sequence assignment and stores the item using the +% assignment function in \cs{l_@@_internal_b_tl}. +% \begin{macrocode} +\cs_new_protected:Npn \@@_pop_item:NnNN #1#2#3#4 + { + \tl_clear:N \l_@@_internal_a_tl + \tl_set:Nn \l_@@_internal_b_tl { \__kernel_tl_set:Nx #3 } + \exp_args:Nff \@@_set_item:nnNNNN + { \int_eval:n {#2} } { \seq_count:N #1 } + #1 \@@_pop_item_aux:w #4 \@@_pop_item:nn + } +\cs_new_protected:Npn \@@_pop_item:nn #1#2 + { + \if_meaning:w \prg_return_false: #2 + \l_@@_internal_b_tl { \exp_not:N \q_no_value } + \fi: + #2 + } +\cs_new:Npn \@@_pop_item_aux:w \@@_item:n #1 + { + \if_false: { \fi: } + \l_@@_internal_b_tl { \if_false: } \fi: \exp_not:n {#1} + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% % \subsection{Additions to \pkg{l3sys}} % % \begin{macrocode} @@ -1209,18 +1416,18 @@ { \sys_if_shell:TF { \exp_args:No \@@_shell_open:nN { \tl_to_str:n {#2} } #1 } - { \__kernel_msg_error:nn { kernel } { pipe-failed } } + { \__kernel_msg_error:nn { ior } { pipe-failed } } } \cs_new_protected:Npn \@@_shell_open:nN #1#2 { \tl_if_in:nnTF {#1} { " } { \__kernel_msg_error:nnx - { kernel } { quote-in-shell } {#1} + { ior } { quote-in-shell } {#1} } { \__kernel_ior_open:Nn #2 { |#1 } } } -\__kernel_msg_new:nnnn { kernel } { pipe-failed } +\__kernel_msg_new:nnnn { ior } { pipe-failed } { Cannot~run~piped~system~commands. } { LaTeX~tried~to~call~a~system~process~but~this~was~not~possible.\\ diff --git a/macros/latex/contrib/l3kernel/l3cctab.dtx b/macros/latex/contrib/l3kernel/l3cctab.dtx index 46d682bd54..a84852f73b 100644 --- a/macros/latex/contrib/l3kernel/l3cctab.dtx +++ b/macros/latex/contrib/l3kernel/l3cctab.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -533,7 +533,7 @@ { \@@_nesting_number:N \l_@@_internal_a_tl } \@@_select:N \l_@@_internal_a_tl } - { \__kernel_msg_error:nn { kernel } { cctab-extra-end } } + { \__kernel_msg_error:nn { cctab } { extra-end } } } % \end{macrocode} % \end{macro} @@ -613,7 +613,7 @@ } { \cs_if_exist_p:c { @@_group_ #1 _chk: } } { - \__kernel_msg_error:nnx { kernel } { cctab-group-mismatch } + \__kernel_msg_error:nnx { cctab } { group-mismatch } { \int_sign:n { \tex_currentgrouplevel:D - \l_@@_internal_b_tl } @@ -652,10 +652,10 @@ % \begin{macrocode} \cs_if_exist:NT \hook_gput_code:nnn { - \hook_gput_code:nnn { enddocument/end } { kernel } + \hook_gput_code:nnn { enddocument/end } { cctab } { \seq_if_empty:NF \g_@@_stack_seq - { \__kernel_msg_error:nn { kernel } { cctab-missing-end } } + { \__kernel_msg_error:nn { cctab } { missing-end } } } } % \end{macrocode} @@ -689,7 +689,7 @@ \@@_chk_if_valid_aux:NTF #1 { \prg_return_true: } { - \__kernel_msg_error:nnx { kernel } { invalid-cctab } + \__kernel_msg_error:nnx { cctab } { invalid-cctab } { \token_to_str:N #1 } \prg_return_false: } @@ -830,32 +830,32 @@ % \subsection{Messages} % % \begin{macrocode} -\__kernel_msg_new:nnnn { kernel } { cctab-stack-full } +\__kernel_msg_new:nnnn { cctab } { stack-full } { The~category~code~table~stack~is~exhausted. } { LaTeX~has~been~asked~to~switch~to~a~new~category~code~table,~ but~there~is~no~more~space~to~do~this! } -\__kernel_msg_new:nnnn { kernel } { cctab-extra-end } +\__kernel_msg_new:nnnn { cctab } { extra-end } { Extra~\iow_char:N\\cctab_end:~ignored~\msg_line_context:. } { LaTeX~came~across~a~\iow_char:N\\cctab_end:~without~a~matching~ \iow_char:N\\cctab_begin:N.~This~command~will~be~ignored. } -\__kernel_msg_new:nnnn { kernel } { cctab-missing-end } +\__kernel_msg_new:nnnn { cctab } { missing-end } { Missing~\iow_char:N\\cctab_end:~before~end~of~TeX~run. } { LaTeX~came~across~more~\iow_char:N\\cctab_begin:N~than~ \iow_char:N\\cctab_end:. } -\__kernel_msg_new:nnnn { kernel } { invalid-cctab } +\__kernel_msg_new:nnnn { cctab } { invalid-cctab } { Invalid~\iow_char:N\\catcode~table. } { You~can~only~switch~to~a~\iow_char:N\\catcode~table~that~is~ initialized~using~\iow_char:N\\cctab_new:N~or~ \iow_char:N\\cctab_const:Nn. } -\__kernel_msg_new:nnnn { kernel } { cctab-group-mismatch } +\__kernel_msg_new:nnnn { cctab } { group-mismatch } { \iow_char:N\\cctab_end:~occurred~in~a~ \int_case:nn {#1} diff --git a/macros/latex/contrib/l3kernel/l3clist.dtx b/macros/latex/contrib/l3kernel/l3clist.dtx index 02064b80ea..3db9365a1f 100644 --- a/macros/latex/contrib/l3kernel/l3clist.dtx +++ b/macros/latex/contrib/l3kernel/l3clist.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -286,7 +286,7 @@ % \end{syntax} % Removes duplicate items from the \meta{comma list}, leaving the % left most copy of each item in the \meta{comma list}. 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{comma list} and % does a comparison with the \meta{items} already checked. It is therefore @@ -307,7 +307,7 @@ % \end{syntax} % Removes every occurrence of \meta{item} from the \meta{comma list}. % The \meta{item} comparison takes place on a token basis, as for -% \cs{tl_if_eq:nn(TF)}. +% \cs{tl_if_eq:nnTF}. % \begin{texnote} % The function may fail if the \meta{item} contains |{|, |}|, or |#| % (assuming the usual \TeX{} category codes apply). @@ -396,7 +396,7 @@ % \end{texnote} % \end{function} % -% \section{Mapping to comma lists} +% \section{Mapping over comma lists} % % The functions described in this section apply a specified function % to each item of a comma list. @@ -455,6 +455,18 @@ % \meta{items} are returned from left to right. % \end{function} % +% \begin{function}[rEXP, added = 2021-05-05] +% {\clist_map_tokens:Nn, \clist_map_tokens:cn, \clist_map_tokens:nn} +% \begin{syntax} +% \cs{clist_map_tokens:Nn} \meta{clist~var} \Arg{code} +% \cs{clist_map_tokens:nn} \Arg{comma list} \Arg{code} +% \end{syntax} +% Calls \meta{code} \Arg{item} for every \meta{item} stored in the +% \meta{comma list}. The \meta{code} receives each \meta{item} as a +% trailing brace group. If the \meta{code} consists of a single +% function this is equivalent to \cs{clist_map_function:nN}. +% \end{function} +% % \begin{function}[rEXP, updated = 2012-06-29]{\clist_map_break:} % \begin{syntax} % \cs{clist_map_break:} @@ -703,7 +715,7 @@ % % \section{Viewing comma lists} % -% \begin{function}[updated = 2015-08-03]{\clist_show:N, \clist_show:c} +% \begin{function}[updated = 2021-04-29]{\clist_show:N, \clist_show:c} % \begin{syntax} % \cs{clist_show:N} \meta{comma list} % \end{syntax} @@ -717,7 +729,7 @@ % Displays the entries in the comma list in the terminal. % \end{function} % -% \begin{function}[added = 2014-08-22, updated = 2015-08-03]{\clist_log:N, \clist_log:c} +% \begin{function}[added = 2014-08-22, updated = 2021-04-29]{\clist_log:N, \clist_log:c} % \begin{syntax} % \cs{clist_log:N} \meta{comma list} % \end{syntax} @@ -1622,32 +1634,32 @@ % \end{macro} % \end{macro} % -% \subsection{Mapping to comma lists} +% \subsection{Mapping over comma lists} % % \begin{macro}{\clist_map_function:NN, \clist_map_function:cN} % \UnitTested -% \begin{macro}{\@@_map_function:Nw} +% \begin{macro}{\@@_map_function:nw} % If the variable is empty, the mapping is skipped (otherwise, % that comma-list would be seen as consisting of one empty item). % Then loop over the comma-list, grabbing one comma-delimited % item at a time. The end is marked by \cs{q_@@_recursion_tail}. -% The auxiliary function \cs{@@_map_function:Nw} is also used +% The auxiliary function \cs{@@_map_function:nw} is also used % in \cs{clist_map_inline:Nn}. % \begin{macrocode} \cs_new:Npn \clist_map_function:NN #1#2 { \clist_if_empty:NF #1 { - \exp_last_unbraced:NNo \@@_map_function:Nw #2 #1 + \exp_last_unbraced:NNo \@@_map_function:nw #2 #1 , \q_@@_recursion_tail , \prg_break_point:Nn \clist_map_break: { } } } -\cs_new:Npn \@@_map_function:Nw #1#2 , +\cs_new:Npn \@@_map_function:nw #1#2 , { \@@_if_recursion_tail_break:nN {#2} \clist_map_break: #1 {#2} - \@@_map_function:Nw #1 + \@@_map_function:nw {#1} } \cs_generate_variant:Nn \clist_map_function:NN { c } % \end{macrocode} @@ -1657,14 +1669,14 @@ % \begin{macro}{\clist_map_function:nN} % \UnitTested % \begin{macro}{\@@_map_function_n:Nn} -% \begin{macro}{\@@_map_unbrace:Nw} +% \begin{macro}{\@@_map_unbrace:wn} % The \texttt{n}-type mapping function is a bit more awkward, % since spaces must be trimmed from each item. % Space trimming is again based on \cs{@@_trim_next:w}. % The auxiliary \cs{@@_map_function_n:Nn} receives as arguments the % function, and the next non-empty item (after space trimming but % before brace removal). One level of braces is removed by -% \cs{@@_map_unbrace:Nw}. +% \cs{@@_map_unbrace:wn}. % \begin{macrocode} \cs_new:Npn \clist_map_function:nN #1#2 { @@ -1675,11 +1687,11 @@ \cs_new:Npn \@@_map_function_n:Nn #1 #2 { \@@_if_recursion_tail_break:nN {#2} \clist_map_break: - \@@_map_unbrace:Nw #1 #2, + \@@_map_unbrace:wn #2 , #1 \exp_after:wN \@@_map_function_n:Nn \exp_after:wN #1 \exp:w \@@_trim_next:w \prg_do_nothing: } -\cs_new:Npn \@@_map_unbrace:Nw #1 #2, { #1 {#2} } +\cs_new:Npn \@@_map_unbrace:wn #1, #2 { #2 {#1} } % \end{macrocode} % \end{macro} % \end{macro} @@ -1708,7 +1720,7 @@ \int_gincr:N \g__kernel_prg_map_int \cs_gset_protected:cpn { @@_map_ \int_use:N \g__kernel_prg_map_int :w } ##1 {#2} - \exp_last_unbraced:Nco \@@_map_function:Nw + \exp_last_unbraced:Nco \@@_map_function:nw { @@_map_ \int_use:N \g__kernel_prg_map_int :w } #1 , \q_@@_recursion_tail , \prg_break_point:Nn \clist_map_break: @@ -1768,6 +1780,49 @@ % \end{macro} % \end{macro} % +% \begin{macro}{\clist_map_tokens:Nn, \clist_map_tokens:cn} +% \begin{macro}{\@@_map_tokens:nw} +% Essentially a copy of \cs{clist_map_function:NN} with braces added. +% \begin{macrocode} +\cs_new:Npn \clist_map_tokens:Nn #1#2 + { + \clist_if_empty:NF #1 + { + \exp_last_unbraced:Nno \@@_map_function:nw {#2} #1 + , \q_@@_recursion_tail , + \prg_break_point:Nn \clist_map_break: { } + } + } +\cs_generate_variant:Nn \clist_map_tokens:Nn { c } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\clist_map_tokens:nn, \@@_map_tokens_n:nw, \@@_use_ii_i:nn} +% Similar to \cs{clist_map_function:nN} but with a different way of +% grabbing items because we cannot use \cs{exp_after:wN} to pass the +% \meta{code}. +% \begin{macrocode} +\cs_new:Npn \clist_map_tokens:nn #1#2 + { + \@@_map_tokens_n:nw {#2} + \prg_do_nothing: #1 , \q_@@_recursion_tail , + \prg_break_point:Nn \clist_map_break: { } + } +\cs_new:Npn \@@_map_tokens_n:nw #1#2 , + { + \tl_if_empty:oF { \use_none:nn #2 ? } + { + \exp_args:No \@@_if_recursion_tail_break:nN {#2} \clist_map_break: + \tl_trim_spaces_apply:oN {#2} \@@_use_ii_i:nn + \@@_map_unbrace:wn , {#1} + } + \@@_map_tokens_n:nw {#1} \prg_do_nothing: + } +\cs_new:Npn \@@_use_ii_i:nn #1#2 { #2 #1 } +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\clist_map_break:, \clist_map_break:n} % The break statements use the general \cs{prg_map_break:Nn} mechanism. % \begin{macrocode} @@ -2009,21 +2064,30 @@ % \subsection{Viewing comma lists} % % \begin{macro}{\clist_show:N, \clist_show:c, \clist_log:N, \clist_log:c, \@@_show:NN} -% Apply the general \cs{__kernel_chk_defined:NT} and -% \cs{msg_show:nnnnnn}. +% Apply the general \cs{__kernel_chk_tl_type:NnnT} with \cs{exp_not:o} +% |#2| serving as a dummy code to prevent a check performed by this +% auxiliary. % \begin{macrocode} -\cs_new_protected:Npn \clist_show:N { \@@_show:NN \msg_show:nnxxxx } +\cs_new_protected:Npn \clist_show:N { \@@_show:NN \__kernel_msg_show:nnxxxx } \cs_generate_variant:Nn \clist_show:N { c } -\cs_new_protected:Npn \clist_log:N { \@@_show:NN \msg_log:nnxxxx } +\cs_new_protected:Npn \clist_log:N { \@@_show:NN \__kernel_msg_log:nnxxxx } \cs_generate_variant:Nn \clist_log:N { c } \cs_new_protected:Npn \@@_show:NN #1#2 { - \__kernel_chk_defined:NT #2 + \__kernel_chk_tl_type:NnnT #2 { clist } { \exp_not:o #2 } { - #1 { LaTeX/kernel } { show-clist } - { \token_to_str:N #2 } - { \clist_map_function:NN #2 \msg_show_item:n } - { } { } + \int_compare:nNnTF { \clist_count:N #2 } + = { \exp_args:No \clist_count:n #2 } + { + #1 { clist } { show } + { \token_to_str:N #2 } + { \clist_map_function:NN #2 \msg_show_item:n } + { } { } + } + { + \__kernel_msg_error:nnxx { kernel } { non-clist } + { \token_to_str:N #2 } { \tl_to_str:N #2 } + } } } % \end{macrocode} @@ -2033,11 +2097,11 @@ % A variant of the above: no existence check, empty first argument for % the message. % \begin{macrocode} -\cs_new_protected:Npn \clist_show:n { \@@_show:Nn \msg_show:nnxxxx } -\cs_new_protected:Npn \clist_log:n { \@@_show:Nn \msg_log:nnxxxx } +\cs_new_protected:Npn \clist_show:n { \@@_show:Nn \__kernel_msg_show:nnxxxx } +\cs_new_protected:Npn \clist_log:n { \@@_show:Nn \__kernel_msg_log:nnxxxx } \cs_new_protected:Npn \@@_show:Nn #1#2 { - #1 { LaTeX/kernel } { show-clist } + #1 { clist } { show } { } { \clist_map_function:nN {#2} \msg_show_item:n } { } { } } % \end{macrocode} diff --git a/macros/latex/contrib/l3kernel/l3coffins.dtx b/macros/latex/contrib/l3kernel/l3coffins.dtx index ae2e660caa..1291f40128 100644 --- a/macros/latex/contrib/l3kernel/l3coffins.dtx +++ b/macros/latex/contrib/l3kernel/l3coffins.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -92,8 +92,8 @@ % \begin{function}[EXP, pTF, added = 2012-06-20] % {\coffin_if_exist:N, \coffin_if_exist:c} % \begin{syntax} -% \cs{coffin_if_exist_p:N} \meta{box} -% \cs{coffin_if_exist:NTF} \meta{box} \Arg{true code} \Arg{false code} +% \cs{coffin_if_exist_p:N} \meta{coffin} +% \cs{coffin_if_exist:NTF} \meta{coffin} \Arg{true code} \Arg{false code} % \end{syntax} % Tests whether the \meta{coffin} is currently defined. % \end{function} @@ -566,7 +566,7 @@ \coffin_if_exist:NTF #1 { #2 } { - \__kernel_msg_error:nnx { kernel } { unknown-coffin } + \__kernel_msg_error:nnx { coffin } { unknown } { \token_to_str:N #1 } } } @@ -913,7 +913,7 @@ \prop_get:cnNF { coffin ~ \@@_to_value:N #1 ~ poles } {#2} #3 { - \__kernel_msg_error:nnxx { kernel } { unknown-coffin-pole } + \__kernel_msg_error:nnxx { coffin } { unknown-pole } { \exp_not:n {#2} } { \token_to_str:N #1 } \tl_set:Nn #3 { { 0pt } { 0pt } { 0pt } { 0pt } } } @@ -1147,7 +1147,7 @@ \l_@@_pole_a_tl \l_@@_pole_b_tl \bool_if:NT \l_@@_error_bool { - \__kernel_msg_error:nn { kernel } { no-pole-intersection } + \__kernel_msg_error:nn { coffin } { no-pole-intersection } \dim_zero:N \l_@@_x_dim \dim_zero:N \l_@@_y_dim } @@ -1677,7 +1677,7 @@ } \cs_generate_variant:Nn \coffin_gresize:Nnn { c } \cs_new_protected:Npn \@@_resize:NnnNN #1#2#3#4#5 - { + { \fp_set:Nn \l_@@_scale_x_fp { \dim_to_fp:n {#2} / \dim_to_fp:n { \coffin_wd:N #1 } } \fp_set:Nn \l_@@_scale_y_fp @@ -1720,7 +1720,7 @@ #4 { coffin ~ \@@_to_value:N #1 ~ corners } \l_@@_corners_prop #4 { coffin ~ \@@_to_value:N #1 ~ poles } - \l_@@_poles_prop + \l_@@_poles_prop } % \end{macrocode} % \end{macro} @@ -1950,7 +1950,7 @@ \@@_reset_structure:N \l_@@_aligned_coffin \prop_set_eq:cc { - coffin ~ \@@_to_value:N \l_@@_aligned_coffin + coffin ~ \@@_to_value:N \l_@@_aligned_coffin \c_space_tl corners } { coffin ~ \@@_to_value:N #1 ~ corners } @@ -2012,7 +2012,7 @@ % \begin{macro}{\@@_offset_pole:Nnnnnnn} % Transferring structures from one coffin to another requires that the % positions are updated by the offset between the two coffins. This is -% done by mapping to the property list of the source coffins, moving +% done by mapping over the property list of the source coffins, moving % as appropriate and saving to the new coffin data structures. The % test for a |-| means that the structures from the parent coffins % are uniquely labelled and do not depend on the order of alignment. @@ -2454,16 +2454,16 @@ % structure then the code complains. % \begin{macrocode} \cs_new_protected:Npn \coffin_show_structure:N - { \@@_show_structure:NN \msg_show:nnxxxx } + { \@@_show_structure:NN \__kernel_msg_show:nnxxxx } \cs_generate_variant:Nn \coffin_show_structure:N { c } \cs_new_protected:Npn \coffin_log_structure:N - { \@@_show_structure:NN \msg_log:nnxxxx } + { \@@_show_structure:NN \__kernel_msg_log:nnxxxx } \cs_generate_variant:Nn \coffin_log_structure:N { c } \cs_new_protected:Npn \@@_show_structure:NN #1#2 { \@@_if_exist:NT #2 { - #1 { LaTeX / kernel } { show-coffin } + #1 { coffin } { show } { \token_to_str:N #2 } { \iow_newline: >~ ht ~=~ \dim_eval:n { \coffin_ht:N #2 } @@ -2484,23 +2484,23 @@ % \subsection{Messages} % % \begin{macrocode} -\__kernel_msg_new:nnnn { kernel } { no-pole-intersection } +\__kernel_msg_new:nnnn { coffin } { no-pole-intersection } { No~intersection~between~coffin~poles. } { LaTeX~was~asked~to~find~the~intersection~between~two~poles,~ but~they~do~not~have~a~unique~meeting~point:~ the~value~(0pt,~0pt)~will~be~used. } -\__kernel_msg_new:nnnn { kernel } { unknown-coffin } +\__kernel_msg_new:nnnn { coffin } { unknown } { Unknown~coffin~'#1'. } { The~coffin~'#1'~was~never~defined. } -\__kernel_msg_new:nnnn { kernel } { unknown-coffin-pole } +\__kernel_msg_new:nnnn { coffin } { unknown-pole } { Pole~'#1'~unknown~for~coffin~'#2'. } { LaTeX~was~asked~to~find~a~typesetting~pole~for~a~coffin,~ but~either~the~coffin~does~not~exist~or~the~pole~name~is~wrong. } -\__kernel_msg_new:nnn { kernel } { show-coffin } +\__kernel_msg_new:nnn { coffin } { show } { Size~of~coffin~#1 : #2 \\ Poles~of~coffin~#1 : #3 . diff --git a/macros/latex/contrib/l3kernel/l3color.dtx b/macros/latex/contrib/l3kernel/l3color.dtx index b3fd3cfa7a..1b59215b8a 100644 --- a/macros/latex/contrib/l3kernel/l3color.dtx +++ b/macros/latex/contrib/l3kernel/l3color.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -299,7 +299,7 @@ % \meta{value(s)} for filling or stroking. % \end{function} % -% \begin{variable}{color.sc} +% \begin{variable}[module = color]{color.sc} % When using \texttt{dvips}, this PostScript variables hold the stroke color. % \end{variable} % @@ -342,6 +342,10 @@ % model, the second containing space-separated values appropriate % for the model; this is the format required by backend functions % of \pkg{expl3} +% \item \texttt{comma-sep-cmyk} Comma-separated cyan-magenta-yellow-black +% values +% \item \texttt{comma-sep-rgb} Comma-separated red-green-blue values +% suitable for use as a PDF annotation color % \item \texttt{HTML} Uppercase two-digit hexadecimal values, expressing % a red-green-blue color; the digits are \emph{not} separated % \item \texttt{space-sep-cmyk} Space-separated cyan-magenta-yellow-black @@ -1554,38 +1558,61 @@ % % \begin{variable} % { +% \c_@@_export_comma-sep-cmyk_tl , +% \c_@@_export_comma-sep-rgb_tl , % \c_@@_export_HTML_tl , % \c_@@_export_space-sep-cmyk_tl , % \c_@@_export_space-sep-rgb_tl % } % \begin{macrocode} +\tl_const:cn { c_@@_export_comma-sep-cmyk_tl } { cmyk } +\tl_const:cn { c_@@_export_comma-sep-rgb_tl } { rgb } \tl_const:Nn \c_@@_export_HTML_tl { rgb } \tl_const:cn { c_@@_export_space-sep-cmyk_tl } { cmyk } \tl_const:cn { c_@@_export_space-sep-rgb_tl } { rgb } % \end{macrocode} % \end{variable} % -% \begin{macro}{\@@_export_format_space-sep-cmyk:nnN} -% \begin{macro}{\@@_export_space-sep-cmyk:Nw} +% \begin{macro} +% { +% \@@_export_format_comma-sep-cmyk:nnN , +% \@@_export_format_comma-sep-rgb:nnN , +% \@@_export_format_space-sep-cmyk:nnN , +% \@@_export_format_space-sep-rgb:nnN +% } % \begin{macrocode} -\cs_new_protected:cpx { @@_export_format_space-sep-cmyk:nnN } #1#2#3 - { - \exp_not:N \@@_export:nnnNN { cmyk } {#1} {#2} #3 - \exp_not:c { @@_export_space-sep-cmyk:Nw } - } -\cs_new_protected:cpn { @@_export_space-sep-cmyk:Nw } #1#2 \s_@@_stop - { \tl_set:Nx #1 {#2} } +\group_begin: + \cs_set_protected:Npn \@@_tmp:w #1#2 + { + \cs_new_protected:cpx { @@_export_format_ #1 :nnN } ##1##2##3 + { + \exp_not:N \@@_export:nnnNN {#2} {##1} {##2} ##3 + \exp_not:c { @@_export_ #1 :Nw } + } + } + \@@_tmp:w { comma-sep-cmyk } { cmyk } + \@@_tmp:w { comma-sep-rgb } { rgb } + \@@_tmp:w { HTML } { rgb } + \@@_tmp:w { space-sep-cmyk } { cmyk } + \@@_tmp:w { space-sep-rgb } { rgb } + +\group_end: % \end{macrocode} % \end{macro} +% +% \begin{macro}{\@@_export_space-sep-cmyk:Nw, \@@_export_comma-sep-cmyk:Nw} +% \begin{macrocode} +\cs_new_protected:cpn { @@_export_comma-sep-cmyk:Nw } + #1#2 ~ #3 ~ #4 ~ #5 \s_@@_stop + { \tl_set:Nn #1 { #2 , #3 , #4 , #5 } } +\cs_new_protected:cpn { @@_export_space-sep-cmyk:Nw } #1#2 \s_@@_stop + { \tl_set:Nn #1 {#2} } +% \end{macrocode} % \end{macro} % % \begin{macro} % { -% \@@_export_format_HTML:nnN , -% \@@_export_format_space-sep-rgb:nnN -% } -% \begin{macro} -% { +% \@@_export_comma-sep-rgb:Nw , % \@@_export_HTML:Nw , % \@@_export_space-sep-rgb:Nw % } @@ -1593,13 +1620,8 @@ % \textsc{html} values must be given in |rgb|: we force conversion if % required, then do some simple maths. % \begin{macrocode} -\cs_new_protected:Npn \@@_export_format_HTML:nnN #1#2#3 - { \@@_export:nnnNN { rgb } {#1} {#2}#3 \@@_export_HTML:Nw } -\cs_new_protected:cpx { @@_export_format_space-sep-rgb:nnN } #1#2#3 - { - \exp_not:N \@@_export:nnnNN { rgb } {#1} {#2} #3 - \exp_not:c { @@_export_space-sep-rgb:Nw } - } +\cs_new_protected:cpn { @@_export_comma-sep-rgb:Nw } #1#2 ~ #3 ~ #4 \s_@@_stop + { \tl_set:Nx #1 { #2 , #3 , #4 } } \cs_new_protected:Npn \@@_export_HTML:Nw #1#2 ~ #3 ~ #4 \s_@@_stop { \tl_set:Nx #1 @@ -1616,11 +1638,10 @@ { \int_to_Hex:n { \fp_to_int:n { #1 * 255 } } } } \cs_new_protected:cpn { @@_export_space-sep-rgb:Nw } #1#2 \s_@@_stop - { \tl_set:Nx #1 {#2} } + { \tl_set:Nn #1 {#2} } % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} % % \subsection{Additional color models} % @@ -1750,6 +1771,35 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\@@_model_init:nn} +% A shared auxiliary to do the basics of setting up a new model: reserve a +% number, create a fallback and white-equivalent, set up links to the backend. +% \begin{macrocode} +\cs_new_protected:Npn \@@_model_init:nnn #1#2#3 + { + \int_gincr:N \g_@@_model_int + \tl_const:cx { c_@@_fallback_ #1 _tl } + { 1 \prg_replicate:nn { #2 - 1 } { ~ 1 } } + \clist_map_inline:nn { fill , stroke , select } + { + \cs_new_protected:cpx { @@_backend_ ##1 _ #1 :n } ####1 + { + \exp_not:c { @@_backend_ ##1 _ #3 :nn } + { color \int_use:N \g_@@_model_int } {####1} + } + } + \cs_new_protected:cpx { @@_model_ #1 _white: } + { + \prop_put:Nnn \exp_not:N \l_@@_named_white_prop {#1} + { 0 \prg_replicate:nn { #2 - 1 } { ~ 0 } } + \exp_not:N \int_compare:nNnF { \tex_currentgrouplevel:D } = 0 + { \group_insert_after:N \exp_not:c { @@_model_ #1 _ white: } } + } + \use:c { @@_model_ #1 _white: } + } +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\@@_model_separation:n} % \begin{macro}{\@@_model_separation:nn} % \begin{macro}{\@@_model_separation:nnn} @@ -1829,31 +1879,15 @@ \cs_new_protected:Npn \@@_model_separation:w #1 , #2 , #3 , #4 , #5 \s_@@_stop #6#7#8 { - \int_gincr:N \g_@@_model_int - \tl_const:cn { c_@@_fallback_ #6 _tl } { 1 } + \@@_model_init:nnn {#6} { 1 } { separation } \cs_new_eq:cN { @@_parse_mix_ #6 :nw } \@@_parse_mix_gray:nw \cs_new:cpn { @@_parse_model_ #6 :w } ##1 , ##2 \s_@@_stop { {#6} { \@@_parse_number:n {##1} } } - \clist_map_inline:nn { fill , stroke , select } - { - \cs_new_protected:cpx { @@_backend_ ##1 _ #6 :n } ####1 - { - \exp_not:c { @@_backend_ ##1 _ separation:nn } - { color \int_use:N \g_@@_model_int } {####1} - } - } \use:c { @@_model_separation_ #8 :nnnnnn } {#6} {#7} {#1} {#2} {#3} {#4} \prop_gput:Nnn \g_@@_alternative_model_prop {#6} {#8} \prop_gput:Nnx \g_@@_colorants_prop {#6} { \str_convert_pdfname:n {#7} } - \cs_new_protected:cpx { @@_model_ #6 _white: } - { - \prop_put:Nnn \exp_not:N \l_@@_named_white_prop {#6} { 0 } - \exp_not:N \int_compare:nNnF { \tex_currentgrouplevel:D } = 0 - { \group_insert_after:N \exp_not:c { @@_model_ #6 _ white: } } - } - \use:c { @@_model_ #6 _white: } } \cs_new_protected:Npn \@@_model_separation_cmyk:nnnnnn #1#2#3#4#5#6 { @@ -2086,35 +2120,17 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_model_devicen:nnnn #1#2#3#4 { - \int_gincr:N \g_@@_model_int - \tl_const:cx { c_@@_fallback_ #4 _tl } - { \prg_replicate:nn {#1} { 1 ~ } } + \@@_model_init:nnn {#4} {#1} { devicen } \cs_if_exist_use:cF { @@_model_devicen_parse_ #1 :nn } { \@@_model_devicen_parse_generic:nn } {#4} {#1} - \clist_map_inline:nn { fill , stroke , select } - { - \cs_new_protected:cpx { @@_backend_ ##1 _ #4 :n } ####1 - { - \exp_not:c { @@_backend_ ##1 _ devicen:nn } - { color \int_use:N \g_@@_model_int } {####1} - } - } - \cs_new_protected:cpx { @@_model_ #4 _white: } - { - \prop_put:Nnn \exp_not:N \l_@@_named_white_prop {#4} - { \prg_replicate:nn {#1} { 0 ~ } } - \exp_not:N \int_compare:nNnF { \tex_currentgrouplevel:D } = 0 - { \group_insert_after:N \exp_not:c { @@_model_ #4 _ white: } } - } - \use:c { @@_model_ #4 _white: } \@@_model_devicen_init:nnn {#1} {#2} {#3} \@@_model_devicen_convert:nnn {#4} {#2} {#3} } % \end{macrocode} -% For short lists of DeviceN colors, wee can use hand-tuned parsing. This +% For short lists of DeviceN colors, we can use hand-tuned parsing. This % lines up with other models, where we allow for up to four components. For -% larger spaces,. rather than limit artificially, we use a somewhat slow +% larger spaces, rather than limit artificially, we use a somewhat slow % approach based on open-ended commas-lists. % \begin{macrocode} \cs_new_protected:cpn { @@_model_devicen_parse_1:nn } #1#2 @@ -2499,7 +2515,7 @@ % \begin{macrocode} \cs_new_protected:Npn \color_show:n #1 { - \msg_show:nnxxxx { LaTeX / color } { show } + \__kernel_msg_show:nnxxxx { color } { show } {#1} { \@@_if_defined:nT {#1} diff --git a/macros/latex/contrib/l3kernel/l3debug.dtx b/macros/latex/contrib/l3kernel/l3debug.dtx index 107601afe8..56b74c3a34 100644 --- a/macros/latex/contrib/l3kernel/l3debug.dtx +++ b/macros/latex/contrib/l3kernel/l3debug.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -169,7 +169,7 @@ \exp_args:No \clist_map_inline:nn { \tl_to_str:n {#1} } { \cs_if_exist_use:cF { @@_ ##1 _on: } - { \__kernel_msg_error:nnn { kernel } { debug } {##1} } + { \__kernel_msg_error:nnn { debug } { debug } {##1} } } } \cs_set_protected:Npn \debug_off:n #1 @@ -177,7 +177,7 @@ \exp_args:No \clist_map_inline:nn { \tl_to_str:n {#1} } { \cs_if_exist_use:cF { @@_ ##1 _off: } - { \__kernel_msg_error:nnn { kernel } { debug } {##1} } + { \__kernel_msg_error:nnn { debug } { debug } {##1} } } } \cs_new_protected:Npn \@@_all_on: @@ -269,7 +269,7 @@ \@@_suspended:T \use_none:nnn \cs_if_exist:NF ##1 { - \__kernel_msg_error:nnx { kernel } { non-declared-variable } + \__kernel_msg_error:nnx { debug } { non-declared-variable } { \token_to_str:N ##1 } } } @@ -362,7 +362,7 @@ \if:w #1 \scan_stop: \cs_gset_nopar:Npn #1 {#2} \else: - \__kernel_msg_error:nnxxx { kernel } { local-global } + \__kernel_msg_error:nnxxx { debug } { local-global } {#1} {#2} { \iow_char:N \\ #3 } \fi: \fi: @@ -437,7 +437,7 @@ } { \__kernel_msg_expandable_error:nnnn - { kernel } { expr } {#4} {#1} + { debug } { expr } {#4} {#1} } #1 } @@ -562,11 +562,11 @@ \if:w n #1 \prg_return_true: \else: \if:w N #1 \prg_return_false: \else: \__kernel_msg_expandable_error:nnn - { kernel } { bad-arg-type } {#1} + { debug } { bad-arg-type } {#1} \fi: \fi: } -\__kernel_msg_new:nnn { kernel } { bad-arg-type } +\__kernel_msg_new:nnn { debug } { bad-arg-type } { Wrong~argument~type~#1. } % \end{macrocode} % The macro below is a modifiec copy of @@ -1431,7 +1431,7 @@ % % Messages. % \begin{macrocode} -\__kernel_msg_new:nnnn { kernel } { debug } +\__kernel_msg_new:nnnn { debug } { debug } { The~debugging~option~'#1'~does~not~exist~\msg_line_context:. } { The~functions~'\iow_char:N\\debug_on:n'~and~ @@ -1439,8 +1439,8 @@ 'all',~'check-declarations',~'check-expressions',~ 'deprecation',~'log-functions',~not~'#1'. } -\__kernel_msg_new:nnn { kernel } { expr } { '#2'~in~#1 } -\__kernel_msg_new:nnnn { kernel } { local-global } +\__kernel_msg_new:nnn { debug } { expr } { '#2'~in~#1 } +\__kernel_msg_new:nnnn { debug } { local-global } { Inconsistent~local/global~assignment } { \c_@@_coding_error_text_tl @@ -1457,7 +1457,7 @@ \ % variable~'#3'. } -\__kernel_msg_new:nnnn { kernel } { non-declared-variable } +\__kernel_msg_new:nnnn { debug } { non-declared-variable } { The~variable~#1~has~not~been~declared~\msg_line_context:. } { \c_@@_coding_error_text_tl diff --git a/macros/latex/contrib/l3kernel/l3deprecation.dtx b/macros/latex/contrib/l3kernel/l3deprecation.dtx index e5a70436f6..29e0f37051 100644 --- a/macros/latex/contrib/l3kernel/l3deprecation.dtx +++ b/macros/latex/contrib/l3kernel/l3deprecation.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -286,7 +286,7 @@ \__kernel_if_debug:TF { \exp_not:N \__kernel_msg_warning:nnxxx - { kernel } { deprecated-command } + { deprecation } { deprecated-command } {#1} { \token_to_str:N #3 } { \tl_to_str:n {#2} } @@ -332,7 +332,7 @@ \cs_if_eq:NNTF #3 \cs_gset_protected:Npn { \exp_not:N \__kernel_msg_error:nnnnnn } { \exp_not:N \__kernel_msg_expandable_error:nnnnnn } - { kernel } { deprecated-command } + { deprecation } { deprecated-command } {#1} { \token_to_str:N #4 } { \tl_to_str:n {#2} } @@ -353,10 +353,10 @@ \tex_protected:D \tex_outer:D \tex_edef:D #1 { \exp_not:N \__kernel_msg_expandable_error:nnnnn - { kernel } { deprecated-command } + { deprecation } { deprecated-command } { \tl_to_str:n {#3} } { \token_to_str:N #1 } { \tl_to_str:n {#2} } \exp_not:N \__kernel_msg_error:nnxxx - { kernel } { deprecated-command } + { deprecation } { deprecated-command } { \tl_to_str:n {#3} } { \token_to_str:N #1 } { \tl_to_str:n {#2} } } } @@ -364,7 +364,7 @@ % \end{macro} % % \begin{macrocode} -\__kernel_msg_new:nnn { kernel } { deprecated-command } +\__kernel_msg_new:nnn { deprecation } { deprecated-command } { \tl_if_blank:nF {#3} { Use~ \tl_trim_spaces:n {#3} ~not~ } #2~deprecated~on~#1. @@ -714,7 +714,7 @@ % \end{macrocode} % \end{macro} % -% \subsubsection{Deprecated \pkg{l3tl} functions} +% \subsection{Deprecated \pkg{l3tl} functions} % % \begin{macrocode} %<@@=tl> diff --git a/macros/latex/contrib/l3kernel/l3doc.dtx b/macros/latex/contrib/l3kernel/l3doc.dtx index 47f57dfb66..9e079c7f43 100644 --- a/macros/latex/contrib/l3kernel/l3doc.dtx +++ b/macros/latex/contrib/l3kernel/l3doc.dtx @@ -27,7 +27,7 @@ \ifx\fmtname\nameofplainTeX\else \expandafter\begingroup \fi -\input l3docstrip.tex +\input docstrip % \askforoverwritefalse \preamble @@ -79,7 +79,7 @@ and all files in that bundle must be distributed together. % % \title{The \cls{l3doc} class} % \author{\Team} -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % \maketitle % \tableofcontents % @@ -1573,7 +1573,7 @@ and all files in that bundle must be distributed together. % 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 +% everything to string catcodes. This is slightly inefficient as we % could have ensured that \tn{index@excludelist} has string catcodes % in the first place. % \begin{macrocode} @@ -1981,7 +1981,7 @@ and all files in that bundle must be distributed together. \tl_replace_all:Nno \l_@@_cmd_tl { _ } \l_@@_tmpb_tl } % \end{macrocode} -% \paragraph{Typesetting} +% Typesetting. % Note the replacement for the underscore is to permit linebreaks. % The \texttt{underscore} package adds the linebreak, % and the regex results in applying the breakable underscore only to the \emph{last} @@ -1989,6 +1989,7 @@ and all files in that bundle must be distributed together. % \begin{macrocode} \mode_if_math:T { \mbox } { + \bool_if:NT \l_@@_allow_indexing_bool { \@@_target: } \verbatim@font \@@_if_almost_str:VT \l_@@_cmd_tl { @@ -1996,8 +1997,8 @@ and all files in that bundle must be distributed together. \bool_if:NT \g_@@_cs_break_bool { \regex_replace_all:nnN - {([^\\])_([^\_])} - {\1\c{BreakableUnderscore}\2} + { ([^\\\_]\_*) \_ ([^\_]) } + { \1 \c{BreakableUnderscore} \2 } \l_@@_cmd_tl } } @@ -2006,16 +2007,17 @@ and all files in that bundle must be distributed together. \@ } % \end{macrocode} -% \paragraph{Indexing} +% Indexing. % \begin{macrocode} - \bool_if:NF \l_@@_cmd_noindex_bool - { + \bool_if:NT \l_@@_allow_indexing_bool + { + \bool_if:NF \l_@@_cmd_noindex_bool + { \quark_if_no_value:NF \l_@@_cmd_index_tl { \__kernel_tl_set:Nx \l_@@_cmd_tl { \c_backslash_str \exp_not:o { \l_@@_cmd_index_tl } } } - \exp_args:No \@@_key_get:n { \l_@@_cmd_tl } \quark_if_no_value:NF \l_@@_cmd_module_tl { @@ -2028,7 +2030,8 @@ and all files in that bundle must be distributed together. { \l_@@_index_module_tl } { usage } \l_@@_index_internal_bool - } + } + } } \cs_generate_variant:Nn \@@_cmd:nn { no } % \end{macrocode} @@ -2241,7 +2244,7 @@ and all files in that bundle must be distributed together. % \begin{macro}{\@@_names_typeset:} % \begin{macro}{\@@_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} +% \env{function} environment. The mapping over \cs{l_@@_names_block_tl} % cannot use \cs{tl_map_inline:Nn} because the code following |\\| % would not be expandable, thus breaking \tn{bottomrule}. % @@ -2688,8 +2691,7 @@ and all files in that bundle must be distributed together. \cs_new_protected:Npn \@@_typeset_functions: { \small\ttfamily - \HD@savedestfalse - \HD@target + \@@_target: \Hy@MakeCurrentHref { HD. \int_use:N \c@HD@hypercount } \begin{tabular} [t] { @{} l @{} >{\hspace{\tabcolsep}} r @{} } \toprule @@ -2982,8 +2984,7 @@ and all files in that bundle must be distributed together. \hbox:n { \strut - \int_compare:nNnT \l_@@_macro_int = 0 - { \HD@target } + \int_compare:nNnT \l_@@_macro_int = 0 { \@@_target: } } \vskip \int_eval:n { \l_@@_macro_int - 1 } \baselineskip } @@ -3146,7 +3147,9 @@ and all files in that bundle must be distributed together. % 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 |\ |. +% names by hand in the box \cs{l_@@_macro_box}. The fixed-size space +% |\MacroFont\ | could be replaced by an customizable horizontal +% space; it is important for it to be the same for all macros. % |#1| is the macro name, |#2| whether to add |TF|. % \begin{macrocode} \cs_new_protected:Npn \@@_macro_typeset_one:nN #1#2 @@ -3154,9 +3157,8 @@ and all files in that bundle must be distributed together. \vbox_set:Nn \l_@@_macro_box { \vbox_unpack_drop:N \l_@@_macro_box - \hbox { \llap { \__codedoc_print_macroname:nN {#1} #2 - \MacroFont % <----- without it the \ is in lmr10 if a link is made - \ + \hbox { \llap { \@@_print_macroname:nN {#1} #2 + \MacroFont \ } } } \int_incr:N \l_@@_macro_int @@ -3440,21 +3442,16 @@ and all files in that bundle must be distributed together. { \@bsphack \begingroup - \HD@target - \let\HDorg@encapchar\encapchar - \edef\encapchar usage - { - \HDorg@encapchar hdclindex{\the\c@HD@hypercount}{usage} - } + \@@_target: \index { #1\actualchar{\protect\ttfamily#1}~(option) - \encapchar usage + \encapchar hdclindex{\the\c@HD@hypercount}{usage} } \index { options:\levelchar#1\actualchar{\protect\ttfamily#1} - \encapchar usage + \encapchar hdclindex{\the\c@HD@hypercount}{usage} } \endgroup \@esphack @@ -3770,17 +3767,53 @@ and all files in that bundle must be distributed together. } % \end{macrocode} % +% Here, |MMMMI| (for page references) and |MMMMV| (for codeline +% references) are interpreted by |makeindex| as an uppercase Roman +% number pages, and should be large enough to avoid collisions with +% other uses of uppercase Roman number pages. Two subtle differences +% between \cs{@wrindex} and \cs{codeline@wrindex} are that the first +% must be a delayed write because the page number is not known yet, and +% it must close a group and finish some space-hack. +% +% We also provide versions for our use that refer % \begin{macrocode} -\cs_gset:Npn \codeline@wrindex #1 +\cs_gset_protected:Npn \@wrindex #1 + { + \protected@write \@indexfile {} + { \string \indexentry {#1} { MMMMI - \thepage } } + \endgroup \@esphack + } +\cs_gset_protected:Npn \codeline@wrindex #1 { \immediate\write\@indexfile { \string\indexentry{#1} - { \filesep \int_use:N \c@CodelineNo } + { MMMMV - \filesep \int_use:N \c@CodelineNo } } } \tl_gclear:N \filesep +\cs_new_protected:Npn \@@_index_page_hc:nn #1#2 + { + \protected@write \@indexfile {} + { + \string \indexentry { #1 \encapchar hdpindex{#2} } + { MMMMI - \thepage } + } + } +\cs_new_protected:Npn \@@_index_codeline_hc:nn #1#2 + { + \immediate\write\@indexfile + { + \string \indexentry { #1 \encapchar hdclindex{\the\c@HD@hypercount}{#2} } + { MMMMV - \filesep \int_use:N \c@CodelineNo - MMMD - \the\c@HD@hypercount - M } + } + } % \end{macrocode} +% We already have a single |HD.xx| target per code line. It would be +% better to have a target |CL.\the\c@CodelineNo| per code line and +% change |hdclindex{\the\c@HD@hypercount}| to a mechanism closer to +% |hdpindex|, but we need to understand better the different types of +% indexings, and there are subtleties with indexing |\{| and |\}|. % \end{macro} % % \begin{macro}{\docincludeaux} @@ -4038,6 +4071,53 @@ and all files in that bundle must be distributed together. % % \subsection{Indexing} % +% \subsubsection{Necessary patching} +% +% The following is useful to set up \pkg{hyperref} targets, for instance +% for the purpose of indexing. Contrarily to \pkg{hypdoc} we do not try +% to save pdf destinations, as this leads to too many \pdfTeX{} warnings +% on early runs. +% \begin{macrocode} +\cs_new_protected:Npn \@@_target: + { + \mode_leave_vertical: + \group_begin: + \HD@savedestfalse \HD@target + \group_end: + } +% \end{macrocode} +% Force targets on every code line. +% \begin{macrocode} +\cs_set_nopar:Npx \theCodelineNo + { + \group_begin: + \exp_not:N \HD@savedestfalse + \exp_not:o \theCodelineNo + \group_end: + } +% \end{macrocode} +% +% Inside the table of contents (and other similar lists introduced by +% \cs{@starttoc}), we suppress indexing. This is because \cs{cmd}, +% \cs{cs}, or \cs{tn} appearing in titles only gets typeset in the +% second run, and getting their indexing right would require even more +% runs than we already need. Besides, it is not useful to index uses of +% some command in the table of contents. +% \begin{macrocode} +\bool_new:N \l_@@_allow_indexing_bool +\bool_set_true:N \l_@@_allow_indexing_bool +\use:x + { + \exp_not:n { \cs_set_nopar:Npn \@starttoc #1 } + { + \group_begin: + \bool_set_false:N \l_@@_allow_indexing_bool + \exp_not:o { \@starttoc {#1} } + \group_end: + } + } +% \end{macrocode} +% % \subsubsection{Userspace commands} % % Fix index (for now): @@ -4201,14 +4281,14 @@ and all files in that bundle must be distributed together. \@@_quote_special_char:N \l_@@_index_escaped_key_tl \@@_special_index_set:Nn \l_@@_index_escaped_macro_tl {#2} \str_if_eq:onTF { \@currenvir } { macrocode } - { \codeline@wrindex } + { \@@_index_codeline_hc:nn } { \str_case:nnF {#6} { - { main } { \codeline@wrindex } - { usage } { \index } + { main } { \@@_index_codeline_hc:nn } + { usage } { \@@_index_page_hc:nn } } - { \HD@target \index } + { \@@_target: \@@_index_page_hc:nn } } { \tl_if_empty:nF { #3 #4 #5 } @@ -4219,12 +4299,54 @@ and all files in that bundle must be distributed together. \token_to_str:N \verbatim@font \c_space_tl \l_@@_index_escaped_macro_tl } - \encapchar - hdclindex{\the\c@HD@hypercount}{#6} } + {#6} } % \end{macrocode} % +% \begin{macro}{\hdpindex, \@@_old_hdpindex:nn, \hdclindex, \@@_old_hdclindex:nnn, \@@_hdindex:nn, \c_@@_active_minus_tl, \@@_hdindex_aux:nn, \@@_hdindex_aux:w} +% Note that |#3| here could contain |MMMMI-| or |MMMMV-| more than once +% if several successive code lines have been merged into a range +% somehow. Note incidentally that the dash is active in some of our +% sources, like |interface3.tex| or |source2e.tex|. +% \begin{macrocode} +\group_begin: +\char_set_active_eq:NN - \scan_stop: +\tl_const:Nx \c_@@_active_minus_tl { \char_generate:nn { `- } { 13 } } +\group_end: +\cs_new_eq:NN \@@_old_hdpindex:nn \hdpindex +\cs_new_eq:NN \@@_old_hdclindex:nnn \hdclindex +\cs_gset_protected:Npn \hdpindex #1 + { \@@_hdindex:nn { \@@_old_hdpindex:nn {#1} } } +\cs_gset_protected:Npn \hdclindex #1#2 + { \@@_hdindex:nn { \@@_old_hdclindex:nnn {#1} {#2} } } +\cs_new_protected:Npn \@@_hdindex:nn #1#2 + { + \tl_set:Nn \l_@@_tmpa_tl {#2} + \tl_replace_all:Nxn \l_@@_tmpa_tl + { \exp_not:V \c_@@_active_minus_tl \exp_not:V \c_@@_active_minus_tl } + { -- } + \seq_set_split:NnV \l_@@_tmpa_seq { -- } \l_@@_tmpa_tl + \seq_set_map:NNn \l_@@_tmpa_seq \l_@@_tmpa_seq + { \@@_hdindex_aux:nn {#1} {##1} } + \seq_use:Nn \l_@@_tmpa_seq { -- } + } +\cs_new_protected:Npn \@@_hdindex_aux:nn #1#2 + { + \tl_set:Nn \l_@@_tmpa_tl {#2} + \tl_replace_all:Nnn \l_@@_tmpa_tl { MMMM } { \use_none:nn } + \tl_if_in:NnT \l_@@_tmpa_tl { MMMD } + { + \tl_replace_all:Nxn \l_@@_tmpa_tl + { \exp_not:V \c_@@_active_minus_tl MMMD } { - MMMD } + \tl_replace_all:Nnn \l_@@_tmpa_tl { - MMMD } { \@@_hdindex_aux:w } + } + \use:x { \exp_not:n {#1} { \exp_not:V \l_@@_tmpa_tl } } + } +\cs_new_protected:Npn \@@_hdindex_aux:w #1 M { } +% \end{macrocode} +% \end{macro} +% % \begin{macrocode} \cs_new_protected:Npn \@@_special_index_set:Nn #1#2 { @@ -4373,11 +4495,18 @@ and all files in that bundle must be distributed together. % 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. +% and underscores to improve the index sorting. +% Then get the module as the first (underscore-delimited) \enquote{word}. +% In the past, we distinguished according to how many such words there +% were, to detect commands like \cs[no-index]{c_zero}, which should be +% sorted as |int| variables, and \cs[no-index]{l_tmpa_dim}, which should +% be sorted in the |dim| and not the |tmpa| module. +% Now the first case has been deprecated for some time, while |tmpa| and +% similar are special-cased through an explicit list given below. +% The way it works is that if the module is in a list of special names +% that are not valid modules, then we try the last word, and if that +% also fails (for instance in the deprecated \cs[no-index]{c_one_hundred}) +% we empty the module completely. % \begin{macrocode} \cs_new_protected:Npn \@@_key_var: { @@ -4387,7 +4516,7 @@ and all files in that bundle must be distributed together. \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 } } + { s } { \tl_set:Nn \l_@@_index_module_tl { scan } } } \@@_key_pop: \@@_key_pop: @@ -4396,15 +4525,14 @@ and all files in that bundle must be distributed together. { \seq_set_split:NoV \l_@@_tmpa_seq { \token_to_str:N _ } \l_@@_index_key_tl - \__kernel_tl_set:Nx \l_@@_index_module_tl + \seq_get_left:NN \l_@@_tmpa_seq \l_@@_index_module_tl + \clist_if_in:NoT \g_@@_non_modules_clist \l_@@_index_module_tl { - \int_case:nnF { \seq_count:N \l_@@_tmpa_seq } + \seq_get_right:NN \l_@@_tmpa_seq \l_@@_index_module_tl + \clist_if_in:NoT \g_@@_non_modules_clist \l_@@_index_module_tl { - { 0 } { } - { 1 } { int } - { 2 } { \seq_item:Nn \l_@@_tmpa_seq { 2 } } + \tl_clear:N \l_@@_index_module_tl } - { \seq_item:Nn \l_@@_tmpa_seq { 1 } } } } } @@ -4416,6 +4544,30 @@ and all files in that bundle must be distributed together. % \end{macrocode} % \end{macro} % +% \begin{variable}{\g_@@_non_modules_clist} +% List of names that appear as the first word in an \pkg{expl3} +% command, but that are not true modules, so that they should be +% sorted differently in an index. +% \begin{macrocode} +\clist_new:N \g_@@_non_modules_clist +\clist_gset:Nx \g_@@_non_modules_clist + { + \tl_to_str:n + { + + alignment, ampersand, atsign, backslash, catcode, circumflex, + code, colon, document, dollar, e, empty, false, hash, inf, + initex, job, left, log, math, mark, max, minus, nan, nil, no, + novalue, other, parameter, percent, pi, recursion, right, space, + stop, term, tilde, tmpa, tmpb, true, underscore, zero, one, two, + three, four, five, six, seven, eight, nine, ten, eleven, twelve, + thirteen, fourteen, fifteen, sixteen, thirty, hundred + + } + } +% \end{macrocode} +% \end{variable} +% % \subsection{Change history} % % Set the change history to use \tn{part}. diff --git a/macros/latex/contrib/l3kernel/l3docstrip.dtx b/macros/latex/contrib/l3kernel/l3docstrip.dtx index c0b1db0487..6555eb4c3b 100644 --- a/macros/latex/contrib/l3kernel/l3docstrip.dtx +++ b/macros/latex/contrib/l3kernel/l3docstrip.dtx @@ -63,66 +63,14 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % % \begin{documentation} % -% \section{Extending \textsf{DocStrip}} -% -% The \pkg{l3docstrip} module adds \LaTeX3 extensions to the \textsf{DocStrip} -% program for extracting code from \texttt{.dtx}. As such, this documentation -% should be read along with that for \textsf{DocStrip}. -% -% \section{Internal functions and variables} -% -% An important consideration for \LaTeX3 development is separating out public -% and internal functions. Functions and variables which are private to one -% module should not be used or modified by any other module. As \TeX{} does -% not have any formal namespacing system, this requires a convention for -% indicating which functions in a code-level module are public and which are -% private. -% -% Using \pkg{l3docstrip} allows internal functions to be indicated using a -% \enquote{two part} system. Within the \texttt{.dtx} file, internal functions -% may be indicated using |@@| in place of the module name, for example -% \begin{verbatim} -% \cs_new_protected:Npn \@@_some_function:nn #1#2 -% { -% % Some code here -% } -% \tl_new:N \l_@@_internal_tl -% \end{verbatim} -% -% To extract the code using \pkg{l3docstrip}, the \enquote{guard} concept -% used by \textsf{DocStrip} is extended by introduction of the syntax -% \texttt{\%<@@=\meta{module}>}. The \meta{module} name then replaces -% the |@@| when the code is extracted, so that -% \begin{verbatim} -% %<*package> -% %<@@=foo> -% \cs_new_protected:Npn \@@_some_function:nn #1#2 -% { -% % Some code here -% } -% \tl_new:N \l_@@_internal_tl -% %</package> -% \end{verbatim} -% is extracted as -% \begin{verbatim} -% \cs_new_protected:Npn \__foo_some_function:nn #1#2 -% { -% % Some code here -% } -% \tl_new:N \l__foo_internal_tl -% \end{verbatim} -% where the |__| indicates that the functions and variables are internal -% to the \texttt{foo} module. -% -% Use |@@@@| to obtain |@@| in the output (|@@@@@| to get |@@@|). For -% longer pieces of code the replacement can be completely suppressed by -% giving an empty module name, namely using the syntax \texttt{\%<@@=>}. +% This is a stub file to allow extraction of \texttt{l3docstrip}: all +% functionality has been moved to the main DocStrip program. % % \end{documentation} % @@ -134,155 +82,11 @@ %<*program> % \end{macrocode} % -% We start by loading the existing \textsf{DocStrip} code using the \TeX{} -% input convention. +% Simply input DocStrip. % \begin{macrocode} \input docstrip % % \end{macrocode} % -% \begin{macro}{\checkOption} -% The \cs{checkOption} macro is defined by \textsf{DocStrip} and is redefined -% here to accommodate the new \texttt{\%<@} syntax. -% -% When the macros that process a line have found that the line starts with -% \enquote{\texttt{\%<}}, a guard line has been encountered. The first -% character of a guard can be an asterisk (\texttt{*}), a slash (\texttt{/}), -% a plus (\texttt{+}), a minus (\texttt{-}), a less-than sign (\texttt{<}) -% starting verbatim mode, a commercial at (\texttt{@}) or any other character -% that can be found in an option name. This means that we have to peek at the -% next token and decide what kind of guard we have. We reinsert |#1| as it -% may be needed by \cs{doOption}. -% \begin{macrocode} -\def\checkOption<#1{% - \ifcase - \ifx*#10\else \ifx/#11\else - \ifx+#12\else \ifx-#13\else - \ifx<#14\else \ifx @#15\else 6\fi\fi\fi\fi\fi\fi\relax - \expandafter\starOption\or - \expandafter\slashOption\or - \expandafter\plusOption\or - \expandafter\minusOption\or - \expandafter\verbOption\or - \expandafter\moduleOption\or - \expandafter\doOption\fi - #1% -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\moduleOption} -% In the case where the line starts |%<@|: the defined syntax requires that -% this continues to |%<@@=|. At the moment, we assume that the syntax is -% correct and |#1| here is the module name for substitution into any -% internal functions in the extracted material. -% \begin{macrocode} -\def\moduleOption @@=#1>#2\endLine{% - \maybeMsg{<@@=#1>}% - \prepareActiveModule{#1}% -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\prepareActiveModule} -% \begin{macro}{\replaceModuleInLine} -% Here, we set up to do the search-and-replace when doing the extraction. -% The argument (|#1|) is the replacement text to use, or if empty an -% indicator that no replacement should be done. The search material is -% one of |__@@|, |_@@| or |@@|, done in order such that all three end -% up the same in the output. The string |@@@@| is hidden from these -% replacements by temporarily turning it into a pair of letters with -% different category codes, not produced by \pkg{docstrip}; this allows to -% get |@@| in the output. The replacement function is initialised as a -% do-nothing for the case where |%<@@=| is never seen. -% \begin{macrocode} -\begingroup - \catcode`\_ = 12 % - \long\gdef\prepareActiveModule#1{% - \ifx\relax#1\relax - \let\replaceModuleInLine\empty - \else - \edef\replaceModuleInLine{% - \noexpand\replaceAllIn\noexpand\inLine{@@@@}{\string aa}% - \noexpand\replaceAllIn\noexpand\inLine{__@@}{__#1}% - \noexpand\replaceAllIn\noexpand\inLine{_@@}{__#1}% - \noexpand\replaceAllIn\noexpand\inLine{@@}{__#1}% - \noexpand\replaceAllIn\noexpand\inLine{\string aa}{@@}% - }% - \fi - } -\endgroup -\let\replaceModuleInLine\empty -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\replaceAllIn} -% \begin{macro}{\replaceAllInAuxI} -% \begin{macro}{\replaceAllInAuxII} -% \begin{macro}{\replaceAllInAuxIII} -% The code here is a simple search-and-replace routine for a macro |#1|, -% replacing |#2| by |#3|. As set up here, there is an assumption that nothing -% is going to be expandable, which is reasonable as \pkg{l3docstrip} deals -% with \enquote{string} material. -% \begin{macrocode} -\long\def\replaceAllIn#1#2#3{% - \long\def\tempa##1##2#2{% - ##2\qMark\replaceAllInAuxIII#3##1% - }% - \edef#1{\expandafter\replaceAllInAuxI#1\qMark#2\qStop}% -} -\def\replaceAllInAuxI{% - \expandafter\replaceAllInAuxII\tempa\replaceAllInAuxI\empty -} -\long\def\replaceAllInAuxII#1\qMark#2{#1} -\long\def\replaceAllInAuxIII#1\qStop{} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\normalLine} -% The \cs{normalLine} macro is present in \textsf{DocStrip} but is modified -% here to include the search-and-replace macro \cs{replaceModuleInLine}. The -% macro \cs{normalLine} writes its argument (which has to be delimited with -% |\endLine|) on all active output files, i.e.~those with off-counters equal -% to zero. The counter \cs{codeLinesPassed} is incremented by~$1$ for -% statistics (the guards for this used in \textsf{DocStrip} are retained). -% \begin{macrocode} -\def\normalLine#1\endLine{% -%<*stats> - \advance\codeLinesPassed\@ne -%</stats> - \maybeMsg{.}% - \def\inLine{#1}% - \replaceModuleInLine - \let\do\putline@do - \activefiles -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\doOption} -% As \textsf{DocStrip} processes each line, a line starting with |%<| triggers (via \cs{checkOption} above) a look-ahead to establish the type of guard encountered. -% Of the branching possibilities, if we ignore the deprecated |+| and |-| and choose to do no replacement for the special verbatim mode, the only branch that we need to alter is that for a single-line guard such as\\ | %<stats> ...stats-only code to include...|. -% The original definition of \cs{doOption} did not use \cs{inLine} but I believe we're safe to do so. -% \begin{macrocode} -\def\doOption#1>#2\endLine{% - \maybeMsg{<#1 . >}% - \Evaluate{#1}% - \def\do##1##2##3{% - \if1\Expr{##2}% - \def\inLine{#2}% - \replaceModuleInLine - \StreamPut##1{\inLine}% - \fi - }% - \activefiles -} -% \end{macrocode} -% \end{macro} -% % \begin{macrocode} %</program> % \end{macrocode} diff --git a/macros/latex/contrib/l3kernel/l3docstrip.pdf b/macros/latex/contrib/l3kernel/l3docstrip.pdf Binary files differindex 887de46717..2c252c5ca9 100644 --- a/macros/latex/contrib/l3kernel/l3docstrip.pdf +++ b/macros/latex/contrib/l3kernel/l3docstrip.pdf diff --git a/macros/latex/contrib/l3kernel/l3expan.dtx b/macros/latex/contrib/l3kernel/l3expan.dtx index c4de266f4e..1c6b1bd01d 100644 --- a/macros/latex/contrib/l3kernel/l3expan.dtx +++ b/macros/latex/contrib/l3kernel/l3expan.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -1601,7 +1601,7 @@ % \begin{macro}[EXP]{\exp_not:V} % \begin{macro}[EXP]{\exp_not:v} % All these except \cs{exp_not:c} call the kernel-internal -% \cs{__kernel_exp_not:w} namely \tn{tex_unexpanded:D}. +% \cs{__kernel_exp_not:w} namely \cs{tex_unexpanded:D}. % \begin{macrocode} \cs_new:Npn \exp_not:c #1 { \exp_after:wN \exp_not:N \cs:w #1 \cs_end: } \cs_new:Npn \exp_not:o #1 { \__kernel_exp_not:w \exp_after:wN {#1} } diff --git a/macros/latex/contrib/l3kernel/l3file.dtx b/macros/latex/contrib/l3kernel/l3file.dtx index 76c21c537e..eb025e0b16 100644 --- a/macros/latex/contrib/l3kernel/l3file.dtx +++ b/macros/latex/contrib/l3kernel/l3file.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -1128,11 +1128,11 @@ % \texttt{show-streams} takes care of translating |ior|/|iow| to % English. % \begin{macrocode} -\cs_new_protected:Npn \ior_show_list: { \@@_list:N \msg_show:nnxxxx } -\cs_new_protected:Npn \ior_log_list: { \@@_list:N \msg_log:nnxxxx } +\cs_new_protected:Npn \ior_show_list: { \@@_list:N \__kernel_msg_show:nnxxxx } +\cs_new_protected:Npn \ior_log_list: { \@@_list:N \__kernel_msg_log:nnxxxx } \cs_new_protected:Npn \@@_list:N #1 { - #1 { LaTeX / kernel } { show-streams } + #1 { kernel } { show-streams } { ior } { \prop_map_function:NN \g_@@_streams_prop @@ -1161,19 +1161,19 @@ % \begin{macrocode} \prg_new_conditional:Npnn \ior_if_eof:N #1 { p , T , F , TF } { - \cs_if_exist:NTF #1 - { - \int_compare:nTF { -1 < #1 < \c_@@_term_ior } - { - \if_eof:w #1 - \prg_return_true: - \else: - \prg_return_false: - \fi: - } - { \prg_return_true: } - } - { \prg_return_true: } + \if_int_compare:w -1 < #1 + \if_int_compare:w #1 < \c_@@_term_ior + \if_eof:w #1 + \prg_return_true: + \else: + \prg_return_false: + \fi: + \else: + \prg_return_true: + \fi: + \else: + \prg_return_true: + \fi: } % \end{macrocode} % \end{macro} @@ -1272,7 +1272,7 @@ % \begin{macro}{\@@_map_inline:NNn} % \begin{macro}{\@@_map_inline:NNNn} % \begin{macro}{\@@_map_inline_loop:NNN} -% Mapping to an input stream can be done on either a token or a string +% Mapping over an input stream can be done on either a token or a string % basis, hence the set up. Within that, there is a check to avoid reading % past the end of a file, hence the two applications of \cs{ior_if_eof:N} % and its lower-level analogue \cs{if_eof:w}. @@ -1524,11 +1524,11 @@ % \begin{macro}{\@@_list:N} % Done as for input, but with a copy of the auxiliary so the name is correct. % \begin{macrocode} -\cs_new_protected:Npn \iow_show_list: { \@@_list:N \msg_show:nnxxxx } -\cs_new_protected:Npn \iow_log_list: { \@@_list:N \msg_log:nnxxxx } +\cs_new_protected:Npn \iow_show_list: { \@@_list:N \__kernel_msg_show:nnxxxx } +\cs_new_protected:Npn \iow_log_list: { \@@_list:N \__kernel_msg_log:nnxxxx } \cs_new_protected:Npn \@@_list:N #1 { - #1 { LaTeX / kernel } { show-streams } + #1 { kernel } { show-streams } { iow } { \prop_map_function:NN \g_@@_streams_prop @@ -2426,102 +2426,126 @@ % \end{macro} % % \begin{macro}[EXP]{\__kernel_file_name_sanitize:n} -% \begin{macro}[EXP]{\__kernel_file_name_expand_loop:w} -% \begin{macro}[EXP]{\__kernel_file_name_expand_N_type:Nw} -% \begin{macro}[EXP]{\__kernel_file_name_expand_group:nw} -% \begin{macro}[EXP]{\__kernel_file_name_expand_space:w} -% \begin{macro}[EXP]{\__kernel_file_name_strip_quotes:n} -% \begin{macro}[EXP]{\__kernel_file_name_strip_quotes:nnnw} -% \begin{macro}[EXP]{\__kernel_file_name_strip_quotes:nnn} -% \begin{macro}[EXP]{\__kernel_file_name_trim_spaces:n} -% \begin{macro}[EXP]{\__kernel_file_name_trim_spaces:nw} -% \begin{macro}[EXP]{\__kernel_file_name_trim_spaces_aux:n} -% \begin{macro}[EXP]{\__kernel_file_name_trim_spaces_aux:w} -% Expanding the file name without expanding active characters is done -% using the same token-by-token approach as for example case changing. -% The finale outcome only need be \texttt{e}-type expandable, so there -% is no need for the shuffling that is seen in other locations. +% \begin{macro}[EXP]{ +% \@@_name_expand:n, +% \@@_name_expand_cleanup:Nw, +% \@@_name_expand_cleanup:w, +% \@@_name_expand_end:, +% \@@_name_expand_error:Nw, +% \@@_name_expand_error_aux:Nw, +% } +% \begin{macro}[EXP]{ +% \@@_name_strip_quotes:n, +% \@@_name_strip_quotes:nnnw, +% \@@_name_strip_quotes:nnn, +% } +% \begin{macro}[EXP]{ +% \@@_name_trim_spaces:n, +% \@@_name_trim_spaces:nw, +% \@@_name_trim_spaces_aux:n, +% \@@_name_trim_spaces_aux:w, +% } +% Expanding the file name uses a \tn{csname}-based approach, and +% relies on active characters (for example from UTF-8 characters) +% being properly set up to expand to a expansion-safe version using +% \cs{ifcsname}. This is less conservative than the token-by-token +% approach used before, but it is much faster. % \begin{macrocode} \cs_new:Npn \__kernel_file_name_sanitize:n #1 { - \exp_args:Ne \__kernel_file_name_trim_spaces:n + \exp_args:Ne \@@_name_trim_spaces:n { - \exp_args:Ne \__kernel_file_name_strip_quotes:n - { - \__kernel_file_name_expand_loop:w #1 - \q_@@_recursion_tail \q_@@_recursion_stop - } + \exp_args:Ne \@@_name_strip_quotes:n + { \@@_name_expand:n {#1} } } } -\cs_new:Npn \__kernel_file_name_expand_loop:w #1 \q_@@_recursion_stop +% \end{macrocode} +% +% We'll use \cs{cs:w} to start expanding the file name, and to avoid +% creating csnames equal to \tn{relax} with \enquote{common} names, +% there's a prefix |__file_name=| to the csname. There's also a guard +% token at the end so we can check if there was an error during the +% process and (try to) clean up gracefully. +% \begin{macrocode} +\cs_new:Npn \@@_name_expand:n #1 { - \tl_if_head_is_N_type:nTF {#1} - { \__kernel_file_name_expand_N_type:Nw } - { - \tl_if_head_is_group:nTF {#1} - { \__kernel_file_name_expand_group:nw } - { \__kernel_file_name_expand_space:w } - } - #1 \q_@@_recursion_stop + \exp_after:wN \@@_name_expand_cleanup:Nw + \cs:w @@_name = #1 \cs_end: + \@@_name_expand_end: } -\cs_new:Npn \__kernel_file_name_expand_N_type:Nw #1 +% \end{macrocode} +% With the csname built, we grab it, and grab the remaining tokens +% delimited by \cs{@@_name_expand_end:}. If there are any remaining +% tokens, something bad happened, so we'll call the error procedure +% \cs{@@_name_expand_error:Nw}. +% If everything went according to plan, then use \cs{token_to_str:N} +% on the csname built, and call \cs{@@_name_expand_cleanup:w} to +% remove the prefix we added a while back. +% \cs{@@_name_expand_cleanup:w} takes a leading argument so we don't +% have to bother about the value of \cs{tex_escapechar:D}. +% \begin{macrocode} +\cs_new:Npn \@@_name_expand_cleanup:Nw #1 #2 \@@_name_expand_end: { - \@@_if_recursion_tail_stop:N #1 - \bool_lazy_and:nnTF - { \token_if_expandable_p:N #1 } - { - \bool_not_p:n - { - \bool_lazy_any_p:n - { - { \token_if_protected_macro_p:N #1 } - { \token_if_protected_long_macro_p:N #1 } - { \token_if_active_p:N #1 } - } - } - } - { \exp_after:wN \__kernel_file_name_expand_loop:w #1 } - { - \token_to_str:N #1 - \__kernel_file_name_expand_loop:w - } + \tl_if_empty:nF {#2} + { \@@_name_expand_error:Nw #2 \@@_name_expand_end: } + \exp_after:wN \@@_name_expand_cleanup:w \token_to_str:N #1 } -\cs_new:Npx \__kernel_file_name_expand_group:nw #1 +\exp_last_unbraced:NNNNo +\cs_new:Npn \@@_name_expand_cleanup:w #1 \tl_to_str:n { @@_name = } { } +% \end{macrocode} +% In non-error cases \cs{@@_name_expand_end:} should not expand. It +% will only do so in case there is a \cs{csname} too much in the file +% name, so it will throw an error (while expanding), then insert the +% missing \cs{cs_end:} and yet another \cs{@@_name_expand_end:} that +% will be used as a delimiter by \cs{@@_name_expand_cleanup:Nw} (or +% that will expand again if yet another \cs{endcsname} is missing). +% \begin{macrocode} +\cs_new:Npn \@@_name_expand_end: { - \c_left_brace_str - \exp_not:N \__kernel_file_name_expand_loop:w - #1 - \c_right_brace_str + \__kernel_msg_expandable_error:nn + { kernel } { filename-missing-endcsname } + \cs_end: \@@_name_expand_end: + } +% \end{macrocode} +% Now to the error case. \cs{@@_name_expand_error:Nw} adds an extra +% \cs{cs_end:} so that in case there was an extra \tn{csname} in the +% file name, then \cs{@@_name_expand_error_aux:Nw} throws the error. +% \begin{macrocode} +\cs_new:Npn \@@_name_expand_error:Nw #1 #2 \@@_name_expand_end: + { \@@_name_expand_error_aux:Nw #1 #2 \cs_end: \@@_name_expand_end: } +\cs_new:Npn \@@_name_expand_error_aux:Nw #1 #2 \cs_end: #3 + \@@_name_expand_end: + { + \__kernel_msg_expandable_error:nnff + { kernel } { filename-chars-lost } + { \token_to_str:N #1 } { \exp_stop_f: #2 } } -\exp_last_unbraced:NNo - \cs_new:Npx \__kernel_file_name_expand_space:w \c_space_tl - { - \c_space_tl - \exp_not:N \__kernel_file_name_expand_loop:w - } % \end{macrocode} % Quoting file name uses basically the same approach as for % \texttt{luaquotejobname}: count the |"| tokens and remove them. % \begin{macrocode} -\cs_new:Npn \__kernel_file_name_strip_quotes:n #1 +\cs_new:Npn \@@_name_strip_quotes:n #1 { - \__kernel_file_name_strip_quotes:nnnw {#1} { 0 } { } - #1 " \q_@@_recursion_tail " \q_@@_recursion_stop + \@@_name_strip_quotes:nw { 0 } + #1 " \q_@@_recursion_tail " \q_@@_recursion_stop {#1} } -\cs_new:Npn \__kernel_file_name_strip_quotes:nnnw #1#2#3#4 " +\cs_new:Npn \@@_name_strip_quotes:nw #1#2 " { - \@@_if_recursion_tail_stop_do:nn {#4} - { \__kernel_file_name_strip_quotes:nnn {#1} {#2} {#3} } - \__kernel_file_name_strip_quotes:nnnw {#1} { #2 + 1 } { #3#4 } + \if_meaning:w \q_@@_recursion_tail #2 + \@@_name_strip_quotes_end:wnwn + \fi: + #2 + \@@_name_strip_quotes:nw { #1 + 1 } } -\cs_new:Npn \__kernel_file_name_strip_quotes:nnn #1#2#3 +\cs_new:Npn \@@_name_strip_quotes_end:wnwn \fi: #1 + \@@_name_strip_quotes:nw #2 \q_@@_recursion_stop #3 { - \int_if_even:nT {#2} + \fi: + \int_if_odd:nT {#2} { \__kernel_msg_expandable_error:nnn - { kernel } { unbalanced-quote-in-filename } {#1} + { kernel } { unbalanced-quote-in-filename } {#3} } - #3 } % \end{macrocode} % Spaces need to be trimmed from the start of the name and from the end of @@ -2530,40 +2554,32 @@ % the standard trimming function but deliberately prevent any spaces being % removed at the end. % \begin{macrocode} -\cs_new:Npn \__kernel_file_name_trim_spaces:n #1 - { \__kernel_file_name_trim_spaces:nw {#1} #1 . \q_@@_nil . \s_@@_stop } -\cs_new:Npn \__kernel_file_name_trim_spaces:nw #1#2 . #3 . #4 \s_@@_stop +\cs_new:Npn \@@_name_trim_spaces:n #1 + { \@@_name_trim_spaces:nw {#1} #1 . \q_@@_nil . \s_@@_stop } +\cs_new:Npn \@@_name_trim_spaces:nw #1#2 . #3 . #4 \s_@@_stop { \@@_quark_if_nil:nTF {#3} { - \exp_args:Ne \__kernel_file_name_trim_spaces_aux:n - { \tl_trim_spaces:n { #1 \s_@@_stop } } + \tl_trim_spaces_apply:nN { #1 \s_@@_stop } + \@@_name_trim_spaces_aux:n } { \tl_trim_spaces:n {#1} } } -\cs_new:Npn \__kernel_file_name_trim_spaces_aux:n #1 - { \__kernel_file_name_trim_spaces_aux:w #1 } -\cs_new:Npn \__kernel_file_name_trim_spaces_aux:w #1 \s_@@_stop {#1} +\cs_new:Npn \@@_name_trim_spaces_aux:n #1 + { \@@_name_trim_spaces_aux:w #1 } +\cs_new:Npn \@@_name_trim_spaces_aux:w #1 \s_@@_stop {#1} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} % % \begin{macro}[EXP]{\__kernel_file_name_quote:n} -% \begin{macro}[EXP]{\__kernel_file_name_quote:nw} +% \begin{macro}[EXP]{\@@_name_quote:nw} % \begin{macrocode} \cs_new:Npn \__kernel_file_name_quote:n #1 - { \__kernel_file_name_quote:nw {#1} #1 ~ \q_@@_nil \s_@@_stop } -\cs_new:Npn \__kernel_file_name_quote:nw #1 #2 ~ #3 \s_@@_stop + { \@@_name_quote:nw {#1} #1 ~ \q_@@_nil \s_@@_stop } +\cs_new:Npn \@@_name_quote:nw #1 #2 ~ #3 \s_@@_stop { \@@_quark_if_nil:nTF {#3} { #1 } @@ -2643,14 +2659,17 @@ % \end{macro} % % \begin{macro}[EXP]{\file_full_name:n, \@@_full_name:n} +% \begin{macro}[EXP]{\@@_full_name_aux:nn} % \begin{macro}[EXP]{\@@_full_name_aux:Nnn} % \begin{macro}[EXP]{\@@_full_name_aux:nN} +% \begin{macro}[EXP]{\@@_full_name_aux:nnN} % \begin{macro}[EXP]{\@@_name_cleanup:w} % \begin{macro}[EXP]{\@@_name_end:} -% \begin{macro}[EXP]{\@@_name_ext_check:n} -% \begin{macro}[EXP]{\@@_name_ext_check:nw} -% \begin{macro}[EXP]{\@@_name_ext_check:nnw} % \begin{macro}[EXP]{\@@_name_ext_check:nn} +% \begin{macro}[EXP]{\@@_name_ext_check:nnw} +% \begin{macro}[EXP]{\@@_name_ext_check:nnnw} +% \begin{macro}[EXP]{\@@_name_ext_check:nnn} +% \begin{macro}[EXP]{\@@_name_ext_check:nnnn} % File searching can be carried out if the \tn{pdffilesize} primitive % or an equivalent is available. That of course means we need to % arrange for everything else to here to be done by expansion too. @@ -2666,25 +2685,29 @@ % First, we check of the file is just here: no mapping so we do not % need the break part of the broader auxiliary. We are using the fact % that the primitive here returns nothing if the file is entirely absent. +% To avoid unnecessary filesystem lookups, the result of \tn{pdffilesize} +% is kept available as an argument. % For package mode, \tn{input@path} is a token list not a sequence. % \begin{macrocode} \cs_new:Npn \@@_full_name:n #1 { \tl_if_blank:nF {#1} + { \exp_args:Nne \@@_full_name_aux:nn {#1} { \@@_size:n {#1} } } + } +\cs_new:Npn \@@_full_name_aux:nn #1 #2 + { + \tl_if_blank:nTF {#2} { - \tl_if_blank:eTF { \@@_size:n {#1} } + \seq_map_tokens:Nn \l_file_search_path_seq + { \@@_full_name_aux:Nnn \seq_map_break:n {#1} } + \cs_if_exist:NT \input@path { - \seq_map_tokens:Nn \l_file_search_path_seq - { \@@_full_name_aux:Nnn \seq_map_break:n {#1} } - \cs_if_exist:NT \input@path - { - \tl_map_tokens:Nn \input@path - { \@@_full_name_aux:Nnn \tl_map_break:n {#1} } - } - \@@_name_end: + \tl_map_tokens:Nn \input@path + { \@@_full_name_aux:Nnn \tl_map_break:n {#1} } } - { \@@_ext_check:n {#1} } + \@@_name_end: } + { \@@_ext_check:nn {#1} {#2} } } % \end{macrocode} % Two pars to the auxiliary here so we can avoid doing quoting @@ -2692,13 +2715,15 @@ % \begin{macrocode} \cs_new:Npn \@@_full_name_aux:Nnn #1#2#3 { \exp_args:Ne \@@_full_name_aux:nN { \tl_to_str:n {#3} / #2 } #1 } -\cs_new:Npn \@@_full_name_aux:nN #1 #2 +\cs_new:Npn \@@_full_name_aux:nN #1 + { \exp_args:Nne \@@_full_name_aux:nnN {#1} { \@@_size:n {#1} } } +\cs_new:Npn \@@_full_name_aux:nnN #1 #2 #3 { - \tl_if_blank:eF { \@@_size:n {#1} } + \tl_if_blank:nF {#2} { - #2 + #3 { - \@@_ext_check:n {#1} + \@@_ext_check:nn {#1} {#2} \@@_name_cleanup:w } } @@ -2710,35 +2735,37 @@ % there is a little clean up to do here. First, make sure we are not in the % directory part, saving that. Then check for an extension. % \begin{macrocode} -\cs_new:Npn \@@_ext_check:n #1 - { \@@_ext_check:nw { / } #1 / \q_@@_nil / \s_@@_stop } -\cs_new:Npn \@@_ext_check:nw #1 #2 / #3 / #4 \s_@@_stop +\cs_new:Npn \@@_ext_check:nn #1 #2 +{ \@@_ext_check:nnw {#2} { / } #1 / \q_@@_nil / \s_@@_stop } +\cs_new:Npn \@@_ext_check:nnw #1 #2 #3 / #4 / #5 \s_@@_stop { - \@@_quark_if_nil:nTF {#3} + \@@_quark_if_nil:nTF {#4} { - \exp_args:No \@@_ext_check:nnw - { \use_none:n #1 } {#2} #2 . \q_@@_nil . \s_@@_stop + \exp_args:No \@@_ext_check:nnnw + { \use_none:n #2 } {#1} {#3} #3 . \q_@@_nil . \s_@@_stop } - { \@@_ext_check:nw { #1 #2 / } #3 / #4 \s_@@_stop } + { \@@_ext_check:nnw {#1} { #2 #3 / } #4 / #5 \s_@@_stop } } -\cs_new:Npx \@@_ext_check:nnw #1#2#3 . #4 . #5 \s_@@_stop +\cs_new:Npx \@@_ext_check:nnnw #1#2#3#4 . #5 . #6 \s_@@_stop { - \exp_not:N \@@_quark_if_nil:nTF {#4} + \exp_not:N \@@_quark_if_nil:nTF {#5} { - \exp_not:N \@@_ext_check:nn - { #1 #2 } { #1 #2 \tl_to_str:n { .tex } } + \exp_not:N \@@_ext_check:nnn + { #1 #3 \tl_to_str:n { .tex } } { #1 #3 } {#2} } - { #1 #2 } + { #1 #3 } } -\cs_new:Npn \@@_ext_check:nn #1#2 +\cs_new:Npn \@@_ext_check:nnn #1 + { \exp_args:Nne \@@_ext_check:nnnn {#1} { \@@_size:n {#1} } } +\cs_new:Npn \@@_ext_check:nnnn #1#2#3#4 { - \tl_if_blank:eTF { \@@_size:n {#2} } - {#1} + \tl_if_blank:nTF {#2} + {#3} { \int_compare:nNnTF - { \@@_size:n {#1} } = { \@@_size:n {#2} } - {#2} + {#4} = {#2} {#1} + {#3} } } % \end{macrocode} @@ -2769,6 +2796,9 @@ % \end{macro} % \end{macro} % \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % % \begin{macro}{\file_get_full_name:nN, \file_get_full_name:VN} % \begin{macro}[TF]{\file_get_full_name:nN, \file_get_full_name:VN} @@ -3360,8 +3390,8 @@ % \cs{AtBeginDocument} into \cs{g_@@_record_seq}), turning it to a % string (this does not affect the commas of this comma list). % \begin{macrocode} -\cs_new_protected:Npn \file_show_list: { \@@_list:N \msg_show:nnxxxx } -\cs_new_protected:Npn \file_log_list: { \@@_list:N \msg_log:nnxxxx } +\cs_new_protected:Npn \file_show_list: { \@@_list:N \__kernel_msg_show:nnxxxx } +\cs_new_protected:Npn \file_log_list: { \@@_list:N \__kernel_msg_log:nnxxxx } \cs_new_protected:Npn \@@_list:N #1 { \seq_clear:N \l_@@_tmp_seq @@ -3372,7 +3402,7 @@ } \seq_concat:NNN \l_@@_tmp_seq \l_@@_tmp_seq \g_@@_record_seq \seq_remove_duplicates:N \l_@@_tmp_seq - #1 { LaTeX/kernel } { file-list } + #1 { kernel } { file-list } { \seq_map_function:NN \l_@@_tmp_seq \@@_list_aux:n } { } { } { } } @@ -3614,6 +3644,19 @@ #1 \\ ............. } +\__kernel_msg_new:nnnn { kernel } { filename-chars-lost } + { #1~invalid~in~file~name.~Lost:~#2. } + { + There~was~an~invalid~token~in~the~file~name~that~caused~ + the~characters~following~it~to~be~lost. + } +\__kernel_msg_new:nnnn { kernel } { filename-missing-endcsname } + { Missing~\iow_char:N\\endcsname~inserted~in~filename. } + { + The~file~name~had~more~\iow_char:N\\csname~commands~than~ + \iow_char:N\\endcsname~ones.~LaTeX~will~add~the~missing~ + \iow_char:N\\endcsname~and~try~to~continue~as~best~as~it~can. + } \__kernel_msg_new:nnnn { kernel } { unbalanced-quote-in-filename } { Unbalanced~quotes~in~file~name~'#1'. } { diff --git a/macros/latex/contrib/l3kernel/l3flag.dtx b/macros/latex/contrib/l3kernel/l3flag.dtx index c55b556453..ee3458bb46 100644 --- a/macros/latex/contrib/l3kernel/l3flag.dtx +++ b/macros/latex/contrib/l3kernel/l3flag.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3fp-assign.dtx b/macros/latex/contrib/l3kernel/l3fp-assign.dtx index 30d9cc9ad5..d4f03e55f2 100644 --- a/macros/latex/contrib/l3kernel/l3fp-assign.dtx +++ b/macros/latex/contrib/l3kernel/l3fp-assign.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % \maketitle % % \begin{documentation} @@ -165,6 +165,7 @@ % \subsection{Showing values} % % \begin{macro}{\fp_show:N, \fp_show:c, \fp_log:N, \fp_log:c, \@@_show:NN} +% \begin{macro}[EXP]{\@@_show_validate:w} % This shows the result of computing its argument by % passing the right data to \cs{tl_show:n} or \cs{tl_log:n}. % \begin{macrocode} @@ -174,11 +175,26 @@ \cs_generate_variant:Nn \fp_log:N { c } \cs_new_protected:Npn \@@_show:NN #1#2 { - \__kernel_chk_defined:NT #2 + \__kernel_chk_tl_type:NnnT #2 { fp } + { + \str_if_eq:eeTF { \tl_head:N #2 } { \s_@@_tuple } { \exp_not:o #2 } + { + \exp_after:wN \@@_show_validate:w #2 + \s_@@ \@@_chk:w ??? ; \s_@@_stop + } + } { \exp_args:Nx #1 { \token_to_str:N #2 = \fp_to_tl:N #2 } } } +\cs_new:Npn \@@_show_validate:w + #1 \s_@@ \@@_chk:w #2#3#4#5 ; #6 \s_@@_stop + { + \token_if_eq_meaning:NNTF #2 1 + { \s_@@ \@@_chk:w #2 #3 {#4} #5 ; } + { \s_@@ \@@_chk:w #2 #3 #4 #5 ; } + } % \end{macrocode} % \end{macro} +% \end{macro} % % \begin{macro}{\fp_show:n, \fp_log:n} % Use general tools. diff --git a/macros/latex/contrib/l3kernel/l3fp-aux.dtx b/macros/latex/contrib/l3kernel/l3fp-aux.dtx index 451f0952fc..172735f54d 100644 --- a/macros/latex/contrib/l3kernel/l3fp-aux.dtx +++ b/macros/latex/contrib/l3kernel/l3fp-aux.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -226,7 +226,7 @@ % stream and its contents reach \TeX{}'s stomach. % \begin{macrocode} \cs_new_protected:Npn \@@_misused:n #1 - { \__kernel_msg_error:nnx { kernel } { misused-fp } { \fp_to_tl:n {#1} } } + { \__kernel_msg_error:nnx { fp } { misused } { \fp_to_tl:n {#1} } } % \end{macrocode} % \end{macro} % @@ -1267,7 +1267,7 @@ % % Using a floating point directly is an error. % \begin{macrocode} -\__kernel_msg_new:nnnn { kernel } { misused-fp } +\__kernel_msg_new:nnnn { fp } { misused } { A~floating~point~with~value~'#1'~was~misused. } { To~obtain~the~value~of~a~floating~point~variable,~use~ diff --git a/macros/latex/contrib/l3kernel/l3fp-basics.dtx b/macros/latex/contrib/l3kernel/l3fp-basics.dtx index 0742eafffd..9ded69aa6f 100644 --- a/macros/latex/contrib/l3kernel/l3fp-basics.dtx +++ b/macros/latex/contrib/l3kernel/l3fp-basics.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3fp-convert.dtx b/macros/latex/contrib/l3kernel/l3fp-convert.dtx index ccac4b8a42..97d449608f 100644 --- a/macros/latex/contrib/l3kernel/l3fp-convert.dtx +++ b/macros/latex/contrib/l3kernel/l3fp-convert.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -150,7 +150,7 @@ } \cs_new:Npn \@@_to_scientific_recover:w #1 #2 ; { - \@@_error:nffn { fp-unknown-type } { \tl_to_str:n { #2 ; } } { } { } + \@@_error:nffn { unknown-type } { \tl_to_str:n { #2 ; } } { } { } nan } \cs_new:Npn \@@_tuple_to_scientific:w @@ -244,7 +244,7 @@ } \cs_new:Npn \@@_to_decimal_recover:w #1 #2 ; { - \@@_error:nffn { fp-unknown-type } { \tl_to_str:n { #2 ; } } { } { } + \@@_error:nffn { unknown-type } { \tl_to_str:n { #2 ; } } { } { } nan } \cs_new:Npn \@@_tuple_to_decimal:w @@ -357,7 +357,7 @@ { \@@_change_func_type:NNN #1 \@@_to_tl:w \@@_to_tl_recover:w #1 } \cs_new:Npn \@@_to_tl_recover:w #1 #2 ; { - \@@_error:nffn { fp-unknown-type } { \tl_to_str:n { #2 ; } } { } { } + \@@_error:nffn { unknown-type } { \tl_to_str:n { #2 ; } } { } { } nan } \cs_new:Npn \@@_tuple_to_tl:w diff --git a/macros/latex/contrib/l3kernel/l3fp-expo.dtx b/macros/latex/contrib/l3kernel/l3fp-expo.dtx index 09e0a27689..1ae1a4faf8 100644 --- a/macros/latex/contrib/l3kernel/l3fp-expo.dtx +++ b/macros/latex/contrib/l3kernel/l3fp-expo.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3fp-extended.dtx b/macros/latex/contrib/l3kernel/l3fp-extended.dtx index d3654cf4f5..ebb2852223 100644 --- a/macros/latex/contrib/l3kernel/l3fp-extended.dtx +++ b/macros/latex/contrib/l3kernel/l3fp-extended.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3fp-logic.dtx b/macros/latex/contrib/l3kernel/l3fp-logic.dtx index e6da23c805..75823bbb95 100644 --- a/macros/latex/contrib/l3kernel/l3fp-logic.dtx +++ b/macros/latex/contrib/l3kernel/l3fp-logic.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -423,7 +423,7 @@ \prg_break_point: \use:n { - \@@_error:nfff { fp-step-tuple } { \fp_to_tl:n { #1#2 ; } } + \@@_error:nfff { step-tuple } { \fp_to_tl:n { #1#2 ; } } { \fp_to_tl:n { #3#4 ; } } { \fp_to_tl:n { #5#6 ; } } } } @@ -442,7 +442,7 @@ { zero-step } {#6} } { - \@@_error:nnfn { fp-bad-step } { } + \@@_error:nnfn { bad-step } { } { \fp_to_tl:n { \s_@@ \@@_chk:w #2#3#4 ; } } {#6} } \use_none:nnnnn @@ -453,7 +453,7 @@ { \fp_compare:nNnTF {#2} = {#3} { - \@@_error:nffn { fp-tiny-step } + \@@_error:nffn { tiny-step } { \fp_to_tl:n {#3} } { \fp_to_tl:n {#4} } {#6} } { @@ -506,11 +506,11 @@ % \end{macro} % % \begin{macrocode} -\__kernel_msg_new:nnn { kernel } { fp-step-tuple } +\__kernel_msg_new:nnn { fp } { step-tuple } { Tuple~argument~in~fp_step_...~{#1}{#2}{#3}. } -\__kernel_msg_new:nnn { kernel } { fp-bad-step } +\__kernel_msg_new:nnn { fp } { bad-step } { Invalid~step~size~#2~in~step~function~#3. } -\__kernel_msg_new:nnn { kernel } { fp-tiny-step } +\__kernel_msg_new:nnn { fp } { tiny-step } { Tiny~step~size~(#1+#2=#1)~in~step~function~#3. } % \end{macrocode} % @@ -698,7 +698,7 @@ \@@_parse_expand:w \else: \__kernel_msg_expandable_error:nnnn - { kernel } { fp-missing } { : } { ~for~?: } + { fp } { missing } { : } { ~for~?: } \exp_after:wN \@@_parse_continue:NwN \exp_after:wN #1 \exp:w \exp_end_continue_f:w diff --git a/macros/latex/contrib/l3kernel/l3fp-parse.dtx b/macros/latex/contrib/l3kernel/l3fp-parse.dtx index ce534ca6c6..c43da846b6 100644 --- a/macros/latex/contrib/l3kernel/l3fp-parse.dtx +++ b/macros/latex/contrib/l3kernel/l3fp-parse.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -789,7 +789,7 @@ } } { - \__kernel_msg_expandable_error:nn { kernel } { fp-early-end } + \__kernel_msg_expandable_error:nn { fp } { early-end } \exp_after:wN \c_nan_fp \exp:w \exp_end_continue_f:w } #1 @@ -811,8 +811,8 @@ { \cs_if_eq:NNTF ##2 #1 { \use_i:nn } { \use:n } { - \__kernel_msg_expandable_error:nnn { kernel } - { fp-robust-cmd } + \__kernel_msg_expandable_error:nnn { fp } + { robust-cmd } } } { @@ -928,7 +928,7 @@ \str_if_eq:nnTF {#1} {#2} { \__kernel_msg_expandable_error:nnn - { kernel } { fp-infty-pi } {#1} + { fp } { infty-pi } {#1} \c_nan_fp } { #4 \@@_parse_expand:w } @@ -1026,7 +1026,7 @@ { @@_parse_caseless_ \str_foldcase:n {#2} :N } { \__kernel_msg_expandable_error:nnn - { kernel } { unknown-fp-word } {#2} + { fp } { unknown-fp-word } {#2} \exp_after:wN \c_nan_fp \exp:w \exp_end_continue_f:w \@@_parse_infix:NN } @@ -1081,13 +1081,13 @@ \cs_if_exist:cTF { @@_parse_infix_ \token_to_str:N #1 :N } { \__kernel_msg_expandable_error:nnn - { kernel } { fp-missing-number } {#1} + { fp } { missing-number } {#1} \exp_after:wN \c_nan_fp \exp:w \exp_end_continue_f:w \@@_parse_infix:NN #3 #1 } { \__kernel_msg_expandable_error:nnn - { kernel } { fp-unknown-symbol } {#1} + { fp } { unknown-symbol } {#1} \@@_parse_one:Nw #3 } } @@ -1760,7 +1760,7 @@ = 0 \exp_stop_f: 0 \__kernel_msg_expandable_error:nnn - { kernel } { fp-after-e } { floating~point~ } + { fp } { after-e } { floating~point~ } \prg_return_true: \else: 0 @@ -1776,14 +1776,14 @@ \else: 0 \__kernel_msg_expandable_error:nnn - { kernel } { fp-after-e } { dimension~#1 } + { fp } { after-e } { dimension~#1 } \fi: \prg_return_false: \fi: \else: 0 \__kernel_msg_expandable_error:nnn - { kernel } { fp-missing } { exponent } + { fp } { missing } { exponent } \prg_return_true: \fi: } @@ -1852,7 +1852,7 @@ \cs_new:Npn \@@_parse_apply_unary_chk:nNNNNw #1#2#3#4#5#6 @ { #2 - \@@_error:nffn { fp-#1-arg } { \@@_func_to_name:N #4 } { } { } + \@@_error:nffn { #1-arg } { \@@_func_to_name:N #4 } { } { } \exp_after:wN #4 \exp_after:wN #5 \c_nan_fp @ } \cs_new:Npn \@@_parse_apply_unary_type:NNN #1#2#3 @@ -1955,7 +1955,7 @@ } { \exp_not:N \__kernel_msg_expandable_error:nnn - { kernel } { fp-missing } { ) } + { fp } { missing } { ) } \exp_not:N \tl_if_empty:nT {#2} \exp_not:N \c_@@_empty_tuple_fp #2 @ \exp_not:N \use_none:n #3 @@ -1978,7 +1978,7 @@ \exp_after:wN \c_@@_empty_tuple_fp \exp:w \else: \__kernel_msg_expandable_error:nnn - { kernel } { fp-missing-number } { ) } + { fp } { missing-number } { ) } \exp_after:wN \c_nan_fp \exp:w \fi: \exp_end_continue_f:w @@ -2294,7 +2294,7 @@ { \if_meaning:w \scan_stop: #1 \__kernel_msg_expandable_error:nnn - { kernel } { fp-missing } { * } + { fp } { missing } { * } \exp_after:wN \@@_parse_infix_mul:N \exp_after:wN #2 \exp_after:wN #3 @@ -2380,7 +2380,7 @@ \exp_after:wN \use_none:n \exp_after:wN #1 \else: - \__kernel_msg_expandable_error:nnn { kernel } { fp-extra } { ) } + \__kernel_msg_expandable_error:nnn { fp } { extra } { ) } \exp_after:wN \@@_parse_infix:NN \exp_after:wN ##1 \exp:w \exp_after:wN \@@_parse_expand:w @@ -2584,7 +2584,7 @@ \@@_ternary_auxii:NwwN \c_@@_prec_colon_int { \__kernel_msg_expandable_error:nnnn - { kernel } { fp-missing } { ? } { ~for~?: } + { fp } { missing } { ? } { ~for~?: } } % \end{macrocode} % \end{macro} @@ -2625,7 +2625,7 @@ \cs_new:Npn \@@_parse_excl_error: { \__kernel_msg_expandable_error:nnnn - { kernel } { fp-missing } { = } { ~after~!. } + { fp } { missing } { = } { ~after~!. } } \cs_new:Npn \@@_parse_compare:NNNNNNN #1 { @@ -2729,7 +2729,7 @@ \@@_array_if_all_fp:nTF {#3} { #2 #3 @ } { - \@@_error:nffn { fp-bad-args } + \@@_error:nffn { bad-args } {#1} { \fp_to_tl:n { \s_@@_tuple \@@_tuple_chk:w {#3} ; } } { } @@ -2768,7 +2768,7 @@ } \cs_new:Npn \@@_parse_function_one_two_error_o:w #1#2#3#4 @ { - \@@_error:nffn { fp-bad-args } + \@@_error:nffn { bad-args } {#2} { \fp_to_tl:n { \s_@@_tuple \@@_tuple_chk:w {#4} ; } } { } @@ -2859,37 +2859,37 @@ % \subsection{Messages} % % \begin{macrocode} -\__kernel_msg_new:nnn { kernel } { fp-deprecated } +\__kernel_msg_new:nnn { fp } { deprecated } { '#1'~deprecated;~use~'#2' } -\__kernel_msg_new:nnn { kernel } { unknown-fp-word } +\__kernel_msg_new:nnn { fp } { unknown-fp-word } { Unknown~fp~word~#1. } -\__kernel_msg_new:nnn { kernel } { fp-missing } +\__kernel_msg_new:nnn { fp } { missing } { Missing~#1~inserted #2. } -\__kernel_msg_new:nnn { kernel } { fp-extra } +\__kernel_msg_new:nnn { fp } { extra } { Extra~#1~ignored. } -\__kernel_msg_new:nnn { kernel } { fp-early-end } +\__kernel_msg_new:nnn { fp } { early-end } { Premature~end~in~fp~expression. } -\__kernel_msg_new:nnn { kernel } { fp-after-e } +\__kernel_msg_new:nnn { fp } { after-e } { Cannot~use~#1 after~'e'. } -\__kernel_msg_new:nnn { kernel } { fp-missing-number } +\__kernel_msg_new:nnn { fp } { missing-number } { Missing~number~before~'#1'. } -\__kernel_msg_new:nnn { kernel } { fp-unknown-symbol } +\__kernel_msg_new:nnn { fp } { unknown-symbol } { Unknown~symbol~#1~ignored. } -\__kernel_msg_new:nnn { kernel } { fp-extra-comma } +\__kernel_msg_new:nnn { fp } { extra-comma } { Unexpected~comma~turned~to~nan~result. } -\__kernel_msg_new:nnn { kernel } { fp-no-arg } +\__kernel_msg_new:nnn { fp } { no-arg } { #1~got~no~argument;~used~nan. } -\__kernel_msg_new:nnn { kernel } { fp-multi-arg } +\__kernel_msg_new:nnn { fp } { multi-arg } { #1~got~more~than~one~argument;~used~nan. } -\__kernel_msg_new:nnn { kernel } { fp-num-args } +\__kernel_msg_new:nnn { fp } { num-args } { #1~expects~between~#2~and~#3~arguments. } -\__kernel_msg_new:nnn { kernel } { fp-bad-args } +\__kernel_msg_new:nnn { fp } { bad-args } { Arguments~in~#1#2~are~invalid. } -\__kernel_msg_new:nnn { kernel } { fp-infty-pi } +\__kernel_msg_new:nnn { fp } { infty-pi } { Math~command~#1 is~not~an~fp } \cs_if_exist:cT { @unexpandable@protect } { - \__kernel_msg_new:nnn { kernel } { fp-robust-cmd } + \__kernel_msg_new:nnn { fp } { robust-cmd } { Robust~command~#1 invalid~in~fp~expression! } } % \end{macrocode} diff --git a/macros/latex/contrib/l3kernel/l3fp-random.dtx b/macros/latex/contrib/l3kernel/l3fp-random.dtx index cf909120d9..a8c2f8403b 100644 --- a/macros/latex/contrib/l3kernel/l3fp-random.dtx +++ b/macros/latex/contrib/l3kernel/l3fp-random.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -334,7 +334,7 @@ } { \__kernel_msg_expandable_error:nnnnn - { kernel } { fp-num-args } { rand() } { 0 } { 0 } + { fp } { num-args } { rand() } { 0 } { 0 } \exp_after:wN \c_nan_fp } } diff --git a/macros/latex/contrib/l3kernel/l3fp-round.dtx b/macros/latex/contrib/l3kernel/l3fp-round.dtx index c67804df2b..e61833552b 100644 --- a/macros/latex/contrib/l3kernel/l3fp-round.dtx +++ b/macros/latex/contrib/l3kernel/l3fp-round.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -410,9 +410,9 @@ \cs_new:Npn \@@_round_no_arg_o:Nw #1 { \cs_if_eq:NNTF #1 \@@_round_to_nearest:NNN - { \@@_error:nnnn { fp-num-args } { round () } { 1 } { 3 } } + { \@@_error:nnnn { num-args } { round () } { 1 } { 3 } } { - \@@_error:nffn { fp-num-args } + \@@_error:nffn { num-args } { \@@_round_name_from_cs:N #1 () } { 1 } { 2 } } \exp_after:wN \c_nan_fp @@ -443,12 +443,12 @@ #2 ; #3 ; } { - \@@_error:nnnn { fp-num-args } { round () } { 1 } { 3 } + \@@_error:nnnn { num-args } { round () } { 1 } { 3 } \exp_after:wN \c_nan_fp } } { - \@@_error:nffn { fp-num-args } + \@@_error:nffn { num-args } { \@@_round_name_from_cs:N #1 () } { 1 } { 2 } \exp_after:wN \c_nan_fp } diff --git a/macros/latex/contrib/l3kernel/l3fp-traps.dtx b/macros/latex/contrib/l3kernel/l3fp-traps.dtx index c9d3d19deb..faba0ea08a 100644 --- a/macros/latex/contrib/l3kernel/l3fp-traps.dtx +++ b/macros/latex/contrib/l3kernel/l3fp-traps.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % \maketitle % % \begin{documentation} @@ -70,7 +70,7 @@ % % \subsection{Flags} % -% \begin{variable} +% \begin{variable}[module = fp] % { % flag fp_invalid_operation, % flag fp_division_by_zero, @@ -127,12 +127,12 @@ { invalid_operation , division_by_zero , overflow , underflow } {#1} { - \__kernel_msg_error:nnxx { kernel } + \__kernel_msg_error:nnxx { fp } { unknown-fpu-trap-type } {#1} {#2} } { \__kernel_msg_error:nnx - { kernel } { unknown-fpu-exception } {#1} + { fp } { unknown-fpu-exception } {#1} } } } @@ -164,7 +164,7 @@ { \cs_set:Npn \@@_invalid_operation:nnw ##1##2##3; } { #1 - \@@_error:nnfn { fp-invalid } {##2} { \fp_to_tl:n { ##3; } } { } + \@@_error:nnfn { invalid } {##2} { \fp_to_tl:n { ##3; } } { } \flag_raise_if_clear:n { fp_invalid_operation } ##1 } @@ -172,7 +172,7 @@ { \cs_set:Npn \@@_invalid_operation_o:Nww ##1##2; ##3; } { #1 - \@@_error:nffn { fp-invalid-ii } + \@@_error:nffn { invalid-ii } { \fp_to_tl:n { ##2; } } { \fp_to_tl:n { ##3; } } {##1} \flag_raise_if_clear:n { fp_invalid_operation } \exp_after:wN \c_nan_fp @@ -181,7 +181,7 @@ { \cs_set:Npn \@@_invalid_operation_tl_o:ff ##1##2 } { #1 - \@@_error:nffn { fp-invalid } {##1} {##2} { } + \@@_error:nffn { invalid } {##1} {##2} { } \flag_raise_if_clear:n { fp_invalid_operation } \exp_after:wN \c_nan_fp } @@ -214,7 +214,7 @@ { \cs_set:Npn \@@_division_by_zero_o:Nnw ##1##2##3; } { #1 - \@@_error:nnfn { fp-zero-div } {##2} { \fp_to_tl:n { ##3; } } { } + \@@_error:nnfn { zero-div } {##2} { \fp_to_tl:n { ##3; } } { } \flag_raise_if_clear:n { fp_division_by_zero } \exp_after:wN ##1 } @@ -222,7 +222,7 @@ { \cs_set:Npn \@@_division_by_zero_o:NNww ##1##2##3; ##4; } { #1 - \@@_error:nffn { fp-zero-div-ii } + \@@_error:nffn { zero-div-ii } { \fp_to_tl:n { ##3; } } { \fp_to_tl:n { ##4; } } {##2} \flag_raise_if_clear:n { fp_division_by_zero } \exp_after:wN ##1 @@ -283,7 +283,7 @@ { #1 \@@_error:nffn - { fp-flow \if_meaning:w 1 ##1 -to \fi: } + { flow \if_meaning:w 1 ##1 -to \fi: } { \fp_to_tl:n { \s_@@ \@@_chk:w ##1##2##3; } } { \token_if_eq_meaning:NNF 0 ##2 { - } #4 } {#2} @@ -338,7 +338,7 @@ % \begin{macro}[EXP]{\@@_error:nnnn, \@@_error:nnfn, \@@_error:nffn, \@@_error:nfff} % \begin{macrocode} \cs_new:Npn \@@_error:nnnn - { \__kernel_msg_expandable_error:nnnnn { kernel } } + { \__kernel_msg_expandable_error:nnnnn { fp } } \cs_generate_variant:Nn \@@_error:nnnn { nnf, nff , nfff } % \end{macrocode} % \end{macro} @@ -347,7 +347,7 @@ % % Some messages. % \begin{macrocode} -\__kernel_msg_new:nnnn { kernel } { unknown-fpu-exception } +\__kernel_msg_new:nnnn { fp } { unknown-fpu-exception } { The~FPU~exception~'#1'~is~not~known:~ that~trap~will~never~be~triggered. @@ -362,7 +362,7 @@ * ~ underflow } } -\__kernel_msg_new:nnnn { kernel } { unknown-fpu-trap-type } +\__kernel_msg_new:nnnn { fp } { unknown-fpu-trap-type } { The~FPU~trap~type~'#2'~is~not~known. } { The~trap~type~must~be~one~of \\ @@ -373,19 +373,19 @@ * ~ none } } -\__kernel_msg_new:nnn { kernel } { fp-flow } +\__kernel_msg_new:nnn { fp } { flow } { An ~ #3 ~ occurred. } -\__kernel_msg_new:nnn { kernel } { fp-flow-to } +\__kernel_msg_new:nnn { fp } { flow-to } { #1 ~ #3 ed ~ to ~ #2 . } -\__kernel_msg_new:nnn { kernel } { fp-zero-div } +\__kernel_msg_new:nnn { fp } { zero-div } { Division~by~zero~in~ #1 (#2) } -\__kernel_msg_new:nnn { kernel } { fp-zero-div-ii } +\__kernel_msg_new:nnn { fp } { zero-div-ii } { Division~by~zero~in~ (#1) #3 (#2) } -\__kernel_msg_new:nnn { kernel } { fp-invalid } +\__kernel_msg_new:nnn { fp } { invalid } { Invalid~operation~ #1 (#2) } -\__kernel_msg_new:nnn { kernel } { fp-invalid-ii } +\__kernel_msg_new:nnn { fp } { invalid-ii } { Invalid~operation~ (#1) #3 (#2) } -\__kernel_msg_new:nnn { kernel } { fp-unknown-type } +\__kernel_msg_new:nnn { fp } { unknown-type } { Unknown~type~for~'#1' } % \end{macrocode} % diff --git a/macros/latex/contrib/l3kernel/l3fp-trig.dtx b/macros/latex/contrib/l3kernel/l3fp-trig.dtx index 55460c8a8f..7ca054e7d2 100644 --- a/macros/latex/contrib/l3kernel/l3fp-trig.dtx +++ b/macros/latex/contrib/l3kernel/l3fp-trig.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3fp.dtx b/macros/latex/contrib/l3kernel/l3fp.dtx index 476e7a8789..e56560e88d 100644 --- a/macros/latex/contrib/l3kernel/l3fp.dtx +++ b/macros/latex/contrib/l3kernel/l3fp.dtx @@ -49,7 +49,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -650,29 +650,29 @@ % % \section{Some useful constants, and scratch variables} % -% \begin{variable}[added = 2012-05-08]{\c_zero_fp, \c_minus_zero_fp} +% \begin{variable}[added = 2012-05-08, module = fp]{\c_zero_fp, \c_minus_zero_fp} % Zero, with either sign. % \end{variable} % -% \begin{variable}[added = 2012-05-08]{\c_one_fp} +% \begin{variable}[added = 2012-05-08, module = fp]{\c_one_fp} % One as an \texttt{fp}: useful for comparisons in some places. % \end{variable} % -% \begin{variable}[added = 2012-05-08]{\c_inf_fp, \c_minus_inf_fp} +% \begin{variable}[added = 2012-05-08, module = fp]{\c_inf_fp, \c_minus_inf_fp} % Infinity, with either sign. These can be input directly in a % floating point expression as \texttt{inf} and \texttt{-inf}. % \end{variable} % -% \begin{variable}[updated = 2012-05-08]{\c_e_fp} +% \begin{variable}[updated = 2012-05-08, module = fp]{\c_e_fp} % The value of the base of the natural logarithm, $\mathrm{e} = \exp(1)$. % \end{variable} % -% \begin{variable}[updated = 2013-11-17]{\c_pi_fp} +% \begin{variable}[updated = 2013-11-17, module = fp]{\c_pi_fp} % The value of~$\pi$. This can be input directly in a floating point % expression as~\texttt{pi}. % \end{variable} % -% \begin{variable}[added = 2012-05-08, updated = 2013-11-17] +% \begin{variable}[added = 2012-05-08, updated = 2013-11-17, module = fp] % {\c_one_degree_fp} % The value of $1^{\circ}$ in radians. Multiply an angle given in % degrees by this value to obtain a result in radians. Note that @@ -681,14 +681,14 @@ % can be accessed as \texttt{deg}. % \end{variable} % -% \begin{variable}{\l_tmpa_fp, \l_tmpb_fp} +% \begin{variable}[module = fp]{\l_tmpa_fp, \l_tmpb_fp} % Scratch floating points for local assignment. These are never used by % the kernel code, and so are safe for use with any \LaTeX3-defined % function. However, they may be overwritten by other non-kernel % code and so should only be used for short-term storage. % \end{variable} % -% \begin{variable}{\g_tmpa_fp, \g_tmpb_fp} +% \begin{variable}[module = fp]{\g_tmpa_fp, \g_tmpb_fp} % Scratch floating points for global assignment. These are never used by % the kernel code, and so are safe for use with any \LaTeX3-defined % function. However, they may be overwritten by other non-kernel @@ -757,7 +757,7 @@ % \emph{This function is experimental, and may be altered or removed.} % \end{function} % -% \begin{variable} +% \begin{variable}[module = fp] % { % flag fp_overflow, % flag fp_underflow, @@ -769,7 +769,7 @@ % % \section{Viewing floating points} % -% \begin{function}[added = 2012-05-08, updated = 2015-08-07, +% \begin{function}[added = 2012-05-08, updated = 2021-04-29, % tested = m3fp002]{\fp_show:N, \fp_show:c, \fp_show:n} % \begin{syntax} % \cs{fp_show:N} \meta{fp~var} @@ -779,7 +779,7 @@ % result in the terminal. % \end{function} % -% \begin{function}[added = 2014-08-22, updated = 2015-08-07] +% \begin{function}[added = 2014-08-22, updated = 2021-04-29] % {\fp_log:N, \fp_log:c, \fp_log:n} % \begin{syntax} % \cs{fp_log:N} \meta{fp~var} @@ -843,7 +843,7 @@ % valid floating point numbers. Note that the latter could be mistaken % with the difference of \enquote{\texttt{e}} and $1$. To avoid % confusions, the base of natural logarithms cannot be input as |e| and -% should be input as \texttt{exp(1)} or \cs{c_e_fp} (which is faster). +% should be input as \texttt{exp(1)} or \cs[module = fp]{c_e_fp} (which is faster). % % Special numbers are input as follows: % \begin{itemize} @@ -904,7 +904,7 @@ % specified, providing a tuple as an argument of any other operation % yields the \enquote{invalid operation} exception and a \nan{} result. % -% \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} @@ -1350,16 +1350,16 @@ % % \begin{variable}[tested = m3fp-parse001]{inf, nan} % The special values $+\infty$, $-\infty$, and \nan{} are represented -% as \texttt{inf}, \texttt{-inf} and \texttt{nan} (see \cs{c_inf_fp}, -% \cs{c_minus_inf_fp} and \cs{c_nan_fp}). +% as \texttt{inf}, \texttt{-inf} and \texttt{nan} (see \cs[module = fp]{c_inf_fp}, +% \cs[module = fp]{c_minus_inf_fp} and \cs[module = fp]{c_nan_fp}). % \end{variable} % % \begin{variable}[tested = m3fp-parse001]{pi} -% The value of $\pi$ (see \cs{c_pi_fp}). +% The value of $\pi$ (see \cs[module = fp]{c_pi_fp}). % \end{variable} % % \begin{variable}[tested = m3fp-parse001]{deg} -% The value of $1^{\circ}$ in radians (see \cs{c_one_degree_fp}). +% The value of $1^{\circ}$ in radians (see \cs[module = fp]{c_one_degree_fp}). % \end{variable} % % \begin{variable}[tested = m3fp-parse001] @@ -1487,8 +1487,8 @@ % hard-code the logarithms of $44$ small integers instead of $9$. % \item Improve notations in the explanations of the division % algorithm (\pkg{l3fp-basics}). -% \item Understand and document \cs{__fp_basics_pack_weird_low:NNNNw} -% and \cs{__fp_basics_pack_weird_high:NNNNNNNNw} better. Move the +% \item Understand and document \cs[no-index]{__fp_basics_pack_weird_low:NNNNw} +% and \cs[no-index]{__fp_basics_pack_weird_high:NNNNNNNNw} better. Move the % other \texttt{basics_pack} auxiliaries to \pkg{l3fp-aux} under a % better name. % \item Find out if underflow can really occur for trigonometric diff --git a/macros/latex/contrib/l3kernel/l3fparray.dtx b/macros/latex/contrib/l3kernel/l3fparray.dtx index 9d4ca672ad..7a110305cb 100644 --- a/macros/latex/contrib/l3kernel/l3fparray.dtx +++ b/macros/latex/contrib/l3kernel/l3fparray.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -106,7 +106,6 @@ % \meta{position} is not between $1$ and the \cs{fparray_count:N}, an % error occurs. % \end{function} - % % \end{documentation} % @@ -263,7 +262,7 @@ } \cs_new_protected:Npn \@@_array_gset_recover:Nw #1#2 ; { - \@@_error:nffn { fp-unknown-type } { \tl_to_str:n { #2 ; } } { } { } + \@@_error:nffn { unknown-type } { \tl_to_str:n { #2 ; } } { } { } \exp_after:wN #1 \c_nan_fp } \cs_new_protected:Npn \@@_array_gset:w \s_@@ \@@_chk:w #1#2 diff --git a/macros/latex/contrib/l3kernel/l3int.dtx b/macros/latex/contrib/l3kernel/l3int.dtx index 85da3a199e..54f36dbab5 100644 --- a/macros/latex/contrib/l3kernel/l3int.dtx +++ b/macros/latex/contrib/l3kernel/l3int.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -891,15 +891,15 @@ % literal numbers. % \end{variable} % -% \begin{variable}{\c_max_int} +% \begin{variable}[module = int]{\c_max_int} % The maximum value that can be stored as an integer. % \end{variable} % -% \begin{variable}{\c_max_register_int} +% \begin{variable}[module = int]{\c_max_register_int} % Maximum number of registers. % \end{variable} % -% \begin{variable}{\c_max_char_int} +% \begin{variable}[module = int]{\c_max_char_int} % Maximum character code completely supported by the engine. % \end{variable} % @@ -1282,6 +1282,7 @@ % \end{macro} % % \begin{macro}{\int_const:Nn, \int_const:cn} +% \begin{macro}{\@@_const:nN} % \begin{macro}{\@@_constdef:Nw} % \begin{variable}{\c_@@_max_constdef_int} % \UnitTested @@ -1293,24 +1294,26 @@ % enabled) this runs some checks that constants would fail. % \begin{macrocode} \cs_new_protected:Npn \int_const:Nn #1#2 + { \exp_args:Ne \@@_const:nN { \int_eval:n {#2} } #1 } +\cs_new_protected:Npn \@@_const:nN #1#2 { - \int_compare:nNnTF {#2} < \c_zero_int + \int_compare:nNnTF {#1} < \c_zero_int { - \int_new:N #1 + \int_new:N #2 \tex_global:D } { - \int_compare:nNnTF {#2} > \c_@@_max_constdef_int + \int_compare:nNnTF {#1} > \c_@@_max_constdef_int { - \int_new:N #1 + \int_new:N #2 \tex_global:D } { - \__kernel_chk_if_free_cs:N #1 + \__kernel_chk_if_free_cs:N #2 \tex_global:D \@@_constdef:Nw } } - #1 = \@@_eval:w #2 \@@_eval_end: + #2 = \@@_eval:w #1 \@@_eval_end: } \cs_generate_variant:Nn \int_const:Nn { c } \if_int_odd:w 0 @@ -1329,6 +1332,7 @@ % \end{variable} % \end{macro} % \end{macro} +% \end{macro} % % \begin{macro}{\int_zero:N, \int_zero:c} % \UnitTested @@ -1671,7 +1675,7 @@ % \begin{macro}{\@@_case:nw, \@@_case_end:nw} % For integer cases, the first task to fully expand the check % condition. The over all idea is then much the same as for -% \cs{tl_case:nn(TF)} as described in \pkg{l3tl}. +% \cs{tl_case:nnTF} as described in \pkg{l3tl}. % \begin{macrocode} \cs_new:Npn \int_case:nnTF #1 { diff --git a/macros/latex/contrib/l3kernel/l3intarray.dtx b/macros/latex/contrib/l3kernel/l3intarray.dtx index dc7b7fdee8..d0be26dc67 100644 --- a/macros/latex/contrib/l3kernel/l3intarray.dtx +++ b/macros/latex/contrib/l3kernel/l3intarray.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -509,15 +509,15 @@ % \begin{macro}{\intarray_show:N, \intarray_show:c, \intarray_log:N, \intarray_log:c} % Convert the list to a comma list (with spaces after each comma) % \begin{macrocode} -\cs_new_protected:Npn \intarray_show:N { \@@_show:NN \msg_show:nnxxxx } +\cs_new_protected:Npn \intarray_show:N { \@@_show:NN \__kernel_msg_show:nnxxxx } \cs_generate_variant:Nn \intarray_show:N { c } -\cs_new_protected:Npn \intarray_log:N { \@@_show:NN \msg_log:nnxxxx } +\cs_new_protected:Npn \intarray_log:N { \@@_show:NN \__kernel_msg_log:nnxxxx } \cs_generate_variant:Nn \intarray_log:N { c } \cs_new_protected:Npn \@@_show:NN #1#2 { \__kernel_chk_defined:NT #2 { - #1 { LaTeX/kernel } { show-intarray } + #1 { intarray } { show } { \token_to_str:N #2 } { \intarray_count:N #2 } { >~ \@@_to_clist:Nn #2 { , ~ } } diff --git a/macros/latex/contrib/l3kernel/l3kernel-functions.dtx b/macros/latex/contrib/l3kernel/l3kernel-functions.dtx index f0fd422707..c5586a9a0d 100644 --- a/macros/latex/contrib/l3kernel/l3kernel-functions.dtx +++ b/macros/latex/contrib/l3kernel/l3kernel-functions.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -53,7 +53,9 @@ % % \begin{implementation} % -% \section{Internal kernel functions} +% \section{\pkg{l3kernel-functions}: kernel-reserved functions} +% +% \subsection{Internal kernel functions} % % \begin{function}{\__kernel_chk_cs_exist:N, \__kernel_chk_cs_exist:c} % \begin{syntax} @@ -90,6 +92,19 @@ % purposes. % \end{function} % +% \begin{function}{\__kernel_chk_tl_type:NnnT} +% \begin{syntax} +% \cs{__kernel_chk_tl_type:NnnT} \meta{control sequence} \Arg{specific type} \\ +% \ \ \Arg{reconstruction} \Arg{true code} +% \end{syntax} +% Helper to test that the \meta{control sequence} is a variable of the +% given \meta{specific type} of token list. Produces suitable error +% messages if the \meta{control sequence} does not exist, or if it is +% not a token list variable at all, or if the \meta{control sequence} +% differs from the result of |x|-expanding \meta{reconstruction}. If +% all of these tests succeed then the \meta{true code} is run. +% \end{function} +% % \begin{function}{\__kernel_cs_parm_from_arg_count:nnF} % \begin{syntax} % \cs{__kernel_cs_parm_from_arg_count:nnF} \Arg{follow-on} \Arg{args} \Arg{false code} @@ -147,16 +162,19 @@ % \begin{syntax} % \cs{__kernel_file_missing:n} \Arg{name} % \end{syntax} -% Expands the \meta{name} as per \cs{__kernel_file_name_sanitize:nN} then +% Expands the \meta{name} as per \cs{__kernel_file_name_sanitize:n} then % produces an error message indicating that this file was not found. % \end{function} % -% \begin{function}{\__kernel_file_name_sanitize:nN} +% \begin{function}[EXP,updated = 2021-04-17]{\__kernel_file_name_sanitize:n} % \begin{syntax} -% \cs{__kernel_file_name_sanitize:nN} \Arg{name} \meta{str var} +% \cs{__kernel_file_name_sanitize:n} \Arg{name} % \end{syntax} -% For converting a \meta{name} to a string where active characters are treated -% as strings. +% Expands the file name using a \tn{csname}-based approach, and +% relies on active characters (for example from UTF-8 characters) +% being properly set up to expand to a expansion-safe version using +% \cs{ifcsname}. This is less conservative than the token-by-token +% approach used before, but it is much faster. % \end{function} % % \begin{function}{\__kernel_file_input_push:n, \__kernel_file_input_pop:} @@ -511,7 +529,7 @@ % The function \cs{__kernel_quark_new_conditional:Nn} can define $2$ % different types of quark conditionals. Which one is defined depends % on the \meta{arg spec}, which \emph{must} be one of the following -% options, modeled after \cs[no-index]{quark_if_nil:(N|n)(TF)}. +% options, modeled after \cs[index=quark_if_nil:NTF]{quark_if_nil:(N|n)(TF)}. % \begin{description} % \def\makelabel#1{\texttt{#1}} % \item[n] defines \cs[no-index]{__\meta{namespace}_quark_if_\meta{name}:n(TF)} such that it @@ -610,7 +628,7 @@ % \meta{tl~var} and \meta{tokens}. % \end{function} % -% \section{Kernel backend functions} +% \subsection{Kernel backend functions} % % These functions are required to pass information to the backend. The nature % of these means that they are defined only when the relevant backend is in diff --git a/macros/latex/contrib/l3kernel/l3keys.dtx b/macros/latex/contrib/l3kernel/l3keys.dtx index 4c2b01526a..cf04ec82d2 100644 --- a/macros/latex/contrib/l3kernel/l3keys.dtx +++ b/macros/latex/contrib/l3kernel/l3keys.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -1223,7 +1223,7 @@ #2 \s_@@_mark \@@_clean_up_active:w { \__kernel_msg_expandable_error:nn - { kernel } { misplaced-equals-sign } + { keyval } { misplaced-equals-sign } \@@_loop_other:nnw } \cs_new:Npn \@@_misplaced_equal_in_split_error:w @@ -1231,7 +1231,7 @@ ##3 \s_@@_mark ##4 ##5 { \__kernel_msg_expandable_error:nn - { kernel } { misplaced-equals-sign } + { keyval } { misplaced-equals-sign } \@@_loop_other:nnw } % \end{macrocode} @@ -1314,16 +1314,16 @@ \cs_new:Npn \@@_blank_key_error:w \s_@@_mark \s_@@_stop \exp_not:n #1 { \__kernel_msg_expandable_error:nn - { kernel } { blank-key-name } + { keyval } { blank-key-name } } % \end{macrocode} % \end{macro} % % Two messages for the low level parsing system. % \begin{macrocode} -\__kernel_msg_new:nnn { kernel } { misplaced-equals-sign } +\__kernel_msg_new:nnn { keyval } { misplaced-equals-sign } { Misplaced~equals~sign~in~key-value~input~\msg_line_context: } -\__kernel_msg_new:nnn { kernel } { blank-key-name } +\__kernel_msg_new:nnn { keyval } { blank-key-name } { Blank~key~name~in~key-value~input~\msg_line_context: } % \end{macrocode} % @@ -1613,7 +1613,7 @@ { \str_if_empty:NF \l_@@_property_str { - \__kernel_msg_error:nnxx { kernel } { key-property-unknown } + \__kernel_msg_error:nnxx { keys } { property-unknown } \l_@@_property_str \l_keys_path_str } } @@ -1676,7 +1676,7 @@ #1 \s_@@_nil #2 \@@_property_find_err:w { \str_clear:N \l__keys_property_str - \__kernel_msg_error:nnn { kernel } { key-no-property } {#1} + \__kernel_msg_error:nnn { keys } { no-property } {#1} } % \end{macrocode} % \end{macro} @@ -1698,7 +1698,7 @@ \l_@@_property_str \s_@@_stop { \use:c { \c_@@_props_root_str \l_@@_property_str } } { - \__kernel_msg_error:nnxx { kernel } { key-property-requires-value } + \__kernel_msg_error:nnxx { keys } { property-requires-value } \l_@@_property_str \l_keys_path_str } } @@ -1728,7 +1728,7 @@ { \exp_not:c { bool_ #2 set_false:N } \exp_not:N #1 } \@@_cmd_set:nn { \l_keys_path_str / unknown } { - \__kernel_msg_error:nnx { kernel } { boolean-values-only } + \__kernel_msg_error:nnx { keys } { boolean-values-only } \l_keys_key_str } \@@_default_set:n { true } @@ -1750,7 +1750,7 @@ { \exp_not:c { bool_ #2 set_true:N } \exp_not:N #1 } \@@_cmd_set:nn { \l_keys_path_str / unknown } { - \__kernel_msg_error:nnx { kernel } { boolean-values-only } + \__kernel_msg_error:nnx { keys } { boolean-values-only } \l_keys_key_str } \@@_default_set:n { true } @@ -1779,7 +1779,7 @@ { \c_@@_type_root_str \@@_parent:o \l_keys_path_str } { choice } { - \__kernel_msg_error:nnxx { kernel } { nested-choice-key } + \__kernel_msg_error:nnxx { keys } { nested-choice-key } \l_keys_path_tl { \@@_parent:o \l_keys_path_str } } { \@@_choice_make_aux:N #1 } @@ -1793,7 +1793,7 @@ \@@_cmd_set:nn \l_keys_path_str { #1 {##1} } \@@_cmd_set:nn { \l_keys_path_str / unknown } { - \__kernel_msg_error:nnxx { kernel } { key-choice-unknown } + \__kernel_msg_error:nnxx { keys } { choice-unknown } \l_keys_path_str {##1} } } @@ -2017,8 +2017,8 @@ } } { - \__kernel_msg_error:nnx { kernel } - { key-property-boolean-values-only } + \__kernel_msg_error:nnx { keys } + { property-boolean-values-only } { .value_ #1 :n } } } @@ -2026,7 +2026,7 @@ { \bool_if:NF \l_@@_no_value_bool { - \__kernel_msg_error:nnxx { kernel } { value-forbidden } + \__kernel_msg_error:nnxx { keys } { value-forbidden } \l_keys_path_str \l_keys_value_tl \use_none:nnn } @@ -2035,7 +2035,7 @@ { \bool_if:NT \l_@@_no_value_bool { - \__kernel_msg_error:nnx { kernel } { value-required } + \__kernel_msg_error:nnx { keys } { value-required } \l_keys_path_str \use_none:nnn } @@ -2875,7 +2875,7 @@ { \c_@@_code_root_str \l_@@_module_str / unknown } { \@@_execute:no { \l_@@_module_str / unknown } \l_keys_value_tl } { - \__kernel_msg_error:nnxx { kernel } { key-unknown } + \__kernel_msg_error:nnxx { keys } { unknown } \l_keys_path_str \l_@@_module_str } } @@ -2948,7 +2948,7 @@ { \tl_if_blank:nF {##1} { - \__kernel_msg_error:nnxx { kernel } { bad-relative-key-path } + \__kernel_msg_error:nnxx { keys } { bad-relative-key-path } \l_keys_path_str \l_@@_relative_tl } @@ -3119,12 +3119,12 @@ % To show a key, show its code using a message. % \begin{macrocode} \cs_new_protected:Npn \keys_show:nn - { \@@_show:Nnn \msg_show:nnxxxx } + { \@@_show:Nnn \__kernel_msg_show:nnxxxx } \cs_new_protected:Npn \keys_log:nn - { \@@_show:Nnn \msg_log:nnxxxx } + { \@@_show:Nnn \__kernel_msg_log:nnxxxx } \cs_new_protected:Npn \@@_show:Nnn #1#2#3 { - #1 { LaTeX / kernel } { show-key } + #1 { keys } { show-key } { \@@_trim_spaces:n { #2 / #3 } } { \keys_if_exist:nnT {#2} {#3} @@ -3148,43 +3148,43 @@ % % For when there is a need to complain. % \begin{macrocode} -\__kernel_msg_new:nnnn { kernel } { bad-relative-key-path } +\__kernel_msg_new:nnnn { keys } { bad-relative-key-path } { The~key~'#1'~is~not~inside~the~'#2'~path. } { The~key~'#1'~cannot~be~expressed~relative~to~path~'#2'. } -\__kernel_msg_new:nnnn { kernel } { boolean-values-only } +\__kernel_msg_new:nnnn { keys } { boolean-values-only } { Key~'#1'~accepts~boolean~values~only. } { The~key~'#1'~only~accepts~the~values~'true'~and~'false'. } -\__kernel_msg_new:nnnn { kernel } { key-choice-unknown } +\__kernel_msg_new:nnnn { keys } { choice-unknown } { Key~'#1'~accepts~only~a~fixed~set~of~choices. } { The~key~'#1'~only~accepts~predefined~values,~ and~'#2'~is~not~one~of~these. } -\__kernel_msg_new:nnnn { kernel } { key-unknown } +\__kernel_msg_new:nnnn { keys } { unknown } { The~key~'#1'~is~unknown~and~is~being~ignored. } { The~module~'#2'~does~not~have~a~key~called~'#1'.\\ Check~that~you~have~spelled~the~key~name~correctly. } -\__kernel_msg_new:nnnn { kernel } { nested-choice-key } +\__kernel_msg_new:nnnn { keys } { nested-choice-key } { Attempt~to~define~'#1'~as~a~nested~choice~key. } { The~key~'#1'~cannot~be~defined~as~a~choice~as~the~parent~key~'#2'~is~ itself~a~choice. } -\__kernel_msg_new:nnnn { kernel } { value-forbidden } +\__kernel_msg_new:nnnn { keys } { value-forbidden } { The~key~'#1'~does~not~take~a~value. } { The~key~'#1'~should~be~given~without~a~value.\\ The~value~'#2'~was~present:~the~key~will~be~ignored. } -\__kernel_msg_new:nnnn { kernel } { value-required } +\__kernel_msg_new:nnnn { keys } { value-required } { The~key~'#1'~requires~a~value. } { The~key~'#1'~must~have~a~value.\\ No~value~was~present:~the~key~will~be~ignored. } -\__kernel_msg_new:nnn { kernel } { show-key } +\__kernel_msg_new:nnn { keys } { show-key } { The~key~#1~ \tl_if_empty:nTF {#2} diff --git a/macros/latex/contrib/l3kernel/l3legacy.dtx b/macros/latex/contrib/l3kernel/l3legacy.dtx index b3c3627c6f..a843e28ffe 100644 --- a/macros/latex/contrib/l3kernel/l3legacy.dtx +++ b/macros/latex/contrib/l3kernel/l3legacy.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3luatex.dtx b/macros/latex/contrib/l3kernel/l3luatex.dtx index e4aed9498c..7e4f729ca5 100644 --- a/macros/latex/contrib/l3kernel/l3luatex.dtx +++ b/macros/latex/contrib/l3kernel/l3luatex.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -280,7 +280,7 @@ \cs_set:Npn #1 ##1 { \__kernel_msg_expandable_error:nnn - { kernel } { luatex-required } { #1 } + { luatex } { luatex-required } { #1 } } } \clist_map_inline:nn @@ -289,7 +289,7 @@ \cs_set_protected:Npn #1 ##1 { \__kernel_msg_error:nnn - { kernel } { luatex-required } { #1 } + { luatex } { luatex-required } { #1 } } } } @@ -301,7 +301,7 @@ % \subsection{Messages} % % \begin{macrocode} -\__kernel_msg_new:nnnn { kernel } { luatex-required } +\__kernel_msg_new:nnnn { luatex } { luatex-required } { LuaTeX~engine~not~in~use!~Ignoring~#1. } { The~feature~you~are~using~is~only~available~ diff --git a/macros/latex/contrib/l3kernel/l3msg.dtx b/macros/latex/contrib/l3kernel/l3msg.dtx index e51d93a30e..b408c181b2 100644 --- a/macros/latex/contrib/l3kernel/l3msg.dtx +++ b/macros/latex/contrib/l3kernel/l3msg.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -665,7 +665,7 @@ { \msg_if_exist:nnT {#1} {#2} { - \__kernel_msg_error:nnxx { kernel } { message-already-defined } + \__kernel_msg_error:nnxx { msg } { already-defined } {#1} {#2} } } @@ -1370,7 +1370,7 @@ \cs_new:Npn \@@_class_chk_exist:nT #1 { \cs_if_free:cTF { @@_ #1 _code:nnnnnn } - { \__kernel_msg_error:nnx { kernel } { message-class-unknown } {#1} } + { \__kernel_msg_error:nnx { msg } { class-unknown } {#1} } } % \end{macrocode} % \end{macro} @@ -1440,7 +1440,7 @@ \@@_use_redirect_name:n { #2 / #3 } } } - { \__kernel_msg_error:nnxx { kernel } { message-unknown } {#2} {#3} } + { \__kernel_msg_error:nnxx { msg } { unknown } {#2} {#3} } \cs_if_exist_use:N \conditionally@traceon } \cs_new_protected:Npn \@@_use_code: { } @@ -1591,7 +1591,7 @@ { \prop_put:cnn { l_@@_redirect_ #2 _prop } {#3} {#2} \__kernel_msg_warning:nnxxxx - { kernel } { message-redirect-loop } + { msg } { redirect-loop } { \seq_item:Nn \l_@@_class_loop_seq { 1 } } { \seq_item:Nn \l_@@_class_loop_seq { 2 } } {#3} @@ -1756,6 +1756,22 @@ % \end{macrocode} % \end{macro} % +% \begin{macro} +% { +% \__kernel_msg_log:nnnnnn, \__kernel_msg_log:nnxxxx, +% \__kernel_msg_show:nnnnnn, \__kernel_msg_show:nnxxxx +% } +% For showing messages. +% \begin{macrocode} +\cs_new_protected:Npn \__kernel_msg_log:nnnnnn #1 + { \msg_log:nnnnnn { LaTeX / #1 } } +\cs_generate_variant:Nn \__kernel_msg_log:nnnnnn { nnxxxx } +\cs_new_protected:Npn \__kernel_msg_show:nnnnnn #1 + { \msg_show:nnnnnn { LaTeX / #1 } } +\cs_generate_variant:Nn \__kernel_msg_show:nnnnnn { nnxxxx } +% \end{macrocode} +% \end{macro} +% % End the group to eliminate \cs{@@_kernel_class_new:nN}. % \begin{macrocode} \group_end: @@ -1764,7 +1780,7 @@ % Error messages needed to actually implement the message system % itself. % \begin{macrocode} -\__kernel_msg_new:nnnn { kernel } { message-already-defined } +\__kernel_msg_new:nnnn { msg } { already-defined } { Message~'#2'~for~module~'#1'~already~defined. } { \c_@@_coding_error_text_tl @@ -1772,7 +1788,7 @@ by~the~module~'#1':~this~message~already~exists. \c_@@_return_text_tl } -\__kernel_msg_new:nnnn { kernel } { message-unknown } +\__kernel_msg_new:nnnn { msg } { unknown } { Unknown~message~'#2'~for~module~'#1'. } { \c_@@_coding_error_text_tl @@ -1780,14 +1796,14 @@ by~the~module~'#1':~this~message~does~not~exist. \c_@@_return_text_tl } -\__kernel_msg_new:nnnn { kernel } { message-class-unknown } +\__kernel_msg_new:nnnn { msg } { class-unknown } { Unknown~message~class~'#1'. } { LaTeX~has~been~asked~to~redirect~messages~to~a~class~'#1':\\ this~was~never~defined. \c_@@_return_text_tl } -\__kernel_msg_new:nnnn { kernel } { message-redirect-loop } +\__kernel_msg_new:nnnn { msg } { redirect-loop } { Message~redirection~loop~caused~by~ {#1} ~=>~ {#2} \tl_if_empty:nF {#3} { ~for~module~' \use_none:n #3 ' } . @@ -1811,16 +1827,6 @@ #2~arguments.~ TeX~allows~between~0~and~9~arguments~for~a~single~function. } -\__kernel_msg_new:nnn { kernel } { char-active } - { Cannot~generate~active~chars. } -\__kernel_msg_new:nnn { kernel } { char-invalid-catcode } - { Invalid~catcode~for~char~generation. } -\__kernel_msg_new:nnn { kernel } { char-null-space } - { Cannot~generate~null~char~as~a~space. } -\__kernel_msg_new:nnn { kernel } { char-out-of-range } - { Charcode~requested~out~of~engine~range. } -\__kernel_msg_new:nnn { kernel } { char-space } - { Cannot~generate~space~chars. } \__kernel_msg_new:nnnn { kernel } { command-already-defined } { Control~sequence~#1~already~defined. } { @@ -1898,7 +1904,55 @@ LaTeX~has~been~asked~to~define~the~conditional~form~'#1'~of~ the~function~'#2',~but~only~'TF',~'T',~'F',~and~'p'~forms~exist. } -\__kernel_msg_new:nnnn { kernel } { key-no-property } +\__kernel_msg_new:nnnn { kernel } { variant-too-long } + { Variant~form~'#1'~longer~than~base~signature~of~'#2'. } + { + \c_@@_coding_error_text_tl + LaTeX~has~been~asked~to~create~a~variant~of~the~function~'#2'~ + with~a~signature~starting~with~'#1',~but~that~is~longer~than~ + the~signature~(part~after~the~colon)~of~'#2'. + } +\__kernel_msg_new:nnnn { kernel } { invalid-variant } + { Variant~form~'#1'~invalid~for~base~form~'#2'. } + { + \c_@@_coding_error_text_tl + LaTeX~has~been~asked~to~create~a~variant~of~the~function~'#2'~ + with~a~signature~starting~with~'#1',~but~cannot~change~an~argument~ + from~type~'#3'~to~type~'#4'. + } +\__kernel_msg_new:nnnn { kernel } { invalid-exp-args } + { Invalid~variant~specifier~'#1'~in~'#2'. } + { + \c_@@_coding_error_text_tl + LaTeX~has~been~asked~to~create~an~\iow_char:N\\exp_args:N...~ + function~with~signature~'N#2'~but~'#1'~is~not~a~valid~argument~ + specifier. + } +\__kernel_msg_new:nnn { kernel } { deprecated-variant } + { + Variant~form~'#1'~deprecated~for~base~form~'#2'.~ + One~should~not~change~an~argument~from~type~'#3'~to~type~'#4' + \str_case:nnF {#3} + { + { n } { :~use~a~'\token_if_eq_charcode:NNTF #4 c v V'~variant? } + { N } { :~base~form~only~accepts~a~single~token~argument. } + {#4} { :~base~form~is~already~a~variant. } + } { . } + } +\__kernel_msg_new:nnn { char } { active } + { Cannot~generate~active~chars. } +\__kernel_msg_new:nnn { char } { invalid-catcode } + { Invalid~catcode~for~char~generation. } +\__kernel_msg_new:nnn { char } { null-space } + { Cannot~generate~null~char~as~a~space. } +\__kernel_msg_new:nnn { char } { out-of-range } + { Charcode~requested~out~of~engine~range. } +\__kernel_msg_new:nnn { char } { space } + { Cannot~generate~space~chars. } +\__kernel_msg_new:nnnn { ior } { quote-in-shell } + { Quotes~in~shell~command~'#1'. } + { Shell~commands~cannot~contain~quotes~("). } +\__kernel_msg_new:nnnn { keys } { no-property } { No~property~given~in~definition~of~key~'#1'. } { \c_@@_coding_error_text_tl @@ -1907,30 +1961,27 @@ \iow_indent:n { #1 .<property> } \\ \\ LaTeX~did~not~find~a~'.'~to~indicate~the~start~of~a~property. } -\__kernel_msg_new:nnnn { kernel } { key-property-boolean-values-only } +\__kernel_msg_new:nnnn { keys } { property-boolean-values-only } { The~property~'#1'~accepts~boolean~values~only. } { \c_@@_coding_error_text_tl The~property~'#1'~only~accepts~the~values~'true'~and~'false'. } -\__kernel_msg_new:nnnn { kernel } { key-property-requires-value } +\__kernel_msg_new:nnnn { keys } { property-requires-value } { The~property~'#1'~requires~a~value. } { \c_@@_coding_error_text_tl LaTeX~was~asked~to~set~property~'#1'~for~key~'#2'.\\ No~value~was~given~for~the~property,~and~one~is~required. } -\__kernel_msg_new:nnnn { kernel } { key-property-unknown } +\__kernel_msg_new:nnnn { keys } { property-unknown } { The~key~property~'#1'~is~unknown. } { \c_@@_coding_error_text_tl LaTeX~has~been~asked~to~set~the~property~'#1'~for~key~'#2':~ this~property~is~not~defined. } -\__kernel_msg_new:nnnn { kernel } { quote-in-shell } - { Quotes~in~shell~command~'#1'. } - { Shell~commands~cannot~contain~quotes~("). } -\__kernel_msg_new:nnnn { kernel } { invalid-quark-function } +\__kernel_msg_new:nnnn { quark } { invalid-function } { Quark~test~function~'#1'~is~invalid. } { \c__msg_coding_error_text_tl @@ -1940,16 +1991,16 @@ { with~signature~'#2',~but~that~signature~ } is~not~valid. } -\__kernel_msg_new:nnn { kernel } { invalid-quark } +\__kernel_msg_new:nnn { quark } { invalid } { Invalid~quark~variable~'#1'. } -\__kernel_msg_new:nnnn { kernel } { scanmark-already-defined } +\__kernel_msg_new:nnnn { scanmark } { already-defined } { Scan~mark~#1~already~defined. } { \c_@@_coding_error_text_tl LaTeX~has~been~asked~to~create~a~new~scan~mark~'#1'~ but~this~name~has~already~been~used~for~a~scan~mark. } -\__kernel_msg_new:nnnn { kernel } { shuffle-too-large } +\__kernel_msg_new:nnnn { seq } { shuffle-too-large } { The~sequence~#1~is~too~long~to~be~shuffled~by~TeX. } { TeX~has~ \int_eval:n { \c_max_register_int + 1 } ~ @@ -1964,40 +2015,30 @@ LaTeX~has~been~asked~to~show~a~variable~#1,~but~this~has~not~ been~defined~yet. } -\__kernel_msg_new:nnnn { kernel } { variant-too-long } - { Variant~form~'#1'~longer~than~base~signature~of~'#2'. } - { - \c_@@_coding_error_text_tl - LaTeX~has~been~asked~to~create~a~variant~of~the~function~'#2'~ - with~a~signature~starting~with~'#1',~but~that~is~longer~than~ - the~signature~(part~after~the~colon)~of~'#2'. - } -\__kernel_msg_new:nnnn { kernel } { invalid-variant } - { Variant~form~'#1'~invalid~for~base~form~'#2'. } +\__kernel_msg_new:nnnn { kernel } { bad-type } + { Variable~'#1'~is~not~a~valid~#3. } { \c_@@_coding_error_text_tl - LaTeX~has~been~asked~to~create~a~variant~of~the~function~'#2'~ - with~a~signature~starting~with~'#1',~but~cannot~change~an~argument~ - from~type~'#3'~to~type~'#4'. + The~variable~'#1'~with~\tl_if_empty:nTF {#4} {meaning} {value}\\\\ + \iow_indent:n {#2}\\\\ + should~be~a~#3~variable,~but~ + \tl_if_empty:nTF {#4} + { it~is~not \str_if_eq:nnF {#3} { bool } { ~a~short~macro } . } + { + it~does~not~have~the~correct~ + \str_if_eq:nnTF {#2} {#4} + { category~codes. } + { internal~structure:\\\\\iow_indent:n {#4} } + } } -\__kernel_msg_new:nnnn { kernel } { invalid-exp-args } - { Invalid~variant~specifier~'#1'~in~'#2'. } +\__kernel_msg_new:nnnn { kernel } { non-clist } + { Variable~'#1'~is~not~a~valid~clist. } { \c_@@_coding_error_text_tl - LaTeX~has~been~asked~to~create~an~\iow_char:N\\exp_args:N...~ - function~with~signature~'N#2'~but~'#1'~is~not~a~valid~argument~ - specifier. - } -\__kernel_msg_new:nnn { kernel } { deprecated-variant } - { - Variant~form~'#1'~deprecated~for~base~form~'#2'.~ - One~should~not~change~an~argument~from~type~'#3'~to~type~'#4' - \str_case:nnF {#3} - { - { n } { :~use~a~'\token_if_eq_charcode:NNTF #4 c v V'~variant? } - { N } { :~base~form~only~accepts~a~single~token~argument. } - {#4} { :~base~form~is~already~a~variant. } - } { . } + The~variable~'#1'~with~value\\\\ + \iow_indent:n {#2}\\\\ + should~be~a~clist~variable,~but~it~includes~empty~or~blank~items~ + without~braces. } % \end{macrocode} % @@ -2006,7 +2047,7 @@ % \texttt{log-functions}, or on the contrary if debugging is turned off. % In format mode the error is somewhat different. % \begin{macrocode} -\__kernel_msg_new:nnnn { kernel } { enable-debug } +\__kernel_msg_new:nnnn { debug } { enable-debug } { To~use~'#1'~set~the~'enable-debug'~option. } { The~function~'#1'~will~be~ignored~because~it~can~only~work~if~ @@ -2024,13 +2065,13 @@ { Misused~\exp_end_continue_f:w or~:nw } \__kernel_msg_new:nnn { kernel } { bad-variable } { Erroneous~variable~#1 used! } -\__kernel_msg_new:nnn { kernel } { misused-sequence } +\__kernel_msg_new:nnn { seq } { misused } { A~sequence~was~misused. } -\__kernel_msg_new:nnn { kernel } { misused-prop } +\__kernel_msg_new:nnn { prop } { misused } { A~property~list~was~misused. } -\__kernel_msg_new:nnn { kernel } { negative-replication } +\__kernel_msg_new:nnn { prg } { negative-replication } { Negative~argument~for~\iow_char:N\\prg_replicate:nn. } -\__kernel_msg_new:nnn { kernel } { prop-keyval } +\__kernel_msg_new:nnn { prop } { prop-keyval } { Missing/extra~'='~in~'#1'~(in~'..._keyval:Nn') } \__kernel_msg_new:nnn { kernel } { unknown-comparison } { Relation~'#1'~unknown:~use~=,~<,~>,~==,~!=,~<=,~>=. } @@ -2045,23 +2086,23 @@ % % Messages used by the \enquote{\texttt{show}} functions. % \begin{macrocode} -\__kernel_msg_new:nnn { kernel } { show-clist } +\__kernel_msg_new:nnn { clist } { show } { The~comma~list~ \tl_if_empty:nF {#1} { #1 ~ } \tl_if_empty:nTF {#2} { is~empty \\>~ . } { contains~the~items~(without~outer~braces): #2 . } } -\__kernel_msg_new:nnn { kernel } { show-intarray } +\__kernel_msg_new:nnn { intarray } { show } { The~integer~array~#1~contains~#2~items: \\ #3 . } -\__kernel_msg_new:nnn { kernel } { show-prop } +\__kernel_msg_new:nnn { prop } { show } { The~property~list~#1~ \tl_if_empty:nTF {#2} { is~empty \\>~ . } { contains~the~pairs~(without~outer~braces): #2 . } } -\__kernel_msg_new:nnn { kernel } { show-seq } +\__kernel_msg_new:nnn { seq } { show } { The~sequence~#1~ \tl_if_empty:nTF {#2} @@ -2103,14 +2144,14 @@ % \begin{macro}{\@@_expandable_error:w} % In expansion only context, we cannot use the normal means of % reporting errors. Instead, we feed \TeX{} an undefined control -% sequence, \cs{LaTeX3 error:}. It is thus interrupted, and shows +% sequence, \cs[module = {}]{LaTeX3 error:}. It is thus interrupted, and shows % the context, which thanks to the odd-looking \cs{use:n} is % \begin{verbatim} % <argument> \LaTeX3 error: % The error message. % \end{verbatim} % In other words, \TeX{} is processing the argument of \cs{use:n}, -% which is \cs{LaTeX3 error:} \meta{error message}. +% which is \cs[module = {}]{LaTeX3 error:} \meta{error message}. % Then \cs{@@_expandable_error:w} cleans up. In fact, there % is an extra subtlety: if the user inserts tokens for error recovery, % they should be kept. Thus we also use an odd space character diff --git a/macros/latex/contrib/l3kernel/l3names.dtx b/macros/latex/contrib/l3kernel/l3names.dtx index bc7d4f1238..9a548a5391 100644 --- a/macros/latex/contrib/l3kernel/l3names.dtx +++ b/macros/latex/contrib/l3kernel/l3names.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -1191,6 +1191,10 @@ \@@_primitive:NN \omathcode \tex_omathcode:D \@@_primitive:NN \oradical \tex_oradical:D % \end{macrocode} +% Newer cross-engine primitives. +% \begin{macrocode} + \@@_primitive:NN \tracingstacklevels \tex_tracingstacklevels:D +% \end{macrocode} % End of the \enquote{just the names} part of the source. % \begin{macrocode} %</names|package> diff --git a/macros/latex/contrib/l3kernel/l3news.pdf b/macros/latex/contrib/l3kernel/l3news.pdf Binary files differindex 8a9da28149..2971e2c1ef 100644 --- a/macros/latex/contrib/l3kernel/l3news.pdf +++ b/macros/latex/contrib/l3kernel/l3news.pdf diff --git a/macros/latex/contrib/l3kernel/l3news01.pdf b/macros/latex/contrib/l3kernel/l3news01.pdf Binary files differindex aedb8f2b06..9d5e2fe3e6 100644 --- a/macros/latex/contrib/l3kernel/l3news01.pdf +++ b/macros/latex/contrib/l3kernel/l3news01.pdf diff --git a/macros/latex/contrib/l3kernel/l3news02.pdf b/macros/latex/contrib/l3kernel/l3news02.pdf Binary files differindex 36d2b99d43..0b8f621fc2 100644 --- a/macros/latex/contrib/l3kernel/l3news02.pdf +++ b/macros/latex/contrib/l3kernel/l3news02.pdf diff --git a/macros/latex/contrib/l3kernel/l3news03.pdf b/macros/latex/contrib/l3kernel/l3news03.pdf Binary files differindex ba772dcdc3..e90998a0bf 100644 --- a/macros/latex/contrib/l3kernel/l3news03.pdf +++ b/macros/latex/contrib/l3kernel/l3news03.pdf diff --git a/macros/latex/contrib/l3kernel/l3news04.pdf b/macros/latex/contrib/l3kernel/l3news04.pdf Binary files differindex 3f4fd28f64..5c8945b925 100644 --- a/macros/latex/contrib/l3kernel/l3news04.pdf +++ b/macros/latex/contrib/l3kernel/l3news04.pdf diff --git a/macros/latex/contrib/l3kernel/l3news05.pdf b/macros/latex/contrib/l3kernel/l3news05.pdf Binary files differindex 2dd69516d7..31af650bda 100644 --- a/macros/latex/contrib/l3kernel/l3news05.pdf +++ b/macros/latex/contrib/l3kernel/l3news05.pdf diff --git a/macros/latex/contrib/l3kernel/l3news06.pdf b/macros/latex/contrib/l3kernel/l3news06.pdf Binary files differindex d9b6818517..2d22191459 100644 --- a/macros/latex/contrib/l3kernel/l3news06.pdf +++ b/macros/latex/contrib/l3kernel/l3news06.pdf diff --git a/macros/latex/contrib/l3kernel/l3news07.pdf b/macros/latex/contrib/l3kernel/l3news07.pdf Binary files differindex 49696d137c..632e781463 100644 --- a/macros/latex/contrib/l3kernel/l3news07.pdf +++ b/macros/latex/contrib/l3kernel/l3news07.pdf diff --git a/macros/latex/contrib/l3kernel/l3news08.pdf b/macros/latex/contrib/l3kernel/l3news08.pdf Binary files differindex 83680088d1..d308888b50 100644 --- a/macros/latex/contrib/l3kernel/l3news08.pdf +++ b/macros/latex/contrib/l3kernel/l3news08.pdf diff --git a/macros/latex/contrib/l3kernel/l3news09.pdf b/macros/latex/contrib/l3kernel/l3news09.pdf Binary files differindex 8cb98e99b9..5f45b57bcf 100644 --- a/macros/latex/contrib/l3kernel/l3news09.pdf +++ b/macros/latex/contrib/l3kernel/l3news09.pdf diff --git a/macros/latex/contrib/l3kernel/l3news10.pdf b/macros/latex/contrib/l3kernel/l3news10.pdf Binary files differindex 532a383802..c2f0363c44 100644 --- a/macros/latex/contrib/l3kernel/l3news10.pdf +++ b/macros/latex/contrib/l3kernel/l3news10.pdf diff --git a/macros/latex/contrib/l3kernel/l3news11.pdf b/macros/latex/contrib/l3kernel/l3news11.pdf Binary files differindex 3b74f69402..aeefd9ab82 100644 --- a/macros/latex/contrib/l3kernel/l3news11.pdf +++ b/macros/latex/contrib/l3kernel/l3news11.pdf diff --git a/macros/latex/contrib/l3kernel/l3news12.pdf b/macros/latex/contrib/l3kernel/l3news12.pdf Binary files differindex c6701103dc..78d84d6f13 100644 --- a/macros/latex/contrib/l3kernel/l3news12.pdf +++ b/macros/latex/contrib/l3kernel/l3news12.pdf diff --git a/macros/latex/contrib/l3kernel/l3pdf.dtx b/macros/latex/contrib/l3kernel/l3pdf.dtx index 58f99438ac..747f46aa9f 100644 --- a/macros/latex/contrib/l3kernel/l3pdf.dtx +++ b/macros/latex/contrib/l3kernel/l3pdf.dtx @@ -43,15 +43,13 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % % \begin{documentation} % -% \section{\pkg{l3pdf} documentation} -% -% \subsection{Objects} +% \section{Objects} % % \begin{function}[added = 2021-02-10]{\pdf_object_new:nn} % \begin{syntax} @@ -113,8 +111,8 @@ % \item[\texttt{array}] A space-separated list of values % \item[\texttt{dict}] Key--value pairs in the form % \texttt{/\meta{key} \meta{value}} -% \item[\texttt{fstream}] Two brace groups: \meta{file name} and -% \meta{file content} +% \item[\texttt{fstream}] Two brace groups: \meta{attributes (dictionary)} +% and \meta{file name} % \item[\texttt{stream}] Two brace groups: \meta{attributes (dictionary)} % and \meta{stream contents} % \end{itemize} @@ -135,7 +133,7 @@ % Inserts the appropriate information to reference the \meta{pageobject}. % \end{function} % -% \subsection{Version} +% \section{Version} % % \begin{function}[pTF, EXP, added = 2021-02-10]{\pdf_version_compare:Nn} % \begin{syntax} @@ -156,7 +154,10 @@ % \meta{version} requested. % % This function may only be used up to the point where the PDF file is -% initialised. +% initialised. With dvips it sets \cs{pdf_version_major:} and \cs{pdf_version_minor:} +% and allows to compare the values with \cs{pdf_version_compare:Nn}, but the +% PDF version itself still has to be set with the command line option +% |-dCompatibilityLevel| of |ps2pdf|. % \end{function} % % \begin{function}[EXP, added = 2021-02-10] @@ -167,7 +168,7 @@ % Expands to the currently-active PDF version. % \end{function} % -% \subsection{Compression} +% \section{Compression} % % \begin{function}[added = 2021-02-10]{\pdf_uncompress:} % \begin{syntax} @@ -179,7 +180,7 @@ % initialised. % \end{function} % -% \subsection{Destinations} +% \section{Destinations} % % Destinations are the places a link jumped too. % Unlike the name may suggest they don't described diff --git a/macros/latex/contrib/l3kernel/l3prefixes.csv b/macros/latex/contrib/l3kernel/l3prefixes.csv index 321f9c1799..cf57038603 100644 --- a/macros/latex/contrib/l3kernel/l3prefixes.csv +++ b/macros/latex/contrib/l3kernel/l3prefixes.csv @@ -34,7 +34,8 @@ chk,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https:/ circumflex,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12, classics,classics,Eduardo C. Lourenço de Lima,,,,2013-03-16,2013-03-16, clist,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27, -cmd,ltcmd,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2021-01-20,2021-01-20, +cmd,latex2e,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2021-01-20,2021-03-03, +code,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2021-04-23,2021-04-23, codedoc,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,Somewhat experimental: may change coffin,"l3kernel,xcoffins",The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27, colon,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12, @@ -68,12 +69,13 @@ expl,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https: exsheets,exsheets,Clemens Niederberger,https://bitbucket.org/cgnieder/exsheets/,git@bitbucket.org:cgnieder/exsheets.git,https://bitbucket.org/cgnieder/exsheets/issues,2013-03-16,2013-03-16, extblx,biblatex-ext,Moritz Wemheuer,https://github.com/moewew/biblatex-ext/,https://github.com/moewew/biblatex-ext.git,https://github.com/moewew/biblatex-ext/issues,2020-02-09,2020-02-09, exwf,exwrapfig,Takuto Asakura,https://github.com/wtsnjp/exwrapfig,https://github.com/wtsnjp/exwrapfig.git,https://github.com/wtsnjp/exwrapfig/issues,2018-06-07,2018-06-07, +false,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2021-04-23,2021-04-23, fdu,fduthesis,Xiangdong Zeng,https://github.com/stone-zeng/fduthesis,https://github.com/stone-zeng/fduthesis.git,https://github.com/stone-zeng/fduthesis/issues,2018-06-14,2020-03-08, fdudoc,fduthesis,Xiangdong Zeng,https://github.com/stone-zeng/fduthesis,https://github.com/stone-zeng/fduthesis.git,https://github.com/stone-zeng/fduthesis/issues,2018-06-14,2020-03-08, fdulogo,fduthesis,Xiangdong Zeng,https://github.com/stone-zeng/fduthesis,https://github.com/stone-zeng/fduthesis.git,https://github.com/stone-zeng/fduthesis/issues,2018-06-14,2020-03-08, fi,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-28,2012-09-28, file,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27, -filehook,ltfilehook,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2020-10-01,2020-10-01, +filehook,latex2e,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2020-10-01,2021-03-03, flag,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2017-02-13, fltr,newlfm,Paul Thomson,,,,2013-01-29,2013-01-29, fmdug,dashundergaps,Frank Mittelbach,https://www.latex-project.org/,https://github.com/FrankMittelbach/fmitex.git,https://github.com/FrankMittelbach/fmitex/issues,2018-06-24,2018-06-24, @@ -95,16 +97,18 @@ hash,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https: hbox,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27, hcoffin,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-28,2012-09-28, hobete,hobete,Tobias Görlach,http://www.disk0s1.de,,,2012-11-07,2012-11-07, -hook,lthooks,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2019-06-03,2021-01-20, +hook,latex2e,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2019-06-03,2021-03-03, hyp,hyperref,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/hyperref.git,https://github.com/latex3/hyperref/issues,2020-11-27,2020-11-27, if,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27, inf,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12, +initex,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2021-04-23,2021-04-23, insert,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-28,2012-09-28, int,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27, intarray,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-04-06,2018-04-06, ior,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27, iow,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27, jiazhu,jiazhu,Qing Lee,https://github.com/CTeX-org/ctex-kit,https://github.com/CTeX-org/ctex-kit.git,https://github.com/CTeX-org/ctex-kit/issues,2020-05-17,2020-05-17, +job,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2021-04-23,2021-04-23, kernel,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27, keys,"l3kernel,l3keys2e",The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27, keyval,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27, @@ -116,6 +120,7 @@ lua,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https:/ luatex,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27, mark,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12, marks,l3kernel/xmarks,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2020-02-17,2020-02-17, +marks,latex2e,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2021-03-03,2021-03-03, math,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12, max,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12, mcrule,multicolrule,Karl Hagen,https://github.com/polysyllabic/multicolrule,https://github.com/polysyllabic/multicolrule.git,https://github.com/polysyllabic/multicolrule/issues,2018-12-24,2018-12-24, @@ -142,13 +147,19 @@ ocgbase,ocgx2,Alexander Grahn,,https://gitlab.com/agrahn/ocgx2,https://gitlab.co ocgxii,ocgx2,Alexander Grahn,,https://gitlab.com/agrahn/ocgx2,https://gitlab.com/agrahn/ocgx2/issues,2016-02-26,2020-04-15, one,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12, or,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-28,2012-09-28, +other,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2021-04-23,2021-04-23, overleaf,overleaf,Overleaf,https://www.overleaf.com/about,,support+tex-dev@overleaf.com,2020-05-27,2020-05-27, +para,latex2e,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2021-03-03,2021-03-03, parameter,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12, pbs,media9,Alexander Grahn,,https://gitlab.com/agrahn/media9,https://gitlab.com/agrahn/media9/issues,2016-02-26,2020-04-15, pdf,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2019-06-02,2019-06-02, +pdfannot,l3pdfmanagement,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2021-02-23,2021-02-23, +pdffile,l3pdfmanagement,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2021-02-23,2021-02-23, pdfmanagement,l3pdfmanagement,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2020-11-27,2020-11-27, +pdfmeta,l3pdfmanagement,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2021-02-23,2021-02-23, pdfoverlay,pdfoverlay,David Purton,https://github.com/dcpurton/pdfoverlay,https://github.com/dcpurton/pdfoverlay.git,https://github.com/dcpurton/pdfoverlay/issues,2020-06-22,2020-06-22, pdftex,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27, +pdfxform,l3pdfmanagement,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2021-02-23,2021-02-23, peek,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27, percent,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12, pgf,pgf,The PGF/TikZ Team,https://pgf-tikz.github.io,https://github.com/pgf-tikz/pgf,https://github.com/pgf-tikz/pgf/issues,2020-07-03,2020-07-03, @@ -177,7 +188,7 @@ scan,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https: scontents,scontents,Pablo González,https://github.com/pablgonz/scontents,git@github.com:pablgonz/scontents.git,https://github.com/pablgonz/scontents/issues,2019-12-05,2019-12-05, sdaps,sdaps,Benjamin Berg,https://sdaps.org,https://github.com/sdaps/sdaps-class.git,https://github.com/sdaps/sdaps-class/issues,2020-02-17,2020-02-17, seq,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27, -shipout,ltshipout,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2020-10-01,2020-10-01, +shipout,latex2e,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2020-10-01,2021-03-03, siunitx,siunitx,Joseph Wright,https://github.com/josephwright/siunitx,https://github.com/josephwright/siunitx.git,https://github.com/josephwright/siunitx/issues,2012-11-04,2012-11-04, skel,skeldoc,Magnus Lie Hetland,https://github.com/mlhetland/skeldoc.sty,https://github.com/mlhetland/skeldoc.sty.git,https://github.com/mlhetland/skeldoc.sty/issues,2021-01-04,2021-01-04, skip,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27, @@ -201,6 +212,7 @@ tl,"l3kernel,l3tl-analysis,l3tl-build",The LaTeX Project,https://www.latex-proje tmpa,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12, tmpb,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12, token,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27, +true,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2021-04-23,2021-04-23, twmk,menukeys,Tobias Weh,https://github.com/tweh/menukeys,git@github.com:tweh/menukeys.git,https://github.com/tweh/menukeys/issues,2020-10-31,2020-10-31,“classic” L2 package using only some expl3 code ufcombo,combofont,Ulrike Fischer,https://github.com/u-fischer/combofont,https://github.com/u-fischer/combofont,https://github.com/u-fischer/combofont/issues,2020-04-24,2020-04-24, ufgrid,returntogrid,Ulrike Fischer,https://github.com/u-fischer/returntogrid,https://github.com/u-fischer/returntogrid,https://github.com/u-fischer/returntogrid/issues,2020-04-24,2020-04-24, @@ -218,6 +230,7 @@ witharrows,witharrows,François Pantigny,,,,2019-12-19,2019-12-19, xeCJK,xecjk,Qing Lee,https://github.com/CTeX-org/ctex-kit,https://github.com/CTeX-org/ctex-kit.git,https://github.com/CTeX-org/ctex-kit/issues,2013-05-26,2013-05-26, xetex,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27, xfrac,xfrac,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27, +xmarks,latex2e,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2021-03-03,2021-03-03, xparse,xparse,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27, xpatch,"regexpatch,xpatch",Enrico Gregorio,,,,2013-03-16,2013-03-16, xpeek,xpeek,Joel C. Salomon,,,,2013-03-16,2013-03-16, diff --git a/macros/latex/contrib/l3kernel/l3prefixes.pdf b/macros/latex/contrib/l3kernel/l3prefixes.pdf Binary files differindex b9bea84aa7..a21877e64c 100644 --- a/macros/latex/contrib/l3kernel/l3prefixes.pdf +++ b/macros/latex/contrib/l3kernel/l3prefixes.pdf diff --git a/macros/latex/contrib/l3kernel/l3prg.dtx b/macros/latex/contrib/l3kernel/l3prg.dtx index e75ab65899..972e417998 100644 --- a/macros/latex/contrib/l3kernel/l3prg.dtx +++ b/macros/latex/contrib/l3kernel/l3prg.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -313,7 +313,7 @@ % based on this result. % \end{function} % -% \begin{function}[added = 2012-02-09, updated = 2015-08-01]{\bool_show:N, \bool_show:c} +% \begin{function}[added = 2012-02-09, updated = 2021-04-29]{\bool_show:N, \bool_show:c} % \begin{syntax} % \cs{bool_show:N} \meta{boolean} % \end{syntax} @@ -328,7 +328,7 @@ % terminal. % \end{function} % -% \begin{function}[added = 2014-08-22, updated = 2015-08-03]{\bool_log:N, \bool_log:c} +% \begin{function}[added = 2014-08-22, updated = 2021-04-29]{\bool_log:N, \bool_log:c} % \begin{syntax} % \cs{bool_log:N} \meta{boolean} % \end{syntax} @@ -987,7 +987,17 @@ \cs_new_protected:Npn \@@_show:NN #1#2 { \__kernel_chk_defined:NT #2 - { \exp_args:Nx #1 { \token_to_str:N #2 = \@@_to_str:n {#2} } } + { + \token_case_meaning:NnF #2 + { + \c_true_bool { \exp_args:Nx #1 { \token_to_str:N #2 = true } } + \c_false_bool { \exp_args:Nx #1 { \token_to_str:N #2 = false } } + } + { + \__kernel_msg_error:nnxxx { kernel } { bad-type } + { \token_to_str:N #2 } { \token_to_meaning:N #2 } { bool } + } + } } % \end{macrocode} % \end{macro} @@ -1540,7 +1550,7 @@ \cs_new:cpn { @@_replicate_first_-:n } #1 { \exp_end: - \__kernel_msg_expandable_error:nn { kernel } { negative-replication } + \__kernel_msg_expandable_error:nn { prg } { negative-replication } } \cs_new:cpn { @@_replicate_first_0:n } #1 { \exp_end: } \cs_new:cpn { @@_replicate_first_1:n } #1 { \exp_end: #1 } diff --git a/macros/latex/contrib/l3kernel/l3prop.dtx b/macros/latex/contrib/l3kernel/l3prop.dtx index d8c7410aaa..38acc36a4c 100644 --- a/macros/latex/contrib/l3kernel/l3prop.dtx +++ b/macros/latex/contrib/l3kernel/l3prop.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -146,16 +146,16 @@ % \begin{function}[updated = 2012-07-09] % { % \prop_put:Nnn, \prop_put:NnV, \prop_put:Nno, \prop_put:Nnx, -% \prop_put:NVn, \prop_put:NVV, \prop_put:NVx, \prop_put:Nvx, +% \prop_put:NVn, \prop_put:NVV, \prop_put:NVx, \prop_put:Nvx, % \prop_put:Non, \prop_put:Noo,, \prop_put:Nxx, % \prop_put:cnn, \prop_put:cnV, \prop_put:cno, \prop_put:cnx, -% \prop_put:cVn, \prop_put:cVV, \prop_put:cVx, \prop_put:cvx, +% \prop_put:cVn, \prop_put:cVV, \prop_put:cVx, \prop_put:cvx, % \prop_put:con, \prop_put:coo, \prop_put:cxx, % \prop_gput:Nnn, \prop_gput:NnV, \prop_gput:Nno, \prop_gput:Nnx, % \prop_gput:NVn, \prop_gput:NVV, \prop_gput:NVx, \prop_gput:Nvx, % \prop_gput:Non, \prop_gput:Noo, \prop_gput:Nxx, % \prop_gput:cnn, \prop_gput:cnV, \prop_gput:cno, \prop_gput:cnx, -% \prop_gput:cVn, \prop_gput:cVV, \prop_gput:cVx, \prop_gput:cvx, +% \prop_gput:cVn, \prop_gput:cVV, \prop_gput:cVx, \prop_gput:cvx, % \prop_gput:con, \prop_gput:coo, \prop_gput:cxx % } % \begin{syntax} @@ -372,7 +372,7 @@ % \meta{token list variable} is assigned locally. % \end{function} % -% \section{Mapping to property lists} +% \section{Mapping over property lists} % % All mappings are done at the current group level, \emph{i.e.}~any % local assignments made by the \meta{function} or \meta{code} discussed @@ -480,14 +480,14 @@ % % \section{Viewing property lists} % -% \begin{function}[updated = 2015-08-01]{\prop_show:N, \prop_show:c} +% \begin{function}[updated = 2021-04-29]{\prop_show:N, \prop_show:c} % \begin{syntax} % \cs{prop_show:N} \meta{property list} % \end{syntax} % Displays the entries in the \meta{property list} in the terminal. % \end{function} % -% \begin{function}[added = 2014-08-12, updated = 2015-08-01]{\prop_log:N, \prop_log:c} +% \begin{function}[added = 2014-08-12, updated = 2021-04-29]{\prop_log:N, \prop_log:c} % \begin{syntax} % \cs{prop_log:N} \meta{property list} % \end{syntax} @@ -602,7 +602,7 @@ % error and removes its argument. % \begin{macrocode} \cs_new:Npn \@@_pair:wn #1 \s_@@ #2 - { \__kernel_msg_expandable_error:nn { kernel } { misused-prop } } + { \__kernel_msg_expandable_error:nn { prop } { misused } } % \end{macrocode} % \end{macro} % @@ -813,7 +813,7 @@ \str_if_eq:nnTF {#2} { = } { \prop_put:Nnn \l_@@_internal_prop {#3} {#1} } { - \__kernel_msg_error:nnx { kernel } { prop-keyval } + \__kernel_msg_error:nnx { prop } { prop-keyval } { \exp_not:o {#4} } } } @@ -1242,7 +1242,7 @@ % \end{macrocode} % \end{macro} % -% \subsection{Mapping to property lists} +% \subsection{Mapping over property lists} % % \begin{macro}[tested = m3prop003] % { @@ -1346,27 +1346,42 @@ % % \begin{macro}[tested = m3show001] % {\prop_show:N, \prop_show:c, \prop_log:N, \prop_log:c} -% Apply the general \cs{__kernel_chk_defined:NT} and -% \cs{msg_show:nnnnnn}. Contrarily to sequences and comma lists, +% \begin{macro}{\@@_show:NN} +% \begin{macro}[rEXP]{\@@_show_validate:w} +% Apply the general \cs{__kernel_chk_tl_type:NnnT}. +% Contrarily to sequences and comma lists, % we use \cs{msg_show_item:nn} to format both the key and the value % for each pair. % \begin{macrocode} -\cs_new_protected:Npn \prop_show:N { \@@_show:NN \msg_show:nnxxxx } +\cs_new_protected:Npn \prop_show:N { \@@_show:NN \__kernel_msg_show:nnxxxx } \cs_generate_variant:Nn \prop_show:N { c } -\cs_new_protected:Npn \prop_log:N { \@@_show:NN \msg_log:nnxxxx } +\cs_new_protected:Npn \prop_log:N { \@@_show:NN \__kernel_msg_log:nnxxxx } \cs_generate_variant:Nn \prop_log:N { c } \cs_new_protected:Npn \@@_show:NN #1#2 { - \__kernel_chk_defined:NT #2 + \__kernel_chk_tl_type:NnnT #2 { prop } + { + \s_@@ + \exp_after:wN \use_i:nn \exp_after:wN \@@_show_validate:w #2 + \@@_pair:wn \q_recursion_tail \s_@@ { } \q_recursion_stop + } { - #1 { LaTeX/kernel } { show-prop } + #1 { prop } { show } { \token_to_str:N #2 } { \prop_map_function:NN #2 \msg_show_item:nn } { } { } } } +\cs_new:Npn \@@_show_validate:w #1 \@@_pair:wn #2 \s_@@ #3 + { + \quark_if_recursion_tail_stop:n {#2} + \exp_not:N \@@_pair:wn \tl_to_str:n {#2} \s_@@ \exp_not:n { {#3} } + \@@_show_validate:w + } % \end{macrocode} % \end{macro} +% \end{macro} +% \end{macro} % % \begin{macrocode} %</package> diff --git a/macros/latex/contrib/l3kernel/l3quark.dtx b/macros/latex/contrib/l3kernel/l3quark.dtx index 8177a2a589..8106e1746e 100644 --- a/macros/latex/contrib/l3kernel/l3quark.dtx +++ b/macros/latex/contrib/l3kernel/l3quark.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -540,7 +540,7 @@ % \UnitTested % \begin{macro}{\@@_if_nil:w, \@@_if_no_value:w} % \begin{macro}[EXP]{\@@_if_empty_if:o} -% Let us explain |\quark_if_nil:n(TF)|. Expanding \cs{@@_if_nil:w} +% Let us explain \cs{quark_if_nil:nTF}. Expanding \cs{@@_if_nil:w} % once is safe thanks to the trailing \cs{q_nil} |??!|. The result of % expanding once is empty if and only if both delimited arguments |#1| % and~|#2| are empty and |#3|~is delimited by the last tokens~|?!|. @@ -623,8 +623,8 @@ % There are only two cases for the \meta{arg spec} here: % \begin{description} % \def\makelabel#1{\texttt{:#1}~} -% \item[n] gives an analogue of \cs[no-index]{quark_if_nil:n(TF)} -% \item[N] gives an analogue of \cs[no-index]{quark_if_nil:N(TF)} +% \item[n] gives an analogue of \cs{quark_if_nil:nTF} +% \item[N] gives an analogue of \cs{quark_if_nil:NTF} % \end{description} % Any other signature causes an error, as does a function without signature. % We use low-level emptiness tests as \pkg{l3tl} is not available yet when these @@ -641,7 +641,7 @@ \cs_new_protected:Npn \@@_new_test_aux:Nn #1 #2 { \if_meaning:w \q_nil #2 \q_nil - \__kernel_msg_error:nnx { kernel } { invalid-quark-function } + \__kernel_msg_error:nnx { quark } { invalid-function } { \token_to_str:N #1 } \else: \@@_new_test:Nccn #1 @@ -665,11 +665,11 @@ \cs_new_protected:Npn \@@_new_conditional:Nnnn #1#2#3#4 { \if_meaning:w \q_nil #2 \q_nil - \__kernel_msg_error:nnx { kernel } { invalid-quark-function } + \__kernel_msg_error:nnx { quark } { invalid-function } { \token_to_str:N #1 } \else: \if_meaning:w \q_nil #3 \q_nil - \__kernel_msg_error:nnx { kernel } { invalid-quark-function } + \__kernel_msg_error:nnx { quark } { invalid-function } { \token_to_str:N #1 } \else: \exp_last_unbraced:Nf \@@_new_test_aux:nnNNnnnn @@ -684,7 +684,7 @@ { \cs_if_exist_use:cTF { @@_new_#5_#2:Nnnn } { #4 } { - \__kernel_msg_error:nnxx { kernel } { invalid-quark-function } + \__kernel_msg_error:nnxx { quark } { invalid-function } { \token_to_str:N #4 } {#2} \use_none:nnn } @@ -961,7 +961,7 @@ { \tl_if_in:NnTF \g_@@_marks_tl { #1 } { - \__kernel_msg_error:nnx { kernel } { scanmark-already-defined } + \__kernel_msg_error:nnx { scanmark } { already-defined } { \token_to_str:N #1 } } { diff --git a/macros/latex/contrib/l3kernel/l3regex.dtx b/macros/latex/contrib/l3kernel/l3regex.dtx index ef7ab6becc..0824cbcb97 100644 --- a/macros/latex/contrib/l3kernel/l3regex.dtx +++ b/macros/latex/contrib/l3kernel/l3regex.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -66,7 +66,7 @@ % \tl_set:Nn \l_my_tl { That~cat. } % \regex_replace_once:nnN { at } { is } \l_my_tl % \end{verbatim} -% the token list variable \cs{l_my_tl} holds the text +% the token list variable \cs[no-index]{l_my_tl} holds the text % \enquote{\texttt{This cat.}}, where the first % occurrence of \enquote{\texttt{at}} was replaced % by \enquote{\texttt{is}}. A more complicated example is @@ -87,8 +87,8 @@ % \begin{verbatim} % \regex_const:Nn \c_foo_regex { \c{begin} \cB. (\c[^BE].*) \cE. } % \end{verbatim} -% stores in \cs{c_foo_regex} a regular expression which matches the -% starting marker for an environment: \cs{begin}, followed by a +% stores in \cs[no-index]{c_foo_regex} a regular expression which matches the +% starting marker for an environment: \cs[no-index]{begin}, followed by a % begin-group token (|\cB.|), then any number of tokens which are % neither begin-group nor end-group character tokens (|\c[^BE].*|), % ending with an end-group token (|\cE.|). As explained in the next @@ -98,6 +98,8 @@ % % \section{Syntax of regular expressions} % +% \subsection{Regex examples} +% % We start with a few examples, and encourage the reader to apply % \cs{regex_show:n} to these regular expressions. % \begin{itemize} @@ -147,6 +149,8 @@ % other things all valid integer expressions (made only with explicit % integers). One should follow it with further testing. % +% \subsection{Characters in regular expressions} +% % Most characters match exactly themselves, % with an arbitrary category code. Some characters are % special and must be escaped with a backslash (\emph{e.g.}, |\*| @@ -191,6 +195,8 @@ % \item[\\t] Horizontal tab (hex 09). % \end{l3regex-syntax} % +% \subsection{Characters classes} +% % Character types. % \begin{l3regex-syntax} % \item[.] A single period matches any token. @@ -235,6 +241,21 @@ % except |p|, as well as control sequences (see below for a description % of |\c|). % +% In character classes, only |[|, |^|, |-|, |]|, |\| and spaces are +% special, and should be escaped. Other non-alphanumeric characters can +% still be escaped without harm. Any escape sequence which matches a +% single character (|\d|, |\D|, \emph{etc.}) is supported in character +% classes. If the first character is |^|, then +% the meaning of the character class is inverted; |^| appearing anywhere +% else in the range is not special. If the first character (possibly +% following a leading |^|) is |]| then it does not need to be escaped +% since ending the range there would make it empty. +% Ranges of characters +% can be expressed using |-|, for instance, |[\D 0-5]| and |[^6-9]| are +% equivalent. +% +% \subsection{Structure: alternatives, groups, repetitions} +% % Quantifiers (repetition). % \begin{l3regex-syntax} % \item[?] $0$ or $1$, greedy. @@ -250,24 +271,6 @@ % \item[\{$n,m$\}?] At least $n$, no more than $m$, lazy. % \end{l3regex-syntax} % -% Anchors and simple assertions. -% \begin{l3regex-syntax} -% \item[\\b] Word boundary: either the previous token is matched by -% |\w| and the next by |\W|, or the opposite. For this purpose, -% the ends of the token list are considered as |\W|. -% \item[\\B] Not a word boundary: between two |\w| tokens -% or two |\W| tokens (including the boundary). -% \item[\char`^ \textrm{or} \\A] -% Start of the subject token list. -% \item[\char`$\textrm{,} \\Z \textrm{or} \\z] ^^A $ -% End of the subject token list. -% \item[\\G] Start of the current match. This is only different from |^| -% in the case of multiple matches: for instance -% |\regex_count:nnN { \G a } { aaba } \l_tmpa_int| yields $2$, but -% replacing |\G| by |^| would result in \cs{l_tmpa_int} holding the -% value $1$. -% \end{l3regex-syntax} -% % Alternation and capturing groups. % \begin{l3regex-syntax} % \item[A\char`|B\char`|C] Either one of \texttt{A}, \texttt{B}, @@ -280,6 +283,31 @@ % group number. % \end{l3regex-syntax} % +% Capturing groups are a means of extracting information about the +% match. Parenthesized groups are labelled in the order of their +% opening parenthesis, starting at $1$. The contents of those groups +% corresponding to the \enquote{best} match (leftmost longest) +% can be extracted and stored in a sequence of token lists using for +% instance \cs{regex_extract_once:nnNTF}. +% +% The |\K| escape sequence resets the beginning of the match to the +% current position in the token list. This only affects what is reported +% as the full match. For instance, +% \begin{verbatim} +% \regex_extract_all:nnN { a \K . } { a123aaxyz } \l_foo_seq +% \end{verbatim} +% results in \cs[no-index]{l_foo_seq} containing the items |{1}| and |{a}|: the +% true matches are |{a1}| and |{aa}|, but they are trimmed by the use of +% |\K|. The |\K| command does not affect capturing groups: for instance, +% \begin{verbatim} +% \regex_extract_once:nnN { (. \K c)+ \d } { acbc3 } \l_foo_seq +% \end{verbatim} +% results in \cs[no-index]{l_foo_seq} containing the items |{c3}| and |{bc}|: the +% true match is |{acbc3}|, with first submatch |{bc}|, but |\K| resets +% the beginning of the match to the last position where it appears. +% +% \subsection{Matching exact tokens} +% % The |\c| escape sequence allows to test the category code of tokens, % and match control sequences. Each character category is represented % by a single uppercase letter: @@ -301,7 +329,7 @@ % \begin{l3regex-syntax} % \item[\\c\Arg{regex}] A control sequence whose csname matches the % \meta{regex}, anchored at the beginning and end, so that |\c{begin}| -% matches exactly \cs{begin}, and nothing else. +% matches exactly \cs[no-index]{begin}, and nothing else. % \item[\\cX] Applies to the next object, which can be a character, % character property, class, or group, and forces this object to % only match tokens with category |X| (any of |CBEMTPUDSLOA|. For @@ -328,11 +356,54 @@ % % The |\u| escape sequence allows to insert the contents of a token list % directly into a regular expression or a replacement, avoiding the need -% to escape special characters. Namely, |\u|\Arg{tl~var~name} matches -% the exact contents of the token list \meta{tl~var}. Within a |\c{...}| +% to escape special characters. Namely, |\u|\Arg{var~name} matches +% the exact contents (both character codes and category codes) of the +% variable \cs[no-index]{\meta{var~name}}, +% which are obtained by applying \cs{exp_not:v} \Arg{var~name} at the +% time the regular expression is compiled. Within a |\c{...}| % control sequence matching, the |\u| escape sequence only expands its -% argument once, in effect performing \cs{tl_to_str:v}. Quantifiers are -% not supported directly: use a group. +% argument once, in effect performing \cs{tl_to_str:v}. +% Quantifiers are supported. +% +% The |\ur| escape sequence allows to insert the contents of a |regex| +% variable into a larger regular expression. For instance, +% |A\ur{l_tmpa_regex}D| matches the tokens |A| and |D| separated by +% something that matches the regular expression +% \cs[no-index]{l_tmpa_regex}. This behaves as if a non-capturing group +% were surrounding \cs[no-index]{l_tmpa_regex}, and any group contained +% in \cs[no-index]{l_tmpa_regex} is converted to a non-capturing group. +% Quantifiers are supported. +% +% For instance, if \cs[no-index]{l_tmpa_regex} has value \verb"B|C", +% then |A\ur{l_tmpa_regex}D| is equivalent to \verb"A(?:B|C)D" (matching +% |ABD| or |ACD|) and not to \verb"AB|CD" (matching |AB| or |CD|). To +% get the latter effect, it is simplest to use \TeX{}'s expansion +% machinery directly: if \cs[no-index]{l_mymodule_BC_tl} contains +% \verb"B|C" then the following two lines show the same result: +% \begin{quote} +% \cs{regex_show:n} |{ A \u{l_mymodule_BC_tl} D }| \\ +% \cs{regex_show:n} \verb"{ A B | C D }" +% \end{quote} +% +% \subsection{Miscellaneous} +% +% Anchors and simple assertions. +% \begin{l3regex-syntax} +% \item[\\b] Word boundary: either the previous token is matched by +% |\w| and the next by |\W|, or the opposite. For this purpose, +% the ends of the token list are considered as |\W|. +% \item[\\B] Not a word boundary: between two |\w| tokens +% or two |\W| tokens (including the boundary). +% \item[\char`^ \textrm{or} \\A] +% Start of the subject token list. +% \item[\char`$\textrm{,} \\Z \textrm{or} \\z] ^^A $ +% End of the subject token list. +% \item[\\G] Start of the current match. This is only different from |^| +% in the case of multiple matches: for instance +% |\regex_count:nnN { \G a } { aaba } \l_tmpa_int| yields $2$, but +% replacing |\G| by |^| would result in \cs{l_tmpa_int} holding the +% value $1$. +% \end{l3regex-syntax} % % The option |(?i)| makes the match case insensitive (identifying % \texttt{A}--\texttt{Z} with \texttt{a}--\texttt{z}; no Unicode support @@ -346,42 +417,6 @@ % |i| option. % ^^A \] % -% In character classes, only |[|, |^|, |-|, |]|, |\| and spaces are -% special, and should be escaped. Other non-alphanumeric characters can -% still be escaped without harm. Any escape sequence which matches a -% single character (|\d|, |\D|, \emph{etc.}) is supported in character -% classes. If the first character is |^|, then -% the meaning of the character class is inverted; |^| appearing anywhere -% else in the range is not special. If the first character (possibly -% following a leading |^|) is |]| then it does not need to be escaped -% since ending the range there would make it empty. -% Ranges of characters -% can be expressed using |-|, for instance, |[\D 0-5]| and |[^6-9]| are -% equivalent. -% -% Capturing groups are a means of extracting information about the -% match. Parenthesized groups are labelled in the order of their -% opening parenthesis, starting at $1$. The contents of those groups -% corresponding to the \enquote{best} match (leftmost longest) -% can be extracted and stored in a sequence of token lists using for -% instance \cs{regex_extract_once:nnNTF}. -% -% The |\K| escape sequence resets the beginning of the match to the -% current position in the token list. This only affects what is reported -% as the full match. For instance, -% \begin{verbatim} -% \regex_extract_all:nnN { a \K . } { a123aaxyz } \l_foo_seq -% \end{verbatim} -% results in \cs{l_foo_seq} containing the items |{1}| and |{a}|: the -% true matches are |{a1}| and |{aa}|, but they are trimmed by the use of -% |\K|. The |\K| command does not affect capturing groups: for instance, -% \begin{verbatim} -% \regex_extract_once:nnN { (. \K c)+ \d } { acbc3 } \l_foo_seq -% \end{verbatim} -% results in \cs{l_foo_seq} containing the items |{c3}| and |{bc}|: the -% true match is |{acbc3}|, with first submatch |{bc}|, but |\K| resets -% the beginning of the match to the last position where it appears. -% % \section{Syntax of the replacement text} % % Most of the features described in regular expressions do not make @@ -412,7 +447,7 @@ % \tl_set:Nn \l_my_tl { Hello,~world! } % \regex_replace_all:nnN { ([er]?l|o) . } { (\0--\1) } \l_my_tl % \end{verbatim} -% results in \cs{l_my_tl} holding |H(ell--el)(o,--o) w(or--o)(ld--l)!| +% results in \cs[no-index]{l_my_tl} holding |H(ell--el)(o,--o) w(or--o)(ld--l)!| % % The submatches are numbered according to the order in which the % opening parenthesis of capturing groups appear in the regular @@ -423,10 +458,17 @@ % the last match is used in the replacement text. Submatches always keep % the same category codes as in the original token list. % -% The characters inserted by the replacement have category code $12$ -% (other) by default, with the exception of space characters. Spaces -% inserted through \verb*|\ | have category code $10$, while spaces -% inserted through |\x20| or |\x{20}| have category code $12$. +% By default, the category code of characters inserted by the +% replacement are determined by the prevailing category code regime at +% the time where the replacement is made, with two exceptions: +% \begin{itemize} +% \item space characters (with character code $32$) inserted with +% \verb*|\ | or |\x20| or |\x{20}| have category code~$10$ regardless +% of the prevailing category code regime; +% \item if the category code would be $0$~(escape), $5$~(newline), +% $9$~(ignore), $14$~(comment) or $15$~(invalid), it is replaced by +% $12$~(other) instead. +% \end{itemize} % The escape sequence |\c| allows to insert characters % with arbitrary category codes, as well as control sequences. % \begin{l3regex-syntax} @@ -441,8 +483,8 @@ % submatches |\0|, |\1|, and so on, as in the example for |\u| below. % \end{l3regex-syntax} % -% The escape sequence |\u|\Arg{tl~var~name} allows to insert the -% contents of the token list with name \meta{tl~var~name} directly into +% The escape sequence |\u|\Arg{var~name} allows to insert the +% contents of the variable with name \meta{var~name} directly into % the replacement, giving an easier control of category codes. When % nested in |\c{|\ldots{}|}| and |\u{|\ldots{}|}| constructions, the % |\u| and |\c|~escape sequences perform \cs{tl_to_str:v}, namely @@ -455,7 +497,16 @@ % \tl_set:Nn \l_my_tl { one , two , one , one } % \regex_replace_all:nnN { [^,]+ } { \u{l_my_\0_tl} } \l_my_tl % \end{verbatim} -% results in \cs{l_my_tl} holding |first,\emph{second},first,first|. +% results in \cs[no-index]{l_my_tl} holding |first,\emph{second},first,first|. +% +% Regex replacement is also a convenient way to produce token lists +% with arbitrary category codes. For instance +% \begin{verbatim} +% \tl_clear:N \l_tmpa_tl +% \regex_replace_all:nnN { } { \cU\% \cA\~ } \l_tmpa_tl +% \end{verbatim} +% results in \cs[no-index]{l_tmpa_tl} containing the percent character +% with category code~$7$ (superscript) and an active tilde character. % % \section{Pre-compiling regular expressions} % @@ -493,18 +544,21 @@ % which never change. % \end{function} % -% \begin{function}[added = 2017-05-26]{\regex_show:n, \regex_show:N} +% \begin{function}[added = 2021-04-26, updated = 2021-04-29] +% {\regex_show:N, \regex_show:n, \regex_log:N, \regex_log:n} % \begin{syntax} % \cs{regex_show:n} \Arg{regex} +% \cs{regex_log:n} \Arg{regex} % \end{syntax} -% Shows how \pkg{l3regex} interprets the \meta{regex}. For instance, +% Displays in the terminal or writes in the log file (respectively) +% how \pkg{l3regex} interprets the \meta{regex}. For instance, % \cs{regex_show:n} \verb+{\A X|Y}+ shows % \begin{verbatim} % +-branch % anchor at start (\A) -% char code 88 +% char code 88 (X) % +-branch -% char code 89 +% char code 89 (Y) % \end{verbatim} % indicating that the anchor |\A| only applies to the first branch: % the second branch is not anchored to the beginning of the match. @@ -515,7 +569,7 @@ % All regular expression functions are available in both |:n| and |:N| % variants. The former require a \enquote{standard} regular expression, % while the later require a compiled expression as generated by -% \cs{regex_(g)set:Nn}. +% \cs{regex_set:Nn}. % % \begin{function}[TF, added = 2017-05-26]{\regex_match:nn, \regex_match:Nn} % \begin{syntax} @@ -549,7 +603,7 @@ % \int_new:N \l_foo_int % \regex_count:nnN { (b+|c) } { abbababcbb } \l_foo_int % \end{verbatim} -% results in \cs{l_foo_int} taking the value $5$. +% results in \cs[no-index]{l_foo_int} taking the value $5$. % \end{function} % % \section{Submatch extraction} @@ -577,10 +631,10 @@ % Then the regular expression (anchored at the start with |\A| and % at the end with |\Z|) must match the whole token list. The first % capturing group, |(La)?|, matches |La|, and the second capturing -% group, |(!*)|, matches |!!!|. Thus, |\l_foo_seq| contains as a result +% group, |(!*)|, matches |!!!|. Thus, \cs[no-index]{l_foo_seq} contains as a result % the items |{LaTeX!!!}|, |{La}|, and |{!!!}|, and the \texttt{true} % branch is left in the input stream. -% Note that the $n$-th item of |\l_foo_seq|, as obtained using +% Note that the $n$-th item of \cs[no-index]{l_foo_seq}, as obtained using % \cs{seq_item:Nn}, correspond to the submatch numbered $(n-1)$ in % functions such as \cs{regex_replace_once:nnN}. % \end{function} @@ -695,7 +749,7 @@ % \item Add tracing information. % \item Detect attempts to use back-references and other % non-implemented syntax. -% \item Test for the maximum register \cs{c_max_register_int}. +% \item Test for the maximum register \cs[no-index]{c_max_register_int}. % \item Find out whether the fact that |\W| and friends match the % end-marker leads to bugs. Possibly update \cs[no-index]{__regex_item_reverse:n}. % \item The empty cs should be matched by |\c{}|, not by @@ -753,11 +807,6 @@ % \item Unicode properties: |\p{..}| and |\P{..}|; % |\X| which should match any \enquote{extended} Unicode sequence. % This requires to manipulate a lot of data, probably using tree-boxes. -% \item Provide a syntax such as |\ur{l_my_regex}| to use an -% already-compiled regex in a more complicated regex. This makes -% regexes more easily composable. -% \item Allowing |\u{l_my_tl}| in more places, for instance as the -% number of repetitions in a quantifier. % \end{itemize} % % The following features of \textsc{pcre} or Perl may or may not be @@ -1218,9 +1267,7 @@ \if_int_compare:w #1 = \l_@@_curr_char_int \exp_after:wN \@@_break_true:w \fi: - \if_int_compare:w \l_@@_case_changed_char_int = \c_max_int - \@@_compute_case_changed_char: - \fi: + \@@_maybe_compute_ccc: \if_int_compare:w #1 = \l_@@_case_changed_char_int \exp_after:wN \@@_break_true:w \fi: @@ -1232,9 +1279,7 @@ \exp_after:wN \exp_after:wN \exp_after:wN \@@_break_true:w \fi: \fi: - \if_int_compare:w \l_@@_case_changed_char_int = \c_max_int - \@@_compute_case_changed_char: - \fi: + \@@_maybe_compute_ccc: \reverse_if:N \if_int_compare:w #1 > \l_@@_case_changed_char_int \reverse_if:N \if_int_compare:w #2 < \l_@@_case_changed_char_int \exp_after:wN \exp_after:wN \exp_after:wN \@@_break_true:w @@ -1246,8 +1291,7 @@ % % \begin{macro}{\@@_compute_case_changed_char:} % This function is called when \cs{l_@@_case_changed_char_int} has -% not yet been computed (or rather, when it is set to the marker value -% \cs{c_max_int}). If the current character code is in the range +% not yet been computed. If the current character code is in the range % $[65,90]$ (upper-case), then add $32$, making it lowercase. If it is % in the lower-case letter range $[97,122]$, subtract $32$. % \begin{macrocode} @@ -1267,7 +1311,9 @@ { \c_@@_ascii_lower_int } \fi: \fi: + \cs_set_eq:NN \@@_maybe_compute_ccc: \prg_do_nothing: } +\cs_new_eq:NN \@@_maybe_compute_ccc: \@@_compute_case_changed_char: % \end{macrocode} % \end{macro} % @@ -1583,7 +1629,7 @@ \cs_new_eq:NN \@@_escape_break:w \prg_break: \cs_new:cpn { @@_escape_/break:w } { - \__kernel_msg_expandable_error:nn { kernel } { trailing-backslash } + \__kernel_msg_expandable_error:nn { regex } { trailing-backslash } \prg_break: } \cs_new:cpn { @@_escape_~:w } { } @@ -1620,7 +1666,7 @@ { \int_compare:nNnTF {#1} > \c_max_char_int { - \__kernel_msg_expandable_error:nnff { kernel } { x-overflow } + \__kernel_msg_expandable_error:nnff { regex } { x-overflow } {#1} { \int_to_Hex:n {#1} } } { @@ -1706,7 +1752,7 @@ } \cs_new:Npn \@@_escape_x_loop_error:n #1 { - \__kernel_msg_expandable_error:nnn { kernel } { x-missing-rbrace } {#1} + \__kernel_msg_expandable_error:nnn { regex } { x-missing-rbrace } {#1} \@@_escape_loop:N #1 } % \end{macrocode} @@ -2143,7 +2189,7 @@ \if_int_compare:w \l_@@_mode_int = \c_@@_class_mode_int \exp_after:wN \exp_after:wN \exp_after:wN \use:n \else: - \__kernel_msg_error:nn { kernel } { c-bad-mode } + \__kernel_msg_error:nn { regex } { c-bad-mode } \exp_after:wN \exp_after:wN \exp_after:wN \use_none:n \fi: \fi: @@ -2196,13 +2242,13 @@ { \@@_if_in_class:TF { - \__kernel_msg_error:nn { kernel } { missing-rbrack } + \__kernel_msg_error:nn { regex } { missing-rbrack } \use:c { @@_compile_]: } \prg_do_nothing: \prg_do_nothing: } { } \if_int_compare:w \l_@@_group_level_int > 0 \exp_stop_f: - \__kernel_msg_error:nnx { kernel } { missing-rparen } + \__kernel_msg_error:nnx { regex } { missing-rparen } { \int_use:N \l_@@_group_level_int } \prg_replicate:nn { \l_@@_group_level_int } @@ -2259,10 +2305,10 @@ \prg_do_nothing: \prg_do_nothing: \prg_do_nothing: \prg_do_nothing: \int_compare:nNnT \l_@@_mode_int = \c_@@_catcode_mode_int - { \__kernel_msg_error:nn { kernel } { c-trailing } } + { \__kernel_msg_error:nn { regex } { c-trailing } } \int_compare:nNnT \l_@@_mode_int < \c_@@_outer_mode_int { - \__kernel_msg_error:nn { kernel } { c-missing-rbrace } + \__kernel_msg_error:nn { regex } { c-missing-rbrace } \@@_compile_end_cs: \prg_do_nothing: \prg_do_nothing: \prg_do_nothing: \prg_do_nothing: @@ -2343,6 +2389,21 @@ % % \subsubsection{Quantifiers} % +% \begin{macro}{\@@_compile_if_quantifier:TFw} +% This looks ahead and checks whether there are any quantifier +% (special character equal to either of \texttt{?+*\{}). This is +% useful for the |\u| and |\ur| escape sequences. +% \begin{macrocode} +\cs_new_protected:Npn \@@_compile_if_quantifier:TFw #1#2#3#4 + { + \token_if_eq_meaning:NNTF #3 \@@_compile_special:N + { \cs_if_exist:cTF { @@_compile_quantifier_#4:w } } + { \use_ii:nn } + {#1} {#2} #3 #4 + } +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\@@_compile_quantifier:w} % This looks ahead and finds any quantifier (special character equal % to either of \texttt{?+*\{}). @@ -2373,7 +2434,7 @@ \cs_new_protected:Npn \@@_compile_quantifier_abort:xNN #1#2#3 { \@@_compile_quantifier_none: - \__kernel_msg_warning:nnxx { kernel } { invalid-quantifier } {#1} {#3} + \__kernel_msg_warning:nnxx { regex } { invalid-quantifier } {#1} {#3} \@@_compile_abort_tokens:x {#1} #2 #3 } @@ -2489,7 +2550,7 @@ { \if_int_compare:w \l_@@_internal_a_int > \l_@@_internal_b_int - \__kernel_msg_error:nnxx { kernel } { backwards-quantifier } + \__kernel_msg_error:nnxx { regex } { backwards-quantifier } { \int_use:N \l_@@_internal_a_int } { \int_use:N \l_@@_internal_b_int } \int_zero:N \l_@@_internal_b_int @@ -2523,7 +2584,7 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_compile_raw_error:N #1 { - \__kernel_msg_error:nnx { kernel } { bad-escape } {#1} + \__kernel_msg_error:nnx { regex } { bad-escape } {#1} \@@_compile_raw:N #1 } % \end{macrocode} @@ -2582,7 +2643,7 @@ \@@_if_end_range:NNTF #2 #3 { \if_int_compare:w `#1 > `#3 \exp_stop_f: - \__kernel_msg_error:nnxx { kernel } { range-backwards } {#1} {#3} + \__kernel_msg_error:nnxx { regex } { range-backwards } {#1} {#3} \else: \tl_build_put_right:Nx \l_@@_build_tl { @@ -2596,7 +2657,7 @@ \fi: } { - \__kernel_msg_warning:nnxx { kernel } { range-missing-end } + \__kernel_msg_warning:nnxx { regex } { range-missing-end } {#1} { \c_backslash_str #3 } \tl_build_put_right:Nx \l_@@_build_tl { @@ -2859,11 +2920,11 @@ { : { \@@_compile_class_posix:NNNNw } = { - \__kernel_msg_warning:nnx { kernel } + \__kernel_msg_warning:nnx { regex } { posix-unsupported } { = } } . { - \__kernel_msg_warning:nnx { kernel } + \__kernel_msg_warning:nnx { regex } { posix-unsupported } { . } } } @@ -2905,7 +2966,7 @@ } } { - \__kernel_msg_warning:nnx { kernel } { posix-unknown } + \__kernel_msg_warning:nnx { regex } { posix-unknown } { \l_@@_internal_a_tl } \@@_compile_abort_tokens:x { @@ -2915,7 +2976,7 @@ } } { - \__kernel_msg_error:nnxx { kernel } { posix-missing-close } + \__kernel_msg_error:nnxx { regex } { posix-missing-close } { [: \l_@@_internal_a_tl } { #2 #4 } \@@_compile_abort_tokens:x { [: \l_@@_internal_a_tl } #1 #2 #3 #4 @@ -2961,7 +3022,7 @@ \int_set_eq:NN \l_@@_catcodes_int \l_@@_default_catcodes_int \exp_after:wN \@@_compile_quantifier:w \else: - \__kernel_msg_warning:nn { kernel } { extra-rparen } + \__kernel_msg_warning:nn { regex } { extra-rparen } \exp_after:wN \@@_compile_raw:N \exp_after:wN ) \fi: } @@ -2980,7 +3041,7 @@ { \if_int_compare:w \l_@@_mode_int = \c_@@_catcode_in_class_mode_int - \__kernel_msg_error:nn { kernel } { c-lparen-in-class } + \__kernel_msg_error:nn { regex } { c-lparen-in-class } \exp_after:wN \@@_compile_raw:N \exp_after:wN ( \else: \exp_after:wN \@@_compile_lparen:w @@ -2994,7 +3055,7 @@ \cs_if_exist_use:cF { @@_compile_special_group_\token_to_str:N #4 :w } { - \__kernel_msg_warning:nnx { kernel } { special-group-unknown } + \__kernel_msg_warning:nnx { regex } { special-group-unknown } { (? #4 } \@@_compile_group_begin:N \@@_group:nnnN \@@_compile_raw:N ? #3 #4 @@ -3063,7 +3124,7 @@ { \@@_item_caseless_range:nn } } { - \__kernel_msg_warning:nnx { kernel } { unknown-option } { (?i #2 } + \__kernel_msg_warning:nnx { regex } { unknown-option } { (?i #2 } \@@_compile_raw:N ( \@@_compile_raw:N ? \@@_compile_raw:N i @@ -3082,7 +3143,7 @@ { \@@_item_caseful_range:nn } } { - \__kernel_msg_warning:nnx { kernel } { unknown-option } { (?-#2#4 } + \__kernel_msg_warning:nnx { regex } { unknown-option } { (?-#2#4 } \@@_compile_raw:N ( \@@_compile_raw:N ? \@@_compile_raw:N - @@ -3121,7 +3182,7 @@ } { \cs_if_exist_use:cF { @@_compile_c_#2:w } } { - \__kernel_msg_error:nnx { kernel } { c-missing-category } {#2} + \__kernel_msg_error:nnx { regex } { c-missing-category } {#2} #1 #2 } } @@ -3142,7 +3203,7 @@ { \token_if_eq_charcode:NNF #2 ( } % ) } { \use:n } - { \__kernel_msg_error:nnn { kernel } { c-C-invalid } {#2} } + { \__kernel_msg_error:nnn { regex } { c-C-invalid } {#2} } #1 #2 } % \end{macrocode} @@ -3195,7 +3256,7 @@ { \@@_compile_c_lbrack_end: } } { - \__kernel_msg_error:nnx { kernel } { c-missing-rbrack } {#2} + \__kernel_msg_error:nnx { regex } { c-missing-rbrack } {#2} \@@_compile_c_lbrack_end: #1 #2 } @@ -3237,6 +3298,21 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}+\@@_compile_{:+ +% We forbid unescaped left braces inside a |\c{...}| escape because +% they otherwise lead to the confusing question of whether the first +% right brace in |\c{{}x}| should end |\c| or whether one should +% match braces. +% \begin{macrocode} +\cs_new_protected:cpn { @@_compile_ \c_left_brace_str : } + { + \@@_if_in_cs:TF + { \__kernel_msg_error:nnn { regex } { cu-lbrace } { c } } + { \exp_after:wN \@@_compile_raw:N \c_left_brace_str } + } +% \end{macrocode} +% \end{macro} +% % \begin{macro}+\@@_compile_}:+ % \begin{macro}{\@@_compile_end_cs:} % \begin{macro}[EXP]{\@@_compile_cs_aux:Nn, \@@_compile_cs_aux:NNnnnN} @@ -3320,36 +3396,58 @@ % \end{macro} % \end{macro} % -% \subsubsection{Raw token lists with \cs{u}} +% \subsubsection{Raw token lists with \cs[no-index]{u}} % % \begin{macro}{\@@_compile_/u:} -% \begin{macro}[EXP]{\@@_compile_u_loop:NN} % The |\u| escape is invalid in classes and directly following a -% catcode test. Otherwise, it must be followed by a left brace. We -% then collect the characters for the argument of |\u| within an -% \texttt{x}-expanding assignment. In principle we could just wait to -% encounter a right brace, but this is unsafe: if the right brace was -% missing, then we would reach the end-markers of the regex, and -% continue, leading to obscure fatal errors. Instead, we only allow -% raw and special characters, and stop when encountering a special -% right brace, any escaped character, or the end-marker. +% catcode test. Otherwise test for a following |r| (for |\ur|), and +% call an auxiliary responsible for finding the variable name. % \begin{macrocode} \cs_new_protected:cpn { @@_compile_/u: } #1#2 { \@@_if_in_class_or_catcode:TF { \@@_compile_raw_error:N u #1 #2 } { - \@@_two_if_eq:NNNNTF #1 #2 \@@_compile_special:N \c_left_brace_str - { - \__kernel_tl_set:Nx \l_@@_internal_a_tl { \if_false: } \fi: - \@@_compile_u_loop:NN - } - { - \__kernel_msg_error:nn { kernel } { u-missing-lbrace } - \@@_compile_raw:N u #1 #2 - } + \@@_two_if_eq:NNNNTF #1 #2 \@@_compile_raw:N r + { \@@_compile_u_brace:NNN \@@_compile_ur_end: } + { \@@_compile_u_brace:NNN \@@_compile_u_end: #1 #2 } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_compile_u_brace:NNN} +% This enforces the presence of a left brace, then starts a loop to +% find the variable name. +% \begin{macrocode} +\cs_new:Npn \@@_compile_u_brace:NNN #1#2#3 + { + \@@_two_if_eq:NNNNTF #2 #3 \@@_compile_special:N \c_left_brace_str + { + \tl_set:Nn \l_@@_internal_b_tl {#1} + \__kernel_tl_set:Nx \l_@@_internal_a_tl { \if_false: } \fi: + \@@_compile_u_loop:NN + } + { + \__kernel_msg_error:nn { regex } { u-missing-lbrace } + \token_if_eq_meaning:NNTF #1 \@@_compile_ur_end: + { \@@_compile_raw:N u \@@_compile_raw:N r } + { \@@_compile_raw:N u } + #2 #3 } } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[EXP]{\@@_compile_u_loop:NN} +% We collect the characters for the argument of |\u| within an +% \texttt{x}-expanding assignment. In principle we could just wait to +% encounter a right brace, but this is unsafe: if the right brace was +% missing, then we would reach the end-markers of the regex, and +% continue, leading to obscure fatal errors. Instead, we only allow +% raw and special characters, and stop when encountering a special +% right brace, any escaped character, or the end-marker. +% \begin{macrocode} \cs_new:Npn \@@_compile_u_loop:NN #1#2 { \token_if_eq_meaning:NNTF #1 \@@_compile_raw:N @@ -3358,29 +3456,92 @@ \token_if_eq_meaning:NNTF #1 \@@_compile_special:N { \exp_after:wN \token_if_eq_charcode:NNTF \c_right_brace_str #2 - { \if_false: { \fi: } \@@_compile_u_end: } - { #2 \@@_compile_u_loop:NN } + { \if_false: { \fi: } \l_@@_internal_b_tl } + { + \if_charcode:w \c_left_brace_str #2 + \__kernel_msg_expandable_error:nnn { regex } { cu-lbrace } { u } + \else: + #2 + \fi: + \@@_compile_u_loop:NN + } } { \if_false: { \fi: } - \__kernel_msg_error:nnx { kernel } { u-missing-rbrace } {#2} - \@@_compile_u_end: + \__kernel_msg_error:nnx { regex } { u-missing-rbrace } {#2} + \l_@@_internal_b_tl #1 #2 } } } % \end{macrocode} % \end{macro} +% +% \begin{macro}{\@@_compile_ur_end:, \@@_compile_ur:n} +% \begin{macro}[EXP]{\@@_compile_ur_aux:w} +% For the |\ur{...}| construction, once we have extracted the +% variable's name, we replace all groups by non-capturing groups in +% the compiled regex (passed as the +% argument of \cs{@@_compile_ur:n}). If that has a single branch +% (namely \cs{tl_if_empty:oTF} is false) and there is no quantifier, +% then simply insert the contents of this branch (obtained by +% \cs{use_ii:nn}, which is expanded later). In all other cases, +% insert a non-capturing group and look for quantifiers to determine +% the number of repetition etc. +% \begin{macrocode} +\cs_new_protected:Npn \@@_compile_ur_end: + { + \group_begin: + \cs_set:Npn \@@_group:nnnN { \@@_group_no_capture:nnnN } + \cs_set:Npn \@@_group_resetting:nnnN { \@@_group_no_capture:nnnN } + \exp_args:NNx + \group_end: + \@@_compile_ur:n { \use:c { \l_@@_internal_a_tl } } + } +\cs_new_protected:Npn \@@_compile_ur:n #1 + { + \tl_if_empty:oTF { \@@_compile_ur_aux:w #1 {} ? ? \q_@@_nil } + { \@@_compile_if_quantifier:TFw } + { \use_i:nn } + { + \tl_build_put_right:Nn \l_@@_build_tl + { \@@_group_no_capture:nnnN { \if_false: } \fi: #1 } + \@@_compile_quantifier:w + } + { \tl_build_put_right:Nn \l_@@_build_tl { \use_ii:nn #1 } } + } +\cs_new:Npn \@@_compile_ur_aux:w \@@_branch:n #1#2#3 \q_@@_nil {#2} +% \end{macrocode} +% \end{macro} % \end{macro} % -% \begin{macro}{\@@_compile_u_end:} -% Once we have extracted the variable's name, we store the contents of -% that variable in \cs{l_@@_internal_a_tl}. The behaviour of |\u| +% \begin{macro}{\@@_compile_u_end:, \@@_compile_u_payload:} +% Once we have extracted the variable's name, we check for +% quantifiers, in which case we set up a non-capturing group with a +% single branch. Inside this branch (we omit it and the group if +% there is no quantifier), \cs{@@_compile_u_payload:} puts +% the right tests corresponding to the contents of the variable, which +% we store in \cs{l_@@_internal_a_tl}. The behaviour of |\u| % then depends on whether we are within a |\c{...}| escape (in this % case, the variable is turned to a string), or not. % \begin{macrocode} \cs_new_protected:Npn \@@_compile_u_end: { + \@@_compile_if_quantifier:TFw + { + \tl_build_put_right:Nn \l_@@_build_tl + { + \@@_group_no_capture:nnnN { \if_false: } \fi: + \@@_branch:n { \if_false: } \fi: + } + \@@_compile_u_payload: + \tl_build_put_right:Nn \l_@@_build_tl { \if_false: { \fi: } } + \@@_compile_quantifier:w + } + { \@@_compile_u_payload: } + } +\cs_new_protected:Npn \@@_compile_u_payload: + { \tl_set:Nv \l_@@_internal_a_tl { \l_@@_internal_a_tl } \if_int_compare:w \l_@@_mode_int = \c_@@_outer_mode_int \@@_compile_u_not_cs: @@ -3465,6 +3626,160 @@ % % \subsubsection{Showing regexes} % +% \begin{macro}[rEXP] +% { +% \@@_clean_bool:n, \@@_clean_int:n, \@@_clean_int_aux:N, +% \@@_clean_regex:n, \@@_clean_regex_loop:w, \@@_clean_branch:n, +% \@@_clean_branch_loop:n, \@@_clean_assertion:Nn, +% \@@_clean_class:NnnnN, \@@_clean_group:nnnN, \@@_clean_class:n, +% \@@_clean_class_loop:nnn, \@@_clean_exact_cs:n, +% \@@_clean_exact_cs:w +% } +% Before showing a regex we check that it is \enquote{clean} in the +% sense that it has the correct internal structure. We do this (in +% the implementation of \cs{regex_show:N} and \cs{regex_log:N}) by +% comparing it with a cleaned-up version of the same regex. Along the +% way we also need similar functions for other types: all +% \cs[no-index]{@@_clean_\meta{type}:n} functions produce valid +% \meta{type} tokens (bool, explicit integer, etc.\@) from arbitrary +% input, and the output coincides with the input if that was valid. +% \begin{macrocode} +\cs_new:Npn \@@_clean_bool:n #1 + { + \tl_if_single:nTF {#1} + { \bool_if:NTF #1 \c_true_bool \c_false_bool } + { \c_true_bool } + } +\cs_new:Npn \@@_clean_int:n #1 + { + \tl_if_head_eq_meaning:nNTF {#1} - + { - \exp_args:No \@@_clean_int:n { \use_none:n #1 } } + { \int_eval:n { 0 \str_map_function:nN {#1} \@@_clean_int_aux:N } } + } +\cs_new:Npn \@@_clean_int_aux:N #1 + { + \if_int_compare:w 1 < 1 #1 ~ + #1 + \else: + \exp_after:wN \str_map_break: + \fi: + } +\cs_new:Npn \@@_clean_regex:n #1 + { + \@@_clean_regex_loop:w #1 + \@@_branch:n { \q_recursion_tail } \q_recursion_stop + } +\cs_new:Npn \@@_clean_regex_loop:w #1 \@@_branch:n #2 + { + \quark_if_recursion_tail_stop:n {#2} + \@@_branch:n { \@@_clean_branch:n {#2} } + \@@_clean_regex_loop:w + } +\cs_new:Npn \@@_clean_branch:n #1 + { + \@@_clean_branch_loop:n #1 + ? ? ? ? ? ? \prg_break_point: + } +\cs_new:Npn \@@_clean_branch_loop:n #1 + { + \tl_if_single:nF {#1} { \prg_break: } + \token_case_meaning:NnF #1 + { + \@@_command_K: { #1 \@@_clean_branch_loop:n } + \@@_assertion:Nn { #1 \@@_clean_assertion:Nn } + \@@_class:NnnnN { #1 \@@_clean_class:NnnnN } + \@@_group:nnnN { #1 \@@_clean_group:nnnN } + \@@_group_no_capture:nnnN { #1 \@@_clean_group:nnnN } + \@@_group_resetting:nnnN { #1 \@@_clean_group:nnnN } + } + { \prg_break: } + } +\cs_new:Npn \@@_clean_assertion:Nn #1#2 + { + \@@_clean_bool:n {#1} + \tl_if_single:nF {#2} { { \@@_A_test: } \prg_break: } + \token_case_meaning:NnTF #2 + { + \@@_A_test: { } + \@@_G_test: { } + \@@_Z_test: { } + \@@_b_test: { } + } + { {#2} } + { { \@@_A_test: } \prg_break: } + \@@_clean_branch_loop:n + } +\cs_new:Npn \@@_clean_class:NnnnN #1#2#3#4#5 + { + \@@_clean_bool:n {#1} + { \@@_clean_class:n {#2} } + { \int_max:nn { 0 } { \@@_clean_int:n {#3} } } + { \int_max:nn { -1 } { \@@_clean_int:n {#4} } } + \@@_clean_bool:n {#5} + \@@_clean_branch_loop:n + } +\cs_new:Npn \@@_clean_group:nnnN #1#2#3#4 + { + { \@@_clean_regex:n {#1} } + { \int_max:nn { 0 } { \@@_clean_int:n {#2} } } + { \int_max:nn { -1 } { \@@_clean_int:n {#3} } } + \@@_clean_bool:n {#4} + \@@_clean_branch_loop:n + } +\cs_new:Npn \@@_clean_class:n #1 + { \@@_clean_class_loop:nnn #1 ????? \prg_break_point: } +\cs_new:Npn \@@_clean_class_loop:nnn #1#2#3 + { + \tl_if_single:nF {#1} { \prg_break: } + \token_case_meaning:NnTF #1 + { + \@@_item_cs:n { #1 { \@@_clean_regex:n {#2} } } + \@@_item_exact_cs:n { #1 { \@@_clean_exact_cs:n {#2} } } + \@@_item_caseful_equal:n { #1 { \@@_clean_int:n {#2} } } + \@@_item_caseless_equal:n { #1 { \@@_clean_int:n {#2} } } + \@@_item_reverse:n { #1 { \@@_clean_class:n {#2} } } + } + { \@@_clean_class_loop:nnn {#3} } + { + \token_case_meaning:NnTF #1 + { + \@@_item_caseful_range:nn { } + \@@_item_caseless_range:nn { } + \@@_item_exact:nn { } + } + { #1 { \@@_clean_int:n {#2} } { \@@_clean_int:n {#3} } } + { + \token_case_meaning:NnTF #1 + { + \@@_item_catcode:nT { } + \@@_item_catcode_reverse:nT { } + } + { + #1 { \@@_clean_int:n {#2} } { \@@_clean_class:n {#3} } + \@@_clean_class_loop:nnn + } + { \prg_break: } + } + } + } +\cs_new:Npn \@@_clean_exact_cs:n #1 + { + \exp_last_unbraced:Nf \use_none:n + { + \@@_clean_exact_cs:w #1 + \scan_stop: \q_recursion_tail \scan_stop: + \q_recursion_stop + } + } +\cs_new:Npn \@@_clean_exact_cs:w #1 \scan_stop: + { + \quark_if_recursion_tail_stop:n {#1} + \scan_stop: \tl_to_str:n {#1} + \@@_clean_exact_cs:w + } +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\@@_show:N} % Within a group and within \cs{tl_build_begin:N} \ldots{} \cs{tl_build_end:N} we % redefine all the function that can appear in a compiled regex, then @@ -3503,18 +3818,18 @@ \cs_set:Npn \@@_A_test: { anchor~at~start~(\iow_char:N\\A) } \cs_set:Npn \@@_G_test: { anchor~at~start~of~match~(\iow_char:N\\G) } \cs_set_protected:Npn \@@_item_caseful_equal:n ##1 - { \@@_show_one:n { char~code~\int_eval:n{##1} } } + { \@@_show_one:n { char~code~\@@_show_char:n{##1} } } \cs_set_protected:Npn \@@_item_caseful_range:nn ##1##2 { \@@_show_one:n - { range~[\int_eval:n{##1}, \int_eval:n{##2}] } + { range~[\@@_show_char:n{##1}, \@@_show_char:n{##2}] } } \cs_set_protected:Npn \@@_item_caseless_equal:n ##1 - { \@@_show_one:n { char~code~\int_eval:n{##1}~(caseless) } } + { \@@_show_one:n { char~code~\@@_show_char:n{##1}~(caseless) } } \cs_set_protected:Npn \@@_item_caseless_range:nn ##1##2 { \@@_show_one:n - { Range~[\int_eval:n{##1}, \int_eval:n{##2}]~(caseless) } + { Range~[\@@_show_char:n{##1}, \@@_show_char:n{##2}]~(caseless) } } \cs_set_protected:Npn \@@_item_catcode:nT { \@@_show_item_catcode:NnT \c_true_bool } @@ -3523,7 +3838,7 @@ \cs_set_protected:Npn \@@_item_reverse:n { \@@_show_scope:nn { Reversed~match } } \cs_set_protected:Npn \@@_item_exact:nn ##1##2 - { \@@_show_one:n { char~##2,~catcode~##1 } } + { \@@_show_one:n { char~\@@_show_char:n{##2},~catcode~##1 } } \cs_set_eq:NN \@@_item_exact_cs:n \@@_show_item_exact_cs:n \cs_set_protected:Npn \@@_item_cs:n { \@@_show_scope:nn { control~sequence } } @@ -3539,6 +3854,19 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}[EXP]{\@@_show_char:n} +% Show a single character, together with its ascii representation if available. +% This could be extended to beyond ascii. It is not ideal for parentheses themselves. +% \begin{macrocode} +\cs_new:Npn \@@_show_char:n #1 + { + \int_eval:n {#1} + \int_compare:nT { 32 <= #1 <= 126 } + { ~ ( \char_generate:nn {#1} {12} ) } + } +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\@@_show_one:n} % Every part of the final message go through this function, which adds % one line to the output, with the appropriate prefix. @@ -4796,7 +5124,7 @@ \int_add:Nn \l_@@_step_int { 2 } \int_incr:N \l_@@_curr_pos_int \int_set_eq:NN \l_@@_last_char_int \l_@@_curr_char_int - \int_set_eq:NN \l_@@_case_changed_char_int \c_max_int + \cs_set_eq:NN \@@_maybe_compute_ccc: \@@_compute_case_changed_char: \tl_set:Nn \l_@@_curr_token_tl {#1} \int_set:Nn \l_@@_curr_char_int {#2} \int_set:Nn \l_@@_curr_catcode_int { "#3 } @@ -5244,7 +5572,11 @@ \if_charcode:w \c_right_brace_str ##1 \@@_replacement_rbrace:N \else: - \@@_replacement_normal:n + \if_charcode:w \c_left_brace_str ##1 + \@@_replacement_lbrace:N + \else: + \@@_replacement_normal:n + \fi: \fi: ##1 } @@ -5253,14 +5585,14 @@ {#1} \prg_do_nothing: \prg_do_nothing: \if_int_compare:w \l_@@_replacement_csnames_int > 0 \exp_stop_f: - \__kernel_msg_error:nnx { kernel } { replacement-missing-rbrace } + \__kernel_msg_error:nnx { regex } { replacement-missing-rbrace } { \int_use:N \l_@@_replacement_csnames_int } \tl_build_put_right:Nx \l_@@_build_tl { \prg_replicate:nn \l_@@_replacement_csnames_int \cs_end: } \fi: \seq_if_empty:NF \l_@@_replacement_category_seq { - \__kernel_msg_error:nnx { kernel } { replacement-missing-rparen } + \__kernel_msg_error:nnx { regex } { replacement-missing-rparen } { \seq_count:N \l_@@_replacement_category_seq } \seq_clear:N \l_@@_replacement_category_seq } @@ -5303,7 +5635,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_replacement_normal:n} +% \begin{macro}{\@@_replacement_normal:n, \@@_replacement_normal_aux:N} % Most characters are simply sent to the output by % \cs{tl_build_put_right:Nn}, unless a particular category code has been % requested: then \cs{@@_replacement_c_A:w} or a similar auxiliary is @@ -5312,13 +5644,16 @@ % sequence is non-empty there: it contains an empty entry % corresponding to the initial value of % \cs{l_@@_replacement_category_tl}. -% The argument |#1| can be a space, otherwise it is a single -% character. +% The argument |#1| is a single character (including the case of a catcode-other space). +% In case no specific catcode is requested, we taked into account the +% current catcode regime (at the time the replacement is performed) +% as much as reasonable, with all impossible catcodes (escape, +% newline, etc.) being mapped to \enquote{other}. % \begin{macrocode} \cs_new_protected:Npn \@@_replacement_normal:n #1 { \tl_if_empty:NTF \l_@@_replacement_category_tl - { \@@_replacement_put:n {#1} } + { \@@_replacement_normal_aux:N #1 } { % ( \token_if_eq_charcode:NNTF #1 ) { @@ -5326,15 +5661,37 @@ \l_@@_replacement_category_tl } { - \use:c - { - @@_replacement_c_ - \l_@@_replacement_category_tl :w - } - \@@_replacement_normal:n {#1} + \use:c { @@_replacement_c_ \l_@@_replacement_category_tl :w } + ? #1 } } } +\cs_new_protected:Npn \@@_replacement_normal_aux:N #1 + { + \token_if_eq_charcode:NNTF #1 \c_space_token + { \@@_replacement_c_S:w } + { + \exp_after:wN \exp_after:wN + \if_case:w \tex_catcode:D `#1 \exp_stop_f: + \@@_replacement_c_O:w + \or: \@@_replacement_c_B:w + \or: \@@_replacement_c_E:w + \or: \@@_replacement_c_M:w + \or: \@@_replacement_c_T:w + \or: \@@_replacement_c_O:w + \or: \@@_replacement_c_P:w + \or: \@@_replacement_c_U:w + \or: \@@_replacement_c_D:w + \or: \@@_replacement_c_O:w + \or: \@@_replacement_c_S:w + \or: \@@_replacement_c_L:w + \or: \@@_replacement_c_O:w + \or: \@@_replacement_c_A:w + \else: \@@_replacement_c_O:w + \fi: + } + ? #1 + } % \end{macrocode} % \end{macro} % @@ -5342,7 +5699,6 @@ % As in parsing a regular expression, we use an auxiliary built from % |#1| if defined. Otherwise, check for escaped digits (standing from % submatches from $0$ to $9$): anything else is a raw character. -% We use \cs{token_to_str:N} to give spaces the right category code. % \begin{macrocode} \cs_new_protected:Npn \@@_replacement_escaped:N #1 { @@ -5351,8 +5707,7 @@ \if_int_compare:w 1 < 1#1 \exp_stop_f: \@@_replacement_put_submatch:n {#1} \else: - \exp_args:No \@@_replacement_normal:n - { \token_to_str:N #1 } + \@@_replacement_normal:n {#1} \fi: } } @@ -5375,6 +5730,9 @@ { \if_int_compare:w #1 < \l_@@_capturing_group_int \@@_replacement_put_submatch_aux:n {#1} + \else: + \__kernel_msg_expandable_error:nnff { regex } { submatch-too-big } + {#1} { \int_eval:n { \l_@@_capturing_group_int - 1 } } \fi: } \cs_new_protected:Npn \@@_replacement_put_submatch_aux:n #1 @@ -5400,8 +5758,7 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_replacement_g:w #1#2 { - \@@_two_if_eq:NNNNTF - #1 #2 \@@_replacement_normal:n \c_left_brace_str + \token_if_eq_meaning:NNTF #1 \@@_replacement_lbrace:N { \l_@@_internal_a_int = \@@_replacement_g_digits:NN } { \@@_replacement_error:NNN g #1 #2 } } @@ -5448,15 +5805,15 @@ { \token_if_eq_meaning:NNTF #1 \@@_replacement_normal:n { - \exp_after:wN \token_if_eq_charcode:NNTF \c_left_brace_str #2 + \cs_if_exist:cTF { @@_replacement_c_#2:w } + { \@@_replacement_cat:NNN #2 } + { \@@_replacement_error:NNN c #1#2 } + } + { + \token_if_eq_meaning:NNTF #1 \@@_replacement_lbrace:N { \@@_replacement_cu_aux:Nw \@@_replacement_exp_not:N } - { - \cs_if_exist:cTF { @@_replacement_c_#2:w } - { \@@_replacement_cat:NNN #2 } - { \@@_replacement_error:NNN c #1#2 } - } + { \@@_replacement_error:NNN c #1#2 } } - { \@@_replacement_error:NNN c #1#2 } } % \end{macrocode} % \end{macro} @@ -5490,8 +5847,7 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_replacement_u:w #1#2 { - \@@_two_if_eq:NNNNTF - #1 #2 \@@_replacement_normal:n \c_left_brace_str + \token_if_eq_meaning:NNTF #1 \@@_replacement_lbrace:N { \@@_replacement_cu_aux:Nw \@@_replacement_exp_not:V } { \@@_replacement_error:NNN u #1#2 } } @@ -5515,6 +5871,21 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\@@_replacement_lbrace:N} +% Within a |\c{...}| or |\u{...}| construction, this is +% forbidden. Otherwise, this is a raw left brace. +% \begin{macrocode} +\cs_new_protected:Npn \@@_replacement_lbrace:N #1 + { + \if_int_compare:w \l_@@_replacement_csnames_int > 0 \exp_stop_f: + \__kernel_msg_error:nnn { regex } { cu-lbrace } { u } + \else: + \@@_replacement_normal:n {#1} + \fi: + } +% \end{macrocode} +% \end{macro} +% % \subsubsection{Characters in replacement} % % \begin{macro}{\@@_replacement_cat:NNN} @@ -5528,12 +5899,12 @@ \cs_new_protected:Npn \@@_replacement_cat:NNN #1#2#3 { \token_if_eq_meaning:NNTF \prg_do_nothing: #3 - { \__kernel_msg_error:nn { kernel } { replacement-catcode-end } } + { \__kernel_msg_error:nn { regex } { replacement-catcode-end } } { \int_compare:nNnTF { \l_@@_replacement_csnames_int } > 0 { \__kernel_msg_error:nnnn - { kernel } { replacement-catcode-in-cs } {#1} {#3} + { regex } { replacement-catcode-in-cs } {#1} {#3} #2 #3 } { @@ -5549,7 +5920,7 @@ \@@_char_if_alphanumeric:NTF #3 { \__kernel_msg_error:nnnn - { kernel } { replacement-catcode-escaped } + { regex } { replacement-catcode-escaped } {#1} {#3} } { } @@ -5713,7 +6084,7 @@ \cs_new_protected:Npn \@@_replacement_c_S:w #1#2 { \if_int_compare:w `#2 = 0 \exp_stop_f: - \__kernel_msg_error:nn { kernel } { replacement-null-space } + \__kernel_msg_error:nn { regex } { replacement-null-space } \fi: \tex_lccode:D `\ = `#2 \scan_stop: \tex_lowercase:D { \@@_replacement_put:n {~} } @@ -5756,7 +6127,7 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_replacement_error:NNN #1#2#3 { - \__kernel_msg_error:nnx { kernel } { replacement-#1 } {#3} + \__kernel_msg_error:nnx { regex } { replacement-#1 } {#3} #2 #3 } % \end{macrocode} @@ -5805,26 +6176,35 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\regex_show:N, \regex_show:n} +% \begin{macro} +% { +% \regex_show:n, \regex_log:n, \@@_show:Nn, +% \regex_show:N, \regex_log:N, \@@_show:NN +% } % User functions: the \texttt{n} variant requires compilation first. % Then show the variable with some appropriate text. The auxiliary -% is defined in a different section. +% \cs{@@_show:N} is defined in a different section. % \begin{macrocode} -\cs_new_protected:Npn \regex_show:n #1 +\cs_new_protected:Npn \regex_show:n { \@@_show:Nn \__kernel_msg_show:nnxxxx } +\cs_new_protected:Npn \regex_log:n { \@@_show:Nn \__kernel_msg_log:nnxxxx } +\cs_new_protected:Npn \@@_show:Nn #1#2 { - \@@_compile:n {#1} + \@@_compile:n {#2} \@@_show:N \l_@@_internal_regex - \msg_show:nnxxxx { LaTeX / kernel } { show-regex } - { \tl_to_str:n {#1} } { } + #1 { regex } { show } + { \tl_to_str:n {#2} } { } { \l_@@_internal_a_tl } { } } -\cs_new_protected:Npn \regex_show:N #1 +\cs_new_protected:Npn \regex_show:N { \@@_show:NN \__kernel_msg_show:nnxxxx } +\cs_new_protected:Npn \regex_log:N { \@@_show:NN \__kernel_msg_log:nnxxxx } +\cs_new_protected:Npn \@@_show:NN #1#2 { - \__kernel_chk_defined:NT #1 + \__kernel_chk_tl_type:NnnT #2 { regex } + { \exp_args:No \@@_clean_regex:n {#2} } { - \@@_show:N #1 - \msg_show:nnxxxx { LaTeX / kernel } { show-regex } - { } { \token_to_str:N #1 } + \@@_show:N #2 + #1 { regex } { show } + { } { \token_to_str:N #2 } { \l_@@_internal_a_tl } { } } } @@ -6148,7 +6528,7 @@ } = 0 { - \__kernel_msg_error:nnxxx { kernel } { result-unbalanced } + \__kernel_msg_error:nnxxx { regex } { result-unbalanced } { splitting~or~extracting~submatches } { \flag_height:n { @@_end } } { \flag_height:n { @@_begin } } @@ -6330,7 +6710,7 @@ { \if_int_compare:w \l_@@_balance_int = 0 \exp_stop_f: \else: - \__kernel_msg_error:nnxxx { kernel } { result-unbalanced } + \__kernel_msg_error:nnxxx { regex } { result-unbalanced } { replacing } { \int_max:nn { - \l_@@_balance_int } { 0 } } { \int_max:nn { \l_@@_balance_int } { 0 } } @@ -6731,14 +7111,14 @@ % \begin{macrocode} \use:x { - \__kernel_msg_new:nnn { kernel } { trailing-backslash } + \__kernel_msg_new:nnn { regex } { trailing-backslash } { Trailing~escape~char~'\iow_char:N\\'~in~regex~or~replacement. } - \__kernel_msg_new:nnn { kernel } { x-missing-rbrace } + \__kernel_msg_new:nnn { regex } { x-missing-rbrace } { Missing~brace~'\iow_char:N\}'~in~regex~ '...\iow_char:N\\x\iow_char:N\{...##1'. } - \__kernel_msg_new:nnn { kernel } { x-overflow } + \__kernel_msg_new:nnn { regex } { x-overflow } { Character~code~##1~too~large~in~ \iow_char:N\\x\iow_char:N\{##2\iow_char:N\}~regex. @@ -6748,7 +7128,7 @@ % % Invalid quantifier. % \begin{macrocode} -\__kernel_msg_new:nnnn { kernel } { invalid-quantifier } +\__kernel_msg_new:nnnn { regex } { invalid-quantifier } { Braced~quantifier~'#1'~may~not~be~followed~by~'#2'. } { The~character~'#2'~is~invalid~in~the~braced~quantifier~'#1'.~ @@ -6760,13 +7140,13 @@ % Messages for missing or extra closing brackets and parentheses, with % some fancy singular/plural handling for the case of parentheses. % \begin{macrocode} -\__kernel_msg_new:nnnn { kernel } { missing-rbrack } +\__kernel_msg_new:nnnn { regex } { missing-rbrack } { Missing~right~bracket~inserted~in~regular~expression. } { LaTeX~was~given~a~regular~expression~where~a~character~class~ was~started~with~'[',~but~the~matching~']'~is~missing. } -\__kernel_msg_new:nnnn { kernel } { missing-rparen } +\__kernel_msg_new:nnnn { regex } { missing-rparen } { Missing~right~ \int_compare:nTF { #1 = 1 } { parenthesis } { parentheses } ~ @@ -6776,7 +7156,7 @@ LaTeX~was~given~a~regular~expression~with~\int_eval:n {#1} ~ more~left~parentheses~than~right~parentheses. } -\__kernel_msg_new:nnnn { kernel } { extra-rparen } +\__kernel_msg_new:nnnn { regex } { extra-rparen } { Extra~right~parenthesis~ignored~in~regular~expression. } { LaTeX~came~across~a~closing~parenthesis~when~no~submatch~group~ @@ -6786,7 +7166,7 @@ % % Some escaped alphanumerics are not allowed everywhere. % \begin{macrocode} -\__kernel_msg_new:nnnn { kernel } { bad-escape } +\__kernel_msg_new:nnnn { regex } { bad-escape } { Invalid~escape~'\iow_char:N\\#1'~ \@@_if_in_cs:TF { within~a~control~sequence. } @@ -6814,14 +7194,14 @@ % % Range errors. % \begin{macrocode} -\__kernel_msg_new:nnnn { kernel } { range-missing-end } +\__kernel_msg_new:nnnn { regex } { range-missing-end } { Invalid~end-point~for~range~'#1-#2'~in~character~class. } { The~end-point~'#2'~of~the~range~'#1-#2'~may~not~serve~as~an~ end-point~for~a~range:~alphanumeric~characters~should~not~be~ escaped,~and~non-alphanumeric~characters~should~be~escaped. } -\__kernel_msg_new:nnnn { kernel } { range-backwards } +\__kernel_msg_new:nnnn { regex } { range-backwards } { Range~'[#1-#2]'~out~of~order~in~character~class. } { In~ranges~of~characters~'[x-y]'~appearing~in~character~classes,~ @@ -6833,7 +7213,7 @@ % % Errors related to |\c| and |\u|. % \begin{macrocode} -\__kernel_msg_new:nnnn { kernel } { c-bad-mode } +\__kernel_msg_new:nnnn { regex } { c-bad-mode } { Invalid~nested~'\iow_char:N\\c'~escape~in~regular~expression. } { The~'\iow_char:N\\c'~escape~cannot~be~used~within~ @@ -6841,33 +7221,40 @@ nor~another~category~test.~ To~combine~several~category~tests,~use~'\iow_char:N\\c[...]'. } -\__kernel_msg_new:nnnn { kernel } { c-C-invalid } +\__kernel_msg_new:nnnn { regex } { c-C-invalid } { '\iow_char:N\\cC'~should~be~followed~by~'.'~or~'(',~not~'#1'. } { The~'\iow_char:N\\cC'~construction~restricts~the~next~item~to~be~a~ control~sequence~or~the~next~group~to~be~made~of~control~sequences.~ It~only~makes~sense~to~follow~it~by~'.'~or~by~a~group. } -\__kernel_msg_new:nnnn { kernel } { c-lparen-in-class } +\__kernel_msg_new:nnnn { regex } { cu-lbrace } + { Left~braces~must~be~escaped~in~'\iow_char:N\\#1{...}'. } + { + Constructions~such~as~'\iow_char:N\\#1{...\iow_char:N\{...}'~are~ + not~allowed~and~should~be~replaced~by~ + '\iow_char:N\\#1{...\token_to_str:N\{...}'. + } +\__kernel_msg_new:nnnn { regex } { c-lparen-in-class } { Catcode~test~cannot~apply~to~group~in~character~class } { Construction~such~as~'\iow_char:N\\cL(abc)'~are~not~allowed~inside~a~ class~'[...]'~because~classes~do~not~match~multiple~characters~at~once. } -\__kernel_msg_new:nnnn { kernel } { c-missing-rbrace } +\__kernel_msg_new:nnnn { regex } { c-missing-rbrace } { Missing~right~brace~inserted~for~'\iow_char:N\\c'~escape. } { LaTeX~was~given~a~regular~expression~where~a~ '\iow_char:N\\c\iow_char:N\{...'~construction~was~not~ended~ with~a~closing~brace~'\iow_char:N\}'. } -\__kernel_msg_new:nnnn { kernel } { c-missing-rbrack } +\__kernel_msg_new:nnnn { regex } { c-missing-rbrack } { Missing~right~bracket~inserted~for~'\iow_char:N\\c'~escape. } { A~construction~'\iow_char:N\\c[...'~appears~in~a~ regular~expression,~but~the~closing~']'~is~not~present. } -\__kernel_msg_new:nnnn { kernel } { c-missing-category } +\__kernel_msg_new:nnnn { regex } { c-missing-category } { Invalid~character~'#1'~following~'\iow_char:N\\c'~escape. } { In~regular~expressions,~the~'\iow_char:N\\c'~escape~sequence~ @@ -6875,19 +7262,19 @@ capital~letter~representing~a~character~category,~namely~ one~of~'ABCDELMOPSTU'. } -\__kernel_msg_new:nnnn { kernel } { c-trailing } +\__kernel_msg_new:nnnn { regex } { c-trailing } { Trailing~category~code~escape~'\iow_char:N\\c'... } { A~regular~expression~ends~with~'\iow_char:N\\c'~followed~ by~a~letter.~It~will~be~ignored. } -\__kernel_msg_new:nnnn { kernel } { u-missing-lbrace } +\__kernel_msg_new:nnnn { regex } { u-missing-lbrace } { Missing~left~brace~following~'\iow_char:N\\u'~escape. } { The~'\iow_char:N\\u'~escape~sequence~must~be~followed~by~ a~brace~group~with~the~name~of~the~variable~to~use. } -\__kernel_msg_new:nnnn { kernel } { u-missing-rbrace } +\__kernel_msg_new:nnnn { regex } { u-missing-rbrace } { Missing~right~brace~inserted~for~'\iow_char:N\\u'~escape. } { LaTeX~ @@ -6901,14 +7288,14 @@ % % Errors when encountering the \textsc{posix} syntax |[:...:]|. % \begin{macrocode} -\__kernel_msg_new:nnnn { kernel } { posix-unsupported } +\__kernel_msg_new:nnnn { regex } { posix-unsupported } { POSIX~collating~element~'[#1 ~ #1]'~not~supported. } { The~'[.foo.]'~and~'[=bar=]'~syntaxes~have~a~special~meaning~ in~POSIX~regular~expressions.~This~is~not~supported~by~LaTeX.~ Maybe~you~forgot~to~escape~a~left~bracket~in~a~character~class? } -\__kernel_msg_new:nnnn { kernel } { posix-unknown } +\__kernel_msg_new:nnnn { regex } { posix-unknown } { POSIX~class~'[:#1:]'~unknown. } { '[:#1:]'~is~not~among~the~known~POSIX~classes~ @@ -6917,7 +7304,7 @@ '[:print:]',~'[:punct:]',~'[:space:]',~'[:upper:]',~ '[:word:]',~and~'[:xdigit:]'. } -\__kernel_msg_new:nnnn { kernel } { posix-missing-close } +\__kernel_msg_new:nnnn { regex } { posix-missing-close } { Missing~closing~':]'~for~POSIX~class. } { The~POSIX~syntax~'#1'~must~be~followed~by~':]',~not~'#2'. } % \end{macrocode} @@ -6926,7 +7313,7 @@ % with an unbalanced token list, which we must re-balance by adding % begin-group or end-group character tokens. % \begin{macrocode} -\__kernel_msg_new:nnnn { kernel } { result-unbalanced } +\__kernel_msg_new:nnnn { regex } { result-unbalanced } { Missing~brace~inserted~when~#1. } { LaTeX~was~asked~to~do~some~regular~expression~operation,~ @@ -6938,13 +7325,13 @@ % % Error message for unknown options. % \begin{macrocode} -\__kernel_msg_new:nnnn { kernel } { unknown-option } +\__kernel_msg_new:nnnn { regex } { unknown-option } { Unknown~option~'#1'~for~regular~expressions. } { The~only~available~option~is~'case-insensitive',~toggled~by~ '(?i)'~and~'(?-i)'. } -\__kernel_msg_new:nnnn { kernel } { special-group-unknown } +\__kernel_msg_new:nnnn { regex } { special-group-unknown } { Unknown~special~group~'#1~...'~in~a~regular~expression. } { The~only~valid~constructions~starting~with~'(?'~are~ @@ -6954,21 +7341,21 @@ % % Errors in the replacement text. % \begin{macrocode} -\__kernel_msg_new:nnnn { kernel } { replacement-c } +\__kernel_msg_new:nnnn { regex } { replacement-c } { Misused~'\iow_char:N\\c'~command~in~a~replacement~text. } { In~a~replacement~text,~the~'\iow_char:N\\c'~escape~sequence~ can~be~followed~by~one~of~the~letters~'ABCDELMOPSTU'~ or~a~brace~group,~not~by~'#1'. } -\__kernel_msg_new:nnnn { kernel } { replacement-u } +\__kernel_msg_new:nnnn { regex } { replacement-u } { Misused~'\iow_char:N\\u'~command~in~a~replacement~text. } { In~a~replacement~text,~the~'\iow_char:N\\u'~escape~sequence~ must~be~~followed~by~a~brace~group~holding~the~name~of~the~ variable~to~use. } -\__kernel_msg_new:nnnn { kernel } { replacement-g } +\__kernel_msg_new:nnnn { regex } { replacement-g } { Missing~brace~for~the~'\iow_char:N\\g'~construction~ in~a~replacement~text. @@ -6978,7 +7365,7 @@ submatches~are~represented~either~as~'\iow_char:N \\g{dd..d}',~ or~'\\d',~where~'d'~are~single~digits.~Here,~a~brace~is~missing. } -\__kernel_msg_new:nnnn { kernel } { replacement-catcode-end } +\__kernel_msg_new:nnnn { regex } { replacement-catcode-end } { Missing~character~for~the~'\iow_char:N\\c<category><character>'~ construction~in~a~replacement~text. @@ -6989,7 +7376,7 @@ the~character~category.~Then,~a~character~must~follow.~LaTeX~ reached~the~end~of~the~replacement~when~looking~for~that. } -\__kernel_msg_new:nnnn { kernel } { replacement-catcode-escaped } +\__kernel_msg_new:nnnn { regex } { replacement-catcode-escaped } { Escaped~letter~or~digit~after~category~code~in~replacement~text. } @@ -6999,7 +7386,7 @@ the~character~category.~Then,~a~character~must~follow,~not~ '\iow_char:N\\#2'. } -\__kernel_msg_new:nnnn { kernel } { replacement-catcode-in-cs } +\__kernel_msg_new:nnnn { regex } { replacement-catcode-in-cs } { Category~code~'\iow_char:N\\c#1#3'~ignored~inside~ '\iow_char:N\\c\{...\}'~in~a~replacement~text. @@ -7009,7 +7396,7 @@ '\iow_char:N\\c\{...\}'~are~ignored~when~building~the~control~ sequence~name. } -\__kernel_msg_new:nnnn { kernel } { replacement-null-space } +\__kernel_msg_new:nnnn { regex } { replacement-null-space } { TeX~cannot~build~a~space~token~with~character~code~0. } { You~asked~for~a~character~token~with~category~space,~ @@ -7018,31 +7405,33 @@ This~specific~case~is~impossible~and~will~be~replaced~ by~a~normal~space. } -\__kernel_msg_new:nnnn { kernel } { replacement-missing-rbrace } +\__kernel_msg_new:nnnn { regex } { replacement-missing-rbrace } { Missing~right~brace~inserted~in~replacement~text. } { There~ \int_compare:nTF { #1 = 1 } { was } { were } ~ #1~ missing~right~\int_compare:nTF { #1 = 1 } { brace } { braces } . } -\__kernel_msg_new:nnnn { kernel } { replacement-missing-rparen } +\__kernel_msg_new:nnnn { regex } { replacement-missing-rparen } { Missing~right~parenthesis~inserted~in~replacement~text. } { There~ \int_compare:nTF { #1 = 1 } { was } { were } ~ #1~ missing~right~ \int_compare:nTF { #1 = 1 } { parenthesis } { parentheses } . } +\__kernel_msg_new:nnn { regex } { submatch-too-big } + { Submatch~#1~used~but~regex~only~has~#2~group(s) } % \end{macrocode} % % Some escaped alphanumerics are not allowed everywhere. % \begin{macrocode} -\__kernel_msg_new:nnnn { kernel } { backwards-quantifier } +\__kernel_msg_new:nnnn { regex } { backwards-quantifier } { Quantifer~"{#1,#2}"~is~backwards. } { The~values~given~in~a~quantifier~must~be~in~order. } % \end{macrocode} % % Used when showing a regex. % \begin{macrocode} -\__kernel_msg_new:nnn { kernel } { show-regex } +\__kernel_msg_new:nnn { regex } { show } { >~Compiled~regex~ \tl_if_empty:nTF {#1} { variable~ #2 } { {#1} } : diff --git a/macros/latex/contrib/l3kernel/l3seq.dtx b/macros/latex/contrib/l3kernel/l3seq.dtx index 046f42b8c5..7b6cc0c857 100644 --- a/macros/latex/contrib/l3kernel/l3seq.dtx +++ b/macros/latex/contrib/l3kernel/l3seq.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -144,6 +144,29 @@ % (assuming \TeX{}'s normal category code r\'egime). % If the \meta{delimiter} is empty, the \meta{token list} is split % into \meta{items} as a \meta{token list}. +% See also \cs{seq_set_split_keep_spaces:Nnn}, which omits space stripping. +% \end{function} +% +% \begin{function}[added = 2021-03-24] +% { +% \seq_set_split_keep_spaces:Nnn , \seq_set_split_keep_spaces:NnV , +% \seq_gset_split_keep_spaces:Nnn, \seq_gset_split_keep_spaces:NnV +% } +% \begin{syntax} +% \cs{seq_set_split_keep_spaces:Nnn} \meta{sequence} \Arg{delimiter} \Arg{token list} +% \end{syntax} +% Splits the \meta{token list} into \meta{items} separated +% by \meta{delimiter}, and assigns the result to the \meta{sequence}. +% One set of outer braces is removed (if any) but any surrounding spaces +% are retained: any braces \emph{inside} one or more spaces are +% therefore kept. Empty \meta{items} are preserved by +% \cs{seq_set_split_keep_spaces:Nnn}, and can be removed afterwards using +% \cs{seq_remove_all:Nn} \meta{sequence} |{}|. +% The \meta{delimiter} may not contain |{|, |}| or |#| +% (assuming \TeX{}'s normal category code r\'egime). +% If the \meta{delimiter} is empty, the \meta{token list} is split +% into \meta{items} as a \meta{token list}. +% See also \cs{seq_set_split:Nnn}, which removes spaces around the delimiters. % \end{function} % % \begin{function} @@ -512,7 +535,7 @@ % Tests if the \meta{item} is present in the \meta{sequence}. % \end{function} % -% \section{Mapping to sequences} +% \section{Mapping over sequences} % % All mappings are done at the current group level, \emph{i.e.}~any % local assignments made by the \meta{function} or \meta{code} discussed @@ -965,14 +988,14 @@ % % \section{Viewing sequences} % -% \begin{function}[updated = 2015-08-01]{\seq_show:N, \seq_show:c} +% \begin{function}[updated = 2021-04-29]{\seq_show:N, \seq_show:c} % \begin{syntax} % \cs{seq_show:N} \meta{sequence} % \end{syntax} % Displays the entries in the \meta{sequence} in the terminal. % \end{function} % -% \begin{function}[added = 2014-08-12, updated = 2015-08-01]{\seq_log:N, \seq_log:c} +% \begin{function}[added = 2014-08-12, updated = 2021-04-29]{\seq_log:N, \seq_log:c} % \begin{syntax} % \cs{seq_log:N} \meta{sequence} % \end{syntax} @@ -1054,7 +1077,7 @@ % \begin{macrocode} \cs_new:Npn \@@_item:n { - \__kernel_msg_expandable_error:nn { kernel } { misused-sequence } + \__kernel_msg_expandable_error:nn { seq } { misused } \use_none:n } % \end{macrocode} @@ -1210,10 +1233,15 @@ % \seq_set_split:Nnn , \seq_set_split:NnV , % \seq_gset_split:Nnn, \seq_gset_split:NnV % } +% \begin{macro} +% { +% \seq_set_split_keep_spaces:Nnn , \seq_set_split_keep_spaces:NnV , +% \seq_gset_split_keep_spaces:Nnn, \seq_gset_split_keep_spaces:NnV +% } % \begin{macro}{\@@_set_split:NNnn} % \begin{macro} % { -% \@@_set_split_auxi:w, \@@_set_split_auxii:w, +% \@@_set_split:Nw, \@@_set_split:w, % \@@_set_split_end: % } % When the separator is empty, everything is very simple, just map @@ -1238,46 +1266,53 @@ % braces which are outermost after space trimming. % \begin{macrocode} \cs_new_protected:Npn \seq_set_split:Nnn - { \@@_set_split:NNnn \__kernel_tl_set:Nx } + { \@@_set_split:NNNnn \__kernel_tl_set:Nx \tl_trim_spaces:n } \cs_new_protected:Npn \seq_gset_split:Nnn - { \@@_set_split:NNnn \__kernel_tl_gset:Nx } -\cs_new_protected:Npn \@@_set_split:NNnn #1#2#3#4 + { \@@_set_split:NNNnn \__kernel_tl_gset:Nx \tl_trim_spaces:n } +\cs_new_protected:Npn \seq_set_split_keep_spaces:Nnn + { \@@_set_split:NNNnn \__kernel_tl_set:Nx \exp_not:n } +\cs_new_protected:Npn \seq_gset_split_keep_spaces:Nnn + { \@@_set_split:NNNnn \__kernel_tl_gset:Nx \exp_not:n } +\cs_new_protected:Npn \@@_set_split:NNNnn #1#2#3#4#5 { - \tl_if_empty:nTF {#3} + \tl_if_empty:nTF {#4} { \tl_set:Nn \l_@@_internal_a_tl - { \tl_map_function:nN {#4} \@@_wrap_item:n } + { \tl_map_function:nN {#5} \@@_wrap_item:n } } { \tl_set:Nn \l_@@_internal_a_tl { - \@@_set_split_auxi:w \prg_do_nothing: - #4 + \@@_set_split:Nw #2 \prg_do_nothing: + #5 \@@_set_split_end: } - \tl_replace_all:Nnn \l_@@_internal_a_tl { #3 } + \tl_replace_all:Nnn \l_@@_internal_a_tl {#4} { \@@_set_split_end: - \@@_set_split_auxi:w \prg_do_nothing: + \@@_set_split:Nw #2 \prg_do_nothing: } \__kernel_tl_set:Nx \l_@@_internal_a_tl { \l_@@_internal_a_tl } } - #1 #2 { \s_@@ \l_@@_internal_a_tl } + #1 #3 { \s_@@ \l_@@_internal_a_tl } } -\cs_new:Npn \@@_set_split_auxi:w #1 \@@_set_split_end: +\cs_new:Npn \@@_set_split:Nw #1#2 \@@_set_split_end: { - \exp_not:N \@@_set_split_auxii:w - \exp_args:No \tl_trim_spaces:n {#1} + \exp_not:N \@@_set_split:w + \exp_args:No #1 {#2} \exp_not:N \@@_set_split_end: } -\cs_new:Npn \@@_set_split_auxii:w #1 \@@_set_split_end: +\cs_new:Npn \@@_set_split:w #1 \@@_set_split_end: { \@@_wrap_item:n {#1} } \cs_generate_variant:Nn \seq_set_split:Nnn { NnV } \cs_generate_variant:Nn \seq_gset_split:Nnn { NnV } +\cs_generate_variant:Nn \seq_set_split_keep_spaces:Nnn { NnV } +\cs_generate_variant:Nn \seq_gset_split_keep_spaces:Nnn { NnV } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} +% \end{macro} % % \begin{macro}{\seq_concat:NNN, \seq_concat:ccc} % \UnitTested @@ -1582,7 +1617,7 @@ { \int_compare:nNnTF { \seq_count:N #2 } > \c_max_register_int { - \__kernel_msg_error:nnx { kernel } { shuffle-too-large } + \__kernel_msg_error:nnx { seq } { shuffle-too-large } { \token_to_str:N #2 } } { @@ -1924,7 +1959,7 @@ % \end{macrocode} % \end{macro} % -% \subsection{Mapping to sequences} +% \subsection{Mapping over sequences} % % \begin{macro}{\seq_map_break:} % \UnitTested @@ -2324,25 +2359,38 @@ % \subsection{Viewing sequences} % % \begin{macro}{\seq_show:N, \seq_show:c, \seq_log:N, \seq_log:c, \@@_show:NN} +% \begin{macro}[rEXP]{\@@_show_validate:nn} % \UnitTested -% Apply the general \cs{msg_show:nnnnnn}. +% Apply the general \cs{__kernel_chk_tl_type:NnnT}. % \begin{macrocode} -\cs_new_protected:Npn \seq_show:N { \@@_show:NN \msg_show:nnxxxx } +\cs_new_protected:Npn \seq_show:N { \@@_show:NN \__kernel_msg_show:nnxxxx } \cs_generate_variant:Nn \seq_show:N { c } -\cs_new_protected:Npn \seq_log:N { \@@_show:NN \msg_log:nnxxxx } +\cs_new_protected:Npn \seq_log:N { \@@_show:NN \__kernel_msg_log:nnxxxx } \cs_generate_variant:Nn \seq_log:N { c } \cs_new_protected:Npn \@@_show:NN #1#2 { - \__kernel_chk_defined:NT #2 + \__kernel_chk_tl_type:NnnT #2 { seq } { - #1 { LaTeX/kernel } { show-seq } + \s_@@ + \exp_after:wN \use_i:nn \exp_after:wN \@@_show_validate:nn #2 + \q_recursion_tail \q_recursion_tail \q_recursion_stop + } + { + #1 { seq } { show } { \token_to_str:N #2 } { \seq_map_function:NN #2 \msg_show_item:n } { } { } } } +\cs_new:Npn \@@_show_validate:nn #1#2 + { + \quark_if_recursion_tail_stop:n {#2} + \@@_wrap_item:n {#2} + \@@_show_validate:nn + } % \end{macrocode} % \end{macro} +% \end{macro} % % \subsection{Scratch sequences} % diff --git a/macros/latex/contrib/l3kernel/l3skip.dtx b/macros/latex/contrib/l3kernel/l3skip.dtx index 97eaef163d..67c71a890b 100644 --- a/macros/latex/contrib/l3kernel/l3skip.dtx +++ b/macros/latex/contrib/l3kernel/l3skip.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -1395,7 +1395,7 @@ % \begin{macro}{\@@_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[index=str_case:nnTF]{str_case:nn(TF)} as described in \pkg{l3basics}. +% \cs{str_case:nnTF} as described in \pkg{l3basics}. % \begin{macrocode} \cs_new:Npn \dim_case:nnTF #1 { diff --git a/macros/latex/contrib/l3kernel/l3sort.dtx b/macros/latex/contrib/l3kernel/l3sort.dtx index 13b94daf67..58e65d59b1 100644 --- a/macros/latex/contrib/l3kernel/l3sort.dtx +++ b/macros/latex/contrib/l3kernel/l3sort.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -65,7 +65,7 @@ % { \sort_return_same: } % } % \end{verbatim} -% results in \cs{l_foo_clist} holding the values +% results in \cs[no-index]{l_foo_clist} holding the values % |{ -2 , 01 , +1 , 3 , 5 }| sorted in non-decreasing order. % % The code defining the comparison should call @@ -590,14 +590,14 @@ \cs_new_protected:Npn \@@_return_mark:w #1 \s_@@_mark { } \cs_new_protected:Npn \@@_return_none_error: { - \__kernel_msg_error:nnxx { kernel } { return-none } + \__kernel_msg_error:nnxx { sort } { return-none } { \tex_the:D \tex_toks:D \l_@@_A_int } { \tex_the:D \tex_toks:D \l_@@_C_int } \@@_return_same:w \@@_return_none_error: } \cs_new_protected:Npn \@@_return_two_error: { - \__kernel_msg_error:nnxx { kernel } { return-two } + \__kernel_msg_error:nnxx { sort } { return-two } { \tex_the:D \tex_toks:D \l_@@_A_int } { \tex_the:D \tex_toks:D \l_@@_C_int } } @@ -1025,12 +1025,12 @@ { \cs_set_eq:NN \toksdef \@@_disabled_toksdef:n } \cs_new_protected:Npn \@@_disabled_toksdef:n #1 { - \__kernel_msg_error:nnx { kernel } { toksdef } + \__kernel_msg_error:nnx { sort } { toksdef } { \token_to_str:N #1 } \@@_error: \tex_toksdef:D #1 } -\__kernel_msg_new:nnnn { kernel } { toksdef } +\__kernel_msg_new:nnnn { sort } { toksdef } { Allocation~of~\iow_char:N\\toks~registers~impossible~while~sorting. } { The~comparison~code~used~for~sorting~a~list~has~attempted~to~ @@ -1049,13 +1049,13 @@ \cs_new_protected:Npn \@@_too_long_error:NNw #1#2 \fi: { \fi: - \__kernel_msg_error:nnxxx { kernel } { too-large } + \__kernel_msg_error:nnxxx { sort } { too-large } { \token_to_str:N #2 } { \int_eval:n { \l_@@_true_max_int - \l_@@_min_int } } { \int_eval:n { \l_@@_top_int - \l_@@_min_int } } #1 \@@_error: } -\__kernel_msg_new:nnnn { kernel } { too-large } +\__kernel_msg_new:nnnn { sort } { too-large } { The~list~#1~is~too~long~to~be~sorted~by~TeX. } { TeX~has~#2~toks~registers~still~available:~ @@ -1066,7 +1066,7 @@ % \end{macro} % % \begin{macrocode} -\__kernel_msg_new:nnnn { kernel } { return-none } +\__kernel_msg_new:nnnn { sort } { return-none } { The~comparison~code~did~not~return. } { When~sorting~a~list,~the~code~to~compare~items~#1~and~#2~ @@ -1075,7 +1075,7 @@ \iow_char:N\\sort_return_swapped: .~ Exactly~one~of~these~should~be~called. } -\__kernel_msg_new:nnnn { kernel } { return-two } +\__kernel_msg_new:nnnn { sort } { return-two } { The~comparison~code~returned~multiple~times. } { When~sorting~a~list,~the~code~to~compare~items~#1~and~#2~called~ diff --git a/macros/latex/contrib/l3kernel/l3str-convert.dtx b/macros/latex/contrib/l3kernel/l3str-convert.dtx index 4cc29c2d21..23fbf0421b 100644 --- a/macros/latex/contrib/l3kernel/l3str-convert.dtx +++ b/macros/latex/contrib/l3kernel/l3str-convert.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -156,7 +156,7 @@ % \begin{verbatim} % \str_set_convert:Nnnn \l_foo_str { Hello! } { } { utf16/hex } % \end{verbatim} -% results in the variable \cs{l_foo_str} holding the string +% results in the variable \cs[no-index]{l_foo_str} holding the string % \texttt{FEFF00480065006C006C006F0021}. This is obtained by % converting each character in the (native) string \texttt{Hello!} to % the \textsc{utf-16} encoding, and expressing each byte as a pair of diff --git a/macros/latex/contrib/l3kernel/l3str.dtx b/macros/latex/contrib/l3kernel/l3str.dtx index 2a0b175bfe..10d4fa865e 100644 --- a/macros/latex/contrib/l3kernel/l3str.dtx +++ b/macros/latex/contrib/l3kernel/l3str.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -401,74 +401,41 @@ % not be used within this string. % \end{function} % -% \section{Mapping to strings} +% \section{Mapping over strings} % % All mappings are done at the current group level, \emph{i.e.}~any % local assignments made by the \meta{function} or \meta{code} discussed % below remain in effect after the loop. % % \begin{function}[added = 2017-11-14, rEXP] -% {\str_map_function:NN, \str_map_function:cN} -% \begin{syntax} -% \cs{str_map_function:NN} \meta{str~var} \meta{function} -% \end{syntax} -% Applies \meta{function} to every \meta{character} in the -% \meta{str~var} including spaces. -% See also \cs{str_map_function:nN}. -% \end{function} -% -% \begin{function}[added = 2017-11-14, rEXP] -% {\str_map_function:nN} +% {\str_map_function:nN, \str_map_function:NN, \str_map_function:cN} % \begin{syntax} % \cs{str_map_function:nN} \Arg{token list} \meta{function} +% \cs{str_map_function:NN} \meta{str~var} \meta{function} % \end{syntax} % Converts the \meta{token list} to a \meta{string} then % applies \meta{function} to every \meta{character} in the % \meta{string} including spaces. -% See also \cs{str_map_function:NN}. -% \end{function} -% -% \begin{function}[added = 2017-11-14] -% {\str_map_inline:Nn, \str_map_inline:cn} -% \begin{syntax} -% \cs{str_map_inline:Nn} \meta{str~var} \Arg{inline function} -% \end{syntax} -% Applies the \meta{inline function} to every \meta{character} in the -% \meta{str~var} including spaces. -% The \meta{inline function} should consist of code which -% receives the \meta{character} as |#1|. See also \cs{str_map_function:NN}. % \end{function} % % \begin{function}[added = 2017-11-14] -% {\str_map_inline:nn} +% {\str_map_inline:nn, \str_map_inline:Nn, \str_map_inline:cn} % \begin{syntax} % \cs{str_map_inline:nn} \Arg{token list} \Arg{inline function} +% \cs{str_map_inline:Nn} \meta{str~var} \Arg{inline function} % \end{syntax} % Converts the \meta{token list} to a \meta{string} then % applies the \meta{inline function} to every \meta{character} in the -% \meta{string} including spaces. +% \meta{str~var} including spaces. % The \meta{inline function} should consist of code which -% receives the \meta{character} as |#1|. See also \cs{str_map_function:NN}. -% \end{function} -% -% \begin{function}[added = 2017-11-14] -% {\str_map_variable:NNn, \str_map_variable:cNn} -% \begin{syntax} -% \cs{str_map_variable:NNn} \meta{str~var} \meta{variable} \Arg{code} -% \end{syntax} -% Stores each \meta{character} of the \meta{string} (including spaces) -% in turn in the (string or token list) \meta{variable} and applies -% the \meta{code}. The \meta{code} will usually make use of the -% \meta{variable}, but this is not enforced. The assignments to the -% \meta{variable} are local. Its value after the loop is the last -% \meta{character} in the \meta{string}, or its original value if the -% \meta{string} is empty. See also \cs{str_map_inline:Nn}. +% receives the \meta{character} as |#1|. % \end{function} % % \begin{function}[added = 2017-11-14] -% {\str_map_variable:nNn} +% {\str_map_variable:nNn, \str_map_variable:NNn, \str_map_variable:cNn} % \begin{syntax} % \cs{str_map_variable:nNn} \Arg{token list} \meta{variable} \Arg{code} +% \cs{str_map_variable:NNn} \meta{str~var} \meta{variable} \Arg{code} % \end{syntax} % Converts the \meta{token list} to a \meta{string} then stores each % \meta{character} in the \meta{string} (including spaces) in turn in @@ -480,6 +447,19 @@ % \meta{string} is empty. See also \cs{str_map_inline:Nn}. % \end{function} % +% \begin{function}[rEXP, added = 2021-05-05] +% {\str_map_tokens:nn, \str_map_tokens:Nn, \str_map_tokens:cn} +% \begin{syntax} +% \cs{str_map_tokens:nn} \Arg{token list} \Arg{code} +% \cs{str_map_tokens:Nn} \meta{str~var} \Arg{code} +% \end{syntax} +% Converts the \meta{token list} to a \meta{string} then applies +% \meta{code} to every \meta{character} in the \meta{string} including +% spaces. The \meta{code} receives each character as a trailing brace +% group. This is equivalent to \cs{str_map_function:nN} if the +% \meta{code} consists of a single function. +% \end{function} +% % \begin{function}[added = 2017-10-08, rEXP]{\str_map_break:} % \begin{syntax} % \cs{str_map_break:} @@ -797,7 +777,7 @@ % % \section{Viewing strings} % -% \begin{function}[added = 2015-09-18] +% \begin{function}[added = 2015-09-18, updated = 2021-04-29] % {\str_show:N, \str_show:c, \str_show:n} % \begin{syntax} % \cs{str_show:N} \meta{str~var} @@ -805,7 +785,7 @@ % Displays the content of the \meta{str~var} on the terminal. % \end{function} % -% \begin{function}[added = 2019-02-15] +% \begin{function}[added = 2019-02-15, updated = 2021-04-29] % {\str_log:N, \str_log:c, \str_log:n} % \begin{syntax} % \cs{str_log:N} \meta{str~var} @@ -815,7 +795,7 @@ % % \section{Constant token lists} % -% \begin{variable}[added = 2015-09-19,updated=2020-12-22] +% \begin{variable}[added = 2015-09-19, updated = 2020-12-22, module = str] % { % \c_ampersand_str, % \c_atsign_str, @@ -1201,7 +1181,7 @@ % \begin{macro}[EXP]{\@@_case:nnTF, \@@_case_e:nnTF} % \begin{macro}[EXP] % {\@@_case:nw, \@@_case_e:nw, \@@_case_end:nw} -% Much the same as \cs[index=tl_case:nn]{tl_case:nn(TF)} here: +% Much the same as \cs{tl_case:nnTF} here: % just a change in the internal comparison. % \begin{macrocode} \cs_new:Npn \str_case:nn #1#2 @@ -1270,7 +1250,7 @@ % \end{macro} % \end{macro} % -% \subsection{Mapping to strings} +% \subsection{Mapping over strings} % % \begin{macro}[rEXP]{\str_map_function:NN, \str_map_function:cN} % \begin{macro}[rEXP]{\str_map_function:nN} @@ -1280,7 +1260,7 @@ % \begin{macro}{\str_map_variable:nNn} % \begin{macro}{\str_map_break:} % \begin{macro}{\str_map_break:n} -% \begin{macro}[rEXP]{\@@_map_function:w, \@@_map_function:Nn} +% \begin{macro}[rEXP]{\@@_map_function:w, \@@_map_function:nn} % \begin{macro}{\@@_map_inline:NN, \@@_map_variable:NnN} % The inline and variable mappings are similar to the usual token list % mappings but start out by turning the argument to an ``other @@ -1288,7 +1268,7 @@ % require \cs{__kernel_str_to_other:n}, quadratic in the string length. To deal % with spaces in that case, \cs{@@_map_function:w} replaces the % following space by a braced space and a further call to itself. -% These are received by \cs{@@_map_function:Nn}, which passes +% These are received by \cs{@@_map_function:nn}, which passes % the space to |#1| and calls \cs{@@_map_function:w} to deal with the % next space. The space before the braced space allows to optimize % the \cs{q_@@_recursion_tail} test. Of course we need to include a @@ -1306,7 +1286,7 @@ \cs_new:Npn \str_map_function:nN #1#2 { \exp_after:wN \@@_map_function:w - \exp_after:wN \@@_map_function:Nn \exp_after:wN #2 + \exp_after:wN \@@_map_function:nn \exp_after:wN #2 \__kernel_tl_to_str:w {#1} \q_@@_recursion_tail ? ~ \prg_break_point:Nn \str_map_break: { } @@ -1315,12 +1295,12 @@ { \exp_args:No \str_map_function:nN } \cs_new:Npn \@@_map_function:w #1 ~ { #1 { ~ { ~ } \@@_map_function:w } } -\cs_new:Npn \@@_map_function:Nn #1#2 +\cs_new:Npn \@@_map_function:nn #1#2 { \if_meaning:w \q_@@_recursion_tail #2 \exp_after:wN \str_map_break: \fi: - #1 #2 \@@_map_function:Nn #1 + #1 #2 \@@_map_function:nn {#1} } \cs_generate_variant:Nn \str_map_function:NN { c } \cs_new_protected:Npn \str_map_inline:nn #1#2 @@ -1383,6 +1363,24 @@ % \end{macro} % \end{macro} % +% \begin{macro}[rEXP]{\str_map_tokens:Nn, \str_map_tokens:cn} +% \begin{macro}[rEXP]{\str_map_tokens:nn} +% Uses an auxiliary of \cs{str_map_function:NN}. +% \begin{macrocode} +\cs_new:Npn \str_map_tokens:nn #1#2 + { + \exp_args:Nno \use:nn + { \@@_map_function:w \@@_map_function:nn {#2} } + { \__kernel_tl_to_str:w {#1} } + \q_@@_recursion_tail ? ~ + \prg_break_point:Nn \str_map_break: { } + } +\cs_new:Npn \str_map_tokens:Nn { \exp_args:No \str_map_tokens:nn } +\cs_generate_variant:Nn \str_map_tokens:Nn { c } +% \end{macrocode} +% \end{macro} +% \end{macro} +% % \subsection{Accessing specific characters in a string} % % \begin{macro}[EXP]{\__kernel_str_to_other:n} @@ -1983,10 +1981,18 @@ % Displays a string on the terminal. % \begin{macrocode} \cs_new_eq:NN \str_show:n \tl_show:n -\cs_new_eq:NN \str_show:N \tl_show:N +\cs_new_protected:Npn \str_show:N #1 + { + \__kernel_chk_tl_type:NnnT #1 { str } { \tl_to_str:N #1 } + { \tl_show:N #1 } + } \cs_generate_variant:Nn \str_show:N { c } \cs_new_eq:NN \str_log:n \tl_log:n -\cs_new_eq:NN \str_log:N \tl_log:N +\cs_new_protected:Npn \str_log:N #1 + { + \__kernel_chk_tl_type:NnnT #1 { str } { \tl_to_str:N #1 } + { \tl_log:N #1 } + } \cs_generate_variant:Nn \str_log:N { c } % \end{macrocode} % \end{macro} diff --git a/macros/latex/contrib/l3kernel/l3styleguide.pdf b/macros/latex/contrib/l3kernel/l3styleguide.pdf Binary files differindex 0ad0ba30d6..82ed3e5bf5 100644 --- a/macros/latex/contrib/l3kernel/l3styleguide.pdf +++ b/macros/latex/contrib/l3kernel/l3styleguide.pdf diff --git a/macros/latex/contrib/l3kernel/l3styleguide.tex b/macros/latex/contrib/l3kernel/l3styleguide.tex index c9a61be054..00e041f294 100644 --- a/macros/latex/contrib/l3kernel/l3styleguide.tex +++ b/macros/latex/contrib/l3kernel/l3styleguide.tex @@ -32,7 +32,7 @@ The released version of this bundle is available from CTAN. {latex-team@latex-project.org}% }% } -\date{Released 2021-02-18} +\date{Released 2021-05-07} \begin{document} diff --git a/macros/latex/contrib/l3kernel/l3syntax-changes.pdf b/macros/latex/contrib/l3kernel/l3syntax-changes.pdf Binary files differindex f119e34fdb..6e0445de7d 100644 --- a/macros/latex/contrib/l3kernel/l3syntax-changes.pdf +++ b/macros/latex/contrib/l3kernel/l3syntax-changes.pdf diff --git a/macros/latex/contrib/l3kernel/l3syntax-changes.tex b/macros/latex/contrib/l3kernel/l3syntax-changes.tex index 75bdfb87d2..d4282431b8 100644 --- a/macros/latex/contrib/l3kernel/l3syntax-changes.tex +++ b/macros/latex/contrib/l3kernel/l3syntax-changes.tex @@ -32,7 +32,7 @@ The released version of this bundle is available from CTAN. {latex-team@latex-project.org}% }% } -\date{Released 2021-02-18} +\date{Released 2021-05-07} \newcommand{\TF}{\textit{(TF)}} diff --git a/macros/latex/contrib/l3kernel/l3sys.dtx b/macros/latex/contrib/l3kernel/l3sys.dtx index 9bcbee56a6..57f3361c51 100644 --- a/macros/latex/contrib/l3kernel/l3sys.dtx +++ b/macros/latex/contrib/l3kernel/l3sys.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3term-glossary.pdf b/macros/latex/contrib/l3kernel/l3term-glossary.pdf Binary files differindex 7aa607d2bb..9bd43ef0f0 100644 --- a/macros/latex/contrib/l3kernel/l3term-glossary.pdf +++ b/macros/latex/contrib/l3kernel/l3term-glossary.pdf diff --git a/macros/latex/contrib/l3kernel/l3term-glossary.tex b/macros/latex/contrib/l3kernel/l3term-glossary.tex index 23b05b09fd..7ea79a155f 100644 --- a/macros/latex/contrib/l3kernel/l3term-glossary.tex +++ b/macros/latex/contrib/l3kernel/l3term-glossary.tex @@ -32,7 +32,7 @@ The released version of this bundle is available from CTAN. {latex-team@latex-project.org}% }% } -\date{Released 2021-02-18} +\date{Released 2021-05-07} \newcommand{\TF}{\textit{(TF)}} diff --git a/macros/latex/contrib/l3kernel/l3text-case.dtx b/macros/latex/contrib/l3kernel/l3text-case.dtx index 19f6e85035..6f6bef57ec 100644 --- a/macros/latex/contrib/l3kernel/l3text-case.dtx +++ b/macros/latex/contrib/l3kernel/l3text-case.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3text-purify.dtx b/macros/latex/contrib/l3kernel/l3text-purify.dtx index f939085021..18cc1db064 100644 --- a/macros/latex/contrib/l3kernel/l3text-purify.dtx +++ b/macros/latex/contrib/l3kernel/l3text-purify.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/l3text.dtx b/macros/latex/contrib/l3kernel/l3text.dtx index 046bf68677..aee505c0c5 100644 --- a/macros/latex/contrib/l3kernel/l3text.dtx +++ b/macros/latex/contrib/l3kernel/l3text.dtx @@ -43,14 +43,12 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % % \begin{documentation} % -% \section{\pkg{l3text} documentation} -% % This module deals with manipulation of (formatted) text; such material is % comprised of a restricted set of token list content. The functions provided % here concern conversion of textual content for example in case changing, @@ -58,7 +56,7 @@ % operate by expansion. Begin-group and end-group tokens in the \meta{text} % are normalized and become |{| and |}|, respectively. % -% \subsection{Expanding text} +% \section{Expanding text} % % \begin{function}[EXP, added = 2020-01-02]{\text_expand:n} % \begin{syntax} @@ -89,7 +87,7 @@ % should be expandable. % \end{function} % -% \subsection{Case changing} +% \section{Case changing} % % \begin{function}[EXP, added = 2019-11-20, updated = 2020-02-24] % { @@ -196,7 +194,7 @@ % character is uppercased, and the rest lowercased, irrespective of the nature % of the character. % -% \subsection{Removing formatting from text} +% \section{Removing formatting from text} % % \begin{function}[EXP, added = 2020-03-05, updated = 2020-05-14]{\text_purify:n} % \begin{syntax} @@ -226,7 +224,7 @@ % should be expandable. % \end{function} % -% \subsection{Control variables} +% \section{Control variables} % % \begin{variable}{\l_text_accents_tl} % Lists commands which represent accents, and which are left unchanged @@ -639,7 +637,10 @@ % \begin{macro}[EXP]{\@@_expand_replace:N} % \begin{macro}[EXP]{\@@_expand_replace:n} % \begin{macro}[EXP]{\@@_expand_cs_expand:N} -% \begin{macro}[EXP]{\@@_expand_noexpand:nn} +% \begin{macro}[EXP]{\@@_expand_unexpanded:w} +% \begin{macro}[EXP]{\@@_expand_unexpanded_test:w} +% \begin{macro}[EXP]{\@@_expand_unexpanded:N} +% \begin{macro}[EXP]{\@@_expand_unexpanded:n} % After precautions against |&| tokens, start a simple loop: that of % course means that \enquote{text} cannot contain the two recursion % quarks. The loop here must be \texttt{f}-type expandable; we have @@ -998,14 +999,13 @@ % Finally, expand any macros which can be: this then loops back around to % deal with what they produce. The only issue is if the token is % \cs{exp_not:n}, as that must apply to the following balanced text. -% There might be an \cs{exp_after:wN} there, so we check for it. % \begin{macrocode} \cs_new:Npn \@@_expand_cs_expand:N #1 { \@@_if_expandable:NTF #1 { \token_if_eq_meaning:NNTF #1 \exp_not:n - { \@@_expand_noexpand:w } + { \@@_expand_unexpanded:w } { \exp_after:wN \@@_expand_loop:w #1 } } { @@ -1013,11 +1013,47 @@ \@@_expand_loop:w } } -\cs_new:Npn \@@_expand_noexpand:w #1# - { \@@_expand_noexpand:nn {#1} } -\cs_new:Npn \@@_expand_noexpand:nn #1#2 +% \end{macrocode} +% Since \cs{exp_not:n} is actually a primitive, it allows a strange syntax +% and it particular the primitive expands what follows and discards spaces +% and \cs{scan_stop:} until finding a braced argument (the opening brace +% can be implicit but we will not support this here). Here, we repeatedly +% |f|-expand after such an \cs{exp_not:n}, and test what follows. If +% it is a brace group, then we found the intended argument of +% \cs{exp_not:n}. If it is a space, then the next |f|-expansion will +% eliminate it. If it is an |N|-type token then +% \cs{@@_expand_unexpanded:N} leaves the token to be expanded if it is +% expandable, and otherwise removes it, assuming that it is +% \cs{scan_stop:}. This silently hides errors when \cs{exp_not:n} is +% incorrectly followed by some non-expandable token other than +% \cs{scan_stop:}, but this should be pretty rare, and there is no good +% error recovery anyways. +% \begin{macrocode} +\cs_new:Npn \@@_expand_unexpanded:w + { + \exp_after:wN \@@_expand_unexpanded_test:w + \exp:w \exp_end_continue_f:w + } +\cs_new:Npn \@@_expand_unexpanded_test:w #1 \q_@@_recursion_stop + { + \tl_if_head_is_group:nTF {#1} + { \@@_expand_unexpanded:n } + { + \@@_expand_unexpanded:w + \tl_if_head_is_N_type:nT {#1} { \@@_expand_unexpanded:N } + } + #1 \q_@@_recursion_stop + } +\cs_new:Npn \@@_expand_unexpanded:N #1 { - #1 \@@_expand_store:n #1 {#2} + \exp_after:wN \if_meaning:w \exp_not:N #1 #1 + \else: + \exp_after:wN #1 + \fi: + } +\cs_new:Npn \@@_expand_unexpanded:n #1 + { + \@@_expand_store:n {#1} \@@_expand_loop:w } % \end{macrocode} @@ -1052,6 +1088,9 @@ % \end{macro} % \end{macro} % \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % % \begin{macro} % { diff --git a/macros/latex/contrib/l3kernel/l3tl-analysis.dtx b/macros/latex/contrib/l3kernel/l3tl-analysis.dtx index 51ad05c995..f2f10d1664 100644 --- a/macros/latex/contrib/l3kernel/l3tl-analysis.dtx +++ b/macros/latex/contrib/l3kernel/l3tl-analysis.dtx @@ -44,14 +44,12 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % % \begin{documentation} % -% \section{\pkg{l3tl-analysis} documentation} -% % This module provides functions that are particularly useful in the % \pkg{l3regex} module for mapping through a token list one \meta{token} % at a time (including begin-group/end-group tokens). For @@ -75,7 +73,7 @@ % writing |"|\meta{catcode}. % \end{itemize} % In addition, there is a debugging function \cs{tl_analysis_show:n}, -% very similar to the \cs{ShowTokens} macro from the \pkg{ted} package. +% very similar to the \cs[no-index]{ShowTokens} macro from the \pkg{ted} package. % % \begin{function}[added = 2018-04-09]{\tl_analysis_show:N, \tl_analysis_show:n} % \begin{syntax} @@ -334,7 +332,7 @@ % % Our goal is to produce a token list of the form roughly % \begin{quote} -% \meta{token 1} \cs{s@__} \meta{catcode 1} \meta{char code 1} \cs{s@__} \\ +% \meta{token 1} \cs{s_@@} \meta{catcode 1} \meta{char code 1} \cs{s_@@} \\ % \meta{token 2} \cs{s_@@} \meta{catcode 2} \meta{char code 2} \cs{s_@@} \\ % \ldots{} % \meta{token N} \cs{s_@@} \meta{catcode N} \meta{char code N} \cs{s_@@} @@ -990,7 +988,7 @@ \tl_if_exist:NTF #1 { \exp_args:No \@@_analysis:n {#1} - \msg_show:nnxxxx { LaTeX / kernel } { show-tl-analysis } + \__kernel_msg_show:nnxxxx { tl } { show-analysis } { \token_to_str:N #1 } { \@@_analysis_show: } { } { } } { \tl_show:N #1 } @@ -998,7 +996,7 @@ \cs_new_protected:Npn \tl_analysis_show:n #1 { \@@_analysis:n {#1} - \msg_show:nnxxxx { LaTeX / kernel } { show-tl-analysis } + \__kernel_msg_show:nnxxxx { tl } { show-analysis } { } { \@@_analysis_show: } { } { } } % \end{macrocode} @@ -1482,7 +1480,7 @@ % \end{variable} % % \begin{macrocode} -\__kernel_msg_new:nnn { kernel } { show-tl-analysis } +\__kernel_msg_new:nnn { tl } { show-analysis } { The~token~list~ \tl_if_empty:nF {#1} { #1 ~ } \tl_if_empty:nTF {#2} diff --git a/macros/latex/contrib/l3kernel/l3tl.dtx b/macros/latex/contrib/l3kernel/l3tl.dtx index c7038b08d1..30a9612af1 100644 --- a/macros/latex/contrib/l3kernel/l3tl.dtx +++ b/macros/latex/contrib/l3kernel/l3tl.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -521,7 +521,7 @@ % available. % \end{function} % -% \section{Mapping to token lists} +% \section{Mapping over token lists} % % All mappings are done at the current group level, \emph{i.e.}~any % local assignments made by the \meta{function} or \meta{code} discussed @@ -583,7 +583,7 @@ % \tl_map_tokens:Nn \l_my_tl { \prg_replicate:nn { 2 } } % \end{verbatim} % expands to twice each item in the \meta{tl~var}: for each item in -% |\l_my_tl| the function \cs{prg_replicate:nn} receives |2| and +% \cs[no-index]{l_my_tl} the function \cs{prg_replicate:nn} receives |2| and % \meta{item} as its two arguments. The function % \cs{tl_map_inline:Nn} is typically faster but is not expandable. % \end{function} @@ -1169,7 +1169,7 @@ % % \section{Viewing token lists} % -% \begin{function}[updated = 2015-08-01]{\tl_show:N, \tl_show:c} +% \begin{function}[updated = 2021-04-29]{\tl_show:N, \tl_show:c} % \begin{syntax} % \cs{tl_show:N} \meta{tl~var} % \end{syntax} @@ -1191,7 +1191,7 @@ % \end{texnote} % \end{function} % -% \begin{function}[added = 2014-08-22, updated = 2015-08-01]{\tl_log:N, \tl_log:c} +% \begin{function}[added = 2014-08-22, updated = 2021-04-29]{\tl_log:N, \tl_log:c} % \begin{syntax} % \cs{tl_log:N} \meta{tl~var} % \end{syntax} @@ -2458,7 +2458,7 @@ % \end{macro} % \end{macro} % -% \subsection{Mapping to token lists} +% \subsection{Mapping over token lists} % % \begin{macro}{\tl_map_function:nN} % \begin{macro}{\tl_map_function:NN, \tl_map_function:cN} @@ -2814,7 +2814,7 @@ % \begin{macro}{\tl_head:w,\@@_tl_head:w} % \begin{macro}{\tl_tail:N, \tl_tail:n, \tl_tail:V, \tl_tail:v, \tl_tail:f} % Finding the head of a token list expandably always strips braces, which -% is fine as this is consistent with for example mapping to a list. The +% is fine as this is consistent with for example mapping over a list. The % empty brace groups in \cs{tl_head:n} ensure that a blank argument gives an % empty result. The result is returned within the \tn{unexpanded} primitive. % The approach here is to use \cs{if_false:} to allow us to use |}| as @@ -3531,8 +3531,16 @@ { \__kernel_chk_defined:NT #2 { - \exp_args:Ne #1 - { \token_to_str:N #2 = \__kernel_exp_not:w \exp_after:wN {#2} } + \exp_args:Nf \tl_if_empty:nTF + { \cs_prefix_spec:N #2 \cs_argument_spec:N #2 } + { + \exp_args:Ne #1 + { \token_to_str:N #2 = \__kernel_exp_not:w \exp_after:wN {#2} } + } + { + \__kernel_msg_error:nnxxx { kernel } { bad-type } + { \token_to_str:N #2 } { \token_to_meaning:N #2 } { tl } + } } } % \end{macrocode} @@ -3584,6 +3592,40 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\__kernel_chk_tl_type:NnnT} +% Helper for checking that |#1| has the correct internal structure to +% be of a certain type. Make sure that it is defined and that it is a +% token list, namely a macro with no \tn{long} nor \tn{protected} +% prefix. Then compare |#1| to an attempt at reconstructing a valid +% structure of the given type using |#2| (see implementation of +% \cs{seq_show:N} for instance). If that is successful run the +% requested code~|#4|. +% \begin{macrocode} +\cs_new_protected:Npn \__kernel_chk_tl_type:NnnT #1#2#3#4 + { + \__kernel_chk_defined:NT #1 + { + \exp_args:Nf \tl_if_empty:nTF + { \cs_prefix_spec:N #1 \cs_argument_spec:N #1 } + { + \tl_set:Nx \l_@@_internal_a_tl {#3} + \tl_if_eq:NNTF #1 \l_@@_internal_a_tl + {#4} + { + \__kernel_msg_error:nnxxxx { kernel } { bad-type } + { \token_to_str:N #1 } { \tl_to_str:N #1 } + {#2} { \tl_to_str:N \l_@@_internal_a_tl } + } + } + { + \__kernel_msg_error:nnxxx { kernel } { bad-type } + { \token_to_str:N #1 } { \token_to_meaning:N #1 } {#2} + } + } + } +% \end{macrocode} +% \end{macro} +% % \subsection{Internal scan marks} % % \begin{variable}{\s_@@_nil,\s_@@_mark,\s_@@_stop} diff --git a/macros/latex/contrib/l3kernel/l3token.dtx b/macros/latex/contrib/l3kernel/l3token.dtx index 31d4d7fcde..3db1f706c8 100644 --- a/macros/latex/contrib/l3kernel/l3token.dtx +++ b/macros/latex/contrib/l3kernel/l3token.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % @@ -74,7 +74,7 @@ % 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 +% For instance, \cs{if:w}, \cs{if_charcode:w}, and \cs[no-index]{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 have the same meaning hence behave identically @@ -146,6 +146,8 @@ % and other values raise an error. The \meta{charcode} may be any one valid % for the engine in use. % Active characters cannot be generated in older versions of \XeTeX{}. +% Another way to build token lists with unusual category codes is +% \cs{regex_replace:nnN} |{.*}| \Arg{replacement} \meta{tl~var}. % \begin{texnote} % Exactly two expansions are needed to produce the character. % \end{texnote} @@ -421,7 +423,7 @@ % % \section{Generic tokens} % -% \begin{variable} +% \begin{variable}[module = token] % { % \c_group_begin_token, % \c_group_end_token, @@ -1164,7 +1166,7 @@ % conditional is encountered before the conditional is evaluated. % \item Expanding \tn{noexpand} \meta{token} (when the \meta{token} is % expandable) results in an internal token, displayed (temporarily) -% as \cs{notexpanded: \meta{token}}, whose shape coincides with the +% as \cs[module = {}]{notexpanded: \meta{token}}, whose shape coincides with the % \meta{token} and whose meaning differs from \tn{relax}. % \item An |\outer endtemplate:| can be encountered when peeking ahead % at the next token; this expands to another internal token, @@ -1570,9 +1572,9 @@ { \if_int_compare:w #2 = 10 \exp_stop_f: \if_int_compare:w #1 = 0 \exp_stop_f: - \__kernel_msg_expandable_error:nn { kernel } { char-null-space } + \__kernel_msg_expandable_error:nn { char } { null-space } \else: - \__kernel_msg_expandable_error:nn { kernel } { char-space } + \__kernel_msg_expandable_error:nn { char } { space } \fi: \else: \if_int_odd:w 0 @@ -1580,14 +1582,14 @@ \if_int_compare:w #2 = 5 \exp_stop_f: 1 \fi: \if_int_compare:w #2 = 9 \exp_stop_f: 1 \fi: \if_int_compare:w #2 > 13 \exp_stop_f: 1 \fi: \exp_stop_f: - \__kernel_msg_expandable_error:nn { kernel } - { char-invalid-catcode } + \__kernel_msg_expandable_error:nn { char } + { invalid-catcode } \else: \if_int_odd:w 0 \if_int_compare:w #1 < 0 \exp_stop_f: 1 \fi: \if_int_compare:w #1 > \c_max_char_int 1 \fi: \exp_stop_f: - \__kernel_msg_expandable_error:nn { kernel } - { char-out-of-range } + \__kernel_msg_expandable_error:nn { char } + { out-of-range } \else: \@@_generate_aux:nnw {#1} {#2} \fi: @@ -1630,7 +1632,7 @@ { #3 \if_int_compare:w #2 = 13 \exp_stop_f: - \__kernel_msg_expandable_error:nn { kernel } { char-active } + \__kernel_msg_expandable_error:nn { char } { active } \else: \@@_generate_auxii:nnw {#1} {#2} \fi: @@ -1681,10 +1683,10 @@ \tl_put_right:Nn \l_@@_tmp_tl { \or: ^^@ } % \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 +% lists, one for each character code, using \cs{tex_lowercase:D} to % convert |^^@| in each case. The \texttt{x}-type expansion ensures -% that \tn{tex_lowercase:D} receives the contents of the token list. -% |^^L| is awkward hence this is done in three parts: up to |^^L|, +% that \cs{tex_lowercase:D} receives the contents of the token list. +% |^^L| is awkward hence this is done in three parts: up to |^^L|, % |^^L| itslef and above |^L|. Notice that at this stage |^^@| is active. % \begin{macrocode} \cs_set_protected:Npn \@@_tmp:n #1 diff --git a/macros/latex/contrib/l3kernel/l3unicode.dtx b/macros/latex/contrib/l3kernel/l3unicode.dtx index a52823c1a2..6165c802ae 100644 --- a/macros/latex/contrib/l3kernel/l3unicode.dtx +++ b/macros/latex/contrib/l3kernel/l3unicode.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-02-18} +% \date{Released 2021-05-07} % % \maketitle % diff --git a/macros/latex/contrib/l3kernel/source3.pdf b/macros/latex/contrib/l3kernel/source3.pdf Binary files differindex 8cfe3b177f..e6503168dc 100644 --- a/macros/latex/contrib/l3kernel/source3.pdf +++ b/macros/latex/contrib/l3kernel/source3.pdf diff --git a/macros/latex/contrib/l3kernel/source3.tex b/macros/latex/contrib/l3kernel/source3.tex index e3134302c7..95e707b01f 100644 --- a/macros/latex/contrib/l3kernel/source3.tex +++ b/macros/latex/contrib/l3kernel/source3.tex @@ -53,7 +53,7 @@ for those people who are interested. {latex-team@latex-project.org}% }% } -\date{Released 2021-02-18} +\date{Released 2021-05-07} \pagenumbering{roman} \maketitle @@ -71,6 +71,10 @@ for those people who are interested. \part{Implementation} \def\maketitle{} +\let\subsubsection\subsection +\let\subsection\section +\let\section\chapter + \EnableImplementation \DisableDocumentation \DocInputAgain diff --git a/macros/latex/contrib/l3kernel/source3body.tex b/macros/latex/contrib/l3kernel/source3body.tex index 588dba1008..946f7a4abc 100644 --- a/macros/latex/contrib/l3kernel/source3body.tex +++ b/macros/latex/contrib/l3kernel/source3body.tex @@ -257,7 +257,7 @@ following argument specifiers: applies to delimited values (where the argument must be terminated by some specified string). \item[\texttt{D}] The \texttt{D} stands for \textbf{Do not use}. - All of the \TeX{} primitives are initially \cs{let} to a \texttt{D} + All of the \TeX{} primitives are initially \cs[no-index]{let} to a \texttt{D} name, and some are then given a second name. These functions have no standardized syntax, they are engine dependent and their name can change without warning, thus their diff --git a/macros/latex/contrib/l3packages/CHANGELOG.md b/macros/latex/contrib/l3packages/CHANGELOG.md index cf52f56e8f..052e070b7d 100644 --- a/macros/latex/contrib/l3packages/CHANGELOG.md +++ b/macros/latex/contrib/l3packages/CHANGELOG.md @@ -7,6 +7,12 @@ this project uses date-based 'snapshot' version identifiers. ## [Unreleased] +## [2021-05-07] + +### Fixed +- Implmentation of `\DeclareRestrictedTemplate` +- Incorrect use of restricted template in `xfrac` + ## [2021-03-12] ### Fixed @@ -124,7 +130,8 @@ this project uses date-based 'snapshot' version identifiers. - Switch to ISO date format - Improve cross-module use of internal functions -[Unreleased]: https://github.com/latex3/latex3/compare/2021-03-12...HEAD +[Unreleased]: https://github.com/latex3/latex3/compare/2021-05-07...HEAD +[2021-05-07]: https://github.com/latex3/latex3/compare/2021-03-12...2021-05-07 [2021-03-12]: https://github.com/latex3/latex3/compare/2021-02-02...2021-03-12 [2021-02-02]: https://github.com/latex3/latex3/compare/2020-10-27...2021-02-02 [2020-10-27]: https://github.com/latex3/latex3/compare/2020-10-05...2020-10-27 diff --git a/macros/latex/contrib/l3packages/README.md b/macros/latex/contrib/l3packages/README.md index 8319851b85..e55e7476dd 100644 --- a/macros/latex/contrib/l3packages/README.md +++ b/macros/latex/contrib/l3packages/README.md @@ -1,7 +1,7 @@ LaTeX3 High-Level Concepts ========================== -Release 2021-03-12 +Release 2021-05-07 Overview -------- diff --git a/macros/latex/contrib/l3packages/l3keys2e.dtx b/macros/latex/contrib/l3packages/l3keys2e.dtx index 501e4c5aaa..7904c7c237 100644 --- a/macros/latex/contrib/l3packages/l3keys2e.dtx +++ b/macros/latex/contrib/l3packages/l3keys2e.dtx @@ -62,7 +62,7 @@ % }^^A % } % -% \date{Released 2021-03-12} +% \date{Released 2021-05-07} % % \maketitle % @@ -139,7 +139,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{l3keys2e}{2021-03-12}{} +\ProvidesExplPackage{l3keys2e}{2021-05-07}{} {LaTeX2e option processing using LaTeX3 keys} % \end{macrocode} % diff --git a/macros/latex/contrib/l3packages/l3keys2e.pdf b/macros/latex/contrib/l3packages/l3keys2e.pdf Binary files differindex e55211ccf9..1d3a6d758a 100644 --- a/macros/latex/contrib/l3packages/l3keys2e.pdf +++ b/macros/latex/contrib/l3packages/l3keys2e.pdf diff --git a/macros/latex/contrib/l3packages/xfp.dtx b/macros/latex/contrib/l3packages/xfp.dtx index 0093447c2e..ac82c7c430 100644 --- a/macros/latex/contrib/l3packages/xfp.dtx +++ b/macros/latex/contrib/l3packages/xfp.dtx @@ -63,7 +63,7 @@ % }^^A % } % -% \date{Released 2021-03-12} +% \date{Released 2021-05-07} % % \maketitle % @@ -166,7 +166,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{xfp}{2021-03-12}{} +\ProvidesExplPackage{xfp}{2021-05-07}{} {L3 Floating point unit} % \end{macrocode} % diff --git a/macros/latex/contrib/l3packages/xfp.pdf b/macros/latex/contrib/l3packages/xfp.pdf Binary files differindex d91a5561bb..64eccb34b7 100644 --- a/macros/latex/contrib/l3packages/xfp.pdf +++ b/macros/latex/contrib/l3packages/xfp.pdf diff --git a/macros/latex/contrib/l3packages/xfrac.dtx b/macros/latex/contrib/l3packages/xfrac.dtx index dbbdeaf65a..f6c01be750 100644 --- a/macros/latex/contrib/l3packages/xfrac.dtx +++ b/macros/latex/contrib/l3packages/xfrac.dtx @@ -65,7 +65,7 @@ % }^^A % } % -% \date{Released 2021-03-12} +% \date{Released 2021-05-07} % % \maketitle % @@ -535,7 +535,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{xfrac}{2021-03-12}{} +\ProvidesExplPackage{xfrac}{2021-05-07}{} {L3 Experimental split-level fractions} % \end{macrocode} % @@ -979,7 +979,6 @@ scale-factor = 0.7 , scale-relative = false , scaling = true , - numerator-top-sep = 0 pt , denominator-bot-sep = 0 pt , math-mode = true , phantom = ( % ) @@ -1004,7 +1003,6 @@ % \begin{macrocode} \DeclareCollectionInstance { plainmath } { xfrac } { mathdefault } { math } { - denominator-bot-sep = 0 pt , numerator-bot-sep = 0 pt , numerator-top-sep = \c_max_dim , scale-factor = 1 , @@ -1128,8 +1126,8 @@ % Just the one. % \begin{macrocode} \msg_new:nnnn { xfrac } { over-specified-numerator-sep } - { You have specified both numerator-top-sep and numerator-bot-sep} - {I will pretend that you didn't specify either of them} + { You~have~specified~both~"numerator-top-sep"~and~"numerator-bot-sep". } + { I~will~pretend~that~you~didn't~specify~either~of~them. } % \end{macrocode} % % \begin{macrocode} diff --git a/macros/latex/contrib/l3packages/xfrac.pdf b/macros/latex/contrib/l3packages/xfrac.pdf Binary files differindex ec7de16964..e4b7e58e3a 100644 --- a/macros/latex/contrib/l3packages/xfrac.pdf +++ b/macros/latex/contrib/l3packages/xfrac.pdf diff --git a/macros/latex/contrib/l3packages/xparse.dtx b/macros/latex/contrib/l3packages/xparse.dtx index b612ed6d23..30f39c1971 100644 --- a/macros/latex/contrib/l3packages/xparse.dtx +++ b/macros/latex/contrib/l3packages/xparse.dtx @@ -67,7 +67,7 @@ % }^^A % } % -% \date{Released 2021-03-12} +% \date{Released 2021-05-07} % % \maketitle % @@ -1064,7 +1064,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{xparse}{2021-03-12}{} +\ProvidesExplPackage{xparse}{2021-05-07}{} {L3 Experimental document command parser} % \end{macrocode} % diff --git a/macros/latex/contrib/l3packages/xparse.pdf b/macros/latex/contrib/l3packages/xparse.pdf Binary files differindex 0722a7b93c..8c939583fc 100644 --- a/macros/latex/contrib/l3packages/xparse.pdf +++ b/macros/latex/contrib/l3packages/xparse.pdf diff --git a/macros/latex/contrib/l3packages/xtemplate.dtx b/macros/latex/contrib/l3packages/xtemplate.dtx index d80d348070..3344621dc5 100644 --- a/macros/latex/contrib/l3packages/xtemplate.dtx +++ b/macros/latex/contrib/l3packages/xtemplate.dtx @@ -63,7 +63,7 @@ % }^^A % } % -% \date{Released 2021-03-12} +% \date{Released 2021-05-07} % % \maketitle % @@ -682,7 +682,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{xtemplate}{2021-03-12}{} +\ProvidesExplPackage{xtemplate}{2021-05-07}{} {L3 Experimental prototype document functions} % \end{macrocode} % @@ -1574,12 +1574,12 @@ \cs_new_protected:Npn \@@_store_key_implementation:nnn #1#2#3 { \@@_recover_defaults:n { #1 / #2 } + \@@_recover_restrictions:n { #1 / #2 } \@@_recover_keytypes:n { #1 / #2 } \prop_clear:N \l_@@_vars_prop \keyval_parse:NNn \@@_parse_vars_elt:n \@@_parse_vars_elt:nn {#3} \@@_store_vars:n { #1 / #2 } - \clist_clear:N \l_@@_restrict_clist \@@_store_restrictions:n { #1 / #2 } \prop_map_inline:Nn \l_@@_keytypes_prop { @@ -1855,15 +1855,19 @@ % \end{macro} % \end{macro} % -% \begin{macro}{\@@_parse_values:nn} +% \begin{macro}{\@@_parse_values:nn, \@@_parse_values_aux:nn} % The routine to parse values is the same for both editing a % template and setting up an instance. So the code here does only the % minimum necessary for reading the values. % \begin{macrocode} \cs_new_protected:Npn \@@_parse_values:nn #1#2 { - \@@_recover_keytypes:n {#1} \clist_clear:N \l_@@_restrict_clist + \@@_parse_values_aux:nn {#1} {#2} + } +\cs_new_protected:Npn \@@_parse_values_aux:nn #1#2 + { + \@@_recover_keytypes:n {#1} \keyval_parse:NNn \@@_parse_values_elt:n \@@_parse_values_elt:nn {#2} } @@ -1954,6 +1958,7 @@ \@@_execute_if_code_exist:nnT {#1} {#2} { \@@_recover_defaults:n { #1 / #2 } + \@@_recover_restrictions:n { #1 / #2 } \@@_recover_vars:n { #1 / #2 } \@@_declare_instance_aux:nnnnn {#1} {#2} {#3} {#4} {#5} } @@ -1961,7 +1966,7 @@ \cs_new_protected:Npn \@@_declare_instance_aux:nnnnn #1#2#3#4#5 { \bool_set_false:N \l_@@_error_bool - \@@_parse_values:nn { #1 / #2 } {#5} + \@@_parse_values_aux:nn { #1 / #2 } {#5} \bool_if:NF \l_@@_error_bool { \prop_put:Nnn \l_@@_values_prop { from~template } {#2} diff --git a/macros/latex/contrib/l3packages/xtemplate.pdf b/macros/latex/contrib/l3packages/xtemplate.pdf Binary files differindex c4b96d62d2..ecf1261faa 100644 --- a/macros/latex/contrib/l3packages/xtemplate.pdf +++ b/macros/latex/contrib/l3packages/xtemplate.pdf diff --git a/macros/latex/contrib/ninecolors/ninecolors.pdf b/macros/latex/contrib/ninecolors/ninecolors.pdf Binary files differindex 7876eaf2ac..9ef44d1880 100644 --- a/macros/latex/contrib/ninecolors/ninecolors.pdf +++ b/macros/latex/contrib/ninecolors/ninecolors.pdf diff --git a/macros/latex/contrib/ninecolors/ninecolors.sty b/macros/latex/contrib/ninecolors/ninecolors.sty index 5331997477..d6ba17f10c 100644 --- a/macros/latex/contrib/ninecolors/ninecolors.sty +++ b/macros/latex/contrib/ninecolors/ninecolors.sty @@ -7,137 +7,372 @@ %%% ---------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e} -\ProvidesClass{ninecolors}[2021/04/11 v2021A Select colors with proper color contrast] +\ProvidesClass{ninecolors}[2021/05/07 v2021B Select colors with proper color contrast] \RequirePackage{xcolor} -\selectcolormodel{rgb} -\definecolor{gray1}{gray}{0.14} -\definecolor{gray2}{gray}{0.23} -\definecolor{gray3}{gray}{0.30} -\definecolor{gray4}{gray}{0.38} -\definecolor{gray5}{gray}{0.46} -\definecolor{gray6}{gray}{0.55} -\definecolor{gray7}{gray}{0.64} -\definecolor{gray8}{gray}{0.75} -\definecolor{gray9}{gray}{0.87} +\ExplSyntaxOn -\definecolor{red1}{Hsb}{0,0.67,0.26}%{0,0.95,0.31} -\definecolor{red2}{Hsb}{0,0.67,0.41} -\definecolor{red3}{Hsb}{0,0.67,0.54} -\definecolor{red4}{Hsb}{0,0.67,0.67} -\definecolor{red5}{Hsb}{0,0.60,0.77} -\definecolor{red6}{Hsb}{0,0.46,0.81} -\definecolor{red7}{Hsb}{0,0.34,0.86} -\definecolor{red8}{Hsb}{0,0.22,0.90} -\definecolor{red9}{Hsb}{0,0.11,0.95} +\tl_new:N \l__ninecolors_sat_tl -\definecolor{brown1}{Hsb}{30,0.67,0.19} -\definecolor{brown2}{Hsb}{30,0.67,0.31} -\definecolor{brown3}{Hsb}{30,0.67,0.41} -\definecolor{brown4}{Hsb}{30,0.67,0.51} -\definecolor{brown5}{Hsb}{30,0.67,0.62} -\definecolor{brown6}{Hsb}{30,0.67,0.74} -\definecolor{brown7}{Hsb}{30,0.49,0.80} -\definecolor{brown8}{Hsb}{30,0.32,0.86} -\definecolor{brown9}{Hsb}{30,0.15,0.93} +\keys_define:nn {ninecolors} + { + saturation .tl_set:N = \l__ninecolors_sat_tl, + saturation .initial:n = medium, + } -\definecolor{yellow1}{Hsb}{60,0.67,0.15} -\definecolor{yellow2}{Hsb}{60,0.67,0.23} -\definecolor{yellow3}{Hsb}{60,0.67,0.31} -\definecolor{yellow4}{Hsb}{60,0.67,0.39} -\definecolor{yellow5}{Hsb}{60,0.67,0.47} -\definecolor{yellow6}{Hsb}{60,0.67,0.56} -\definecolor{yellow7}{Hsb}{60,0.67,0.66} -\definecolor{yellow8}{Hsb}{60,0.59,0.77} -\definecolor{yellow9}{Hsb}{60,0.27,0.88} +\NewDocumentCommand \NineColors {m} + { + \keys_set:nn {ninecolors} {#1} + \cs:w ninecolors@define@color@ \l__ninecolors_sat_tl \cs_end: + } -\definecolor{olive1}{Hsb}{90,0.67,0.16} -\definecolor{olive2}{Hsb}{90,0.67,0.25} -\definecolor{olive3}{Hsb}{90,0.67,0.33} -\definecolor{olive4}{Hsb}{90,0.67,0.42} -\definecolor{olive5}{Hsb}{90,0.67,0.51} -\definecolor{olive6}{Hsb}{90,0.67,0.60} -\definecolor{olive7}{Hsb}{90,0.67,0.71} -\definecolor{olive8}{Hsb}{90,0.48,0.81} -\definecolor{olive9}{Hsb}{90,0.22,0.90} +\@namedef{ninecolors@define@mono}{% + \definecolor{gray1}{gray}{0.14} + \definecolor{gray2}{gray}{0.23} + \definecolor{gray3}{gray}{0.30} + \definecolor{gray4}{gray}{0.38} + \definecolor{gray5}{gray}{0.46} + \definecolor{gray6}{gray}{0.55} + \definecolor{gray7}{gray}{0.64} + \definecolor{gray8}{gray}{0.75} + \definecolor{gray9}{gray}{0.87} +} -\definecolor{green1}{Hsb}{120,0.67,0.16} -\definecolor{green2}{Hsb}{120,0.67,0.26} -\definecolor{green3}{Hsb}{120,0.67,0.35} -\definecolor{green4}{Hsb}{120,0.67,0.44} -\definecolor{green5}{Hsb}{120,0.67,0.53} -\definecolor{green6}{Hsb}{120,0.67,0.63} -\definecolor{green7}{Hsb}{120,0.67,0.74} -\definecolor{green8}{Hsb}{120,0.42,0.83} -\definecolor{green9}{Hsb}{120,0.19,0.91} +\@namedef{ninecolors@define@color@low}{% + \definecolor{red1}{rgb:Hsb}{0,0.67,0.26} + \definecolor{red2}{rgb:Hsb}{0,0.67,0.41} + \definecolor{red3}{rgb:Hsb}{0,0.67,0.54} + \definecolor{red4}{rgb:Hsb}{0,0.67,0.67} + \definecolor{red5}{rgb:Hsb}{0,0.60,0.77} + \definecolor{red6}{rgb:Hsb}{0,0.46,0.81} + \definecolor{red7}{rgb:Hsb}{0,0.34,0.86} + \definecolor{red8}{rgb:Hsb}{0,0.22,0.90} + \definecolor{red9}{rgb:Hsb}{0,0.11,0.95} + \definecolor{brown1}{rgb:Hsb}{30,0.67,0.19} + \definecolor{brown2}{rgb:Hsb}{30,0.67,0.31} + \definecolor{brown3}{rgb:Hsb}{30,0.67,0.41} + \definecolor{brown4}{rgb:Hsb}{30,0.67,0.51} + \definecolor{brown5}{rgb:Hsb}{30,0.67,0.62} + \definecolor{brown6}{rgb:Hsb}{30,0.67,0.74} + \definecolor{brown7}{rgb:Hsb}{30,0.49,0.80} + \definecolor{brown8}{rgb:Hsb}{30,0.32,0.86} + \definecolor{brown9}{rgb:Hsb}{30,0.15,0.93} + \definecolor{yellow1}{rgb:Hsb}{60,0.67,0.15} + \definecolor{yellow2}{rgb:Hsb}{60,0.67,0.23} + \definecolor{yellow3}{rgb:Hsb}{60,0.67,0.31} + \definecolor{yellow4}{rgb:Hsb}{60,0.67,0.39} + \definecolor{yellow5}{rgb:Hsb}{60,0.67,0.47} + \definecolor{yellow6}{rgb:Hsb}{60,0.67,0.56} + \definecolor{yellow7}{rgb:Hsb}{60,0.67,0.66} + \definecolor{yellow8}{rgb:Hsb}{60,0.59,0.77} + \definecolor{yellow9}{rgb:Hsb}{60,0.27,0.88} + \definecolor{olive1}{rgb:Hsb}{90,0.67,0.16} + \definecolor{olive2}{rgb:Hsb}{90,0.67,0.25} + \definecolor{olive3}{rgb:Hsb}{90,0.67,0.33} + \definecolor{olive4}{rgb:Hsb}{90,0.67,0.42} + \definecolor{olive5}{rgb:Hsb}{90,0.67,0.51} + \definecolor{olive6}{rgb:Hsb}{90,0.67,0.60} + \definecolor{olive7}{rgb:Hsb}{90,0.67,0.71} + \definecolor{olive8}{rgb:Hsb}{90,0.48,0.81} + \definecolor{olive9}{rgb:Hsb}{90,0.22,0.90} + \definecolor{green1}{rgb:Hsb}{120,0.67,0.16} + \definecolor{green2}{rgb:Hsb}{120,0.67,0.26} + \definecolor{green3}{rgb:Hsb}{120,0.67,0.35} + \definecolor{green4}{rgb:Hsb}{120,0.67,0.44} + \definecolor{green5}{rgb:Hsb}{120,0.67,0.53} + \definecolor{green6}{rgb:Hsb}{120,0.67,0.63} + \definecolor{green7}{rgb:Hsb}{120,0.67,0.74} + \definecolor{green8}{rgb:Hsb}{120,0.42,0.83} + \definecolor{green9}{rgb:Hsb}{120,0.19,0.91} + \definecolor{teal1}{rgb:Hsb}{150,0.67,0.16} + \definecolor{teal2}{rgb:Hsb}{150,0.67,0.26} + \definecolor{teal3}{rgb:Hsb}{150,0.67,0.34} + \definecolor{teal4}{rgb:Hsb}{150,0.67,0.43} + \definecolor{teal5}{rgb:Hsb}{150,0.67,0.52} + \definecolor{teal6}{rgb:Hsb}{150,0.67,0.62} + \definecolor{teal7}{rgb:Hsb}{150,0.67,0.73} + \definecolor{teal8}{rgb:Hsb}{150,0.44,0.82} + \definecolor{teal9}{rgb:Hsb}{150,0.20,0.91} + \definecolor{cyan1}{rgb:Hsb}{180,0.67,0.16} + \definecolor{cyan2}{rgb:Hsb}{180,0.67,0.25} + \definecolor{cyan3}{rgb:Hsb}{180,0.67,0.33} + \definecolor{cyan4}{rgb:Hsb}{180,0.67,0.42} + \definecolor{cyan5}{rgb:Hsb}{180,0.67,0.51} + \definecolor{cyan6}{rgb:Hsb}{180,0.67,0.60} + \definecolor{cyan7}{rgb:Hsb}{180,0.67,0.71} + \definecolor{cyan8}{rgb:Hsb}{180,0.47,0.81} + \definecolor{cyan9}{rgb:Hsb}{180,0.21,0.90} + \definecolor{azure1}{rgb:Hsb}{210,0.67,0.22} + \definecolor{azure2}{rgb:Hsb}{210,0.67,0.35} + \definecolor{azure3}{rgb:Hsb}{210,0.67,0.47} + \definecolor{azure4}{rgb:Hsb}{210,0.67,0.59} + \definecolor{azure5}{rgb:Hsb}{210,0.67,0.71} + \definecolor{azure6}{rgb:Hsb}{210,0.56,0.78} + \definecolor{azure7}{rgb:Hsb}{210,0.41,0.83} + \definecolor{azure8}{rgb:Hsb}{210,0.27,0.88} + \definecolor{azure9}{rgb:Hsb}{210,0.13,0.94} + \definecolor{blue1}{rgb:Hsb}{240,0.67,0.34} + \definecolor{blue2}{rgb:Hsb}{240,0.67,0.53} + \definecolor{blue3}{rgb:Hsb}{240,0.67,0.70} + \definecolor{blue4}{rgb:Hsb}{240,0.58,0.77} + \definecolor{blue5}{rgb:Hsb}{240,0.48,0.81} + \definecolor{blue6}{rgb:Hsb}{240,0.39,0.84} + \definecolor{blue7}{rgb:Hsb}{240,0.29,0.87} + \definecolor{blue8}{rgb:Hsb}{240,0.19,0.91} + \definecolor{blue9}{rgb:Hsb}{240,0.10,0.95} + \definecolor{violet1}{rgb:Hsb}{270,0.67,0.29} + \definecolor{violet2}{rgb:Hsb}{270,0.67,0.45} + \definecolor{violet3}{rgb:Hsb}{270,0.67,0.60} + \definecolor{violet4}{rgb:Hsb}{270,0.67,0.75} + \definecolor{violet5}{rgb:Hsb}{270,0.54,0.79} + \definecolor{violet6}{rgb:Hsb}{270,0.43,0.82} + \definecolor{violet7}{rgb:Hsb}{270,0.32,0.86} + \definecolor{violet8}{rgb:Hsb}{270,0.21,0.90} + \definecolor{violet9}{rgb:Hsb}{270,0.11,0.95} + \definecolor{magenta1}{rgb:Hsb}{300,0.67,0.23} + \definecolor{magenta2}{rgb:Hsb}{300,0.67,0.37} + \definecolor{magenta3}{rgb:Hsb}{300,0.67,0.49} + \definecolor{magenta4}{rgb:Hsb}{300,0.67,0.61} + \definecolor{magenta5}{rgb:Hsb}{300,0.67,0.74} + \definecolor{magenta6}{rgb:Hsb}{300,0.51,0.80} + \definecolor{magenta7}{rgb:Hsb}{300,0.37,0.84} + \definecolor{magenta8}{rgb:Hsb}{300,0.24,0.89} + \definecolor{magenta9}{rgb:Hsb}{300,0.12,0.94} + \definecolor{purple1}{rgb:Hsb}{330,0.67,0.25} + \definecolor{purple2}{rgb:Hsb}{330,0.67,0.39} + \definecolor{purple3}{rgb:Hsb}{330,0.67,0.52} + \definecolor{purple4}{rgb:Hsb}{330,0.67,0.65} + \definecolor{purple5}{rgb:Hsb}{330,0.63,0.76} + \definecolor{purple6}{rgb:Hsb}{330,0.48,0.81} + \definecolor{purple7}{rgb:Hsb}{330,0.35,0.85} + \definecolor{purple8}{rgb:Hsb}{330,0.23,0.90} + \definecolor{purple9}{rgb:Hsb}{330,0.11,0.95} +} -\definecolor{teal1}{Hsb}{150,0.67,0.16} -\definecolor{teal2}{Hsb}{150,0.67,0.26} -\definecolor{teal3}{Hsb}{150,0.67,0.34} -\definecolor{teal4}{Hsb}{150,0.67,0.43} -\definecolor{teal5}{Hsb}{150,0.67,0.52} -\definecolor{teal6}{Hsb}{150,0.67,0.62} -\definecolor{teal7}{Hsb}{150,0.67,0.73} -\definecolor{teal8}{Hsb}{150,0.44,0.82} -\definecolor{teal9}{Hsb}{150,0.20,0.91} +\@namedef{ninecolors@define@color@medium}{% + \definecolor{red1}{rgb:Hsb}{0,0.79,0.28} + \definecolor{red2}{rgb:Hsb}{0,0.79,0.44} + \definecolor{red3}{rgb:Hsb}{0,0.79,0.58} + \definecolor{red4}{rgb:Hsb}{0,0.79,0.72} + \definecolor{red5}{rgb:Hsb}{0,0.72,0.84} + \definecolor{red6}{rgb:Hsb}{0,0.54,0.87} + \definecolor{red7}{rgb:Hsb}{0,0.40,0.90} + \definecolor{red8}{rgb:Hsb}{0,0.26,0.93} + \definecolor{red9}{rgb:Hsb}{0,0.13,0.97} + \definecolor{brown1}{rgb:Hsb}{30,0.79,0.21} + \definecolor{brown2}{rgb:Hsb}{30,0.79,0.33} + \definecolor{brown3}{rgb:Hsb}{30,0.79,0.43} + \definecolor{brown4}{rgb:Hsb}{30,0.79,0.54} + \definecolor{brown5}{rgb:Hsb}{30,0.79,0.66} + \definecolor{brown6}{rgb:Hsb}{30,0.79,0.78} + \definecolor{brown7}{rgb:Hsb}{30,0.63,0.86} + \definecolor{brown8}{rgb:Hsb}{30,0.41,0.90} + \definecolor{brown9}{rgb:Hsb}{30,0.20,0.95} + \definecolor{yellow1}{rgb:Hsb}{60,0.79,0.15} + \definecolor{yellow2}{rgb:Hsb}{60,0.79,0.23} + \definecolor{yellow3}{rgb:Hsb}{60,0.79,0.31} + \definecolor{yellow4}{rgb:Hsb}{60,0.79,0.39} + \definecolor{yellow5}{rgb:Hsb}{60,0.79,0.48} + \definecolor{yellow6}{rgb:Hsb}{60,0.79,0.57} + \definecolor{yellow7}{rgb:Hsb}{60,0.79,0.66} + \definecolor{yellow8}{rgb:Hsb}{60,0.79,0.77} + \definecolor{yellow9}{rgb:Hsb}{60,0.46,0.89} + \definecolor{olive1}{rgb:Hsb}{90,0.79,0.16} + \definecolor{olive2}{rgb:Hsb}{90,0.79,0.25} + \definecolor{olive3}{rgb:Hsb}{90,0.79,0.34} + \definecolor{olive4}{rgb:Hsb}{90,0.79,0.42} + \definecolor{olive5}{rgb:Hsb}{90,0.79,0.51} + \definecolor{olive6}{rgb:Hsb}{90,0.79,0.61} + \definecolor{olive7}{rgb:Hsb}{90,0.79,0.72} + \definecolor{olive8}{rgb:Hsb}{90,0.76,0.83} + \definecolor{olive9}{rgb:Hsb}{90,0.34,0.92} + \definecolor{green1}{rgb:Hsb}{120,0.79,0.17} + \definecolor{green2}{rgb:Hsb}{120,0.79,0.26} + \definecolor{green3}{rgb:Hsb}{120,0.79,0.35} + \definecolor{green4}{rgb:Hsb}{120,0.79,0.44} + \definecolor{green5}{rgb:Hsb}{120,0.79,0.53} + \definecolor{green6}{rgb:Hsb}{120,0.79,0.63} + \definecolor{green7}{rgb:Hsb}{120,0.79,0.74} + \definecolor{green8}{rgb:Hsb}{120,0.64,0.85} + \definecolor{green9}{rgb:Hsb}{120,0.28,0.93} + \definecolor{teal1}{rgb:Hsb}{150,0.79,0.16} + \definecolor{teal2}{rgb:Hsb}{150,0.79,0.26} + \definecolor{teal3}{rgb:Hsb}{150,0.79,0.35} + \definecolor{teal4}{rgb:Hsb}{150,0.79,0.43} + \definecolor{teal5}{rgb:Hsb}{150,0.79,0.53} + \definecolor{teal6}{rgb:Hsb}{150,0.79,0.62} + \definecolor{teal7}{rgb:Hsb}{150,0.79,0.73} + \definecolor{teal8}{rgb:Hsb}{150,0.68,0.85} + \definecolor{teal9}{rgb:Hsb}{150,0.30,0.93} + \definecolor{cyan1}{rgb:Hsb}{180,0.79,0.16} + \definecolor{cyan2}{rgb:Hsb}{180,0.79,0.25} + \definecolor{cyan3}{rgb:Hsb}{180,0.79,0.34} + \definecolor{cyan4}{rgb:Hsb}{180,0.79,0.42} + \definecolor{cyan5}{rgb:Hsb}{180,0.79,0.51} + \definecolor{cyan6}{rgb:Hsb}{180,0.79,0.61} + \definecolor{cyan7}{rgb:Hsb}{180,0.79,0.71} + \definecolor{cyan8}{rgb:Hsb}{180,0.77,0.83} + \definecolor{cyan9}{rgb:Hsb}{180,0.32,0.92} + \definecolor{azure1}{rgb:Hsb}{210,0.79,0.24} + \definecolor{azure2}{rgb:Hsb}{210,0.79,0.38} + \definecolor{azure3}{rgb:Hsb}{210,0.79,0.51} + \definecolor{azure4}{rgb:Hsb}{210,0.79,0.64} + \definecolor{azure5}{rgb:Hsb}{210,0.79,0.77} + \definecolor{azure6}{rgb:Hsb}{210,0.67,0.85} + \definecolor{azure7}{rgb:Hsb}{210,0.50,0.88} + \definecolor{azure8}{rgb:Hsb}{210,0.33,0.92} + \definecolor{azure9}{rgb:Hsb}{210,0.17,0.96} + \definecolor{blue1}{rgb:Hsb}{240,0.79,0.41} + \definecolor{blue2}{rgb:Hsb}{240,0.79,0.64} + \definecolor{blue3}{rgb:Hsb}{240,0.77,0.83} + \definecolor{blue4}{rgb:Hsb}{240,0.65,0.85} + \definecolor{blue5}{rgb:Hsb}{240,0.54,0.87} + \definecolor{blue6}{rgb:Hsb}{240,0.43,0.90} + \definecolor{blue7}{rgb:Hsb}{240,0.33,0.92} + \definecolor{blue8}{rgb:Hsb}{240,0.22,0.94} + \definecolor{blue9}{rgb:Hsb}{240,0.11,0.97} + \definecolor{violet1}{rgb:Hsb}{270,0.79,0.33} + \definecolor{violet2}{rgb:Hsb}{270,0.79,0.52} + \definecolor{violet3}{rgb:Hsb}{270,0.79,0.69} + \definecolor{violet4}{rgb:Hsb}{270,0.76,0.83} + \definecolor{violet5}{rgb:Hsb}{270,0.62,0.86} + \definecolor{violet6}{rgb:Hsb}{270,0.49,0.88} + \definecolor{violet7}{rgb:Hsb}{270,0.37,0.91} + \definecolor{violet8}{rgb:Hsb}{270,0.25,0.94} + \definecolor{violet9}{rgb:Hsb}{270,0.13,0.97} + \definecolor{magenta1}{rgb:Hsb}{300,0.79,0.25} + \definecolor{magenta2}{rgb:Hsb}{300,0.79,0.39} + \definecolor{magenta3}{rgb:Hsb}{300,0.79,0.52} + \definecolor{magenta4}{rgb:Hsb}{300,0.79,0.65} + \definecolor{magenta5}{rgb:Hsb}{300,0.79,0.78} + \definecolor{magenta6}{rgb:Hsb}{300,0.62,0.86} + \definecolor{magenta7}{rgb:Hsb}{300,0.44,0.89} + \definecolor{magenta8}{rgb:Hsb}{300,0.29,0.93} + \definecolor{magenta9}{rgb:Hsb}{300,0.14,0.96} + \definecolor{purple1}{rgb:Hsb}{330,0.79,0.27} + \definecolor{purple2}{rgb:Hsb}{330,0.79,0.42} + \definecolor{purple3}{rgb:Hsb}{330,0.79,0.56} + \definecolor{purple4}{rgb:Hsb}{330,0.79,0.70} + \definecolor{purple5}{rgb:Hsb}{330,0.76,0.83} + \definecolor{purple6}{rgb:Hsb}{330,0.57,0.87} + \definecolor{purple7}{rgb:Hsb}{330,0.42,0.90} + \definecolor{purple8}{rgb:Hsb}{330,0.27,0.93} + \definecolor{purple9}{rgb:Hsb}{330,0.14,0.96} +} -\definecolor{cyan1}{Hsb}{180,0.67,0.16} -\definecolor{cyan2}{Hsb}{180,0.67,0.25} -\definecolor{cyan3}{Hsb}{180,0.67,0.33} -\definecolor{cyan4}{Hsb}{180,0.67,0.42} -\definecolor{cyan5}{Hsb}{180,0.67,0.51} -\definecolor{cyan6}{Hsb}{180,0.67,0.60} -\definecolor{cyan7}{Hsb}{180,0.67,0.71} -\definecolor{cyan8}{Hsb}{180,0.47,0.81} -\definecolor{cyan9}{Hsb}{180,0.21,0.90} +\@namedef{ninecolors@define@color@high}{% + \definecolor{red1}{rgb:Hsb}{0,0.89,0.30} + \definecolor{red2}{rgb:Hsb}{0,0.89,0.46} + \definecolor{red3}{rgb:Hsb}{0,0.89,0.61} + \definecolor{red4}{rgb:Hsb}{0,0.89,0.76} + \definecolor{red5}{rgb:Hsb}{0,0.87,0.90} + \definecolor{red6}{rgb:Hsb}{0,0.62,0.93} + \definecolor{red7}{rgb:Hsb}{0,0.45,0.95} + \definecolor{red8}{rgb:Hsb}{0,0.30,0.96} + \definecolor{red9}{rgb:Hsb}{0,0.15,0.98} + \definecolor{brown1}{rgb:Hsb}{30,0.89,0.22} + \definecolor{brown2}{rgb:Hsb}{30,0.89,0.34} + \definecolor{brown3}{rgb:Hsb}{30,0.89,0.46} + \definecolor{brown4}{rgb:Hsb}{30,0.89,0.57} + \definecolor{brown5}{rgb:Hsb}{30,0.89,0.69} + \definecolor{brown6}{rgb:Hsb}{30,0.89,0.82} + \definecolor{brown7}{rgb:Hsb}{30,0.77,0.91} + \definecolor{brown8}{rgb:Hsb}{30,0.51,0.94} + \definecolor{brown9}{rgb:Hsb}{30,0.25,0.97} + \definecolor{yellow1}{rgb:Hsb}{60,0.89,0.15} + \definecolor{yellow2}{rgb:Hsb}{60,0.89,0.23} + \definecolor{yellow3}{rgb:Hsb}{60,0.89,0.31} + \definecolor{yellow4}{rgb:Hsb}{60,0.89,0.39} + \definecolor{yellow5}{rgb:Hsb}{60,0.89,0.48} + \definecolor{yellow6}{rgb:Hsb}{60,0.89,0.57} + \definecolor{yellow7}{rgb:Hsb}{60,0.89,0.66} + \definecolor{yellow8}{rgb:Hsb}{60,0.89,0.77} + \definecolor{yellow9}{rgb:Hsb}{60,0.89,0.90} + \definecolor{olive1}{rgb:Hsb}{90,0.89,0.16} + \definecolor{olive2}{rgb:Hsb}{90,0.89,0.26} + \definecolor{olive3}{rgb:Hsb}{90,0.89,0.34} + \definecolor{olive4}{rgb:Hsb}{90,0.89,0.43} + \definecolor{olive5}{rgb:Hsb}{90,0.89,0.52} + \definecolor{olive6}{rgb:Hsb}{90,0.89,0.61} + \definecolor{olive7}{rgb:Hsb}{90,0.89,0.72} + \definecolor{olive8}{rgb:Hsb}{90,0.89,0.84} + \definecolor{olive9}{rgb:Hsb}{90,0.52,0.94} + \definecolor{green1}{rgb:Hsb}{120,0.89,0.17} + \definecolor{green2}{rgb:Hsb}{120,0.89,0.27} + \definecolor{green3}{rgb:Hsb}{120,0.89,0.35} + \definecolor{green4}{rgb:Hsb}{120,0.89,0.44} + \definecolor{green5}{rgb:Hsb}{120,0.89,0.54} + \definecolor{green6}{rgb:Hsb}{120,0.89,0.64} + \definecolor{green7}{rgb:Hsb}{120,0.89,0.75} + \definecolor{green8}{rgb:Hsb}{120,0.89,0.87} + \definecolor{green9}{rgb:Hsb}{120,0.39,0.95} + \definecolor{teal1}{rgb:Hsb}{150,0.89,0.17} + \definecolor{teal2}{rgb:Hsb}{150,0.89,0.26} + \definecolor{teal3}{rgb:Hsb}{150,0.89,0.35} + \definecolor{teal4}{rgb:Hsb}{150,0.89,0.44} + \definecolor{teal5}{rgb:Hsb}{150,0.89,0.53} + \definecolor{teal6}{rgb:Hsb}{150,0.89,0.63} + \definecolor{teal7}{rgb:Hsb}{150,0.89,0.74} + \definecolor{teal8}{rgb:Hsb}{150,0.89,0.86} + \definecolor{teal9}{rgb:Hsb}{150,0.43,0.95} + \definecolor{cyan1}{rgb:Hsb}{180,0.89,0.16} + \definecolor{cyan2}{rgb:Hsb}{180,0.89,0.25} + \definecolor{cyan3}{rgb:Hsb}{180,0.89,0.34} + \definecolor{cyan4}{rgb:Hsb}{180,0.89,0.42} + \definecolor{cyan5}{rgb:Hsb}{180,0.89,0.51} + \definecolor{cyan6}{rgb:Hsb}{180,0.89,0.61} + \definecolor{cyan7}{rgb:Hsb}{180,0.89,0.71} + \definecolor{cyan8}{rgb:Hsb}{180,0.89,0.83} + \definecolor{cyan9}{rgb:Hsb}{180,0.50,0.94} + \definecolor{azure1}{rgb:Hsb}{210,0.89,0.26} + \definecolor{azure2}{rgb:Hsb}{210,0.89,0.41} + \definecolor{azure3}{rgb:Hsb}{210,0.89,0.55} + \definecolor{azure4}{rgb:Hsb}{210,0.89,0.69} + \definecolor{azure5}{rgb:Hsb}{210,0.89,0.83} + \definecolor{azure6}{rgb:Hsb}{210,0.77,0.91} + \definecolor{azure7}{rgb:Hsb}{210,0.58,0.93} + \definecolor{azure8}{rgb:Hsb}{210,0.39,0.95} + \definecolor{azure9}{rgb:Hsb}{210,0.20,0.98} + \definecolor{blue1}{rgb:Hsb}{240,0.89,0.48} + \definecolor{blue2}{rgb:Hsb}{240,0.89,0.73} + \definecolor{blue3}{rgb:Hsb}{240,0.84,0.90} + \definecolor{blue4}{rgb:Hsb}{240,0.70,0.92} + \definecolor{blue5}{rgb:Hsb}{240,0.58,0.93} + \definecolor{blue6}{rgb:Hsb}{240,0.47,0.94} + \definecolor{blue7}{rgb:Hsb}{240,0.36,0.96} + \definecolor{blue8}{rgb:Hsb}{240,0.25,0.97} + \definecolor{blue9}{rgb:Hsb}{240,0.13,0.98} + \definecolor{violet1}{rgb:Hsb}{270,0.89,0.37} + \definecolor{violet2}{rgb:Hsb}{270,0.89,0.57} + \definecolor{violet3}{rgb:Hsb}{270,0.89,0.75} + \definecolor{violet4}{rgb:Hsb}{270,0.85,0.90} + \definecolor{violet5}{rgb:Hsb}{270,0.68,0.92} + \definecolor{violet6}{rgb:Hsb}{270,0.54,0.94} + \definecolor{violet7}{rgb:Hsb}{270,0.41,0.95} + \definecolor{violet8}{rgb:Hsb}{270,0.28,0.97} + \definecolor{violet9}{rgb:Hsb}{270,0.14,0.98} + \definecolor{magenta1}{rgb:Hsb}{300,0.89,0.26} + \definecolor{magenta2}{rgb:Hsb}{300,0.89,0.41} + \definecolor{magenta3}{rgb:Hsb}{300,0.89,0.54} + \definecolor{magenta4}{rgb:Hsb}{300,0.89,0.67} + \definecolor{magenta5}{rgb:Hsb}{300,0.89,0.80} + \definecolor{magenta6}{rgb:Hsb}{300,0.76,0.91} + \definecolor{magenta7}{rgb:Hsb}{300,0.52,0.94} + \definecolor{magenta8}{rgb:Hsb}{300,0.33,0.96} + \definecolor{magenta9}{rgb:Hsb}{300,0.17,0.98} + \definecolor{purple1}{rgb:Hsb}{330,0.89,0.29} + \definecolor{purple2}{rgb:Hsb}{330,0.89,0.45} + \definecolor{purple3}{rgb:Hsb}{330,0.89,0.59} + \definecolor{purple4}{rgb:Hsb}{330,0.89,0.73} + \definecolor{purple5}{rgb:Hsb}{330,0.89,0.88} + \definecolor{purple6}{rgb:Hsb}{330,0.66,0.92} + \definecolor{purple7}{rgb:Hsb}{330,0.47,0.94} + \definecolor{purple8}{rgb:Hsb}{330,0.31,0.96} + \definecolor{purple9}{rgb:Hsb}{330,0.16,0.98} +} -\definecolor{azure1}{Hsb}{210,0.67,0.22} -\definecolor{azure2}{Hsb}{210,0.67,0.35} -\definecolor{azure3}{Hsb}{210,0.67,0.47} -\definecolor{azure4}{Hsb}{210,0.67,0.59} -\definecolor{azure5}{Hsb}{210,0.67,0.71} -\definecolor{azure6}{Hsb}{210,0.56,0.78} -\definecolor{azure7}{Hsb}{210,0.41,0.83} -\definecolor{azure8}{Hsb}{210,0.27,0.88} -\definecolor{azure9}{Hsb}{210,0.13,0.94} +\@nameuse{ninecolors@define@mono} +\@nameuse{ninecolors@define@color@medium} -\definecolor{blue1}{Hsb}{240,0.67,0.34} -\definecolor{blue2}{Hsb}{240,0.67,0.53} -\definecolor{blue3}{Hsb}{240,0.67,0.70} -\definecolor{blue4}{Hsb}{240,0.58,0.77} -\definecolor{blue5}{Hsb}{240,0.48,0.81} -\definecolor{blue6}{Hsb}{240,0.39,0.84} -\definecolor{blue7}{Hsb}{240,0.29,0.87} -\definecolor{blue8}{Hsb}{240,0.19,0.91} -\definecolor{blue9}{Hsb}{240,0.10,0.95} - -\definecolor{violet1}{Hsb}{270,0.67,0.29} -\definecolor{violet2}{Hsb}{270,0.67,0.45} -\definecolor{violet3}{Hsb}{270,0.67,0.60} -\definecolor{violet4}{Hsb}{270,0.67,0.75} -\definecolor{violet5}{Hsb}{270,0.54,0.79} -\definecolor{violet6}{Hsb}{270,0.43,0.82} -\definecolor{violet7}{Hsb}{270,0.32,0.86} -\definecolor{violet8}{Hsb}{270,0.21,0.90} -\definecolor{violet9}{Hsb}{270,0.11,0.95} - -\definecolor{magenta1}{Hsb}{300,0.67,0.23} -\definecolor{magenta2}{Hsb}{300,0.67,0.37} -\definecolor{magenta3}{Hsb}{300,0.67,0.49} -\definecolor{magenta4}{Hsb}{300,0.67,0.61} -\definecolor{magenta5}{Hsb}{300,0.67,0.74} -\definecolor{magenta6}{Hsb}{300,0.51,0.80} -\definecolor{magenta7}{Hsb}{300,0.37,0.84} -\definecolor{magenta8}{Hsb}{300,0.24,0.89} -\definecolor{magenta9}{Hsb}{300,0.12,0.94} - -\definecolor{purple1}{Hsb}{330,0.67,0.25} -\definecolor{purple2}{Hsb}{330,0.67,0.39} -\definecolor{purple3}{Hsb}{330,0.67,0.52} -\definecolor{purple4}{Hsb}{330,0.67,0.65} -\definecolor{purple5}{Hsb}{330,0.63,0.76} -\definecolor{purple6}{Hsb}{330,0.48,0.81} -\definecolor{purple7}{Hsb}{330,0.35,0.85} -\definecolor{purple8}{Hsb}{330,0.23,0.90} -\definecolor{purple9}{Hsb}{330,0.11,0.95} +\ExplSyntaxOff diff --git a/macros/latex/contrib/ninecolors/ninecolors.tex b/macros/latex/contrib/ninecolors/ninecolors.tex index cdda3624bd..812ea72a9b 100644 --- a/macros/latex/contrib/ninecolors/ninecolors.tex +++ b/macros/latex/contrib/ninecolors/ninecolors.tex @@ -11,13 +11,14 @@ urlcolor=blue3, } -\newcommand*{\myversion}{2021A} -\newcommand*{\mydate}{\the\year/\mylpad\month/\mylpad\day\ (v\myversion)} +\newcommand*{\myversion}{2021B} +\newcommand*{\mydate}{Version \myversion\ (\the\year-\mylpad\month-\mylpad\day)} \newcommand*{\mylpad}[1]{\ifnum#1<10 0\the#1\else\the#1\fi} \begin{document} -\title{\href{https://github.com/lvjr/ninecolors}{Ninecolors: select colors with proper WCAG color contrast}} +\title{\textcolor{blue3}{Ninecolors: select colors with proper WCAG color contrast}% + \footnote{\url{https://github.com/lvjr/ninecolors}}} \author{Jianrui Lyu (tolvjr@163.com)} \date{\mydate} \maketitle @@ -28,6 +29,7 @@ Also color black is of level 0, and color white is of level 10. \bigskip +\newcommand{\NineTestBack}{% \foreach \l in {1,...,9} { \noindent @@ -37,10 +39,12 @@ Also color black is of level 0, and color white is of level 10. \colorbox{\n\l}{\color{\mycolor}\texttt\strut\n\l}% } \par -} +}} +\NineTestBack \bigskip +\newcommand{\NineTestFore}{% \foreach \l in {1,...,9} { \noindent @@ -50,7 +54,8 @@ Also color black is of level 0, and color white is of level 10. \colorbox{\mycolor}{\color{\n\l}\texttt\strut\n\l}% } \par -} +}} +\NineTestFore \bigskip \hrule @@ -62,6 +67,7 @@ as foreground and background colors, you will get proper \bigskip +\newcommand{\NineTestContrast}{% \colorbox{blue9}{% \strut\color{green3}The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. } @@ -76,7 +82,90 @@ as foreground and background colors, you will get proper \par\nointerlineskip \colorbox{brown3}{% \strut\color{violet9}The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. -} +}} +\NineTestContrast + +\bigskip +\hrule +\bigskip + +If you need to select more contrasting foreground and background colors, which may have other hues, +you could visit \href{https://lvjr.bitbucket.io/contrast.html}{WCAG Color Contrast Tool} +page which is designed by the author. + +\newpage\vspace*{31mm} +\NineColors{saturation=low} + +You can change the saturation of colors by {\color{red3}\verb!\NineColors!} command. +By default {\color{red3}\verb!saturation=medium!}. +Colors in this page have been changed by {\color{red3}\verb!\NineColors{saturation=low}!}. + +\bigskip + +\textcolor{red4}{Ninecolors} package carefully selects and defines 9 colors for 13 hues each. +All colors with the same suffix number have equal luminance level. +Also color black is of level 0, and color white is of level 10. + +\bigskip + +\NineTestBack + +\bigskip + +\NineTestFore + +\bigskip +\hrule +\bigskip + +By simply choosing two colors in the above list, which differ in level by at least 5, +as foreground and background colors, you will get proper +\href{https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum.html}{WCAG Color Contrast}. + +\bigskip + +\NineTestContrast + +\bigskip +\hrule +\bigskip + +If you need to select more contrasting foreground and background colors, which may have other hues, +you could visit \href{https://lvjr.bitbucket.io/contrast.html}{WCAG Color Contrast Tool} +page which is designed by the author. + +\newpage\vspace*{31mm} +\NineColors{saturation=high} + +You can change the saturation of colors by {\color{red3}\verb!\NineColors!} command. +By default {\color{red3}\verb!saturation=medium!}. +Colors in this page have been changed by {\color{red3}\verb!\NineColors{saturation=high}!}. + +\bigskip + +\textcolor{red4}{Ninecolors} package carefully selects and defines 9 colors for 13 hues each. +All colors with the same suffix number have equal luminance level. +Also color black is of level 0, and color white is of level 10. + +\bigskip + +\NineTestBack + +\bigskip + +\NineTestFore + +\bigskip +\hrule +\bigskip + +By simply choosing two colors in the above list, which differ in level by at least 5, +as foreground and background colors, you will get proper +\href{https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum.html}{WCAG Color Contrast}. + +\bigskip + +\NineTestContrast \bigskip \hrule |