编辑

编辑

再会,

我想编写一个宏(使用 Latex3/expl3)来发布图片并可以为生成的标签/标题等获取几个键值参数。我已经找到了可以做到这一点的代码,但传递生成的标签不起作用。

它从这个线程开始: \ref 使用宏作为参数

这是采用通用键值参数来放置图的宏代码(如果我使用带有硬编码标签的 \addpic 则有效):

%usage example
% \addpic{
  % width=0.3,
  % image=example-image,
  % caption={This is an example image, and a comma in the caption},
  % label=one,
% }

% \addpic{
  % placement=bp,
  % width=0.2,
  % options={angle=90},
  % image=example-image-a,
  % caption=Rotated image,
  % shortcaption=In the text the image is rotated!,
  %}


\ExplSyntaxOn

% the user level command
\NewDocumentCommand{\addpic}{m}
 {
  \group_begin: % localize the changes to the variables
  \simonson_pic:n { #1 }
  \group_end:
 }

% the key-value interface
\keys_define:nn { simonson/pic }
 {
  placement .tl_set:N = \l_simonson_pic_placement_tl,
  placement .initial:n = htp,
  width .tl_set:N = \l_simonson_pic_width_tl,
  width .initial:n = 1,
  options .tl_set:N = \l_simonson_pic_options_tl,
  image .tl_set:N = \l_simonson_pic_image_tl,
  caption .tl_set:N = \l_simonson_pic_caption_tl,
  shortcaption .tl_set:N = \l_simonson_pic_shortcaption_tl,
  label .tl_set:N = \l_simonson_pic_label_tl,
 }

% the main command
\cs_new_protected:Nn \simonson_pic:n
 {
  % set the keys from the argument
  \keys_set:nn { simonson/pic } { #1 }
  % start the figure environment
  \__simonson_start_figure:V \l_simonson_pic_placement_tl
  \centering
  % include the image
  \__simonson_pic_image:VVV
    \l_simonson_pic_width_tl % the text width fraction
    \l_simonson_pic_options_tl % other options
    \l_simonson_pic_image_tl % the image name
  % the caption
  \tl_if_empty:NTF \l_simonson_pic_shortcaption_tl
   {
    \caption{\l_simonson_pic_caption_tl}
   }
   {
    \caption[\l_simonson_pic_shortcaption_tl]{\l_simonson_pic_caption_tl}
   }
   % the label
     In \ addpics \ macro:\ label=\l_simonson_pic_label_tl %for test(my code)
   \tl_if_empty:NF \l_simonson_pic_label_tl
    {
     \label{\l_simonson_pic_label_tl}
    }
   % end the figure environment

   %### %for parser to ignore
   \end{figure}
   %###
}

% syntactic sugar: we want some token lists to be expanded before usage
\cs_new_protected:Nn \__simonson_start_figure:n
 {
  \begin{figure}[#1]
 }
\cs_generate_variant:Nn \__simonson_start_figure:n { V }

\cs_new_protected:Nn \__simonson_pic_image:nnn
 {
  \includegraphics[width=#1\textwidth,#2]{#3}
 }
\cs_generate_variant:Nn \__simonson_pic_image:nnn { VVV }

\ExplSyntaxOff

关键要求是生成标签的代码位于一个地方(作为宏),因为我需要引用生成的标签,并且在使用多个键值参数引用时将使用相同的代码。

以下是 egreg 在第一个主题中提出的建议(尽管我并没有在那里指出最终目标):

    \documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn
\keys_define:nn { strider/label }
 {
  Re        .tl_set:N = \l_strider_label_Re_tl, 
  DOF       .tl_set:N = \l_strider_label_DOF_tl,
  statsName .tl_set:N = \l_strider_label_statsName_tl,
  Re        .value_required:n = true,
  DOF       .value_required:n = true,
  statsName .value_required:n = true,
 }

\NewDocumentCommand{\keyref}{m}
 {
  \strider_label:Nn \ref { #1 }
 }
\NewDocumentCommand{\keylabel}{m}
 {
  \strider_label:Nn \label { #1 }
 }

\cs_new_protected:Nn \strider_label:Nn
 {
  \keys_set:nn { strider/label } { #2 }
  #1 % will be \label or \ref
   {
    fig \c_colon_str 
    \tl_item:Nn \l_strider_label_statsName_tl { 1 }
    \tl_item:Nn \l_strider_label_statsName_tl { 2 }
    \tl_item:Nn \l_strider_label_statsName_tl { 3 }
    Re \l_strider_label_Re_tl DOF \l_strider_label_DOF_tl
   }
 }
\ExplSyntaxOff

\begin{document}

\section{X}
\keylabel{statsName=Strouhal,DOF=4M, Re=50} % just to experiment

This gives a number: \keyref{statsName=Strouhal,DOF=4M, Re=50} (should be 1)

\end{document}

这确实有效,尽管不知道如何使用 \keylabel 将标签作为参数传递给 \addpic。 \addpic 宏将很少在文档级别使用(而不是在生成标签和标题的其他宏中使用),因此我希望尽可能保持它的通用性。文档级宏:示例调用:

\myplotFF{file={\plotsPathReFifty/StrouhalNumber},Re=50,DOF=4M, statsName=Drag}

宏:

\keys_define:nn{myPlot}{ 
Re .tl_set:N = \l_myPlot_Re_tl, 
DOF .tl_set:N = \l_myPlot_DOF_tl,
statsName .tl_set:N = \l_myPlot_statsName_tl,
file .tl_set:N = \l_myPlot_file_tl,
height .tl_set:N = \l_myPlot_height_tl,
label .tl_set:N = \l_myPlot_label_tl,
path .tl_set:N = \l_myPlot_path_tl

}

\NewDocumentCommand{\myplotFF}{m}{
        \keys_set:nn{myPlot}{#1}
            \addpic{

                width=0.6,
                %height=0.6,
                image=\l_myPlot_file_tl,
                caption=\getCaption{statsName=\l_myPlot_statsName_tl,
                DOF=\l_myPlot_DOF_tl, 
                Re=\l_myPlot_Re_tl},
                     label=\keylabel{statsName=\l_myPlot_statsName_tl,DOF=\l_myPlot_DOF_tl,Re=\l_myPlot_Re_tl},
            }
}

当然,带有“label=...”的行不起作用,但如果我传递一个硬编码的标签,它就起作用了。这就是第一个线程的全部内容。谢谢!

答案1

如果我理解正确,那么你需要以下输入

\section{X}
\myplotFF{file={example-image-a},Re=50,DOF=4M, statsName=Drag}

产生以下输出

目标输出(可能)

您目前拥有的代码很乱。您似乎为一个包/类/设置了多个模块,并为处理相同的选项/数据设置了多个子模块。这不是一个好策略。 expl3 语法的重点是一致性,而混乱的键值对集合的大杂烩会导致代码极不一致。

请注意,这并不是对原始答案的批评。相反,这是由于试图将相关功能的完全不同的实例相互抛出,希望事物能够结合在一起形成一个和谐的整体而产生的一个问题。这有点像让一群两岁的孩子在你的客厅里迷失,三四套协调得很好的油漆组合在一起时会非常不协调,并希望幼儿的审美感能将它们组合成一个令人愉悦的结果。问题不在于任何协调的配色方案,而在于试图用幼儿方法将它们组合起来。结果不会很漂亮。

我已将其标准化strider为主模块,并strider/pic作为唯一的子模块。我不确定子模块是否有用或必要,但我不知道大局是什么,所以也许是有原因的。

% arara: pdflatex
\pdfminorversion=7
\documentclass{article}
\usepackage{xparse,graphicx}
\ExplSyntaxOn
% the key-value interface
\keys_define:nn {strider/pic} {
  Re .tl_set:N = \l_strider_label_Re_tl,
  DOF .tl_set:N = \l_strider_label_DOF_tl,
  statsName .tl_set:N = \l_strider_label_statsName_tl,
  file .tl_set:N = \l_strider_file_tl,
  height .tl_set:N = \l_strider_height_tl,
  Re        .value_required:n = true,
  DOF       .value_required:n = true,
  statsName .value_required:n = true,
  caption .tl_set:N = \l_strider_pic_caption_tl,
  placement .tl_set:N = \l_strider_pic_placement_tl,
  placement .initial:n = htp,
  width .tl_set:N = \l_strider_pic_width_tl,
  width .initial:n = 0.6,
  options .tl_set:N = \l_strider_pic_options_tl,
  shortcaption .tl_set:N = \l_strider_pic_shortcaption_tl,
}
\cs_new_protected:Nn \strider_label:N
{
  #1 % will be \label or \ref
  {
    fig \c_colon_str
    \tl_item:Nn \l_strider_label_statsName_tl { 1 }
    \tl_item:Nn \l_strider_label_statsName_tl { 2 }
    \tl_item:Nn \l_strider_label_statsName_tl { 3 }
    Re \l_strider_label_Re_tl DOF \l_strider_label_DOF_tl
  }
}
% the main command
\cs_new_protected:Nn \strider_pic:
{
  % start the figure environment
  \__strider_start_figure:V \l_strider_pic_placement_tl
  \centering
  % include the image
  \__strider_pic_image:VVV
  \l_strider_pic_width_tl % the text width fraction
  \l_strider_pic_options_tl % other options
  \l_strider_file_tl % the image name
  % the caption
  \tl_if_empty:NT \l_strider_pic_caption_tl
  {
    \tl_set:Nn \l_strider_pic_caption_tl
    {
      statsName:~\l_strider_label_statsName_tl,~DOF:~\l_strider_label_DOF_tl,~Re:~\l_strider_label_Re_tl
    }
  }
  \tl_if_empty:NTF \l_strider_pic_shortcaption_tl
  {
    \caption{\l_strider_pic_caption_tl}
  }
  {
    \caption[\l_strider_pic_shortcaption_tl]{\l_strider_pic_caption_tl}
  }
  \strider_label:N \label
  % end the figure environment

  %### %for parser to ignore
\end{figure}
%###
}
% syntactic sugar: we want some token lists to be expanded before usage
\cs_new_protected:Nn \__strider_start_figure:n
{
  \begin{figure}[#1]
}
\cs_generate_variant:Nn \__strider_start_figure:n { V }

\cs_new_protected:Nn \__strider_pic_image:nnn
{
  \includegraphics[width=#1\textwidth,#2]{#3}
}
\cs_generate_variant:Nn \__strider_pic_image:nnn { VVV }

\NewDocumentCommand{\myplotFF}{m}{
  \group_begin:
    \keys_set_known:nn { strider / pic } {#1}
    \strider_pic:
  \group_end:
}
\NewDocumentCommand{\keyref}{m}
{
  \keys_set_known:nn { strider / pic } { #1 }
  \strider_label:N \ref
}
\ExplSyntaxOff

\begin{document}
\section{X}
\myplotFF{file={example-image-a},Re=50,DOF=4M, statsName=Drag}

See figure \keyref{Re=50,DOF=4M, statsName=Drag}

\myplotFF{file={example-image-b},Re=48,DOF=4M, statsName=Drag,caption={Override caption in this case} }

See figure \keyref{Re=50,DOF=4M, statsName=Drag} and \keyref{Re=48,DOF=4M, statsName=Drag}
\end{document}

编辑

上面的代码经过编辑,以证明标签已经自动生成了!为了展示这一点,我添加了一个稍微修改过的版本,\keyref以便可以轻松地在输出中说明标签。

编辑 编辑

进一步编辑以简化一些并为标题提供可选的覆盖。

带有引用和覆盖的示例

相关内容