내가 찾은 코드 조각을 이해하려고 시도 중입니다.

내가 찾은 코드 조각을 이해하려고 시도 중입니다.

이 스레드에서 저는 정말 흥미롭고 유용하다고 생각하는 코드를 발견했지만, 그것이 어떻게 작동하는지 전혀 모릅니다.https://tex.stackexchange.com/a/584979/261033

참고로 문제의 코드는 다음과 같습니다.

\def\addto#1#2{\expandafter\def\expandafter#1\expandafter{#1#2}}
\def\matr#1{\def\matrL{}\matrA#1\end}
\def\matrA#1{\ifx\end#1\pmatrix{\matrL}\else 
   \ifx,#1\addto\matrL{&}\else
   \ifx;#1\addto\matrL{\cr}\else
   \addto\matrL{#1}\fi\fi
   \expandafter\matrA\fi
}

이는 다음과 같이 호출될 수 \matr{a,b;c,d}있으며 pmatrix를 생성합니다. 내 생각에는 간단한 행렬로 자주 작업하고 전체 긴 명령을 반복적으로 입력하는 데 지친 경우 매우 유용합니다. 누군가는 amsmath 패키지와 함께 작동하게 하려면 \pmatrix{\matrL}를 로 바꿔야 한다고 지적했습니다 \begin{pmatrix}\matrL\end{pmatrix}.

\matr{[)}{...}어쨌든, 이 명령을 추가 로 수정하고 싶습니다. 예를 들어 행/열 구분 기호로 다른 기호를 사용하거나, 입력을 열 단위로 구문 분석하거나, 모든 행렬 괄호 유형에 대해 일반화합니다. 와 유사한 특정 묶음 괄호 세트가 있는 행렬이지만 \left[\begin{matrix}...\end{matrix}\right)아직 그 중 하나를 수행하는 방법을 모릅니다.

이러한 명령에 대해 알아보려고 노력했지만 곧 문제가 발생했습니다. 와 같은 일부는 \addto너무 모호해서 이에 대한 문서가 어디에도 없는 것 같습니다! Google은 내가 관심이 없는 \addtocontents또는 같은 항목만 찾을 수 있었고 \g@addto@macro, 이를 나열하는 포괄적인 TeX 리소스도 찾지 못했습니다.https://www.latex-project.org또는https://texdoc.org/index.html.

그러니 누구든지 이 문제에 대해 도움을 주실 수 있다면 이 명령에 대한 실제 기존 문서를 알려주시면 정말 감사하겠습니다. 미리 감사드립니다.

답변1

매크로 \addto는 다른 매크로에 코드를 추가합니다.

당신이 가지고 있고 \def\foo{X}한다면 \addto\foo{Y}TeX가 할 것입니다

\expandafter\def\expandafter\foo\expandafter{\foo Y}

그 결과

\def\foo{XY}

\expandafter체인이 작업을 마친 후 . 그러나 당신은캔트\addtoLaTeX에서 코드를 사용하려는 경우 사용하세요 . 왜냐하면 \addto은 에서 사용되는 중요한 명령이고 babel재정의하면 재난의 위험이 있기 때문입니다. 그냥 다른 이름을 사용하세요.

무엇을 \matr합니까? 이는 \def\matrL{}행렬 본문에 대한 컨테이너를 초기화합니다. 다음으로 인수를 에 전달하여 \matrA재귀를 시작합니다.

매크로는 \matrA다음 토큰을 하나씩 읽습니다.

  • 다음 토큰이 ,(셀의 끝을 나타냄)이면 &에 추가됩니다 \matrL.
  • 다음 토큰이 ;(행의 끝을 나타냄)이면 \cr에 추가됩니다 \matrL.
  • 다음 토큰이 이면 \end최종 게임이 실행됩니다. 즉, \pmatrix{\matrL}실행되고 재귀가 중지됩니다.
  • 다른 모든 경우에는 토큰이 \matrL.

이것을 LaTeX, 특히 환경에 적용할 수 있습니까 pmatrix? 네, 쉽게요.

우선, 내부 매크로에 대해 다른 이름을 선택하십시오 @. 가급적이면 그 안에 포함되어 있어야 합니다.

\documentclass{article}
\usepackage{amsmath}

