diff options
Diffstat (limited to 'macros/latex/contrib/l3kernel/l3sys.dtx')
-rw-r--r-- | macros/latex/contrib/l3kernel/l3sys.dtx | 561 |
1 files changed, 328 insertions, 233 deletions
diff --git a/macros/latex/contrib/l3kernel/l3sys.dtx b/macros/latex/contrib/l3kernel/l3sys.dtx index 172d9507eb..c476e67e23 100644 --- a/macros/latex/contrib/l3kernel/l3sys.dtx +++ b/macros/latex/contrib/l3kernel/l3sys.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2019-10-02} +% \date{Released 2019-10-11} % % \maketitle % @@ -276,6 +276,16 @@ % back deprecations, respectively. % \end{function} % +% \subsection{Final settins} +% +% \begin{function}[added = 2019-10-06]{\sys_finalise:} +% \begin{syntax} +% \cs{sys_finalise:} +% \end{syntax} +% Finalises all system-dependent functionality: required before loading +% a backend. +% \end{function} +% % \end{documentation} % % \begin{implementation} @@ -283,34 +293,16 @@ % \section{\pkg{l3sys} implementation} % % \begin{macrocode} -%<*initex|package> -% \end{macrocode} -% -% \begin{macrocode} %<@@=sys> % \end{macrocode} % -% \subsection{The name of the job} +% \subsection{Kernel code} % -% \begin{variable}{\c_sys_jobname_str} -% Inherited from the \LaTeX3 name for the primitive: this needs to -% actually contain the text of the job name rather than the name of -% the primitive, of course. % \begin{macrocode} -%<*initex> -\tex_everyjob:D \exp_after:wN - { - \tex_the:D \tex_everyjob:D - \str_const:Nx \c_sys_jobname_str { \tex_jobname:D } - } -%</initex> -%<*package> -\str_const:Nx \c_sys_jobname_str { \tex_jobname:D } -%</package> +%<*initex|package> % \end{macrocode} -% \end{variable} % -% \subsection{Detecting the engine} +% \subsubsection{Detecting the engine} % % \begin{macro}{\@@_const:nn} % Set the |T|, |F|, |TF|, |p| forms of |#1| to be constants equal to @@ -373,89 +365,7 @@ % \end{variable} % \end{macro} % -% \subsection{Time and date} -% -% \begin{variable} -% { -% \c_sys_minute_int, -% \c_sys_hour_int, -% \c_sys_day_int, -% \c_sys_month_int, -% \c_sys_year_int, -% } -% Copies of the information provided by \TeX{}. There is a lot of defensive -% code in package mode: someone may have moved the primitives, and they can -% only be recovered if we have \tn{primitive} and it is working correctly. -% \begin{macrocode} -%<*initex> -\int_const:Nn \c_sys_minute_int - { \int_mod:nn { \tex_time:D } { 60 } } -\int_const:Nn \c_sys_hour_int - { \int_div_truncate:nn { \tex_time:D } { 60 } } -\int_const:Nn \c_sys_day_int { \tex_day:D } -\int_const:Nn \c_sys_month_int { \tex_month:D } -\int_const:Nn \c_sys_year_int { \tex_year:D } -%</initex> -%<*package> -\group_begin: - \cs_set:Npn \@@_tmp:w #1 - { - \str_if_eq:eeTF { \cs_meaning:N #1 } { \token_to_str:N #1 } - { #1 } - { - \cs_if_exist:NTF \tex_primitive:D - { - \bool_lazy_and:nnTF - { \sys_if_engine_xetex_p: } - { - \int_compare_p:nNn - { \exp_after:wN \use_none:n \tex_XeTeXrevision:D } - < { 99999 } - } - { 0 } - { \tex_primitive:D #1 } - } - { 0 } - } - } - \int_const:Nn \c_sys_minute_int - { \int_mod:nn { \@@_tmp:w \time } { 60 } } - \int_const:Nn \c_sys_hour_int - { \int_div_truncate:nn { \@@_tmp:w \time } { 60 } } - \int_const:Nn \c_sys_day_int { \@@_tmp:w \day } - \int_const:Nn \c_sys_month_int { \@@_tmp:w \month } - \int_const:Nn \c_sys_year_int { \@@_tmp:w \year } -\group_end: -%</package> -% \end{macrocode} -% \end{variable} -% -% \subsection{Detecting the output} -% -% \begin{macro}[pTF, EXP] -% { -% \sys_if_output_dvi:, -% \sys_if_output_pdf: -% } -% \begin{variable}{\c_sys_output_str} -% This is a simple enough concept: the two views here are complementary. -% \begin{macrocode} -\str_const:Nx \c_sys_output_str - { - \int_compare:nNnTF - { \cs_if_exist_use:NF \tex_pdfoutput:D { 0 } } > { 0 } - { pdf } - { dvi } - } -\@@_const:nn { sys_if_output_dvi } - { \str_if_eq_p:Vn \c_sys_output_str { dvi } } -\@@_const:nn { sys_if_output_pdf } - { \str_if_eq_p:Vn \c_sys_output_str { pdf } } -% \end{macrocode} -% \end{variable} -% \end{macro} -% -% \subsection{Randomness} +% \subsubsection{Randomness} % % This candidate function is placed there because % \cs{sys_if_rand_exist:TF} is used in \pkg{l3fp-rand}. @@ -468,7 +378,7 @@ % \end{macrocode} % \end{macro} % -% \subsection{Platform} +% \subsubsection{Platform} % % \begin{macro}[pTF]{\sys_if_platform_unix:, \sys_if_platform_windows:} % \begin{variable}{\c_sys_platform_str} @@ -477,63 +387,95 @@ % \end{variable} % \end{macro} % -% \subsection{Random numbers} +% \subsubsection{Configurations} % -% \begin{macro}[EXP]{\sys_rand_seed:} -% Unpack the primitive. When random numbers are not available, we -% return zero after an error (and incidentally make sure the number of -% expansions needed is the same as with random numbers available). +% \begin{macro}{\sys_load_backend:n} +% \begin{macro}{\@@_load_backend_check:N} +% \begin{variable}{\c_sys_backend_str} +% Loading the backend code is pretty simply: check that the backend is valid, +% then load it up. % \begin{macrocode} -\sys_if_rand_exist:TF - { \cs_new:Npn \sys_rand_seed: { \tex_the:D \tex_randomseed:D } } +\cs_new_protected:Npn \sys_load_backend:n #1 { - \cs_new:Npn \sys_rand_seed: + \sys_finalise: + \str_if_exist:NTF \c_sys_backend_str + { \__kernel_msg_error:nn { sys } { backend-set } } { - \int_value:w - \__kernel_msg_expandable_error:nnn { kernel } { fp-no-random } - { \sys_rand_seed: } - \c_zero_int + \tl_if_blank:nF {#1} + { \tl_set:Nn \g_@@_backend_tl {#1} } + \@@_load_backend_check:N \g_@@_backend_tl + \str_const:Nx \c_sys_backend_str { \g_@@_backend_tl } + \__kernel_sys_configuration_load:n + { l3backend- \c_sys_backend_str } } } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\sys_gset_rand_seed:n} -% The primitive always assigns the seed globally. -% \begin{macrocode} -\sys_if_rand_exist:TF - { - \cs_new_protected:Npn \sys_gset_rand_seed:n #1 - { \tex_setrandomseed:D \int_eval:n {#1} \exp_stop_f: } - } +\cs_new_protected:Npn \@@_load_backend_check:N #1 { - \cs_new_protected:Npn \sys_gset_rand_seed:n #1 + \sys_if_engine_xetex:TF { - \__kernel_msg_error:nnn { kernel } { fp-no-random } - { \sys_gset_rand_seed:n {#1} } + \str_if_eq:VnF #1 { xdvipdfmx } + { + \__kernel_msg_error:nnxx { sys } { wrong-backend } + #1 { xdvipdfmx } + \tl_gset:Nn #1 { xdvipdfmx } + } + } + { + \sys_if_output_pdf:TF + { + \str_if_eq:VnF #1 { pdfmode } + { + \__kernel_msg_error:nnxx { sys } { wrong-backend } + #1 { pdfmode } + \tl_gset:Nn #1 { pdfmode } + } + } + { + \str_case:VnF #1 + { + { dvipdfmx } { } + { dvips } { } + { dvisvgm } { } + } + { + \__kernel_msg_error:nnxx { sys } { wrong-backend } + #1 { dvips } + \tl_gset:Nn #1 { dvips } + } + } } } % \end{macrocode} +% \end{variable} +% \end{macro} % \end{macro} % -% \subsection{Access to the shell} +% \begin{variable}{\g_@@_debug_bool, \g_@@_deprecation_bool} +% \begin{macrocode} +\bool_new:N \g_@@_debug_bool +\bool_new:N \g_@@_deprecation_bool +% \end{macrocode} +% \end{variable} % -% \begin{variable}{\c_sys_shell_escape_int} -% Expose the engine's shell escape status to the user. +% \begin{macro}{\sys_load_debug:, \sys_load_deprecation:} +% Simple. % \begin{macrocode} -\int_const:Nn \c_sys_shell_escape_int +\cs_new_protected:Npn \sys_load_debug: { - \sys_if_engine_luatex:TF - { - \tex_directlua:D - { tex.sprint(status.shell_escape~or~os.execute()) } - } - { - \tex_shellescape:D - } + \bool_if:NF \g_@@_debug_bool + { \__kernel_sys_configuration_load:n { l3debug } } + \bool_gset_true:N \g_@@_debug_bool + } +\cs_new_protected:Npn \sys_load_deprecation: + { + \bool_if:NF \g_@@_deprecation_bool + { \__kernel_sys_configuration_load:n { l3deprecation } } + \bool_gset_true:N \g_@@_deprecation_bool } % \end{macrocode} -% \end{variable} +% \end{macro} +% +% \subsubsection{Access to the shell} % % \begin{variable}{\l_@@_internal_tl} % \begin{macrocode} @@ -597,21 +539,6 @@ % \end{macro} % \end{macro} % -% \begin{macro}[EXP, pTF]{\sys_if_shell:, \sys_if_shell_unrestricted:, \sys_if_shell_restricted:} -% Performs a check for whether shell escape is enabled. The first set -% of functions returns true if either of restricted or unrestricted -% shell escape is enabled, while the other two sets of functions -% return true in only one of these two cases. -% \begin{macrocode} -\@@_const:nn { sys_if_shell } - { \int_compare_p:nNn \c_sys_shell_escape_int > 0 } -\@@_const:nn { sys_if_shell_unrestricted } - { \int_compare_p:nNn \c_sys_shell_escape_int = 1 } -\@@_const:nn { sys_if_shell_restricted } - { \int_compare_p:nNn \c_sys_shell_escape_int = 2 } -% \end{macrocode} -% \end{macro} -% % \begin{variable}{\c_@@_shell_stream_int} % This is not needed for \LuaTeX{}: shell escape there isn't done using % a \TeX{} interface. @@ -659,117 +586,285 @@ % \end{macrocode} % \end{macro} % -% \subsection{Configurations} +% \subsection{Dynamic (every job) code} % -% \begin{variable}{\g_@@_backend_tl} -% As the backend has to be checked and possibly adjusted, the approach here -% is to create a variable and use that in a one-shot to set a constant. +% \begin{macro}{\sys_everyjob:} +% \begin{macro}{\@@_everyjob:n} +% \begin{variable}{\g_@@_everyjob_tl} % \begin{macrocode} -\tl_new:N \g_@@_backend_tl -\tl_gset:Nx \g_@@_backend_tl +\cs_new_protected:Npn \sys_everyjob: { - \sys_if_engine_xetex:TF - { xdvipdfmx } - { - \sys_if_output_pdf:TF - { pdfmode } - { - \bool_lazy_or:nnTF - { \sys_if_engine_ptex_p: } - { \sys_if_engine_uptex_p: } - { dvipdfmx } - { dvips } - } - } + \tl_use:N \g_@@_everyjob_tl + \tl_gclear:N \g_@@_everyjob_tl } +\cs_new_protected:Npn \@@_everyjob:n #1 + { \tl_gput_right:Nn \g_@@_everyjob_tl {#1} } +\tl_new:N \g_@@_everyjob_tl % \end{macrocode} % \end{variable} +% \end{macro} +% \end{macro} % -% \begin{macro}{\sys_load_backend:n} -% \begin{macro}{\@@_load_backend_check:N} -% \begin{variable}{\c_sys_backend_str} -% Loading the backend code is pretty simply: check that the backend is valid, -% then load it up. +% \subsubsection{The name of the job} +% +% \begin{variable}{\c_sys_jobname_str} +% Inherited from the \LaTeX3 name for the primitive: this needs to +% actually contain the text of the job name rather than the name of +% the primitive, of course. % \begin{macrocode} -\cs_new_protected:Npn \sys_load_backend:n #1 +\@@_everyjob:n + { \str_const:Nx \c_sys_jobname_str { \tex_jobname:D } } +% \end{macrocode} +% \end{variable} +% +% \subsubsection{Time and date} +% +% \begin{variable} +% { +% \c_sys_minute_int, +% \c_sys_hour_int, +% \c_sys_day_int, +% \c_sys_month_int, +% \c_sys_year_int, +% } +% Copies of the information provided by \TeX{}. There is a lot of defensive +% code in package mode: someone may have moved the primitives, and they can +% only be recovered if we have \tn{primitive} and it is working correctly. +% For Ini\TeX{} of course that is all redundant but does no harm. +% \begin{macrocode} +\@@_everyjob:n { - \str_if_exist:NTF \c_sys_backend_str - { \__kernel_msg_error:nnxx { sys } { backend-set } } - { - \tl_if_blank:nF {#1} - { \tl_set:Nn \g_@@_backend_tl {#1} } - \@@_load_backend_check:N \g_@@_backend_tl - \str_const:Nx \c_sys_backend_str { \g_@@_backend_tl } - \__kernel_sys_configuration_load:n - { l3backend- \c_sys_backend_str } - } + \group_begin: + \cs_set:Npn \@@_tmp:w #1 + { + \str_if_eq:eeTF { \cs_meaning:N #1 } { \token_to_str:N #1 } + { #1 } + { + \cs_if_exist:NTF \tex_primitive:D + { + \bool_lazy_and:nnTF + { \sys_if_engine_xetex_p: } + { + \int_compare_p:nNn + { \exp_after:wN \use_none:n \tex_XeTeXrevision:D } + < { 99999 } + } + { 0 } + { \tex_primitive:D #1 } + } + { 0 } + } + } + \int_const:Nn \c_sys_minute_int + { \int_mod:nn { \@@_tmp:w \time } { 60 } } + \int_const:Nn \c_sys_hour_int + { \int_div_truncate:nn { \@@_tmp:w \time } { 60 } } + \int_const:Nn \c_sys_day_int { \@@_tmp:w \day } + \int_const:Nn \c_sys_month_int { \@@_tmp:w \month } + \int_const:Nn \c_sys_year_int { \@@_tmp:w \year } + \group_end: } -\cs_new_protected:Npn \@@_load_backend_check:N #1 +% \end{macrocode} +% \end{variable} +% +% \subsubsection{Random numbers} +% +% \begin{macro}[EXP]{\sys_rand_seed:} +% Unpack the primitive. When random numbers are not available, we +% return zero after an error (and incidentally make sure the number of +% expansions needed is the same as with random numbers available). +% \begin{macrocode} +\@@_everyjob:n { - \sys_if_engine_xetex:TF + \sys_if_rand_exist:TF + { \cs_new:Npn \sys_rand_seed: { \tex_the:D \tex_randomseed:D } } { - \str_if_eq:VnF #1 { xdvipdfmx } + \cs_new:Npn \sys_rand_seed: { - \__kernel_msg_error:nnxx { sys } { wrong-backend } - #1 { xdvipdfmx } - \tl_gset:Nn #1 { xdvipdfmx } + \int_value:w + \__kernel_msg_expandable_error:nnn { kernel } { fp-no-random } + { \sys_rand_seed: } + \c_zero_int } } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\sys_gset_rand_seed:n} +% The primitive always assigns the seed globally. +% \begin{macrocode} +\@@_everyjob:n + { + \sys_if_rand_exist:TF { - \sys_if_output_pdf:TF + \cs_new_protected:Npn \sys_gset_rand_seed:n #1 + { \tex_setrandomseed:D \int_eval:n {#1} \exp_stop_f: } + } + { + \cs_new_protected:Npn \sys_gset_rand_seed:n #1 { - \str_if_eq:VnF #1 { pdfmode } - { - \__kernel_msg_error:nnxx { sys } { wrong-backend } - #1 { pdfmode } - \tl_gset:Nn #1 { pdfmode } - } + \__kernel_msg_error:nnn { kernel } { fp-no-random } + { \sys_gset_rand_seed:n {#1} } } + } + } +% \end{macrocode} +% \end{macro} +% +% \subsubsection{Access to the shell} +% +% \begin{variable}{\c_sys_shell_escape_int} +% Expose the engine's shell escape status to the user. +% \begin{macrocode} +\@@_everyjob:n + { + \int_const:Nn \c_sys_shell_escape_int + { + \sys_if_engine_luatex:TF { - \str_case:VnF #1 - { - { dvipdfmx } { } - { dvips } { } - { dvisvgm } { } - } - { - \__kernel_msg_error:nnxx { sys } { wrong-backend } - #1 { dvips } - \tl_gset:Nn #1 { dvips } - } + \tex_directlua:D + { tex.sprint(status.shell_escape~or~os.execute()) } } + { \tex_shellescape:D } } } % \end{macrocode} % \end{variable} -% \end{macro} +% +% \begin{macro}[EXP, pTF]{\sys_if_shell:, \sys_if_shell_unrestricted:, \sys_if_shell_restricted:} +% Performs a check for whether shell escape is enabled. The first set +% of functions returns true if either of restricted or unrestricted +% shell escape is enabled, while the other two sets of functions +% return true in only one of these two cases. +% \begin{macrocode} +\@@_everyjob:n + { + \@@_const:nn { sys_if_shell } + { \int_compare_p:nNn \c_sys_shell_escape_int > 0 } + \@@_const:nn { sys_if_shell_unrestricted } + { \int_compare_p:nNn \c_sys_shell_escape_int = 1 } + \@@_const:nn { sys_if_shell_restricted } + { \int_compare_p:nNn \c_sys_shell_escape_int = 2 } + } +% \end{macrocode} % \end{macro} % -% \begin{variable}{\g_@@_debug_bool, \g_@@_deprecation_bool} +% \subsubsection{Held over from \pkg{l3file}} +% +% \begin{variable}{\g_file_curr_name_str} % \begin{macrocode} -\bool_new:N \g_@@_debug_bool -\bool_new:N \g_@@_deprecation_bool +\@@_everyjob:n + { \str_gset:Nx \g_file_curr_name_str { \tex_jobname:D } } % \end{macrocode} % \end{variable} % -% \begin{macro}{\sys_load_debug:, \sys_load_deprecation:} -% Simple. +% \subsection{Last-minute code} +% +% \begin{macro}{\sys_finalise:} +% \begin{macro}{\@@_finalise:n} +% \begin{variable}{\g_@@_finalise_tl} +% A simple hook to finalise the system-dependent layer. This is forced by +% the backend loader, which is forced by the main loader, so we do not need +% to include that here. % \begin{macrocode} -\cs_new_protected:Npn \sys_load_debug: +\cs_new_protected:Npn \sys_finalise: { - \bool_if:NF \g_@@_debug_bool - { \__kernel_sys_configuration_load:n { l3debug } } - \bool_gset_true:N \g_@@_debug_bool + \sys_everyjob: + \tl_use:N \g_@@_finalise_tl + \tl_gclear:N \g_@@_finalise_tl } -\cs_new_protected:Npn \sys_load_deprecation: +\cs_new_protected:Npn \@@_finalise:n #1 + { \tl_gput_right:Nn \g_@@_finalise_tl {#1} } +\tl_new:N \g_@@_finalise_tl +% \end{macrocode} +% \end{variable} +% \end{macro} +% \end{macro} +% +% \subsubsection{Detecting the output} +% +% \begin{macro}[pTF, EXP] +% { +% \sys_if_output_dvi:, +% \sys_if_output_pdf: +% } +% \begin{variable}{\c_sys_output_str} +% This is a simple enough concept: the two views here are complementary. +% \begin{macrocode} +\@@_finalise:n { - \bool_if:NF \g_@@_deprecation_bool - { \__kernel_sys_configuration_load:n { l3deprecation } } - \bool_gset_true:N \g_@@_deprecation_bool + \str_const:Nx \c_sys_output_str + { + \int_compare:nNnTF + { \cs_if_exist_use:NF \tex_pdfoutput:D { 0 } } > { 0 } + { pdf } + { dvi } + } + \@@_const:nn { sys_if_output_dvi } + { \str_if_eq_p:Vn \c_sys_output_str { dvi } } + \@@_const:nn { sys_if_output_pdf } + { \str_if_eq_p:Vn \c_sys_output_str { pdf } } } % \end{macrocode} +% \end{variable} % \end{macro} % +% \subsubsection{Configurations} +% +% If there is a class option set, and recognised, we pick it up: these +% will over-ride anything set automatically but will themsevles be +% over-written if there is a package option. +% \begin{macrocode} +\@@_finalise:n + { + \cs_if_exist:NT \@classoptionslist + { + \cs_if_eq:NNF \@classoptionslist \scan_stop: + { + \clist_map_inline:Nn \@classoptionslist + { + \str_case:nnT {#1} + { + { dvipdfmx } + { \tl_gset:Nn \g_@@_backend_tl { dvipdfmx } } + { dvips } + { \tl_gset:Nn \g_@@_backend_tl { dvips } } + { dvisvgm } + { \tl_gset:Nn \g_@@_backend_tl { dvisvgm } } + { pdftex } + { \tl_gset:Nn \g_@@_backend_tl { pdfmode } } + { xetex } + { \tl_gset:Nn \g_@@_backend_tl { xdvipdfmx } } + } + { \clist_remove_all:Nn \@unusedoptionlist {#1} } + } + } + } + } +% \end{macrocode} +% +% \begin{variable}{\g_@@_backend_tl} +% As the backend has to be checked and possibly adjusted, the approach here +% is to create a variable and use that in a one-shot to set a constant. +% \begin{macrocode} +\tl_new:N \g_@@_backend_tl +\@@_finalise:n + { + \tl_gset:Nx \g_@@_backend_tl + { + \sys_if_engine_xetex:TF + { xdvipdfmx } + { + \sys_if_output_pdf:TF + { pdfmode } + { dvips } + } + } + } +% \end{macrocode} +% \end{variable} +% % \begin{macrocode} %</initex|package> % \end{macrocode} |