![확장성: LaTeX3 VS LaTeX](https://rvso.com/image/328469/%ED%99%95%EC%9E%A5%EC%84%B1%3A%20LaTeX3%20VS%20LaTeX.png)
확장성은 매크로/함수의 핵심입니다. 나는 알고 싶다:
- 의 확장성에 대한 더 나은 이해는 의
LaTeX3
확장성에 대한 좋은 배경을 통해서만 가능합니다LaTeX
. 어디까지 독립적이라고 볼 수 있을까요? - 보다 정확하게는 에서 제공하는 기능이
l3expan
모든 확장성 요구 사항을 처리하기에 충분한 경우입니다. 즉, 내에서LaTeX3
"LaTeX
확장성"이 지원되지만완전히대체. - 확장성 프로세스가 수행되는 동안 중간 단계를 확인할 수 있는 방법이 있습니까(예: 일부 출력 파일, 프로파일링 옵션 등)
답변1
직접 해본 적은 없지만, 새로운 LaTeX 프로그래머의 경우 기본 TeX 프로그래밍을 먼저 배우고 위로 올라가는 것보다 로딩에 의해 정의된 기능 expl3
(또는 LaTeX3 커널 또는 ) 으로 시작하는 것이 더 쉽다고 믿습니다 .l3kernel
그 이유는 expl3
강력하고 내부적으로 일관성이 있는 아주 멋진 추상화 계층을 제공하기 때문입니다. TeX 프로그래밍을 사용하면 오히려 간단한 작업을 수행하기 위해 '트릭'을 배우는 단계로 매우 빠르게 이동해야 합니다.
\foo
예를 들어, 두 개의 명령 및 에 대해 이야기하는 경우 복사본을 \baz
만들려면 다음을 작성하십시오.\foo
\baz
\let\foo\baz
하지만 제어 순서 대신 이름으로 참조해야 한다면 어떻게 될까요? 예를 들어, 다음과 같이 이를 수행하기 위해 무언가를 정의할 수 있습니다.
\defineacronym{baz}{BAZ}
\useacronym{baz} % => \textsc{\MakeLowercase{BAZ}}
이는 다음으로 정의할 수 있습니다.
\makeatletter
\newcommand\defineacronym[2]{%
\@namedef{acronym@#1}{\textsc{\MakeLowercase{BAZ}}}%
}
\newcommand\useacronym[1]{%
\@nameuse{acronym@#1}%
}
\makeatother
여태까지는 그런대로 잘됐다. 그러나 와 같은 명령을 정의하려면 다음과 같이 \copyacronym{foo}{baz}
작성해야 합니다.
\newcommand\copyacronym[2]{%
\expandafter\let\csname acronym@#1\expandafter\endcsname\csname acronym@#2\endcsname
}
이것은 노련한 TeX 프로그래머에게는 따르기 쉽지만 새로운 프로그래머에게는 그다지 좋지 않습니다.
여기 에는 expl3
다음과 같이 작성됩니다.
\ExplSyntaxOn
\newcommand\copyacronym[2]{
\cs_set_eq:cc {acronym@#1} {acronym@#2}
}
\ExplSyntaxOff
의 목표 expl3
는 TeX 프로그래밍을 보다 구조화하여 더 쉽게 만드는 것입니다. 우리희망이는 이전 TeX 프로그래머보다 새로운 TeX 프로그래머의 경우 더욱 그렇습니다.
마지막 질문에 대한 대답은 다음과 같습니다. Bruno Le Floch가 패키지를 작성했는데 unravel
, 이는 확장에 대해 무슨 일이 일어나고 있는지 확실히 보여줄 수 있습니다. 글을 쓴 후
\usepackage{unravel}
\def\baz{BAZ}
\unravel{\expandafter\let\csname foo\expandafter\endcsname\csname baz\endcsname}
다음을 반환합니다.
======== Welcome to the unravel package ========
"<|" denotes the output to TeX's stomach.
"||" denotes tokens waiting to be used.
"|>" denotes tokens that we will act on.
Press <enter> to continue; 'h' <enter> for help.
||
|> \expandafter \let \csname foo\expandafter \endcsname \csname baz\endcsname
[===== Step 1 =====] \expandafter \let
[===== Step 2 =====] \csname = \csname
|| \expandafter \let
|| \csname
|> foo\expandafter \endcsname \csname baz\endcsname
[===== Step 3 =====] \expandafter \endcsname
|| \expandafter \let
|| \csname foo
|| \expandafter \endcsname
|> \csname baz\endcsname
[===== Step 4 =====] \csname = \csname
|| \expandafter \let
|| \csname foo
|| \expandafter \endcsname
|| \csname
|> baz\endcsname
[===== Step 5 =====] \endcsname
|| \expandafter \let
|| \csname foo
|| \expandafter \endcsname
|| \csname baz\endcsname
|>
[===== Step 6 =====] \csname baz\endcsname =\baz
|| \expandafter \let
|| \csname foo
|| \expandafter \endcsname
|> \baz
[===== Step 7 =====] back_input: \expandafter \endcsname
|| \expandafter \let
|| \csname foo
|> \endcsname \baz
[===== Step 8 =====] \endcsname
|| \expandafter \let
|| \csname foo\endcsname
|> \baz
[===== Step 9 =====] \csname foo\endcsname =\foo
|| \expandafter \let
|> \foo \baz
[===== Step 10 =====] back_input: \expandafter \let
||
|> \let \foo \baz
[===== Step 11 =====] \let \foo
|| \let \foo
|> \baz
[===== Step 12 =====] Set \foo=macro:->BAZ
||
|>
[===== End =====]
보시다시피, 간단한 케이스로도 꽤 한 입 먹을 수 있습니다. (소화하기 쉽지만 여전히 그렇습니다.) 특히 expl3
새로운 사용자로 디버깅할 때 이는 특정 상황에서만 유용할 수 있습니다.