Joseph Brenner

NAME

Emacs::Rep - a find & replace engine for rep.pl and rep.el

SYNOPSIS

  use Emacs::Rep qw( do_finds_and_reps  parse_perl_substitutions );

   my $substitutions =>>'END_S';
      s/jerk/iconoclast/
      s/conniving/shrewd/
      s/(t)asteless/$1alented/i
  END_S

  my $find_replaces_aref =
    parse_perl_substitutions( \$substitutions );

  my $change_metatdata_aref =
        do_finds_and_reps( \$text, $find_replaces_aref );

DESCRIPTION

Emacs::Rep is a module that acts as a back-end for the rep.pl script which in turn is used by the emacs library. rep.el.

Emacs::Rep is a find and replace engine that can perform multiple perl substitution commands (e.g. s///g) on a given file, recording all metadata about each change so that an an external program (such as emacs) can interactively display and control the changes.

The end user isn't expected to need to use these routines directly.

An application programmer might use these routines to add support to an interactive front-end (Emacs or otherwise).

EXPORT

None by default. Any of the following may be requested (or all with the ':all' tag).

parse_perl_substitutions

Breaks down a set of perl substitution command (i.e. "s///;", "s{}{};", etc.) into it's main components (the find pattern and the replace expression). It returns this in an an array of arrays data structure (which is the form used by do_finds_and_args).

Takes one argument, a scalar reference to a block of text containing one or more perl substitution commands, in any form (PPI is used internally to parse this).

The more elaborate "s{}{}xmsg;" is fine, as well as "s///g;".

End of line comments (after the closing semicolon) beginning with a "#", are allowed, as are embedded comments inside the find pattern if the /x modifier is in use.

Example usage:

my $substitutions =>>'END_S'; s/pointy-haired boss/esteemed leader/g; s/death spiral/minor adjustment/g; END_S

my $find_replaces_aref = parse_perl_substitutions( \$substitutions );

Where the returned data should look like:

   [ ['pointy-haired boss', 'esteemed leader'],
     ['death spiral',       'minor adjustment'],
   ]

Any trailing modifiers are automatically prefixed to the find_pattern, using the (? ... ) notation, *except* for /g and /e.

For purposes of do_finds_and_reps /e is always ignored (as of this writing), and /g is always assumed, irrespective of whether it was added explicitly.

accumulate_find_reps

For internal use. Example usage:

 accumulate_find_reps( \@find_reps, $find, $rep, $raw_mods );
do_finds_and_reps

Does a series of finds and replaces on some text and returns the beginning and end points of each of the modfied regions, along with some other information about the matches.

Takes two arguments:

(1) The text to be modified, usually as a reference, though a scalar is okay (2) A series of find and replace pairs in the form of an aref of arefs, e.g.

  $find_replaces_aref =
   [ ['jerk',            'iconoclast'],
     ['conniving',       'shrewd'].
     ['(?i)(t)asteless', '$1alented'].
   ]:

(See parse_perl_substitutions.)

Example usage:

$locations_aref = do_finds_and_reps( \$text, $find_replaces_aref );

The returned change metadata is an aref of arefs of hrefs; an array of passes with an entry for each substitution pair, an an array of changes made by each pass. The href has keys: 'beg', 'delta', 'orig', 'rep'.

The fields 'orig' and 'rep' contain the modified string, before and after the change.

'delta' is the change in length due to the change.

'beg' is the beginning of the region that was modified, an integer counting from the start of the file, where the first character is 1.

This numbering does not change while a s///g is in progress, even if it is changing the length of the strings. And further, these change locations are recorded *during* each pass, which means that later passes throw off the numbering.

In practice, for the rep.el application, we apply this data on the emacs side in inverse order, so that the numbering is correct in the context we use it.

Note, error messages are routed to stdout, labeled with the prefix "Problem:". The elisp call shell-command-to-string merges stdout and stderr, but we use the 'Problem' prefix to spot error messages

check_versions

Verify that all three pieces of the system have the same version: the *.pl, *.pm and *.el.

The elisp code is expected to run this command string with it's own version number:

   perl rep.pl --check_versions="0.08"

rep.pl then runs this check_versions routine, passing along the elisp version and the rep.pl version number:

Example usage:

  check_versions( $elisp_version, $script_version );

This compares those two versions with the module's version, and warns if they're not all the same.

SEE ALSO

The web page for this project is:

  http://obsidianrook.com/rep

The code is available on github (as well as on CPAN):

  http://github.com/doomvox/rep

Emacs::Rep is the back-end for the script rep.pl which in turn is the back-end for the emacs lisp code rep.el.

If rep.el is not installed, look in the "elisp" sub-directory of this CPAN package.

A good discussion forum for projects such as this is:

  http://groups.google.com/group/emacs-perl-intersection

AUTHOR

Joseph Brenner, <doom@kzsu.stanford.edu>

COPYRIGHT AND LICENSE

Copyright (C) 2010,2012 by Joseph Brenner

This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.

See http://dev.perl.org/licenses/ for more information.

BUGS

None reported... yet.