복잡한 목록 처리 매크로를 사용하여 pdfauthor 설정

복잡한 목록 처리 매크로를 사용하여 pdfauthor 설정

\joinlist내부 목록 의 요소 사이에 쉼표나 기타 구분 기호를 추가하는 매크로를 만들었습니다 etoolbox. 두 개의 요소("a 및 b")만 있는 목록에 대한 특수 처리 기능이 있습니다. 또한 긴 목록의 마지막 두 항목("a, b 및 c") 사이에 다른 구분 기호를 배치하는 방법도 알고 있습니다. 내가 만든 정의는 다음과 같습니다.

% typical use: \joinlist{\listmacro}{, }{, and }{ and }

\RequirePackage{etoolbox}

\newcommand{\@join@ignore}[1]{} % used to ignore current list element when counting
\newcount\@join@listlength % used to count length of list
\newcount\@join@currentnum % used to track current list element number

\newcommand{\joinlist}[4]{%
  %
  % count list elements
  \@join@listlength 0 %
  \forlistloop{\advance\@join@listlength 1\relax\@join@ignore}{#1}%
  %
  % now join list elements, tracking current element number
  \@join@currentnum 0 %
  \forlistloop{%
    \advance\@join@currentnum 1 %
    \ifnumequal{\the\@join@currentnum}{1}%
    {}% first
    {% not first
      \ifnumequal{\the\@join@currentnum}{\the\@join@listlength}%
      {% last
        \ifnumequal{\the\@join@listlength}{2}%
        {#4}% last of exactly two
        {#3}% last of more than two
      }%
      {#2}% neither first nor last
    }%
  }%
  {#1}}

위의 내용을 로 저장한 join-list.sty후 문제를 보여주는 다음의 작은 예를 고려하십시오.

\documentclass{article}

\usepackage{hyperref}
\usepackage{join-list}

\begin{document}

    \newcommand{\people}[0]{}
    \listadd{\people}{a}
    \joinlist{\people}{, }{, and }{ and }  % a

    \listadd{\people}{b}
    \joinlist{\people}{, }{, and }{ and }  % a and b

    \listadd{\people}{c}
    \joinlist{\people}{, }{, and }{ and }  % a, b, and c

    \hypersetup{pdfauthor=\joinlist{\people}{, }{, and }{ and }}

\end{document}

\joinlist문서 본문 내용을 만드는 데 적합합니다. 예상대로 "a", "a 및 b", "a, b 및 c"가 표시됩니다.

불행하게도 이것을 사용하면 \hypersetup{pdfauthor=...}원하는 대로 작동하지 않습니다. 대신 문서의 PDF 작성자 메타데이터를 "0 1110 1 , a1 , b1 , c"로 설정합니다. 분명히 \joinlist이 맥락에서 매크로를 확장/평가하는 데 뭔가 크게 잘못되었습니다 .

내가 여기서 뭘 잘못하고 있는 걸까? 이 문제를 어떻게 해결할 수 있나요? 내 \joinlist매크로를 개선할 수 있는 다른 방법이 있습니까 ? 널리 사용되는 패키지에 유사한 매크로가 이미 존재합니까? (검색했지만 아무것도 발견하지 못했습니다.)

답변1

문제는 "확장 가능"하지 않다는 것입니다 . 즉, 값에서는 수행할 수 없는 \joinlist할당을 수행해야 합니다 .\advance\@join@currentnum 1pdfauthor=

(더 이상 LaTeX3의 실험적인 프로그래밍 계층이 아님)을 사용하면 expl3필요한 것이 있습니다.

\documentclass{article}

\usepackage{hyperref}

\RequirePackage{xparse}
\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\joinlist}{ m m m m }
 {
  \seq_use:cnnn { g_liblit_list_#1_seq } { #2 } { #3 } { #4 }
 }
\cs_generate_variant:Nn \seq_use:Nnnn { c }
\NewDocumentCommand{\newlist}{ m }
 {
  \seq_new:c { g_liblit_list_#1_seq }
 }
\NewDocumentCommand{\listadd}{ m m }
 {
  \seq_gput_right:cn { g_liblit_list_#1_seq } { #2 }
 }
\ExplSyntaxOff

\begin{document}

\newlist{people}
\listadd{people}{a}
\joinlist{people}{ and }{, }{, and } % a

\listadd{people}{b}
\joinlist{people}{ and }{, }{, and }  % a and b

\listadd{people}{c}
\joinlist{people}{ and }{, }{, and }  % a, b, and c

\hypersetup{pdfauthor=\joinlist{people}{ and }{, }{, and }}

\end{document}

설정과 관련하여 몇 가지 변경 사항이 있습니다. 목록은 매크로에 의해 호출되지 않고 이름을 갖습니다. 에 의해 새로운 것이 생성될 수 있습니다 \newlist. 또한 인수의 순서도 \joinlist다릅니다.

  1. 목록 이름;
  2. 요소가 두 개인 경우 요소 사이에 무엇이 들어가야 할까요?
  3. 2개 이상이면 요소 사이에 무엇을 넣어야 할까요(마지막 2개 제외).
  4. 그 사이에 무엇이 들어가야 할까?마지막요소가 2개 이상이면 2개입니다.

목록이 비어 있으면 아무것도 생성되지 않습니다. 단 하나의 요소만 있으면 그 요소가 생성됩니다.

이 버전의 는 \joinlist확장 가능하며 에 값을 제공하는 데 문제가 없습니다 pdfauthor=.

파일에서 귀하의 코드를 대체하기 위해 서문의 코드를 사용할 수 있습니다 .sty.

여기에 이미지 설명을 입력하세요

관련 정보