“\begin{environment}...\end{environment}”的自定义命令

发布于 2024-08-30 20:55:01 字数 302 浏览 4 评论 0原文

要使用 screenplay 包输入一些对话,我必须使用

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

一段时间后它会变得有点乏味。是否可以指定一个自定义命令,以便我可以使用类似的命令

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

To enter a bit of dialogue using the screenplay package, I have to use

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

It gets a bit tedious after a while. Is it possible to specify a custom command so that I can use something like

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

instead?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

婴鹅 2024-09-06 20:55:01

试试这个:

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

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

Try this:

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

% Usage example:
\dialogueline{Johnny}{Some dialogue.}  
\dialogueline{Jane}{I see.}  
怼怹恏 2024-09-06 20:55:01

事实上,您可以准确地得到您想要的:

\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-protected - 被 \makeatletter/\makeatother 包围(编辑:这意味着您将 \makeatletter 放在定义之前,将 \makeatother 放在定义之后),或者放在 .sty 文件中。请注意,名为 dialogue 的环境定义了名为 \dialogue 的命令,因此您需要一个不同的名称。不要更改格式!

它的工作方式是 \dialogueline 是一个不带参数的命令,而是扩展为多个序列。首先,一个组开放令牌,将后面的任何内容放入其自己的范围内。其次,\catcode`^^M=12 序列。 LaTeX 为每个字母分配一个 catcode :一个数字,表明它是什么类型。例如,反斜杠是catcode 0,命令名称构造函数;字母为类别代码 11;非字母打印字符(例如 at 符号)的 catcode 12。此序列使换行符 ^^M 具有 catcode 12,因此我们可以与其交互。最后,我们写出命令 \dialogueline@EOL,它完成了繁重的工作。

接下来,我们定义\dialogueline@EOL。我们在换行符为 catcode 12 的组中执行此操作,就像展开 \dialogueline 时一样。请注意,这就是为什么您不能用换行符分隔第二行的原因 - 它会被解释为文本。接下来,我们定义 \dialogueline@EOL 来接受两个参数,以换行符结尾;它通过获取第一个参数(在大括号中传递)并将其作为参数传递给 dialogue 环境来扩展,并将第二个参数(第一个参数之后和行尾之前的所有内容)传递为环境的身体。最后,\dialogueline@EOL结束在\dialogueline中打开的组,这样对^^M的catcode的更改在任何地方都不可见别的。鉴于此,您可以编写

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

并且一切都应该正常。

You can in fact get exactly what you want:

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

This code needs to be \makeatletter-protected—either surrounded by \makeatletter/\makeatother (edit: this means that you put \makeatletter before the definition, and \makeatother after it), or in a .sty file. Note that an environment named dialogue defines a command named \dialogue, so you need a different name. Do not change the formatting!

The way it works is that \dialogueline is a command which takes no arguments, but instead expands to multiple sequences. First, a group-opening token, to put whatever follows in its own scope. Second, the \catcode`^^M=12 sequence. LaTeX assigns each letter a catcode: a number which says what type it is. For instance, the backslash is catcode 0, the command-name constructor; letters are catcode 11; and non-letter printing characters, such as the at sign, are catcode 12. This sequence makes ^^M, the newline character, have catcode 12, so we can interact with it. Finally, we write out the command \dialogueline@EOL, which does the heavy lifting.

Next, we define \dialogueline@EOL. We do so within a group where the newline character is catcode 12, just as it will be where \dialogueline is expanded. Note that this is why you cannot break the second line with a newline—it would be interpreted as text. Next, we define \dialogueline@EOL to take two arguments, ending with a newline; it expands by taking the first argument (which you pass in braces) and passing it as an argument to the dialogue environment, and passing the second argument (everything after the first and before the end of line) as the body of the environment. Finally, \dialogueline@EOL ends the group opened in \dialogueline, so that the change to the catcode of ^^M is not visible anywhere else. Given this, you can write

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

and everything should work.

如梦 2024-09-06 20:55:01

如果您假设每个对话框占据一个段落(通常,它以双行段落分隔符开始和结束),那么还有另一种方法让 \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 而不关心其现有内容 - 并且 Latex 有更清晰的抽象来执行此操作,我已经忘记了,但原理应该很清楚。

If you assume that each dialog occupies one paragraph (usually, it starts and ends with a double-line paragraph break), then there is another way to have \dialogue take just one argument:

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

That code is kind of dirty and un-Latexy —it sets \everypar without caring about its existing content— and Latex has cleaner abstractions for doing it, which I have forgotten, but the principle should be clear.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文