中间诗是一种类似于首字母诗的诗歌/文本,只是“主干词”位于中间。Wiki 的文章对此进行了很好的解释。
这种格式是由作曲家约翰·凯奇首创的,随着时间的推移,他增加了更多的规则,并开始用它来“写”大段的文本(比如瓦尔登湖)创作了数百首或更多的中观诗歌。最终,他找到了一些人,通过软件将这一过程自动化。
我创建了自己的中观生成器。下面是使用 Poe 的乌鸦书脊上印有“Lenore”字样:
nearLy napping,
camE a
tappiNg,
as Of
gently Rapping,
at my chambEr door.
大致来说,可以通过以下代码实现:
\documentclass[11pt]{memoir}
\usepackage{fancyvrb}
\usepackage{DejaVuSansMono}
\begin{document}
\begin{Verbatim}[xleftmargin=-35mm,commandchars=\\\{\}]
near\textbf{L}y napping,
cam\textbf{E} a
tappi\textbf{N}g,
as \textbf{O}f
gently \textbf{R}apping,
at my chamb\textbf{E}r door.
\end{Verbatim}
\end{document}
我的中间生成器是用 Lua 编写的,可以自动在左侧添加足够的空间以使书脊沿着中心排列(另外我还添加了粗体内容)。
这对于等宽字体来说非常有效。当我浏览凯奇的书时,我发现他使用了比例字体,但仍然保留了书脊完美地位于中间的格式。我猜这是排字员手动完成的。
所以我想知道是否有人知道如何使用 TeX/LaTeX 中的比例字体自动格式化中间体?
几点说明:
LuaLaTeX 中的解决方案就很好。
在 Cage 和我的 mesostics 中,所有字母都转换为小写,只有脊柱字母大写。这可以用来帮助格式化吗?
Cage 的规则将一行中的字符总数限制为 90 个左右(书脊字母两侧限制为 45 个字符)。我在软件中遵循此规则。事实上,当行变长时,我会自动更改字体大小。
答案1
免责声明。 下面的代码并不以任何方式暗示我认可或以其他方式尊重约翰·凯奇的任何作品。
以下方法在 处分割输入\\
,然后逐行构建,设置一个,\hbox
其中测量中心字母的宽度;然后框将由
- 一个宽度为线宽的一半减去中心字母宽度的一半的框,右对齐;
- 中心字母;
- 类似于步骤 1 的盒子,但左对齐。
\documentclass{article}
\usepackage{environ,xparse}
\usepackage{kantlipsum} % for context
\ExplSyntaxOn
\NewEnviron{mesostic}
{
\par\addvspace{\topsep}
\mesostic_build:V \BODY
\addvspace{\topsep}
}
\seq_new:N \l__mesostic_body_seq
\box_new:N \l__mesostic_center_box
\cs_new_protected:Nn \mesostic_build:n
{
\seq_set_split:Nnn \l__mesostic_body_seq { \\ } { #1 }
\seq_map_inline:Nn \l__mesostic_body_seq
{
\__mesostic_line:w ##1 \q_stop
}
}
\cs_generate_variant:Nn \mesostic_build:n { V }
\cs_new_protected:Npn \__mesostic_line:w #1 | #2 | #3 \q_stop
{
\hbox_set:Nn \l__mesostic_center_box { \textbf{#2} }
\hbox_to_wd:nn { \linewidth }
{
\hbox_to_wd:nn { (\linewidth-\box_wd:N \l__mesostic_center_box)/2 }
{
\hss #1
}
\textbf{#2}
\hbox_to_wd:nn { (\linewidth-\box_wd:N \l__mesostic_center_box)/2 }
{
#3 \hss
}
}
}
\ExplSyntaxOff
\begin{document}
\kant[1]
\begin{mesostic}
near|L|y napping, \\
cam|E| a \\
tappi|N|g, \\
as |O|f \\
gently |R|apping, \\
at my chamb|E|r door.
\end{mesostic}
\kant[2]
\end{document}
改变字体可以通过进行试验性排版并测量每个部分来实现,以查看它是否满足包含在线宽的约束;如果失败,则停止,更改字体大小并重复。
允许使用可选参数来声明字体或字体大小(或两者)的变体;还添加了尾随检查\\
。主要代码已简化(感谢 jfbu 的创意)。
\documentclass{article}
\usepackage{environ,xparse}
\usepackage{kantlipsum} % for context
\ExplSyntaxOn
\NewEnviron{mesostic}[1][]
{
#1
\par\addvspace{\topsep}
\mesostic_build:V \BODY
\addvspace{\topsep}
}
\seq_new:N \l__mesostic_body_seq
\cs_generate_variant:Nn \tl_if_empty:nT { x }
\cs_new_protected:Nn \mesostic_build:n
{
\seq_set_split:Nnn \l__mesostic_body_seq { \\ } { #1 }
% check for a trailing \\
\tl_if_empty:xT { \seq_item:Nn \l__mesostic_body_seq { -1 } }
{
\seq_pop_right:NN \l__mesostic_body_seq \l_tmpa_tl
}
\seq_map_inline:Nn \l__mesostic_body_seq
{
\__mesostic_line:w ##1 \q_stop
}
}
\cs_generate_variant:Nn \mesostic_build:n { V }
\cs_new_protected:Npn \__mesostic_line:w #1 | #2 | #3 \q_stop
{
\hbox_to_wd:nn { \linewidth }
{
\hss
\hbox_to_wd:nn { 0pt } { \hss \tl_lower_case:n { #1 } }
\textbf{\tl_upper_case:n { #2 }}
\hbox_to_wd:nn { 0pt } { \tl_lower_case:n { #3 } \hss }
\hss
}
}
\ExplSyntaxOff
\begin{document}
\kant[1]
\begin{mesostic}
near|L|y napping, \\
cam|E| a \\
tappi|N|g, \\
as |O|f \\
gently |R|apping, \\
at my chamb|E|r door.
\end{mesostic}
\kant[2]
\begin{mesostic}[\sffamily\footnotesize]
NEAR|l|Y NAPPING \\
CAM|e| A \\
TAPPI|n|G \\
AS |o|F \\
GENTLY |r|APPING \\
AT MY CHAMB|e|R DOOR \\
\end{mesostic}
\kant[3]
\end{document}
答案2
\documentclass{article}
\makeatletter
\def\mesostic@end{\end{mesostic}}
\begingroup\catcode`\^^M\active
\gdef\mesostic@aux#1|#2|#3\mesostic@aux%
{\noindent\hfill%
\llap{\MakeLowercase{#1}}%
\textbf{\MakeUppercase{#2}}%
\rlap{\MakeLowercase{#3}}%
\hfill\hbox{}\par%
\expandafter^^M}%
\endgroup
\newenvironment{mesostic}{\parskip0pt\relax
\obeylines
\begingroup\lccode`~`\^^M
\lowercase{\endgroup\def~##1~}{%
\def\mesostic@tmp{##1}%
\ifx\mesostic@tmp\mesostic@end
\expandafter\mesostic@end
\else
\mesostic@aux##1\mesostic@aux
\fi}%
}{}
\makeatother
\begin{document}
blah blah blah
\noindent X\dotfill X
\begin{mesostic}
near|L|y napping,
cam|E| a
tappi|N|g,
as |O|f
gently |R|apping,
at my chamb|E|r door.
\end{mesostic}
\noindent X\dotfill X
blah blah blah
\noindent X\dotfill X
\begin{mesostic}
NEAR|l|Y NAPPING,
CAM|e| A
TAPPI|n|G,
AS |o|F
GENTLY |r|APPING,
AT MY CHAMB|e|R DOOR.
\end{mesostic}
\noindent X\dotfill X
blah blah blah
\end{document}
并使用X\dotfill X\dotfill X
额外的行来表示上下文:
答案3
\documentclass{article}
\makeatletter
\let\zzfont\textbf
{\obeylines\everyeof{\noexpand}%
\gdef\zzz#1{%
\catcode`#1\active\scantokens{\def\zzzz{\gdef#1}}%
\zzzz##1^^M{\makebox[.5\textwidth][l]{\zzfont{\string#1}##1}\par}%
}}
\def\zz{\flushright\obeylines%
\let\or\zzz\@Alph{0\fi\iftrue}}%
\def\endzz{\endflushright}
\begin{document}
\begin{zz}
nearLy napping,
camE a
tappiNg,
as Of
gently Rapping,
at my chambEr door.
\end{zz}
\renewcommand\zzfont[1]{\large$\mathcal{#1}$}
\begin{zz}
nearLy napping,
camE a
tappiNg,
as Of
gently Rapping,
at my chambEr door.
\end{zz}
\end{document}