csv-list 구문 분석, 콜백으로 매개변수가 1개 이상인 함수

csv-list 구문 분석, 콜백으로 매개변수가 1개 이상인 함수

내 텍스트에서 나는 항목의 형식을 별도로 지정해야 하는 목록을 처리해야 합니다. 즉:

\funktion[3][]{T}--\funktion{S}--\funktion[3][7]{D}--\funktion{T}

\funktion서식이 지정 되고 \emphsubsup선택적 매개변수가 처리됩니다.

다음과 같은 기능을 사용하여 이 작업을 어떻게 단축할 수 있나요 \funktionen? 즉:

\funktionen{[3][]{T},{Sp},[3][{7,9,11}]{D},{T}}또는 더 나은:

\funktionen{[3][]T,Sp,[3][{7,9,11}]D,T}

각 인수에는 쉼표를 포함하여 2개 이상의 문자가 포함될 수 있습니다!

나는 패키지 forcsvlist에서 그것을 시도했지만 etoolbox(물론) 전체 값을 [3][]{T}하나의 단일 인수로 사용합니다. 또한 구분 기호를 인식하는 방법을 모르겠습니다 --.

MWE:

\documentclass[border=5]{standalone}
\usepackage{etoolbox, xparse, fixltx2e, letltxmacro}

