this post was submitted on 09 Jan 2025
5 points (100.0% liked)

TeX typesetting

157 readers
1 users here now

A place to share ideas, resources, tips, and hacks for Donald Knuths typesetting software TeX. All variants and formats like OpTeX, LaTeX and ConTeXt are welcome.

founded 2 years ago
MODERATORS
 

cross-posted from: https://linkage.ds8.zone/post/363360

I am trying to do some simple character replacements on an input file and writing it to a file. The output produced by \StrSubstitute is quite bizarre. Here is a MWE:

\documentclass{article}

\usepackage{newfile}      % furnishes \newoutputstream
\usepackage{catchfile}    % furnishes \CatchFileDef
\usepackage{xstring}      % furnishes \StrSubstitute
\usepackage{stringstrings}% furnishes \convertword (a \StrSubstitute alternative)

% heredoc that creates source input file
\begin{filecontents*}{\jobname_sample.txt}
line one

line two
tricky symbols: _&%
\end{filecontents*}

\CatchFileDef{\cfile}{\jobname_sample.txt}{}

\begin{document}

% Replacements needed:
%   & → \&
%   % → \%
%   _ → \_
%   \newline\newline → \textLF (replace blank lines)
%
\StrSubstitute{\cfile}{&}{\&}[\mystring]
\StrSubstitute{\mystring}{\%}{\%}[\mystring]
\StrSubstitute{\mystring}{_}{\_}[\mystring]
\StrSubstitute{\mystring}{\newline\newline}{\\textLF}[\mystring]

\newwrite\myoutput
\immediate\openout\myoutput=\jobname_filtered_native.txt
\immediate\write\myoutput{\mystring}
\immediate\closeout\myoutput

\newoutputstream{filtered}
\openoutputfile{\jobname_filtered_newfile.txt}{filtered}
\addtostream{filtered}{\mystring}
\closeoutputstream{filtered}

\noindent\textbf{filtered catchfile}:\\
\mystring

\noindent\textbf{filtered catchfile (2nd attempt)}:\\
\convertword{\mystring}{\newline\newline}{\noexpand\textLF}
 
\end{document}

That uses two different techniques to write to a file, and both give slightly different yet wildly unexpected output:

$ cat sample_code_filtered_native.txt
line one \par line two tricky symbols: \protect \global \let \OT1\textunderscore \unhbox \voidb@x \kern .06em\vbox {\hrule width.3em}\OT1\textunderscore \&
$ cat sample_code_filtered_newfile.txt
line one \par line two tricky symbols: \global\let \OT1\textunderscore \unhbox \voidb@x \kern .06em\vbox {\hrule width.3em}\OT1\textunderscore \&

What triggered all that garbage to be created? This is what the output [b]should[/b] be:

line one\textLF
line two
tricky symbols: _&%

I also tried a 3rd way to write \mystring to a file, as follows:

\begin{filecontents*}{\jobname_myvar.txt}
  \mystring
\end{filecontents*}

That approach literally writes the string “\mystring” to a file, which is useless in this case.

(update) apparently a \string needs to prefix the substituted strings.

no comments (yet)
sorted by: hot top controversial new old
there doesn't seem to be anything here