我想要\input"|..."
调用一个 shell 命令并将其输出作为 LaTeX 代码使用。
具体来说,我想编写类似以下内容的代码:
\expandableShellCmdProtectCmdArgsWithBackslashes{echo}{2(3)}
并让它使用以下内容调用 shell:
echo \2\(\3\)
使用反斜杠转义所有“arg”字符。
原因是转义 shell 特殊字符,例如(
。
期望的结果是echo
打印2(3)
并作为 LaTeX 输入使用。
\str_map_inline:nn
下面通过+进行的尝试\c_backslash_str
失败了,在调用 shell 之前我期望反斜杠的所有位置都出现了奇怪的倾斜双引号符号,而且实际执行的 shell 命令不包含大多数所需的输入。
如何在\input
命令的每个字符前添加反斜杠?
\documentclass[11pt]{article}
\begin{document}
\makeatletter
\newcommand{\expandableShellCmd}[1]{ \@@input"|#1"} % \input is not expandable
\makeatother
\ExplSyntaxOn
\NewDocumentCommand{\protectWithBackslashes}{m} { % prepends every character of the input with a backslash
\str_map_inline:nn{#1}{\c_backslash_str##1}
}
\NewDocumentCommand{\expandableShellCmdProtectCmdArgsWithBackslashes}{mm} {% shell command, args
% Pass the input string as a cmd to the shell, but prepend each char in the args with a backslash
\exp_args:Ne\expandableShellCmd{#1~\protectWithBackslashes{#2}} % Fully expand the argument before invoking the shell
}
\ExplSyntaxOff
\expandableShellCmdProtectCmdArgsWithBackslashes{echo}{2(3)} % want to run in shell "echo \2\(\3\)" which produces output "2(3)"
% However, this produces PDF output:
% “2“(“3“)”
% and the console output shows that the shell command executed was (without quotes) "|echo "
\end{document}
答案1
用 定义的命令\NewDocumentCommand
不会受到e
-expansion 的影响;也\str_map_inline:nn
具有相同的特性,因此调用\exp_args:Ne
根本不会执行任何操作。
而且我认为您不需要担心可扩展性。
\documentclass{article}
\ExplSyntaxOn
\tl_new:N \l_fink_shell_output_tl
\NewDocumentCommand{\DoShellCommand}{O{}m}
{
\fink_shell_do:nn { #1 } { #2 }
}
\NewExpandableDocumentCommand{\protectWithBackslashes}{m}
{ % prepends every character of the input with a backslash
\fink_shell_addbackslash:n { #1 }
}
\cs_new_protected:Nn \fink_shell_do:nn
{
\sys_get_shell:nnN { #2 } { #1 } \l_fink_shell_output_tl
\tl_use:N \l_fink_shell_output_tl
}
\cs_generate_variant:Nn \fink_shell_do:nn { ne }
\cs_new:Nn \fink_shell_addbackslash:n
{
\str_map_function:nN { #1 } \__fink_shell_addbackslash:n
}
\cs_new:Nn \__fink_shell_addbackslash:n
{
\c_backslash_str #1
}
\NewDocumentCommand{\DoShellCmdProtectCmdArgsWithBackslashes}{mm}
{% shell command, args
% Pass the input string as a cmd to the shell, but prepend each char in the args with a backslash
\fink_shell_do:ne {} {#1~\fink_shell_addbackslash:n {#2}}
% Fully expand the argument before invoking the shell
}
\ExplSyntaxOff
\begin{document}
\DoShellCmdProtectCmdArgsWithBackslashes{echo}{2(3)}
\end{document}
日志文件有
(|echo \2\(\3\))