2   var slice = Array.prototype.slice;
 
   4   function update(array, args) {
 
   5     var arrayLength = array.length, length = args.length;
 
   6     while (length--) array[arrayLength + length] = args[length];
 
  10   function merge(array, args) {
 
  11     array = slice.call(array, 0);
 
  12     return update(array, args);
 
  15   Function.prototype.bind = function(context) {
 
  16     if (arguments.length < 2 && typeof arguments[0] === 'undefined') {
 
  20     var args = slice.call(arguments, 1);
 
  22       var a = merge(args, arguments);
 
  23       return __method.apply(context, a);
 
  30 function ScriptletCenter()
 
  34     this.scriptlets['insert_tag'] = function(context, params)
 
  36         var text = this.XMLEditorSelectedText(context);
 
  37         var start_tag = '<'+params.tag;
 
  38         var move_cursor = false;
 
  40         for (var attr in params.attrs) {
 
  41             start_tag += ' '+attr+'="' + params.attrs[attr] + '"';
 
  45         var end_tag = '</'+params.tag+'>';
 
  51             for(var index=0; index < text.length; index++)
 
  53                 if (text[index].match(/\s/)) { // whitespace
 
  58                     if(output == token) output += start_tag;
 
  60                     output += text[index];
 
  64             if( output[output.length-1] == '\\' ) {
 
  65                 output = output.substr(0, output.length-1) + end_tag + '\\';
 
  72             if(params.nocontent) {
 
  73                 output = "<"+params.tag +" />";
 
  76                 output = start_tag + end_tag;
 
  81         this.XMLEditorReplaceSelectedText(context, output);
 
  85                 this.XMLEditorMoveCursorForward(context, params.tag.length+2);
 
  91     this.scriptlets['lineregexp'] = function(context, params) {
 
  93         var exprs = $.map(params.exprs, function(expr) {
 
  98                 rx: new RegExp(expr[0], opts),
 
 104         var text = this.XMLEditorSelectedText(context);
 
 108         var lines = text.split('\n');
 
 109         lines = $.map(lines, function(line) {
 
 111             $(exprs).each(function() {
 
 113                 line = line.replace(expr.rx, expr.repl);
 
 116             if(old_line != line) changed += 1;
 
 121             this.XMLEditorReplaceSelectedText(context, lines.join('\n') );
 
 125     this.scriptlets['codemirror_fontsize'] = function(context, params) {
 
 126         var frameBody = this.XMLEditorBody(context);
 
 128         if(params.fontSize) {
 
 129             frameBody.css('font-size', params.fontSize);
 
 132             var old_size = parseInt(frameBody.css('font-size'), 10);
 
 133             frameBody.css('font-size', old_size + (params.change || 0) );
 
 138     this.scriptlets['fulltextregexp'] = function(context, params) {
 
 139         var exprs = $.map(params.exprs, function(expr) {
 
 141             if(expr.length > 2) {
 
 145                 rx: new RegExp(expr[0], opts),
 
 150         var text = this.XMLEditorSelectedText(context);
 
 153         $(exprs).each(function() {
 
 154             text = text.replace(this.rx, this.repl);
 
 157         if( original != text) {
 
 158             this.XMLEditorReplaceSelectedText(context, text);
 
 162     this.scriptlets['macro'] = function(context, params) {
 
 165         $(params).each(function() {
 
 166             $.log(this[0], this[1]);
 
 167             self.scriptlets[this[0]](context, this[1]);
 
 171     this.scriptlets['lowercase'] = function(context, params)
 
 173         var text = this.XMLEditorSelectedText(context);
 
 178         var lcase = text.toLowerCase();
 
 179         var ucase = text.toUpperCase();
 
 181         if(lcase == text) repl = ucase; /* was lowercase */
 
 182         else if(ucase != text) repl = lcase; /* neither lower- or upper-case */
 
 183         else { /* upper case -> camel-case */
 
 184             var words = $(lcase.split(/\s/)).map(function() {
 
 185                 if(this.length > 0) { 
 
 186                     return this[0].toUpperCase() + this.slice(1);
 
 191             repl = words.join(' ');
 
 194         if(repl != text) this.XMLEditorReplaceSelectedText(context, repl);
 
 198     this.scriptlets["insert_stanza"] = function(context, params) {
 
 199         var text = this.XMLEditorSelectedText(context);
 
 202             var verses = text.split('\n');
 
 203             text = ''; var buf = ''; var ebuf = '';
 
 206             for(var i=0;  i < verses.length; i++) {
 
 207                 var verse = verses[i].replace(/^\s+/, "").replace(/\s+$/, "");
 
 209                     text += (buf ? buf + '/\n' : '') + ebuf;
 
 210                     buf = (first ? '<strofa>\n' : '') + verses[i];
 
 214                     ebuf += '\n' + verses[i];
 
 217             text = text + buf + '\n</strofa>' + ebuf;
 
 218             this.XMLEditorReplaceSelectedText(context, text);
 
 222             this.XMLEditorMoveCursorForward(context, params.tag.length + 2);
 
 229 ScriptletCenter.prototype.XMLEditorSelectedText = function(panel) {
 
 230     return panel.selection();
 
 233 ScriptletCenter.prototype.XMLEditorReplaceSelectedText = function(panel, replacement)
 
 235     panel.replaceSelection(replacement);
 
 236     // Tell XML view that it's data has changed
 
 237     // panel.contentView.editorDataChanged();
 
 240 ScriptletCenter.prototype.XMLEditorMoveCursorForward = function(panel, n) {
 
 241     var pos = panel.cursorPosition();
 
 242     panel.selectLines(pos.line, pos.character + n);
 
 248     scriptletCenter = new ScriptletCenter();