Search code examples
linuxm4i3

M4 not expanding all macros in .m4 file


I'm using m4 to replace some macros with colors/etc defined in included files in my i3wm config file.

$ m4 -I themes/gruvbox-dark config.m4 > config

This is (an excerpt of) my directory structure for the above command.

$ tree .
.
├── config.m4
├── font.m4
├── themes
│   ├── gruvbox-dark
│   │   ├── color.m4
│   │   └── i3.m4
└── Xresources.m4

I have macros defined such as:

define(M4_COLOR_FG,`#a89984')
define(M4_I3_FG,`M4_COLOR_FG')
define(M4_I3_BG,`#3c3836')

and in the output of m4 I still see unexpanded macros, such as:

client.focused #3c3836 M4_I3_BG M4_I3_ACTIVE_FG M4_I3_BG M4_I3_BG
client.focused_inactive #3c3836 M4_I3_BG M4_COLOR_FG M4_I3_BG M4_I3_BG
client.unfocused #3c3836 M4_I3_BG M4_COLOR_FG M4_I3_BG M4_I3_BG
client.urgent #fb4934 M4_I3_BG M4_COLOR_9 M4_COLOR_9 M4_I3_BG
client.placeholder #3c3836 M4_I3_BG M4_COLOR_FG M4_I3_BG M4_I3_BG
client.background #282828

The first macro was expanded, but the remaining ones on the line are left unexpanded. Here are the same lines in the input .m4 file:

client.focused M4_I3_BG M4_I3_BG M4_I3_ACTIVE_FG M4_I3_BG M4_I3_BG
client.focused_inactive M4_I3_BG M4_I3_BG M4_COLOR_FG M4_I3_BG M4_I3_BG
client.unfocused M4_I3_BG M4_I3_BG M4_COLOR_FG M4_I3_BG M4_I3_BG
client.urgent M4_COLOR_9 M4_I3_BG M4_COLOR_9 M4_COLOR_9 M4_I3_BG
client.placeholder M4_I3_BG M4_I3_BG M4_COLOR_FG M4_I3_BG M4_I3_BG
client.background M4_COLOR_BG

When I try to make some MWEs, it always works... not sure what the problem is with these specific files/macros.

All the files are under: https://github.com/tomocafe/dotfiles/tree/master/i3/.i3

I have tried this at work and at home, my home computer is Solus (Linux).

$ m4 --version | head -1
m4 (GNU M4) 1.4.18

Solution

  • It's very simple: if you want expand the M4_COLOR_3 M4_COLOR_3:

    1. m4 replace the first M4_COLOR_3 to #colorcode.
    2. m4 doesn't expand the next M4_COLOR_3 because the (expanded) # means comment.

    You've the solution:

    1. You'll change (or disable) the comment character with changecom.
    2. You'll use double quotation inside definition: define(FOO,``#aabbcc'')

    The first: changecom(XXX) will change the comment begin mark (only in m4 of course) to XXX and the end will the newline. The changecom()' will disable the comments (so everything will parsed bym4`).

    The second:

    define(FOO,``#aabbcc'')
    FOO FOO FOO FOO FOO