2010-04-28 2 views
9

Чтобы ввести немного диалога, используя screenplay пакет, я должен использоватьПользовательские команды для « начать {среды} ... {конец среды}»

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

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

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

вместо этого?

+0

В зависимости от того, какой редактор вы используете, вы также можете посмотреть в пакет сниппетов. – Mica

+0

+1 Это действительно интересный вопрос – Geoff

ответ

8

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

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

% Usage example: 
\dialogueline{Johnny}{Some dialogue.} 
\dialogueline{Jane}{I see.} 
+0

Это прекрасно работает. Большое спасибо! – njt

+1

Это хороший ответ, но если кто-то знает, как копировать точный формат, запрошенный оригинальным плакатом, было бы неплохо увидеть. – Geoff

+1

Я думаю, это примерно так же близко, как вы можете дойти до того, что хочет плакат. Должны быть скобки вокруг текста, поэтому LaTeX знает, где правильно положить '\ begin {dialog}' и '\ end {dialog}'. Кроме того, я использовал '\ dialogueline' в случае, если есть еще одна команда с именем' \ dialog', но если это не так, то плакат может заменить '\ dialogueline'' 'диалогом вместо этого, если не вызывает ошибок. –

12

Вы можете фактически получить именно то, что вы хотите:

\newcommand{\dialogueline}{\begingroup\catcode`\^^M=12 \[email protected]} 
{\catcode`\^^M=12\gdef\[email protected]#1#2^^M{\begin{dialogue}{#1}#2\end{dialogue}\endgroup}} 

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

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

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

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

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

+0

Очень хороший ответ! (+1) – topskip

+1

Это довольно умно. До сих пор я не знал о '\ catcode'. В то время как мое решение будет работать на все, что находится внутри брекетов, ваш будет работать на однострочные линии и будет ближе к запрошенному синтаксису искателя. –

+0

Трюк на самом деле меньше о кодах и больше о сопоставлении с образцом в '\ def': вы также можете сделать что-то вроде' \ gdef \ dialogueline @ EOL # 1: # 2 ^^ M', чтобы иметь возможность писать '\ dialogueline Джонни: Некоторый диалог. Переключатель catcode состоит в том, что конец строки не просто рассматривается как пробельный символ и игнорируется, а вместо этого рассматривается как подходящий символ. Вы правы, что это может запретить некоторые допустимые строки (хотя некоторые из них могут быть разрешены путем спряжения сопоставленной строки в фигурных скобках, например '\ dialogueline {Alexander: the Great}: Die!'), Но это хорошо для ярлыков и встроенные DSL. –

3

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

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

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

+0

Это умно, я раньше не видел эту технику. –

Смежные вопросы