Nyes, even more slithering Perl Horrors for you to use!

I'll put a few helpful Perl (and elisp) scripts here. These are not really long enough to be noded separately...

Take and use these as you see fit. Just don't blame me if they don't work. =)

e2-filter.el

This will filter text files in Emacs/XEmacs so that they'll look more or less interesting when copied/pasted. (I used it to filter these scripts, for example... =)

What this does?... it translates & to &amp;, translates square brackets to &#91; and &#93;, and < and > to &lt; and &gt;.

Has been tested in XEmacs 21.4.something and above. I have no idea how it works in other Emacs versions.

To use this, put (load "~/path/to/file/e2-filter") to your ~/.emacs or ~/.xemacs/init.el file.


;;; Filters the region for potentially annoying stuff...
;;; By Weyfour WWWWolf, 2000-10-20
;;;
;;; $Id: e2-filter.el,v 1.0.1.1 2000/10/20 18:06:35 wwwwolf Exp wwwwolf $
;;;
;;; Distributed under the Artistic Lisence.

; Taken mostly from documentation...
(defun glob-replace (from to)
  "Globally replaces string `from' to `to'."
  (goto-char 0)
  (while (search-forward from nil t)
    (replace-match to nil t)))

(defun e2-escape-region (min max)
  "HTML-escapes the current region, also replacing square brackets with
   &#91; and &#93;. Mostly aimed at Everything2.com users."
  (interactive "r")
  (buffer-disable-undo)
  (narrow-to-region min max)
  (glob-replace "&" "&amp;")
  (glob-replace "[" "&#91;")
  (glob-replace "]" "&#93;")
  (glob-replace "<" "&lt;")
  (glob-replace ">" "&gt;")
  (widen)
  (buffer-enable-undo)
  (message "Done."))

fake-e2-linker.pl

This generates a HTML for previewing purposes. See that sumbit sinking feeling for philosophical background. This script is probably better than the Python script featured there. =)

It's called "fake" linker because the first version didn't link the links anywhere, but it did produce the <A> tags.

Usage: perl fake-e2-linker.pl yournode.txt > nodepreview.html

Variations of theme:

  • that sumbit sinking feeling (Python script that does the same)
  • E2 Offline Scratchpad (Windows app. Not that I have anything against it, but let's compare it a little: Do you want a huge bells-and-whistles noding environment, or a little tool that integrates well with others? For bells and whistles, go for E2OS. For a nice little tool, try my script.)


#!/usr/bin/perl -w
############################################################################
#
# Fake E2 linker
# Useful for "previewing" stuff "offline" before posting.
#
# Written by Weyfour WWWWolf / Urpo Lankinen
# Use as you see fit, no warranty.
#
# $Id: fake-e2-linker.pl,v 1.5 2001/05/05 23:29:58 wwwwolf Exp wwwwolf $
#
############################################################################
#
# Updated 2000-08-20 - Noether mentioned some Python crap that
#   was apparently cooler than this (See "that sumbit sinking
#   feeling"). Punished with extreme cruelty.
# Updated 2001-05-06 - Uses some More Interesting Perl Idioms now,
#   like proper looping, commented regular expressions,
#   and "s" modifier of regex instead of concatenation - so now
#   <pre>...</pre> elements will no longer break and other weird
#   things should not happen... as often! =) This ought to be
#   easier to understand for the newbies, too.
#
############################################################################

use strict; # Jawohl, Herr Obersturmf├╝hrer!
use URI;    # Doesn't come with Perl, but everyone should have it anyway =)

# Print HTML header
print "<!doctype html public \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n",
  "<html>\n<head>\n<title>Cheesy node preview</title>",
  "\n</head>\n<body>\n<h1>Node preview</h1>\n\n<hr>\n";

# Join everything from input files. (All lines have "\n" in the end...)
# I know, I know, memory/efficiency requirements.
$_ = join "", <>;

# Loop as long as there are linked words.
while(1) {
  if(m{
       \[               # Starting bracket
       ([^\|\]]*\|)?    # Possibly the pipelink part (To $1)
       ([^\]]*)         # Link text                  (To $2)
       \]               # Ending bracket
      }sx) {

    my $match = $&;     # Whole matched expression (to be replaced later)
    my $dest = $1 || "";
    my $linkword = $2;

    $dest =~ s/\|$//;  # Remove the oft-abused idiom
    $dest =~ s/\s+/ /; # Keep whitespace in order

    # Link is either pipelink or link word destination in E2...
    my $link =
      URI->new('http://www.everything2.com/?node=' .
	       ($dest ? $dest : $linkword))->canonical->as_string;

    # We do quoting so that our pattern match will work a bit better...
    $match = quotemeta($match);

    # Replace our previously matched text with the link...
    s!$match!<a href="$link">$linkword</a>!gi;

  } else {
    # We no longer have anything that matches, so let's exit the loop.
    last;
  }
}
# Print out the new and improved file.
print;

# Print out the HTML footer.
print "<hr>\n<p>Spewed forth by fake-e2-linker.pl by WWWWolf\n",
       "</body>\n</html>\n";



