如何在 Plain TeX 中段落旁边的边距添加波浪线?

如何在 Plain TeX 中段落旁边的边距添加波浪线?

我正在尝试在 Plain (Xe)TeX 中重现以下内容(如果可能的话,使用更多振荡):

伏尔泰

也就是在给定段落旁边的边距中添加波浪线。我考虑了以下 API:

\beginsquiggle
Nos passions ne sont pas distinctes \&c.
\endsquiggle

也许应该使用\sim\cleaders,但这\sim\mkern-3mu\sim不是平滑的连接。

答案1

这是一个可能的解决方案。它不适用于分页符,需要做更多工作……

\def\pdfliteral#1{\special{pdf:literal #1}}

\def\converttobp#1{\the\dimexpr .99626\dimexpr #1\relax\relax} % convert pt to bp
\newdimen\squiggleosc
\newdimen\squigglesep

\def\var#1#2{-\expandafter\\\expanded{\converttobp{%
             \squiggleosc *#1 + \squiggleosc *#2/3}}}
\def\ifneg#1{\ifodd #1 \empty\else -\fi \squigelamp}
\def\squigglewidth{1}
\def\gobble#1{}
\def\secondoftwo#1#2{#2}

\def\varloop#1#2%
  {%
    \ifnum#1<#2
    \ifneg{#1} \var{#1}{1} \ifneg{#1} \var{#1}{2} 0 \var{#1}{3} c
      \expandafter\secondoftwo
    \fi
    \gobble{\expandafter\varloop\expandafter{\the\numexpr#1+1}{#2}}%
  }
  
\newcount\squigglecount
\def\squiggleline#1{\pdfliteral{q \squigglewidth w 1 j 1 J 0 0 m
                \varloop{0}{\the\numexpr #1\relax} S Q}}

\def\divceil#1#2{%
    \ifnum\numexpr #1 - #2*\numexpr #1/#2\relax>0
    \the\numexpr #1/#2 +1\relax\else\the\numexpr #1/#2\relax\fi
}

\def\squigglebox{%
\raise .6\squiggleosc\hbox to0pt{\kern-\dimexpr
                \csname  beg-x-\the\squigglecount\endcsname sp
                 - \the\hoffset -1in +\squigglesep\relax
                \hbox{\squiggleline{%
                \numexpr\divceil{%
                    (\csname  beg-y-\the\squigglecount\endcsname - 
                    \csname  end-y-\the\squigglecount\endcsname)}%
                    {\numexpr\dimexpr\squiggleosc\relax\relax}+1\relax
                }}\hss}%
}


\newlinechar=`^^J
\newwrite\squigglefile
\immediate\openin\squigglefile=squig.tex
\ifeof\squigglefile
\immediate\closein\squigglefile
\else
\immediate\closein\squigglefile\input squig
\fi
\immediate\openout\squigglefile=squig.tex   
    
\def\beginsquiggle{\global\advance\squigglecount by 1
            \ifcsname beg-x-\the\squigglecount\endcsname
            \ifvmode\noindent\leavevmode\pdfsavepos
                \squigglebox\hbox to\parindent{}%
            \else\pdfsavepos
                \squigglebox
            \fi\fi
               \write\squigglefile{
               \unexpanded{\expandafter\def\csname}
               beg-x-\the\squigglecount\noexpand\endcsname
               {\the\pdflastxpos}^^J
               \unexpanded{\expandafter\def\csname}
               beg-y-\the\squigglecount\noexpand\endcsname
               {\the\pdflastypos}
               }%
           }
\def\endsquiggle{\pdfsavepos
    \write\squigglefile{
           \unexpanded{\expandafter\def\csname}
           end-y-\the\squigglecount\noexpand\endcsname
           {\the\pdflastypos}
           }}
        
           

\squiggleosc=\baselineskip
\squigglesep=4pt
\def\squigelamp{2}


Here is the definitive guide to the use of TeX, written by the
system's creator, Donald E. Knuth. TeX represents the state of the art in
computer typesetting. It is particularly valuable where the document, article,
or book to be produced contains a lot of mathematics, and where the user 
\special{color push rgb 0 0 1}is\special{ color pop }
\beginsquiggle
concerned about typographic quality. TeX software offers both writers and
publishers the opportunity to produce technical text of all kinds, in an
attractive form, with the speed and efficiency of a computer system. Novice and
expert users alike will gain from The TeXbook the level of information they
seek. Knuth warns newcomers away from the more difficult areas, while he entices
experienced users with new challenges. The novice need not learn much about 
\special{color push rgb 0 0 1}TeX\special{ color pop }
\endsquiggle
to prepare a simple manuscript with it. But for the preparation of more complex
documents, The TeXbook contains all the detail required. Knuth's familiar wit,
and illustrations specially drawn by Duane Bibby, add a light touch to an
unusually readable software manual. The TeXbook is the first in a five-volume
series on Computers and Typesetting, all authored by Knuth.


\bye

在此处输入图片描述

您需要两次编译才能获得正确的结果。

您可以配置三个变量:

  • \squiggleosc是控制波的长度的维度。上面的例子是\squiggleosc=\baselineskip

  • \squigglesep是控制波浪线和文本之间的水平空间的尺寸。

  • \squigelamp是控制波的振幅的数字。

结果如下

\squiggleosc=.5\baselineskip
\squigglesep=8pt
\def\squigelamp{4}

在此处输入图片描述

答案2

请注意,tikz 需要运行两次才能获得正确的位置。

\documentclass{book}
%\usepackage[marginparsep=1.5em]{geometry}
\usepackage{xcolor}
\usepackage{tikzpagenodes}
\usetikzlibrary{tikzmark}
\usepackage{ifoddpage}
\usepackage{lipsum}% random text

\newcounter{squiggle}% for unique tikzmark id
\newcommand{\squiggles}{}% reserve global name

\newenvironment{squiggle}[1][5]% #1 = number of arcs (optional)
  {\xdef\squiggles{#1}% save argument
    \stepcounter{squiggle}%
    \tikzmark{squiggle.\thesquiggle}%
    \checkoddpage}%
  {\begin{tikzpicture}[overlay, remember picture]
    \path (pic cs:squiggle.\thesquiggle) ++(0,\ht\strutbox) coordinate(start);
    \coordinate (end) at (0,-\dp\strutbox);
    \ifoddpageoroneside
      \path (current page text area.east) ++(1pt,0) coordinate (left);
      \path (current page marginpar area.west) ++(-1pt,0) coordinate (right);
    \else
      \path (current page text area.west) ++(-1pt,0) coordinate (right);
      \path (current page marginpar area.east) ++(1pt,0) coordinate (left);
    \fi
    %\draw[red] (start-|left) rectangle (end-|right);% debug
    \path (start-|left);
    \pgfgetlastxy{\xleft}{\ytop}%
    \path (end-|right);
    \pgfgetlastxy{\xright}{\ybottom}%
    \pgfmathsetlengthmacro{\segment}{(\ytop-\ybottom)/\squiggles}
    \pgfmathsetmacro{\angle}{atan((\xright-\xleft)/\segment)}%
    \pgfmathsetlengthmacro{\R}{0.5*\segment/sin(\angle)}%
    %\node[right] at (current page footer area.west) {\angle};% debug
    \coordinate (A) at (0.5*\xleft+0.5*\xright, \ytop);
    \foreach \i in {1,2,...,\squiggles} {%
      \ifodd\i\relax
        \draw (A) arc[start angle=\angle, end angle=-\angle, radius=\R] coordinate(A);
      \else
        \draw (A) arc[start angle={180-\angle}, end angle={180+\angle}, radius=\R] coordinate(A);
      \fi
    }
  \end{tikzpicture}}
    

\begin{document}
  \lipsum[1]
  \begin{squiggle}
    \textcolor{red}{Squiggle should start on this line.}
    \lipsum[2]
    \textcolor{red}{Squiggle should end on this line.}
  \end{squiggle}
  \lipsum[3]
\end{document}

演示

相关内容