
이 스레드에서 저는 정말 흥미롭고 유용하다고 생각하는 코드를 발견했지만, 그것이 어떻게 작동하는지 전혀 모릅니다.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
체인이 작업을 마친 후 . 그러나 당신은캔트\addto
LaTeX에서 코드를 사용하려는 경우 사용하세요 . 왜냐하면 \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
수 있음 ).bvVB
amsmath
\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에도 적용할 수 있습니다. 하지만 \addto
LaTeX 패키지에서 같은 이름으로 공유되는 이름과 같은 약간의 장애물이 있는 경우도 있습니다 . 저자는 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