More Slithering Perl Horrors!

My shots for same issue... these programs are my first, second and third actual perl scripts (not counting test-programs, of course), respectively.

As for the more minor ones:


autolinker.pl

This thing is nodevertizer's best friend. Um, well, at least an acquaintance. Give it your node's node_id as parameter and feed its body into stdin (ie. ./autolinker.pl 1234567, and, cut-and-paste), and after a while you should see a nice bunch of soft links on your node (and, more importantly, on the nodes you hardlinked to).

*BZZT* I was informed of E2 node autolinker in perl. Somehow I'm not surprised I'm not the first one think of that, but still, I didn't know it was done. I must say that my code is certainly much shorter, with less bloat, but more on user. I think I'll leave it here as slim alternative. BTW, I really think someone should make E2 perl scripts metanode. And no, don't think it's as easy as it sounds... "*.pl" isn't searchable currently :( that makes it one hell of a job to find all the perl thingies by crawling through softlinks.

#!/usr/bin/perl -w

use Socket;

$node_id=shift(@ARGV);

while (<>) {
    $urf=$_;
    while ($urf =~ /\[(.*?)(?:\|.*?)?\]/) {
        $next=$';
        $hop=$1;
        $hop =~ s/ /+/g;
        $hop =~ s/([^A-Za-z+])/"%".sprintf("%02X",ord($1))/ge;
        push @node_list,$hop;
        $urf=$next;
    }
}

for $i (0 .. $#node_list) {
    $request=
"GET /?node=$node_list[$i]&lastnode_id=$node_id HTTP/1.0\r\n\r\n";
    
    consock(HTTP,"everything2.com",80)
        || die "can't connect to server!";
    hotfh(HTTP);

#    print $request;
    print HTTP $request;
    <HTTP>;               # this should make me sleep until something comes out
#    while (<HTTP>) { }
#    <HTTP> =~ /<HTTP>/m;
    close(HTTP);
    print "$i/$#node_list\n";
}

sub hotfh {
    my $ofh;
    $ofh = select $_[0];
    $|++;
    select $ofh;
}

sub consock {
# SYNTAX: consock(filehandle, address, port)
    my ($remote, $port, $iaddr, $paddr, $proto, $fh, $sval);
    $fh = $_[0];
    $remote = $_[1];
    $port = $_[2];
    if (!($iaddr = inet_aton($remote))) {
        return;
    }
    $paddr = sockaddr_in($port, $iaddr);
    $proto = getprotobyname('tcp');
    socket($fh, PF_INET, SOCK_STREAM, $proto);
    $sval = connect($fh, $paddr);
    return $sval;
}

E2ify_source.pl

This thing does the same thing countless other scripties, escapes the [ ] < and >, but it also leaves comments unescaped ! Whoa! Innovantion! ... It also collapses tabs.

#!/usr/bin/perl -w

## (perl )?source E2ifier, written in, of course, perl! ;)
## feed perl source in stdin, it will puke E2-ready text to output.
## actually, what makes this anything but your basic E2 escaper is
## that it ignores "literal" comment fields (##), so link off.
## oh, that and of course that it collapses tab-indented code; tab is
## fine for my terminal (especially since it's resizable), but too
## wide for E2.

$tabreplace="    ";

