#! /usr/bin/perl use warnings; use strict; use CGI (); use HTML::Entities(); use Regexp::Common qw(balanced); use URI::Find::Schemeless (); $| = 1;    # no suffering from buffering use vars qw(%TagsBlocked %TagsFastReplace %TagsLastReplace $HighlightBin); # use external program from # http://gnu.j1b.org/software/src-highlite/source-highlight.html $HighlightBin = 'E:\apps\gnu\src-highlight\bin\source-highlight.exe'; # tags within which no further replacements should be done # better replacing the font stuff by CSS %TagsBlocked = (    perle => {        -start => qq~
PERL:
~,        -end    => qq~
~,        -string => \&HighlightPerlCode,    },    code => {        -start => qq~
CODE:
~,        -end    => qq~
~,        -string => sub { return $_[0] },    },    perldoc => {        -start  => "",        -end    => "",        -string => sub {            return qq~ perldoc $_[0] ~;        },    }, ); # tags to be replaced on the fly %TagsFastReplace = (    b => {        -start  => "",        -end    => "",        -string => sub { return $_[0] },    },    i => {        -start  => "",        -end    => "",        -string => sub { return $_[0] },    }, ); # tags that may be recursive or containing other tags %TagsLastReplace = (    quote => {        -start =>          qq~
~,        -end    => qq~
~,        -string => sub { return $_[0] },    }, ); {    local $/;    # slurp in data    my $posting = ;    &ParseText($posting); } # ------------------------------------------------------------ sub ParseText {    my ($text) = @_;    $text = &CGI::escapeHTML($text);    $text =~ s/\n/
\n/g;    # replace newlines by
   my @scanned = ();    # extract and replace %TagsBlocked    foreach my $tag ( keys %TagsBlocked ) {        # @scanned yet empty, start with $text        unless ( scalar(@scanned) ) {            @scanned = &PostFilterBlocked( $text, $tag );        }                      # unless        # @scanned filled, start scanning the rest        else {            my @scanned2 = ();    # temporary variable            foreach (@scanned) {                # skip already scanned parts                push ( @scanned2, $_ ), next if ref($_);                # scan only if scalar                push ( @scanned2, &PostFilterBlocked( $_, $tag ) );            }                     # foreach            @scanned = @scanned2;        }    # else    }    # foreach    # replace %TagsFastReplace    foreach my $tag ( keys %TagsFastReplace ) {        # @scanned yet empty, start with $text        unless ( scalar(@scanned) ) {            @scanned = &PostFilterFastReplace( $text, $tag );        }    # unless        # @scanned filled, start scanning the rest        else {            my @scanned2 = ();    # temporary variable            foreach (@scanned) {                # skip already scanned parts                push ( @scanned2, $_ ), next if ref($_);                # scan only if scalar                push ( @scanned2, &PostFilterFastReplace( $_, $tag ) );            }                     # foreach            @scanned = @scanned2;        }    # else    }    # foreach    # prepare finder sub for replacing URIs in Text with HTML-Links    my $uriFinder = URI::Find::Schemeless->new(        sub {            return qq~~              . &HTML::Entities::encode_entities( $_[1] ) . '';        }    );    # replace URIs in Text with HTML-Links    ref($_) or $uriFinder->find( \$_ ) foreach @scanned;    # build string and replace code/perl/...-tags with [\0\0$tag]    # to prevent further parsing    my $string = join (        "",        map {            ref($_)              ? map {                my $r = $_;                $r =~ s/(\[)(.+\])/$1."\0\0".$2/gse;                $r;              } values( %{$_} )              : $_;          } @scanned    );    # replace stuff that might contain other tags (like quote)    foreach my $tag ( keys %TagsLastReplace ) {        $string = &PostFilterLastReplace( $string, $tag );    }    # foreach    $string =~ s/\0\0//g;    # remove \0\0 (from [\0\0$tag])    print "\n\n", $string; }    # ParseText # ------------------------------------------------------------ sub PostFilterBlocked {    my ( $text, $tag ) = @_;    my $startLength = length("[$tag]");    my $endLength   = length("[/$tag]");    my @scanned = ();    my $startPos = index( $text, "[$tag]" );    my $lastPos  = 0;    print "\nScanning for tag [$tag]";    while ( $startPos != -1 ) {        print " $startPos";        # add leading part to @scanned        my $string = substr( $text, $lastPos, $startPos - $lastPos );        push ( @scanned, $string ) if length $string;        # check if [$tag]...[/$tag]-block found        $lastPos = index( $text, "[/$tag]", $startPos + $startLength );        print "-$lastPos";        unless ( $lastPos == -1 ) {    # if found            # push reference to @scanned: { $tag => $string }            my $string = substr(                $text,                $startPos + $startLength,                $lastPos - $startPos - $startLength            );            $string =~ s/^\r?\n//g;            $string =~ s/\r?\n$//g;            # replace tags with replacement            $string =              $TagsBlocked{ lc($tag) }->{ -start }              . $TagsBlocked{ lc($tag) }->{ -string }->($string)              . $TagsBlocked{ lc($tag) }->{ -end };            # add to queue as reference            push ( @scanned, { $tag => $string } ) unless $string =~ /^\s*$/;        }    # if        else {    # if not found            # push rest of $text to @scanned (as string)            my $string = substr( $text, $startPos, length($text) - $startPos );            # if last line was in @TagsBlocked, add new array element            if ( ref $scanned[-1] ) {                push ( @scanned, $string ) if length $string;            }            # if not, append as text to the last element            else {                $scanned[-1] .= $string;            }    # else            last;    # and exit while        }    # else        # (re-)initialize next search position        $lastPos += $endLength;        # search for next [tag]        $startPos = index( $text, "[$tag]", $lastPos );    }    # while    # care for rest of $text    if ( $lastPos != -1 ) {        my $string = substr( $text, $lastPos, length($text) - $lastPos );        push ( @scanned, $string ) if length($string);    }    # if    return @scanned; }    # PostFilterBlocked # ------------------------------------------------------------ sub PostFilterFastReplace {    my ( $text, $tag ) = @_;    print "\nScanning for tag [$tag]";    my $startLength = length("[$tag]");    my $endLength   = length("[/$tag]");    my @scanned = ();    while (        $text =~ s/    \[\Q$tag\E\]    (.+?)    \[\/\Q$tag\E\]    /    $TagsFastReplace{lc($tag)}->{-start} .    $TagsFastReplace{lc($tag)}->{-string}->($1) .    $TagsFastReplace{lc($tag)}->{-end}    /xseig      )    {        1;    }    # while    return $text; }    # PostFilterFastReplace # ------------------------------------------------------------ sub PostFilterLastReplace {    my ( $string, $tag ) = @_;    print "\nScanning for tag [$tag]";    my $startLength = length("[$tag]");    my $endLength   = length("[/$tag]");    1 while $string =~ s! $RE{balanced}{-begin => "[$tag]"}{-end => "[/$tag]"}{-keep}    ! $TagsLastReplace{lc($tag)}->{-start} . $TagsLastReplace{lc($tag)}->{-string}-> (substr ($1, $startLength, -$endLength) ) . $TagsLastReplace{lc($tag)}->{-end};    !gex;    return ($string); }    # PostFilterLastReplace # ------------------------------------------------------------ sub HighlightPerlCode {    my $code = shift;    use Perl::Tidy;    my @dest;    perltidy(        source      => \$code,        destination => \@dest,        #      argv => '-html',    );    return join ( "", @dest ); }    # HighlightPerlCode # ------------------------------------------------------------ Hallo Leute, [b]das[/b] ist [i]mein [b]erstes[/i] Posting: [perldoc]CGI[/perldoc] oder so. [perle]#! /usr/bin/perl use warnings; use strict; use CGI (); my $cgi = CGI->new();[/perle] und das[/b] ist was anderes: [perldoc]CGI[/perldoc] [perle]#! /usr/bin/perl use warnings; use strict; use CGI (); my $cgi = CGI->new(); my $string = "[perldoc]CGI[/perldoc]";[/perle] normaltext [quote]error error [quote]Strat, 12.08.2003 14:04 [URL=ftp://ftp.gnu.org/]ftp://ftp.gnu.org/[/URL] ftp.gnu.org Quoting Level 1 [quote] Quoting Level 2 [perle]#! /usr/bin/perl @list = (1..30); foreach (0..$#list) {     print "$list[$_]"; }[/perle] [URL=http://www.fabiani.net/]http://www.fabiani.net/[/URL] [/quote] Quoting Level 1 www.fabiani.net [/quote]