\makeatletter
\newcommand{\matr}[1]{\def\tsskyx@matrL{}\tsskyx@matrA#1\end}

\def\tsskyx@addto#1#2{\expandafter\def\expandafter#1\expandafter{#1#2}}

\def\tsskyx@matrA#1{%
  \ifx\end#1%
    \begin{pmatrix}\tsskyx@matrL\end{pmatrix}%
  \else 
    \ifx,#1%
      \tsskyx@addto\tsskyx@matrL{&}%
    \else
      \ifx;#1%
        \tsskyx@addto\tsskyx@matrL{\\}%
      \else
        \tsskyx@addto\tsskyx@matrL{#1}%
      \fi
    \fi
    \expandafter\tsskyx@matrA
  \fi
}
\makeatother

\begin{document}

\[
\matr{a,b;c,d}
\]

\end{document}

최소한의 차이만 있는 동일한 코드: 대신 \cr추가 \\하고 \begin{pmatrix}...\end{pmatrix}사용됩니다.

expl3선택적 인수가 구분 기호를 지정하는 를 사용하는 다른 구현입니다 (기본값은 규칙 에 따를 p수 있음 ).bvVBamsmath

\documentclass{article}
\usepackage{amsmath}

\ExplSyntaxOn

\NewDocumentCommand{\matr}{O{p}m}
 {
  \tsskyx_matr:nn { #1 } { #2 }
 }

\seq_new:N \l__tsskyx_matr_body_seq

\cs_new_protected:Nn \tsskyx_matr:nn
 {
  % build the matrix
  \begin{#1matrix}
  % split the argument at ;
  \seq_set_split:Nnn \l__tsskyx_matr_body_seq { ; } { #2 }
  % map the items, that are comma separated lists
  \seq_map_function:NN \l__tsskyx_matr_body_seq \__tsskyx_matr_row:N
  \end{#1matrix}
 }

\cs_new_protected:Nn \__tsskyx_matr_row:N
 {
  \clist_use:nn { #1 } { & } \\
 }

\ExplSyntaxOff

\begin{document}

\[
\matr{a,b;c,d}
\qquad
\matr[b]{a,b;c,d}
\]

\end{document}

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

행 및 열 구분 기호도 변경하려는 경우 키-값 시스템을 사용할 수 있습니다.

\documentclass{article}
\usepackage{amsmath}

\ExplSyntaxOn

\NewDocumentCommand{\matr}{O{}m}
 {
  \group_begin:
  \keys_set:nn { tsskyx/matr } { #1 }
  \tsskyx_matr:n { #2 }
  \group_end:
 }

\seq_new:N \l__tsskyx_matr_body_seq
\seq_new:N \l__tsskyx_matr_row_seq

\keys_define:nn { tsskyx/matr }
 {
  row-sep .tl_set:N  = \l__tsskyx_matr_rowsep_tl,
  col-sep .tl_set:N  = \l__tsskyx_matr_colsep_tl,
  delim   .tl_set:N  = \l__tsskyx_matr_delim_tl,
  row-sep .initial:n = { ; },
  col-sep .initial:n = { , },
  delim   .initial:n = { p },
 }

\cs_new_protected:Nn \tsskyx_matr:n
 {
  % build the matrix
  \begin{\l__tsskyx_matr_delim_tl matrix}
  % split the argument at ;
  \seq_set_split:NVn \l__tsskyx_matr_body_seq \l__tsskyx_matr_rowsep_tl { #1 }
  % map the items, that are comma separated lists
  \seq_map_function:NN \l__tsskyx_matr_body_seq \__tsskyx_matr_row:N
  \end{\l__tsskyx_matr_delim_tl matrix}
 }

\cs_new_protected:Nn \__tsskyx_matr_row:N
 {
  \seq_set_split:NVn \l__tsskyx_matr_row_seq \l__tsskyx_matr_colsep_tl { #1 }
  \seq_use:Nn \l__tsskyx_matr_row_seq { & } \\
 }

\ExplSyntaxOff

\begin{document}

\begin{gather*}
\matr{a,b;c,d}
\\
\matr[delim=b]{a,b;c,d}
\\
\matr[row-sep=\\,col-sep=&,delim=V]{a & b \\ c & d}
\\
\matr[row-sep=;,col-sep=:]{a:b;c:d}
\end{gather*}

\end{document}

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

답변2

\addto코드에 언급된 매크로는 원래 csplain용으로 설계된 OPmac 매크로에서 가져온 것입니다. 나중에 OPmac은 일반 TeX용으로, 요즘은 OpTeX에서 사용됩니다 . 이 매크로 패키지의 작성자는 LaTeX를 지원하지 않습니다. 그의 매크로는 주로 일반 TeX용이며 대부분 TeX 기본 형식을 기반으로 하기 때문에 LaTeX에도 적용할 수 있습니다. 하지만 \addtoLaTeX 패키지에서 같은 이름으로 공유되는 이름과 같은 약간의 장애물이 있는 경우도 있습니다 . 저자는 LaTeX나 그 패키지(babel과 같은)를 사용하지 않기 때문에 그와 다른 일반 TeX 사용자에게는 문제가 되지 않습니다.

매개변수에서 행렬의 괄호 유형을 설정할 수 있도록 매크로를 수정하려는 경우 지정된 유형을 정의된 정의로 보낼 수 있습니다 \matrA.내부에매크로 \matr. 그래서 당신은 트릭을 가지고 \def있습니다 \def:

\def\addto#1#2{\expandafter\def\expandafter#1\expandafter{#1#2}}
\def\matr#1#2#3{\def\matrL{}%
   \def\matrA##1{\ifx\end##1\left#1\matrix{\matrL}\right#2\else 
      \ifx,##1\addto\matrL{&}\else
      \ifx;##1\addto\matrL{\cr}\else
      \addto\matrL{##1}\fi\fi
      \expandafter\matrA\fi
   }
   \matrA#3\end
}

Test and usage:
$$
  \matr[]{a,b;c,d}
$$

\bye

편집하다여기의 다른 답변과 비교하기 위해 OpTeX의 키-값 매크로를 사용하는 방법을 보여줍니다.

\def\matrdefaults{%
   delims=(),   % delimiters of the matrix
   row-sep={;}, % row separator used in parameter
   col-sep={,}, % column separator used in parameter
}
\optdef\matr [] #1{{%
   \readkv\matrdefaults \readkv{\the\opt}%
   \ea\matrX \expanded{\kv{delims}\kv{row-sep}\kv{col-sep}}#1\end
}}
\def\matrX#1#2#3#4{\def\matrL{}%
   \def\matrA##1{\ifx\end##1\left#1\matrix{\matrL}\right#2\else 
      \ifx#4##1\addto\matrL{&}\else
      \ifx#3##1\addto\matrL{\cr}\else
      \addto\matrL{##1}\fi\fi
      \ea\matrA\fi
   }
   \matrA
}

$$
  \displaylines{
     \matr {a,b;c,d} \cr
     \matr [delims={[]}] {a,b;c,d} \cr
     \matr [row-sep={\cr}, col-sep={&}, delims={\|\|}] {a&b\cr c&d} \cr
     \matr [row-sep=;,col-sep=:]{a:b;c:d}
}
$$

\bye

그리고 이 매크로를 사용하여 패키지를 생성하려면 별도의 네임스페이스( tsskyx여기)를 사용해야 합니다. 이 네임스페이스의 제어 시퀀스에는 접두사가 붙고 .다른 사용된 제어 시퀀스(기본 및 OpTeX 매크로)에는 가 붙습니다 _. 그런 다음 매크로는 사용자 이름 공간(접두사가 없는 이름) 및 다른 이름 공간을 가진 다른 매크로 패키지로부터 격리됩니다.

\_namespace{tsskyx}
\_def\.matrdefaults{%
   delims=(),   % delimiters of the matrix
   row-sep={;}, % row separator used in parameter
   col-sep={,}, % column separator used in parameter
}
\_optdef\.matr [] #1{{%
   \_kvdict{tsskyx}%
   \_readkv\.matrdefaults \_readkv{\_the\_opt}%
   \_ea\.matrX \_expanded{\_kv{delims}\_kv{row-sep}\_kv{col-sep}}#1\_end
}}
\_def\.matrX#1#2#3#4{\_def\.matrL{}%
   \_def\.matrA##1{\_ifx\_end##1\_left#1\_matrix{\.matrL}\_right#2\_else 
      \_ifx#4##1\_addto\.matrL{&}\_else
      \_ifx#3##1\_addto\.matrL{\_cr}\_else
      \_addto\.matrL{##1}\_fi\_fi
      \_ea\.matrA\_fi
   }
   \.matrA
}
\_nspublic \matr ;
\_endnamespace

$$
  \displaylines{
     \matr {a,b;c,d} \cr
     \matr [delims={[]}] {a,b;c,d} \cr
     \matr [row-sep={\cr}, col-sep={&}, delims={\|\|}] {a&b\cr c&d} \cr
     \matr [row-sep=;,col-sep=:]{a:b;c:d}
}
$$

\bye

관련 정보