diff options
author | Karl Berry <karl@freefriends.org> | 2020-09-24 20:46:14 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2020-09-24 20:46:14 +0000 |
commit | 2e1f687d46764061ec8df089e40b9ac1aece2761 (patch) | |
tree | b633d8a205fd529be57878fc2502e2c07a4c5efc /Master/texmf-dist/source | |
parent | c0e73acce7eb5e03fceb4e011fa579a5706460c2 (diff) |
l3 (24sep20)
git-svn-id: svn://tug.org/texlive/trunk@56424 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source')
81 files changed, 1474 insertions, 514 deletions
diff --git a/Master/texmf-dist/source/latex/l3backend/l3backend-basics.dtx b/Master/texmf-dist/source/latex/l3backend/l3backend-basics.dtx index abd972dca08..8b01e543ce0 100644 --- a/Master/texmf-dist/source/latex/l3backend/l3backend-basics.dtx +++ b/Master/texmf-dist/source/latex/l3backend/l3backend-basics.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-11} +% \date{Released 2020-09-24} % % \maketitle % @@ -70,27 +70,27 @@ % \begin{macrocode} \ProvidesExplFile %<*dvipdfmx> - {l3backend-dvipdfmx.def}{2020-09-11}{} + {l3backend-dvipdfmx.def}{2020-09-24}{} {L3 backend support: dvipdfmx} %</dvipdfmx> %<*dvips> - {l3backend-dvips.def}{2020-09-11}{} + {l3backend-dvips.def}{2020-09-24}{} {L3 backend support: dvips} %</dvips> %<*dvisvgm> - {l3backend-dvisvgm.def}{2020-09-11}{} + {l3backend-dvisvgm.def}{2020-09-24}{} {L3 backend support: dvisvgm} %</dvisvgm> %<*luatex> - {l3backend-luatex.def}{2020-09-11}{} + {l3backend-luatex.def}{2020-09-24}{} {L3 backend support: PDF output (LuaTeX)} %</luatex> %<*pdftex> - {l3backend-pdftex.def}{2020-09-11}{} + {l3backend-pdftex.def}{2020-09-24}{} {L3 backend support: PDF output (pdfTeX)} %</pdftex> %<*xetex> - {l3backend-xetex.def}{2020-09-11}{} + {l3backend-xetex.def}{2020-09-24}{} {L3 backend support: XeTeX} %</xetex> % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3backend/l3backend-box.dtx b/Master/texmf-dist/source/latex/l3backend/l3backend-box.dtx index 039fa38c85b..e233c729f3a 100644 --- a/Master/texmf-dist/source/latex/l3backend/l3backend-box.dtx +++ b/Master/texmf-dist/source/latex/l3backend/l3backend-box.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-11} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3backend/l3backend-color.dtx b/Master/texmf-dist/source/latex/l3backend/l3backend-color.dtx index a9a86daebb1..baefde5d3cb 100644 --- a/Master/texmf-dist/source/latex/l3backend/l3backend-color.dtx +++ b/Master/texmf-dist/source/latex/l3backend/l3backend-color.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-11} +% \date{Released 2020-09-24} % % \maketitle % @@ -308,10 +308,11 @@ %<*dvips> % \end{macrocode} % -% \begin{macro}{\@@_backend_select_separation:nn} +% \begin{macro}{\@@_backend_select_separation:nn, \@@_backend_select_devicen:nn} % \begin{macrocode} \cs_new_protected:Npn \@@_backend_select_separation:nn #1#2 { \@@_backend_select:n { separation ~ #1 ~ #2 } } +\cs_new_eq:NN \@@_backend_select_devicen:nn \@@_backend_select_separation:nn % \end{macrocode} % \end{macro} % @@ -362,7 +363,7 @@ { ! TeXDict ~ begin ~ - /color \int_use:N \g_@@_separation_int + /color \int_use:N \g_@@_model_int { [ ~ /Separation ~ ( \str_convert_pdfname:n {#1} ) ~ @@ -541,6 +542,30 @@ % \end{macro} % \end{macro} % +% \begin{macro}{\@@_backend_devicen_init:nnn} +% Trivial as almost all of the work occurs in the shared code. +% \begin{macrocode} +\cs_new_protected:Npn \@@_backend_devicen_init:nnn #1#2#3 + { + \__kernel_backend_literal:e + { + ! + TeXDict ~ begin ~ + /color \int_use:N \g_@@_model_int + { + [ ~ + /DeviceN ~ + [ ~ #1 ~ ] ~ + #2 ~ + { ~ #3 ~ } ~ + ] ~ setcolorspace + } ~ def ~ + end + } + } +% \end{macrocode} +% \end{macro} +% % \begin{macrocode} %</dvips> % \end{macrocode} @@ -549,10 +574,11 @@ %<*dvisvgm> % \end{macrocode} % -% \begin{macro}{\@@_backend_select_separation:nn} +% \begin{macro}{\@@_backend_select_separation:nn, \@@_backend_select_devicen:nn} % No support at present. % \begin{macrocode} \cs_new_protected:Npn \@@_backend_select_separation:nn #1#2 { } +\cs_new_protected:Npn \@@_backend_select_devicen:nn #1#2 { } % \end{macrocode} % \end{macro} % @@ -573,7 +599,7 @@ %<*dvipdfmx|luatex|pdftex|xetex> % \end{macrocode} % -% \begin{macro}{\@@_backend_select_separation:nn} +% \begin{macro}{\@@_backend_select_separation:nn, \@@_backend_select_devicen:nn} % \begin{macro}{\@@_backend_select:n} % Different syntaxes here as the stacks are accessed very differently. % \begin{macrocode} @@ -591,6 +617,7 @@ \group_insert_after:N \@@_backend_reset: } %</dvipdfmx|xetex> +\cs_new_eq:NN \@@_backend_select_devicen:nn \@@_backend_select_separation:nn % \end{macrocode} % \end{macro} % \end{macro} @@ -617,7 +644,7 @@ } \@@_backend_separation_init:n { - /Separation + /Separation ~ / \str_convert_pdfname:n {#1} ~ #2 ~ \pdf_object_last: } @@ -626,7 +653,7 @@ { \pdfcoredict_gput:nnn { Page / Resources / ColorSpace } - { color \int_use:N \g_@@_separation_int } + { color \int_use:N \g_@@_model_int } { \pdf_object_last: } } %</luatex|pdftex> @@ -638,7 +665,7 @@ %<*dvipdfmx|xetex> \__kernel_backend_literal:x { - pdf:obj ~ @color \int_use:N \g_@@_separation_int \c_space_tl + pdf:obj ~ @color \int_use:N \g_@@_model_int \c_space_tl [#1] } %</dvipdfmx|xetex> @@ -682,6 +709,67 @@ % \end{macro} % \end{macro} % +% \begin{macro}{\@@_backend_devicen_init:nnn} +% \begin{macro}[EXP]{\@@_backend_devicen_init:w} +% \begin{macro}{\@@_backend_devicen_init:n} +% Similar to the Separations case, but with an arbitrary function for +% the alternative space work. +% \begin{macrocode} +\cs_new_protected:Npn \@@_backend_devicen_init:nnn #1#2#3 + { + \pdf_object_now:nx { stream } + { + { + /FunctionType ~ 4 ~ + /Domain ~ + [ ~ + \prg_replicate:nn + { 0 \@@_backend_devicen_init:w #1 ~ \s_@@_stop } + { 0 ~ 1 ~ } ~ + ] ~ + /Range ~ + [ ~ + \str_case:nn {#2} + { + { /DeviceCMYK } { 0 ~ 1 ~ 0 ~ 1 ~ 0 ~ 1 ~ 0 ~ 1 } + { /DeviceGray } { 0 ~ 1 } + { /DeviceRGB } { 0 ~ 1 ~ 0 ~ 1 ~ 0 ~ 1 } + } ~ + ] + } + {#3} + } + \@@_backend_separation_init:n + { + /DeviceN ~ + [ ~ #1 ~ ] ~ + #2 ~ + \pdf_object_last: + } +%<*luatex|pdftex> + \use:x + { + \pdfcoredict_gput:nnn + { Page / Resources / ColorSpace } + { color \int_use:N \g_@@_model_int } + { \pdf_object_last: } + } +%</luatex|pdftex> + } +\cs_if_exist:NF \pdf_object_now:nn + { \cs_gset_protected:Npn \@@_backend_devicen_init:nnn #1#2#3 { } } +\cs_new:Npn \@@_backend_devicen_init:w #1 ~ #2 \s_@@_stop + { + + 1 + \tl_if_blank:nF {#2} + { \@@_backend_devicen_init:w #2 \s_@@_stop } + } +\cs_new_eq:NN \@@_backend_devicen_init:n \@@_backend_separation_init:n +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% % \begin{macrocode} %</dvipdfmx|luatex|pdftex|xetex> % \end{macrocode} @@ -730,13 +818,17 @@ % \begin{macro} % { % \@@_backend_fill_separation:nn, -% \@@_backend_stroke_separation:nn +% \@@_backend_stroke_separation:nn, +% \@@_backend_fill_devicen:nn, +% \@@_backend_stroke_devicen:nn % } % \begin{macrocode} \cs_new_protected:Npn \@@_backend_fill_separation:nn #1#2 { \__kernel_backend_literal_pdf:n { /#1 ~ cs ~ #2 ~ scn } } \cs_new_protected:Npn \@@_backend_stroke_separation:nn #1#2 { \__kernel_backend_literal_pdf:n { /#1 ~ CS ~ #2 ~ SCN } } +\cs_new_eq:NN \@@_backend_fill_devicen:nn \@@_backend_fill_separation:nn +\cs_new_eq:NN \@@_backend_stroke_devicen:nn \@@_backend_stroke_separation:nn % \end{macrocode} % \end{macro} % @@ -777,13 +869,17 @@ % \begin{macro} % { % \@@_backend_fill_separation:nn, -% \@@_backend_stroke_separation:nn +% \@@_backend_stroke_separation:nn, +% \@@_backend_fill_devicen:nn, +% \@@_backend_stroke_devicen:nn % } % \begin{macrocode} \cs_new_protected:Npn \@@_backend_fill_separation:nn #1#2 { \__kernel_backend_postscript:n { /color.fc { #1 } def } } \cs_new_protected:Npn \@@_backend_stroke_separation:nn #1#2 { \__kernel_backend_postscript:n { /color.sc { #1 } def } } +\cs_new_eq:NN \@@_backend_fill_devicen:nn \@@_backend_fill_separation:nn +\cs_new_eq:NN \@@_backend_stroke_devicen:nn \@@_backend_stroke_separation:nn % \end{macrocode} % \end{macro} % @@ -892,14 +988,16 @@ % \begin{macro} % { % \@@_backend_fill_separation:nn, -% \@@_backend_stroke_separation:nn +% \@@_backend_stroke_separation:nn, +% \@@_backend_fill_devicen:nn, +% \@@_backend_stroke_devicen:nn % } % At present, these are no-ops. % \begin{macrocode} -\cs_new_protected:Npn \@@_backend_fill_separation:nn #1#2 - { } -\cs_new_protected:Npn \@@_backend_stroke_separation:nn #1#2 - { } +\cs_new_protected:Npn \@@_backend_fill_separation:nn #1#2 { } +\cs_new_protected:Npn \@@_backend_stroke_separation:nn #1#2 { } +\cs_new_eq:NN \@@_backend_fill_devicen:nn \@@_backend_fill_separation:nn +\cs_new_eq:NN \@@_backend_stroke_devicen:nn \@@_backend_stroke_separation:nn % \end{macrocode} % \end{macro} % diff --git a/Master/texmf-dist/source/latex/l3backend/l3backend-draw.dtx b/Master/texmf-dist/source/latex/l3backend/l3backend-draw.dtx index f28bfd13bf0..8de6910edf0 100644 --- a/Master/texmf-dist/source/latex/l3backend/l3backend-draw.dtx +++ b/Master/texmf-dist/source/latex/l3backend/l3backend-draw.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-11} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3backend/l3backend-graphics.dtx b/Master/texmf-dist/source/latex/l3backend/l3backend-graphics.dtx index bac80fa884d..e72bbe9a588 100644 --- a/Master/texmf-dist/source/latex/l3backend/l3backend-graphics.dtx +++ b/Master/texmf-dist/source/latex/l3backend/l3backend-graphics.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-11} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3backend/l3backend-header.dtx b/Master/texmf-dist/source/latex/l3backend/l3backend-header.dtx index 73cf1bc5ad3..e1584916888 100644 --- a/Master/texmf-dist/source/latex/l3backend/l3backend-header.dtx +++ b/Master/texmf-dist/source/latex/l3backend/l3backend-header.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-11} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3backend/l3backend-pdf.dtx b/Master/texmf-dist/source/latex/l3backend/l3backend-pdf.dtx index 0763c411ebe..58c7da7f086 100644 --- a/Master/texmf-dist/source/latex/l3backend/l3backend-pdf.dtx +++ b/Master/texmf-dist/source/latex/l3backend/l3backend-pdf.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-11} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.dtx b/Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.dtx index 370723ec90d..eb67ec98760 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3benchmark/l3benchmark.dtx @@ -46,7 +46,7 @@ % }^^A % } % -% \date{Released 2020-09-11} +% \date{Released 2020-09-24} % % \maketitle % @@ -129,7 +129,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{l3benchmark}{2020-09-11}{} +\ProvidesExplPackage{l3benchmark}{2020-09-24}{} {L3 Experimental benchmarking} % \end{macrocode} % @@ -139,7 +139,7 @@ %<@@=sys> % \end{macrocode} % -% \begin{macro}[EXP]{\sys_timer:} +% \begin{macro}[EXP]{\sys_timer:, \@@_elapsedtime:, \@@_resettimer:} % \begin{macro}[EXP,pTF]{\sys_if_timer_exist:} % In \LuaTeX{}, use emulation (see \pkg{l3luatex}), % otherwise try to locate the primitive. The @@ -147,8 +147,27 @@ % \begin{macrocode} \sys_if_engine_luatex:TF { + \cs_new:Npn \@@_elapsedtime: { } + \cs_new:Npn \@@_resettimer: { } + \lua_now:n + { + local~gettimeofday = os.gettimeofday~ + local~epoch = gettimeofday() - os.clock()~ + local~write = tex.write~ + local~tointeger = math.tointeger~ + local~id = luatexbase.new_luafunction'@@_elapsedtime:' + lua.get_functions_table()[id] = function() + write(tointeger((gettimeofday() - epoch)*65536 // 1)) + end~ + token.set_lua('@@_elapsedtime:', id, 'global') + id = luatexbase.new_luafunction'@@_resettimer:' + lua.get_functions_table()[id] = function() + epoch = gettimeofday() + end~ + token.set_lua('@@_resettimer:', id, 'global', 'protected') + } \cs_new:Npn \sys_timer: - { \lua_now:n { l3kernel.elapsedtime() } } + { \@@_elapsedtime: } } { \cs_if_exist:NT \tex_elapsedtime:D @@ -163,8 +182,7 @@ % \end{macro} % \end{macro} % -% \begin{macro}{\sys_gzero_timer:, \@@_timer_fp:} -% \begin{variable}{\g_@@_timer_base_fp} +% \begin{macro}{\sys_gzero_timer:} % Three case, and in each case we define \cs{sys_gzero_timer:}. % \begin{macrocode} \cs_if_exist:NTF \sys_timer: @@ -172,7 +190,7 @@ \sys_if_engine_luatex:TF { \cs_new_protected:Npn \sys_gzero_timer: - { \lua_now:n { l3kernel.resettimer() } } + { \@@_resettimer: } } { \cs_new_protected:Npn \sys_gzero_timer: { \tex_resettimer:D } } } @@ -198,7 +216,6 @@ } } % \end{macrocode} -% \end{variable} % \end{macro} % % \subsection{Benchmarking code} diff --git a/Master/texmf-dist/source/latex/l3experimental/l3color/l3color.dtx b/Master/texmf-dist/source/latex/l3experimental/l3color/l3color.dtx index f644bf5fdee..88129ca31ee 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3color/l3color.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3color/l3color.dtx @@ -46,7 +46,7 @@ % }^^A % } % -% \date{Released 2020-09-11} +% \date{Released 2020-09-24} % % \maketitle % @@ -362,6 +362,7 @@ % Creates a new \meta{model} which is derived from the color model \meta{family}. % The latter should be one of % \begin{itemize} +% \item \texttt{DeviceN} % \item \texttt{Separation} % \end{itemize} % (The \meta{family} may be given in mixed case as-in the PDF reference: @@ -398,6 +399,13 @@ % not the case, \pkg{l3color} will fallback to using black as the colorant in % any mixing. % +% For a \texttt{DeviceN} space, there is one \emph{compulsory} key. +% \begin{itemize} +% \item \texttt{names} The names of the components of the \texttt{DeviceN} +% space. Each should be either the \meta{name} of a \texttt{Separation} model, +% a process color name (\texttt{cyan}, etc.) or the special name \texttt{none}. +% \end{itemize} +% % \end{documentation} % % \begin{implementation} @@ -413,7 +421,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{l3color}{2020-09-11}{} +\ProvidesExplPackage{l3color}{2020-09-24}{} {L3 Experimental color support} % \end{macrocode} % @@ -439,8 +447,9 @@ % % \subsection{Setup} % -% \begin{variable}{\l_@@_internal_tl} +% \begin{variable}{\l_@@_internal_int, \l_@@_internal_tl} % \begin{macrocode} +\int_new:N \l_@@_internal_int \tl_new:N \l_@@_internal_tl % \end{macrocode} % \end{variable} @@ -1517,10 +1526,36 @@ % \end{macrocode} % \end{variable} % -% \begin{variable}{\g_@@_separation_int} -% A tracker for the total number of separations. +% \begin{variable}{\g_@@_model_int} +% A tracker for the total number of new models. +% \begin{macrocode} +\int_new:N \g_@@_model_int +% \end{macrocode} +% \end{variable} +% +% \begin{variable} +% {\c_@@_fallback_cmyk_tl, \c_@@_fallback_gray_tl, \c_@@_fallback_rgb_tl} +% Conversion from Separation or DeviceN spaces may not be possible; have +% a fallback to black. +% \begin{macrocode} +\tl_const:Nn \c_@@_fallback_cmyk_tl { 0 ~ 0 ~ 0 ~ 1 } +\tl_const:Nn \c_@@_fallback_gray_tl { 1 } +\tl_const:Nn \c_@@_fallback_rgb_tl { 1 ~ 1 ~ 1 } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\g_@@_colorants_prop} +% Mapping from names to colorants. % \begin{macrocode} -\int_new:N \g_@@_separation_int +\prop_new:N \g_@@_colorants_prop +\prop_gput:Nnn \g_@@_colorants_prop { black } { Black } +\prop_gput:Nnn \g_@@_colorants_prop { blue } { Blue } +\prop_gput:Nnn \g_@@_colorants_prop { cyan } { Cyan } +\prop_gput:Nnn \g_@@_colorants_prop { green } { Green } +\prop_gput:Nnn \g_@@_colorants_prop { magenta } { Magenta } +\prop_gput:Nnn \g_@@_colorants_prop { none } { None } +\prop_gput:Nnn \g_@@_colorants_prop { red } { Red } +\prop_gput:Nnn \g_@@_colorants_prop { yellow } { Yellow } % \end{macrocode} % \end{variable} % @@ -1553,6 +1588,31 @@ % \end{macrocode} % \end{variable} % +% \begin{variable}{\g_@@_alternative_model_prop} +% For tracking the alternative model set up for separations, etc. +% \begin{macrocode} +\prop_new:N \g_@@_alternative_model_prop +\clist_map_inline:nn { cyan , magenta , yellow , black } + { \prop_gput:Nnn \g_@@_alternative_model_prop {#1} { cmyk } } +\clist_map_inline:nn { red , green , blue } + { \prop_gput:Nnn \g_@@_alternative_model_prop {#1} { rgb } } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\g_@@_alternative_values_prop} +% Same for the values: a bit more involved. +% \begin{macrocode} +\prop_new:N \g_@@_alternative_values_prop +\prop_gput:Nnn \g_@@_alternative_values_prop { cyan } { 1 , 0 , 0 , 0 } +\prop_gput:Nnn \g_@@_alternative_values_prop { magenta } { 0 , 1 , 0 , 0 } +\prop_gput:Nnn \g_@@_alternative_values_prop { yellow } { 0 , 0 , 1 , 0 } +\prop_gput:Nnn \g_@@_alternative_values_prop { black } { 0 , 0 , 0 , 1 } +\prop_gput:Nnn \g_@@_alternative_values_prop { red } { 1 , 0 , 0 } +\prop_gput:Nnn \g_@@_alternative_values_prop { green } { 0 , 1 , 0 } +\prop_gput:Nnn \g_@@_alternative_values_prop { blue } { 0 , 0 , 1 } +% \end{macrocode} +% \end{variable} +% % \begin{macro}{\color_model_new:nnn, \@@_model_new:nnn} % Set up a new model: in general this has to be handled by a family-dependent % function. To avoid some \enquote{interesting} questions with casing, we @@ -1665,7 +1725,7 @@ \cs_new_protected:Npn \@@_model_separation:w #1 , #2 , #3 , #4 , #5 \s_@@_stop #6#7#8 { - \int_gincr:N \g_@@_separation_int + \int_gincr:N \g_@@_model_int \tl_const:cn { c_@@_fallback_ #6 _tl } { 1 } \cs_new_eq:cN { @@_parse_mix_ #6 :nw } \@@_parse_mix_gray:nw \cs_new:cpn { @@_parse_model_ #6 :w } ##1 , ##2 \s_@@_stop @@ -1675,11 +1735,14 @@ \cs_new_protected:cpx { @@_backend_ ##1 _ #6 :n } ####1 { \exp_not:c { @@_backend_ ##1 _ separation:nn } - { color \int_use:N \g_@@_separation_int } {####1} + { 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 } @@ -1699,6 +1762,7 @@ } \@@_model_convert:nnn {#1} { cmyk } { rgb } \@@_model_convert:nnn {#1} { cmyk } { gray } + \prop_gput:Nnn \g_@@_alternative_values_prop {#1} { #3 , #4 , #5 , #6 } \@@_backend_separation_init:nnnnn {#2} { /DeviceCMYK } { } { 0 ~ 0 ~ 0 ~ 0 } { #3 ~ #4 ~ #5 ~ #6 } } @@ -1712,6 +1776,7 @@ } \@@_model_convert:nnn {#1} { rgb } { cmyk } \@@_model_convert:nnn {#1} { rgb } { gray } + \prop_gput:Nnn \g_@@_alternative_values_prop {#1} { #3 , #4 , #5 } \@@_backend_separation_init:nnnnn {#2} { /DeviceRGB } { } { 0 ~ 0 ~ 0 } { #3 ~ #4 ~ #5 } } @@ -1732,6 +1797,7 @@ \fp_eval:n {##1 * #3} ~ \fp_eval:n {##1 * #3} } + \prop_gput:Nnn \g_@@_alternative_values_prop {#1} {#3} \@@_backend_separation_init:nnnnn {#2} { /DeviceGray } { } { 0 } {#3} } % \end{macrocode} @@ -1797,6 +1863,529 @@ % \end{macro} % \end{macro} % +% \begin{macro}{\@@_model_devicen:n} +% \begin{macro}{\@@_model_devicen:nn} +% \begin{macro}{\@@_model_devicen:nnn} +% \begin{macro}{\@@_model_devicen:nnnn} +% \begin{macro} +% { +% \@@_model_devicen_parse_1:nn , +% \@@_model_devicen_parse_2:nn , +% \@@_model_devicen_parse_3:nn , +% \@@_model_devicen_parse_4:nn , +% \@@_model_devicen_parse_generic:nn +% } +% \begin{macro}[EXP]{\@@_model_devicen_parse:nw} +% \begin{macro}[EXP]{\@@_model_devicen_mix:nw} +% \begin{macro}{\@@_model_devicen_init:nnn} +% \begin{macro}{\@@_model_devicen_init:nnnn} +% \begin{macro}{\@@_model_devicen_tranform:w} +% \begin{macro} +% { +% \@@_model_devicen_tranform_1:nnnnn , +% \@@_model_devicen_tranform_3:nnnnn , +% \@@_model_devicen_tranform_4:nnnnn , +% } +% \begin{macro}{\@@_model_devicen_tranform:nnn} +% \begin{macro}[EXP]{\@@_model_devicen_colorant:n} +% \begin{macro}{\@@_model_devicen_convert:nnn} +% \begin{macro} +% { +% \@@_model_devicen_convert_cmyk:n , +% \@@_model_devicen_convert_gray:n , +% \@@_model_devicen_convert_rgb:n +% } +% \begin{macro}{\@@_model_devicen_convert:nnnn} +% \begin{macro}[EXP]{\@@_model_devicen_convert:n, \@@_model_devicen_convert_aux:n} +% \begin{macro}[EXP]{\@@_model_devicen_convert:w} +% \begin{macro}[EXP]{\@@_convert_devicen_cmyk:nnnnw} +% \begin{macro}[EXP]{\@@_convert_devicen_cmyk:nnnnnnnnn} +% \begin{macro}[EXP]{\@@_convert_devicen_cmyk_aux:nnnnw} +% \begin{macro}[EXP]{\@@_convert_devicen_gray:nw} +% \begin{macro}[EXP]{\@@_convert_devicen_gray:nnn} +% \begin{macro}[EXP]{\@@_convert_devicen_gray_aux:nw} +% \begin{macro}[EXP]{\@@_convert_devicen_rgb:nnnw} +% \begin{macro}[EXP]{\@@_convert_devicen_rgb:nnnnnnn} +% \begin{macro}[EXP]{\@@_convert_devicen_rgb_aux:nnnw} +% We require a list of component names here: one might call them colorants, +% but it's convenient to use \TeX{} names instead so we slightly adjust the +% terminology. +% \begin{macrocode} +\cs_new_protected:Npn \@@_model_devicen:n #1 + { + \prop_get:NnNTF \l_@@_internal_prop { names } + \l_@@_internal_tl + { + \exp_args:NV \@@_model_devicen:nn + \l_@@_internal_tl {#1} + } + { + \__kernel_msg_error:nnn { color } + { DeviceN-requires-names } {#1} + } + } +% \end{macrocode} +% All valid models will have an alternative listed, either hard-coded for +% the core device ones, or dynamically added for Separations, etc. +% \begin{macrocode} +\cs_new_protected:Npn \@@_model_devicen:nn #1#2 + { + \tl_clear:N \l_@@_model_tl + \clist_map_inline:nn {#1} + { + \prop_get:NnNTF \g_@@_alternative_model_prop {##1} + \l_@@_internal_tl + { + \tl_if_empty:NTF \l_@@_model_tl + { \tl_set_eq:NN \l_@@_model_tl \l_@@_internal_tl } + { + \str_if_eq:VVF \l_@@_model_tl \l_@@_internal_tl + { + \__kernel_msg_error:nnn { color } + { DeviceN-inconsistent-alternative } + {#2} + \clist_map_break:n { \use_none:nnnn } + } + } + } + { + \str_if_eq:nnF {##1} { none } + { + \__kernel_msg_error:nnn { color } + { DeviceN-no-alternative } + {#2} + } + } + } + \tl_if_empty:NTF \l_@@_model_tl + { + \__kernel_msg_error:nnn { color } + { DeviceN-no-alternative } {#2} + } + { \exp_args:NV \@@_model_devicen:nnn \l_@@_model_tl {#1} {#2} } + } +% \end{macrocode} +% We now complete the data we require by first finding out how many +% colorants there are, then moving on to begin constructing the function +% required to map to the alternative color space. +% \begin{macrocode} +\cs_new_protected:Npn \@@_model_devicen:nnn #1#2#3 + { + \exp_args:Nx \@@_model_devicen:nnnn + { \clist_count:n {#2} } {#1} {#2} {#3} + } +% \end{macrocode} +% At this stage, we have checked everything is in place, so we can set up +% the \TeX{} and backend data structures. As for separations, it's not really +% possible in general to have a fallback, so we simply provide +% \enquote{black} for each element. +% \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 ~ } } + \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 +% 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 +% approach based on open-ended commas-lists. +% \begin{macrocode} +\cs_new_protected:cpn { @@_model_devicen_parse_1:nn } #1#2 + { + \cs_new:cpn { @@_parse_model_ #1 :w } ##1 , ##2 \s_@@_stop + { {#1} { \@@_parse_number:n {##1} } } + \cs_new_eq:cN { @@_parse_mix_ #1 :nw } \@@_parse_mix_gray:nw + } +\cs_new_protected:cpn { @@_model_devicen_parse_2:nn } #1#2 + { + \cs_new:cpn { @@_parse_model_ #1 :w } ##1 , ##2 , ##3 \s_@@_stop + { {#1} { \@@_parse_number:n {##1} ~ \@@_parse_number:n {##2} } } + \cs_new:cpn { @@_parse_mix_ #1 :nw } + ##1##2 ~ ##3 \s_@@_mark ##4 ~ ##5 \s_@@_stop + { + \fp_eval:n { ##2 * ##1 + ##4 * ( 1 - ##1 ) } \c_space_tl + \fp_eval:n { ##3 * ##1 + ##5 * ( 1 - ##1 ) } + } + } +\cs_new_protected:cpn { @@_model_devicen_parse_3:nn } #1#2 + { + \cs_new:cpn { @@_parse_model_ #1 :w } ##1 , ##2 , ##3 , ##4 \s_@@_stop + { + {#1} + { + \@@_parse_number:n {##1} ~ + \@@_parse_number:n {##2} ~ + \@@_parse_number:n {##3} + } + } + \cs_new_eq:cN { @@_parse_mix_ #1 :nw } \@@_parse_mix_rgb:nw + } +\cs_new_protected:cpn { @@_model_devicen_parse_4:nn } #1#2 + { + \cs_new:cpn { @@_parse_model_ #1 :w } + ##1 , ##2 , ##3 , ##4 , ##5 \s_@@_stop + { + {#1} + { + \@@_parse_number:n {##1} ~ + \@@_parse_number:n {##2} ~ + \@@_parse_number:n {##3} ~ + \@@_parse_number:n {##4} + } + } + \cs_new_eq:cN { @@_parse_mix_ #1 :nw } \@@_parse_mix_cmyk:nw + } +\cs_new_protected:Npn \@@_model_devicen_parse_generic:nn #1#2 + { + \cs_new:cpn { @@_parse_model_ #1 :w } ##1 , ##2 \s_@@_stop + { + {#1} + { \@@_model_devicen_parse:nw {#2} ##1 , ##2 , \q_nil , \s_@@_stop } + } + \cs_new:cpx { @@_parse_mix_ #1 :nw } + ##1 ##2 \s_@@_mark ##3 \s_@@_stop + { + \exp_not:N \@@_model_devicen_mix:nw {##1} + ##2 \c_space_tl \exp_not:N \q_nil \c_space_tl \exp_not:N \s_@@_mark + ##3 \c_space_tl \exp_not:N \q_nil \c_space_tl \exp_not:N \s_@@_stop + } + } +\cs_new:Npn \@@_model_devicen_parse:nw #1#2 , #3 \s_@@_stop + { + \int_compare:nNnT {#1} > 0 + { + \quark_if_nil:nTF {#2} + { \prg_replicate:nn {#1} { 0 ~ } } + { + \@@_parse_number:n {#2} + \int_compare:nNnT {#1} > 1 { ~ } + \exp_args:Nf \@@_model_devicen_parse:nw + { \int_eval:n { #1 - 1 } } #3 \s_@@_stop + } + } + } +\cs_new:Npn \@@_model_devicen_mix:nw #1#2 ~ #3 \s_@@_mark #4 ~ #5 \s_@@_stop + { + \fp_eval:n { #2 * #1 + #4 * ( 1 - #1 ) } + \quark_if_nil:oF { \tl_head:w #3 \q_stop } + { + \c_space_tl + \@@_model_devicen_mix:nw {#1} #3 \s_@@_mark #5 \s_@@_stop + } + } +% \end{macrocode} +% To construct the tint transformation, we have to use PostScript. The +% aim is to have the final tint for each device colorant as +% \[ +% 1 - \prod_{n} (1 - X_{n} D_{X_{n}}) +% \] +% where $X$ is a DeviceN colorant and $D$ is the amount of device colorant +% that the DeviceN colorant maps to. At the start of the process, the +% PostScript stack will contain the $X_{n}$ values, whilst we have the +% $D$ values on a per-DeviceN colorant basis. The more convenient approach +% for us is therefore to take each DeviceN colorant in turn and find the +% value $1 - X_{n} D_{X_{n}}$, multiplying as we go, and finalise with the +% subtraction. That contrasts to \pkg{colorspace}: it splits the process +% up by process color, which works better when you have a fixed list +% of colorants. (\pkg{colorspace} only supports up to $4$ DeviceN colors, +% and only \texttt{cmyk} as the alternative space.) To set this up, +% we first need to know the number of values in the target color space: +% this is easily handled as there are a very small range of possibles. +% Once we have that information, it's relatively easy to build the required +% PostScript using some generic code. +% \begin{macrocode} +\cs_new_protected:Npn \@@_model_devicen_init:nnn #1#2#3 + { + \exp_args:Ne \@@_model_devicen_init:nnnn + { + \str_case:nn {#2} + { + { cmyk } { 4 } + { gray } { 1 } + { rgb } { 3 } + } + } + {#1} {#2} {#3} + } +% \end{macrocode} +% As we always need to split the alternative values into parts, we use a +% shared auxiliary and only use a minimal difference between code paths. +% Construction of the tint transformation is as far as possible done using +% loops, which means there are some inefficiencies for device colors in +% the \texttt{DeviceN} space: we roll the stack one-at-a-time even if there +% is a potential shortcut. However, that way there is nothing to special-case. +% Once this is sorted, we can write the tint transform object, which will +% remain as the last object until we sort out the final step: the colorant +% list. +% \begin{macrocode} +\cs_new_protected:Npn \@@_model_devicen_init:nnnn #1#2#3#4 + { + \tl_set:Nx \l_@@_internal_tl + { \prg_replicate:nn {#1} { 1.0 ~ } } + \int_zero:N \l_@@_internal_int + \clist_map_inline:nn {#4} + { + \int_incr:N \l_@@_internal_int + \prop_get:NnN \g_@@_alternative_values_prop {##1} + \l_@@_value_tl + \exp_after:wN \@@_model_devicen_transform:w + \l_@@_value_tl , 0 , 0 , 0 \s_@@_stop {#1} {#2} + } + \tl_put_right:Nx \l_@@_internal_tl + { + \prg_replicate:nn {#1} + { neg ~ 1.0 ~ add ~ #1 ~ -1 ~ roll ~ } + \int_eval:n { #2 + 4 } ~ 4 ~ roll + \prg_replicate:nn {#2} { ~ pop } + } + \use:x + { + \@@_backend_devicen_init:nnn + { + \clist_map_function:nN {#4} + \@@_model_devicen_colorant:n + } + { + \str_case:nn {#3} + { + { cmyk } { /DeviceCMYK } + { gray } { /DeviceGray } + { rgb } { /DeviceRGB } + } + } + { \exp_not:V \l_@@_internal_tl } + } + } +\cs_new_protected:Npn \@@_model_devicen_transform:w + #1 , #2 , #3 , #4 , #5 \s_@@_stop #6#7 + { + \use:c { @@_model_devicen_transform_ #6 :nnnnn } + {#1} {#2} {#3} {#4} {#7} + } +\cs_new_protected:cpn { @@_model_devicen_transform_1:nnnnn } #1#2#3#4#5 + { \@@_model_devicen_transform:nnn {#5} { 1 } {#1} } +\cs_new_protected:cpn { @@_model_devicen_transform_3:nnnnn } #1#2#3#4#5 + { + \clist_map_inline { #1 , #2 , #3 } + { \@@_model_devicen_transform:nnn {#5} { 3 } {##1} } + } +\cs_new_protected:cpn { @@_model_devicen_transform_4:nnnnn } #1#2#3#4#5 + { + \clist_map_inline:nn { #1 , #2 , #3 , #4 } + { \@@_model_devicen_transform:nnn {#5} { 4 } {##1} } + } +\cs_new_protected:Npn \@@_model_devicen_transform:nnn #1#2#3 + { + \tl_put_right:Nx \l_@@_internal_tl + { + \fp_compare:nNnF {#3} = \c_zero_fp + { + \int_eval:n { #1 - \l_@@_internal_int + #2 } ~ index ~ + #3 ~ neg ~ mul ~ 1.0 ~ add ~ mul ~ + } + #2 ~ -1 ~ roll ~ + } + } +\cs_new:Npn \@@_model_devicen_colorant:n #1 + { + / \prop_item:Nn \g_@@_colorants_prop {#1} ~ + } +% \end{macrocode} +% Here we need to set up conversion from the DeviceN space to the alternative +% at the \TeX{} level. This also means supplying methods for inter-converting +% to other parameter-based spaces. Essentially the approach is exactly the same +% as the PostScript, just expressed in \TeX{} terms. +% \begin{macrocode} +\cs_new_protected:Npn \@@_model_devicen_convert:nnn #1#2#3 + { + \use:c { @@_model_devicen_convert_ #2 :nn } {#1} {#3} + } +\cs_new_protected:Npn \@@_model_devicen_convert_cmyk:nn #1#2 + { + \@@_model_convert:nnn {#1} { cmyk } { gray } + \@@_model_convert:nnn {#1} { cmyk } { rgb } + \@@_model_devicen_convert:nnnn {#1} { cmyk } { 4 } {#2} + } +\cs_new_protected:Npn \@@_model_devicen_convert_gray:nn #1#2 + { + \@@_model_convert:nnn {#1} { gray } { cmyk } + \@@_model_convert:nnn {#1} { gray } { rgb } + \@@_model_devicen_convert:nnnn {#1} { gray } { 1 } {#2} + } +\cs_new_protected:Npn \@@_model_devicen_convert_rgb:nn #1#2 + { + \@@_model_convert:nnn {#1} { rgb } { cmyk } + \@@_model_convert:nnn {#1} { rgb } { gray } + \@@_model_devicen_convert:nnnn {#1} { rgb } { 3 } {#2} + } +\cs_new_protected:Npn \@@_model_devicen_convert:nnnn #1#2#3#4 + { + \cs_new:cpx { @@_convert_ #1 _ #2 :w } ##1 \s_@@_stop + { + \exp_not:c { @@_convert_devicen_ #2 : \prg_replicate:nn {#3} { n } w } + \prg_replicate:nn {#3} { { 1 } } + ##1 \exp_not:N \s_@@_mark + \clist_map_function:nN {#4} \@@_model_devicen_convert:n + \exp_not:N \s_@@_stop + } + } +\cs_new:Npn \@@_model_devicen_convert:n #1 + { + { + \exp_args:Ne \@@_model_devicen_convert_aux:n + { \prop_item:Nn \g_@@_alternative_values_prop {#1} } + } + } +\cs_new:Npn \@@_model_devicen_convert_aux:n #1 + { \@@_model_devicen_convert_aux:w #1 , , , , \s_@@_stop } +\cs_new:Npn \@@_model_devicen_convert_aux:w #1 , #2 , #3 , #4 , #5 \s_@@_stop + { + {#1} + \tl_if_blank:nF {#2} + { + {#2} + \tl_if_blank:nF {#3} + { + {#3} + \tl_if_blank:nF {#4} { {#4} } + } + } + } +\cs_new:Npn \@@_convert_devicen_cmyk:nnnnw + #1#2#3#4#5 ~ #6 \s_@@_mark #7#8 \s_@@_stop + { + \@@_convert_devicen_cmyk:nnnnnnnnn {#5} {#1} {#2} {#3} {#4} #7 + #6 \s_@@_mark #8 \s_@@_stop + } +\cs_new:Npn \@@_convert_devicen_cmyk:nnnnnnnnn #1#2#3#4#5#6#7#8#9 + { + \use:e + { + \exp_not:N \@@_convert_devicen_cmyk_aux:nnnnw + { \fp_eval:n { #2 * (1 - (#1 * #6)) } } + { \fp_eval:n { #3 * (1 - (#1 * #7)) } } + { \fp_eval:n { #4 * (1 - (#1 * #8)) } } + { \fp_eval:n { #5 * (1 - (#1 * #9)) } } + } + } +\cs_new:Npn \@@_convert_devicen_cmyk_aux:nnnnw + #1#2#3#4 #5 \s_@@_mark #6 \s_@@_stop + { + \tl_if_blank:nTF {#5} + { + \fp_eval:n { 1 - #1 } ~ + \fp_eval:n { 1 - #2 } ~ + \fp_eval:n { 1 - #3 } ~ + \fp_eval:n { 1 - #4 } + } + { + \@@_convert_devicen_cmyk:nnnnw {#1} {#2} {#3} {#4} + #5 \s_@@_mark #6 \s_@@_stop + } + } +\cs_new:Npn \@@_convert_devicen_gray:nw + #1#2 ~ #3 \s_@@_mark #4#5 \s_@@_stop + { + \@@_convert_devicen_gray:nnn {#2} {#1} #4 + #3 \s_@@_mark #5 \s_@@_stop + } +\cs_new:Npn \@@_convert_devicen_gray:nnn #1#2#3 + { + \exp_arsgs:Ne \@@_convert_devicen_gray_aux:nw + { \fp_eval:n { #2 * (1 - (#1 * #3)) } } + } +\cs_new:Npn \@@_convert_devicen_gray_aux:nw + #1 #2 \s_@@_mark #3 \s_@@_stop + { + \tl_if_blank:nTF {#2} + { \fp_eval:n { 1 - #1 } } + { + \@@_convert_devicen_gray:nw {#1} + #2 \s_@@_mark #3 \s_@@_stop + } + } +\cs_new:Npn \@@_convert_devicen_rgb:nnnw + #1#2#3#4 ~ #5 \s_@@_mark #6#7 \s_@@_stop + { + \@@_convert_devicen_cmyk:nnnnnn {#4} {#1} {#2} {#3} #6 + #5 \s_@@_mark #7 \s_@@_stop + } +\cs_new:Npn \@@_convert_devicen_rgb:nnnnnnn #1#2#3#4#5#6#7 + { + \use:e + { + \exp_not:N \@@_convert_devicen_rgb_aux:nnnw + { \fp_eval:n { #2 * (1 - (#1 * #5)) } } + { \fp_eval:n { #3 * (1 - (#1 * #6)) } } + { \fp_eval:n { #4 * (1 - (#1 * #7)) } } + } + } +\cs_new:Npn \@@_convert_devicen_rgb_aux:nnnw + #1#2#3 #4 \s_@@_mark #5 \s_@@_stop + { + \tl_if_blank:nTF {#4} + { + \fp_eval:n { 1 - #1 } ~ + \fp_eval:n { 1 - #2 } ~ + \fp_eval:n { 1 - #3 } + } + { + \@@_convert_devicen_rgb:nnnw {#1} {#2} {#3} + #4 \s_@@_mark #5 \s_@@_stop + } + } +% \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} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% % \subsection{Diagnostics} % % \begin{macro}{\color_show:n} @@ -1830,7 +2419,7 @@ % % \subsection{Messages} % -% \begin{macrocode} +% \begin{macrocode} \__kernel_msg_new:nnnn { color } { CIELAB-requires-illuminant } { CIELAB~color~space~'#1'~require~an~illuminant. } { @@ -1847,6 +2436,28 @@ LaTeX~has~been~asked~to~convert~a~color~from~model~'#1'~ to~model'#2',~but~there~is~no~method~available~to~do~that. } +\__kernel_msg_new:nnnn { color } { DeviceN-inconsistent-alternative } + { DeviceN~color~spaces~require~a~single~alternative~space. } + { + LaTeX~has~been~asked~to~create~a~DeviceN~color~space~'#1',~ + but~the~constituent~colors~do~not~have~a~common~alternative~ + color. + } +\__kernel_msg_new:nnnn { color } { DeviceN-no-alternative } + { DeviceN~color~spaces~require~an~alternative~space. } + { + LaTeX~has~been~asked~to~create~a~DeviceN~color~space~'#1',~ + but~the~constituent~colors~do~not~all~have~a~device-based~alternative. + } +\__kernel_msg_new:nnnn { color } { DeviceN-requires-names } + { DeviceN~color~space~'#1'~require~a~list~of~names. } + { + LaTeX~has~been~asked~to~create~a~DeviceN~color~space,~ + but~no~\\ \\ + \iow_indent:n { names~=~<names> } + \\ \\ + key~was~given~with~the~correct~information. + } \__kernel_msg_new:nnnn { color } { model-already-defined } { Color~model~'#1'~already~defined. } { @@ -1919,9 +2530,9 @@ LaTeX~has~been~asked~to~create~a~new~color~model~called~'#1',~ but~this~type~of~model~was~never~set~up. } -% \end{macrocode} +% \end{macrocode} % -% \begin{macrocode} +% \begin{macrocode} \__kernel_msg_new:nnn { color } { show } { The~color~#1~ @@ -1929,7 +2540,7 @@ { is~undefined. } { has~the~properties: #2 } } -% \end{macrocode} +% \end{macrocode} % % \begin{macrocode} %</package> diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-boxes.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-boxes.dtx index afc4616dfbc..029f7918136 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-boxes.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-boxes.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2020-09-11} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-layers.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-layers.dtx index ffe0cd95884..19898aee89e 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-layers.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-layers.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2020-09-11} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-paths.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-paths.dtx index 9f87bf357c0..5ca8e42688e 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-paths.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-paths.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2020-09-11} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-points.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-points.dtx index aafe12bcc2f..7537ffb85ad 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-points.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-points.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2020-09-11} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-scopes.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-scopes.dtx index 99edbf19921..c35149facbe 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-scopes.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-scopes.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2020-09-11} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx index e6b35bf7908..b0e003b844b 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2020-09-11} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-state.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-state.dtx index 53cc03b98e7..1af7a525b9b 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-state.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-state.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2020-09-11} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-transforms.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-transforms.dtx index e30bcf6d193..6bb90111e19 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-transforms.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-transforms.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2020-09-11} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.dtx index 6d1e5e96aae..69f322a0fad 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.dtx @@ -110,7 +110,7 @@ % }^^A % } % -% \date{Released 2020-09-11} +% \date{Released 2020-09-24} % % \maketitle % @@ -1136,7 +1136,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{l3draw}{2020-09-11}{} +\ProvidesExplPackage{l3draw}{2020-09-24}{} {L3 Experimental core drawing support} % \end{macrocode} % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3graphics/l3graphics.dtx b/Master/texmf-dist/source/latex/l3experimental/l3graphics/l3graphics.dtx index 6d74ceebb96..9a449734172 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3graphics/l3graphics.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3graphics/l3graphics.dtx @@ -46,7 +46,7 @@ % }^^A % } % -% \date{Released 2020-09-11} +% \date{Released 2020-09-24} % % \maketitle % @@ -240,7 +240,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{l3graphics}{2020-09-11}{} +\ProvidesExplPackage{l3graphics}{2020-09-24}{} {L3 Experimental graphics inclusion support} % \end{macrocode} % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3pdf/l3pdf.dtx b/Master/texmf-dist/source/latex/l3experimental/l3pdf/l3pdf.dtx index e5af45a9b80..4eec458dcee 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3pdf/l3pdf.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3pdf/l3pdf.dtx @@ -46,7 +46,7 @@ % }^^A % } % -% \date{Released 2020-09-11} +% \date{Released 2020-09-24} % % \maketitle % @@ -190,7 +190,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{l3pdf}{2020-09-11}{} +\ProvidesExplPackage{l3pdf}{2020-09-24}{} {L3 Experimental core PDF support} % \end{macrocode} % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-format.dtx b/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-format.dtx index 775e5d809f5..da524edf580 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-format.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-format.dtx @@ -48,7 +48,7 @@ % }^^A % } % -% \date{Released 2020-09-11} +% \date{Released 2020-09-24} % % \maketitle % @@ -166,7 +166,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{l3str-format}{2020-09-11}{} +\ProvidesExplPackage{l3str-format}{2020-09-24}{} {L3 Experimental string formatting} % \end{macrocode} % diff --git a/Master/texmf-dist/source/latex/l3experimental/l3sys-shell/l3sys-shell.dtx b/Master/texmf-dist/source/latex/l3experimental/l3sys-shell/l3sys-shell.dtx index 807e7383d3f..40b52017676 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3sys-shell/l3sys-shell.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3sys-shell/l3sys-shell.dtx @@ -46,7 +46,7 @@ % }^^A % } % -% \date{Released 2020-09-11} +% \date{Released 2020-09-24} % % \maketitle % @@ -135,7 +135,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{l3sys-shell}{2020-09-11}{} +\ProvidesExplPackage{l3sys-shell}{2020-09-24}{} {L3 Experimental system shell functions} % \end{macrocode} % diff --git a/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx b/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx index 4286442045a..9985fbb3936 100644 --- a/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx @@ -56,7 +56,7 @@ % }^^A % } % -% \date{Released 2020-09-11} +% \date{Released 2020-09-24} % % \maketitle % @@ -675,7 +675,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{xcoffins}{2020-09-11}{} +\ProvidesExplPackage{xcoffins}{2020-09-24}{} {L3 Experimental design level coffins} % \end{macrocode} % diff --git a/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx b/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx index 5de6c7c4aae..212d9e63209 100644 --- a/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx @@ -61,7 +61,7 @@ % }^^A % } % -% \date{Released 2020-09-11} +% \date{Released 2020-09-24} % % \maketitle % @@ -686,7 +686,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{l3galley}{2020-09-11}{} +\ProvidesExplPackage{l3galley}{2020-09-24}{} {L3 Experimental galley code} % \end{macrocode} % diff --git a/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx b/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx index 52667441b65..06c7f3c3716 100644 --- a/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx @@ -47,7 +47,7 @@ % }^^A % } % -% \date{Released 2020-09-11} +% \date{Released 2020-09-24} % % \maketitle % @@ -734,7 +734,7 @@ % \end{macrocode} % % \begin{macrocode} -\ProvidesExplPackage{xgalley}{2020-09-11}{} +\ProvidesExplPackage{xgalley}{2020-09-24}{} {L3 Experimental galley} \RequirePackage{xparse,xtemplate,l3galley} % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3kernel/expl3.dtx b/Master/texmf-dist/source/latex/l3kernel/expl3.dtx index 140e507b63c..003502090ef 100644 --- a/Master/texmf-dist/source/latex/l3kernel/expl3.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/expl3.dtx @@ -24,7 +24,7 @@ % %<*driver|generic|package|2ekernel> %</driver|generic|package|2ekernel> -\def\ExplFileDate{2020-09-06}% +\def\ExplFileDate{2020-09-24}% %<*driver> \documentclass[full]{l3doc} \usepackage{graphicx} @@ -51,7 +51,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3.ins b/Master/texmf-dist/source/latex/l3kernel/l3.ins index 5e7d1bfff91..ad3b5267ddb 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3.ins +++ b/Master/texmf-dist/source/latex/l3kernel/l3.ins @@ -60,7 +60,7 @@ and all files in that bundle must be distributed together. { \from{expl3.dtx} {package} \from{l3bootstrap.dtx} {package} - \from{l3names.dtx} {package} + \from{l3names.dtx} {package,tex} \from{l3basics.dtx} {package} \from{l3expan.dtx} {package} \from{l3quark.dtx} {package} @@ -70,9 +70,9 @@ and all files in that bundle must be distributed together. \from{l3int.dtx} {package} \from{l3flag.dtx} {package} \from{l3prg.dtx} {package} - \from{l3sys.dtx} {package} + \from{l3sys.dtx} {package,tex} \from{l3clist.dtx} {package} - \from{l3token.dtx} {package} + \from{l3token.dtx} {package,tex} \from{l3prop.dtx} {package} \from{l3msg.dtx} {package} \from{l3file.dtx} {package} @@ -165,6 +165,11 @@ and all files in that bundle must be distributed together. \endpreamble \nopostamble -\generate{\file{expl3.lua}{\from{l3luatex.dtx}{package,lua}}} +\generate{\file{expl3.lua}{ + \from{l3luatex.dtx}{package,lua} + \from{l3names.dtx}{package,lua} + \from{l3sys.dtx}{package,lua} + \from{l3token.dtx}{package,lua} +}} \endbatchfile diff --git a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx index b167eb6dcf4..0d2594ca747 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx b/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx index 810de9812c4..c3b597031a5 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % @@ -176,16 +176,23 @@ \begingroup\expandafter\expandafter\expandafter\endgroup \expandafter\ifx\csname directlua\endcsname\relax \else - \ifnum\luatexversion<95 % + \ifnum\luatexversion<110 % \else % \end{macrocode} % For \LuaTeX{} we make sure the basic support is loaded: % this is only necessary in plain. +% +% Additionally we just ensure that \TeX{} has seen the csnames \cs{prg_return_true:} +% and \cs{prg_return_false:} before the Lua code builds these tokens. % \begin{macrocode} \begingroup\expandafter\expandafter\expandafter\endgroup \expandafter\ifx\csname newcatcodetable\endcsname\relax \input{ltluatex}% \fi + \begingroup\edef\ignored{% + \expandafter\noexpand\csname prg_return_true:\endcsname + \expandafter\noexpand\csname prg_return_false:\endcsname + }\endgroup \directlua{require("expl3")}% % \end{macrocode} % As the user might be making a custom format, no assumption is made about @@ -212,6 +219,9 @@ % The code currently requires \eTeX{} and functionality equivalent to % \tn{pdfstrcmp}, and also driver and Unicode character support. This is % available in a reasonably-wide range of engines. +% +% For \LuaTeX, we require at least Lua 5.3 and the |token.set_lua| function. +% This is available at least since \LuaTeX{} 1.10. % \begin{macrocode} \begingroup \def\next{\endgroup}% @@ -224,7 +234,7 @@ These are available in the engines\LineBreak - pdfTeX v1.40\LineBreak - XeTeX v0.99992\LineBreak - - LuaTeX v0.95\LineBreak + - LuaTeX v1.10\LineBreak - e-(u)pTeX mid-2012\LineBreak or later.\LineBreak \LineBreak @@ -247,7 +257,7 @@ \fi \expandafter\ifx\csname directlua\endcsname\relax \else - \ifnum\luatexversion<76 \else 1\fi + \ifnum\luatexversion<110 \else 1\fi \fi =0 % \newlinechar`\^^J % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3box.dtx b/Master/texmf-dist/source/latex/l3kernel/l3box.dtx index d3a00d00f34..dbf1619275c 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3box.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3box.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx b/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx index 7c745269ec7..3014f8a118f 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3cctab.dtx b/Master/texmf-dist/source/latex/l3kernel/l3cctab.dtx index 79f1f45fcd8..f07f1a1b6d7 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3cctab.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3cctab.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx b/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx index b125b7f2f84..e2931f26de4 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx b/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx index 849eddaaea4..3ec8d95ff9c 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3color-base.dtx b/Master/texmf-dist/source/latex/l3kernel/l3color-base.dtx index f34fab40200..47515cd30e3 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3color-base.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3color-base.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3debug.dtx b/Master/texmf-dist/source/latex/l3kernel/l3debug.dtx index 5a214de133a..72cd83ed35c 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3debug.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3debug.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx b/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx index be0f204446f..fff81d47ad4 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx b/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx index 60f5e465c3e..db015fd3722 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx @@ -79,7 +79,7 @@ and all files in that bundle must be distributed together. % % \title{The \cls{l3doc} class} % \author{\Team} -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % \maketitle % \tableofcontents % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx b/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx index c0e139cb3b5..171d20f6946 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx @@ -63,7 +63,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx b/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx index 41af274e8b9..4c2039f9110 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3file.dtx b/Master/texmf-dist/source/latex/l3kernel/l3file.dtx index 67d708da28a..d96d9c7e31e 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3file.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3file.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % @@ -2636,18 +2636,9 @@ % \end{macro} % % \begin{macro}{\@@_size:n} -% A copy of the primitive where it's available, or the \LuaTeX{} -% equivalent if relevant. +% A copy of the primitive where it's available. % \begin{macrocode} \cs_new_eq:NN \@@_size:n \tex_filesize:D -\sys_if_engine_luatex:T - { - \cs_gset:Npn \@@_size:n #1 - { - \lua_now:e - { l3kernel.filesize ( " \lua_escape:e {#1} " ) } - } - } % \end{macrocode} % \end{macro} % @@ -2753,9 +2744,7 @@ % \end{macrocode} % Deal with the fact that the primitive might not be available. % \begin{macrocode} -\bool_lazy_or:nnF - { \cs_if_exist_p:N \tex_filesize:D } - { \sys_if_engine_luatex_p: } +\cs_if_exist:NF \tex_filesize:D { \cs_gset:Npn \file_full_name:n #1 { @@ -2817,9 +2806,7 @@ % existence of the file with |.tex| extension in that directory, and % if it exists we include the |.tex| extension in the result. % \begin{macrocode} -\bool_lazy_or:nnF - { \cs_if_exist_p:N \tex_filesize:D } - { \sys_if_engine_luatex_p: } +\cs_if_exist:NF \tex_filesize:D { \prg_set_protected_conditional:Npnn \file_get_full_name:nN #1#2 { T , F , TF } { @@ -2882,8 +2869,6 @@ % As the MD5 function has a slightly different syntax from the other commands, % there is a little cleaning up to do. % \begin{macrocode} -\cs_new:Npn \file_mdfive_hash:n #1 - { \@@_details:nn {#1} { mdfivesum } } \cs_new:Npn \file_size:n #1 { \@@_details:nn {#1} { size } } \cs_new:Npn \file_timestamp:n #1 @@ -2898,20 +2883,10 @@ \tl_if_blank:nF {#1} { \use:c { tex_file #2 :D } {#1} } } -\sys_if_engine_luatex:TF - { - \cs_gset:Npn \@@_details_aux:nn #1#2 - { - \lua_now:e - { l3kernel.file#2 ( " \lua_escape:e { #1 } " ) } - } - } - { - \cs_gset:Npn \file_mdfive_hash:n #1 - { \exp_args:Ne \@@_mdfive_hash:n { \file_full_name:n {#1} } } - \cs_new:Npn \@@_mdfive_hash:n #1 - { \tex_mdfivesum:D file {#1} } - } +\cs_new:Npn \file_mdfive_hash:n #1 + { \exp_args:Ne \@@_mdfive_hash:n { \file_full_name:n {#1} } } +\cs_new:Npn \@@_mdfive_hash:n #1 + { \tex_mdfivesum:D file {#1} } % \end{macrocode} % \end{macro} % \end{macro} @@ -2973,34 +2948,21 @@ length ~ \int_eval:n { #1 - #2 + 1 } {#3} } -\sys_if_engine_luatex:T - { - \cs_gset:Npn \@@_hex_dump_auxiv:nnn #1#2#3 - { - \lua_now:e - { - l3kernel.filedump - ( - " \lua_escape:e {#3} " , - \int_eval:n { #2 - 1 } , - \int_eval:n { #1 - #2 + 1 } - ) - } - } - } \cs_new:Npn \file_hex_dump:n #1 { \exp_args:Ne \@@_hex_dump:n { \file_full_name:n {#1} } } -\cs_new:Npn \@@_hex_dump:n #1 +\sys_if_engine_luatex:TF { - \tl_if_blank:nF {#1} - { \tex_filedump:D length \tex_filesize:D {#1} {#1} } + \cs_new:Npn \@@_hex_dump:n #1 + { + \tl_if_blank:nF {#1} + { \tex_filedump:D whole {#1} {#1} } + } } -\sys_if_engine_luatex:T { - \cs_gset:Npn \@@_hex_dump:n #1 + \cs_new:Npn \@@_hex_dump:n #1 { - \lua_now:e - { l3kernel.filedump ( " \lua_escape:e { #1 } " ) } + \tl_if_blank:nF {#1} + { \tex_filedump:D length \tex_filesize:D {#1} {#1} } } } % \end{macrocode} @@ -3048,9 +3010,7 @@ % Where the primitive is not available, issue an error: this is a little % more conservative than absolutely needed, but does work. % \begin{macrocode} -\bool_lazy_or:nnF - { \cs_if_exist_p:N \tex_filesize:D } - { \sys_if_engine_luatex_p: } +\cs_if_exist:NF \tex_filesize:D { \cs_set_protected:Npn \@@_get_details:nnN #1#2#3 { @@ -3095,33 +3055,12 @@ % \end{macro} % % \begin{macro}[EXP]{\@@_str_cmp:nn} -% \begin{macro}[EXP]{\@@_str_escape:n} % As we are doing a fixed-length \enquote{big} integer comparison, it % is easiest to use the low-level behavior of string comparisons. % \begin{macrocode} -\cs_new:Npn \@@_str_cmp:nn #1#2 { \tex_strcmp:D {#1} {#2} } -\sys_if_engine_luatex:T - { - \cs_set:Npn \@@_str_cmp:nn #1#2 - { - \lua_now:e - { - l3kernel.strcmp - ( - " \@@_str_escape:n {#1}", - " \@@_str_escape:n {#2}" - ) - } - } - \cs_new:Npn \@@_str_escape:n #1 - { - \lua_escape:e - { \__kernel_tl_to_str:w \use:e { {#1} } } - } - } +\cs_new_eq:NN \@@_str_cmp:nn \tex_strcmp:D % \end{macrocode} % \end{macro} -% \end{macro} % % \begin{macro}[EXP, pTF]{\file_compare_timestamp:nNn} % \begin{macro}[EXP]{\@@_compare_timestamp:nnN} @@ -3169,15 +3108,7 @@ } } } -\sys_if_engine_luatex:TF - { - \cs_new:Npn \@@_timestamp:n #1 - { - \lua_now:e - { l3kernel.filemoddate ( " \lua_escape:e {#1} " ) } - } - } - { \cs_new_eq:NN \@@_timestamp:n \tex_filemoddate:D } +\cs_new_eq:NN \@@_timestamp:n \tex_filemoddate:D \cs_if_exist:NF \@@_timestamp:n { \prg_set_conditional:Npnn \file_compare_timestamp:nNn #1#2#3 diff --git a/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx b/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx index 697a9bd0dea..66c065a0e79 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx index 4635d8a5af9..cddaff1eba6 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % \maketitle % % \begin{documentation} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx index a01a2aa3a3d..9e917ddb9de 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % @@ -1239,27 +1239,9 @@ % \subsection{Fast string comparison} % % \begin{macro}{\@@_str_if_eq:nn} -% A private version of the low-level string comparison function. As -% the nature of the arguments is restricted and as speed is of the essence, -% this version does not seek to deal with |#| tokens. -% No \pkg{l3sys} or \pkg{l3luatex} just yet so we have to define in terms of -% primitives. +% A private version of the low-level string comparison function. % \begin{macrocode} -\sys_if_engine_luatex:TF - { - \cs_new:Npn \@@_str_if_eq:nn #1#2 - { - \tex_directlua:D - { - l3kernel.strcmp - ( - " \tex_luaescapestring:D {#1}", - " \tex_luaescapestring:D {#2}" - ) - } - } - } - { \cs_new_eq:NN \@@_str_if_eq:nn \tex_strcmp:D } +\cs_new_eq:NN \@@_str_if_eq:nn \tex_strcmp:D % \end{macrocode} % \end{macro} % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx index e0a2b26b1ab..29e30ecc1f1 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx index a18213f9117..3b0dd3360e5 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx index b7e4e1bb29b..c86808203c8 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx index f801c860b59..7ed1e427368 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx index daf38c1a394..8c0a2156527 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx index 0753398abc3..7d43b526eac 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx index 4b86d9aa074..7a125bc22f0 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx index 76400b3bac5..551902b58bd 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx index 6948b7104a7..89f47bfafc0 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % \maketitle % % \begin{documentation} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx index 3719dd113d6..319e825bd07 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx @@ -40,7 +40,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx index f19f21c1c37..144a59bb7e2 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx @@ -49,7 +49,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx index 449f7862012..41824d74786 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3int.dtx b/Master/texmf-dist/source/latex/l3kernel/l3int.dtx index 02c29627da2..175a9e07dd5 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3int.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3int.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx b/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx index e41a839d393..dbeddb1ca1d 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx b/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx index e73b8d6c55a..c7a577d8baf 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx b/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx index 812b0941e1f..3e79e8c464b 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3legacy.dtx b/Master/texmf-dist/source/latex/l3kernel/l3legacy.dtx index 0dcb0a5cb65..f5453f5fe1d 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3legacy.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3legacy.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx b/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx index b8f00b1187e..ca266626585 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % @@ -120,9 +120,15 @@ % As well as interfaces for \TeX{}, there are a small number of Lua functions % provided here. % -% \begin{function}{l3kernel} -% All public interfaces provided by the module are stored within the -% |l3kernel| table. +% \begin{function}{ltx.utils} +% Most public interfaces provided by the module are stored within the +% |ltx.utils| table. +% \end{function} +% +% \begin{function}[deprecated = 2021-12-31]{l3kernel} +% For compatibility reasons, there are also some deprecated interfaces provided +% in the |l3kernel| table. These do not return their result as Lua values but +% instead print them to \TeX. % \end{function} % % \begin{function}{l3kernel.charcat} @@ -143,8 +149,9 @@ % for user input. % \end{function} % -% \begin{function}{l3kernel.filedump} +% \begin{function}{ltx.utils.filedump, l3kernel.filedump} % \begin{syntax} +% \meta{dump}| = ltx.utils.filedump(|\meta{file}|,|\meta{offset}|,|\meta{length}|)| \\ % |l3kernel.filedump(|\meta{file}|,|\meta{offset}|,|\meta{length}|)| % \end{syntax} % Returns the uppercase hexadecimal representation of the content of the @@ -154,8 +161,9 @@ % is read starting at the \meta{offset}. % \end{function} % -% \begin{function}{l3kernel.filemdfivesum} +% \begin{function}{ltx.utils.filemd5sum, l3kernel.filemdfivesum} % \begin{syntax} +% \meta{hash}| = ltx.utils.filemd5sum(|\meta{file}|)| \\ % |l3kernel.filemdfivesum(|\meta{file}|)| % \end{syntax} % Returns the MD5 sum of the file contents read as bytes; note that @@ -164,8 +172,9 @@ % nothing is returned with \emph{no error raised}. % \end{function} % -% \begin{function}{l3kernel.filemoddate} +% \begin{function}{ltx.utils.filemoddate, l3kernel.filemoddate} % \begin{syntax} +% \meta{date}| = ltx.utils.filemoddate(|\meta{file}|)| \\ % |l3kernel.filemoddate(|\meta{file}|)| % \end{syntax} % Returns the date/time of last modification of the \meta{file} in the @@ -179,8 +188,9 @@ % not found, nothing is returned with \emph{no error raised}. % \end{function} % -% \begin{function}{l3kernel.filesize} +% \begin{function}{ltx.utils.filesize, l3kernel.filesize} % \begin{syntax} +% |size = ltx.utils.filesize(|\meta{file}|)| \\ % |l3kernel.filesize(|\meta{file}|)| % \end{syntax} % Returns the size of the \meta{file} in bytes. If the \meta{file} is not @@ -313,11 +323,17 @@ % \pkg{pdftexcmds} package. % % \begin{macro}{l3kernel} +% \begin{macro}{ltx.utils} % Create a table for the kernel's own use. % \begin{macrocode} l3kernel = l3kernel or { } +local l3kernel = l3kernel +ltx = ltx or {utils={}} +ltx.utils = ltx.utils or { } +local ltxutils = ltx.utils % \end{macrocode} % \end{macro} +% \end{macro} % % Local copies of global tables. % \begin{macrocode} @@ -331,7 +347,6 @@ local string = string local tex = tex local texio = texio local tonumber = tonumber -local unicode = unicode % \end{macrocode} % % Local copies of standard functions. @@ -342,23 +357,33 @@ local floor = math.floor local format = string.format local gsub = string.gsub local lfs_attr = lfs.attributes -local md5_sum = md5.sum local open = io.open -local os_clock = os.clock local os_date = os.date -local os_exec = os.execute local setcatcode = tex.setcatcode local sprint = tex.sprint local cprint = tex.cprint local write = tex.write local write_nl = texio.write_nl +local utf8_char = utf8.char + +local scan_int = token.scan_int or token.scan_integer +local scan_string = token.scan_string +local scan_keyword = token.scan_keyword +local put_next = token.put_next + +local true_tok = token.create'prg_return_true:' +local false_tok = token.create'prg_return_false:' % \end{macrocode} % -% Newer Con\TeX{}t releases replace the |unicode| library by |utf| and -% since Lua 5.3 we can even use the Lua standard |utf8| library. % \begin{macrocode} -local utf8_char = (utf8 and utf8.char) or (utf and utf.char) or unicode.utf8.char -% \end{macrocode} +local function deprecated(table, name, func) + table[name] = function(...) + write_nl(format("Calling deprecated Lua function %s", name)) + table[name] = func + return func(...) + end +end +% \end{macrocode % % Deal with Con\TeX{}t: doesn't use |kpse| library. % \begin{macrocode} @@ -371,20 +396,20 @@ local kpse_find = (resolvers and resolvers.findfile) or kpse.find_file % covered in \pkg{pdftexcmds} but is not currently required here. % \begin{macrocode} local function escapehex(str) - write((gsub(str, ".", - function (ch) return format("%02X", byte(ch)) end))) + return (gsub(str, ".", + function (ch) return format("%02X", byte(ch)) end)) end % \end{macrocode} % \end{macro} % % \begin{macro}{l3kernel.charcat} % Creating arbitrary chars using |tex.cprint|. +% The alternative approach using |token.put_next(token.create(...))| +% would be about 10\% slower. % \begin{macrocode} -local charcat -function charcat(charcode, catcode) +deprecated(l3kernel, 'charcat', function(charcode, catcode) cprint(catcode, utf8_char(charcode)) -end -l3kernel.charcat = charcat +end) % \end{macrocode} % \end{macro} % @@ -392,9 +417,10 @@ l3kernel.charcat = charcat % Simple timing set up: give the result from the system clock in scaled % seconds. % \begin{macrocode} -local base_time = 0 +local os_clock = os.clock +local base_clock_time = 0 local function elapsedtime() - local val = (os_clock() - base_time) * 65536 + 0.5 + local val = (os_clock() - base_clock_time) * 65536 + 0.5 if val > 2147483647 then val = 2147483647 end @@ -402,36 +428,56 @@ local function elapsedtime() end l3kernel.elapsedtime = elapsedtime local function resettimer() - base_time = os_clock() + base_clock_time = os_clock() end l3kernel.resettimer = resettimer % \end{macrocode} % \end{macro} % +% \begin{macro}{ltx.utils.filedump} % \begin{macro}{l3kernel.filedump} % Similar comments here to the next function: read the file in binary mode % to avoid any line-end weirdness. % \begin{macrocode} local function filedump(name,offset,length) local file = kpse_find(name,"tex",true) - if file then - local length = tonumber(length) or lfs_attr(file,"size") - local offset = tonumber(offset) or 0 - local f = open(file,"rb") - if f then - if offset > 0 then - f:seek("set",offset) - end - local data = f:read(length) - escapehex(data) - f:close() - end + if not file then return end + local f = open(file,"rb") + if not f then return end + if offset and offset > 0 then + f:seek("set", offset) end + local data = f:read(length or 'a') + f:close() + return escapehex(data) end -l3kernel.filedump = filedump +ltxutils.filedump = filedump +deprecated(l3kernel, "filedump", function(name, offset, length) + local dump = filedump(name, tonumber(offset), tonumber(length)) + if dump then + write(dump) + end +end) % \end{macrocode} % \end{macro} +% \end{macro} % +% \begin{macro}{md5.HEX} +% Hash a string and return the hash in uppercase hexadecimal format. +% In some engines, this is build-in. For traditional \LuaTeX{}, the conversion +% to hexadecimal has to be done by us. +% \begin{macrocode} +local md5_HEX = md5.HEX +if not md5_HEX then + local md5_sum = md5.sum + function md5_HEX(data) + return escapehex(md5_sum(data)) + end + md5.HEX = md5_HEX +end +% \end{macrocode} +% \end{macro} +% \begin{macro}{ltx.utils.filemd5sum} % \begin{macro}{l3kernel.filemdfivesum} % Read an entire file and hash it: the hash function itself is a built-in. % As Lua is byte-based there is no work needed here in terms of UTF-8 @@ -439,94 +485,129 @@ l3kernel.filedump = filedump % \LuaTeX{}). The file is read in binary mode so that no line ending % normalisation occurs. % \begin{macrocode} -local function filemdfivesum(name) - local file = kpse_find(name, "tex", true) - if file then - local f = open(file, "rb") - if f then - local data = f:read("*a") - escapehex(md5_sum(data)) - f:close() - end - end +local function filemd5sum(name) + local file = kpse_find(name, "tex", true) if not file then return end + local f = open(file, "rb") if not f then return end + + local data = f:read("*a") + f:close() + return md5_HEX(data) end -l3kernel.filemdfivesum = filemdfivesum +ltxutils.filemd5sum = filemd5sum +deprecated(l3kernel, "filemdfivesum", function(name) + local hash = filemd5sum(name) + if hash then + write(hash) + end +end) % \end{macrocode} % \end{macro} +% \end{macro} % +% \begin{macro}{ltx.utils.filemoddate} % \begin{macro}{l3kernel.filemoddate} +% There are two cases: If the C standard library is C99 compliant, +% we can use |%z| to get the timezone in almost the right format. +% We only have to add primes and replace a zero or missing offset +% with |Z|. +% +% Of course this would be boring, so Windows does things differently. +% There we have to manually calculate the offset. % See procedure \texttt{makepdftime} in \texttt{utils.c} of % \pdfTeX{}. % \begin{macrocode} -local function filemoddate(name) - local file = kpse_find(name, "tex", true) - if file then +local filemoddate +if os_date'%z':match'^[+-]%d%d%d%d$' then + local pattern = lpeg.Cs(16 * + (lpeg.Cg(lpeg.S'+-' * '0000' * lpeg.Cc'Z') + + 3 * lpeg.Cc"'" * 2 * lpeg.Cc"'" + + lpeg.Cc'Z') + * -1) + function filemoddate(name) + local file = kpse_find(name, "tex", true) + if not file then return end + local date = lfs_attr(file, "modification") + if not date then return end + return pattern:match(os_date("D:%Y%m%d%H%M%S%z", date)) + end +else + local function filemoddate(name) + local file = kpse_find(name, "tex", true) + if not file then return end local date = lfs_attr(file, "modification") - if date then - local d = os_date("*t", date) - if d.sec >= 60 then - d.sec = 59 + if not date then return end + local d = os_date("*t", date) + local u = os_date("!*t", date) + local off = 60 * (d.hour - u.hour) + d.min - u.min + if d.year ~= u.year then + if d.year > u.year then + off = off + 1440 + else + off = off - 1440 end - local u = os_date("!*t", date) - local off = 60 * (d.hour - u.hour) + d.min - u.min - if d.year ~= u.year then - if d.year > u.year then - off = off + 1440 - else - off = off - 1440 - end - elseif d.yday ~= u.yday then - if d.yday > u.yday then - off = off + 1440 - else - off = off - 1440 - end + elseif d.yday ~= u.yday then + if d.yday > u.yday then + off = off + 1440 + else + off = off - 1440 end - local timezone - if off == 0 then - timezone = "Z" + end + local timezone + if off == 0 then + timezone = "Z" + else + if off < 0 then + timezone = "-" + off = -off else - local hours = floor(off / 60) - local mins = abs(off - hours * 60) - timezone = format("%+03d", hours) - .. "'" .. format("%02d", mins) .. "'" + timezone = "+" end - write("D:" - .. format("%04d", d.year) - .. format("%02d", d.month) - .. format("%02d", d.day) - .. format("%02d", d.hour) - .. format("%02d", d.min) - .. format("%02d", d.sec) - .. timezone) + timezone = format("%s%02d'%02d'", timezone, hours // 60, hours % 60) end + return format("D:%04d%02d%02d%02d%02d%02d%s", + d.year, d.month, d.day, d.hour, d.min, d.sec, timezone) end end -l3kernel.filemoddate = filemoddate +ltxutils.filemoddate = filemoddate +deprecated(l3kernel, "filemoddate", function(name) + local hash = filemoddate(name) + if hash then + write(hash) + end +end) % \end{macrocode} % \end{macro} +% \end{macro} % +% \begin{macro}{ltx.utils.filesize} % \begin{macro}{l3kernel.filesize} % A simple disk lookup. % \begin{macrocode} local function filesize(name) - local file = kpse_find(name, "tex", true) + local file = kpse_find(name, "tex", true) if file then local size = lfs_attr(file, "size") if size then - write(size) + return size end end end -l3kernel.filesize = filesize +ltxutils.filesize = filesize +deprecated(l3kernel, "filesize", function(name) + local size = filesize(name) + if size then + write(size) + end +end) % \end{macrocode} % \end{macro} +% \end{macro} % % \begin{macro}{l3kernel.strcmp} % String comparison which gives the same results as \pdfTeX{}'s % \tn{pdfstrcmp}, although the ordering should likely not be relied upon! % \begin{macrocode} -local function strcmp(A, B) +deprecated(l3kernel, "strcmp", function (A, B) if A == B then write("0") elseif A < B then @@ -534,15 +615,15 @@ local function strcmp(A, B) else write("1") end -end -l3kernel.strcmp = strcmp +end) % \end{macrocode} % \end{macro} % % \begin{macro}{l3kernel.shellescape} % Replicating the \pdfTeX{} log interaction for shell escape. % \begin{macrocode} -local function shellescape(cmd) +local os_exec = os.execute +deprecated(l3kernel, "shellescape", function(cmd) local status,msg = os_exec(cmd) if status == nil then write_nl("log","runsystem(" .. cmd .. ")...(" .. msg .. ")\n") @@ -551,8 +632,48 @@ local function shellescape(cmd) else write_nl("log","runsystem(" .. cmd .. ")...failed " .. (msg or "") .. "\n") end +end) +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{luadef} +% An internal function for defining control sequences form Lua which behave +% like primitives. This acts as a wrapper around |token.set_lua| which accepts +% a function instead of an index into the functions table. +% \begin{macrocode} +local luacmd do + local token_create = token.create + local set_lua = token.set_lua + local undefined_cs = token.command_id'undefined_cs' + + if not context and not luatexbase then require'ltluatex' end + if luatexbase then + local new_luafunction = luatexbase.new_luafunction + local functions = lua.get_functions_table() + function luacmd(name, func, ...) + local id + local tok = token_create(name) + if tok.command == undefined_cs then + id = new_luafunction(name) + set_lua(name, id, ...) + else + id = tok.index or tok.mode + end + functions[id] = func + end + elseif context then + local register = context.functions.register + local functions = context.functions.known + function luacmd(name, func, ...) + local tok = token.create(name) + if tok.command == undefined_cs then + token.set_lua(name, register(func), ...) + else + functions[tok.index or tok.mode] = func + end + end + end end -l3kernel.shellescape = shellescape % \end{macrocode} % \end{macro} % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx b/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx index 748aa87885e..56040ef2071 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3names.dtx b/Master/texmf-dist/source/latex/l3kernel/l3names.dtx index 08dad0f48d9..e7b7a0e50a3 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3names.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3names.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % @@ -55,18 +55,19 @@ % performs the following tasks: % \begin{itemize} % \item defines new names for all \TeX{} primitives; +% \item emulate required primitives not provided by default in \LuaTeX; % \item switches to the category code r{\'e}gime for programming; % \end{itemize} % -% This module is entirely dedicated to primitives, which should not be -% used directly within \LaTeX3 code (outside of \enquote{kernel-level} -% code). As such, the primitives are not documented here: \emph{The -% \TeX{}book}, \emph{\TeX{} by Topic} and the manuals for \pdfTeX{}, -% \XeTeX{}, \LuaTeX{}, \pTeX{} and \upTeX{} should be consulted for -% details of the primitives. These are named -% \cs[no-index]{tex_\meta{name}:D}, typically based on the primitive's -% \meta{name} in \pdfTeX{} and omitting a leading |pdf| when the -% primitive is not related to pdf output. +% This module is entirely dedicated to primitives (and emulations of +% these), which should not be used directly within \LaTeX3 code +% (outside of \enquote{kernel-level} code). As such, the primitives +% are not documented here: \emph{The \TeX{}book}, \emph{\TeX{} by +% Topic} and the manuals for \pdfTeX{}, \XeTeX{}, \LuaTeX{}, \pTeX{} +% and \upTeX{} should be consulted for details of the primitives. +% These are named \cs[no-index]{tex_\meta{name}:D}, typically based +% on the primitive's \meta{name} in \pdfTeX{} and omitting a leading +% |pdf| when the primitive is not related to pdf output. % % \end{documentation} % @@ -75,7 +76,7 @@ % \section{\pkg{l3names} implementation} % % \begin{macrocode} -%<*package> +%<*package&tex> % \end{macrocode} % % The prefix here is \texttt{kernel}. A few places need |@@| to be left @@ -111,7 +112,8 @@ % % To allow extracting \enquote{just the names}, a bit of DocStrip fiddling. % \begin{macrocode} -%</package> +%</package&tex> +%<*names|tex> %<*names|package> % \end{macrocode} % @@ -609,9 +611,6 @@ \@@_primitive:NN \pdfeachlinedepth \tex_eachlinedepth:D \@@_primitive:NN \pdfeachlineheight \tex_eachlineheight:D \@@_primitive:NN \pdfelapsedtime \tex_elapsedtime:D - \@@_primitive:NN \pdffiledump \tex_filedump:D - \@@_primitive:NN \pdffilemoddate \tex_filemoddate:D - \@@_primitive:NN \pdffilesize \tex_filesize:D \@@_primitive:NN \pdffirstlineheight \tex_firstlineheight:D \@@_primitive:NN \pdffontexpand \tex_fontexpand:D \@@_primitive:NN \pdffontsize \tex_fontsize:D @@ -622,7 +621,6 @@ \@@_primitive:NN \pdflastypos \tex_lastypos:D \@@_primitive:NN \pdfmapfile \tex_mapfile:D \@@_primitive:NN \pdfmapline \tex_mapline:D - \@@_primitive:NN \pdfmdfivesum \tex_mdfivesum:D \@@_primitive:NN \pdfnoligatures \tex_noligatures:D \@@_primitive:NN \pdfnormaldeviate \tex_normaldeviate:D \@@_primitive:NN \pdfpageheight \tex_pageheight:D @@ -635,7 +633,6 @@ \@@_primitive:NN \pdfrandomseed \tex_randomseed:D \@@_primitive:NN \pdfresettimer \tex_resettimer:D \@@_primitive:NN \pdfsavepos \tex_savepos:D - \@@_primitive:NN \pdfstrcmp \tex_strcmp:D \@@_primitive:NN \pdfsetrandomseed \tex_setrandomseed:D \@@_primitive:NN \pdfshellescape \tex_shellescape:D \@@_primitive:NN \pdftracingfonts \tex_tracingfonts:D @@ -681,6 +678,16 @@ %</package> %<*names|package> % \end{macrocode} +% Some \pdfTeX{} primitives are handled here because they got dropped in +% \LuaTeX{} but the corresponding internal names are emulated later. The +% Lua code is already loaded at this point, so we shouldn't overwrite them. +% \begin{macrocode} + \@@_primitive:NN \pdfstrcmp \tex_strcmp:D + \@@_primitive:NN \pdffilesize \tex_filesize:D + \@@_primitive:NN \pdfmdfivesum \tex_mdfivesum:D + \@@_primitive:NN \pdffilemoddate \tex_filemoddate:D + \@@_primitive:NN \pdffiledump \tex_filedump:D +% \end{macrocode} % \XeTeX{}-specific primitives. Note that \XeTeX{}'s \tn{strcmp} is % handled earlier and is \enquote{rolled up} into \tn{pdfstrcmp}. % A few cross-compatibility names which lack @@ -1187,7 +1194,9 @@ % End of the \enquote{just the names} part of the source. % \begin{macrocode} %</names|package> +%</names|tex> %<*package> +%<*tex> % \end{macrocode} % % The job is done: close the group (using the primitive renamed!). @@ -1441,6 +1450,103 @@ % \end{macrocode} % % \begin{macrocode} +%</tex> +% \end{macrocode} +% +% In \LuaTeX{}, we additionally emulate some primitives using Lua code. +% \begin{macrocode} +%<*lua> +% \end{macrocode} +% +% \begin{macro}{\tex_strcmp:D} +% Compare two strings, expanding to |0| if they are equal, +% |-1| if the first one is smaller and |1| if the second one is smaller. +% Here \enquote{smaller} refers to codepoint order which does not correspond to +% the user expected order for most non-ASCII strings. +% \begin{macrocode} +luacmd('tex_strcmp:D', function() + local first = scan_string() + local second = scan_string() + write(first == second and '0' + or first < second and '-1' + or '1') +end, 'global') +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tex_Ucharcat:D} +% Creating arbitrary chars using |tex.cprint|. +% The alternative approach using |token.put_next(token.create(...))| +% would be about 10\% slower. +% \begin{macrocode} +local cprint = tex.cprint +luacmd('tex_Ucharcat:D', function() + local charcode = scan_int() + local catcode = scan_int() + cprint(catcode, utf8_char(charcode)) +end, 'global') +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tex_filesize:D} +% Wrap the function from |ltxutils|. +% \begin{macrocode} +luacmd('tex_filesize:D', function() + local size = filesize(scan_string()) + if size then write(size) end +end, 'global') +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tex_mdfivesum:D} +% There are two cases: Either hash a file or a string. +% Both are already implemented in l3luatex or built-in. +% \begin{macrocode} +luacmd('tex_mdfivesum:D', function() + local hash + if scan_keyword"file" then + hash = filemd5sum(scan_string()) + else + hash = md5_HEX(scan_string()) + end + if hash then write(hash) end +end, 'global') +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tex_filemoddate:D} +% A primitive for getting the modification date of a file. +% \begin{macrocode} +luacmd('tex_filemoddate:D', function() + local date = filemoddate(scan_string()) + if date then write(date) end +end, 'global') +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tex_filedump:D} +% An emulated primitive for getting a hexdump from a (partial) file. +% The length has a default of |0|. This is consistent with +% \pdfTeX, but it effectivly makes the primitive useless without an +% explicit |length|. Therefore we allow the keyword |whole| to be used +% instead of a length, indicating that the whole remaining file should +% be read. +% \begin{macrocode} +luacmd('tex_filedump:D', function() + local offset = scan_keyword'offset' and scan_int() or nil + local length = scan_keyword'length' and scan_int() + or not scan_keyword'whole' and 0 or nil + local data = filedump(scan_string(), offset, length) + if data then write(data) end +end, 'global') +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%</lua> +% \end{macrocode} +% +% \begin{macrocode} %</package> % \end{macrocode} % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx b/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx index 6003f49343f..882e0367afb 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx b/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx index 9125c5ec8e3..0f10a77defc 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx b/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx index 8361fa47f2a..0251fc2e822 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx b/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx index faa41bc68ae..4d63d5bd800 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx b/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx index 0201692ebbf..63156f66da3 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx b/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx index 3ecd3004d05..d9ea8d1e20e 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx b/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx index 4c981becf9d..55471855e0a 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3str-convert.dtx b/Master/texmf-dist/source/latex/l3kernel/l3str-convert.dtx index 324f9f8b928..805a3ebeb3f 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3str-convert.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3str-convert.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3str.dtx b/Master/texmf-dist/source/latex/l3kernel/l3str.dtx index 84d2e2d7ae6..a7731373d2e 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3str.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3str.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % @@ -1121,44 +1121,12 @@ % \end{macro} % % \begin{macro}[EXP]{\@@_if_eq:nn} -% \begin{macro}[EXP]{\@@_escape:n} -% String comparisons rely on the primitive \cs[index=pdfstrcmp]{(pdf)strcmp} if available: -% \LuaTeX{} does not have it, so emulation is required. As the net result -% is that we do not \emph{always} use the primitive, the correct approach -% is to wrap up in a function with defined behaviour. That's done by -% providing a wrapper and then redefining in the \LuaTeX{} case. Note that -% the necessary Lua code is loaded in \pkg{l3boostrap}. -% The need to detokenize and force -% expansion of input arises from the case where a |#| token is used in the -% input, \emph{e.g.}~|\__str_if_eq:nn {#} { \tl_to_str:n {#} }|, which -% otherwise would fail as \cs{tex_luaescapestring:D} does not double -% such tokens. +% String comparisons rely on the primitive \cs[index=pdfstrcmp]{(pdf)strcmp}, +% so we define a new name for it. % \begin{macrocode} -\cs_new:Npn \@@_if_eq:nn #1#2 { \tex_strcmp:D {#1} {#2} } -\cs_if_exist:NT \tex_luatexversion:D - { - \cs_set_eq:NN \lua_escape:e \tex_luaescapestring:D - \cs_set_eq:NN \lua_now:e \tex_directlua:D - \cs_set:Npn \@@_if_eq:nn #1#2 - { - \lua_now:e - { - l3kernel.strcmp - ( - " \@@_escape:n {#1} " , - " \@@_escape:n {#2} " - ) - } - } - \cs_new:Npn \@@_escape:n #1 - { - \lua_escape:e - { \__kernel_tl_to_str:w \use:e { {#1} } } - } - } +\cs_new_eq:NN \@@_if_eq:nn \tex_strcmp:D % \end{macrocode} % \end{macro} -% \end{macro} % % \begin{macro}[pTF, EXP] % { diff --git a/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx b/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx index 9c9b8fa84b1..6ca5313c506 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % @@ -317,6 +317,7 @@ % % \begin{macrocode} %<*package> +%<*tex> % \end{macrocode} % % \subsubsection{Detecting the engine} @@ -391,23 +392,26 @@ % however, is reliable only if the user doesn't change % \cs{tex_pdfoutput:D} before loading this code. % \begin{macrocode} -\str_const:Nx \c_sys_engine_exec_str - { - \sys_if_engine_pdftex:T { pdf } - \sys_if_engine_xetex:T { xe } - \sys_if_engine_ptex:T { ep } - \sys_if_engine_uptex:T { eup } - \sys_if_engine_luatex:T - { - lua \lua_now:e - { - if (pcall(require, 'luaharfbuzz')) then ~ - tex.print("hb") ~ - end - } - } - tex - } +\group_begin: + \cs_set_eq:NN \lua_now:e \tex_directlua:D + \str_const:Nx \c_sys_engine_exec_str + { + \sys_if_engine_pdftex:T { pdf } + \sys_if_engine_xetex:T { xe } + \sys_if_engine_ptex:T { ep } + \sys_if_engine_uptex:T { eup } + \sys_if_engine_luatex:T + { + lua \lua_now:e + { + if (pcall(require, 'luaharfbuzz')) then ~ + tex.print("hb") ~ + end + } + } + tex + } +\group_end: \str_const:Nx \c_sys_engine_format_str { \cs_if_exist:NTF \fmtname @@ -647,34 +651,78 @@ % \end{variable} % % \begin{macro}{\sys_shell_now:n} +% \begin{macro}{\@@_shell_now:e} % Execute commands through shell escape immediately. +% +% For \LuaTeX{}, we use a pseudo-primitive to do the actual work. +% \begin{macrocode} +%</tex> +%<*lua> +do + local os_exec = os.execute + + local function shellescape(cmd) + local status,msg = os_exec(cmd) + if status == nil then + write_nl("log","runsystem(" .. cmd .. ")...(" .. msg .. ")\n") + elseif status == 0 then + write_nl("log","runsystem(" .. cmd .. ")...executed\n") + else + write_nl("log","runsystem(" .. cmd .. ")...failed " .. (msg or "") .. "\n") + end + end + luacmd("@@_shell_now:e", function() + shellescape(scan_string()) + end, "global", "protected") +%</lua> +% \end{macrocode} +% % \begin{macrocode} +%<*tex> \sys_if_engine_luatex:TF { \cs_new_protected:Npn \sys_shell_now:n #1 - { - \lua_now:e - { l3kernel.shellescape(" \lua_escape:e { \tl_to_str:n {#1} } ") } - } + { \@@_shell_now:e { \exp_not:n {#1} } } } { \cs_new_protected:Npn \sys_shell_now:n #1 { \iow_now:Nn \c_@@_shell_stream_int {#1} } } \cs_generate_variant:Nn \sys_shell_now:n { x } +%</tex> % \end{macrocode} % \end{macro} +% \end{macro} % % \begin{macro}{\sys_shell_shipout:n} +% \begin{macro}{\@@_shell_shipout:e} % Execute commands through shell escape at shipout. +% +% For \LuaTeX, we use the same helper as above but delayed to using a late_lua whatsit. % \begin{macrocode} +%<*lua> + local whatsit_id = node.id'whatsit' + local latelua_sub = node.subtype'late_lua' + local node_new = node.direct.new + local setfield = node.direct.setwhatsitfield or node.direct.setfield + local node_write = node.direct.write + + luacmd("@@_shell_shipout:e", function() + local cmd = scan_string() + local n = node_new(whatsit_id, latelua_sub) + setfield(n, 'data', function() shellescape(cmd) end) + node_write(n) + end, "global", "protected") +end +%</lua> +% \end{macrocode} +% +% \begin{macrocode} +%<*tex> \sys_if_engine_luatex:TF { \cs_new_protected:Npn \sys_shell_shipout:n #1 - { - \lua_shipout_e:n - { l3kernel.shellescape(" \lua_escape:e { \tl_to_str:n {#1} } ") } - } + { \@@_shell_shipout:e { \exp_not:n {#1} } } } { \cs_new_protected:Npn \sys_shell_shipout:n #1 @@ -683,6 +731,7 @@ \cs_generate_variant:Nn \sys_shell_shipout:n { x } % \end{macrocode} % \end{macro} +% \end{macro} % % \subsection{Dynamic (every job) code} % @@ -969,6 +1018,7 @@ % \end{variable} % % \begin{macrocode} +%</tex> %</package> % \end{macrocode} % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx b/Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx index c44bede9f7a..b89de90efdf 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3text-purify.dtx b/Master/texmf-dist/source/latex/l3kernel/l3text-purify.dtx index 5b0770e6f32..4833e91f414 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3text-purify.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3text-purify.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3text.dtx b/Master/texmf-dist/source/latex/l3kernel/l3text.dtx index e0623262863..325b7f2763d 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3text.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3text.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx b/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx index 532c5142633..55559abdbbb 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx b/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx index 095a51d9484..7ac12bb1270 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3token.dtx b/Master/texmf-dist/source/latex/l3kernel/l3token.dtx index 473cd48a82c..6d3f13581f1 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3token.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3token.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % @@ -737,12 +737,13 @@ % (not used by \LaTeX3). % \end{function} % -% \begin{function}[updated = 2011-05-23, EXP,pTF]{\token_if_primitive:N} +% \begin{function}[updated = 2020-09-11, EXP,pTF]{\token_if_primitive:N} % \begin{syntax} % \cs{token_if_primitive_p:N} \meta{token} \\ % \cs{token_if_primitive:NTF} \meta{token} \Arg{true code} \Arg{false code} % \end{syntax} -% Tests if the \meta{token} is an engine primitive. +% Tests if the \meta{token} is an engine primitive. In \LuaTeX{} +% this includes primitive-like commands defined using |{token.set_lua}|. % \end{function} % % \section{Peeking ahead at the next token} @@ -1112,6 +1113,10 @@ % \end{macrocode} % % \begin{macrocode} +%<*tex> +% \end{macrocode} +% +% \begin{macrocode} %<@@=char> % \end{macrocode} % @@ -1454,37 +1459,26 @@ \if_int_odd:w 0 \sys_if_engine_luatex:T { 1 } \sys_if_engine_xetex:T { 1 } \exp_stop_f: - \sys_if_engine_luatex:TF - { - \cs_new:Npn \@@_generate_aux:nnw #1#2#3 \exp_end: - { - #3 - \exp_after:wN \exp_after:wN \exp_after:wN \exp_end: - \lua_now:e { l3kernel.charcat(#1, #2) } - } - } - { - \cs_new:Npn \@@_generate_aux:nnw #1#2#3 \exp_end: - { - #3 - \exp_after:wN \exp_end: - \tex_Ucharcat:D #1 \exp_stop_f: #2 \exp_stop_f: - } - \cs_if_exist:NF \tex_expanded:D - { - \cs_new_eq:NN \@@_generate_auxii:nnw \@@_generate_aux:nnw - \cs_gset:Npn \@@_generate_aux:nnw #1#2#3 \exp_end: - { - #3 - \if_int_compare:w #2 = 13 \exp_stop_f: - \__kernel_msg_expandable_error:nn { kernel } { char-active } - \else: - \@@_generate_auxii:nnw {#1} {#2} - \fi: - \exp_end: - } - } - } + \cs_new:Npn \@@_generate_aux:nnw #1#2#3 \exp_end: + { + #3 + \exp_after:wN \exp_end: + \tex_Ucharcat:D #1 \exp_stop_f: #2 \exp_stop_f: + } + \cs_if_exist:NF \tex_expanded:D + { + \cs_new_eq:NN \@@_generate_auxii:nnw \@@_generate_aux:nnw + \cs_gset:Npn \@@_generate_aux:nnw #1#2#3 \exp_end: + { + #3 + \if_int_compare:w #2 = 13 \exp_stop_f: + \__kernel_msg_expandable_error:nn { kernel } { char-active } + \else: + \@@_generate_auxii:nnw {#1} {#2} + \fi: + \exp_end: + } + } \else: % \end{macrocode} % For engines where \tn{Ucharcat} isn't available or emulated, we have @@ -2369,7 +2363,8 @@ % \@@_if_primitive_nullfont:N, % \@@_if_primitive_loop:N, % \@@_if_primitive:Nw, -% \@@_if_primitive_undefined:N} +% \@@_if_primitive_undefined:N, +% \@@_if_primitive_lua:N} %^^A See http://groups.google.com/group/comp.text.tex/browse_thread/thread/0a72666873f8753d# % % We filter out macros first, because they cause endless trouble later @@ -2414,67 +2409,142 @@ % \cs{tex_undefined:D}, and if it is |"| or a digit, then the token % is not a primitive. % +% For \LuaTeX{} we use a different implementation which just looks at the +% command code for the token and compaes it to a list of non-primitives. +% Again, \tn{nullfont} is a special case because it is the only primitive +% with the normally non-primitive |set_font| command code. +% % \begin{macrocode} -\tex_chardef:D \c_@@_A_int = `A ~ % -\use:x +\sys_if_engine_luatex:TF { - \prg_new_conditional:Npnn \exp_not:N \token_if_primitive:N ##1 - { p , T , F , TF } +%</tex> +%<*lua> +do + local get_next = token.get_next + local get_command = token.get_command + local get_index = token.get_index + local get_mode = token.get_mode or token.get_index + local cmd = token.command_id + local set_font = cmd'get_font' + local biggest_char = token.biggest_char() + + local mode_below_biggest_char = {} + local index_not_nil = {} + local mode_not_null = {} + local non_primitive = { + [cmd'left_brace'] = true, + [cmd'right_brace'] = true, + [cmd'math_shift'] = true, + [cmd'mac_param'] = mode_below_biggest_char, + [cmd'sup_mark'] = true, + [cmd'sub_mark'] = true, + [cmd'endv'] = true, + [cmd'spacer'] = true, + [cmd'letter'] = true, + [cmd'other_char'] = true, + [cmd'tab_mark'] = mode_below_biggest_char, + [cmd'char_given'] = true, + [cmd'math_given'] = true, + [cmd'xmath_given'] = true, + [cmd'set_font'] = mode_not_null, + [cmd'undefined_cs'] = true, + [cmd'call'] = true, + [cmd'long_call'] = true, + [cmd'outer_call'] = true, + [cmd'long_outer_call'] = true, + [cmd'assign_glue'] = index_not_nil, + [cmd'assign_mu_glue'] = index_not_nil, + [cmd'assign_toks'] = index_not_nil, + [cmd'assign_int'] = index_not_nil, + [cmd'assign_attr'] = true, + [cmd'assign_dimen'] = index_not_nil, + } + + luacmd("@@_if_primitive_lua:N", function() + local tok = get_next() + local is_non_primitive = non_primitive[get_command(tok)] + return put_next( + is_non_primitive == true + and false_tok + or is_non_primitive == nil + and true_tok + or is_non_primitive == mode_not_null + and (get_mode(tok) == 0 and true_tok or false_tok) + or is_non_primitive == index_not_nil + and (get_index(tok) and false_tok or true_tok) + or is_non_primitive == mode_below_biggest_char + and (get_mode(tok) > biggest_char and true_tok or false_tok)) + end, "global") +end +%</lua> +%<*tex> + \prg_new_conditional:Npnn \token_if_primitive:N #1 { p , T , F , TF } { - \exp_not:N \token_if_macro:NTF ##1 - \exp_not:N \prg_return_false: - { - \exp_not:N \exp_after:wN \exp_not:N \@@_if_primitive:NNw - \exp_not:N \token_to_meaning:N ##1 - \tl_to_str:n { : : : } \s_@@_stop ##1 - } + \@@_if_primitive_lua:N #1 } - \cs_new:Npn \exp_not:N \@@_if_primitive:NNw - ##1##2 ##3 \c_colon_str ##4 \s_@@_stop + } + { + \tex_chardef:D \c_@@_A_int = `A ~ % + \use:x { - \exp_not:N \tl_if_empty:oTF - { \exp_not:N \@@_if_primitive_space:w ##3 ~ } + \prg_new_conditional:Npnn \exp_not:N \token_if_primitive:N ##1 + { p , T , F , TF } { - \exp_not:N \@@_if_primitive_loop:N ##3 - \c_colon_str \s_@@_stop + \exp_not:N \token_if_macro:NTF ##1 + \exp_not:N \prg_return_false: + { + \exp_not:N \exp_after:wN \exp_not:N \@@_if_primitive:NNw + \exp_not:N \token_to_meaning:N ##1 + \tl_to_str:n { : : : } \s_@@_stop ##1 + } + } + \cs_new:Npn \exp_not:N \@@_if_primitive:NNw + ##1##2 ##3 \c_colon_str ##4 \s_@@_stop + { + \exp_not:N \tl_if_empty:oTF + { \exp_not:N \@@_if_primitive_space:w ##3 ~ } + { + \exp_not:N \@@_if_primitive_loop:N ##3 + \c_colon_str \s_@@_stop + } + { \exp_not:N \@@_if_primitive_nullfont:N } } - { \exp_not:N \@@_if_primitive_nullfont:N } } - } -\cs_new:Npn \@@_if_primitive_space:w #1 ~ { } -\cs_new:Npn \@@_if_primitive_nullfont:N #1 - { - \if_meaning:w \tex_nullfont:D #1 - \prg_return_true: - \else: - \prg_return_false: - \fi: - } -\cs_new:Npn \@@_if_primitive_loop:N #1 - { - \if_int_compare:w `#1 < \c_@@_A_int % - \exp_after:wN \@@_if_primitive:Nw - \exp_after:wN #1 - \else: - \exp_after:wN \@@_if_primitive_loop:N - \fi: - } -\cs_new:Npn \@@_if_primitive:Nw #1 #2 \s_@@_stop - { - \if:w : #1 - \exp_after:wN \@@_if_primitive_undefined:N - \else: - \prg_return_false: - \exp_after:wN \use_none:n - \fi: - } -\cs_new:Npn \@@_if_primitive_undefined:N #1 - { - \if_cs_exist:N #1 - \prg_return_true: - \else: - \prg_return_false: - \fi: + \cs_new:Npn \@@_if_primitive_space:w #1 ~ { } + \cs_new:Npn \@@_if_primitive_nullfont:N #1 + { + \if_meaning:w \tex_nullfont:D #1 + \prg_return_true: + \else: + \prg_return_false: + \fi: + } + \cs_new:Npn \@@_if_primitive_loop:N #1 + { + \if_int_compare:w `#1 < \c_@@_A_int % + \exp_after:wN \@@_if_primitive:Nw + \exp_after:wN #1 + \else: + \exp_after:wN \@@_if_primitive_loop:N + \fi: + } + \cs_new:Npn \@@_if_primitive:Nw #1 #2 \s_@@_stop + { + \if:w : #1 + \exp_after:wN \@@_if_primitive_undefined:N + \else: + \prg_return_false: + \exp_after:wN \use_none:n + \fi: + } + \cs_new:Npn \@@_if_primitive_undefined:N #1 + { + \if_cs_exist:N #1 + \prg_return_true: + \else: + \prg_return_false: + \fi: + } } % \end{macrocode} % \end{macro} @@ -2869,6 +2939,10 @@ % \end{macro} % % \begin{macrocode} +%</tex> +% \end{macrocode} +% +% \begin{macrocode} %</package> % \end{macrocode} % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx b/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx index 4b024350af8..3cc420f68f7 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2020-09-06} +% \date{Released 2020-09-24} % % \maketitle % @@ -97,22 +97,9 @@ { \exp_not:N \tex_unexpanded:D \exp_not:N \exp_after:wN { - \sys_if_engine_luatex:TF - { - \exp_not:N \tex_directlua:D - { - l3kernel.charcat - ( - \exp_not:N \tex_number:D #1 , - \exp_not:N \tex_the:D \tex_catcode:D #1 - ) - } - } - { - \exp_not:N \tex_Ucharcat:D - #1 ~ - \tex_catcode:D #1 ~ - } + \exp_not:N \tex_Ucharcat:D + #1 ~ + \tex_catcode:D #1 ~ } } % \end{macrocode} |