答案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}