Пользовательская команда для '\ begin {environment} ... \ end {environment}' - PullRequest
9 голосов
/ 29 апреля 2010

Чтобы ввести немного диалога, используя пакет screenplay, я должен использовать

\begin{dialogue}{Johnny} Some dialogue. \end{dialogue}
\begin{dialogue}{Jane} I see. \end{dialogue}

Через некоторое время становится немного утомительно. Можно ли указать пользовательскую команду, чтобы я мог использовать что-то вроде

\dialogue{Johnny} Some dialogue.
\dialogue{Jane} I see.

вместо

Ответы [ 3 ]

12 голосов
/ 29 апреля 2010

На самом деле вы можете получить именно то, что вы хотите:

\newcommand{\dialogueline}{\begingroup\catcode`\^^M=12 \dialogueline@EOL}
{\catcode`\^^M=12\gdef\dialogueline@EOL#1#2^^M{\begin{dialogue}{#1}#2\end{dialogue}\endgroup}}

Этот код должен быть \makeatletter -защищен - либо окружен \makeatletter / \makeatother ( edit : это означает, что вы ставите \makeatletter перед определение и \makeatother после него) или в файле .sty. Обратите внимание, что среда с именем dialogue определяет команду с именем \dialogue, поэтому вам нужно другое имя. Не меняйте форматирование!

То, как это работает, заключается в том, что \dialogueline - это команда, которая не принимает аргументов, но расширяется до нескольких последовательностей. Во-первых, токен открытия группы, чтобы поместить все, что следует, в его собственную область. Во-вторых, последовательность \catcode`^^M=12. LaTeX присваивает каждой букве catcode : число, указывающее, какой это тип. Например, обратная косая черта - это код 0, конструктор имени команды; буквы каток 11; и непечатаемые символы печати, такие как знак at, являются catcode 12. Эта последовательность делает ^^M, символ новой строки, имеет catcode 12, поэтому мы можем взаимодействовать с ним. Наконец, мы выписываем команду \dialogueline@EOL, которая выполняет тяжелую работу.

Далее мы определяем \dialogueline@EOL. Мы делаем это в группе, где символ новой строки - это код 12, так же, как и в случае, когда \dialogueline раскрывается. Обратите внимание, что именно поэтому вы не можете разбить вторую строку новой строкой & mdash; она будет интерпретирована как текст. Далее мы определяем \dialogueline@EOL для двух аргументов, заканчивающихся символом новой строки; он расширяется, беря первый аргумент (который вы передаете в скобках) и передавая его в качестве аргумента в среду dialogue, и передавая второй аргумент (все после первого и до конца строки) в качестве тела среды , Наконец, \dialogueline@EOL завершает группу, открытую в \dialogueline, так что изменение катод-кода ^^M больше нигде не видно. Учитывая это, вы можете написать

\dialogueline{Johnny} Some dialogue.
\dialogueline{Jane}   I see.

и все должно работать.

8 голосов
/ 29 апреля 2010

Попробуйте это:

\newcommand{\dialogueline}[2]{\begin{dialogue}{#1} #2 \end{dialogue}}

% Usage example:
\dialogueline{Johnny}{Some dialogue.}  
\dialogueline{Jane}{I see.}  
3 голосов
/ 29 апреля 2010

Если вы предполагаете, что каждое диалоговое окно занимает один абзац (обычно оно начинается и заканчивается двухстрочным разрывом абзаца), то есть другой способ заставить \dialogue принимать только один аргумент:

\newif\indialog \indialogfalse
\def\dialogue#1{\ifindialog \end{dialogue}#1\begin{dialog}\else 
                \everypar={\end{dialogue}\indialogfalse \everypar={}}#1\indialogtrue\begin{dialogue} 
                \fi}

Этот код немного грязный и не латексный - он устанавливает \everypar, не заботясь о существующем контенте & mdash; и у латекса есть более чистые абстракции для этого, о которых я забыл, но принцип должен быть ясен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...