20 用expl3定义的命令读取二维 sequence 中的某个元素,若这个元素为我设置的文件名,此时将其应用于 \includegraphics{} 中报错,展开也没用

发布于 2024-12-20 16:47:46

如题,我定义了个数组:

\clist_set:Nn \l__skyrmion_tmp_clist
  { example-image-a/yyyy1-mm1-dd1,example-image-b/yyyy2-mm2-dd2  }

很明显,一级分隔符是 clist 默认的逗号,二维分隔符是 /,为了继续拆分,我把
\clist_item:Nn \l__skyrmion_tmp_clist {#1} 展开并丢到 \seq_set_split:Nnn 中处理

\seq_set_split:Nne \l__skyrmion_tmp_seq {/}
  { \clist_item:Nn \l__skyrmion_tmp_clist { 1 } }

理所当然,此时 \seq_item:Nn \l__skyrmion_tmp_seq {1} 输出为 example-image-a,众所周知,这是 mwe 包的测试图像A.


现在,我要把这个读取数组封一个命令:

\cs_new_protected_nopar:Npn \__skyrmion_process_array_aux:nn #1#2
  {
    \clist_set:Nn \l__skyrmion_tmp_clist {#1}
    \seq_set_split:Nne \l__skyrmion_tmp_seq {/}
      { \clist_item:Nn \l__skyrmion_tmp_clist {#2} }
    \seq_item:Nn \l__skyrmion_tmp_seq {1}
    \seq_clear:N \l__skyrmion_tmp_seq
    \clist_clear:N \l__skyrmion_tmp_clist
  }

参数 #1 是接收数组,#2 是指定要数组第几个元素的 / 左面的元素. 此时

\__skyrmion_process_array_aux:nn
  { example-image-a/yyyy1-mm1-dd1,example-image-b/yyyy1-mm1-dd1 }{1},~

\__skyrmion_process_array_aux:nn
  { example-image-a/yyyy1-mm1-dd1,example-image-b/yyyy2-mm2-dd2 }{2}

很正常地输出了 example-image-a, example-image-b,于是我把其中一个应用到 \includegraphics

\includegraphics [ width = 2cm ]
  { \__skyrmion_process_array_aux:nn
  { example-image-a/yyyy1-mm1-dd1,example-image-b/yyyy2-mm2-dd2 }{2} }

很明显,此时会报错,于是我想到了展开,并封到一个 token list 中:

\tl_set:Ne \l__skyrmion_tmp_tl
  {
    \__skyrmion_process_array_aux:nn
      { example-image-a/yyyy1-mm1-dd1,example-image-b/yyyy2-mm2-dd2 }{2}
  }

此时再使用 \includegraphics [ width = 2cm ] { \l__skyrmion_tmp_tl }:依旧报错🥵

请问如何解决?(\exp_args:Ne 我也试过了,没用...)


报错信息:

Missing endcsname inserted.
<to be read again>
Use of ??? doesn't match its definition.
<argument> ???
Missing endcsname inserted.
<to be read again>
Use of ??? doesn't match its definition.
<argument> ???
Missing endcsname inserted.
<to be read again>
Use of ??? doesn't match its definition.
<argument> ???
File `\__skyrmion_process_array_aux:nn {example-image-a/yyyy1-mm1-dd1,example-image-b/yyyy2-mm2-dd2}{2}' not found.

根据最后一条,我认为就是展开的问题,但是我已经展开了...


完整的 MWE 如下,报错那一行 \includegraphics 被我注释掉了:

\documentclass{article}

\usepackage{graphicx}

\begin{document}

\ExplSyntaxOn

\clist_set:Nn \l__skyrmion_tmp_clist
  { example-image-a/yyyy1-mm1-dd1,example-image-b/yyyy2-mm2-dd2  }
\seq_set_split:Nne \l__skyrmion_tmp_seq {/}
  { \clist_item:Nn \l__skyrmion_tmp_clist { 1 } }
\seq_item:Nn \l__skyrmion_tmp_seq {1}

\includegraphics [ width = 2cm ] { \seq_item:Nn \l__skyrmion_tmp_seq {1} }

\ExplSyntaxOff

\par 

\ExplSyntaxOn
\cs_new_protected_nopar:Npn \__skyrmion_process_array_aux:nn #1#2
  {
    \clist_set:Nn \l__skyrmion_tmp_clist {#1}
    \seq_set_split:Nne \l__skyrmion_tmp_seq {/}
      { \clist_item:Nn \l__skyrmion_tmp_clist {#2} }
    \seq_item:Nn \l__skyrmion_tmp_seq {1}
    \seq_clear:N \l__skyrmion_tmp_seq
    \clist_clear:N \l__skyrmion_tmp_clist
  }

\__skyrmion_process_array_aux:nn
  { example-image-a/yyyy1-mm1-dd1,example-image-b/yyyy1-mm1-dd1 }{1},~

\__skyrmion_process_array_aux:nn
  { example-image-a/yyyy1-mm1-dd1,example-image-b/yyyy2-mm2-dd2 }{2}

\tl_set:Ne \l__skyrmion_tmp_tl
  {
    \__skyrmion_process_array_aux:nn
      { example-image-a/yyyy1-mm1-dd1,example-image-b/yyyy2-mm2-dd2 }{2}
  }

\par

\l__skyrmion_tmp_tl

% \includegraphics [ width = 2cm ] { \l__skyrmion_tmp_tl }

\ExplSyntaxOff

\end{document}

查看更多

关注者
0
被浏览
128
鱼香肉丝没有鱼先生
脾气不好,别来惹我!!!

首先需要明白的是 tex/expl3 是一门宏语言, 没有函数, 也没有返回值, 有的只是宏展开

  1. 先说点题外话
\tl_set:Ne \l__skyrmion_tmp_tl
  {
    \__skyrmion_process_array_aux:nn
      { example-image-a/yyyy1-mm1-dd1,example-image-b/yyyy2-mm2-dd2 }{2}
  }

e 展开了个寂寞, \cs_new_protected_nopar:Npn \__skyrmion_process_array_aux:nn

  1. 你的需求是将 \__skyrmion_process_array_aux:nn 的运行结果交给变量 \l__skyrmion_tmp_tl, 你可以使用 \tl_analysis_log:N \l__skyrmion_tmp_tl 看看它究竟是个什么东西. (一堆未展开的东西)
  2. 要想在 expl3 中得到所谓的函数展开值, 建议将其声明在参数列表中
\cs_new_protected_nopar:Npn \__skyrmion_process_array_aux:nnN #1#2#3
  {
    \clist_set:Nn \l__skyrmion_tmp_clist {#1}
    \seq_set_split:Nne \l__skyrmion_tmp_seq {/}
      { \clist_item:Nn \l__skyrmion_tmp_clist {#2} }
    % here ^_^
    \tl_set:Ne #3 
      { \seq_item:Nn \l__skyrmion_tmp_seq {1} }
    \seq_clear:N \l__skyrmion_tmp_seq
    \clist_clear:N \l__skyrmion_tmp_clist
  }

使用

\__skyrmion_process_array_aux:nnN
  { example-image-a/yyyy1-mm1-dd1,example-image-b/yyyy2-mm2-dd2 }{2}
\l__skyrmion_tmp_tl
\includegraphics [ width = 2cm ] { \l__skyrmion_tmp_tl }

.

1 个回答

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览