3

I am trying to reproduce the following in Plain (Xe)TeX (with more oscillations if possible):

voltaire

That is to add a squiggle in the margin next to a given paragraph. I was thinking of the following API:

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

Maybe one should use \sim and \cleaders,but \sim\mkern-3mu\sim is not a smooth join.

3
  • 1
    Welcome to TeX.SE! (Xe)TeX and friends are really cool, is there any chance you could make a small example of code with random text that people can play with ending with \bye please? Helps people help you if they can copy and paste, welcome and I hope you like it here!
    – JamesT
    Aug 30, 2023 at 20:38
  • I would go with tikzpagenodes and tikzmark and put the squiggle between (current page text area) and (current page marginpar area). However, semirandom squiggles are very difficult to computerize. It might be easier to scale an image to fit. Aug 30, 2023 at 23:43
  • @JohnKormylo I would be more than happy with a repeating pattern
    – user303294
    Aug 31, 2023 at 7:56

2 Answers 2

5

Here is a possible solution. It won't work with page breaks, more work for that is needed...

\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

enter image description here

You will need two compilations to get the correct result.

There are three variables you can configure:

  • \squiggleosc is a dimen which controls length of the wave. The above example is with \squiggleosc=\baselineskip

  • \squigglesep is a dimen which controls the horizontal space between the squiggle and the text.

  • \squigelamp is a number that controls the amplitude of the wave.

Here is the result with

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

enter image description here

1
  • This looks like black magic for me at the moment, I will study the code carefully, thanks a lot
    – user303294
    Sep 1, 2023 at 8:53
1

Note that it takes two runs for tikz to get the locations right.

\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}

demo

3
  • This is an interesting solution for LaTeX, I will see if I manage to port it to TeX
    – user303294
    Aug 31, 2023 at 16:21
  • You cannot really see the margin on this image.
    – Gaussler
    Sep 1, 2023 at 8:31
  • It was cropped. The squiggle fits between the text area and the marginpar area. The (commented out) geometry line shows how to increase the width. BTW, have you tried the plain package? It will allow you to run TeX inside LaTeX. Sep 1, 2023 at 13:24

You must log in to answer this question.