9

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}

screenshot of my MWE

And this or similar is what I’m after: screenshot of my dreams

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.

3 Answers 3

3

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: Fixed-width spaces are replaced with centered dots.

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: Fixed-width spaces are replaced with brackets.

\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}}
4
  • 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
  • 1
    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
4

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}

enter image description here

1
  • \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
4

You can use leaders:

\documentclass{article}

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

\renewcommand~{\visiblenobreakspace{}}
\DeclareRobustCommand\visiblenobreakspace{%
  \leavevmode\nobreak
  \cleaders\hbox to 0.3em{\hss\textcolor{blue}{\v{}}\hss}\hskip
  \ifdim\spaceskip>0pt
    \spaceskip
  \else
    \fontdimen2\font plus \fontdimen3\font minus \fontdimen4\font
  \fi
}

\begin{document}

\noindent\hsize 5cm
\testline

\end{document}

enter image description here

With a rule, instead:

\documentclass{article}

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

\renewcommand~{\visiblenobreakspace{}}
\DeclareRobustCommand\visiblenobreakspace{%
  \leavevmode\nobreak
  {\color{blue}%
   \cleaders\hrule height 1ex depth -0.7ex\hskip
   \ifdim\spaceskip>0pt
     \spaceskip
   \else
     \fontdimen2\font plus \fontdimen3\font minus \fontdimen4\font
   \fi
  }%
}

\begin{document}

\noindent\hsize 5cm
\testline

\end{document}

enter image description here

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.