1

I want to draw a ditto line, which is a horizontal line with two small marks in the middle.

My first attempt was \dittoLatex which uses a box with characters and rules, but is frankly ugly.

My second attempt was \dittotikzA which looks a lot better, but does not calculate its width automatically from an argument.

My third attempt is \dittotikzB which attempts to use the same method for calculating the width as \dittoLatex, but it doesn't work. I suspect the issue is with mismatching units, but I can't figure out how to fix it.

MWE:

\documentclass{article}
\usepackage[showframe]{geometry}
\usepackage{xparse}

\makeatletter

\usepackage{tikz}
\usetikzlibrary{math}

\newcommand\dittotikzA[1][3em]{%
    \def\x{#1/4}%
    %\show\x%
    \def\y{#1*.01}%
    \begin{tikzpicture}[x=1ex,y=1ex,baseline=-.5ex,cap=round]
        \draw (0,0) sin (1*\x,\y) cos (2*\x,0) sin (3*\x,-\y) cos (4*\x,0);
        \draw[xshift=-.2ex, bend right=20] (2*\x-.5,-.5) edge (2*\x+.5,.5);
        \draw[xshift=.2ex, bend right=20] (2*\x-.5,-.5) edge (2*\x+.5,.5);
    \end{tikzpicture}%
}


\newlength{\ditto@width}
\NewDocumentCommand\dittotikzB{ s O{1em} m }{%
    % #1 = starred means horizontal line along entire width, unstarred means no line (only ditto marks)
    % #2 = minimum width
    % #3 = string to use for calculating width
    \settowidth{\ditto@width}{#3}%
    %\show\ditto@width%
    \edef\w{\ifdim#2<\ditto@width\the\ditto@width\else#2\fi}
    %\show\w%
    \begin{tikzpicture}[x=1ex,y=1ex,baseline=-.5ex,cap=round]
        \tikzmath{
            \xfactor = \w / 4 * 1pt/1ex;
            \yfactor = .175;
        };
        %\show\xfactor;
        %\show\yfactor;
        \IfBooleanT{#1}{% starred
            \draw (0,0) sin (1\xfactor, \yfactor) cos (2\xfactor, 0) sin (3\xfactor, -\yfactor) cos (4\xfactor, 0);
        };
        \draw[xshift=-.2ex, bend right=20] (2\xfactor - .5, -.5) edge (2\xfactor + .5, .5);
        \draw[xshift=.2ex, bend right=20] (2\xfactor - .5, -.5) edge (2\xfactor + .5, .5);
    \end{tikzpicture}%
}


\usepackage{xhfill}
\newcommand\ditto@symbol{%
    ||%
}
\NewDocumentCommand\dittoLatex{ s O{1em} m }{%
    % #1 = starred means horizontal line along entire width, unstarred means no line (only ditto marks)
    % #2 = minimum width
    % #3 = string to use for calculating width
    \settowidth{\ditto@width}{#3}%
    \makebox[{\ifdim#2<\ditto@width\ditto@width\else#2\fi}]{%
        \IfBooleanTF{#1}{% starred
            \xrfill[.5ex]{.4pt}%
            \ditto@symbol%
            \xrfill[.5ex]{.4pt}%
        }{%
            \ditto@symbol%
        }%
    }%
}

\makeatother

\begin{document}

\let\ditto=\dittotikzA
\noindent
blah blah \ditto{} blah blah\\
blah blah \ditto[10em]{} blah blah\\

\let\ditto=\dittotikzB
\noindent
blah blah Test blah blah\\
blah blah \ditto{Test} blah blah\\
blah blah \ditto*{Test} blah blah\\
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\\

\let\ditto=\dittoLatex
\noindent
blah blah Test blah blah\\
blah blah \ditto{Test} blah blah\\
blah blah \ditto*{Test} blah blah\\
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}

example

Some related questions:

8
  • 1
    Tipp: Use \pgfmathsetmacro\y{#1*.01} to evaluate the expression eagerly and avoid parsing oddities. Dec 2 '19 at 5:14
  • 1
    related "How do I make ditto marks?" : tex.stackexchange.com/q/442650/138900
    – AndréC
    Dec 2 '19 at 5:16
  • @HenriMenke: that part of \dittotikzA works fine, it's just to adjust the amplitude of the sinus curve so it becomes more pronounced with length. I'm looking to make the width-calculation of \dittotikzB work.
    – meide
    Dec 2 '19 at 6:19
  • 1
    @meide I know, that is why I wrote “Tipp” and not “Answer”. Dec 2 '19 at 6:25
  • 1
    inside tikz the font is \nullfont and so em and ex units are 0. You should at least use \edef\w{\ifdim#2<\ditto@width\the\ditto@width\else\the\dimexpr#2\relax\fi} to get pt inside \w. Dec 2 '19 at 11:26
2

You forgot the multiplication signs. 4\xfactor is not 4*\xfactor.

\documentclass{article}
\usepackage[showframe]{geometry}
\usepackage{xparse}

\makeatletter

\usepackage{tikz}
\usetikzlibrary{math}
\newcommand\w{}
\newlength{\ditto@width}
\NewDocumentCommand\dittotikzB{ s O{1em} m }{%
    % #1 = starred means horizontal line along entire width, unstarred means no line (only ditto marks)
    % #2 = minimum width
    % #3 = string to use for calculating width
    \settowidth{\ditto@width}{#3}%
    %\show\ditto@width%
    \edef\w{\ifdim#2<\ditto@width\the\ditto@width\else\dimexpr#2\relax\fi}
    %\show\w%
    \begin{tikzpicture}[x=1ex,y=1ex,baseline=-.5ex,cap=round]
        \tikzmath{
            \xfactor = \w / 4 * 1pt/1ex;
            \yfactor = .175;
        };
        %\show\xfactor;
        %\show\yfactor;
        \IfBooleanT{#1}{% starred
            \draw (0,0) sin (1*\xfactor, \yfactor) cos (2*\xfactor, 0) sin (3*\xfactor, -\yfactor) cos (4*\xfactor, 0);
        };
        \draw[xshift=-.2ex, bend right=20] (2*\xfactor - .5, -.5) edge (2*\xfactor + .5, .5);
        \draw[xshift=.2ex, bend right=20] (2*\xfactor - .5, -.5) edge (2*\xfactor + .5, .5);
    \end{tikzpicture}%
}



\makeatother

\begin{document}

\let\ditto=\dittotikzB
\noindent
blah blah Test blah blah\\
blah blah \ditto{Test} blah blah\\
blah blah \ditto*{Test} blah blah\\
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}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.