groff

Macro BOLDing 2+ lines


I am trying to debug one my macro and finally I reduced it to the simplest form: it accepts an argument, wraps it with "set-bold", "reset-bold" font requests and that's all. But the problem is that I want to pass it multiple lines as 1 argument. I tried to embed "\n" inside the string, but without success (I still don't know if it's possible). So, I switched to a diversion:

.\" Start a diversion to capture text                                                                                         
.di t1                                                                                                                        
aaa                                                                                                                           
                                                                                                                              
bbb                                                                                                                           
                                                                                                                              
.di                                                                                                                           
                                                                                                                              
.\" Define a macro to print the diversion content in bold                                                                     
.de MMM                                                                                                                      
.ft B                                                                                                                         
\\$1                                                                                                                          
.                                                                                                                             
.ft R                                                                                                                         
..                                                                                                                            
                                                                                                                              
.\" Use the macro to process and print the diversion (I am
.\" not sure about asciify too)
.asciify t1                                                                                                                   
.MMM \*[t1]

and it prints

aaa

bbb

I.e. "bbb" is not bold! It was a problem to force it to print "bbb", not only "aaa" (I tried .br between lines but it seems only empty line works fine). And after this, I hit impossibility to bold ALL lines (in the case they are only 2).

So how to force it to make "bbb" bold, I have not idea. I don't understand even why it happens. Usually such trick works but not with multi-line arguments.

How to fix this simple macro?


Solution

  • You cannot give multiple lines as an argument to a macro call.

    When you do the call to MMM, actually only the first line is given as argument. To show this:

    .\" Start a diversion to capture text                                                                                         
    .di t1
    aaa
    
    bbb
    
    .di
    
    .\" Define a macro to print the diversion content in bold                                                                     
    .de MMM
    .ft B
    \\$1
    .
    .ft R
    .br
    MMM end
    ..
    
    .\" Use the macro to process and print the diversion (I am
    .\" not sure about asciify too)
    .asciify t1                                                                                                                   
    .MMM \*[t1]
    

    which gives:

    demonstration_macro_end

    So the bbb is never seen by the macro MMM. The actual input for groff would be

    .MMM aaa
    
    bbb
    
    

    There are two ways to gt around this problem. First: use a known diversion name. If you always use t1 as the diversion name, simply do

    .de MMM2
    .ft B
    \*[t1]
    .ft R
    ..
    

    Or use the name of the diversion as argument:

    .de MMM3
    .ft B
    \\*[\\$1]
    .ft R
    ..
    

    Some explanation about diversions: a diversion is used to divert the formatted text into a named storage area. What you need is unformatted text. .asciify basically unformats the diversion again.

    Putting it all together in one demo, you'll get:

    .\" Start a diversion to capture text  
    .di t1
    aaa
    
    bbb
    
    .di
    
    .di t2
    ccc
    
    ddd
    
    .di
    
    .\" Define a macro to print the diversion content in bold                                                                     
    .de MMM
    .ft B
    \\$1
    .
    .ft R
    .br
    MMM end
    ..
    
    .\" Unformat the diversions using asciify
    .asciify t1                                                                                                                   
    .asciify t2    
    
    .\" Use the macro to process and print the diversion 
                                                                                                                   
    .MMM \*[t1]
    
    .\" Use a known diversion name instead of an argument to the macro
    .de MMM2
    .ft B
    \*[t1]
    .ft R
    ..
    
    .MMM2
    .\" Use the name of the diversion as argument to the macro
    .de MMM3
    .ft B
    \\*[\\$1]
    .ft R
    ..
    
    .MMM3 t1
    
    .MMM3 t2
    
    .MMM3 t1
    

    with the output:

    all possibilities together