The phase when groff reads a macro is called "copy-in mode" in roff-talk. This is comparable to the C~preprocessing phase during the development of a program written in the C~language.
In this phase, groff interprets all backslashes; that means that all escape sequences in the macro body are interpreted and replaced by their value. For constant expression, this is wanted, but strings and registers that might change between calls of the macro must be protected from being evaluated. This is most easily done by doubling the backslash that introduces the escape sequence. This doubling is most important for the positional parameters. For example, to print information on the arguments that were passed to the macro to the terminal, define a macro named .print_args, say.
When calling this macro by
the following text is printed to the terminal:
Lets analyze each backslash in the macro definition. As the positional parameters and the number of arguments will change with each call of the macro their leading backslash must be doubled, which results in [rs][rs]$* and [rs][rs][.$]. The same applies to the macro name because it could be called with an alias name, so [rs][rs]$0.
On the other hand, midpart is a constant string, it will not change, so no doubling for [rs]*[midpart]. The [rs]f escape sequences are predefined groff elements for setting the font within the text. Of course, this behavior will not change, so no doubling with [rs]f[I] and [rs]f.
Writing groff macros is easy when the escaping mechanism is temporarily disabled. In groff, this is done by enclosing the macro definition(s) into a pair of .eo and .ec requests. Then the body in the macro definition is just like a normal part of the document [em] text enhanced by calls of requests, macros, strings, registers, etc. For example, the code above can be written in a simpler way by
Unfortunately, draft mode cannot be used universally. Although it is good enough for defining normal macros, draft mode will fail with advanced applications, such as indirectly defined strings, registers, etc. An optimal way is to define and test all macros in draft mode and then do the backslash doubling as a final step; do not forget to remove the .eo request.
"Tips for Macro Definitions"