LaTeX: appending verbatim lines to an out file

969 Views Asked by At

I'm trying to create an environment in latex that writes the lines that are between the \begin{environment} and \end{environment} verbatim in a TeX file.

I have tried the fancyvrb package, it works but if I specify several \begin{environment} in my source file, only the last lines are written to the outfile (I'm guessing that VerbatimOut recreates the outfile every time, and does not append to it).

Does anybody have a lead on this? Thanks!

2

There are 2 best solutions below

0
On

This is a slightly indirect answer, but Victor Eijkhout's comment package does something similar, in the sense that it processes ‘verbatim’ blocks in the same way that LaTeX does. If that doesn't, then its implementation suggests how to do this by hand (that is, this package is what I copied when I had to this myself).

Failing that, you might want to ask on the TeX Stackexchange site.

0
On

I ran into the same problem and solved it as follows.

File verbatimappend.tex (note the file LaTeX writes to is no longer an argument as it is in the verbatimwrite environment, but defined in \verbatimFile):

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{moreverb}

\makeatletter
\def\verbatimappend{% inspired by moreverb.sty (verbatimwrite)
  \@bsphack
  \let\do\@makeother\dospecials
  \catcode`\^^M\active \catcode`\^^I=12
  \def\verbatim@processline{%
    \immediate\write\verbatimFile%
      {\the\verbatim@line}}%
  \verbatim@start}
\def\endverbatimappend{%
  \@esphack%
}
\makeatother

\begin{document}

\newwrite\verbatimFile
\immediate\openout\verbatimFile=verbatimFile.txt\relax%

\begin{verbatimappend}
Hello, world!
\end{verbatimappend}

\input{random_chars.tex}

\begin{verbatimappend}
Bye, world!
\end{verbatimappend}

\immediate\closeout\verbatimFile

\end{document}

Which I stress-tested as follows. File random_chars.pl:

#! /usr/bin/perl
use warnings;
use strict;
binmode STDOUT, ":utf8";
binmode STDERR, ":utf8";

my @ords = (32..126, 160..255); # usable latin-1/latin-9 codepoints
my $N = scalar @ords;
my @lines = ( );

sub choose_random_char {
  my $ord = int(rand($N));
  return chr($ords[$ord]);
}

while ((scalar @lines) < 10000) {
  my $line = join('', map { choose_random_char() } (1..78));
  next if $line =~ m/\\end{verbatimappend}/sx; # probably very unlikely!
  next if $line =~ m/\s+$/sx; # final spaces do not get output -> false positive
  push @lines, $line;
}

print join("\n", @lines, '');
print STDERR join("\n\n",
  (map { "Paragraph\n\n\\begin{verbatimappend}\n$_\n\\end{verbatimappend}" } @lines), '');

To use them:

$ perl random_chars.pl  > random_chars.txt 2> random_chars.tex 
$ latex verbatimappend.tex 
$ diff random_chars.txt verbatimFile.txt 

Note the specific cases excluded in random_chars.pl:

  next if $line =~ m/\\end{verbatimappend}/sx; # probably very unlikely!
  next if $line =~ m/\s+$/sx; # final spaces do not get output -> false positive

Not sure how/whether this could/should be sent to the https://www.ctan.org/pkg/moreverb package authors, as the package appears to be unmaintained.

HTH.