Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
;; This file: ;; http://angg.twu.net/elisp/eev-peg.el.html ;; http://angg.twu.net/elisp/eev-peg.el ;; (find-angg "elisp/eev-peg.el") ;; Author: Eduardo Ochs <eduardoochs@gmail.com> ;; ;; "Query-replace pairs". ;; ;; (defun q () (interactive) (find-angg "elisp/eev-peg.el")) ;; (find-es "emacs" "rx") ;; (find-elnode "Rx Constructs" "(regexp EXPR)") ;; (find-angg ".emacs" "fooi") ;; (find-eev "eev-compose-hash.el") ;; (find-eev "eev-compose-hash.el" "ee-composes-do") ;; (load (buffer-file-name)) (require 'peg) (defun find-epp-2a (obj &rest pos-spec-list) (find-2a nil `(find-epp ',obj ,@pos-spec-list))) (defun find-eppm-2a (obj &rest pos-spec-list) (find-2a nil `(find-eppm ',obj ,@pos-spec-list))) (defun find-pegtest (str peg) (find-2a nil `(progn (find-estring str) (peg-run peg)))) (defun find-pegtestm (str matcher) (find-2a nil `(progn (find-estring str) (eval matcher)))) ;; This file needs peg.el: ;; ;; (find-epackage-links 'peg "peg" t) ;; (find-epackage 'peg) ;; (code-c-d "peg" "~/.emacs.d/elpa/peg-1.0/") ;; (find-pegfile "") ;; ;; See: ;; ;; (find-pegfile "peg.el") ;; (find-pegfile "peg.el" ";; Parsing Expression Grammars") ;; (find-pegfile "peg.el" ";; Regexp equivalents:") ;; (find-pegfile "peg.el" "(defmacro peg ") ;; (find-pegfile "peg.el" "(defmacro peg " "Return a PEG-matcher") ;; (find-pegfile "peg.el" "(defun peg-run ") ;; (find-pegfile "peg.el" "(defun peg-run " "Parse with PEG-MATCHER") ;; ;; This is a PEX equivalent to the regexp "\n;; *": ;; ;; (and "\n;;" (* " ")) ;; ;; The "and" can sometimes be omitted. Try: ;; ;; (peg-run (peg "\n;;" (* " "))) ;; (peg "\n;;" (* " ")) ;; (find-epp (peg "\n;;" (* " "))) ;; (find-2a nil '(find-epp (peg "\n;;" (* " ")))) ;; (find-epp-2a (peg "\n;;" (* " "))) ;; (find-epp-2a (peg "\n;;" (* " ")) "while") ;; ;; (find-epp-2a (peg (* (range ?a ?d)))) ;; (find-pegtest "abcdef" (peg (* (range ?a ?d)))) ;; ;; ;; `ee-build-replacer' ;; =================== ;; The "replacer" associated to this list of pairs ;; ;; (("a" "AA") ("b" "BB") ("c" "CC")) ;; ;; is a peg matcher that performs a search and replace that replaces ;; each "a" by a "AA", each "b" by a "BB", and each "c" by a "CC". ;; Replacers are easy to write using peg.el, and the replacer ;; associated to the list of pairs above is: ;; ' (with-peg-rules ((r (or (replace "a" "AA") (replace "b" "BB") (replace "c" "CC"))) (rs (* (* (not r) (any)) r))) (peg-run (peg rs))) ;; ;; Try: ;; ;; (setq mypairs '(("a" "AA") ("b" "BB") ("c" "CC"))) ;; (setq myreplacer (ee-build-replacer mypairs)) ;; (find-epp-2a myreplacer) ;; (find-eppm-2a myreplacer) ;; (find-pegtestm "_a__b__c_def" myreplacer) ;; ;; Note that `myreplacer' is a sexp that starts with `with-peg-rules', ;; that is this macro: ;; ;; (find-pegfile "peg.el" "(defmacro with-peg-rules ") ;; ;; and so we need to run it with `(eval myreplacer)', not with ;; `(peg-run myreplacer)'. Try: ;; ;; (find-pegtest "_a__b__c_def" myreplacer) ;; (find-pegtestm "_a__b__c_def" myreplacer) ;; ;; The version with `find-pegtest' aborts with an "invalid function". ;; ;; ATTENTION, IMPORTANT: if you run the sexp below in this buffer ;; ;; (eval myreplacer) ;; ;; it will replace all the "a"s, "b"s and "c"s from the end of the ;; sexp to the end of the buffer to "AA"s, "BB"s, and "CC"s - and you ;; will have to run an "undo" after running it... and this is why this ;; function `ee-replace-pairs' runs `(eval (ee-build-replacer pairs))' ;; after a narrow-to-region and inside a save-restriction. ;; ;; Test: ;; (find-epp (ee-replace-pairs-0 '(("a" "AA") ("b" "BB") ("c" "CC")))) ;; (defun ee-build-replacer (pairs) "Return the replacer associated to the list of pairs PAIRS." (let* ((f (lambda (ab) (cons 'replace ab))) (replaces (mapcar f pairs))) `(with-peg-rules ((r (or ,@replaces)) (rs (* (* (not r) (any)) r))) (peg-run (peg rs))))) (defun ee-replace-pairs (pairs) "Replace all PAIRS in the region." (save-excursion (save-restriction (narrow-to-region (point) (mark)) (goto-char (point-min)) (eval (ee-build-replacer pairs))))) (defun erp-test () (interactive) (ee-replace-pairs '(("a" "AA") ("b" "BB") ("c" "CC")))) ;; Local Variables: ;; coding: utf-8-unix ;; End: