Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked

PM Code Tidier/Highlighter

by juster (Friar)
on Oct 25, 2008 at 21:39 UTC ( #719563=monkdiscuss: print w/replies, xml ) Need Help??

I have made a user script for Greasemonkey in Firefox. This userscript in turn passes data to a perl script on the net to highlight and/or tidy up perl code in code blocks, here on PerlMonks. If you have Greasemonkey installed, click the following link and tell it to install to try it out. PMTidy.user.js

I recently stumbled upon an AJAX syntax highlighter for perl that uses a perl script. The script uses Perl::Tidy to recolor perl code. I thought this was neat and wanted to see if I could make it work here.

I started with Jon Allen's scripts until after a few days I have this! The script creates links next to download beneath the code that let you highlight or tidy up the code. There are some kinks/bugs, though:

  • When you click a link, you scroll up to the top of the code block. It's a bit jerky but otherwise you could end up looking anywhere nearby.
  • Since the links go to an anchor created around the code, it creates another entry in your history (you have to click Back more times).
  • Perl::Tidy craps out on the crazier obfuscations, and won't display the highlight or tidy links.
  • Word wrapping does not work perfectly, long strings are not wrapped. This I can probably fix later.
  • You can't tidy code blocks in readmore tags because the markup is different and I didn't anticipate this. (update: guess I was wrong)
  • The userscript inserts a pre block around the code because I couldn't get indentation working properly with &nbsp

I also transfered my domain name to a new host today so you might get the old IP number once and awhile. Hopefully that won't last long.

There are two configuration options you can change by editing the Greasemonkey script. When you Manage Users Scripts there is an Edit button to open your editor. One is the url of the perl script to call and the other is a wordwrap setting (that works poorly).

I also found a node via Super Search that talks about syntax highlighting and has alternatives. I was already halfway done with this when I found it though.

The perl script the Greasemonkey script calls to tidy up is on my web hosting account and the source code is the following:

#!/usr/local/bin/perl -w use strict; use warnings; use CGI qw/:standard/; use Perl::Tidy; use HTML::Entities; use XML::Simple; our $VERSION = '0.01'; use constant { UNPERLMSG => 'How very unperlish of you!', # ERRLOGFILE => 'pmtidyerr.log', }; my $cgi = new CGI; my $code = $cgi->param('code'); my $wordwrap = $cgi->param('wordwrap'); eval { die 'No code given' unless(defined $code); $wordwrap = 80 unless(defined $wordwrap); $code =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg; # from URI::Encode decode_entities($code); $code =~ s/\xA0/ /g; # wtf! &nbsp=this+spac +e? # Removes rampant <br> tags $code =~ s|<br(?:\s+/)?>||g; # put the perltidy.ERR file in /tmp chdir('/tmp') or die "could not chdir to /tmp: $!"; # We return two versions, both are converted to html and colorized # But one is also tidied up (reformatted) first. my $errors; my $tidied; # The stderr option to perltidy does not seem to do anything!. # So we force it muahaha! Take that! open my $tmpstderr, '>', \$errors or die "open for temp STDERR: $!"; my $oldstderr = *STDERR; *STDERR = $tmpstderr; perltidy( source => \$code, destination => \$tidied ); *STDERR = $oldstderr; close $tmpstderr; if( $errors ) { print $cgi->header; print UNPERLMSG; exit 0; } # I'm thinking errors won't happen with perltidy below if they # did not above... # BUG: wordwrap option doesn't work for long string, need to manuall +y # fix that my $tidyargs = "-html -pre -l=$wordwrap"; my $result; perltidy( source => \$code, destination => \$result, argv => $tidyargs ); $code = $result; perltidy( source => \$tidied, destination => \$result, argv => $tidyargs ); $tidied = $result; # Removes the anchors that are created since we wont use them. $code =~ s|</?a.*?>||g; # Remove the <pre> tags and use <br>'s again like perlmonks does (*b +arf*) # BUG: I can't get this to indent at beginning of line properly. # So I'm just leaving the pre tags, so much easier! # $code =~ s|</?pre>\n||mg; # $tidied =~ s|</?pre>\n||mg; # $code =~ s|\n|<br />\n|mg; # $tidied =~ s|\n|<br />\n|mg; # $code =~ s|^( +)|length($1)x'&nbsp;'|gem; # $tidied =~ s|^( +)|length($1)x'&nbsp;'|gem; my $html = join "\n", ("<div>", "<div id=\"highlight\">", $code, "</div>", "<div id=\"tidy\">", $tidied, "</div>", "</div>"); print $cgi->header; print $html; }; if($@) { # open my $errlog, '>>', ERRLOGFILE; # print $errlog "$@"; # close $errlog; print $cgi->header(-status => 500); #die "$0: $@"; } exit 0;

Replies are listed 'Best First'.
Re: PM Code Tidier/Highlighter
by ccn (Vicar) on Oct 28, 2008 at 08:03 UTC

    I have Greasemonkey and PMTidy.user.js installed, but it doesn't work for some reason. I don't see any links below [download]

    What should I check to make it works? (FF 3.0.3, Ubuntu 8.04)

      Oops that is entirely my fault. I forgot to test with PM's code wrapping feature turned off. I have fixed this major oversight and many smaller problems.

      New script version is: PMTidy-1.2.user.js.

      Almost all formatting issues are fixed. The one I couldn't figure out is how to get the trailing newline being exactly the same as the original code.

      I was having problems getting Greasemonkey to give me a fresh copy of the script. It seemed to use a cached version and even when I deleted the temporary file and cleared my browser history it still gave me an old version. Maybe I have to dig into the .mozilla directory to find a file in there to delete. An easier solution was to give the script a new file name on the webserver: PMTidy-1.2.user.js (same link as above).

      I also updated the perl script without thinking about the fact that it might screw anyone who might be using the old script. If it does I'm sorry and try the new script.

      Thank you ccn, for trying this and telling me there was a problem. I'm hoping I fixed it. If not please tell me.

      I have created a new version that fixed many problems. Highlighted, wordwrapped code should have identical whitespace now. The user script is now more dynamic and properly handles font tags in the code or around them.

      New version is PMTidy 1.4 (click to install). The cgi script has become much larger so I won't post it but you can view it offsite.

        It's really good now. Thanks, it makes monk life a bit more colourful

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: monkdiscuss [id://719563]
Approved by Old_Gray_Bear
Front-paged by tye
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (5)
As of 2016-12-08 14:54 GMT
Find Nodes?
    Voting Booth?
    On a regular basis, I'm most likely to spy upon:

    Results (142 votes). Check out past polls.