
Я хочу определить среду теоремы, где я могу вручную выдавать нумерацию вместо того, чтобы следовать какому-то внутреннему счетчику. Оглядевшись, я обнаружил,этотответ. Там в качестве решения предлагается следующий код:
\newtheorem{innercustomthm}{Theorem}
\newenvironment{customthm}[1]
{\renewcommand\theinnercustomthm{#1}\innercustomthm}
{\endinnercustomthm}
Код работает так, как мне нужно, однако я пытался понять все в коде, на случай, если мне захочется немного его подправить (а также узнать, что я вставляю в свой документ), и немного застрял.
Прежде всего, \newenvironment имеет следующую структуру:
\newenvironment{<env-name>}[<n-args>][<default>]{<begin-code>}{<end-code>}
Я понимаю, что третий аргумент оставлен пустым; с этим проблем нет. Затем идет \renewcommand, которая имеет структуру:
\renewcommand{<cmd>}[<n-args>][<default>]{<text>}
Здесь мне трудно понять, что происходит, так как не используются фигурные скобки; я думал, что, возможно, команда позволяет их опускать, но я не нашел никакой информации об этом. И после этого все становится еще более запутанным, так как команды \theinnercustomthm, \innercustomthm и \endinnercustomthm кажутся специально созданными для этого конкретного решения, и я не понимаю, как они работают.
Например, я заметил, что изменение имени среды (например, mytheo вместо customthm) приводит к поломке кода.
Если кто-то может объяснить, что происходит, или указать мне на какое-либо руководство или веб-страницу, где я могу понять, что происходит, я буду очень признателен.
решение1
Первое, что следует отметить, это то, что
\newtheorem{innercustomthm}{Theorem}
внутренне делает что-то похожее на
\newenvironment{innercustomthm}[1][]{<begin>}{<end>}
где коды <begin>
и <end>
здесь не имеют значения. Обратите внимание, что среда ищет необязательный аргумент (теорему или атрибуцию). Она также устанавливает счетчик с тем же именем, что и среда.
Название выбрано длинным и непривлекательным намеренно: маловероятно, что такое название будет конфликтовать с существующей или воображаемой средой.
Для приложения, которое мы имеем в виду, нам на самом деле не нужен счетчик, а скорее тот факт, что любой вызов innercustomthm
будет шагать по счетчику и устанавливать то, что нужно, чтобы следующие \label
команды использовали значение счетчика. Однако LaTeX не смотрит на само значение, а использует текущее значение \the<counter>
, в данном случае \theinnercustomthm
. Значение \theinnercustomthm
также используется для нумерации окружения.
Наша идея — вручную нумеровать теоремы, поскольку нам нужно цитировать теоремы с тем же номером, который они имеют в другой публикации, поэтому автоматическая нумерация невозможна. Ну, мы создаем обертку, которая innercustomthm
будет принимать в качестве аргумента номер, который мы хотим, чтобы имело утверждение.
Итак, идея состоит в том, чтобы создать среду, принимающую аргумент, который будет использоваться для (локального) переопределения \theinnercustomthm
и вызова «внутренней» среды, которая выполнит свою работу по набору утверждения.
Определение customthm
может быть
\newenvironment{customthm}[1]
{\renewcommand{\theinnercustomthm}{#1}\begin{innercustomthm}}
{\end{innercustomthm}}
но у этого есть небольшой недостаток: если вы забудете \end{customthm}
, то получите ошибку «Missing \end
» упоминая innercustomthm
вместо customthm
. Итак,крутые программистыиспользуйте в этом случае внутреннюю версию \begin
и \end
процедуры для «внутренней» среды: бухгалтерия уже сделана \begin{customthm}
и нам не нужно ее повторять. Таким образом, мы получаем
\newenvironment{customthm}[1]
{\renewcommand{\theinnercustomthm}{#1}\innercustomthm}
{\endinnercustomthm}
Ну, фактический код, который вы цитируете, это
\newenvironment{customthm}[1]
{\renewcommand\theinnercustomthm{#1}\innercustomthm}
{\endinnercustomthm}
Почему не хватает брекетов? Еще одна (плохая) привычкакрутые программистыкоторые знают, что эти брекеты не нужны и их все равно снимут.
В случае сомнений используйте их.
решение2
Во-первых, мы должны спросить, что \newvironment{myenv}{..start code...}{...end code...}
на самом деле делает. Немного упрощая, происходит следующее: \newenvironment
определяет две команды \myenv
и \endmyenv
, где \myenv
расширяется до ...start code...
и \endmyenv
расширяется до ...end code...
. Когда вы пишете, \begin{myenv}...\end{myenv}
LaTeX заменяет эту среду кодом, который (почти) эквивалентен {\myenv ... \endmyend}
. (Немного больше происходит за кулисами.)
Далее строка \newtheorem{innercustomthm}{Theorem}
определяет innercustomthm
среду как среду "Теорема", которая использует счетчик innercustomthm
. В частности, "номер теоремы" для этой среды печатается с использованием \theinnercustomthm
.
Теперь давайте рассмотрим:
\newenvironment{customthm}[1]
{\renewcommand\theinnercustomthm{#1}\innercustomthm}
{\endinnercustomthm}
Это определяет customthm
среду, которая принимает один аргумент #1
. Согласно первому абзацу выше, \begin{customthm}[X]...\end{customthm}
расширяется до:
{\renewcommand\theinnercustomthm{X}\innercustomthm ... \endinnercustomthm}
То есть, \theinnercustomthm
переопределяется, чтобы быть равным , X
после чего innercustomthm
применяется окружение. Таким образом, customthm
окружение по сути то же самое, что и innercustomthm
окружение, за исключением того, что \theinnercustomthm
сначала устанавливается равным X
, где X
— аргумент окружения customthm
. Таким образом, чистый эффект заключается в том, что это окружение печатает: "Теорема X" ...
Наконец, вы сказалиизменение имени среды (например, mytheo
вместо customthm
) нарушает код. Если то, что я сказал, верно, то это не может быть правдой! Действительно, как показывает следующий код, код работает точно так же, если мы изменим имя среды:
\documentclass{article}
\newtheorem{innercustomthm}{Theorem}
\newenvironment{mytheo}[1]
{\renewcommand\theinnercustomthm{#1}\innercustomthm}
{\endinnercustomthm}
\begin{document}
\begin{innercustomthm}Hi
\end{innercustomthm}
\begin{mytheo}Hi
\end{mytheo}
\end{document}