TeX 帮助书写隐藏的首字母缩略词

TeX 帮助书写隐藏的首字母缩略词

这是一个有趣的挑战。尝试想出(并编写)技术,通过这些技术(La)TeX 可以帮助作者将首字母缩略词在他们的写作中。维基百科的定义:

一个首字母缩略词是一首诗或其他形式的写作,其中每行、每段或文本中其他重复特征的首字母、音节或单词拼出一个单词或一个信息。

文章中包含许多有趣的例子。

我不指望 TeX 能做所有的工作(尽管这会让你大的加分),但我可以想象它可能会以多种方式提供帮助:

  1. 允许作者断言特定的首字母缩略词是否存在,如果不存在则生成警告/错误。
  2. 对于“每行第一”的品种,巧妙地调整换行点帮助。
  3. 可选择显示秘密消息中已经与以下内容“对齐”的部分不同的格式

如果您有其他好的想法,或者更好的是,可行的代码(不必完美),请与我们分享!:-)

澄清观点

我提出这个挑战的初衷是合作编写一个包,让你首先能够嵌入隐藏信息变成文本。我同意所提出的问题具有误导性。

理想情况下,普通读者根本不应该意识到首字母缩略词的存在,因此换行应该遵循文本的自然流程。

这对作者来说是一个挑战。我设想的软件包将允许作者说明他想要隐藏什么消息以及隐藏在哪里。界面可能看起来像这样(使用 David 的示例):

\begin{acrostic}{1 letter}{every line}{TeXisfun}
    The trick is to let the system find the line breaks such
    that the expected letter starts each line. It is much easier
    if the source is XML. This main text is more or less relevant
    to the subject raised in the question. This text is far more
    interesting than boring Lipsum that you see in so many other
    answers on this site. You may find a distinct lack of TikZ in
    this answer, booktabs doesn't show up and nor does Lua. You
    will note how no special markup is needed: \TeX\ has a built-
    in ability to find the correct breaks.
\end{acrostic}

如上所述,LaTeX 可能会:

  • 当作者的首字母缩略词被破坏时,警告作者,
  • 在某种程度上,通过巧妙操纵断行惩罚或其他巧妙的策略,迫使首字母缩略词出现。

这是理想情况,但可能不可行。我认为实施其他“几乎同样好”的解决方案会更容易,例如允许作者在全文中明确标记相关字母,然后让 LaTeX 以此为基础进行工作。

从评论和答案中收集的想法

  1. 对于“每行第一行”的变体:巧妙地调整\textwidth提供帮助。[大卫·卡莱尔]
  2. 对于“每行首字”的变体:我们可以采取相反的做法,强制将首字与左边距对齐,并在段落太松或太紧时警告作者,而不是保持文本的自然流畅并在首字与首字之间断开时警告作者。[作者:Steven B. Segletes]
  3. 我们需要对跨多​​个部分或章节的首字母缩略词进行特殊处理。[作者:Ivan Andrus]

答案1

注意:文章末尾添加了实际应用!重新修订以重新扩展功能(并显著压缩编码),详情如下:

以下宏是针对左对齐首字母缩略词引入的。本文后面将介绍针对中线首字母缩略词的宏。

\RAWacrostic{acrostic}- 以普通、未改变的模式查看首字母缩略词

