我正在开发一个环境,其中每个句子都应该以换行符结尾。这应该自动发生,并且对文本的干扰最小,因为在实际使用情况下,环境的内容(将从\include
另一个文件中复制)将在其他文档中重复使用,而这种行为是不可取的。在另一个问题它是建议的可以通过激活句号来实现这一点,这样它们就可以作为一个命令,不仅可以正常打印句号,还可以插入所需的换行符。当与保护字符的非句号用法的命令结合使用时(这很烦人,但还不算太糟),这对于句号结束句子但在结束分隔符(引号、圆括号、大括号和方括号)发挥作用时发生冲突的情况相当有效。
理论上,这样的结束分隔符可以添加到环境内的活动字符列表中,但这样做会使活动字符列表变得更长,并且需要更具侵入性地使用保护功能。
有没有一种方法可以调整答案(其版本如下所示),使其考虑到结束分隔符,同时又不需要对文本进行大量的侵入?
\documentclass{article}
\begingroup
\catcode`\.=\active
\catcode`\?=\active
\catcode`\!=\active
\gdef.{\normalperiod\formattingcommand}%
\gdef?{\normalqmark\formattingcommand}%
\gdef!{\normalexclam\formattingcommand}%
\endgroup
\newcommand\formattingcommand{\newline\makebox[0pt][r]{$\rightarrow$}\ignorespaces}
\newenvironment{speech}
{ \vspace{2ex}\par
\let\normalperiod=.
\let\normalqmark=?
\let\normalexclam=!
\catcode`\.=\active
\catcode`\?=\active
\catcode`\!=\active
\sffamily\small
}{\vspace{2ex}\par}
\chardef\periodcatcode=\catcode`\.
\chardef\qmarkcatcode=\catcode`\?
\chardef\exclamcatcode=\catcode`\!
\newcommand\aeprotect[1]{%%
\begingroup
\catcode`\.=\periodcatcode
\catcode`\?=\qmarkcatcode
\catcode`\!=\exclamcatcode
\scantokens{#1\ignorespaces}%%
\endgroup
}
\begin{document}
GALLIA est omnis divisa in partes tres, quarum unam incolunt Belgae, aliam Aquitani, tertiam qui ipsorum lingua Celtae, nostra Galli appellantur. Hi omnes lingua,
institutis, legibus inter se differunt. Gallos ab Aquitanis Garumna flumen, a Belgis Matrona et Sequana dividit. Horum omnium fortissimi sunt Belgae, propterea quod a
cultu atque humanitate provinciae longissime absunt, minimeque ad eos mercatores saepe commeant atque ea quae ad effeminandos animos pertinent important, proximique sunt
\begin{speech}
\providecommand{\aeprotect}{\relax}
This is the beginning of paragraph 1.
Lorem ipsum dolor sit amet, consectetur adipiscing elit?
\aeprotect{S.P.Q.R.} Sed faucibus, sem vel suscipit eleifend, ipsum dolor tempus nunc, ut iaculis nibh arcu vitae tortor.
Pellentesque a efficitur lectus, eget sagittis lorem.
Fusce vestibulum feugiat nibh, pulvinar convallis eros sagittis ac.
Pellentesque aliquam arcu a augue malesuada, sit amet eleifend orci vulputate!
Sed nibh dolor, commodo vel risus quis, elementum consequat dui.
This is the beginning of paragraph 2.
Pellentesque eu neque eleifend, tincidunt mauris id, ultricies odio.
Aenean ac nisi congue, mollis leo a, cursus dolor!
Aenean non justo felis.
Cras interdum quam eu metus imperdiet ultricies.
Fusce finibus pellentesque volutpat?
“Praesent id lacus eget dui ullamcorper finibus nec nec urna?”
“Quisque vel vestibulum quam.”
(Lorem ipsum dolor sit amet, consectetur adipiscing elit.)
Mauris vel nisl eros.
\end{speech}
Germanis, qui trans Rhenum incolunt, quibuscum continenter bellum gerunt. Qua de causa Helvetii quoque reliquos Gallos virtute praecedunt, quod fere cotidianis proeliis
cum Germanis contendunt, cum aut suis finibus eos prohibent aut ipsi in eorum finibus bellum gerunt.
\end{document}
哦,如果它有用的话,我使用 LuaLaTeX 作为我的默认引擎,所以如果需要的话,可以随意使用该引擎的功能。
答案1
下面给出了一个可定义的异常列表\formattingcommand@exceptionlist
,您可以在其中定义在句号后应被特殊处理的标记。这些异常应该是单个字符,它们应该在您的 之前输出\newline...
。请注意,这仅适用于支持 Unicode 的引擎(因此 XeTeX 和 LuaLaTeX),其他引擎将抛出错误(因为您使用了结尾的引号字符)。
\documentclass{article}
\begingroup
\catcode`\.=\active
\catcode`\?=\active
\catcode`\!=\active
\gdef.{\normalperiod\formattingcommand}%
\gdef?{\normalqmark\formattingcommand}%
\gdef!{\normalexclam\formattingcommand}%
\endgroup
\makeatletter
\newcommand\formattingcommand@exceptionlist{(,),”}
\newif\if@formattingcommand@bool@
\newcommand\formattingcommand{\futurelet\next\formattingcommand@A}
\newcommand\formattingcommand@A
{%
\@formattingcommand@bool@false
\@for\zz:=\formattingcommand@exceptionlist\do
{%
\expandafter\let\expandafter\zzz\zz
\unskip % remove a trailing space from \zz
\ifx\zzz\next
\@formattingcommand@bool@true
\fi
}%
\if@formattingcommand@bool@
\expandafter\formattingcommand@C
\else
\formattingcommand@B
\fi
}
\newcommand\formattingcommand@B
{\newline\makebox[0pt][r]{$\rightarrow$}\ignorespaces}
\newcommand\formattingcommand@C[1]
{#1\formattingcommand@B}
\makeatother
\newenvironment{speech}
{ \vspace{2ex}\par
\let\normalperiod=.
\let\normalqmark=?
\let\normalexclam=!
\catcode`\.=\active
\catcode`\?=\active
\catcode`\!=\active
\sffamily\small
\ignorespaces
}{\vspace{2ex}\par}
\chardef\periodcatcode=\catcode`\.
\chardef\qmarkcatcode=\catcode`\?
\chardef\exclamcatcode=\catcode`\!
\newcommand\aeprotect[1]{%%
\begingroup
\catcode`\.=\periodcatcode
\catcode`\?=\qmarkcatcode
\catcode`\!=\exclamcatcode
\scantokens{#1\ignorespaces}%%
\endgroup
}
\begin{document}
GALLIA est omnis divisa in partes tres, quarum unam incolunt Belgae, aliam Aquitani, tertiam qui ipsorum lingua Celtae, nostra Galli appellantur. Hi omnes lingua,
institutis, legibus inter se differunt. Gallos ab Aquitanis Garumna flumen, a Belgis Matrona et Sequana dividit. Horum omnium fortissimi sunt Belgae, propterea quod a
cultu atque humanitate provinciae longissime absunt, minimeque ad eos mercatores saepe commeant atque ea quae ad effeminandos animos pertinent important, proximique sunt
\begin{speech}
\providecommand{\aeprotect}{\relax}
This is the beginning of paragraph 1.
Lorem ipsum dolor sit amet, consectetur adipiscing elit?
\aeprotect{S.P.Q.R.} Sed faucibus, sem vel suscipit eleifend, ipsum dolor tempus nunc, ut iaculis nibh arcu vitae tortor.
Pellentesque a efficitur lectus, eget sagittis lorem.
Fusce vestibulum feugiat nibh, pulvinar convallis eros sagittis ac.
Pellentesque aliquam arcu a augue malesuada, sit amet eleifend orci vulputate!
Sed nibh dolor, commodo vel risus quis, elementum consequat dui.
This is the beginning of paragraph 2.
Pellentesque eu neque eleifend, tincidunt mauris id, ultricies odio.
Aenean ac nisi congue, mollis leo a, cursus dolor!
Aenean non justo felis.
Cras interdum quam eu metus imperdiet ultricies.
Fusce finibus pellentesque volutpat?
“Praesent id lacus eget dui ullamcorper finibus nec nec urna?”
“Quisque vel vestibulum quam.”
(Lorem ipsum dolor sit amet, consectetur adipiscing elit.)
Mauris vel nisl eros.
\end{speech}
Germanis, qui trans Rhenum incolunt, quibuscum continenter bellum gerunt. Qua de causa Helvetii quoque reliquos Gallos virtute praecedunt, quod fere cotidianis proeliis
cum Germanis contendunt, cum aut suis finibus eos prohibent aut ipsi in eorum finibus bellum gerunt.
\end{document}
.
由于上述内容改变了您无法在环境内的语句.
中使用的定义,因为您最终会尝试类似无法解决的事情。诀窍是利用一旦读入标记,类别代码在 TeX 中不会改变的事实。因此,以下内容适用于包含句点的文件名:\input
speech
\input
foo\normalperiod\formattingcommand tex
\newcommand\speechinput[1]
{%
\begin{speech}
\providecommand\aeprotect{\relax}%
\input{#1}%
\end{speech}%
}
当您指定参数时,点会被标记化,因此不会在内部语句(位于环境内部)中\speechinput
替换为,因此输入文件内的任何点都会按预期进行评估。完整示例:\normalperiod\formattingcommand
\input
speech
\documentclass{article}
\usepackage{filecontents}
\begin{filecontents}{\jobname-input.tex}
This is the beginning of paragraph 1.
Lorem ipsum dolor sit amet, consectetur adipiscing elit?
\aeprotect{S.P.Q.R.} Sed faucibus, sem vel suscipit eleifend, ipsum dolor tempus nunc, ut iaculis nibh arcu vitae tortor.
Pellentesque a efficitur lectus, eget sagittis lorem.
Fusce vestibulum feugiat nibh, pulvinar convallis eros sagittis ac.
Pellentesque aliquam arcu a augue malesuada, sit amet eleifend orci vulputate!
Sed nibh dolor, commodo vel risus quis, elementum consequat dui.
This is the beginning of paragraph 2.
Pellentesque eu neque eleifend, tincidunt mauris id, ultricies odio.
Aenean ac nisi congue, mollis leo a, cursus dolor!
Aenean non justo felis.
Cras interdum quam eu metus imperdiet ultricies.
Fusce finibus pellentesque volutpat?
“Praesent id lacus eget dui ullamcorper finibus nec nec urna?”
“Quisque vel vestibulum quam.”
(Lorem ipsum dolor sit amet, consectetur adipiscing elit.)
Mauris vel nisl eros.
\end{filecontents}
\begingroup
\catcode`\.=\active
\catcode`\?=\active
\catcode`\!=\active
\gdef.{\normalperiod\formattingcommand}%
\gdef?{\normalqmark\formattingcommand}%
\gdef!{\normalexclam\formattingcommand}%
\endgroup
\makeatletter
\newcommand\formattingcommand@exceptionlist{(,),”}
\newif\if@formattingcommand@bool@
\newcommand\formattingcommand{\futurelet\next\formattingcommand@A}
\newcommand\formattingcommand@A
{%
\@formattingcommand@bool@false
\@for\zz:=\formattingcommand@exceptionlist\do
{%
\expandafter\let\expandafter\zzz\zz
\unskip % remove a trailing space from \zz
\ifx\zzz\next
\@formattingcommand@bool@true
\fi
}%
\if@formattingcommand@bool@
\expandafter\formattingcommand@C
\else
\formattingcommand@B
\fi
}
\newcommand\formattingcommand@B
{\newline\makebox[0pt][r]{$\rightarrow$}\ignorespaces}
\newcommand\formattingcommand@C[1]
{#1\formattingcommand@B}
\makeatother
\newenvironment{speech}
{ \vspace{2ex}\par
\let\normalperiod=.
\let\normalqmark=?
\let\normalexclam=!
\catcode`\.=\active
\catcode`\?=\active
\catcode`\!=\active
\sffamily\small
\ignorespaces
}{\vspace{2ex}\par}
\chardef\periodcatcode=\catcode`\.
\chardef\qmarkcatcode=\catcode`\?
\chardef\exclamcatcode=\catcode`\!
\newcommand\aeprotect[1]{%%
\begingroup
\catcode`\.=\periodcatcode
\catcode`\?=\qmarkcatcode
\catcode`\!=\exclamcatcode
\scantokens{#1\ignorespaces}%%
\endgroup
}
\newcommand\speechinput[1]
{%
\begin{speech}
\providecommand\aeprotect{\relax}%
\input{#1}%
\end{speech}%
}
\begin{document}
GALLIA est omnis divisa in partes tres, quarum unam incolunt Belgae, aliam Aquitani, tertiam qui ipsorum lingua Celtae, nostra Galli appellantur. Hi omnes lingua,
institutis, legibus inter se differunt. Gallos ab Aquitanis Garumna flumen, a Belgis Matrona et Sequana dividit. Horum omnium fortissimi sunt Belgae, propterea quod a
cultu atque humanitate provinciae longissime absunt, minimeque ad eos mercatores saepe commeant atque ea quae ad effeminandos animos pertinent important, proximique sunt
\speechinput{\jobname-input.tex}
Germanis, qui trans Rhenum incolunt, quibuscum continenter bellum gerunt. Qua de causa Helvetii quoque reliquos Gallos virtute praecedunt, quod fere cotidianis proeliis
cum Germanis contendunt, cum aut suis finibus eos prohibent aut ipsi in eorum finibus bellum gerunt.
\end{document}
输出显然与上面的相同。