나는 필드의 특성을 나타내기 위해 \char를 재정의하려고 할 때 이것을 발견했고 이상한 오류 메시지를 받았습니다. 아래는 일어난 이상한 일을 보여주는 최소한의 예입니다.
\documentclass[12pt]{article}
\usepackage{amsmath}
\renewcommand{\char}{\stepcounter{section}}
\begin{document}
\section{test}
test$1 + 1 = 2$test$2 + 2 = 4$test
\section{test}
test$1 + 1 = 2$test$2 + 2 = 4$test
\section{test}
\end{document}
이것을 조판하면 섹션 번호가 1, 3, 4가 됩니다. 이것을 실험하면서 문서의 첫 번째 인라인 수학, 디스플레이 수학 또는 정렬 환경으로 인해 \char가 한 번 호출되고 그 이후부터라는 것을 확인했습니다. on, 다른 어떤 것도 다시 호출할 수 없는 것 같습니다. 이는 amsmath 패키지가 로드된 경우에만 발생합니다. 도대체 무슨 일이 일어나고 있는 걸까요? 이상한 문제를 일으키지 않고 \char를 재정의할 수 있는 방법이 있나요?
답변1
tl;dr
안전하게 재정의할 수 있나요 \char
? 없이는많이쓸모없는 일이 될 것입니다.
\renewcommand
모르는 명령은 절대 하지 마세요 . 당신의 명령에 따라
\DeclareMathOperator{\Char}{char}
을 사용하고 \Char
. 아니면 \fldchar
가장 좋다고 생각되는 이름을 선택하세요.~ 아니다 \char
.
자세한 답변
특정 오류는 글꼴 크기 변경 후 수학 공식이 처음 나타날 때마다 실행되는 매크로 에서 amsmath
사용된다는 사실로 인해 발생합니다.\char
\resetMathstrut@
\def\resetMathstrut@{%
\begingroup
\setbox\z@\hbox{%
\mathchardef\@tempa\mathcode`\(\relax
\def\@tempb##1"##2##3{\the\textfont"##3\char"}%
\expandafter\@tempb\meaning\@tempa \relax
}%
\edef\@tempa{%
\ht\Mathstrutbox@\the\ht\z@\relax
\dp\Mathstrutbox@\the\dp\z@\relax}%
\expandafter\endgroup\@tempa
}
정렬 환경에서 사용되는 수학 스트럿을 설정한다는 점을 제외하고는 이 매크로가 수행하는 작업을 설명할 필요가 없습니다.
코드를 사용하면 이 매크로는 한 번만 실행되지만 인수에 수식을 추가하면 \section
한 번 더 실행되는 것을 볼 수 있습니다.
안전하게 재정의할 수 있는 방법이 있나요 \char
? 예, 있습니다: 전체 LaTeX 트리의 복사본을 만들고 \let\primitivechar\char
(복사본)의 시작 부분에 추가합니다 latex.ltx
. 그런 다음 \char
전체 트리에서 다른 모든 항목을 로 바꿉니다 \primitivechar
. 그런 다음 형식을 다시 컴파일하십시오. 어떤 패키지가 \char
.
ack
(또는 grep
) 을 실행하면 \char
총 960개 파일에서 8682번 나타납니다.
> ack -ch '\\char[^a-z]' /usr/local/texlive/2022/texmf-dist/tex/latex/
8682
> ack -cl '\\char' /usr/local/texlive/2022/texmf-dist/tex/latex/ | wc -l
960
하지만 당신 외에는 누구도 당신의 문서에서 LaTeX를 실행할 수 없다는 점을 고려하십시오. 그래서 귀하의 질문에 대한 대답은
예, 하지만 실제적인 목적으로는 그렇지 않습니다.
일부 배경. LaTeX3의 원래 목표 중 하나는정의 해제모든 기본 요소를 별칭으로 바꿉니다. 그러나 팀은 이것이 비실용적이라는 것을 깨달았습니다. 왜냐하면 이는 본질적으로 현재 패키지가 새 버전에서 사용될 수 없고 수천 개가 있다는 것을 의미하기 때문입니다!
원본 LaTeX에서는 왜 이 단계를 수행하지 않았나요? 여러 가지 이유로 주요 이유는 다음과 같습니다.
LaTeX가 작성될 당시에는 일반 TeX가 사용 가능한 유일한 형식이었고 LaTeX는 여러 일반 구조를 차용했습니다.
일반에서 LaTeX로 전환하는 것이 더 쉬우므로 코드를 재사용할 수 있습니다.
컴퓨터 메모리가 부족했습니다.정말부족한.
LaTeX2e가 출시되었을 때 패키지가 많지 않았기 때문에 모든 프리미티브를 앨리어싱하고 이를 앨리어스로 바꾸는 프로젝트를 수행하는 계기가 되었을 것입니다. 그러나 LaTeX는 모든 별칭이 메모리 공간을 차지하기 때문에 기본적으로 어떤 컴퓨터에서도 실행되지 않습니다. 요즘에는 이러한 메모리 고려 사항이 문제가 되지 않지만 패키지는 수천 개에 이릅니다.
어떤 경우에는 프리미티브를 재정의하는 것이 가능하지만 그 동작을 약간 변경하기 위해서만 가능합니다. \input
예를 들어 LaTeX는 로 이를 수행하지만 재정의된 것은 \input
결국 항상 프리미티브에 대한 별칭을 호출합니다.
답변2
\char
숫자로 문자에 액세스하는 TeX 프리미티브이므로 재정의하면 라텍스뿐만 아니라 모든 종류의 라텍스 구성이 중단됩니다.amsmath
\documentclass{article}
\renewcommand{\char}{\stepcounter{section}}
\begin{document}
\begin{picture}(0,0)
\put(0,0){\circle{5}}
\end{picture}
\end{document}
LaTeX는 올바른 크기의 원을 선택할 수 없습니다.
\newcommand
실수로 재정의되는 것을 방지하려면 항상 사용하세요 . \renewcommand
기존 명령의 모든 사용 동작을 변경하려는 경우 에만 사용하십시오 .