How do I make ditto marks?

In France, students are taught not to repeat the same text twice when there is little difference between a line and the one below. It's a quick way to take notes.

I reproduced this effect by tinkering:

The code is as follows:

\documentclass[aspectratio=1610]{beamer}
\usepackage[T1]{fontenc}
\usepackage[french]{babel}
\usepackage{amsmath, amsfonts, amssymb}
\usefonttheme[onlymath]{serif}

\begin{document}
\begin{frame}
Lorsque le \og \textit{carreau carré} \fg{}   mesure:
\begin{itemize}
\item $\rm 1\,cm$ de côté, l'unité d'aire est appelée le \og \textrm{centimètre carré} \fg{} et est noté $\rm cm^2$;
\item $\rm 1\,dm$ \hspace{1mm}'' \hspace{3mm}'' \hspace{8mm}'' \hspace{8mm}'' \hspace{5mm}''\hspace{8mm}'' \hspace{5.5mm}''\hspace{1mm} \og \textrm{décimètre carré} \fg{} \hspace{2mm}'' \hspace{2mm}'' \hspace{4mm}'' \hspace{1.5mm} $\rm dm^2$;
\item $\rm 1\,m$ \hspace{3mm}'' \hspace{3mm}'' \hspace{8mm}'' \hspace{8mm}'' \hspace{5mm}'' \hspace{7mm}'' \hspace{5.5mm}''\hspace{1mm} \og \textrm{mètre carré} \fg{}  \hspace{9mm}'' \hspace{2mm}'' \hspace{4mm}'' \hspace{1mm} $\rm m^2$;
\item etc.
\end{itemize}
\end{frame}
\end{document}


How can I get the same effect more simply than by tinkering like I just did?

• I think French typography prefers closing French guillemets for this (»). Also, don't type units in maths italic. Better use the siunitx package and the \SI1\cm}, for instance, to have the correct font and the correct spacing (a thin unbreakable space). Jul 21, 2018 at 22:05
• @Bernard I haven't found a typographical source for the use of French quotation marks in this case and I've never seen any of my teachers use them on the board. As for siuntix, its use of the fonts without serif with beamer makes the reading difficult, in particular for the liters (merges with the number 1). Jul 22, 2018 at 5:36
• Never put units in italics! Jul 22, 2018 at 9:36
• @AndreasRejbrand I wrote the units in mathematical mode which is in italics. To avoid italics, I replaced $cm^2$ by $\rm cm^2$. I edited the question to take into account the remarks of Bernard and yourself. Jul 22, 2018 at 11:05
• @AndréC Your litre problem with siunitx can very easily be solved: \DeclareSIUnit\litre{\ell} \SI{1}{\litre} Jul 22, 2018 at 11:50

Since @samcarter was faster than me, I had to build some special functionality in my answer, borrowing some code from @egreg (link):

\documentclass[aspectratio=1610]{beamer}
\usepackage[french]{babel}
\usepackage[T1]{fontenc}
\usepackage{amsmath, amsfonts, amssymb}
\usefonttheme[onlymath]{serif}

