Skip to content

Commit

Permalink
Add macro interface for l3sys-query
Browse files Browse the repository at this point in the history
  • Loading branch information
josephwright committed Mar 6, 2024
1 parent 0d8f7c3 commit d60966a
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 0 deletions.
3 changes: 3 additions & 0 deletions l3kernel/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ this project uses date-based 'snapshot' version identifiers.

## [Unreleased]

### Added
- Macro interface for `l3sys-query`

### Changed
- Require that `expl3` is loaded at top level in generic mode

Expand Down
135 changes: 135 additions & 0 deletions l3kernel/l3sys.dtx
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,54 @@
% Execute \meta{tokens} through shell escape at shipout.
% \end{function}
%
% \section{System queries}
%
% Some queries can be made about the file system, etc., without needing to
% use unrestricted shell escape. This is carried out using the script
% \texttt{l3sys-query}, which is documented separately. The wrappers here
% use this script, if available, to obtain system information that is
% not directly available within the \TeX{} run. Note that if restricted
% shell escape is disabled, no results can be obtained.
%
% \begin{function}[added = 2024-03-06]
% {\sys_get_query:nN, \sys_get_query:nnN, \sys_get_query:nnnN}
% \begin{syntax}
% \cs{sys_get_query:nN} \Arg{cmd} \Arg{str var}
% \cs{sys_get_query:nnN} \Arg{cmd} \Arg{spec} \Arg{str var}
% \cs{sys_get_query:nnnN} \Arg{cmd} \Arg{options} \Arg{spec} \Arg{str var}
% \end{syntax}
% Sets the \meta{str var} to the information returned by the
% \texttt{l3sys-query} \meta{cmd}, potentially supplying the \meta{options}
% and \meta{spec} to the query call. The valid \meta{cmd} names are at present
% \begin{itemize}
% \item \texttt{pwd} Returns the present working directory
% \item \texttt{ls} Returns a directory listing, using the \meta{spec} to
% select files and applying the \meta{options} if given
% \end{itemize}
% The \meta{spec} should be a file glob and will automatically be passed to
% the script without shell expansion. In a glob is needed within the
% \meta{options}, this will need to be protected from shell expansion
% using |'| tokens.
%
% If more than one line of text is returned by the \meta{cmd}, these will be
% separated by character~13 (|^^M|) tokens of category code~12. In most
% cases, \cs{sys_split_query:nnnN} should be preferred when multi-line
% output is expected.
% \end{function}
%
% \begin{function}[added = 2024-03-06]
% {\sys_split_query:nN, \sys_split_query:nnN, \sys_split_query:nnnN}
% \begin{syntax}
% \cs{sys_split_query:nN} \Arg{cmd} \Arg{seq}
% \cs{sys_split_query:nnN} \Arg{cmd} \Arg{spec} \Arg{seq}
% \cs{sys_split_query:nnnN} \Arg{cmd} \Arg{options} \Arg{spec} \Arg{seq}
% \end{syntax}
% Works as described for \cs{sys_split_query:nnnN}, but sets the \meta{seq}
% to contain one (string) entry for each line returned by \texttt{l3sys-query}.
% This function should therefore be preferred where multi-line return is
% expected, e.g.~for the \texttt{ls} command.
% \end{function}
%
% \section{Loading configuration data}
%
% \begin{function}[added = 2019-09-12]{\sys_load_backend:n}
Expand Down Expand Up @@ -390,6 +438,12 @@
%<*tex>
% \end{macrocode}
%
% \begin{macro}{\l_@@_tmp_tl}
% \begin{macrocode}
\tl_new:N \l_@@_tmp_tl
% \end{macrocode}
% \end{macro}
%
% \subsubsection{Detecting the engine}
%
% \begin{macro}{\@@_const:nn}
Expand Down Expand Up @@ -1083,6 +1137,87 @@ end
% \end{macrocode}
% \end{macro}
%
% \subsection{System queries}
%
% \begin{macro}{\sys_get_query:nN}
% \begin{macro}{\sys_get_query:nnN}
% \begin{macro}{\sys_get_query:nnnN, \@@_get_query:nnnN, \@@_get_query:neeN}
% Calling the query system is quite straight-forward: most of the effort is
% in making the read-back catcode-safe. We also want to trim off the trailing
% |^^M| from the last line.
% \begin{macrocode}
\cs_new_protected:Npn \sys_get_query:nN #1#2
{ \sys_query:nnnN {#1} { } { } #2 }
\cs_new_protected:Npn \sys_get_query:nnN #1#2#3
{ \sys_query:nnnN {#1} { } {#2} #3 }
\cs_new_protected:Npn \sys_get_query:nnnN #1#2#3#4
{
\str_clear:N #4
\@@_get_query:neeN {#1}
{ \tl_if_blank:nF {#2} { \exp_not:n { ~ #2 } } }
{ \tl_if_blank:nF {#3} { \exp_not:n { ~ '#3' } } }
#4
}
\cs_new_protected:Npe \@@_get_query:nnnN #1#2#3#4
{
\sys_if_shell:T
{
\exp_not:N \sys_get_shell:nnN
{ l3sys-query~#1 #2 #3 }
{
\ExplSyntaxOff
\char_set_catcode_other:N \exp_not:N \{
\char_set_catcode_other:N \exp_not:N \}
\char_set_catcode_other:N \exp_not:N \\
\char_set_catcode_other:N \exp_not:N \#
\char_set_catcode_other:N \exp_not:N \^
\char_set_catcode_other:N \exp_not:N \~
\char_set_catcode_other:N \exp_not:N \%
\char_set_catcode_other:n { 13 }
\tex_endlinechar:D 13 \scan_stop:
}
\exp_not:N \l_@@_tmp_tl
\exp_not:N \tl_if_empty:NF \exp_not:N \l_@@_tmp_tl
{
\exp_not:N \exp_after:wN \exp_not:N \@@_get_query:Nw
\exp_not:N \exp_after:wN #4
\exp_not:N \l_@@_tmp_tl \exp_not:N \q_stop
}
}
}
\cs_generate_variant:Nn \@@_get_query:nnnN { nee }
\use:e
{
\cs_new_protected:Npn \exp_not:N \@@_query:Nw
#1#2 \char_generate:nn { 13 } { 12 } \exp_not:N \q_stop
}
{ \str_set:Nn #1 {#2} }
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\sys_split_query:nN}
% \begin{macro}{\sys_split_query:nnN}
% \begin{macro}{\sys_split_query:nnnN}
% A wrapper for convenience.
% \begin{macrocode}
\cs_new_protected:Npn \sys_split_query:nN #1#2
{ \sys_split_query:nnnN {#1} { } { } #2 }
\cs_new_protected:Npn \sys_split_query:nnN #1#2#3
{ \sys_split_query:nnnN {#1} { } {#2} #3 }
\cs_new_protected:Npe \sys_split_query:nnnN #1#2#3#4
{
\seq_clear:N #4
\sys_get_query:nnnN {#1} {#2} {#3} \exp_not:N \l_@@_tmp_tl
\seq_set_split:NnV #4 { \char_generate:nn { 13 } { 12 } }
\exp_not:N \l_@@_tmp_tl
}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \subsubsection{Held over from \pkg{l3file}}
%
% \begin{variable}{\g_file_curr_name_str}
Expand Down

0 comments on commit d60966a

Please sign in to comment.