“\begin{environment}...\end{environment}”的自定义命令
要使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
试试这个:
Try this:
事实上,您可以准确地得到您想要的:
此代码需要是
\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的更改在任何地方都不可见别的。鉴于此,您可以编写并且一切都应该正常。
You can in fact get exactly what you want:
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 nameddialogue
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 thedialogue
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 writeand everything should work.
如果您假设每个对话框占据一个段落(通常,它以双行段落分隔符开始和结束),那么还有另一种方法让
\dialogue
仅采用一个参数:该代码是友好的肮脏和非 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: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.