5

I am using the here doc to print usage messages for the user. Is there a way to print specific words BOLD similar to the man pages on unix. I am using this on Unix. Is there a way to use Term::ANSIColor(or some other way?) with the here doc?

Wilderness
  • 1,309
  • 2
  • 15
  • 27

2 Answers2

9

1) You can simply include ANSI codes into heredoc:

print <<EOD;
XXXX\033[1;30;40m YYYY\033[1;33;43m ZZZZ\033[0mRESET
EOD

2) Heredoc interpolates the variables, so if you include ANSI colors into a variable, it works.

my $v="xxxxx";
$var = "\nXXXX\033[1;30;40m YYYY\033[1;33;43mZZZZ\033[0mRESET\n";
print <<EOD;
$var
EOD

3) Building on #2, you can generate ANSI codes via Term::ANSIColor's color() method as a string and use the variable containing that string in the heredoc. Sorry, no working example since I don't have ANSIColor installed but should be obvious.

You may want to store a specific ANSI code in some specific variable and put the actual text in heredoc and sprincle ANSI-code variables there.

DVK
  • 126,886
  • 32
  • 213
  • 327
  • @DVK: Please put that semicolon up next to the heredoc token where it belongs. You should not change where things go. – tchrist Nov 11 '10 at 19:02
  • @tchrist - Done. Haven't used heredocs in ages, sorry. I'm curious as to why does it seem to work just as well with semicolon after the end of heredoc as after the token? – DVK Nov 11 '10 at 19:37
  • @DVK: check your mail. The reason it still works is because the parser is still looking for a semicolon. Think of heredocs as literals, and swap in `"blah"` where you put `<<"DOC"`. For example, `foo(1, <<"EO_SPECIAL", 2);`. See how the rest of the syntax stays the same around it? It would be just supericky to wait for the `, 2);` part until *after* the line containing only `EO_SPECIAL`, you know? So do the same with a semicolon. – tchrist Nov 11 '10 at 19:59
  • @DVK: In your inbox you will find my unitrio scripts; *uniprops* in particular has lotsa heredocs in it. Here’s an example of one: `return eval(dequeue("|QQ|", <<"VALIDATE_PROPERTY")) || 0;`. See how that works? – tchrist Nov 11 '10 at 20:02
  • FWIW, generating those ansi codes can be easily achieved with `Term::ANSIColor`, and afterwards you'll actually be able to understand what's going on without either remembering a lot of shit or looking the escapes up every time. – rafl Nov 11 '10 at 20:06
  • @Rafl - that's the point of entry #3 - I have put the relevant portion in **bold** now to maike it more clear that's exactly what I'm driving at. – DVK Nov 11 '10 at 20:14
  • @DVK & @Rafl: Got the point ! Am actually using the variables for the ansi codes. For this specific case, it would have been good to have <> allowed in variable name (like $ = "\033[1m"; and $ = "\033[0m";) to make the code more readable when used in the here doc...but anyways, it works, so thanks again ! – Wilderness Nov 11 '10 at 20:29
  • @DVK: Sorry. I was simply not reading carefully and overlooked that bit. Nevermind! :-) – rafl Nov 11 '10 at 20:49
  • @Wilderness - you can try for all-caps variable names or use underscores, e.g. `This is my$__ANSI_BLUE comment` – DVK Nov 11 '10 at 21:53
  • @DVK: Yeah ! That's what I will do. But the code looks a lil messy with $BBs sprinkled around disorderly. The here doc seems to have issues with tabs as well. Doesn't preserve the space I see in the code on the terminal as well. I had to use spaces instead to preserve the look. – Wilderness Nov 11 '10 at 22:50
  • 1
    @Wilderness, you can use `${var}` to access `$var` and make the variable references stand out a bit more. It will also help you when you try to write something like `${bold}word${reset}`. – Ven'Tatsu Nov 11 '10 at 23:12
  • @Ven'Tatsu: That looks better and I don't need to have a space between $bold and word. – Wilderness Nov 12 '10 at 00:22
  • Hardcoding ANSI colours like that is a *staggeringly* bad idea. Please edit your examples so that they use Term::ANSIColor. – Leolo Nov 12 '10 at 06:59
  • @Leolo - please see the bolded part in item #3. – DVK Nov 12 '10 at 15:55
  • @All: Can overloading '<' and '>' be used here or will it be stretching the small need too far (bad programming practice???)? Also, in context of the larger program needs, is it wise to have modules loaded for cosmetic purposes (from a system performance standpoint)? – Wilderness Nov 12 '10 at 18:17
5

You can use the @{[expression]} syntax within a heredoc to evaluate arbitrary code. The output of this little program will look OK if your terminal has a dark background and light foreground color:

use Term::ANSIColor;

print <<EOF;
I am using the here doc to print usage messages 
for the user. Is there a way to print @{[colored['bright_white'],'specific words']} 
BOLD similar to the man pages on unix. I am using 
this on Unix. Is there a way to use Term::ANSIColor
(or some other way?) with the here doc?
EOF
mob
  • 117,087
  • 18
  • 149
  • 283