print "<pre>";
while (<STDIN>) {
    if (!/^\s*##/) {
        s/&/&amp;/g;
        s/\[/&#91;/g;
        s/\]/&#93;/g;
        s/</&lt;/g;
        s/>/&gt;/g;
    }
    while (s/^((?:\s*#)?(?:$tabreplace)*)\t/$1$tabreplace/g) { }
    print $_;
}
print "</pre>\n";
If you have procmail and perl installed on your system, this perl script will process the spam from everything@blockstackers.com into a html table, at least the top 25 cooled by rep section, which is my favorite...

First, add the following to your .procmailrc file (after editing the '/www/minitrue/data' to be an output path relevant on your system of course):

:0c:
* ^From:.*everything@blockstackers.com
| ParseE2DR.pl > /www/minitrue/data/table_DailyTopE2.html; 
  chmod o+r /www/minitrue/data/table_DailyTopE2.html

:0:
* ^From:.*everything@blockstackers.com
in-e2

This will process emails from everything with the script ParseE2DR.pl (which will be given shortly), and will send a copy of the email to the mailbox 'in-e2'. On a redhat 7 linux system, this mailbox will be created if it does not exist. You may want to test to see if this is different on your system!

The contents of ParseE2DR.pl are as follows:

#!/usr/bin/perl -w

# read top25 lines
while(<>) {
    # find the top 25 by rep section
    if(/Top 25 Cool Writeups by Rep<br>/) {
    $InSec="1";
    }

    # if we're parsing, grap the vars
    if($InSec) {
	    if(/<a href=([^>]+)>(.+)<\/a>/) {
	        push(@url, $1);
	        push(@title, $2);
	    } elsif(/written by (.+) and cooled by (.+)/) {
	        push(@auth, $1);
	#         push(@cooler, $2);
        
	    } elsif(/^\*-*\*/) {
	        $InSec="0";
	    }
    }
}

# formatting section -> dump the html output to stdout
print "<!-- Begin output from E2 daily report mail parse -->\n";
print "<table width=\"100%\"><th class=\"ib\">Yesterday's Top 25 in E2</th>\n";
for($i=0; $i<@url; $i++) {
    # alternating css class names on 'td' tags to make formatting easy
    if(($i % 2) == 0) {
    	class="ibalt1";
    } else {
    	$class="ibalt2";
    }

    print "<tr><td class=\"$class\">" +
      "<a href=$url[$i]>$title[$i]</a><br><small>by $auth[$i]</small></td></tr>\n";
}
print "</table>\n";
print "<!-- END output from E2 daily report mail parse -->\n";
-- EOF

This table adds the table header tags and table data tags with class attributes set, so if you're a cascading style sheets fan, it's easy to add a <style> section before the table to format it...

Note: I am in the process of learning perl. Suggestions, comments, anything please /msg me.

E2 Source Code Formatter

This script will reformat your entire node containing source code as long as you've used <pre></pre> and/or <code></code> pairs. This script takes a text file containing an entire node as its input, HTML and all. It won't work if you nest <pre></pre> or <code></code> pairs. It also doesn't handle <code> inside <pre> or vice versa, but unless you're noding about <pre> or <code> none of those should ever happen.

Usage example: ./source.prl node.e2 > node.e2.out

#!/usr/bin/perl
use strict;

my @open  = qw(<pre> <code>);
my @close = qw(</pre> </code>);

open(IN, $ARGV[0]);
my @node = <IN>;
close(IN);

my $node = join('__JOIN__STRING__', @node);
for my $i (0..1) {
    $node =~ s/($open[$i])/__PADDING__STRING__\1/g;
    @node =  split($open[$i], $node);

    for my $j (0..$#node) {
        if($j == 0) {
            push(@node, shift(@node));
        } else {
            my ($left, $right) = split($close[$i], shift(@node));
            $left =~ s/&/&amp;/g;
            $left =~ s/</&lt;/g;
            $left =~ s/>/&gt;/g;
            $left =~ s/\[/&#91;/g;
            $left =~ s/\]/&#93;/g;
            $left =~ s/\t/    /g;
            push(@node, $left . $close[$i] . $right);
        }
    }

    $node =  join($open[$i], @node);
    $node =~ s/__PADDING__STRING__//g;
}

@node = split('__JOIN__STRING__', $node);
print foreach (@node);


E2 Offline Node Preview

For those of us without QBASIC (I don't know when Microsoft quit distibuting it, but my installation of Windows XP Professional doesn't have it), here is a Windows Scripting Host/Perl offline node previewer. If you're looking for a Windows-friendly version of Perl, Active Perl1 is free, and it works well for me. This script currently uses a table width of 600, but that's easy to change (even if you don't know Perl). Just change the 600 in <table width="600"...> to whatever you'd prefer, and you're good to go. If you'd prefer to use a browser other than Internet Explorer (which I preview nodes in so it doesn't interfere with browsing with Mozilla Firefox), it's a one line change in the second to last line. Just replace iexplore with your favorite browser's executable.

Usage example: cscript node_preview.wsf node.txt

<Job ID="Offline_Node_Preview">
<script language=PerlScript>
# File name: node_preview.wsf
# Usage: cscript node_preview.wsf <file>

open(IN,$WScript->Arguments(0)) or die "Couldn't open input\n";
open(OUT,'>C:\\tempNode.html') or die "Couldn't open output\n";

print OUT<<'HEADER';
<html>
<head>
<style type="text/css">
body, p, td, li {font: normal normal normal 10pt Arial;}
a {color: #003366;}
</style>
<title>Offline Node Preview</title>
</head>
<body>
<table width="600" border="1" cellpadding="5">
<tr>
<td>
HEADER

@node = <IN>;
$node = join('__JOIN__STRING__', @node);
@node = split(/\[/, $node);
for $i (0..$#node) {
    unless($i == 0) {
        ($link, $rest) = split(/\]/, $node[$i]);
        $link =~ /(.+)/ unless($link =~ /(.+)\|(.+)/);
        $link  = '<a href="http://www.everything2.org/?node=';
        $link .= $1;
        $link .= '">';
        $link .= $1 unless(($2 ne '') and ($link .= $2));
        $link .= '</a>';
        $node[$i] = $link . $rest;
    }
}
$node = join('', @node);
@node = split('__JOIN__STRING__', $node);
print OUT foreach (@node);

print OUT<<'FOOTER';
</td>
</tr>
</table>
</body>
</html>
FOOTER

close(OUT);
close(IN);

$WshShell = $WScript->CreateObject('WScript.Shell');
$WshShell->Run('iexplore C:\\tempNode.html', 1, true);
system('del C:\\tempNode.html');
</script>
</Job>

1 - Active Perl is available for download at http://www.activestate.com/Products/ActivePerl/

Log in or registerto write something here or to contact authors.