diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3sys.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3sys.dtx | 454 |
1 files changed, 453 insertions, 1 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx b/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx index 2d791425776..73d4e787f74 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 2019-09-19} +% \date{Released 2019-09-28} % % \maketitle % @@ -126,6 +126,156 @@ % |dvi| or |pdf|. % \end{variable} % +% \section{Platform} +% +% \begin{function}[added = 2018-07-27, EXP, pTF] +% { +% \sys_if_platform_unix:, +% \sys_if_platform_windows: +% } +% \begin{syntax} +% \cs{sys_if_platform_unix:TF} \Arg{true code} \Arg{false code} +% \end{syntax} +% Conditionals which allow platform-specific code to be used. The names +% follow the \Lua{} |os.type()| function, \emph{i.e.}~all Unix-like systems +% are |unix| (including Linux and MacOS). +% \end{function} +% +% \begin{variable}[added = 2018-07-27]{\c_sys_platform_str} +% The current platform given as a lower case string: one of +% |unix|, |windows| or |unknown|. +% \end{variable} +% +% \section{Random numbers} +% +% \begin{function}[added = 2017-05-27, EXP]{\sys_rand_seed:} +% \begin{syntax} +% \cs{sys_rand_seed:} +% \end{syntax} +% Expands to the current value of the engine's random seed, a +% non-negative integer. In engines without random number support this +% expands to $0$. +% \end{function} +% +% \begin{function}[added = 2017-05-27]{\sys_gset_rand_seed:n} +% \begin{syntax} +% \cs{sys_gset_rand_seed:n} \Arg{intexpr} +% \end{syntax} +% Globally sets the seed for the engine's pseudo-random number +% generator to the \meta{integer expression}. This random seed +% affects all \cs[no-index]{\ldots{}_rand} functions (such as +% \cs{int_rand:nn} or \cs{clist_rand_item:n}) as well as other +% packages relying on the engine's random number generator. In +% engines without random number support this produces an error. +% \begin{texnote} +% While a $32$-bit (signed) integer can be given as a seed, only the +% absolute value is used and any number beyond $2^{28}$ is divided +% by an appropriate power of~$2$. We recommend using an integer in +% $[0,2^{28}-1]$. +% \end{texnote} +% \end{function} +% +% \section{Access to the shell} +% +% \begin{function}[noTF, added = 2019-09-20] +% {\sys_get_shell:nnN} +% \begin{syntax} +% \cs{sys_get_shell:nnN} \Arg{shell~command} \Arg{setup} \meta{tl~var} +% \cs{sys_get_shell:nnNTF} \Arg{shell~command} \Arg{setup} \meta{tl~var} \Arg{true code} \Arg{false code} +% \end{syntax} +% Defines \meta{tl} to the text returned by the \meta{shell command}. +% The \meta{shell command} is converted to a string using +% \cs{tl_to_str:n}. Category codes may need to be set appropriately +% via the \meta{setup} argument, which is run just before running the +% \meta{shell command} (in a group). +% If shell escape is disabled, the \meta{tl~var} will be set to +% \cs{q_no_value} in the non-branching version. +% Note that quote characters (|"|) \emph{cannot} be used inside the +% \meta{shell command}. The \cs{sys_get_shell:nnNTF} conditional +% returns \texttt{true} if the shell is available and no quote is +% detected, and \texttt{false} otherwise. +% \end{function} +% +% \begin{variable}[added = 2017-05-27]{\c_sys_shell_escape_int} +% This variable exposes the internal triple of the shell escape +% status. The possible values are +% \begin{description} +% \item[0] Shell escape is disabled +% \item[1] Unrestricted shell escape is enabled +% \item[2] Restricted shell escape is enabled +% \end{description} +% \end{variable} +% +% \begin{function}[added = 2017-05-27, EXP, pTF]{\sys_if_shell:} +% \begin{syntax} +% \cs{sys_if_shell_p:} +% \cs{sys_if_shell:TF} \Arg{true code} \Arg{false code} +% \end{syntax} +% Performs a check for whether shell escape is enabled. This +% returns true if either of restricted or unrestricted shell escape +% is enabled. +% \end{function} +% +% \begin{function}[added = 2017-05-27, EXP, pTF]{\sys_if_shell_unrestricted:} +% \begin{syntax} +% \cs{sys_if_shell_unrestricted_p:} +% \cs{sys_if_shell_unrestricted:TF} \Arg{true code} \Arg{false code} +% \end{syntax} +% Performs a check for whether \emph{unrestricted} shell escape is +% enabled. +% \end{function} +% +% \begin{function}[added = 2017-05-27, EXP, pTF]{\sys_if_shell_restricted:} +% \begin{syntax} +% \cs{sys_if_shell_restricted_p:} +% \cs{sys_if_shell_restricted:TF} \Arg{true code} \Arg{false code} +% \end{syntax} +% Performs a check for whether \emph{restricted} shell escape is +% enabled. This returns false if unrestricted shell escape is +% enabled. Unrestricted shell escape is not considered a superset +% of restricted shell escape in this case. To find whether any +% shell escape is enabled use \cs{sys_if_shell:}. +% \end{function} +% +% \begin{function}[added = 2017-05-27]{\sys_shell_now:n, \sys_shell_now:x} +% \begin{syntax} +% \cs{sys_shell_now:n} \Arg{tokens} +% \end{syntax} +% Execute \meta{tokens} through shell escape immediately. +% \end{function} +% +% \begin{function}[added = 2017-05-27]{\sys_shell_shipout:n, \sys_shell_shipout:x} +% \begin{syntax} +% \cs{sys_shell_shipout:n} \Arg{tokens} +% \end{syntax} +% Execute \meta{tokens} through shell escape at shipout. +% \end{function} +% +% \subsection{Loading configuration data} +% +% \begin{function}[added = 2019-09-12]{\sys_load_backend:n} +% \begin{syntax} +% \cs{sys_load_backend:n} \Arg{backend} +% \end{syntax} +% Loads the additional configuration file needed for backend support. +% If the \meta{backend} is empty, the standard backend for the engine in +% use will be loaded. This command may only be used once. +% \end{function} +% +% \begin{variable}{\c_sys_backend_str} +% Set to the name of the backend in use by \cs{sys_load_backend:n} when +% issued. +% \end{variable} +% +% \begin{function}[added = 2019-09-12]{\sys_load_debug:, \sys_load_deprecation:} +% \begin{syntax} +% \cs{sys_load_debug:} +% \cs{sys_load_deprecation:} +% \end{syntax} +% Load the additional configuration files for debugging support and rolling +% back deprecations, respectively. +% \end{function} +% % \end{documentation} % % \begin{implementation} @@ -318,6 +468,308 @@ % \end{macrocode} % \end{macro} % +% \subsection{Platform} +% +% \begin{macro}[pTF]{\sys_if_platform_unix:, \sys_if_platform_windows:} +% \begin{variable}{\c_sys_platform_str} +% Setting these up requires the file module (file lookup), so is actually +% implemented there. +% \end{variable} +% \end{macro} +% +% \subsection{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} +\sys_if_rand_exist:TF + { \cs_new:Npn \sys_rand_seed: { \tex_the:D \tex_randomseed:D } } + { + \cs_new:Npn \sys_rand_seed: + { + \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} +\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 \sys_gset_rand_seed:n #1 + { + \__kernel_msg_error:nnn { kernel } { fp-no-random } + { \sys_gset_rand_seed:n {#1} } + } + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Access to the shell} +% +% \begin{variable}{\c_sys_shell_escape_int} +% Expose the engine's shell escape status to the user. +% \begin{macrocode} +\int_const:Nn \c_sys_shell_escape_int + { + \sys_if_engine_luatex:TF + { + \tex_directlua:D + { tex.sprint(status.shell_escape~or~os.execute()) } + } + { + \tex_shellescape:D + } + } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_internal_tl} +% \begin{macrocode} +\tl_new:N \l_@@_internal_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\c_@@_marker_tl} +% The same idea as the marker for rescanning token lists. +% \begin{macrocode} +\tl_const:Nx \c_@@_marker_tl { : \token_to_str:N : } +% \end{macrocode} +% \end{variable} +% +% \begin{macro}[TF]{\sys_get_shell:nnN} +% \begin{macro}{\sys_get_shell:nnN,\@@_get:nnN,\@@_get_do:Nw} +% Setting using a shell is at this level just a slightly specialised file +% operation, with an additional check for quotes, as these are not supported. +% \begin{macrocode} +\cs_new_protected:Npn \sys_get_shell:nnN #1#2#3 + { + \sys_get_shell:nnNF {#1} {#2} #3 + { \tl_set:Nn #3 { \q_no_value } } + } +\prg_new_protected_conditional:Npnn \sys_get_shell:nnN #1#2#3 { T , F , TF } + { + \sys_if_shell:TF + { \exp_args:No \@@_get:nnN { \tl_to_str:n {#1} } {#2} #3 } + { \prg_return_false: } + } +\cs_new_protected:Npn \@@_get:nnN #1#2#3 + { + \tl_if_in:nnTF {#1} { " } + { + \__kernel_msg_error:nnx + { kernel } { quote-in-shell } {#1} + \prg_return_false: + } + { + \group_begin: + \if_false: { \fi: + \int_set_eq:NN \tex_tracingnesting:D \c_zero_int + \exp_args:No \tex_everyeof:D { \c_@@_marker_tl } + #2 \scan_stop: + \exp_after:wN \@@_get_do:Nw + \exp_after:wN #3 + \exp_after:wN \prg_do_nothing: + \tex_input:D | "#1" \scan_stop: + \if_false: } \fi: + \prg_return_true: + } + } +\exp_args:Nno \use:nn + { \cs_new_protected:Npn \@@_get_do:Nw #1#2 } + { \c_@@_marker_tl } + { + \group_end: + \tl_set:No #1 {#2} + } +% \end{macrocode} +% \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. +% \begin{macrocode} +\sys_if_engine_luatex:F + { \int_const:Nn \c_@@_shell_stream_int { 18 } } +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\sys_shell_now:n} +% Execute commands through shell escape immediately. +% \begin{macrocode} +\sys_if_engine_luatex:TF + { + \cs_new_protected:Npn \sys_shell_now:n #1 + { + \lua_now:e + { os.execute(" \lua_escape:e { \tl_to_str: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 } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\sys_shell_shipout:n} +% Execute commands through shell escape at shipout. +% \begin{macrocode} +\sys_if_engine_luatex:TF + { + \cs_new_protected:Npn \sys_shell_shipout:n #1 + { + \lua_shipout_e:n + { os.execute(" \lua_escape:e { \tl_to_str:n {#1} } ") } + } + } + { + \cs_new_protected:Npn \sys_shell_shipout:n #1 + { \iow_shipout:Nn \c_@@_shell_stream_int {#1} } + } +\cs_generate_variant:Nn \sys_shell_shipout:n { x } +% \end{macrocode} +% \end{macro} +% +% \subsection{Configurations} +% +% \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 +\tl_gset:Nx \g_@@_backend_tl + { + \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 } + } + } + } +% \end{macrocode} +% \end{variable} +% +% \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} +\cs_new_protected:Npn \sys_load_backend:n #1 + { + \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 } + } + } +\cs_new_protected:Npn \@@_load_backend_check:N #1 + { + \sys_if_engine_xetex:TF + { + \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} +% +% \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{macro}{\sys_load_debug:, \sys_load_deprecation:} +% Simple. +% \begin{macrocode} +\cs_new_protected:Npn \sys_load_debug: + { + \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{macro} +% % \begin{macrocode} %</initex|package> % \end{macrocode} |