Newcommand: Что нельзя сделать?

Newcommand: Что нельзя сделать?

Это не первый раз, когда я безуспешно пытаюсь создать новую команду. Некоторые вещи, которые я обнаружил, не работают (получение "неопределенной управляющей последовательности" или других ошибок).

  • Используйте аргумент «цитата-конец-цитаты».

    \newcommand{\mytest}[1]{
      \quote #1 \endquote
    }
    
  • Используйте \verbкоманду с аргументом

    \newcommand{\mytest}[1]{
      \verb+#1+
    }
    
  • Используйте begin{lstlisting}среду:

    \newcommand{\mytest}[1]{
      \begin{lstlisting}
      #1
      \end{lstlisting}
    }
    

Знаете ли вы, где я могу найти исчерпывающий список того, что я могу делать \newcommand, а что нет? А еще лучше, почему?

решение1

Довольно сложно сказать, что можно сделать с помощью \newcommand, потому что возможности (действительно) безграничны.

Я могу обсудить ваши два примера и указать на ошибки, которые вы допускаете.

В первом определении вы используете \quoteand \endquote, и это ошибка; \quoteэто команда, которую LaTeX выполняет, когда находит\begin{quote} , но это происходитпосле открытия группыкак побочный эффект \begin. Группа обычно закрывается, \endкогда LaTeX находит, \end{quote}таким образом автоматически отменяя настройки параметров, выполненные \quote.

С вашим определением, после\mytest{something} вы обнаружите, что ширина линии равнанавсегда измененои левый отступ будет продолжаться вечно. Вместо этого можно с уверенностью сказать,

\newenvironment{myenv}{\quote}{\endquote}

поскольку группировка будет предоставлена \begin{myenv}​​и \end{myenv}.

В чем главная особенность \newcommand? Давайте рассмотрим простой пример:

\newcommand{\foo}[1]{?#1!}

Теперь, если вы наберете \foo{xyz}, это будет то же самое, что набрать

?xyz!

потому что при сканировании TeX \fooзнает, что ему нужно найти аргумент (первый токен после , \fooесли это не так {, или весь список токенов до совпадающего }) и заменить \foo<argument>его текстом замены, указанным в \newcommandинструкции, где <argument>обозначается #1.

У вас может быть до девяти аргументов (или вообще ни одного). Все, что он делает, это «замена». С подходящими определениями, вместе с условными структурами, вы даже можете определить рекурсивные макросы, но это было бы слишком долго описывать. Большая часть «пользовательских определений» — это просто простые (или умеренно сложные) замены для разметки логических единиц.

TeX не сканирует то, что следует после команды, пока она неимеетto. Таким образом, при выполнении \foo, он не выйдет за пределы аргумента и не расширит макрос внутри аргумента, пока не закончится замена макроса. Таким образом, после

\foo{\baz{x}}

TeX увидит

?\baz{x}!

после чего он сначала обработает их ?, а затем будет \baz{x}действовать так, как если бы они были во входных данных с самого начала, но с небольшой разницей, которая проявляется во втором примере.

Разница в наборе текста \foo{\baz{x}}и?\baz{x}! в том, что TeX уже будет иметьтокенизированный \baz{x}.

Команда \verbработает, изменяя значение всех специальных символов. Она делает это, задерживая до тех пор, пока не станет возможным поглощение текста, который будет набран дословно, и это произойдет в группе; так

\verb+\baz{x}+

выполним следующие шаги

  1. Откройте группу (предоставив {)
  2. Начните набор текста моноширинным шрифтом
  3. Изменить значение всех специальных символов на «печатаемые»
  4. Определить +, чтобы вести себя как }(токен закрытия группы)
  5. Продолжайте печатать все, что найдете.
  6. Завершающий символ +отменит все специальные настройки.

Описание не полное, но достаточное для наших целей; имеются и другие технические детали, не имеющие значения для понимания общей картины.

Что происходит, когда вы определяете

\newcommand{\foo}[1]{\verb+#1+}

как вы предлагаете? Когда TeX видит\foo{\baz{x}} что он знает, что ему нужно сканировать аргумент и токенизировать его. Поэтому аргументчетыре жетона(Я разделяю их знаком •)

\baz • { • x • }

и никакие изменения в значении \, {и }больше не могут быть выполнены. Хуже того, +that должен изменить свое значение, чтобы стать токеном закрытия группы, не может быть изменен, поскольку он уже был токенизирован во время определения. Поэтому LaTeX имеет защитный механизм, который запрещает \verbнаходиться в аргументе команды, поскольку при его использовании в таком месте может произойти любое зло: изменение значения специальных символов без возможности отмены настройки загонит вас в угол без возможности выхода.

Есть ли обходные пути? Да, см.Как поместить команду \verb внутрь блока \textbf{}?, но прежде всего спросите себя, действительно ли вам нужна дословная формулировка аргумента к команде.

Связанный контент