13

filecontents package replaces tabs with spaces. Is there any solution to preserve tabs in the generated file without changing the following code?

\begin{filecontents*}{textWithTabs.txt}
Aa    Bb    Cc
1     2     3
\end{filecontents*}

Generated file is:

Aa Bb Cc
1 2 3

Desired file is:

Aa    Bb    Cc
1     2     3
Kadir
  • 1,537
  • 1
  • 11
  • 27
  • 4
    That's a good question. texdoc filecontents says nothing about that point. – Clément Jul 09 '14 at 12:37
  • 6
    texdoc usrguide documents the original filecontents environment, before the environment is patched by the filecontents package. Quoting the document: Only normal ASCII text characters (7-bit visible text) should be included in a filecontents environment. Anything else, such as tab characters, form-feeds or 8-bit characters, should not be included in a filecontents environment. There is more text about the conversion to spaces. The document does not suggest any solution around this limitation. – mvkorpel Jul 09 '14 at 12:50
  • 1
    @mvkorpel: That is interesting information, but does the package circumvents this? I found also nothing about this, as Clément already stated. The package filecontents version claims about verbatim writing the content, in this case, the tab characters should be preserved. –  Jul 09 '14 at 12:58
  • 3
    Related (and showing why this is a problem): How to output a tabulation into a file – egreg Jul 09 '14 at 13:08
  • @ChristianHupfer The results we are seeing suggest that the filecontents package does nothing about this particular limitation. One could also assume that the package documentation would advertise the ability to preserve tabs if such a feature was implemented. I don't understand what you mean by "verbatim writing the content". – mvkorpel Jul 09 '14 at 13:22
  • 1
    @mvkorpel: Sorry about verbatim writing... I meant, as stated in filecontents package manual filecontents works much like verbatim ... I misinterpreted this, that verbatim is used. –  Jul 09 '14 at 13:43
  • 1
    The filecontents environment makes the tab active \catcode`\^^I\active and later defines it to insert a space AFAIK – cgnieder Mar 08 '17 at 21:52

3 Answers3

3

LaTeX and package filcontents define the filecontents environment with a TAB character active in order to change it into a space. To disable this feature, you have just to destroy this processus for TAB character. Then you have this code:

\documentclass{article}
\makeatletter
\chardef\other=12
\begingroup%
\catcode`\*=11 %
\catcode`\^^M\active%
\catcode`\^^L\active\let^^L\relax%
\catcode`\^^I\other%
\gdef\filec@ntents#1{%
  \openin\@inputcheck#1 %
  \ifeof\@inputcheck%
    \@latex@warning@no@line%
        {Writing file `\@currdir#1'}%
  \else %
    \@latex@warning@no@line%
        {Overwriting file `\@currdir#1'}%
  \fi %
  \closein\@inputcheck %
  \chardef\reserved@c15 %
  \ch@ck7\reserved@c\write%
  \immediate\openout\reserved@c#1\relax%
  \if@tempswa%
    \immediate\write\reserved@c{%
      \@percentchar\@percentchar\space%
          \expandafter\@gobble\string\LaTeX2e file `#1'^^J%
      \@percentchar\@percentchar\space  generated by the %
        `\@currenvir' \expandafter\@gobblefour\string\newenvironment^^J%
      \@percentchar\@percentchar\space from source `\jobname' on %
         \number\year/\two@digits\month/\two@digits\day.^^J%
      \@percentchar\@percentchar}%
  \fi%
  \let\do\@makeother\dospecials%
  \count0=128\relax %
  \loop %
    \catcode\count0=11\relax %
    \advance\count0 by 1\relax %
    \ifnum\count0<256 %
  \repeat %
  \edef\E{\@backslashchar end\string{\@currenvir\string}}%
  \edef\reserved@b{%
    \def\noexpand\reserved@b%
         ####1\E####2\E####3\relax}%
  \reserved@b{%
    \ifx\relax##3\relax%
      \immediate\write\reserved@c{##1}%
    \else%
      \edef^^M{\noexpand\end{\@currenvir}}%
      \ifx\relax##1\relax%
      \else%
          \@latex@warning{Writing text `##1' before %
             \string\end{\@currenvir}\MessageBreak as last line of #1}%
        \immediate\write\reserved@c{##1}%
      \fi%
      \ifx\relax##2\relax%
      \else%
         \@latex@warning{%
           Ignoring text `##2' after \string\end{\@currenvir}}%
      \fi%
    \fi%
    ^^M}%
  \catcode`\^^L\active%
  \let\L\@undefined%
  \def^^L{\@ifundefined L^^J^^J^^J}%
  \catcode`\^^I\other%
  \catcode`\^^M\active%
  \edef^^M##1^^M{%
    \noexpand\reserved@b##1\E\E\relax}}%
\endgroup%
\def\fc@no@preamblecmds#1\do\filecontents#2\do\filec@ntents#3\relax{%
  \gdef\@preamblecmds{#1#3}}
\expandafter\fc@no@preamblecmds\@preamblecmds\relax
\makeatother
\begin{document}
\begin{filecontents*}{textWithTabs.txt}
  Aa    Bb  Cc
  1 2   3
\end{filecontents*}
\end{document}
  • Nice work, I can't see which lines have been modified, can you explain the modifications made? – AndréC Sep 04 '17 at 07:08
  • I have created the \other code (catcode 'other' is 12).

    The catcode of character ^^I has became \other (twice).

    I have removed the definition of ^^I since it was no more an active char (catcode 13).

    That's all.

    – Jean-Côme Charpentier Sep 05 '17 at 16:49
  • I do not have a problem with the principle, but with its practical implementation in 71 lines of code. Which lines (numbers) are modified? – AndréC Sep 05 '17 at 17:27
  • 1
    line 3 is a created one. Lines 8 and 65 are changed. In original code there was some lines after line 65 which define ^^I. These lines are removed in my code. – Jean-Côme Charpentier Sep 12 '17 at 21:35
3

With the scontents package it is possible to save the TABs character in the <output file>.

\documentclass{article}
\usepackage{scontents}
\usepackage{xcolor,fvextra} % only for example
\pagestyle{empty}
\begin{document}
% Write real tabs
\begin{scontents}[write-out=textWithTabs.txt]
	Aa	Bb	Cc
	1	2	3
\end{scontents}
Show correct TABs in \verb|textWithTabs.txt|.
\VerbatimInput[obeytabs, showtabs, tab=\rightarrowfill, tabcolor=red,showspaces, spacecolor=blue]{textWithTabs.txt}
\end{document}
output
-2

Works fine. works like verbatim.

\documentclass{article}
\usepackage{filecontents}
\begin{document}
\begin{filecontents*}{textWithTabs.txt}
Aa          Bb             Cc
1           2              3
\end{filecontents*}

\end{document}

I got

enter image description here

JMP
  • 3,238
murugan
  • 1,669
  • 3
    This does not work, after replacing the spaces with tabs, on a mac with current texlive. Are you sure the tabs in the input file were not converted to spaces by the editor? – Andrew Swann Feb 06 '17 at 18:35