Macro processor

from Wikipedia, the free encyclopedia

As macro processors are computer programs called, replace the strings within a text by other strings. A character string with its replacement text is called a macro . Macros can usually be parameterized . Most macro processors know a few commands: Usually, for example, define is used to define macros. Other commands often allow string processing, conditional text replacement, writing and reading of auxiliary files, etc. Sometimes commands and macros can be processed very similarly.

A known macro processor is e.g. B. Part of the typesetting program TeX . The C preprocessor of the C language is also a macro processor.

The m4 macro processor as an example

The Unix operating system contains the macro processor m4 as standard . This allows you to define your own macros using the define macro.

    define(`H',`Hans')define(`U',`und')define(`I',`Inge')dnl
    H U I, I U H. H liebt I.

results

  • Hans und Inge, Inge und Hans. Hans liebt Inge.

The characters `(on a German keyboard to the right of the question mark) and '(to the right of the Ä) ensure that macros are not replaced if they are within a part that begins with` and ends with'.

Expressions and conditions can be implemented using many other built-in macros such as eval , ifelse . Repetitions and loops can be achieved through recursion .

Predefined macros in macro processor m4 (selection)
macro description
define (`name ', def) Definition of the new macro name , replacement with def
eval Evaluation of an arithmetic expression
incr Increase the argument by one
ifdef Conditional execution
divert (-1) Suppression of output
dnl Suppression of the rest of the line (including line separators)
include (`file ') Read text from file and interpret it.
$ 1 , $ 2 , ... Parameters which can be used within def in a macro definition and which are then replaced by the text of the current parameter when called.

For example, a macro processor can be used to implement automatic counters:

define(`Zaehler',`define(`$1',incr($1))Kapitel $1.')dnl
define(`kapitelnr',0)dnl
Zaehler(`kapitelnr')
Zaehler(`kapitelnr')
Zaehler(`kapitelnr')
Zaehler(`kapitelnr')

If this example is processed with m4, the following output is obtained:

Kapitel 1.
Kapitel 2.
Kapitel 3.
Kapitel 4.

This z. B. Automatically incrementing chapter and section numbers in a text:

divert(-1)dnl
  define(`Zaehler',`define(`$1',incr($1))$1')
  define(`kapitelnr',0)
  define(`abschnittnr',0)
  define(`Kapitel',`<h1>Zaehler(`kapitelnr'). $1</h1>define(`abschnittnr',0)')
  define(`Abschnitt',`<h2>kapitelnr.Zaehler(`abschnittnr') $1</h2>')
divert(0)dnl
Kapitel(Einführung)
Dieser Text handelt von …
Abschnitt(Geschichte)
Geschichtlich ist folgendes zu sagen …
Abschnitt(Neuere Entwicklungen)
Doch in neuerer Zeit ergeben sich …
Kapitel(Definitionen)
Abschnitt(Zahlenwerte)
…
Abschnitt(Konstanten)
…
Abschnitt(Variablen)
…

The output of m4 is then

  <h1>1. Einführung</h1>
  Dieser Text handelt von …
  <h2>1.1 Geschichte</h2>
  Geschichtlich ist folgendes zu sagen …
  <h2>1.2 Neuere Entwicklungen</h2>
  Doch in neuerer Zeit ergeben sich …
  <h1>2. Definitionen</h1>
  <h2>2.1 Zahlenwerte</h2>
  … …
  <h2>2.2 Konstanten</h2>
  … …
  <h2>2.3 Variablen</h2>
  … …

The macro processor as a preprocessor

A macro processor is a form of preprocessor ( pre- processor). It changes an input text before the user transfers it to the actual processing program.

Under Unix , many macro processors can be called in the command line as separate processes; the processed text is passed on via a pipe :

  $ m4 diplomarbeit.txt | tbl | eqn | groff -mt -Tps | kprinter

Here the diplomarbeit.txt file is first processed by the macro processor m4 , then by the table processor tbl and the formula set processor eqn (both macro processors), in order then to be converted by the text set (macro) processor groff into the PostScript language. kprinter can then output the result on a Postscript-compatible printer.

The C preprocessor

The C programming language contains a simple macro processor, the C preprocessor . This can be used for the following tasks:

  • Definition of symbolic constants
  • Conditional translation
  • Extension of the language through simple language constructs
  • Simplification of paperwork
Commands of the C preprocessor (selection)
macro description
#define name replacement text Definition of the new macro name . If name occurs in the text, it is replaced by the replacement text .
#define name (p1, p2) txt Definition of the new macro name with the parameters p1 and p2 . Within txt , the character strings p1 and p2 are replaced by the respective text of the current parameters.
#ifdef name
#else
#endif
Conditional translation. The lines between the macros are only translated if a macro name exists or not.
__FILE__
__LINE__
Name and line number of the file that contains the program text.
__unix__ Predefined under Unix operating systems, undefined under other systems.
#include <file>
#include "file"
Read in the file and insert text into the output.

The possibilities of the C preprocessor are relatively limited. However, it gives the language an additional flexibility that other languages ​​can hardly achieve. However, in complex program systems this also leads to difficulties with the maintenance and care of uniform definitions, which is why the programming languages ​​developed in the following deliberately avoided this concept.

In the following program example

  #define FIELDSIZE 100

  int Feld[FIELDSIZE];
  main() {
     int i;
     Feld[0] = 0; Feld[1] = 1;
     for (i = 2; i < FIELDSIZE; ++i)
        Feld[i] = Feld[i-1] + Feld[i-2];
  }

FIELDSIZE is simply replaced by 100:

  int Feld[100];
  main() {
     int i;
     Feld[0] = 0; Feld[1] = 1;
     for (i = 2; i < 100; ++i)
        Feld[i] = Feld[i-1] + Feld[i-2];
  }

Only then does a program text arise that the actual C compiler can translate without errors.

The following program determines whether it was compiled under Unix. Otherwise the system waits for an input:

  #include <stdio.h>
  main() {
     printf("Das Programm läuft ");
  #ifdef __UNIX__
     printf("unter Unix.\n");
  #else
     printf("unter einem unbekannten Betriebssystem.\n");
     printf("Bitte drücken Sie eine Taste!");
     getchar();
  #endif
  }

A Unix compiler would translate the following text here:

  main() {
     printf("Das Programm läuft ");
     printf("unter Unix.\n");
  }

On the other hand, a compiler from an unknown operating system would compile the following program:

  main() {
     printf("Das Programm läuft ");
     printf("unter einem unbekannten Betriebssystem.\n");
     printf("Bitte drücken Sie eine Taste!");
     getchar();
  }

However, the C macro processor is much simpler than the m4 processor. It does not allow recursive calls, loops or evaluation of expressions.

TeX and LaTeX

The macro processor of the typesetting program TeX can be used for user-defined extensions. The macro package LaTeX by Leslie Lamport is a widespread extension. Instead of define , new macros are defined by newcommand .

The following example shows part of a CD cover:

 \documentclass[landscape,dvips]{article}
 \usepackage{cd-cover}

 \newcommand{\lied}[4]{
 \small{\textsf{#1}} & \small{\textsf{#2}}
                     & \small{\textsf{#3}}
                     & \small{\textsf{#4}} \\}
 \begin{document}
 %[...]
 \begin{tabular}{l l l l}
 \lied{1} {Neneh Cherry}
          {Woman}
          {04:10}
 \lied{2} {Luz Casal}
          {Piensa en mi}
          {04:27}
 %[...]
 \lied{14}{Axelle Red}
          {Rester femme}
          {05:01}
 \end{tabular}

 \end{document}

MediaWiki

The MediaWiki Wiki engine contains a macro processor. To this end, master pages ( Engl. Template) created, which can then be incorporated including parameters in a page.

See also

Remarks

  1. In fact, for decades now, processing has not been done in two successive steps (unless the user explicitly wants to see the result of preprocessing as output), but in one pass during compilation.