Larry Moore, said in Re: [MacPerl-Scribes] "Basic Perl Filters in BBEdit" Column at Apr/20/2000, Thu 06:52:34. > Minutes of "Basic Perl Filters in BBEdit" Column as/at 10 April [snip] Okay, I'm more or less back. Things did not go well yesterday, and I'm more or less in the same position regarding the status of my Mac, albeit with a slightly faster modem in place. Although I applaud Larry's efforts, His HTML is questionable. He's also missing the comments I got from Jim Corriea yesterday off list (happened too late last night to bother posting it here). So, here's what I've got NOW, and believe me some of whats been said, has helped. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> <html> <head> <title>Perl Filters in BBEdit</title> <meta name="generator" content="BBEdit 5.1.1"> </head> <body bgcolor="#ffffff"> <h2>Basic Perl Filters in BBEdit</h2> <p> Back in issue #7, Vicki Brown wrote about her "<a href="http://www.perlmonth.com/columns/mac_perl/mac_perl.html?issue=7">MacPe rl Development Environment</a>". For the most part, what she describes there is a typical setup for a serious MacPerler. In her article Vicki covered, among other things, BBEdit, from <a href="http://www.barebones.com/">Bare Bones Software</a>. As of version 5.1, BBEdit has MacPerl support built in. Older versions used a plug-in module for roughly the same functionality. However having built-in support means MORE than just the ability to use BBEdit as a text-editor and front end for MacPerl. </p> <p> BBEdit allows you to create "Perl Filters": scripts to which a text selection, or even an entire document may be passed, which then return their results to BBEdit. BBEdit isn't the only Mac text-editor with built-in Perl support, and neither is it the only such editor which lets you use Perl scripts as text filters. <a href="http://alpha.olm.net/">Alpha</a> has similar functionality and a very vocal following. I'm hoping to corral one of those vocal followers into writing a column on the subject. </p> <p> I spoke (via email) with Jim Correia, Senior Software Engineer at Bare Bones Software. Although perl filters weren't his idea (credit rightly goes to Brad Hanson for that), he did do a complete rewrite of the code for BBEdit 5.1. It's safe to say that Jim's intimately familiar with the code. I asked Jim to describe what a Perl Filter does: </p> <blockquote> A perl filter is a perl program that transforms the selection in an active BBEdit window. The program takes input as a file path on the command line, and writes its output to STDOUT. If we were on a unix-like operating system, the program might be invoked liked this </blockquote> <blockquote> <code>perl filter.plx /usr/tmp/bbedit_selection.txt</code> </blockquote> <blockquote> On the Macintosh, there isn't a command line. Instead BBEdit writes out the selection to a temporary file called [DocumentName].§ then sends an apple event to the MacPerl application giving it the program to execute, the command line parameters (the data file) and sets up some flags telling MacPerl it should return STDOUT and STDERR in the apple event reply. BBEdit replaces the selection in the active window with the contents of STDOUT. </blockquote> <blockquote> So for instance, if I had a window opened called "Testing Perl Filters" and ran the following perl filter: </blockquote> <blockquote> <pre> #!perl -w use strict; print "$ARGV[0]\n"; </pre> </blockquote> <blockquote> the selection would be replaced with </blockquote> <blockquote> <pre> Boot:Temporary Items:Testing Perl Filters.§ </pre> </blockquote> <blockquote> More interesting is when we actually have some useful transformation we want to perform on the data. One such example would be sorting the lines in a data file: </blockquote> <blockquote> <pre> #!perl -w use strict; my @lines = <>; @lines = sort @lines; foreach(@lines){ print; } </pre> </blockquote> <blockquote> You can use all of the command line flags in a perl filter that MacPerl would normally understand. Taking advantage of this, a filter which reverses all of the characters in each line becomes the canonical perl one liner: </blockquote> <blockquote> <pre> #!perl -wpl $_ = reverse; </pre> </blockquote> <h3>An Example One-Line Filter</h3> <p> For the most part, Perl Filters tend to be short (one or two line) scripts, which do various regular expression functions not possible with BBEdit's own regex capability. Frequently, you need to make multiple passes over a document, or parse it in a way which isn't possible with regex alone, like so: </p> <pre> #!perl -p s/(\d+)-(\d+)/$1 > $2 ? "$1-$2" : join ', ', $1 .. $2/ge </pre> <p> Alas, I'm not the author of this gem. This came about as the result of one of the frequent filter-generation sessions on the BBEdit-Talk[<a href="#talk-list">1</a>] list. On a Friday, someone blithely asked for a script which could parse a certain set of strictly formatted strings of numbers. The problem was first approached using a rather convoluted AppleScript, which even the author concluded was ugly. Next, a Perler tried his hand. Finally, Ronald Kimball stepped in, reducing the Perl script to its most idiomatically concise form. Ron claims the result is again "ugly", but the original poster referred to it as "inspirational". </p> <p> Oh, and what does it do? The answer is <a href="http://search.barebones.com/action.lasso?-database=lists.fp3&- layout=import&-response=%2ftalk%5flists%2fdetail.html&-recid=47440&- search">here</a>. </p> <h3>Filters using Perl Modules</h3> <p> Are you lazy? You just don't want to open your mail client to post mail? You'd rather stay in your text-editor? Well, so did Rory Campbell-Lange: </p> <pre> #!perl -w # campbell-lange@easynet.co.uk (Rory Campbell-Lange) # only barely modified from the example in # the Mail::Send POD require Mail::Send; @allmail = <>; $to = shift @allmail; chomp $to; $subject = shift @allmail; chomp $subject; $msg = new Mail::Send; $msg->to($to); $msg->subject($subject); $fh = $msg->open; print $fh "@allmail"; $fh->close; </pre> <p> Oh, but that doesn't handle MIME attachments you say? </p> <pre> #!perl -w # campbell-lange@easynet.co.uk (Rory Campbell-Lange) # only barely modified from the example in # the MIME::Lite POD use MIME::Lite; MIME::Lite->send('smtp', "mymail.example.org", Timeout=>200); my $to = shift; my $sub = shift; my $filetoattach = shift; my $filename = shift; my @message = @_; $msg = new MIME::Lite From =>'me@mymail.co.uk', To => $to, #Cc => couldbeshift, Subject => $sub, Type =>'TEXT', Data => @message, attach $msg Type =>'image/gif', Path => $filetoattch, Encoding => 'base64', Filename => $filename; $msg->send; </pre> <p> A sufficiently intrepid programmer could easily use this as the starting point for a complete mail client, written as a BBEdit Perl Filter! </p> <h3>Filters with No Input</h3> <p> Nothing says that a "filter" has to take an input to produce an output. This example creates a timestamp: </p> <pre> #!perl my ( $year, $month, $day, $hour, $min, $sec) = reverse((localtime)[0 .. 5]); printf('%04d:%02d:%02d %02d:%02d:%02d',$year+1900,$month+1,$day,$hour,$min,$sec); </pre> <p> I've done other scripts which do more complex things, such as generating an XML file, then parsing it to create HTML[<a href="#mother-of-perl">2</a>]. However, I'm saving the really tricky Perl Filters for Chris Nandor. </p> <p> Finally, a word about switches. I've seen more than my share of Perl Filters, and a lot of evidence that MacPerler's in general are unaware of which #! switches work under MacPerl, and when and how to use them. This is really a topic for an entirely separate column, but I'll try to deal with it briefly here. Most switches work with MacPerl. Of those which might be considered most useful in the context of Perl Filters: </p> <pre> -n (iterate entire script using <>) works as expected -p (iterate entire script using <> printing each line) works as expected -l (automatically chomp line endings from input -- with -n or -p no terminating \n needed on output) works as expected -e (execute following string as command-line) generates error message -- not emulated. Works only under MPW Perl. -0 (sets $\ in octal) works as expected </pre> <p> Although in this context, I can't imagine you doing such a thing, I feel the need to point out that: </p> <p> -u (does core dump) Believe me, you don't want to use "-u" on a Macintosh. </p> <h3>Next Issue</3> <h3>References/Footnotes</h3> <p> <a name="talk-list">1) BBEdit-Talk Mailing List:</a> <<a href="mailto:bbedit-talk@barebones.com">bbedit-talk@barebones.com</a>> To subscribe, visit the Bare Bones Software Web site. </p> <p> <a name="mother-of-perl">2) Mother of Perl</a> <a href="http://webreference.com/perl/scripts/">http://webreference.com/perl/sc ripts/</a>, which is actually <b>rewritten</b> there as a BBEdit Include file. Most of the code is Jonathan Eisenzopf's not mine, I merely had to figure out new ways of passing data to it. </p> </body> </html> ==== Want to unsubscribe from this list? ==== Send mail with body "unsubscribe" to macperl-scribes-request@macperl.org