%https://tex.stackexchange.com/a/280981/97512
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\xsameword}{m}
{
\leavevmode\maieul_xsameword:n { #1 }
}

\tl_new:N \l__maieul_xsameword_list_tl

\cs_new_protected:Nn \maieul_xsameword:n
{
\tl_set:Nn \l__maieul_xsameword_list_tl
{
\__maieul_xsameword_start:n { #1 }
}
\regex_replace_all:nnN
{ (\c{footnote}\cB..*?\cE.) }
{ \cE\} \1 \c{__maieul_xsameword_start:n} \cB\{ }
\l__maieul_xsameword_list_tl
\tl_use:N \l__maieul_xsameword_list_tl
}
\cs_new_protected:Nn \__maieul_xsameword_start:n
{
\tl_set:Nn \l__maieul_xsameword_list_tl { #1 }
\regex_replace_all:nnN
{ ([^\s,.!?]+) }% Delete what should not be printed again here
{ \c{maieul_xsameword_format:n} \cB\{ \1 \cE\} }
\l__maieul_xsameword_list_tl
\tl_use:N \l__maieul_xsameword_list_tl
}

\NewDocumentCommand{\setxsamewordformat}{m}
{
\cs_set_protected:Nn \maieul_xsameword_format:n { #1 }
}
\ExplSyntaxOff
%%%%%%%%%%%%%%%%%%%%%

\newbox\mytmpbox

\newcommand{\repword}[1]{%
\sbox{\mytmpbox}{#1}%
\hbox to \wd\mytmpbox{\hss\hspace{.2em}''\hss}%
}

\setxsamewordformat{\repword{#1}}

\newcommand{\keepword}[2]{%
\sbox{\mytmpbox}{#2}%
\hbox to \wd\mytmpbox{\hss#1\hss}%
}

\begin{document}
\begin{frame}

Lorsque le \og \textit{carreau carré} \fg{}   mesure:
\begin{itemize}
\item {1}\,$cm$ de côté, l'unité d'aire est appelée le \og \textit{\textrm{centimètre carré}} \fg{} et est noté $cm^2$;

\item 1\,\keepword{$dm$}{$cm$} \xsameword{de côté, l'unité d'aire est appelée le} \keepword{\og \textit{\textrm{décimètre carré}} \fg{}}{\og \textit{\textrm{centimètre carré}} \fg{}} \xsameword{et est noté} $cm^2$;

\item 1\,\keepword{$m$}{$cm$} \xsameword{de côté, l'unité d'aire est appelée le}  \keepword{\og \textit{\textrm{mètre carré}} \fg{}}{\og \textit{\textrm{centimètre carré}} \fg{}} \xsameword{et est noté} \keepword{$m^2$}{$cm^2$};
\end{itemize}

\end{frame}
\end{document}


This allows you to put a whole sentence in the argument of \xsamewords and they will be replaced. Also, I built a macro that allows you to insert words taking the same amount of space as another word: \keepwords{this line}{line above}.

edit: Now I put the first $dm$ in \keepwords and it is aligned properly, thanks @marmot for pointing me there! :-)

edit2: Example with three lines added.

edit3: Added \usepackage[T1]{fontenc} and inserted a comment showing which line should be edited to remove, e.g., commas.

The line { ([^\s,.!?]+) } represents a regular expression, or short regex. These can be used for advanced pattern matching, if a simple find or find & replace is not sufficient. Here, this regex represents the words that should be replaced by '' your ditto marks:

• [..] brackets match one character from the inside. [abc] operated on foobar would match the b or the a (but only one of them, a single character).
• [^..] is the negation of the characters inside, so this regex here is matching anything not present. [^abc] operated on foobar would match f, o, o, or r.
• \s is any white space character (spaces, tabs, sometimes also new lines)
• ,.!? are self-explanatory I assume ;)
• + after a character (remember, brackets match a single character) makes the character match as many multiple ("identical") characters, as possible (usual behavior) but at least one. So, e.g., o+ in regex operated on the string fooobar would match ooo, not just one or two os. [abc]+ operated on foobar would match ba.

You can see now, this regex matches everything that is not a white space or punctuation mark, i.e., everything else, that is words with all other special characters. You can think of the symbols inside the negated brackets to be the word delimiters that you still want to print and not replace in this context.

edit4: If you add \leavevmode before calling (the old) \xsameword, it should work fine at the beginning of a line as well. Now, I added it in the definition of \xsameword, so there's no need to take care of it manually.

• Beautiful work, only, it doesn't work anymore when I add a third line with "square meter" . I edited the question. Jul 21, 2018 at 19:30
• @AndréC see my edit. It works, you just need to put your \og and \fg inside the braces of \keepword ;)
– nox
Jul 21, 2018 at 19:44
• Your solution is beautiful, but it would be better if commas were removed. Indeed, the goal here is to teach very young students to write faster. Jul 21, 2018 at 20:14
• @AndréC it's a thing called regular expression. See my updated answer.
– nox
Jul 24, 2018 at 6:13
• @AndréC see my last edit, \leavevmode is all you need to add there. Put inside the command of \xsameword makes it work out of the box.
– nox
Oct 6, 2019 at 13:30

Instead of guessing the required spaces, you could measure the width of the words you want to replace:

\documentclass[aspectratio=1610]{beamer}
\usepackage[french]{babel}
\usepackage{amsmath, amsfonts, amssymb}
\usefonttheme[onlymath]{serif}
\usepackage{siunitx}

\newlength{\mywidth}

\newcommand{\test}[1]{%
\settowidth{\mywidth}{#1}%
\makebox[\mywidth][c]{''}%
}

\newlength{\centwidth}
\settowidth{\centwidth}{<< centimètre carré >>}

\newlength{\foowidth}
\settowidth{\foowidth}{\SI{1}{\centi\meter}}

\begin{document}
\begin{frame}
Lorsque le \og \textit{carreau carré} \fg{}   mesure:
\begin{itemize}
\item \makebox[\foowidth][l]{\SI{1}{\centi\meter}} de côté, l'unité d'aire est appelée le \makebox[\centwidth][c]{\og \textit{\textrm{centimètre carré}} \fg} et est noté \si{\centi\meter\square};
\item \makebox[\foowidth][l]{\SI{1}{\deci\meter}} \test{de} \test{côté,} \test{l'unité} \test{d'aire} \test{est} \test{appelée} \test{le} \makebox[\centwidth][c]{\og \textit{\textrm{décimètre carré}} \fg} \test{et} \test{est} \test{noté} \si{\deci\meter\square};
\item \makebox[\foowidth][l]{\SI{1}{\meter}} \test{de} \test{côté,} \test{l'unité} \test{d'aire} \test{est} \test{appelée} \test{le} \makebox[\centwidth][c]{\og \textit{\textrm{mètre carré}} \fg} \test{et} \test{est} \test{noté} \si{\meter\square};
\end{itemize}
\end{frame}
\end{document}


Another approach could be to use a tabular

\documentclass[aspectratio=1610]{beamer}
\usepackage[french]{babel}
\usepackage{amsmath, amsfonts, amssymb}
\usefonttheme[onlymath]{serif}
\usepackage{siunitx}

\begin{document}
\begin{frame}
Lorsque le \og \textit{carreau carré} \fg{}   mesure:

\begin{tabular}{ll*{11}{@{~}c}@{~}l}
\usebeamertemplate{itemize item} & \SI{1}{\centi\meter} & de & côté,& l'unité &d'aire &est& appelée& le &\og \textit{\textrm{centimètre carré}} \fg{}& et &est& noté& \si{\centi\meter\square};\\
\usebeamertemplate{itemize item} & \SI{1}{\deci\meter} & " & " & " & " & " & " & " &\og \textit{\textrm{décimètre carré}} \fg{}& " & " & " & \si{\deci\meter\square};\\
\usebeamertemplate{itemize item} & \SI{1}{\meter} & " & " & " & " & " & " & " &\og \textit{\textrm{mètre carré}} \fg{}& " & " & " & \si{\meter\square};\\
\end{tabular}

\end{frame}
\end{document}

• very smart idea! +1 Jul 21, 2018 at 17:26
• now i see, that you can suggest to replace {1}\,{$cm$} with siunitx system of writing units: \SI{1}{cm}. of course, in this case to preamble should be added \usepackage{siunitx} (all is very off-topic, of course :-) ) Jul 21, 2018 at 17:53
• Very nice work, only, it doesn't work anymore when I add a third line with "square meter" . I edited the question. Jul 21, 2018 at 19:29
• @AndréC Please see my edit. The same technique can be used to align the square meter line. Jul 21, 2018 at 19:56
• @Zarko Thanks for the suggestion about siunitx. Originally I discarded this idea because I thought the different font was used on purpose to emphasis the unit, but after the edit of the question I agree that siunitx is a good idea to add. Jul 22, 2018 at 11:44