13

How can I replace all occurrence of user defined latex macros with their definitions?

For example, given this file

old.tex

\newcommand{\blah}[2]{#1 \to #2}
...
foo \blah{egg}{spam} bar
...

how to generate the file below in an automatic way

new.tex

...
foo egg \to spam bar
...

Instead of reimplementing latex macro logic with perl, can I use latex or tex engine itself to do this?

Yoo
  • 17,526
  • 6
  • 41
  • 47
  • Interesting question. I think this is really hard, if not impossible. An appropriate TeX script would have to parse every token in every line and check whether it is a user-defined command, which I think is quite complex. Things like catcode changes in the document complicate it even further. I'd suggest that you try to find a completely different solution. TeX is fine for typesetting a DVI or PDF output file from an input file, but anything else is extremely complicated. – Philipp Oct 02 '09 at 18:17
  • You are probably much better off using perl or your language of choice to parse your .tex files and replace the macros. – Mica Oct 02 '09 at 18:40
  • [This](http://stackoverflow.com/questions/2462656/transform-a-tex-source-so-that-all-macros-are-replaced-by-their-definition) stackoverflow question has an answer for it: [tme](http://www.astro.indiana.edu/~jthorn/software.html#tme) – Mauro Sep 05 '13 at 17:07

4 Answers4

14

VOILÀ http://www.ctan.org/tex-archive/support/de-macro

This is a Python that:

[...] will ex­pand macros de­fined in (re)new­com­mand or (re)newen­vi­ron­ment com­mands, within the doc­u­ment, or in the doc­u­ment’s “pri­vate” pack­age file.

Alex
  • 778
  • 2
  • 12
  • 16
1

Never seen this done, but 2 half-baked ideas:

  1. If the reason why you want to expand all these macros inline is for debugging, then setting \tracingmacros=1 in your document will expand all your macros, but the output goes to a log file.

  2. The CTAN archive provides a package that you can use to inline expansions within definitions (but not newcommand), but I didn't know if you might take a look and see how painful it might be to modify to perform inline expansions of \newcommand instead of \def.

DaveParillo
  • 2,233
  • 22
  • 20
1

Consider using a template engine such as Jinja2 with Python.

You may wish to change the syntax from the default {%, {{, etc. in order to make it more compatible with LaTeX's own. For example:

env = jinja2.Environment(
      loader=jinja2.FileSystemLoader( JINJA_DIRS ),
      comment_start_string='["', # don't conflict with e.g. {#1
      comment_end_string = '"]',
      block_start_string = '[%',
      block_end_string = '%]',
      variable_start_string = '[=',
      variable_end_string = ']',
      autoescape=True,
      finalize=_jinja2_finalize_callback, # make a function that escapes TeX
      )

template = env.get_template( self.template )

tex = template.render( content ) 

In addition to functions that are passed to the template's environment, Jinja2 supports macros. For example, your above code should work as expected as:

[% macro blah(egg, spam) -%]
foo [=egg] \to [=spam] bar
[%- endmacro %]

[= blah("chicken","pork") ]
% substitutes with "foo chicken \to pork"

I'm not sure what your goals are, and this requires a bit of work, but isn't an insurmountable problem at all if you're familiar with Python.

I hope that helps.

Brian M. Hunt
  • 81,008
  • 74
  • 230
  • 343
1

I wrote a C program back in 2007 to expand \newcommand: http://www.gtoal.com/src/newcommand/ - I guess it wasn't indexed at the time this question was posted. Mentioning it now for anyone still looking for such a thing and finding this page.

From the code...

// FOR DOCUMENTATION, SEE MY BLOG POST:
//    http://techennui.blogspot.com/2007/11/quick-hack-17-in-series-of-42-inlining.html

// Expands LaTeX \newcommand macros to allow submission of documents
// to print services which do not allow user-defined macros.

// Valid input formats are:
// \newcommand{\whatever}{Replacement text}
// \newcommand{\whatever}[2]{Expand #1 and #2 but not \#1 or even $\#1$}
// - anything else ought to be passed through verbatim; if an insurmountable
// error is detected, the program exits with a non-0 return code.

// The purpose of this utility is similar to:
//    http://winedt.org/Macros/LaTeX/uncommand.php
// which I wasn't aware of when I wrote it.  Though I would like to see how
// well that program handles the test input file, to see if it does the
// right thing with some of the more complex definitions :-)
//
// See also http://texcatalogue.sarovar.org/entries/de-macro.html
// and http://www.mackichan.com/index.html?techtalk/685.htm~mainFrame
Graham Toal
  • 324
  • 1
  • 7
  • The WinEdt uncommand macro is is now available via https://www.winedt.org/old/Macros/LaTeX/uncommand.php – ttq Apr 19 '23 at 15:33