Syntax::Highlight::Shell - Highlight shell scripts


Syntax-Highlight-Shell documentation Contained in the Syntax-Highlight-Shell distribution.

Index


Code Index:

NAME

Top

Syntax::Highlight::Shell - Highlight shell scripts

VERSION

Top

Version 0.04

SYNOPSIS

Top

    use Syntax::Highlight::Shell;

    my $highlighter = new Syntax::Highlight::Shell;
    $output = $highlighter->parse($script);

If $script contains the following shell code:

    # an if statement
    if [ -f /etc/passwd ]; then
        grep $USER /etc/passwd | awk -F: '{print $5}' /etc/passwd
    fi

then the resulting HTML contained in $output will render like this:

DESCRIPTION

Top

This module is designed to take shell scripts and highlight them in HTML with meaningful colours using CSS. The resulting HTML output is ready for inclusion in a web page. Note that no reformating is done, all spaces are preserved.

METHODS

Top

new()

The constructor. Returns a Syntax::Highlight::Shell object, which derives from Shell::Parser.

Options

  • nnn - Activate line numbering. Default value: 0 (disabled).
  • pre - Surround result by <pre>...</pre> tags. Default value: 1 (enabled).
  • syntax - Selects the shell syntax. Check the documentation about the syntax() method in Shell::Parser documentation for more information on the available syntaxes. Default value: bourne.
  • tabs - When given a non-nul value, converts tabulations to this number of spaces. Default value: 4.

Example

To avoid surrounding the result by the <pre>...</pre> tags:

    my $highlighter = Syntax::Highlight::Shell->new(pre => 0);

parse()

Parse the shell code given in argument and returns the corresponding HTML code, ready for inclusion in a web page.

Examples

    $html = $highlighter->parse(q{ echo "hello world" });

    $html = $highlighter->parse(<<'END');
        # find my name
        if [ -f /etc/passwd ]; then
            grep $USER /etc/passwd | awk -F: '{print $5}' /etc/passwd
        fi
    END

Internal Methods

The following methods are for internal use only.

_generic_highlight()

Shell::Parser callback that does all the work of highlighting the code.

NOTES

Top

The resulting HTML uses CSS to colourize the syntax. Here are the classes that you can define in your stylesheet.

An example stylesheet can be found in examples/shell-syntax.css.

EXAMPLE

Top

Here is an example of generated HTML output. It was generated with the script eg/highlight.pl.

The following shell script

    #!/bin/sh

    user="$1"

    case "$user" in
      # check if the user is root
      'root')
        echo "You are the BOFH."
        ;;

      # for normal users, grep throught /etc/passwd
      *)
        passwd=/etc/passwd
        if [ -f $passwd ]; then 
            grep "$user" $passwd | awk -F: '{print $5}'
        else
            echo "No $passwd"
        fi
    esac

will be rendered like this (using the CSS stylesheet eg/shell-syntax.css):

CAVEATS

Top

Syntax::Highlight::Shell relies on Shell::Parser for parsing the shell code and therefore suffers from the same limitations.

SEE ALSO

Top

Shell::Parser

AUTHOR

Top

Sébastien Aperghis-Tramoni, <sebastien@aperghis.net>

BUGS

Top

Please report any bugs or feature requests to bug-syntax-highlight-shell@rt.cpan.org, or through the web interface at https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Syntax-Highlight-Shell. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

COPYRIGHT & LICENSE

Top


Syntax-Highlight-Shell documentation Contained in the Syntax-Highlight-Shell distribution.
package Syntax::Highlight::Shell;
use strict;
use Shell::Parser;

{ no strict;
  $VERSION = '0.04';
  @ISA = qw(Shell::Parser);
}

my %classes = (
    metachar      => 's-mta',   # shell metacharacters (; |, >, &, \)
    keyword       => 's-key',   # a shell keyword (if, for, while, do...)
    builtin       => 's-blt',   # a builtin command
    command       => 's-cmd',   # an external command
    argument      => 's-arg',   # command arguments
    quote         => 's-quo',   # single (') and double (") quotes
    variable      => 's-var',   # an expanded variable ($VARIABLE)
    assigned      => 's-avr',   # an assigned variable (VARIABLE=value)
    value         => 's-val',   # a value
    comment       => 's-cmt',   # a comment
    line_number   => 's-lno',   # line number
);

my %defaults = (
    pre     => 1, # add <pre>...</pre> around the result? (default: yes)
    nnn     => 0, # add line numbers (default: no)
    syntax  => 'bourne', # shell syntax (default: Bourne shell)
    tabs    => 4, # convert tabs to this number of spaces; zero to disable
);

sub new {
    my $self = __PACKAGE__->SUPER::new(handlers => {
        default => \&_generic_highlight
    });
    my $class = ref $_[0] || $_[0]; shift;
    bless $self, $class;
    
    $self->{_shs_options} = { %defaults };
    my %args = @_;
    for my $arg (keys %defaults) {
        $self->{_shs_options}{$arg} = $args{$arg} if defined $args{$arg}
    }
    
    $self->syntax($self->{_shs_options}{syntax});
    $self->{_shs_output} = '';
    
    return $self
}

sub parse {
    my $self = shift;
    
    ## parse the shell command
    $self->{_shs_output} = '';
    $self->SUPER::parse($_[0]);
    $self->eof;
    
    ## add line numbering?
    if($self->{_shs_options}{nnn}) {
        my $i = 1;
        $self->{_shs_output} =~ s|^|<span class="$classes{line_number}">@{[sprintf '%3d', $i++]}</span> |gm;
    }
    
    ## add <pre>...</pre>?
    $self->{_shs_output} = "<pre>\n" . $self->{_shs_output} . "</pre>\n" if $self->{_shs_options}{pre};
    
    ## convert tabs?
    $self->{_shs_output} =~ s/\t/' 'x$self->{_shs_options}{tabs}/ge if $self->{_shs_options}{tabs};
    
    return $self->{_shs_output}
}

sub _generic_highlight {
    my $self = shift;
    my %args = @_;
    
    if(index('metachar,keyword,builtin,command,variable,comment', $args{type}) >= 0) {
        $self->{_shs_output} .= qq|<span class="$classes{$args{type}}">| 
                              . $args{token} . qq|</span>|
    
    } else {
        if($args{token} =~ /^(["'])([^"']*)\1$/) {
            $self->{_shs_output} .= qq|<span class="$classes{quote}">$1</span>|
                                  . qq|<span class="$classes{value}">$2</span>|
                                  . qq|<span class="$classes{quote}">$1</span>|
        
        } elsif($args{type} eq 'assign')  {
            $args{token} =~ s|^([^=]*)=|<span class="$classes{assigned}">$1</span>=<span class="$classes{value}">|;
            $args{token} =~ s|$|</span>|;
            $self->{_shs_output} .= $args{token}
        
        } else {
            $self->{_shs_output} .= $args{token}
        }
    }
}

1; # End of Syntax::Highlight::Shell