http://www.perlmonks.org?node_id=665657

Here's a utility I built that is probably the most under-appreciated and widely used custom tool I have. I call it stringilizer. I initially built it to "stringilize" stanza-like SQL statements into nice double-quoted, vbcrlf, line-broken ASP strings, and it has since been used for about everything else you can possibly imagine.

It has two text areas, one for pasting text from somewhere into, and a second one that contains a little snippet of Perl code that manipulates the lines of text in the first text area. Click the "stringilize" button, and the code in the snippet area gets eval'd.

Here's a picture

I recently added something I should have a long time ago, the ability to tag code snippets and save them for later use. Now, if I want to transform a list of strings into a static C# string array, I simply select "csharp no dupe string array" and click "stringilize".

I can't say I'm a very experienced Perl::Tk developer, so there are probably some better ways to do things than I've done. However, for a little utility that has saved me hours of frustration in exchange for almost perpetual neglect, I'm pretty happy with it.

I've included the code below, but you can also download stringilizer at

http://www.arbingersys.com/concerns.html

There's a zip archive at that address that contains a clickable .bat file and a few snippets in the snippet folder. Plus, the code is a little easier on the eyes, since it has vertical white space and comments.

Update: I've added a clipilize button to the application, per the suggestions below. This automatically grabs what's in the clipboard, applies your code to it, and places it back into the clipboard with a single button press. Quite a step saver. It also inserts the text into the 'subject' area so you can look at it.

use Tk; use Tk::BrowseEntry; use Tk::Dialog; my $note = "This is the 'Subject' area. Usually, you will paste something in here. Below is some code that fires when you click the 'stringilize' button. It modifies the text in this area. Change it to whatever you like. Errors in your code (if there are any), will be inserted here. "; my $def_code =<<EOC; my \@subject_lines = split(/\\n/, \$subject_text->get('1.0','end') ); for (\@subject_lines) { # Do something, e.g. # tr/a-z/A-Z/; } \$subject_text->delete('1.0', 'end'); \$subject_text->insert( 'end', join("\\n", \@subject_lines) ); EOC my $snippets_dir = 'snippets'; my $mainw = MainWindow->new(-title=>'Stringilizer'); my $tags; my $dia = $mainw->Dialog( -title =>'Tag snippet', -default_button=>'Save' ); $dia->add( 'LabEntry', -textvariable=>\$tags, -label=>'Enter tags to save snippet' )-> pack(-side => 'left')-> configure(-relief=>'groove'); $dia->protocol("WM_DELETE_WINDOW" => sub {} ); my $frame1 = $mainw->Frame->pack( -side => 'top', -fill => 'x' ); $frame1->Button( -text => "exit", -command => sub { $mainw->destroy; } )-> pack(-side => 'left')-> configure(-relief=>'groove'); $frame1->Button(-text => "stringilize", -command => \&stringilize_exec )-> pack(-side => 'left')-> configure(-relief=>'groove'); $frame1->Button(-text => "save", -command => \&save_snippet )-> pack(-side => 'left')-> configure(-relief=>'groove'); $code_text = $mainw->Scrolled("Text")-> pack(-side => 'bottom', -fill => 'both', -expand => 1); $subject_text = $mainw->Scrolled("Text")-> pack(-side => 'bottom', -fill => 'both', -expand => 1); $subject_text->configure(-height => 12, -scrollbars=>'se'); $code_text->configure(-height => 18, -scrollbars=>'se'); $subject_text->insert('end', $note); $code_text->insert('end', $def_code); my $snippet; my $be = $frame1->BrowseEntry( -label=>'snippets', -browsecmd=> \&load_snippet, -variable=> \$snippet ); load_snippet_tags(); $be->pack( -side => 'left')->configure( -relief=>'groove'); MainLoop; sub stringilize_exec { # Put the code area text into variable my $code = $code_text->get("1.0", 'end'); eval($code); # Report error if ($@) { $subject_text->insert('1.0', "ERROR: $@\n"); } } sub load_snippet_tags { $be->delete('0', 'end'); if (!-e $snippets_dir and !-d $snippets_dir) { mkdir $snippets_dir; return; } opendir(DIR, $snippets_dir) || die "$!"; my @files = grep { /txt$/i && -f "$snippets_dir\/$_" } readdir(DIR); closedir(DIR); for (@files) { my $f = $_; $f =~ s/\.txt$//; $be->insert('end', $f); } } sub load_snippet { my $file = $snippet . '.txt'; open(F, "$snippets_dir\/$file") or die "$! $snippets_dir\/$file"; my $s; while(<F>){ $s .= $_ } close(F); $code_text->delete('1.0', 'end'); $code_text->insert('end', $s); } sub save_snippet { my $ans = $dia->Show; if ($tags ne '') { $tags =~ s/\s/_/g; $tags =~ s/\W//g; $tags =~ s/_/ /g; open(F, ">$snippets_dir\/$tags\.txt") or die "$!"; print F $code_text->get('1.0','end'); close(F); load_snippet_tags(); undef($tags); } }

Replies are listed 'Best First'.
Re: Perl::Tk app to manipulate pasted text on the fly
by hossman (Prior) on Feb 01, 2008 at 23:03 UTC

    It's been a while since I used it, but something like Clipboard could simplify your UI a lot (no need for the top text box).

      That actually looks useful for another reason. If you close stringilizer before you paste (on Windows at least), you lose all the data you've copied. I suppose you could use Clipboard to put it in the OS clipboard when the text is stringilized. Then if you closed your data would still be accessible.

      I'll definitely check it out. Thanks.

        Well.... yeah. what you described is basically half of what I was suggesting.

        with Clipboard you can get things from the clipboard, and put things into the clipboard. So you could remove the upper textarea from your UI completely, and just have the (lower) textarea for the perl code, and the "eval" button. Users "copy" arbitrary text in any app so that it is in the clipboard, click the "eval" button, and your app can fetch from the clipboard, run the perl code over it, and put it back in the clipboard. no pasting/re-coping required.

        (it would basically be the same as the "clipfilter" script that comes with Clipboard except that instead of executing a single command line app, it would eval code from the textarea)

Re: Perl::Tk app to manipulate pasted text on the fly
by zentara (Archbishop) on Feb 02, 2008 at 14:07 UTC
    Just a tidbit of a thought...... IIRC, the last time I experimented with cut-n-paste sort of things, the most reliable in my testing was the Tk::Text widget. The biggest glitch was when copying, did it automatically get the text into both the mouse-paste-clipboard, as well as the menu paste selection( control-v). See Tk copy to mouse clipboard

    Also I found using Tk in a withdrawn state, gave good results

    #!/usr/bin/perl use warnings; use strict; use Tk; use Tk::Clipboard; my $mw = tkinit; $mw->withdraw; #use Tk without showing a window my $content = 'foobar'.time; print "$content\n"; $mw->clipboardClear; $mw->clipboardAppend($content); MainLoop;

    I'm not really a human, but I play one on earth. Cogito ergo sum a bum
      Thanks for the pointers. I appreciate it.