\SHOWacrostic[# acrostic chars]{acrostic}- 以突出显示的首字母缩写(大写粗体)来查看,不刷新。

\MEASUREacrostic[test width]{acrostic}- 查看首字母缩略词每行的自然宽度。使用可选的长度参数,它将告诉您将首字母缩略词调整到给定长度后产生的单词间距。注意:宽度必须以字符串形式提供,如200pt\the\textwidth

\FLUSHacrostic[width]{acrostic}\textwidth- 将首字母缩进段落。除非可选参数另有规定,否则宽度为。

该宏\SHOWacrostic采用一个可选参数,即要将多少个首字母大写并加粗。辅助宏\accnt就是将这些字母大写并加粗。 \accnt它还会避免突出显示首字母标点符号,而是查找字母。要查看此功能,请在输出中查找包含“Love not”的行,其中“L”而不是引号加粗。

\MEASUREacrostic可以提供如何改善长度以及设置文本的宽度的指导。 \FLUSHacrostic将设置文本的宽度作为可选参数。当然,如果你的首字母缩略词的行长差异很大,那么它看起来就不会那么好了。

还引入了中线首字母缩略词 [请参阅本文末尾提到的更多内容]。

已编辑以恢复由于软件包升级造成的破坏而丢失的功能。

\documentclass{article}
\usepackage{stackengine, stringstrings, calc}
\parskip 1em
\newcounter{index}
\def\stackalignment{l}
\def\stacktype{L}
\newcounter{nexttolast}
\newcounter{wordindex}
\newcounter{linegaps}
\newlength\natwidth
\newlength\extragapwidth
\newlength\spacewidth
\newsavebox{\verseline}
\sbox{\verseline}{-}
\setlength\spacewidth{\wd\verseline}
\makeatletter

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% The \getargsC macro mimics the behavior of the \getargs macro
% of the stringstrings package, but runs faster, and can handle
% arbitrary tokens.  For the development of \getargsC, significant
% assistance was provided by David Carlisle, for which the author is
% most appreciative.
% http://tex.stackexchange.com/questions/101604/
%      parsing-strings-containing-diacritical-marks-macros
%
\def\string@end{$\SaveHardspace}
\def\converttilde{F}
\newcounter{arg@index}
\newcounter{break@count}
\let\SaveHardspace~%%%
%
\def\getargsC#1{%
  \if T\converttilde\def~{ }\else\catcode`~=12\fi
  \protected@edef\the@string{#1}%
  \setcounter{arg@index}{0}%
  \lowercase{\expandafter\parse@Block\the@string} \string@end
  \let~\SaveHardspace%
  \catcode`~=13
}
%
\def\parse@Block#1 {%
  \stepcounter{arg@index}%
  \@namedef{arg\roman{arg@index}}{#1}%
  \futurelet\tmp\parse@Block@}
