使用 LaTeX 3 进行 Shell 逃逸

使用 LaTeX 3 进行 Shell 逃逸

\write18如果有的话,LaTeX 3 相当于什么?我想lilypond从我的 TeX 文档中调用。

答案1

更新

自 2013 年以来,情况发生了变化,现在已完全支持 shell 转义expl3。手册中的相关部分(截至 2021 年)目前为 10.7。

获取命令的输出

\sys_get_shell:nnN
\sys_get_shell:nnNTF

对于这两个函数,第一个n参数都是不带引号的 shell 命令("会自动为其加上引号;标准限制适用,即"不能出现在此参数中)。第二个参数用于应用于 shell 命令中的标记的“设置”(例如,类别代码更改)。第三个参数应为标记列表变量。在第二个函数中,T如果命令格式正确且启用了 shell 转义,则返回参数;否则F返回参数。TF应用的通常约定。标记列表变量将包含 shell 命令的输出。如果禁用了 shell 转义,变量将包含\q_no_value

这是 `\input{|"..."} 的界面

检查 shell 转义状态

\c_sys_shell_escape_int

设置为01或者2在作业的开始处,具有通常的含义:0表示 shell 转义被禁用;1不受限制;2` 表示受到限制。

\sys_if_shell_p:
\sys_if_shell:TF
\sys_if_shell_unrestricted_p:
\sys_if_shell_unrestricted:TF
\sys_if_shell_restricted_p:
\sys_if_shell_restricted:TF

是用于测试 shell 转义状态的谓词和条件。

执行 shell 命令

\sys_shell_now:n
\sys_shell_now:x

将执行作为参数传递的命令,该x版本将对参数进行完全扩展。立即执行。

这是\immediate\write18{...}

\sys_shell_shipout:n
\sys_shell_shipout:x

将在下一次输出时执行 shell 命令(例如,如果要执行的命令需要页码作为输入,则很有用)。

这是 的界面\write18

原始答案

目前 LaTeX3 中没有处理该问题的函数\write18;可以通过以下方式获得

\RequirePackage{expl3,pdftexcmds}
\ExplSyntaxOn
\int_const:Nn \c_tobi_eighteen_int { 18 }
\int_const:Nn \c_tobi_shell_escape_int { \int_eval:n { \use:c { pdf@shellescape } } }
\cs_new_protected:Npn \tobi_system_exec_now:n #1
 {
  \int_compare:nT { \c_tobi_shell_escape_int > 0 }
   { \iow_now:Nn \c_tobi_eighteen_int { #1 } }
 }
\cs_new_protected:Npn \tobi_system_exec_shipout:n #1
 {
  \int_compare:nT { \c_tobi_shell_escape_int > 0 }
   {  \iow_shipout:Nn \c_tobi_eighteen_int { #1 } }
 }
\cs_generate_variant:Nn \tobi_system_exec_now:n { x }
\cs_generate_variant:Nn \tobi_system_exec_shipout:n { x }

%% Examples
\tobi_system_exec_now:n { ls }
\tl_set:Nn \l_tmpa_tl { ls }
\tobi_system_exec_now:x { \l_tmpa_tl }

您可能想要添加消息来告知当 shell 转义被禁用时事情出错了;或者只是删除它\int_compare:nT

我使用tobi前缀是因为使用\system可能不是一个好主意(你知道,我不想在聊天中被约瑟夫打耳光)。

答案2

自从这个问题得到解答以来,LaTeX3 已经发展起来了。请参阅 上的第 10.7 节访问 shell interface3.pdf。特别是,

\immediate\write18

被替换为

\sys_shell_now:n

及其:x变体。

相关内容