16

I would like to replace the white space (full space entered by pressing "space" any number of times on the keyboard or by hitting enter) by something else. Let's say, a rule of the same width.

Is there some command I could redefine? The easiest way in order to keep the stretching of the white spaces would be to highlight them.

I already know that I can get something like this with the package lua-visual-debug and debugging is the purpose for that redefinition, but I would like to do that in pdfLaTeX.

If we can find a simple answer to this, we might get some reference for debugging "spurious white-space errors".

Of course, I am giving an MWE for this. The first line should result in the second line after inserting the redefinition (hopefully not with hard-coded width of the rules.)

% arara: pdflatex

\documentclass{article}
\usepackage{xcolor}
\definecolor{spacecolor}{named}{red}
\newcommand*{\test}{%
    Test}
\newcommand{\yatest}{
    Test
    }
\newcommand*{\here}{\textcolor{spacecolor}{\rule{.335em}{1.5ex}}}
\usepackage{lua-visual-debug}

\begin{document}
Test Test    Test \test\yatest\test 

Test\here{}Test\here{}Test\here{}Test\here{}Test\here{}Test
\end{document}

enter image description here

LaRiFaRi
  • 43,807
  • 1
    Showing a spurious space is one thing; finding where it is introduced in the source is (for most users) another matter. :-) But, I am assuming this question is a building block to something more, and I'm interested in that! :-) – Paul Gessler Jun 16 '15 at 12:45

3 Answers3

13

Borrowing code by Marcin Woliński at "How to make a box disappear at a line break", already used for my answer at Check if at begin of a line

\documentclass{article}
\newcommand{\AND}{%
  \leaders\hrule height 1.5ex
  \hskip\fontdimen2\font plus \fontdimen3\font minus \fontdimen4\font
  }

\newenvironment{showspaces}
 {\par\obeyspaces\obeylines
  \begingroup\lccode`\~=`\ \lowercase{\endgroup\let~}\AND
  \begingroup\lccode`\~=`\^^M\lowercase{\endgroup\let~}\AND}
 {\par}

\begin{document}

\begin{showspaces}%
some text some text someveryverylongword text text
some text some text someveryverylongword text text
some text some text someveryverylongword text text
some text some text someveryverylongword text text
some text some text someveryverylongword text text
\end{showspaces}

\end{document}

enter image description here

egreg
  • 1,121,712
  • Thank you, but it is not working at all with my MWE. It is redefining my real keystrokes, but I want to redefine everything, LaTeX sees as a white space. Maybe I formulated that wrong. Now, I am seeing 4 rules after my second "Test" and none at all for my spurious white spaces inserted on purpose by my \yatest command. – LaRiFaRi Jun 16 '15 at 14:26
  • @LaRiFaRi Debugging spurious spaces cannot be done this way. By definition a spurious space has already been tokenized, so there's no hope to get it by changing the category code of the space. – egreg Jun 16 '15 at 14:27
  • That is a pity. Do you mean that you can't debug with visible white (red) spaces or do you say that it is not possible to interfere the moment, LaTeX decides to provide an white space. (Which would just happen for x times "space" or 1 time "enter" in the source, afaik) – LaRiFaRi Jun 16 '15 at 14:41
  • Ok, I see. Thanks for your comment. But maybe someone will have a solution without changing the cat-code, but by highlighting it like Patrick Gundlach did with lua-visual-debug. We will see. – LaRiFaRi Jun 16 '15 at 14:47
9

The new feature \pdfinterwordspaceon of pdfTeX 1.40.15 can be exploited to get a tiny visible space, where TeX would put an invisible space. The feature has the purpose to have a real space character in the output instead of pure white space by moving to the next character position. By changing the font to cmtt10, which has a visible space at the space position:

\pdfmapline{=dummy-space <cmtt10.pfb}
\pdfglyphtounicode{space}{0042}

\documentclass{article}

\newcommand{\foo}{Some text with }

\begin{document}
\pdfinterwordspaceon
\foo faked interword spaces.
\end{document}

Result

Disadvantages:

  • The character is scaled so tiny, that it is nearly invisible, even with an visible character.

  • Several spaces in a row are merged to one space character.

  • Even worse, the space character additions can also happen for \hskip or \kern commands.

Advantage:

  • At least this method gets some useful visual feedback on unwanted spaces hidden in macros, where category code changes have too much side effects.

At least, the appearance of the visible space could be improved by post-processing the PDF file.

Heiko Oberdiek
  • 271,626
4

Knuth's CWEB program inserts visible space characters automatically for string constants in a C program, as this example shows (save as space.w, compile as cweave space && pdftex space).

@ \.{CWEB}, show me how you format spaces in string constants.

@p
#include <stdio.h>
static const char greeting[] = "H e l l o  ,   w o r l d !\n";
int main(void)
{
    printf("%s", greeting);
    return(0);
}

enter image description here

This behavior is defined in cwebmac.tex, and I have modified only the part that shows spaces for LaTeX in this example:

\documentclass{article}
\newcommand{\SP}{\texttt{\char`\ }} % (visible) space in a string
\newcommand{\showspaces}[1]{\begingroup\let\ =\SP #1\endgroup}
\begin{document}

Test\SP Test\SP\SP % method one

\showspaces{Test\ Test\ \ } % method two

\end{document}

enter image description here

CWEB does this automatically by pre-processing the input .w file, which only contains "H e l l o" with spaces, and producing a .tex file which contains H\ e\ l\ l\ o. Especially if this is for testing purposes, perhaps a preprocessor approach might work for you as well. For example, a fairly simple C program could read a .tex file in one character at a time and every time it reads a space it could substitute \SP.

Something like this could be the core algorithm:

if ((c = fgetc(infile)) == ' ') 
    fprintf(outfile, "\\SP");
else fputc(c, outfile);
musarithmia
  • 12,463