使用引用对象的名称作为字符串比较的参数

使用引用对象的名称作为字符串比较的参数

我有#1一个包含一些文本的论点X代表一些标签。我想用它\str_if_eq来比较X以及此字符串引用的段落的名称。我想要实现的是,如果\label{X}位于某个之下\paragraph[shortname_different_from_X]{Long description},我想要包含\nameref{X},以便读者可以看到shortname_different_from_X,这样就有可能在印刷版中找到我所说的内容。(假设知道shortname_different_from_X就足以在印刷版本中找到正确的段落。

这是我的代码:

\cs_new_protected:Nn \mynode_print:N
 {
  \texttt
   {
    \tl_if_empty:NTF #1
      { - }
      { \hyperref[\tl_to_str:N #1] { \tl_to_str:N #1} % this is here only to show name of label and make it so that reader can click on it and go to label
      \str_if_eq:nnTF{\tl_to_str:N #1}{ \nameref{\tl_to_str:N #1} }{}{ ~(see~\nameref{\tl_to_str:N #1}) } } % second argument should be changed so that it contains name of referenced paragraph
   };~
 }

在提供的代码中,比较总是返回false,因为\nameref{\tl_to_str:N #1}在第二个参数中使用str_if_eq是错误的,它不是一个字符串。

为了完整起见,这里是使用示例,我不希望see n_1see n_2see n_3可见,只see missing_nodes应该可见:

\documentclass[12pt, oneside]{book}
\usepackage[a4paper,top=2.5cm,bottom=2.5cm,left=3.5cm,right=2cm]{geometry}
\usepackage[utf8]{inputenc}
\usepackage[IL2]{fontenc}
\usepackage{graphicx}
\usepackage{url}
\DeclareUrlCommand\url{\def\UrlLeft{<}\def\UrlRight{>} \urlstyle{tt}}
\usepackage[hidelinks,breaklinks]{hyperref}
\usepackage[slovak]{babel}
\usepackage{blindtext}
\usepackage{xcolor}
\usepackage{fancyvrb}
\usepackage{listings}
\usepackage{subcaption}
\usepackage{tikz}
\usepackage{dot2texi}
\usepackage{nameref}
\usepackage{xparse}
\usepackage{xstring}
\usepackage{ifthen}
\usetikzlibrary{snakes,arrows,shapes}
\linespread{1.25}
\setlength{\emergencystretch}{30pt}

\ExplSyntaxOn
\NewDocumentCommand\mynode{mmmm}
 {
  \mynode_main:nnnn { #1 } { #2 } { #3 } { #4 }
 }

\seq_new:N \l_mynode_input_seq
\seq_new:N \l_mynode_output_seq
\tl_new:N \l_mynode_node_tl
\tl_new:N \l_mynode_text_tl

\cs_new_protected:Nn \mynode_main:nnnn
 {
  \seq_set_split:Nnn \l_mynode_input_seq { ; } { #3 }
  \seq_set_split:Nnn \l_mynode_output_seq { ; } { #4 }
  \tl_set:Nn \l_mynode_node_tl { #1 }
  \mynode_replace:N \l_mynode_node_tl
  \tl_set:Nn \l_mynode_text_tl { #2 }
  \mynode_replace:N \l_mynode_text_tl

  \mynode_paragraph:VV \l_mynode_node_tl \l_mynode_text_tl
  \label{ \tl_to_str:n { #1 } }

  \begin{itemize}
    \item in:~
    \seq_map_variable:NNn \l_mynode_input_seq \l_mynode_node_tl
     {
      \mynode_print:N \l_mynode_node_tl
     }
    \item out:~
    \seq_map_variable:NNn \l_mynode_output_seq \l_mynode_node_tl
     {
      \mynode_print:N \l_mynode_node_tl
     }
  \end{itemize}
 }

\cs_new_protected:Nn \mynode_paragraph:nn
 {
  \paragraph[#1]{#2~(\texttt{#1}):}
 }
\cs_generate_variant:Nn \mynode_paragraph:nn { VV }

\cs_new_protected:Nn \mynode_print:N
 {
  \texttt
   {
    \tl_if_empty:NTF #1
      { - }
      { \hyperref[\tl_to_str:N #1] { \tl_to_str:N #1}
      \str_if_eq:nnTF{\tl_to_str:N #1}{ \nameref{\tl_to_str:N #1} }{}{ ~(see~\nameref{\tl_to_str:N #1}) } }
   };~
 }

\cs_new_protected:Nn \mynode_replace:N
 {
  \regex_replace_all:nnN { \_ } { \c{_} } #1
  \regex_replace_all:nnN { \< } { \c{textless} } #1
  \regex_replace_all:nnN { \> } { \c{textgreater} } #1
 }

\NewDocumentCommand{\change}{m}
 {
  \tl_set:Nn \l_mynode_text_tl { #1 }
  \mynode_replace:N \l_mynode_text_tl
  \tl_use:N \l_mynode_text_tl
\tl_show_analysis:N #1
 }
\ExplSyntaxOff


\begin{document}     
\mynode{n_1}{node 1}{}{n_2;n_3}
\mynode{n_2}{node 2}{n_1}{n_4}
\mynode{n_3}{node 3}{n_1}{}
\paragraph[missing\_nodes]{Nodes that are not present}
Some text describing why nodes are missing.
\label{n_4}
\label{n_5}
% ...

\end{document}

答案1

就这样!

第一个问题是您使用了\str_if_eq:nn而不是\str_if_eq:ee。前者,当您传递一个像 这样的参数时,\tl_to_str:N #1会比较文字“\tl_to_str:N#1”(用#1实际参数正确替换 ),并且不会扩展\tl_to_str:N。但是一旦您更改它,\nameref就会爆炸,因为它不可扩展。我加载了refcount包并使用,它是可扩展的。最后一个问题是您过早地\getrefbykeydefault用 替换,然后标签将被保存为但会与 进行比较。我将 移到实际排版之前,这是您需要替换的地方。_\_n\_1n_1\mynode_replace:N

为了举例,我删除了未使用的包。请注意,hyperref应该是最后一个要加载的包,除了极少数例外(这句话很棒:)。

2018 年 6 月,该\str_if_eq_x:nn函数被重命名为\str_if_eq:eeTF,因此如果你有一个旧版本,expl3它将无法使用。我添加了一个检查,以便代码将使用可用的版本。

输出如下:

在此处输入图片描述

以及代码:

\documentclass[12pt, oneside]{book}
\usepackage{xparse}
\usepackage{refcount}
\usepackage[hidelinks,breaklinks]{hyperref}

\ExplSyntaxOn
\NewDocumentCommand\mynode{mmmm}
 {
   \mynode_main:nnnn { #1 } { #2 } { #3 } { #4 }
 }

\seq_new:N \l_mynode_input_seq
\seq_new:N \l_mynode_output_seq
\tl_new:N \l_mynode_node_tl
\tl_new:N \l_mynode_text_tl

\cs_new_protected:Nn \mynode_main:nnnn
 {
  \seq_set_split:Nnn \l_mynode_input_seq { ; } { #3 }
  \seq_set_split:Nnn \l_mynode_output_seq { ; } { #4 }
  \tl_set:Nn \l_mynode_node_tl { #1 }
  \tl_set:Nn \l_mynode_text_tl { #2 }

  \mynode_paragraph:VV \l_mynode_node_tl \l_mynode_text_tl
  \label{ \tl_to_str:n { #1 } }

  \begin{itemize}
    \item in:~
    \seq_map_variable:NNn \l_mynode_input_seq \l_mynode_node_tl
     {
      \mynode_print:N \l_mynode_node_tl
     }
    \item out:~
    \seq_map_variable:NNn \l_mynode_output_seq \l_mynode_node_tl
     {
      \mynode_print:N \l_mynode_node_tl
     }
  \end{itemize}
 }

\cs_new_protected:Nn \mynode_paragraph:nn
 {
   \tl_set:Nn \l_tmpa_tl {#1}
   \mynode_replace:N \l_tmpa_tl
   \paragraph[#1]{#2~(\texttt{\l_tmpa_tl}):}
 }
\cs_generate_variant:Nn \mynode_paragraph:nn { VV }

\cs_new_protected:Nn \mynode_print:N
 {
  \texttt
   {
    \tl_if_empty:NTF #1
      { - }
      {
        \tl_set:Nx #1 { \tl_to_str:N #1 } % To avoid repetition
        \hyperref [#1] {#1}
        \cs_if_exist_use:NF \str_if_eq:eeTF \str_if_eq_x:nnTF
        % \str_if_eq:eeTF
            {#1}
            { \getrefbykeydefault {#1} { name } { squirdshlicker~:) } }
          {}
          { ~(see~\nameref{#1}) }
      }
   };~
 }

\cs_new_protected:Nn \mynode_replace:N
 {
  \regex_replace_all:nnN { \_ } { \c{_} } #1
  \regex_replace_all:nnN { \< } { \c{textless} } #1
  \regex_replace_all:nnN { \> } { \c{textgreater} } #1
 }

\NewDocumentCommand{\change}{m}
 {
  \tl_set:Nn \l_mynode_text_tl { #1 }
  \mynode_replace:N \l_mynode_text_tl
  \tl_use:N \l_mynode_text_tl
\tl_show_analysis:N #1
 }
\ExplSyntaxOff

\begin{document}
\mynode{n_1}{node 1}{}{n_2;n_3}
\mynode{n_2}{node 2}{n_1}{n_4}
\mynode{n_3}{node 3}{n_1}{}
\paragraph[missing\_nodes]{Nodes that are not present}
Some text describing why nodes are missing.
\label{n_4}
\label{n_5}

\end{document}

关于你的第二个请求。是的,这是可能的,但不推荐。我制作了一个宏来执行此操作,但请注意,:D参数规范表示“请勿使用”!

有一个主要问题使这成为一件奇怪的事情:(\paragraph或任何其他分段命令)的可选参数中的材料应该是可排版的材料,所以你应该逃离_

我使用了最不麻烦的方法来做到这一点:我将标签的副本复制到临时宏中,然后将其应用于\mynode_replace:N该标签,然后调用\nameref该宏对现在已转义的标签执行操作。最后我将标签恢复为其原始值。

完整代码(输出相同):

\documentclass[12pt, oneside]{book}
\usepackage{xparse}
\usepackage{refcount}
\usepackage[hidelinks,breaklinks]{hyperref}

\ExplSyntaxOn
\NewDocumentCommand\mynode{mmmm}
 {
   \mynode_main:nnnn { #1 } { #2 } { #3 } { #4 }
 }

\seq_new:N \l_mynode_input_seq
\seq_new:N \l_mynode_output_seq
\tl_new:N \l_mynode_node_tl
\tl_new:N \l_mynode_text_tl

\cs_new_protected:Nn \mynode_main:nnnn
 {
  \seq_set_split:Nnn \l_mynode_input_seq { ; } { #3 }
  \seq_set_split:Nnn \l_mynode_output_seq { ; } { #4 }
  \tl_set:Nn \l_mynode_node_tl { #1 }
  \tl_set:Nn \l_mynode_text_tl { #2 }

  \mynode_paragraph:VV \l_mynode_node_tl \l_mynode_text_tl
  \label{ \tl_to_str:n { #1 } }

  \begin{itemize}
    \item in:~
    \seq_map_variable:NNn \l_mynode_input_seq \l_mynode_node_tl
     {
      \mynode_print:N \l_mynode_node_tl
     }
    \item out:~
    \seq_map_variable:NNn \l_mynode_output_seq \l_mynode_node_tl
     {
      \mynode_print:N \l_mynode_node_tl
     }
  \end{itemize}
 }

\cs_new_protected:Nn \mynode_paragraph:nn
 {
   \tl_set:Nn \l_tmpa_tl {#1}
   \mynode_replace:N \l_tmpa_tl
   \paragraph[#1]{#2~(\texttt{\l_tmpa_tl}):}
 }
\cs_generate_variant:Nn \mynode_paragraph:nn { VV }

\cs_new_protected:Nn \mynode_print:N
 {
  \texttt
   {
    \tl_if_empty:NTF #1
      { - }
      {
        \tl_set:Nx #1 { \tl_to_str:N #1 } % To avoid repetition
        \hyperref [#1] {#1}
        \cs_if_exist_use:NF \str_if_eq:eeTF \str_if_eq_x:nnTF
        % \str_if_eq:eeTF
            {#1}
            { \getrefbykeydefault {#1} { name } { squirdshlicker~:) } }
          {}
          {
            \exp_args:NV
            \__mynode_label_bodge:D #1 { ~(see~\nameref{#1}) }
          }
      }
   };~
 }

\cs_new_protected:Npn \__mynode_label_bodge:D #1 #2
  {
    \cs_set_eq:Nc \__mynode_tmpa: { r@#1 }
    \exp_args:Nc
    \mynode_replace:N { r@#1 }
    #2
    \cs_set_eq:cN { r@#1 } \__mynode_tmpa:
  }

\cs_new_protected:Nn \mynode_replace:N
 {
  \regex_replace_all:nnN { \_ } { \c{_} } #1
  \regex_replace_all:nnN { \< } { \c{textless} } #1
  \regex_replace_all:nnN { \> } { \c{textgreater} } #1
 }

\NewDocumentCommand{\change}{m}
 {
  \tl_set:Nn \l_mynode_text_tl { #1 }
  \mynode_replace:N \l_mynode_text_tl
  \tl_use:N \l_mynode_text_tl
\tl_show_analysis:N #1
 }
\ExplSyntaxOff

\begin{document}
\mynode{n_1}{node 1}{}{n_2;n_3}
\mynode{n_2}{node 2}{n_1}{n_4}
\mynode{n_3}{node 3}{n_1}{}
\paragraph[missing_nodes]{Nodes that are not present}
Some text describing why nodes are missing.
\label{n_4}
\label{n_5}

\end{document}

相关内容