5

I need to write a command that searches a file for a string that matches a certain regexp, and inserts that string. I know how to parse a string of text using a regex with

\usepackage{l3regex}
\ExplSyntaxOn
\cs_new_protected:Npn \mycom #1
  {
    \tl_set:Nn \l_tmpa_tl {#1}
    \regex_replace_all:nnN { THE-REGEXP } { THE-REPLACEMENT } \l_tmpa_tl
    \tl_use:N \l_tmpa_tl
  }
\ExplSyntaxOff

but I don't know how I can use it to parse the contents of a file. I tried replacing {#1} with {\input{#1}}, but it didn't work (the \input was simply considered part of the string).

1
  • Take a look at the catchfile package to allow you to read an entire file to a macro, or iterate over the file line-by-line with \ior_map_inline:Nn (experimental function).
    – Joseph Wright
    Apr 25, 2012 at 7:58

1 Answer 1

7

There is no facility, at the moment, for storing into a token list the contents of a file, but you can still use the catchfile package:

\documentclass{article}
\usepackage{catchfile}
\usepackage{expl3,l3regex}
\ExplSyntaxOn
\cs_new_protected:Npn \mycom #1
  {
    \CatchFileDef \l_tmpa_tl {#1} {}
    \regex_replace_all:nnN { xrep } { foo } \l_tmpa_tl
    \tl_use:N \l_tmpa_tl
  }
\ExplSyntaxOff

\mycom{xrep}

Update

In the revision dated 2014-06-25, the functionality has been added to expl3:

\documentclass{article}
\usepackage{expl3,l3regex,xparse}
\ExplSyntaxOn

\NewDocumentCommand{\mycom}{m}
 {
  \malabarba_mycom:n { #1 }
 }

\tl_new:N \l_malabarba_mycom_content_tl
\cs_new_protected:Npn \malabarba_mycom:n #1
  {
   \tl_set_from_file:Nnn \l_malabarba_mycom_content_tl {} {#1}
   \regex_replace_all:nnN { xrep } { foo } \l_malabarba_mycom_content_tl
   \tl_use:N \l_malabarba_mycom_content_tl
  }
\ExplSyntaxOff

\mycom{xrep}

Note that there's a difference between \CatchFileDef and \tl_set_from_file:Nnn: in the former command the trailing argument contains setup instructions to be performed (locally) before loading the file, in the latter these setup tokens should go in the second argument

\CatchFileDef<command name>{<filename>}{<setup>}

\tl_set_from_file:Nnn <tl variable> { <setup> } { <filename> }

The analog of \CatchFileEdef is called

\tl_set_from_file_x:Nnn
12
  • Thanks, that's perfect. Any chance I might get LaTeX to interpret the output? =) (instead of just displaying it verbatim)
    – Malabarba
    Apr 25, 2012 at 10:07
  • @BruceConnor I get what's expected. Probably what you get wrong depends on the "replacement" regex you're using.
    – egreg
    Apr 25, 2012 at 10:14
  • What do you mea by that? The regexp does output what I expect it to ({\bf Test} for example). The problem is that this output does't get iterpreted by LaTeX (so my pdf would contain a literal {\bf Test} istead of a Test). Is that not the expected behaviour?
    – Malabarba
    Apr 25, 2012 at 10:23
  • @BruceConnor If the search regex is something like ([^\*]*?)\*\* and the replacement regex is \c{textbf}\cB\{\1\cE\} I get that **Test** is replaced by \textbf{Test} and interpreted correctly.
    – egreg
    Apr 25, 2012 at 10:29
  • If I copy/paste your answer's preamble to a new document, replace xrep with .* and foo with \c{textbf}\cB\{ Hi \cE\}, create a file in the same folder cotaining **TEST**, and call \mycom{filename} inside begin/end{document} I get the bizarre: c–textbf ̋cB–HicE ̋c–textbf ̋cB–HicE ̋
    – Malabarba
    Apr 25, 2012 at 11:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .