Text Formattingprogrammatic find and replace in a tex file or fragment

Information and discussion about LaTeX's general text formatting features (e.g. bold, italic, enumerations, ...)
Post Reply
mmthomas
Posts: 5
Joined: Sat Dec 22, 2012 12:04 am

programmatic find and replace in a tex file or fragment

Post by mmthomas »

Hello,

I'm looking for a way to find and replace a string throughout a tex file by adding a line of code, without doing any type of manual "find and replace." The reason is that I'm using tex fragments that are the output of a Stata regression, and I have one main Stata file where I insert all the tex fragments, using the \input command. However, I want to change parts of the tex code without actually opening up those files. For example, I want to change the variable name to a latex construction, so that it appears properly in my tables. Here is the code from the main .tex file:

Code: Select all

\documentclass[10pt]{article}
\usepackage[margin=1in]{geometry}

\begin{document}
    \input{wagesinc}
    \input{hours}
    \input{parttime2}
    \input{parttimelw}
\end{document}
"wagesinc," "hours," "parttime2," and "parttimelw" are all .tex fragments that were the output of Stata and produce tables. In those pieces of code, there are several references to a variable beta, but I would like to change this to \beta by inserting an additional line of code into the main .tex file here.

I know that, for example, the PSfrag package allows one to replace tags in an .eps file with Latex constructions. I essentially want to do what I think is a simpler task: replace the strings directly in the .tex code.

I also know that the xstring package allows one to substitute in a string, so if I knew how to refer to the entire fragment of tex code as a string, that may help. However, I tried using the xstring package and the following line:

Code: Select all

\StrSubstitute{\input{hours}}{beta}{\beta}
but StrSubstitute is not reading "\input{hours}" in as a string consisting of the entire tex fragment.

So knowing either a function to search a file and output the file with all the substitutions, or knowing how to bring in the .tex fragment all as a string to search so that I can use the StrSubstitute function would be helpful.

Thanks!
Last edited by Stefan Kottwitz on Sat Dec 22, 2012 12:44 am, edited 1 time in total.

Recommended reading 2024:

LaTeXguide.org • LaTeX-Cookbook.net • TikZ.org

NEW: TikZ book now 40% off at Amazon.com for a short time.

Stefan Kottwitz
Site Admin
Posts: 10345
Joined: Mon Mar 10, 2008 9:44 pm

programmatic find and replace in a tex file or fragment

Post by Stefan Kottwitz »

Hi,

welcome to the board!

It could be done using xesearch and XeLaTeX.

Stefan
LaTeX.org admin
mmthomas
Posts: 5
Joined: Sat Dec 22, 2012 12:04 am

programmatic find and replace in a tex file or fragment

Post by mmthomas »

Hi Stefan,

Thank you so much for your help. The xesearch package is exactly what I need for this. One related question on using xesearch: I want to replace what appears in the .tex code as "beta\_3" with "$\beta_3$" - essentially the .tex fragment output from Stata is creating a table to write the variable as literally "beta_3."

My problem is that if I have the following code:

Code: Select all

\SearchList{list1}{$\beta_3$}{beta\_3}
then XeLatex gives me the following error:
! Missing \endcsname inserted.
<to be read again>
\protect
l.8 \SearchList{list1}{$\beta_3$}{treat\_s\_t\_d}
If I have the following code:

Code: Select all

\SearchList{list1}{$\beta_3$}{beta?}
"beta\_3" is not replaced. I think somehow xesearch considers "\" the end of a word or a word separator (If I have the following:

Code: Select all

\SearchList{list1}{$\beta_3$}{beta}
I get the "beta" part replaced, but I still have "_3" remaining in the table output.").

I tried using

Code: Select all

\UndoBoundary{\{\}}
but I get the same error (Missing \endcsname inserted).

Here is the entire sample code for clarity:

Code: Select all

\documentclass[10pt]{article}
\usepackage{xesearch}


\begin{document}
\SearchList{list1}{$\beta_3$}{beta\_3}
\input{wagesinc}
\end{document}
and wagesinc is a .tex fragment:

Code: Select all

\begin{tabular}
VARIABLES beta\_3 
User avatar
Stefan Kottwitz
Site Admin
Posts: 10345
Joined: Mon Mar 10, 2008 9:44 pm

programmatic find and replace in a tex file or fragment

Post by Stefan Kottwitz »

Perhaps \ could be made a letter character, by changing the catcode. But this might lead to other problems.

I guess it would be easier to treat _ like a letter character, i.e.

Code: Select all

\SearchList{list1}{$\beta$}{beta_3}
...
\catcode`\_=13
VARIABLES beta_3 
I guess it would not match yet, but should be error free, which looks like a step forward.

Stefan
LaTeX.org admin
mmthomas
Posts: 5
Joined: Sat Dec 22, 2012 12:04 am

programmatic find and replace in a tex file or fragment

Post by mmthomas »

Hi Stefan,

Thanks so much for your help.

What I would ideally want to write is something like the following:

Code: Select all

\SearchList{list1}{$\beta_3$}{beta\backslash\textunderscore3}
The reason is that the tex fragment that I have has

Code: Select all

beta\_3
in the code (so it writes "beta_3" to the table), and I would like it to have

Code: Select all

\beta_3
.

If I use the catcode command (\catcode'\\_=13, since I want to replace "\_"), I get an error that says "missing number, treated as zero. Unfortunately, if I use the command you suggested, which is just replacing "_", it does cause other problems in the code, as you mentioned. If I define a new string (using \def) to equal "\beta\_3" I get the same "Missing \endcsname inserted" error.
mmthomas
Posts: 5
Joined: Sat Dec 22, 2012 12:04 am

programmatic find and replace in a tex file or fragment

Post by mmthomas »

Another example of a similar problem is that I want to replace all instances of

Code: Select all

\hline
in the tex fragment with

Code: Select all

\hline \hline
, but if I use

Code: Select all

\SearchList{list1}{\hline\hline}{\hline}
, then I get the same error: Missing endcsname inserted.
User avatar
Stefan Kottwitz
Site Admin
Posts: 10345
Joined: Mon Mar 10, 2008 9:44 pm

Re: programmatic find and replace in a tex file or fragment

Post by Stefan Kottwitz »

Even if there are nice LaTeX possibilities, it's not a native LaTeX job to reformat its own code, so we get problems with masking or escaping special characters.

I would use a command line tool or a script for this. Such as sed, Perl, or PHP, which are great for pattern matching and replacement in text files.

Stefan
LaTeX.org admin
mmthomas
Posts: 5
Joined: Sat Dec 22, 2012 12:04 am

Re: programmatic find and replace in a tex file or fragment

Post by mmthomas »

Okay, thanks for the advice!
User avatar
Stefan Kottwitz
Site Admin
Posts: 10345
Joined: Mon Mar 10, 2008 9:44 pm

programmatic find and replace in a tex file or fragment

Post by Stefan Kottwitz »

I often use sed at the command line, such as

Code: Select all

grep <IP ADRESS> filename.log | sed -e 's/^.*\(<INTERFACE>\):\([^ \/]*\).*$/\2/g' | sort | uniq | xargs nslookup ...
Expressions in <...> are something meaningful. I mean I search log files, do a search and replace for extracing IPs, sort them, select just the unique IPs, apply further commands. sed can do search and replace "in place", great for piping. The same is possible with perl, like perl -p -e s/<value>/<value>/ig.

With Linux all tools are on board, with Windows perhaps with Cygwin, or using ActiveState Perl.

After all, I would write a Makefile or a script which does replacing and calling LaTeX.

Stefan
LaTeX.org admin
Post Reply