Ввести немного диалога с помощью screenplay
пакет, я должен использовать
\begin{dialogue}{Johnny} Some dialogue. \end{dialogue}
\begin{dialogue}{Jane} I see. \end{dialogue}
Это становится немного утомительным через некоторое время. Действительно ли возможно указать пользовательскую команду так, чтобы я мог использовать что-то как
\dialogue{Johnny} Some dialogue.
\dialogue{Jane} I see.
вместо этого?
Попробуйте следующее:
\newcommand{\dialogueline}[2]{\begin{dialogue}{#1} #2 \end{dialogue}}
% Usage example:
\dialogueline{Johnny}{Some dialogue.}
\dialogueline{Jane}{I see.}
Фактически вы можете получить именно то, что хотите:
\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
. Обратите внимание, что среда с именем dialog
определяет команду с именем \ dialog
, поэтому вам нужно другое имя. Не меняйте форматирование!
Это работает так: \ dialogueline
- это команда, которая не принимает аргументов, а вместо этого расширяется до нескольких последовательностей. Во-первых, токен открытия группы, чтобы поместить все, что следует, в свою собственную область видимости. Во-вторых, последовательность \ catcode` ^^ M = 12
. LaTeX присваивает каждой букве catcode : число, указывающее, какой это тип. Например, обратная косая черта - это catcode 0, конструктор имени команды; буквы - catcode 11; а небуквенные печатные символы, такие как знак at, - это код 12.Эта последовательность заставляет ^^ M
, символ новой строки, иметь код 12, поэтому мы можем взаимодействовать с ним. Наконец, мы выписываем команду \ dialogueline @ EOL
, которая выполняет основную работу.
Затем мы определяем \ dialogueline @ EOL
. Мы делаем это в группе, где символ новой строки - это код 12, точно так же, как он будет там, где \ dialogueline
развернут. Обратите внимание, что именно поэтому вы не можете разбить вторую строку новой строкой - это будет интерпретировано как текст. Затем мы определяем \ dialogueline @ EOL
, чтобы принимать два аргумента, заканчивающиеся новой строкой; он расширяется, принимая первый аргумент (который вы передаете в фигурных скобках) и передавая его в качестве аргумента среде dialog
, а также передавая второй аргумент (все, что находится после первого и до конца строки) в качестве тело окружающей среды. Наконец, \ dialogueline @ EOL
завершает группу, открытую в \ dialogueline
, так что изменение кода каталогов ^^ M
больше нигде не видно. Учитывая это, вы можете написать
\dialogueline{Johnny} Some dialogue.
\dialogueline{Jane} I see.
, и все должно работать.
Если вы предполагаете, что каждое диалоговое окно занимает один абзац (обычно оно начинается и заканчивается разрывом абзаца, состоящим из двух строк), то есть другой способ заставить \ dialog
принимать только один аргумент:
\newif\indialog \indialogfalse \def\dialogue#1{\ifindialog \end{dialogue}#1\begin{dialog}\else \everypar={\end{dialogue}\indialogfalse \everypar={}}#1\indialogtrue\begin{dialogue} \fi}
Этот код грязный и не-латексный - он устанавливает \ everypar
, не заботясь о его существующем содержании, - и в Latex есть более чистые абстракции для этого, о которых я забыл, но принцип должен быть ясен.