\DeclareDocumentCommand{\subsup}{ o o m }{%
\IfValueTF{#1}{%
    \IfValueTF{#2}{%
    \textsubscript{#1}#3\textsuperscript{#2}%
    }{%
    #3\textsuperscript{#1}}%
}{#3}%
}
\DeclareDocumentCommand{\emphsubsup}{ o o m }{\emph{\subsup[#1][#2]{#3}}}%same, only emphasized

\LetLtxMacro{\funktion}{\emphsubsup}

%test
\newcommand*{\funktionen}[1]{%
    \forcsvlist{\funktion}{#1}
}

\begin{document}

    \funktion[3][]{T}--\funktion{Sp}--\funktion[3][7,9,11]{D}--\funktion{T}

    \hskip1ex

    \funktionen{[3][]{T},{Sp},[3][{7,9,11}]{D},{T}}

\end{document}

답변1

실제로 문서 명령 '이상의' 구문 분석을 찾고 있으므로(이것은 간단한 명령에 대한 표준 LaTeX2e 스타일 인수가 아닙니다.) 파서 비트를 직접 코딩하고 싶은 유혹을 느낄 것입니다. [중첩 에 대해 걱정할 필요가 없다고 가정하면 ](이 경우에는 필요하다고 생각합니다 xparse) '고전적인' 미리보기 접근 방식을 사용하여 매우 간단하게 수행할 수 있습니다. 나는 이 작업을 수행했지만 다음을 expl3사용하여 쉽게 수행할 수도 있습니다 \@ifnextchar.

\RequirePackage{fixltx2e}
\documentclass{article}
\usepackage{expl3,xparse}
\ExplSyntaxOn
\DeclareDocumentCommand \funktionen { > { \SplitList { , } } m }
  {
    \musicman_parse:n {#1}
  }
\seq_new:N \l__musicman_parse_seq
\tl_new:N \l__musicman_tmp_tl
\cs_new_protected:Npn \musicman_parse:n #1
  {
    \group_begin:
      \seq_clear:N \l__musicman_parse_seq
      \tl_map_inline:nn {#1}
        {
          \tl_clear:N \l__musicman_tmp_tl
          \peek_meaning_ignore_spaces:NTF [ % ]
            { \__musicman_parse_auxi:w }
            { \__musicman_parse_auxiii:w }
          ##1 \q_stop
          \seq_put_right:NV \l__musicman_parse_seq \l__musicman_tmp_tl
        }
      \seq_use:Nn \l__musicman_parse_seq { -- }
    \group_end:
  }
\cs_new_protected:Npn \__musicman_parse_auxi:w [ #1 ]
  {
    \tl_set:Nn \l__musicman_tmp_tl { \textsubscript {#1} }
    \peek_meaning_ignore_spaces:NTF [ % ]
      { \__musicman_parse_auxii:w }
      { \__musicman_parse_auxiii:w }
  }
\cs_new_protected:Npn \__musicman_parse_auxii:w [ #1 ] #2 \q_stop
  {
    \tl_put_right:Nx \l__musicman_tmp_tl
      {
        \exp_not:n {#2}
        \tl_if_blank:nF {#1} { \exp_not:n { \textsuperscript {#1} } }
      }
  }
\cs_new_protected:Npn \__musicman_parse_auxiii:w #1 \q_stop
  { \tl_set:Nn \l__musicman_tmp_tl {#1} }
\ExplSyntaxOff
\begin{document}

\funktionen{[3][]{T},{Sp},[3][{7,9,11}]{D},{T}}

\end{document}

나는 항목의 '부분' 목록을 보관하기 위해 시퀀스를 사용했습니다. 이렇게 하면 --'목록 끝' 또는 ​​이와 유사한 테스트를 직접 수행할 필요 없이 구분 기호( )를 쉽게 삽입할 수 있기 때문입니다. 이 경우 대신 손으로 만든 매핑을 사용할 수 있지만 성능이 중요하지 않은 경우 여기의 접근 방식보다 덜 명확해지는 경향이 있습니다.

전문가 의 경우 , 논쟁이 이미 파악되었기 때문에 여기서 대신 expl3사용할 수 있다는 점에 주목합니다 .\tl_if_head_eq_meaning:nNTF\peek_meaning:NTF

답변2

그룹 내에서 함수가 실행되는 것이 마음에 들지 않으면 TeX다음을 시도해 볼 수 있습니다 pgffor.

\documentclass[border=5]{standalone}

\usepackage{etoolbox, xparse, fixltx2e, pgffor}

\DeclareDocumentCommand{\funktion}{ o o m }{%
\IfValueTF{#1}{%
    \IfValueTF{#2}{%
    \textsubscript{#1}#3\textsuperscript{#2}%
    }{%
    #3\textsuperscript{#1}}%
}{#3}%
}

%test
\newcommand*{\funktionen}[1]{%%
  \foreach \args [count=\x]in {#1}{%
    \ifnum\x>1--\fi\expandafter\funktion\args%
  }%
}

\begin{document}

\funktion[3][]{T}--\funktion{S}--\funktion[3][7]{D}--\funktion{T}
\hskip1ex

\funktionen{[3][]{T},{S},[3][7]{D},{T}}

\end{document}

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

그러나 사용자 정의 목록 파서는 매우 간단합니다.

\documentclass[border=5]{standalone}

\usepackage{etoolbox, xparse, fixltx2e}


\DeclareDocumentCommand{\funktion}{ o o m }{%
\IfValueTF{#1}{%
    \IfValueTF{#2}{%
    \textsubscript{#1}#3\textsuperscript{#2}%
    }{%
    #3\textsuperscript{#1}}%
}{#3}%
}

\newcommand*{\Funktionen}[1]{%
  \let\FunctionenNext=\relax%
  \FunctionenLoop#1,\FunctionenHalt,%
}
\def\FunctionenHalt{\FunctionenHalt}%
\def\FunctionenLoop#1,{%
  \def\tmp{#1}%
  \ifx\tmp\FunctionenHalt%
    \let\FunctionenNext=\relax%
  \else%
    \ifx\FunctionenNext\relax\else--\fi%
    \funktion#1%
    \let\FunctionenNext=\FunctionenLoop%
  \fi%
  \FunctionenNext%
}
\begin{document}

\funktion[3][]{T}--\funktion{S}--\funktion[3][7]{D}--\funktion{T}

\hskip1ex

\Funktionen{[3][]{T},{S},[3][7]{D},{T}}

\end{document}

결과는 이전과 같습니다.

답변3

LaTeX 패키지가 필요 없는 솔루션은 다음과 같습니다. 후에

\funktionen{[3][]T,Sp,[3][7,9,11]D,T}

다음 콘텐츠를 저장했습니다:

\funktion[3][]{T}--\funktion{Sp}--\funktion[3][7,9,11]{D}--\funktion{T}

매크로 에서 \funktionenL. 간단히 실행하여 실행할 수 있습니다 \funktionenL.

\long\def\addto#1#2{\expandafter\def\expandafter#1\expandafter{#1#2}}

\def\funktionen#1{\def\funktionenL{}\funktionenA#1,,}
\def\funktionenA{\let\tmpa=\relax \let\tmpb=\relax \futurelet\next\funktionenB}
\def\funktionenB{\ifx\next[\expandafter\funktionenC \else \expandafter\funktionenF \fi}
\def\funktionenC[#1]{\def\tmpa{#1}\futurelet\next\funktionenD}
\def\funktionenD{\ifx\next[\expandafter\funktionenE \else \expandafter\funktionenF \fi}
\def\funktionenE[#1]{\def\tmpb{#1}\funktionenF}
\def\funktionenF#1,{\ifx,#1,\else
   \ifx\funktionenL\empty \else \addto\funktionenL{--}\fi
   \addto\funktionenL{\funktion}%
   \ifx\tmpa\relax\else \funktionenG{\expandafter[\tmpa]}\fi
   \ifx\tmpb\relax\else \funktionenG{\expandafter[\tmpb]}\fi
   \addto\funktionenL{{#1}}%
   \expandafter\funktionenA
   \fi
}
\def\funktionenG{\expandafter\addto\expandafter\funktionenL\expandafter}

\funktionen{[3][]T,Sp,[3][7,9,11]D,T}

\message{\meaning\funktionenL}

관련 정보