확장성: LaTeX3 VS LaTeX

확장성: LaTeX3 VS LaTeX

확장성은 매크로/함수의 핵심입니다. 나는 알고 싶다:

  1. 의 확장성에 대한 더 나은 이해는 의 LaTeX3확장성에 대한 좋은 배경을 통해서만 가능합니다 LaTeX. 어디까지 독립적이라고 볼 수 있을까요?
  2. 보다 정확하게는 에서 제공하는 기능이 l3expan모든 확장성 요구 사항을 처리하기에 충분한 경우입니다. 즉, 내에서 LaTeX3"LaTeX 확장성"이 지원되지만완전히대체.
  3. 확장성 프로세스가 수행되는 동안 중간 단계를 확인할 수 있는 방법이 있습니까(예: 일부 출력 파일, 프로파일링 옵션 등)

답변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새로운 사용자로 디버깅할 때 이는 특정 상황에서만 유용할 수 있습니다.

관련 정보