%
\def\parse@Block@{%
\ifx\tmp\string@end\edef\narg{\thearg@index}\expandafter\@gobble
\else\expandafter\parse@Block\fi}
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newcommand\@acrostic[3]{%
  \def\quietstack{T}%
  \getargsC{#2}%
  \setcounter{nexttolast}{\narg}%
  \addtocounter{nexttolast}{-1}%
  \setcounter{index}{1}%
  \if R#3\sbox{\stackedbox}{\argi}\else%
  \if S#3\sbox{\stackedbox}{\@accnt{\argi}{#1}}\else%
  \if M#3\if x#1\else(Ref: #1)\fi\sbox{\stackedbox}{\@measure{\argi}{#1}}\else%
  \if F#3\sbox{\stackedbox}{\@fittowidth{\argi}{#1}}%
  \fi\fi\fi\fi%
  \whiledo{\value{index}<\value{nexttolast}}{%
    \stepcounter{index}%
    \edef\poemline{\csname arg\roman{index}\endcsname}%
    \if R#3\stackon{\poemline}{\usebox{\stackedbox}}\else%
    \if S#3\stackon{\@accnt{\poemline}{#1}}{\usebox{\stackedbox}}\else%
    \if M#3\stackon{\@measure{\poemline}{#1}}{\usebox{\stackedbox}}\else%
    \if F#3\stackon{\@fittowidth{\poemline}{#1}}{\usebox{\stackedbox}}%
    \fi\fi\fi\fi%
  }%
  \stepcounter{index}%
  \edef\poemline{\csname arg\roman{index}\endcsname}%
  \if R#3\stackon{\poemline}{\usebox{\stackedbox}}\else%
  \if S#3\stackon{\@accnt{\poemline}{#1}}{\usebox{\stackedbox}}\else%
  \if M#3\stackon{\@measure{\poemline}{#1}}{\usebox{\stackedbox}}\else%
  \if F#3\stackon{\poemline}{\usebox{\stackedbox}}%
  \fi\fi\fi\fi%
  \usebox{\stackedbox}%
  \def\quietstack{F}%
}
\newcommand\RAWacrostic[2][1]{\@acrostic{#1}{#2}{R}}
\newcommand\SHOWacrostic[2][1]{\@acrostic{#1}{#2}{S}}
\newcommand\MEASUREacrostic[2][x]{\@acrostic{#1}{#2}{M}}
\newcommand\FLUSHacrostic[2][\textwidth]{\@acrostic{#1}{#2}{F}}

\newcommand\@MIDacrostic[3]{%
  \getargsC{#2}%
  \setcounter{nexttolast}{\narg}%
  \addtocounter{nexttolast}{-1}%
  \setcounter{index}{1}%
  \if R#3\sbox{\stackedbox}{\argi}\else%
  \if S#3\sbox{\stackedbox}{\argi}\else%
  \if M#3\if x#1\else(Ref: #1)\fi\sbox{\stackedbox}{\@measure{\argi}{#1}+}%
  \fi\fi\fi%
  \whiledo{\value{index}<\value{nexttolast}}{%
    \addtocounter{index}{2}%
    \edef\poemline{\csname arg\roman{index}\endcsname}%
    \if R#3\stackengine{\Lstackgap}{\poemline}{\usebox{\stackedbox}}{O}{r}{T}{F}{L}\else%
    \if S#3\stackengine{\Lstackgap}{\poemline}{\usebox{\stackedbox}}{O}{r}{T}{F}{L}\else%
    \if M#3\stackengine{\Lstackgap}{\@measure{\poemline}{#1}+}{\usebox{\stackedbox}}{O}{r}{T}{F}{L}%
    \fi\fi\fi%
  }%
  \usebox{\stackedbox}%
\if R#3#1\fi%
  \setcounter{index}{2}%
  \if R#3\sbox{\stackedbox}{\argii}\else%
  \if S#3\sbox{\stackedbox}{\@accnt{\argii}{#1}}\else%
  \if M#3\sbox{\stackedbox}{\@measure{\argii}{#1}}%
  \fi\fi\fi%
  \whiledo{\value{index}<\narg}{%
    \addtocounter{index}{2}%
    \edef\poemline{\csname arg\roman{index}\endcsname}%
    \if R#3\stackengine{\Lstackgap}{\poemline}{\usebox{\stackedbox}}{O}{l}{T}{F}{L}\else%
    \if S#3\stackengine{\Lstackgap}{\@accnt{\poemline}{#1}}{\usebox{\stackedbox}}{O}{l}{T}{F}{L}\else%
    \if M#3\stackengine{\Lstackgap}{\@measure{\poemline}{#1}}{\usebox{\stackedbox}}{O}{l}{T}{F}{L}%
    \fi\fi\fi%
  }%
  \usebox{\stackedbox}%
}
\newcommand\RAWMIDacrostic[2][]{\@MIDacrostic{#1}{#2}{R}}
\newcommand\SHOWMIDacrostic[2][1]{\@MIDacrostic{#1}{#2}{S}}
\newcommand\MEASUREMIDacrostic[2][\textwidth]{\@MIDacrostic{x}{#2}{M}}
% HELPER ROUTINES
\newcommand\@fittowidth[2]{%
  \getargsC{#1}%
  \setcounter{wordindex}{1}%
  \parbox[b]{#2}{%
    \argi%
    \whiledo{\value{wordindex} < \narg}{%
      \stepcounter{wordindex}%
      \hfill\csname arg\roman{wordindex}\endcsname%
    }%
  }%
}
\newcommand\@measure[2]{%
  \sbox{\verseline}{#1}%
  \setlength\natwidth{\wd\verseline}%
  \the\natwidth%
  \if x#2\else%
  \getargsC{#1}%
  \setcounter{linegaps}{\narg}%
  \addtocounter{linegaps}{-1}%
  \setlength\extragapwidth{(#2-\natwidth)/\thelinegaps+\spacewidth}%
  (\the\extragapwidth)%
  \fi%
}
\newcommand\@accnt[2]{%
  \if T\ignorepunctuation%
    \alphabetic[q]{#1}%
    \substring[q]{\thestring}{1}{1}%
    \edef\searchletter{\thestring}%
    \whereischar[q]{#1}{\searchletter}%
    \edef\searchletterloc{\theresult}%
  \else%
    \edef\searchletterloc{1}%
  \fi%
          \substring{#1}{1}{\searchletterloc-1}%
          \substring[q]{#1}{\searchletterloc}{\searchletterloc+#2-1}%
          \textbf{\caseupper{\thestring}}%
          \substring{#1}{\searchletterloc+#2}{$}%
}
\def\ignorepunctuation{T}
\makeatother
\parindent 0in
\begin{document}
\SHOWacrostic{My very excellent mother just served us nachos}
tells us the planets: 
\SHOWacrostic{Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune}

\def\months{%
 {Janet was quite ill one day.}
 {Febrile trouble came her way.}
 {Martyr-like, she lay in bed;}
 {Aproned nurses softly sped.}
 {Maybe, said the leech judicial}
 {Junket would be beneficial.}
 {Juleps, too, though freely tried,}
 {Augured ill, for Janet died.}
 {Sepulchre was sadly made.}
 {Octaves pealed and prayers were said.}
 {Novices with ma'y a tear}
 {Decorated Janet's bier.}}

\RAWacrostic[3]{\months}
~~
\SHOWacrostic[3]{\months}

\clearpage
\def\liz{%
 {Elizabeth it is in vain you say}
 {``love not'' thou sayest it in so sweet a way:}
 {in vain those words from thee or L.E.L.}
 {Zantippe's talents had enforced so well:}
 {Ah! if that language from thy heart arise,}
 {breath it less gently forth and veil thine eyes.}
 {Endymion, recollect, when Luna tried}
 {to cure his love was cured of all beside}
 {his follie pride and passion for he died.}}
%
\RAWacrostic{\liz}

\SHOWacrostic{\liz}

\MEASUREacrostic{\liz}~~~~~
\MEASUREacrostic[185pt]{\liz}


The measuring algorithm assumes a natural space is the same width as a
hyphen, namely \the\spacewidth.

\FLUSHacrostic[185pt]{\liz}  $\leftarrow$ verse set to 185pt width
\clearpage

\def\midway{%
  {The programming } {language I am}
  {trying to imagine } {at the moment,}
  {I am told, is qui} {te fun to use,}
  {as David Carlisl} {e spoke of in}
  {a very a proli} {x manner.}}

\RAWMIDacrostic[\hspace{.1ex}\rule{.4ex}{4.7\baselineskip}\hspace{.1ex}]
  {\midway}

\RAWMIDacrostic{\midway}

Measure:
\MEASUREMIDacrostic{\midway}

\SHOWMIDacrostic{\midway}

\def\ignorepunctuation{F}

\def\ode{%
{You~~~~} {\ \ \ \ are a}
{truly amaz} {ing woman:}
{with grace, } {laughter, fun.}
{And then y} {ou are seen}
{showing lo} {ve always.}
{I most } {especially}
{know } {you're}
{a h} {oney}
{b} {un} {} {!!}}

\RAWMIDacrostic{\ode}~~~~~
\SHOWMIDacrostic{\ode}

\end{document}

在第一张图片中,我演示了如何\SHOWacrostic将 和首字母缩略词中的 1 个或多个字母一起使用(作为可选参数传递)。请注意,\SHOWacrostic与左侧显示的原始首字母缩略词相比,它将如何将首字母缩略词变为大写并加粗。

在此处输入图片描述

在这幅图中,我演示了左对齐首字母缩略词的更多功能。我首先显示使用 输入的原始首字母缩略词\RAWacrostic。然后我使用 显示显示的首字母缩略词\SHOWacrostic。然后我使用 通过两种方式对其进行测量\MEASUREacrostic。如果没有提供可选参数,它将显示每行的自然长度。如果提供了长度字符串(\the提供宏时使用)作为可选参数,它将像以前一样显示测量值,但如果要将首字母缩略词对齐到给定的宽度,则会在括号中添加计算出的每行单词间距。这些可用于定量判断间隙是太大还是太小。最后,我用 将首字母缩略词设置为对齐后的宽度\FLUSHacrostic

在此处输入图片描述

此外,

\RAWMIDacrostic[divider]{acrostic}

\MEASUREMIDacrostic{acrostic}

\SHOWMIDacrostic[# acrostic chars]{acrostic}

已为中行首字母诗添加了 。首先,我用一条划分两半的规则来显示首字母诗。这就是首字母诗本身必须左对齐而不是居中对齐的原因,因为首字母诗是通过将两个(已经堆叠的)半部分对接在一起而形成的。然后,我显示原始的首字母诗诗句,其中隐藏了消息。然后,我显示每行两半的测量值。请注意,由于我(尚未)提供中行首字母诗的刷新功能,因此我不提供将这些长度与两个测试宽度进行比较的方法。最后,我用 显示首字母诗\SHOWMIDacrostic

在此处输入图片描述

使中间的首字母缩略词与页边距齐平是留给读者的练习。;^)

然而,伙计们,这里你需要仔细记下。即使没有为中线首字母缩略词而烦恼,你也可以从中线首字母缩略词中获益匪浅。想想你最好的女孩,为她写一首诗,一定会让她心动不已。我向你保证,好事会随之而来。

在此处输入图片描述

答案2

\hsize10.25cm
\raggedright
\parindent0pt


The trick is to let the system find the line breaks such that the expected letter starts each line.
It is much easier if the source is XML. This main text is more or less relevant to the subject
raised in the question. This text is far more interesting than boring Lipsum that you see in
so many other answers on this site. You may find a distinct lack of TikZ in this answer,
booktabs doesn't show up and nor does Lua. You will note how no special markup is needed:
\TeX\ has a built-in ability to find the correct breaks.


\bye

相关内容