Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

Regex replace your writeups: a free nodelet hack

by ambrus (Abbot)
on Jul 30, 2008 at 00:03 UTC ( #700954=monkdiscuss: print w/replies, xml ) Need Help??

Add the following snippet to your Free nodelet. This will show an input box where you can enter substitution (s///) expressions and a Subst button. If, while editing a writeup, you click on the Subst button, it will perform those substitutions on the writeup text in the input area.

<p> <form> <input type="text" size="15" id="viewer_replaceTextSpec" value="s/\n\n ++/\n&lt;p&gt;/g; s/\&#x5b/&amp;#x5b;/g; s/\&#x5d;/&amp;#x5d;/"> <input type="button" value="Subst" id="viewer_replaceTextButton"> </form> <script type="text/javascript"><!-- function viewer_replaceText() { var spec = document.getElementById("viewer_replaceTextSpec").value +; var parser = /\s*s\s*(\S)((?:[^\\]|\\.)*?)\1((?:[^\\]|\\.)*?)\1(\w +*)\s*;?\s*|(.+)/g ; var parseE = {}; var pairs = []; while (fret = parser.exec(spec)) { if (undefined != fret[5]) { window.alert("Error parsing substitution list, remaining: +" + fret[5]); return; } else { pairs.push([new RegExp(fret[2], fret[4]), fret[3]]); } }; if (!pairs) { window.alert("Warning: no substitution patterns given."); } var textarea = document.getElementsByTagName("textarea")[0]; var text = new String(textarea.value); var nmatches = 0; pairs.forEach(function(pair) { var lh = pair[0]; var rh = pair[1]; text = text.replace(lh, function(whole) { nmatches++; var captures = arguments; var rp = rh.replace( /(\\(?:u\w{1,4}|x\w{1,2}|\d{1,3}|.))| +(\$\&)|\$(\d+)|\$\{(\d+)\}/g, function(rNone, rBs, rWhole, rCapture, +rCapture2) { var t; if (rBs.length) { t = eval('"'+rBs+'"'); } else if (rWhole.length) { t = whole; } else if (rCapture.length) { t = captures[rCapture-0]; +} else if (rCapture2.length) { t = captures[rCapture2-0] +; } if (undefined == t) return ""; return t; }); return rp; }); }) //window.alert(text); textarea.value = text; window.alert("Replaced " + nmatches + " matches."); } var btn = document.getElementById("viewer_replaceTextButton"); var stdEventQueue = window.addEventListener; if (stdEventQueue) { btn.addEventListener("click", function(e) { viewer_replaceText(); +}, false); } else { btn.attachEvent("onclick", function(e) { viewer_replaceText(); }); + } //--> </script>

The input box allows more than one substitution operator separated by semicolons: these are performed one after another. Each substitution needs to have a syntax apparently similar to a perl substitution operator: it starts with s, followed by a delimiter, followed by a regular expression, followed by the same delimiter (nesting delimiters are not supported), followed by a replace expression, followed by the same delimiter, followed by optional sequence of flags. The regex is a javascript regex, which have syntax and semantics very similar to perl regexes: they support non-capturing parenthesis /(?:...) and they are backtracking the way perl regexen are. The replace can contain ordinary characters, backslash escapes (like the four escapes in "\n\\\x28\$"), and the following special variable references which are replaced by captures as in perl: $&; $1, $2 (even multi-digit); ${1}, ${2} The captures that don't match are replaced by an empty string like in perl, but numbers that don't even have a capturing parenthesis in the regex can be replaced by strange things. The supported flags are that of javascript regexen as well: g for repeated match, i for case-insensitive match, m, and some browsers have a fourth as an extension.

The substitution input field is preloaded by an example. You can use this as is, or write new substitutions. Then, when you activate the Subst button besides the field, the substitutions are parsed, performed in place on the first input area on the current html page, and then you get a popup with an error or success message. Typically you would use this on a page where you edit a future writeup (like the comment on page, the preview page, or a section) or an existing writeup of yours, but you may use this on other pages as well. Then, you'd hit preview or submit to finalize the changes.

If you use this freenodelet utility (possibly modified), I'd be glad to be informed whether it works for you or not. (I've done few tests, and those too only in one browser environment.)

Update: thanks for the idea for moritz, bart, and an unnamed monk who posted a node with no paragraph tags that could be mostly fixed by a s/\n\n+/\n<p>/g.

Replies are listed 'Best First'.
Re: Regex replace your writeups: a free nodelet hack
by CountZero (Bishop) on Jul 30, 2008 at 10:00 UTC
    Very nice! It works on my IBM T42 laptop with Windows XP Pro and FireFox 3.0.1 installed.

    A suggestion for a future enhancement: have the regex work only on the selection --if any-- within the input area, otherwise on the whole input area.


    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: monkdiscuss [id://700954]
Approved by ikegami
Front-paged by Corion
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (3)
As of 2021-10-19 10:19 GMT
Find Nodes?
    Voting Booth?
    My first memorable Perl project was:

    Results (76 votes). Check out past polls.