# Make non-breakable spaces (~) visible in the PDF and preserve their glue

I use several tools to ease my editing process and line and layout optimization. As one of them I’d like to see where I already placed non-breakable spaces ~ directly in the PDF to better understand why certain breakpoints and stretching were chosen.

How could one redefine ~ to show up the in PDF – possibly as a literal tilde symbol ~ – without affecting the line breaking? The substitution should therefore have exactly the same stretch- and shrinkability as the original ~ and, of course, still be non-breaking.

My attempt so far:

\documentclass{article}

\usepackage{color}
\newcommand\testline{Lorem~ipsum dolor~sit\linebreak}

\begin{document}\noindent\hsize 5cm
\testline
\def~{\textcolor{blue}{\textasciitilde}}
\testline
\end{document}


And this or similar is what I’m after:

I couldn’t find the default glue of interword spaces and how to place a symbol in the middle of it. If possible ~ should also be redefined in a way to not cause additional errors because it is used in section titles and the bibliography, for example.

Here are two solutions that center the dot between the two words:

\def\visiblenobreakspacesymbol{$\cdot$}
\let\invisiblenobreakspace=~
\newdimen\fontdimentwo
\newdimen\fontdimenthree
\newdimen\fontdimenfour
\protected\def\visiblenobreakspace{%
\fontdimentwo=\fontdimen2\font
\fontdimenthree=\fontdimen3\font
\fontdimenfour=\fontdimen4\font
\fontdimen2\font=\dimexpr\fontdimen2\font/2\relax
\fontdimen3\font=\dimexpr\fontdimen3\font/2\relax
\fontdimen4\font=\dimexpr\fontdimen4\font/2\relax
\invisiblenobreakspace
\hbox to 0pt{\hss\visiblenobreakspacesymbol\hss}%
\invisiblenobreakspace
\fontdimen2\font=\fontdimentwo
\fontdimen3\font=\fontdimenthree
\fontdimen4\font=\fontdimenfour}
\def~{\visiblenobreakspace}


and

\usepackage{tikz}
\usetikzlibrary{tikzmark}

\newcommand{\visiblenobreakspacesymbol}{$\cdot$}
\let\invisiblenobreakspace=~
\newcounter{nbsp}
\DeclareRobustCommand{\visiblenobreakspace}{%
\stepcounter{nbsp}%
\tikzmark{{nbsp-left\arabic{nbsp}}}%
\invisiblenobreakspace
\tikzmark{{nbsp-right\arabic{nbsp}}}%
\tikz[remember picture,overlay]
\path ({pic cs:nbsp-left\arabic{nbsp}})
-- ({pic cs:nbsp-right\arabic{nbsp}})
node [midway,anchor=base] {\visiblenobreakspacesymbol};}
\AtBeginDocument{\renewcommand{~}{\visiblenobreakspace}}


Both produce the following output:

The first solution should run on any TeX engine with e-TeX available. The second solution requires two passes, but it is more powerful; a small change gives the following output:

\usepackage{tikz}
\usetikzlibrary{tikzmark}

\let\invisiblenobreakspace=~
\newcounter{nbsp}
\DeclareRobustCommand{\visiblenobreakspace}{%
\stepcounter{nbsp}%
\tikzmark{{nbsp-left\arabic{nbsp}}}%
\invisiblenobreakspace
\tikzmark{{nbsp-right\arabic{nbsp}}}%
\tikz[remember picture,overlay]
\draw ({pic cs:nbsp-left\arabic{nbsp}}) -- +(0,-0.3ex)
-| ({pic cs:nbsp-right\arabic{nbsp}});}
\AtBeginDocument{\renewcommand{~}{\visiblenobreakspace}}

• Works grat as a MWE, but in a real document (a thesis) used exactly the same way, your third code causes many errors: Missing \endcsname inserted Undefined control sequence Use of \use@tikzlibrary doesn't match its definition Use of \tikz@opt doesn't match its definition Use of \tikz@picture doesn't match its definition. Any idea?
– lblb
Apr 29, 2018 at 19:31
• And your first code solution works with my thesis in the first few pages, but then suddenly all interword spaces are made extremely thin. I declare manual font sizes at various places, maybe this messes with your code.
– lblb
Apr 29, 2018 at 19:48
• I've changed the versions with tikzmark so they should hopefully work now. I couldn't reproduce the error with the first version (how exactly do you change the font size?). Does it help to protect that version too: \def\newtilde{...} instead of \def~{...} and then \def~{\protect\newtilde}? Apr 29, 2018 at 21:18
• The \tikzmark-solutions work now, thanks! The first one got broken because I placed a custom macro instead of $\cdot$ inside (for more involved formatting) and didn't \protect it there. Doing that it works as well and I prefer not having to compile twice.
– lblb
Apr 30, 2018 at 8:57

Here is a possible solution:

\documentclass{article}

\usepackage{color}
\newcommand\testlinei{Lorem~ipsum dolor~sit\linebreak}
\newcommand\testlineii{Lorem~ipsum dolor~sit~skdjfh~skdhf~skfdh~sdf\linebreak}

\begin{document}\noindent\hsize 5cm
\testlinei
\testlineii
\let\oldtilde=~
\def~{\rlap{\textcolor{blue}{$\cdot$}}\oldtilde}
\testlinei
\testlineii
\end{document}


• \cdot really seems to be better suited than the wider tilde symbol. Thanks for introducing me to \rlap!
– lblb
Apr 25, 2018 at 14:10

\documentclass{article}

\usepackage{color}
\newcommand\testline{Lorem~ipsum dolor~sit\linebreak no underfull}

\renewcommand~{\visiblenobreakspace{}}
\DeclareRobustCommand\visiblenobreakspace{%
\leavevmode\nobreak
\ifdim\spaceskip>0pt
\spaceskip
\else
\fontdimen2\font plus \fontdimen3\font minus \fontdimen4\font
\fi
}

\begin{document}

\noindent\hsize 5cm
\testline

\end{document}


\documentclass{article}

\usepackage{color}
\newcommand\testline{Lorem~ipsum dolor~sit\linebreak no underfull}

\renewcommand~{\visiblenobreakspace{}}
\DeclareRobustCommand\visiblenobreakspace{%
\leavevmode\nobreak
{\color{blue}%
\ifdim\spaceskip>0pt
\spaceskip
\else
\fontdimen2\font plus \fontdimen3\font minus \fontdimen4\font
\fi
}%
}

\begin{document}

\noindent\hsize 5cm
\testline

\end{document}