..png)
Ich arbeite an einigen Verzierungen für mein Ditto-Mark-Makro (sieheTikz: Latexlänge für Pfadlänge verwenden (ebenfalls Markierungen)). Nämlich die Verwendung variabler Strichstärken. Unten ist es als Sternversion des Makros implementiert.
Wenn ich jedoch versuche, einen Strich mit variabler Dicke zu verwenden, erhalte ich 35 Dimension too large
Fehler für einen einzelnen \ditto*
, obwohl der generierte Pfad gut aussieht ...
Wie behebe ich das?
MWE:
\documentclass{article}
\usepackage[showframe]{geometry}
\usepackage{xparse}
\makeatletter
\usepackage{tikz}
\usetikzlibrary{math}
\usetikzlibrary{decorations}
\pgfkeys{/pgf/decoration/.cd,
start stroke width/.store in = \startstrokewidth,
end stroke width/.store in = \endstrokewidth,
}
\pgfkeys{/tikz/.cd,
pen stroke/.style args={#1,#2}{
decorate,
decoration={
variable stroke width,
start stroke width=#1,
end stroke width=#2,
}
}
}
\pgfdeclaredecoration{variable stroke width}{initial}{%
% modified version of:
% https://tex.stackexchange.com/questions/14283/stroke-with-variable-thickness
\state{initial}[width=0pt, next state=line, persistent precomputation={%
\pgfmathsubtract@{\startstrokewidth}{\endstrokewidth}%
\pgfmathdivide{\pgfmathresult}{\pgfdecoratedpathlength}%
\let\strokeincrement=\pgfmathresult%
\def\strokewidth{\startstrokewidth}%
}]{}
\state{line}[width=\startstrokewidth, persistent postcomputation={%
\pgfmathsubtract@{\strokewidth}{\strokeincrement}%
\let\strokewidth=\pgfmathresult%
}]{%
\pgfsetlinewidth{\strokewidth}%
\pgfsetarrows{-}%
\pgfpathmoveto{\pgfpointorigin}%
\pgfpathlineto{\pgfqpoint{.75pt}{0pt}}%
\pgfusepath{stroke}%
}
\state{final}{%
\pgfsetlinewidth{\pgflinewidth}%
\pgfpathmoveto{\pgfpointorigin}%
\pgfusepath{stroke}%
}
}
\newdimen\dto@x
\newdimen\dto@y
\newdimen\dto@spc
\NewDocumentCommand\ditto{ s O{2ex} m }{%
% #1 = starred means use pen stroke, unstarred use regular line
% #2 = minimum width
% #3 = string to use for calculating width
\settowidth{\dto@x}{#3}%
%\showthe\dto@x%
\dto@x = \ifdim#2<\dto@x\the\dto@x\else\the\dimexpr#2\relax\fi% whichever is widest of #2 and #3
\divide\dto@x by 4% sine wave has 4 points
\dto@y = .0675ex% .125ex%
\dto@spc = .5pt% ditto mark sizing
\begin{tikzpicture}[baseline=-.5ex,cap=round]
\IfBooleanTF{#1}{% starred
\draw[pen stroke={.4pt,.35pt}] (0,0) sin (1\dto@x, \dto@y) cos (2\dto@x, 0) sin (3\dto@x, -\dto@y) cos (4\dto@x, 0);
}{% unstarred
\draw (0,0) sin (1\dto@x, \dto@y) cos (2\dto@x, 0) sin (3\dto@x, -\dto@y) cos (4\dto@x, 0);
}%
\draw[xshift=-.2ex, pen stroke={.4pt,.35pt}] (2\dto@x + .25pt, 3\dto@y) -- (2\dto@x - .25pt, -3\dto@y);
\draw[xshift=.2ex, pen stroke={.4pt,.35pt}] (2\dto@x + .25pt, 3\dto@y) -- (2\dto@x - .25pt, -3\dto@y);
\end{tikzpicture}%
}
\makeatother
\begin{document}
\noindent
blah blah Test blah blah\\
blah blah \ditto{Test} blah blah\\
blah blah \ditto*{Test} blah blah\\ % throws 'Dimension too large' several times, but looks great in doc?!
blah blah Testing testing blah blah\\
blah blah \ditto{Testing testing} blah blah\\
%blah blah \ditto*{Testing testing} blah blah\\
blah blah \ditto{} blah blah\\
%blah blah \ditto*{} blah blah\\
blah blah \ditto[10em]{Test} blah blah\\
%blah blah \ditto*[10em]{Test} blah blah\\
blah blah \ditto[10em]{Testing testing} blah blah\\
%blah blah \ditto*[10em]{Testing testing} blah blah\\
blah blah \ditto[10em]{} blah blah\\
%blah blah \ditto*[10em]{} blah blah\\
\end{document}
Verwandt:
Antwort1
Immer das gleiche Problem: veclen
Kleine Werte mögen sie nicht. Siehe diesen Beitrag:So setzen Sie eine Markierung
Eine Lösung mitxfp
\documentclass{article}
\usepackage[showframe]{geometry}
\usepackage{xparse}
\makeatletter
\usepackage{tikz,xfp}
\usetikzlibrary{math}
\usetikzlibrary{decorations}
\pgfkeys{/pgf/decoration/.cd,
start stroke width/.store in = \startstrokewidth,
end stroke width/.store in = \endstrokewidth,
}
\pgfkeys{/tikz/.cd,
pen stroke/.style args={#1,#2}{
decorate,
decoration={
variable stroke width,
start stroke width=#1,
end stroke width=#2,
}
}
}
\pgfdeclaredecoration{variable stroke width}{initial}{%
% modified version of:
% https://tex.stackexchange.com/questions/14283/stroke-with-variable-thickness
\state{initial}[width=0pt, next state=line, persistent precomputation={%
\pgfmathsubtract@{\startstrokewidth}{\endstrokewidth}%
\pgfmathdivide{\pgfmathresult}{\pgfdecoratedpathlength}%
\let\strokeincrement=\pgfmathresult%
\def\strokewidth{\startstrokewidth}%
}]{}
\state{line}[width=\startstrokewidth, persistent postcomputation={%
\pgfmathsubtract@{\strokewidth}{\strokeincrement}%
\let\strokewidth=\pgfmathresult%
}]{%
\pgfsetlinewidth{\strokewidth}%
\pgfsetarrows{-}%
\pgfpathmoveto{\pgfpointorigin}%
\pgfpathlineto{\pgfqpoint{.75pt}{0pt}}%
\pgfusepath{stroke}%
}
\state{final}{%
\pgfsetlinewidth{\pgflinewidth}%
\pgfpathmoveto{\pgfpointorigin}%
\pgfusepath{stroke}%
}
}
\newdimen\dto@x
\newdimen\dto@y
\newdimen\dto@spc
\NewDocumentCommand\ditto{ s O{2ex} m }{%
% #1 = starred means use pen stroke, unstarred use regular line
% #2 = minimum width
% #3 = string to use for calculating width
\settowidth{\dto@x}{#3}%
%\showthe\dto@x%
\dto@x = \ifdim#2<\dto@x\the\dto@x\else\the\dimexpr#2\relax\fi% whichever is widest of #2 and #3
\divide\dto@x by 4% sine wave has 4 points
\dto@y = .0675ex% .125ex%
\dto@spc = .5pt% ditto mark sizing
\begin{tikzpicture}[baseline=-.5ex,cap=round]
\IfBooleanTF{#1}{% starred
\draw[pen stroke={.4pt,.35pt}] (0,0) sin (1\dto@x, \dto@y) cos (2\dto@x, 0) sin (3\dto@x, -\dto@y) cos (4\dto@x, 0);
}{% unstarred
\draw (0,0) sin (1\dto@x, \dto@y) cos (2\dto@x, 0) sin (3\dto@x, -\dto@y) cos (4\dto@x, 0);
}%
\draw[xshift=-.2ex, pen stroke={.4pt,.35pt}] (2\dto@x + .25pt, 3\dto@y) -- (2\dto@x - .25pt, -3\dto@y);
\draw[xshift=.2ex, pen stroke={.4pt,.35pt}] (2\dto@x + .25pt, 3\dto@y) -- (2\dto@x - .25pt, -3\dto@y);
\end{tikzpicture}%
}
\pgfmathdeclarefunction*{veclen}{2}{%
\begingroup%
\pgfmath@x#1pt\relax%
\pgfmath@y#2pt\relax%
\pgf@xa=\pgf@x%
\pgf@ya=\pgf@y%
\edef\tkz@temp@a{\fpeval{\pgfmath@tonumber{\pgf@xa}}}
\edef\tkz@temp@b{\fpeval{\pgfmath@tonumber{\pgf@ya}}}
\edef\tkz@temp@sum{\fpeval{(\tkz@temp@a*\tkz@temp@a+\tkz@temp@b*\tkz@temp@b)}}
\edef\tkzFPMathLen{\fpeval{sqrt(\tkz@temp@sum)}}
%\edef\pgfmath@tmp{\fpeval{round(\tkzFPMathLen,6)}}
%\pgfmath@tmp %
\pgfmath@returnone\tkzFPMathLen pt%
\endgroup%
}
\makeatother
\begin{document}
\noindent
blah blah Test blah blah\\
blah blah \ditto{Test} blah blah\\
blah blah \ditto*{Test} blah blah\\ % throws 'Dimension too large' several times, but looks great in doc?!
blah blah Testing testing blah blah\\
blah blah \ditto{Testing testing} blah blah\\
%blah blah \ditto*{Testing testing} blah blah\\
blah blah \ditto{} blah blah\\
%blah blah \ditto*{} blah blah\\
blah blah \ditto[10em]{Test} blah blah\\
%blah blah \ditto*[10em]{Test} blah blah\\
blah blah \ditto[10em]{Testing testing} blah blah\\
%blah blah \ditto*[10em]{Testing testing} blah blah\\
blah blah \ditto[10em]{} blah blah\\
%blah blah \ditto*[10em]{} blah blah\\
\end{document}
Eine weitere Modifikation von Loop Space
\pgfmathdeclarefunction*{veclen}{2}{%
\begingroup%
\pgfmath@x#1pt\relax%
\pgfmath@y#2pt\relax%
\ifdim\pgfmath@x<0pt\relax%
\pgfmath@x-\pgfmath@x%
\fi%
\ifdim\pgfmath@y<0pt\relax%
\pgfmath@y-\pgfmath@y%
\fi%
\ifdim\pgfmath@x=0pt\relax%
\pgfmath@x\pgfmath@y%
\else%
\ifdim\pgfmath@y=0pt\relax%
\else%
\ifdim\pgfmath@x>\pgfmath@y%
\pgfmath@xa\pgfmath@x%
\pgfmath@x\pgfmath@y%
\pgfmath@y\pgfmath@xa%
\fi%
% We use a scaling factor to reduce errors.
% First, see if we should scale down
\let\pgfmath@tmp@scale=\divide
\let\pgfmath@tmp@restore=\multipy
\ifdim\pgfmath@y>10000pt\relax%
\c@pgfmath@counta1500\relax%
\else%
\ifdim\pgfmath@y>1000pt\relax%
\c@pgfmath@counta150\relax%
\else%
\ifdim\pgfmath@y>100pt\relax%
\c@pgfmath@counta50\relax%
\else%
% Not scaling down, should we scale up?
\let\pgfmath@tmp@scale=\multiply
\let\pgfmath@tmp@restore=\divide
\ifdim\pgfmath@y<0.00001pt\relax%
\c@pgfmath@counta1500\relax%
\else%
\ifdim\pgfmath@y<0.0001pt\relax%
\c@pgfmath@counta150\relax%
\else%
\ifdim\pgfmath@y<0.001pt\relax%
\c@pgfmath@counta50\relax%
\else
\c@pgfmath@counta1\relax%
\fi%
\fi%
\fi%
\fi%
\fi%
\fi%
\pgfmath@tmp@scale\pgfmath@x\c@pgfmath@counta\relax%
\pgfmath@tmp@scale\pgfmath@y\c@pgfmath@counta\relax%
\pgfmathreciprocal@{\pgfmath@tonumber{\pgfmath@y}}%
\pgfmath@x\pgfmathresult\pgfmath@x%
\pgfmath@xa\pgfmath@tonumber{\pgfmath@x}\pgfmath@x%
\edef\pgfmath@temp{\pgfmath@tonumber{\pgfmath@xa}}%
%
% Use A+x^2*(B+x^2*(C+x^2*(D+E*x^2)))
% where
% A = +1.000012594
% B = +0.4993615349
% C = -0.1195159052
% D = +0.04453994279
% E = -0.01019210944
%
\[email protected]\pgfmath@xa%
\advance\[email protected]\relax%
\pgfmath@x\pgfmath@temp\pgfmath@x%
\advance\[email protected]\relax%
\pgfmath@x\pgfmath@temp\pgfmath@x%
\advance\[email protected]\relax%
\pgfmath@x\pgfmath@temp\pgfmath@x%
\advance\[email protected]\relax%
\ifdim\pgfmath@y<0pt\relax%
\pgfmath@y-\pgfmath@y%
\fi%
\pgfmath@x\pgfmath@tonumber{\pgfmath@y}\pgfmath@x%
% Invert the scaling factor.
\pgfmath@tmp@restore\pgfmath@x\c@pgfmath@counta\relax%
\fi%
\fi%
\pgfmath@returnone\pgfmath@x%
\endgroup%
}