我定义了一个命令,用于舞台剧的文本脚本。
目前,你可以写:
\says[quietly]{Minka}{Hello, are you there?}
编译后的结果类似如下:
*Minka*: (quietly) Hello, are you there?
其中Minka
为粗体、quietly
倾斜且有颜色。
然而,他们问我是否可以提供“多个方括号”,因为他们想写:
\says{Minka}{[quietly]Hello, are you there? [shouting] Is anyone there?}
编译结果应为:
*Minka*: (quieltly) Hello, are you there? (shouting) Is anyone there?
我的问题是,我能否以某种方式解析给出的文本\says{name}{text}
并用某些命令替换方括号之间的所有部分?
编辑:当前命令:
\newlength\widest
\settowidth\widest{\textbf{Longest Name in document}}
\newcommand{\says}[2]{
\begin{description}[leftmargin=\dimexpr\widest+\labelsep\relax,labelindent=0pt,labelwidth=\widest]
\item[#1] #2
\end{description}
}
其中 应该#2
是右侧的部分。我还在脚本开头重新定义了命令:
\newcommand\minka[1]{\says{Minka}{#1}} \newcommand\arthur[1]{\says{Arthur}{#1}}
并且可能使用多行或多段文字:
\minka{Hello, you//
[louder] yes, you there!
[normal voice] Is it you that helped me with that latex stuff?
}
答案1
您的要求可以通过 LaTeX3 的regex
模块来完成:
\documentclass{article}
\usepackage{xcolor}
\usepackage{xparse}
\definecolor{saysHow}{RGB}{37,29,118}
\ExplSyntaxOn
\regex_const:Nn \l__tobiscript_howsays_regex { \[ ([^\]]+) \] }
\cs_new_protected:Npn \tobiscript_says:nn #1#2
{
\tl_set:Nn \l_tmpa_tl {#2}
\regex_replace_all:NnN \l__tobiscript_howsays_regex
{ \c{how} \cB\{ \1 \cE\} }
\l_tmpa_tl
\textbf{#1:} \nobreakspace \tl_use:N \l_tmpa_tl
\par
}
\NewDocumentCommand \says { m m }
{
\tobiscript_says:nn {#1} {#2}
}
\ExplSyntaxOff
% Define how to format the things inside brackets
\newcommand*{\how}[1]{%
\textcolor{saysHow}{\textsl{(#1)}}%
~\ignorespaces % replace following spaces with one nobreak space
}
\setlength{\parindent}{0pt}
\begin{document}
\says{Minka}{[quietly]Hello, are you there? [shouting] Is anyone there?}
\says{Arthur}{[hesitating] Uh, maybe me?.. [now assured] Patsy!
Patsy's here!}
\end{document}
关于您编辑的问题,您可以使用这个。如果您不再对旧\says
命令感兴趣,只需删除其定义,然后重命名\newsays
或\says
使用您想要的新命令的任何名称。
\documentclass{article}
\usepackage{xcolor}
\usepackage{enumitem}
\usepackage{xparse}
\definecolor{saysHow}{RGB}{37,29,118}
\ExplSyntaxOn
\regex_const:Nn \l__tobiscript_howsays_regex { \[ ([^\]]+) \] }
\cs_new_protected:Npn \tobiscript_format_howsays_in_text:n #1
{
\tl_set:Nn \l_tmpa_tl {#1}
\regex_replace_all:NnN \l__tobiscript_howsays_regex
{ \c{how} \cB\{ \1 \cE\} }
\l_tmpa_tl
\tl_use:N \l_tmpa_tl
}
\cs_new_protected:Npn \tobiscript_says:nn #1#2
{
\textbf{#1:} \nobreakspace \tobiscript_format_howsays_in_text:n {#2}
\par
}
% \says command as requested in the original question
\NewDocumentCommand \says { m +m }
{
\tobiscript_says:nn {#1} {#2}
}
\NewDocumentCommand \formathowsaysintext { +m }
{
\tobiscript_format_howsays_in_text:n {#1}
}
\ExplSyntaxOff
\newlength{\widest}
\settowidth\widest{\textbf{Longest Name in document}}
% \newsays: command added to the question after the answer was provided
\newcommand{\newsays}[2]{%
\begin{description}[leftmargin=\dimexpr\widest+\labelsep\relax,
labelindent=0pt,labelwidth=\widest]
\item[#1] \formathowsaysintext{\ignorespaces #2\unskip}
\end{description}%
}
% Define how to format the things inside brackets
\newcommand*{\how}[1]{%
\textcolor{saysHow}{\textsl{(#1)}}%
~\ignorespaces % replace following spaces with one nobreak space
}
\setlength{\parindent}{0pt}
\begin{document}
\says{Minka}{[quietly]Hello, are you there? [shouting] Is anyone there?}
\says{Arthur}{[hesitating] Uh, maybe me?.. [now assured] Patsy!
Patsy's here!}
\newsays{Roger}{
[irritated]Oh, what sad times are these when passing ruffians can say ``ni''
at will to old ladies.
[sorry for interrupting the show] Stupid paragraph added only to show this
can be done. [again, really sorry!] Back to the text in one second.
There is a pestilence upon this land. Nothing is sacred. Even
those who arrange and design shrubberies are under considerable economic
stress at this period in history.
}
\newsays{Arthur}{
[showing sudden interest] Did you say ``shrubberies''?
}
\end{document}
答案2
您可以使用不同的宏来表示某人“如何”说某事,例如:
\documentclass{article}
\usepackage{xcolor}
\newcommand{\how}[1]{
\textit{\textcolor{red}{(#1)}}
}
\begin{document}
\how{quietly} Hello, are you there? \how{shouting} Is anyone there?
\end{document}
答案3
如果你确实想要这个界面,你可以用 TeX 解析文本:
\documentclass{article}
\usepackage{enumitem}
\newlength\widest
\settowidth\widest{\textbf{Longest Name in document}}
\makeatletter
\def\@stop{\@stop}%
\long\def\says@parse#1[#2]{%
#1%
\ifx\@stop#2\else
\how{#2}%
\expandafter\says@parse
\fi
}
\long\def\says#1#2{%
\begin{description}[leftmargin=\dimexpr\widest+\labelsep\relax,labelindent=0pt,labelwidth=\widest]%
\item[#1]%
\says@parse #2[\@stop]%
\end{description}%
}
\def\how#1{%
\ifhmode\unskip\ \fi
\textsl{(#1)}%
~\ignorespaces
}
\let\normalbackslash\@backslashchar
\makeatother
\begin{document}
\says{Minka}{[quietly]Hello, are you there? [shouting] Is anyone there?}
\says{Tobi}{
[annoyed] Oh, don't be so fearful.
You know I'm here!
Just don't concentrate on what you're doing and you'll be fine.
[rambling]
It's not like a lot could go wrong anyway.
I mean, it's just a program, your computer won't literally explode.
If you somehow mess it up completely, we'll just reinstall it and you can try again.
[resigned] But okay, I'll explain it to you again.
[lecturing] You just write \texttt{\normalbackslash says}, then a pair of braces containing the name of the person speaking\dots
[pausing] Good, like that.
Now you open another pair of braces and put their dialogue in there.
Close the brace, and [happily] you're done.
}
\end{document}
但这有一些缺点。
- 我认为语法不太适合使用。每当你输入许多段落作为宏的参数时,停下来问问自己这是否真的应该是一个环境
- 更重要的是,由于这个原因,您不能使用任何改变
\catcode
文本内部 s 的宏(例如\verb
)。在我的示例中,我不得不使用\texttt
and\@backslashchar
。
我认为,更好的方法是使用环境和主动角色。我们确实不是想要使[
(或]
) 处于活动状态,因为这会破坏所有可选参数。不过,如果您愿意将语法从 更改为[instruction]
,|instruction|
我们可以很好地做到这一点。
\documentclass{article}
\usepackage{enumitem}
\newlength\widest
\settowidth\widest{\textbf{Longest Name in document}}
\makeatletter
\def\@speech#1{%
\item[#1]%
\catcode`\|=13
}
\newenvironment{dialogue}{%
\let\speech\@speech
\begin{description}[leftmargin=\dimexpr\widest+\labelsep\relax,labelindent=0pt,labelwidth=\widest]%
}{%
\end{description}%
}
\def\how#1{%
\ifhmode\unskip\ \fi
\textsl{(#1)}%
~\ignorespaces
}
{
\catcode`\|=12
\gdef\verticalbar{|}
\catcode`\|=13
\AtBeginDocument{%
\gdef|{\ifmmode\verticalbar\else\expandafter\@how\fi}%
}
\gdef\@how#1|{%
\how{#1}%
}
}
\makeatother
\begin{document}
\begin{dialogue}
\speech{Minka}
|quietly|Hello, are you there? |shouting| Is anyone there?
\speech{Tobi}
|annoyed| Oh, don't be so fearful.
You know I'm here!
Just don't concentrate on what you're doing and you'll be fine.
|rambling|
It's not like a lot could go wrong anyway.
I mean, it's just a program, your computer won't literally explode.
If you somehow mess it up completely, we'll just reinstall it and you can try again.
|resigned| But okay, I'll explain it to you again.
|lecturing| In the \verb|dialogue| environment, you just write \verb|\speech|, then a pair of braces containing the name of the person speaking\dots
|pausing| Good, like that.
Now you just type on what they should say.
Close the brace, and |happily| you're done.
\end{dialogue}
\end{document}