LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Easier way to color text in Perl like BASH? (https://www.linuxquestions.org/questions/programming-9/easier-way-to-color-text-in-perl-like-bash-800842/)

DevonB 04-08-2010 01:53 PM

Easier way to color text in Perl like BASH?
 
Hello all,

I've been trying to figure out a way to more easily color text in Perl like I do on Bash on a Linux box. In bash, what I'll do is set color variables up to equal the escape sequence, then echo out with escape seqeunces to print it exactly how I want it. Typically I'll want a character or a word in a different color, not the whole line. For example
Code:


echo -n -e "My face is turning ${RED}red${UNCOLOR} like a lobster."

In Perl with the term::ANSIColor module, it seems to just do a line. Am I being dense? Is there a way that I can do it like I do it in BASH that's fairly easy to read after the fact? Any suggestions?

Devon

Sergei Steshenko 04-08-2010 02:03 PM

Quote:

Originally Posted by DevonB (Post 3928876)
Hello all,

I've been trying to figure out a way to more easily color text in Perl like I do on Bash on a Linux box. In bash, what I'll do is set color variables up to equal the escape sequence, then echo out with escape seqeunces to print it exactly how I want it. Typically I'll want a character or a word in a different color, not the whole line. For example
Code:


echo -n -e "My face is turning ${RED}red${UNCOLOR} like a lobster."

In Perl with the term::ANSIColor module, it seems to just do a line. Am I being dense? Is there a way that I can do it like I do it in BASH that's fairly easy to read after the fact? Any suggestions?

Devon

http://perldoc.perl.org/Term/ANSIColor.html - line numbers 17 .. 22 in the first listing. You can use 'print' without "\n" in the end.

DevonB 04-08-2010 02:17 PM

Thanks for the suggestion. This will work, but looks very messy. For example -

Code:

#!/usr/bin/perl -w

    use Term::ANSIColor qw(:constants);
    $Term::ANSIColor::AUTORESET = 1;
    print "Do you wish to operate in ";
    print BOLD GREEN "(s)";
    print "cript mode or in ";
    print BOLD RED "(l)";
    print "ive mode ? \n";

That's very hard to read from a maintainability standpoint. In BASH, it be

Code:

echo -ne "Do you wish to operate in ${GREEN}(s)${UNCOLOR}ript or ${RED}(l)${UNCOLOR}ive mode ? \n"
That to me is more readable and what I'm trying to emulate, if possible.

Devon

Sergei Steshenko 04-08-2010 03:03 PM

Quote:

Originally Posted by DevonB (Post 3928904)
Thanks for the suggestion. This will work, but looks very messy. For example -

Code:

#!/usr/bin/perl -w

    use Term::ANSIColor qw(:constants);
    $Term::ANSIColor::AUTORESET = 1;
    print "Do you wish to operate in ";
    print BOLD GREEN "(s)";
    print "cript mode or in ";
    print BOLD RED "(l)";
    print "ive mode ? \n";

That's very hard to read from a maintainability standpoint. In BASH, it be

Code:

echo -ne "Do you wish to operate in ${GREEN}(s)${UNCOLOR}ript or ${RED}(l)${UNCOLOR}ive mode ? \n"
That to me is more readable and what I'm trying to emulate, if possible.

Devon

You can have a number of 'print' statements on in one line.

You can invent your own simplistic color management language, like

Code:

"The next hello will be red __RED__hello, but goodbye to come will be __BLUE__goodbye"
, trivially parse it and convert into what Term::ANSIColor understands.

You can probably even overload 'print' in order to do the above parsing.

Sergei Steshenko 04-08-2010 03:49 PM

Or you can use a subset of standard language, say, HTML (it allows coloration), any standard HTML parser and, again, convert the parser output into what Term::ANSIColor understands.

DevonB 04-09-2010 08:38 AM

I went a different route and the problem is solved, but it produced a different error. Here's how I did it -

I made a subroutine that takes parameters in pairs; the color you want printed and the statement you want printed. The call of the subroutine makes it read very close to the way it did in BASH for me.

Code:

&colorprint("NO","The lobster was ","RED","red");
Here's the problem; The statement inside the subroutine of

Code:

print $COLOR "$STATEMENT";
Makes it thinks $COLOR is a filehandle, and gives an error stating that RED is not a file handle. However -

Code:

print RED "$STATEMENT";
works fine, and prints as expected. I did an ugly work around of lots of elsif's searching for all the possible color names, but I'd prefer for it to evaluate $COLOR and consider it a color selection instead of a file handle. My guess is this is a presidence problem of how it evaluates the statement from right to left, but I have no idea how to fix it? I'm way too new to perl still.

Suggestions? Thanks for the help so far.

Devon

theNbomr 04-09-2010 09:29 AM

Why not just create your own print function which translates embedded color tags to escape sequences, using regular expression substitutions, and ultimately prints the converted string?
Untested:
Code:

#! /bin/perl -w
use strict;
sub colorPrint($);

    colorPrint( "This is \${red}red\${unred}\n" );
    colorPrint( "This is \${green}green\${ungreen}\n" );
    colorPrint( "This is \${blue}blue\${unblue}\n" );
    exit 0;

sub colorPrint($){

# Escape sequences not real, just invented for demonstration
my %colorTags = (
    '${red}'  => "esc[#",
    '${unred}' => "esc]#",
    '${green}' => "esc[\$",
    '${ungreen}'=> "esc]\$",
    '${blue}'  => "esc[%",
    '${unblue}'=> "esc]%"
);

my $stringToPrint = shift;
    foreach my $color ( keys %colorTags ){
        my $escapeSeq = $colorTags{ $color };
        $color = quotemeta( $color );
        $stringToPrint =~ s/$color/$escapeSeq/g;
    }
    print $stringToPrint;
}

--- rod.

DevonB 04-09-2010 11:55 AM

Thank you for the excellent suggestion, rod. I had tried something similiar to your suggestion, yet I could not figure out the escape sequences to put in place to make the colors work. All's it did was print the 'garbage' characters to the screen. With the TERM:ANSIcolors module there, it kind of lead me to believe that it didn't exist, and that printf didn't have the ability to interpret escape seqeunces like BASH does with a %b or echo does inline with -e to process escape codes. If I could get just "print $COLOR "$STATEMENT" to process $COLOR as a color name and not see it as a file handle, I'd be happy.

Devon

theNbomr 04-09-2010 12:22 PM

Quote:

Originally Posted by DevonB (Post 3929897)
Code:

print $COLOR "$STATEMENT";
Makes it thinks $COLOR is a filehandle, and gives an error stating that RED is not a file handle.

How about
Code:

print "$COLOR $STATEMENT";
or
Code:

print $COLOR, "$STATEMENT";
--- rod.

Sergei Steshenko 04-09-2010 01:04 PM

Quote:

Originally Posted by theNbomr (Post 3930134)
How about
Code:

print "$COLOR $STATEMENT";
or
Code:

print $COLOR, "$STATEMENT";
--- rod.

You don't need quotes in the last example.

DevonB 04-09-2010 01:52 PM

I got it gentlemen. I should have just looked at the TERM:ANSIColor module in the first place. The fomulation of the escape code I had earlier was my problem. I now have -


Code:

$RED="\e[31m";
$GREEN="\e[32m";

etc. and doing a

Code:

print "My lobster is ${RED}red${NO} in color.";
works as I want it to. BASH is different. It uses -

Code:

RED='\E[31;40m'
GREEN='\E[32;40m'

Just a slight variation.

Thanks for the help.

Devon

grail 04-10-2010 12:48 AM

Nice to see the easy solution was available, please don't forget to mark as SOLVED.


All times are GMT -5. The time now is 11:13 PM.