fixes #953: Leave users' whitespace alone. I'm serious!
authorRadek Czajka <radoslaw.czajka@nowoczesnapolska.org.pl>
Fri, 19 Nov 2010 15:18:09 +0000 (16:18 +0100)
committerRadek Czajka <radoslaw.czajka@nowoczesnapolska.org.pl>
Mon, 22 Nov 2010 11:13:23 +0000 (12:13 +0100)
Add padding_{top,bottom} options to insert_{tag,stanza}.
Only pad when inserting tags from toolbar, not on html->wl-xml.

apps/toolbar/fixtures/initial_data.yaml
redakcja/static/js/button_scripts.js
redakcja/static/js/wiki/xslt.js
redakcja/static/xsl/wl2html_client.xsl

index 7ff8e30..137cd48 100644 (file)
@@ -45,7 +45,7 @@
         group: [14, 12]
         label: akapit
         link: ''
-        params: '{"tag": "akap"}'
+        params: '{"padding_top": 1, "padding_bottom": 3, "tag": "akap"}'
         scriptlet: insert_tag
         slug: akapit
         tooltip: wstawia akapit
@@ -56,7 +56,7 @@
         group: [14]
         label: akapit cd.
         link: ''
-        params: '{"tag": "akap_cd"}'
+        params: '{"padding_top": 1, "padding_bottom": 3, "tag": "akap_cd"}'
         scriptlet: insert_tag
         slug: akapit-cd
         tooltip: "ci\u0105g dalszy akapitu po wewn\u0105trzakapitowym wtr\u0105ceniu"
@@ -67,7 +67,7 @@
         group: [14]
         label: akapit dialogowy
         link: ''
-        params: '{"tag": "akap_dialog"}'
+        params: '{"padding_top": 1, "padding_bottom": 3, "tag": "akap_dialog"}'
         scriptlet: insert_tag
         slug: akapit-dialogowy
         tooltip: wstawia akapit dialogowy
@@ -89,7 +89,7 @@
         group: [1]
         label: akt
         link: ''
-        params: '{"tag": "akt"}'
+        params: '{"padding_top": 1, "padding_bottom": 4, "tag": "naglowek_akt"}'
         scriptlet: insert_tag
         slug: akt
         tooltip: ''
         group: [13]
         label: autor
         link: ''
-        params: '{"tag": "autor_utworu"}'
+        params: '{"padding_top": 1, "padding_bottom": 2, "tag": "autor_utworu"}'
         scriptlet: insert_tag
         slug: autor
         tooltip: ''
         group: [1]
         label: "cz\u0119\u015B\u0107/ksi\u0119ga"
         link: ''
-        params: '{"tag": "naglowek_czesc"}'
+        params: '{"padding_top": 1, "padding_bottom": 4, "tag": "naglowek_czesc"}'
         scriptlet: insert_tag
         slug: czesc
         tooltip: ''
         group: [12]
         label: didaskalia
         link: ''
-        params: '{"tag": "didaskalia"}'
+        params: '{"padding_top": 1, "padding_bottom": 2, "tag": "didaskalia"}'
         scriptlet: insert_tag
         slug: didaskalia
         tooltip: ''
         group: [22]
         label: "didaskalia pocz\u0105tkowe"
         link: ''
-        params: '{"tag": "miejsce_czas"}'
+        params: '{"padding_top": 1, "padding_bottom": 3, "tag": "miejsce_czas"}'
         scriptlet: insert_tag
         slug: didaskalia-poczatkowe
         tooltip: "komentarze wprowadzaj\u0105ce przed tekstem dramatu"
         group: [11]
         label: dramat wiersz.
         link: ''
-        params: '{"tag": "dramat_wierszowany_l"}'
+        params: '{"padding_top": 1, "padding_bottom": 4, "tag": "dramat_wierszowany_l"}'
         scriptlet: insert_tag
         slug: dramat-wiersz
         tooltip: ''
         group: [11]
         label: "dramat wiersz./w. \u0142am"
         link: ''
-        params: '{"tag": "dramat_wierszowany_lp"}'
+        params: '{"padding_top": 1, "padding_bottom": 4, "tag": "dramat_wierszowany_lp"}'
         scriptlet: insert_tag
         slug: dramat-wiersz-w-lam
         tooltip: "dramat wierszowany o zw\u0119\u017Conej szeroko\u015Bci \u0142amu"
         group: [11]
         label: "dramat wsp\xF3\u0142czesny"
         link: ''
-        params: '{"tag": "dramat_wspolczesny"}'
+        params: '{"padding_top": 1, "padding_bottom": 4, "tag": "dramat_wspolczesny"}'
         scriptlet: insert_tag
         slug: dramat-wspolczesny
         tooltip: "dramat wsp\xF3\u0142czesny (proz\u0105)"
         group: [13]
         label: "dzie\u0142o nadrz\u0119dne"
         link: ''
-        params: '{"tag": "dzielo_nadrzedne"}'
+        params: '{"padding_top": 1, "padding_bottom": 2, "tag": "dzielo_nadrzedne"}'
         scriptlet: insert_tag
         slug: dzielo-nadrzedne
         tooltip: ''
         group: [12]
         label: kwestia
         link: ''
-        params: '{"tag": "kwestia"}'
+        params: '{"padding_top": 1, "padding_bottom": 1, "tag": "kwestia"}'
         scriptlet: insert_tag
         slug: kwestia
         tooltip: "wstawia kwesti\u0119"
         group: [12]
         label: kwestioakapit
         link: ''
-        params: '[["insert_tag", {"tag": "akap"}], ["insert_tag", {"tag": "kwestia"}]]'
+        params: '[["insert_tag", {"tag": "akap"}], ["insert_tag", {"padding_top":
+            1, "padding_bottom": 1, "tag": "kwestia"}]]'
         scriptlet: macro
         slug: kwestioakapit
         tooltip: ''
         group: [12]
         label: kwestiostrofa
         link: ''
-        params: '[["insert_stanza", {"tag": "strofa"}], ["insert_tag", {"tag": "kwestia"}]]'
+        params: '[["insert_stanza", {"tag": "strofa"}], ["insert_tag", {"padding_top":
+            1, "padding_bottom": 1, "tag": "kwestia"}]]'
         scriptlet: macro
         slug: kwestiostrofa
         tooltip: ''
         group: [11]
         label: liryka
         link: ''
-        params: '{"tag": "liryka_l"}'
+        params: '{"padding_top": 1, "padding_bottom": 4, "tag": "liryka_l"}'
         scriptlet: insert_tag
         slug: liryka
         tooltip: ''
         group: [11]
         label: "liryka/w. \u0142am"
         link: ''
-        params: '{"tag": "liryka_lp"}'
+        params: '{"padding_top": 1, "padding_bottom": 4, "tag": "liryka_lp"}'
         scriptlet: insert_tag
         slug: liryka-w-lam
         tooltip: "utw\xF3r liryczny o zw\u0119\u017Conej szeroko\u015Bci \u0142amu"
         group: [22]
         label: "lista os\xF3b"
         link: ''
-        params: '{"tag": "lista_osob"}'
+        params: '{"padding_top": 1, "padding_bottom": 4, "tag": "lista_osob"}'
         scriptlet: insert_tag
         slug: lista-osob
         tooltip: "lista os\xF3b poprzedzaj\u0105ca tekst dramatu"
         group: [22]
         label: 'typ osoby '
         link: ''
-        params: '{"tag": "lista_osoba", "attrs": {"typ": ""}}'
+        params: '{"padding_top": 1, "padding_bottom": 1, "tag": "lista_osoba", "attrs":
+            {"typ": ""}}'
         scriptlet: insert_tag
         slug: lista-osob-pole
         tooltip: osoby z takim samym opisem
         group: [13, 22]
         label: motto
         link: ''
-        params: '{"tag": "motto"}'
+        params: '{"padding_top": 1, "padding_bottom": 3, "tag": "motto"}'
         scriptlet: insert_tag
         slug: motto
         tooltip: ''
         group: [13, 22]
         label: motto podpis
         link: ''
-        params: '{"tag": "motto_podpis"}'
+        params: '{"padding_top": 1, "padding_bottom": 2, "tag": "motto_podpis"}'
         scriptlet: insert_tag
         slug: motto-podpis
         tooltip: ''
         group: [12]
         label: "nag\u0142\xF3wek kwestii"
         link: ''
-        params: '{"tag": "naglowek_osoba"}'
+        params: '{"padding_top": 1, "padding_bottom": 4, "tag": "naglowek_osoba"}'
         scriptlet: insert_tag
         slug: naglowek-kwestii
         tooltip: "nag\u0142\xF3wek kwestii - nazwa osoby"
         group: [22]
         label: "nag\u0142\xF3wek listy"
         link: ''
-        params: '{"tag": "naglowek_listy"}'
+        params: '{"padding_top": 1, "padding_bottom": 2, "tag": "naglowek_listy"}'
         scriptlet: insert_tag
         slug: naglowek-listy
         tooltip: "nag\u0142\xF3wek listy os\xF3b"
         group: [13]
         label: nazwa utworu
         link: ''
-        params: '{"tag": "nazwa_utworu"}'
+        params: '{"padding_top": 1, "padding_bottom": 2, "tag": "nazwa_utworu"}'
         scriptlet: insert_tag
         slug: nazwa-utworu
         tooltip: ''
         group: [11]
         label: opowiadanie
         link: ''
-        params: '{"tag": "opowiadanie"}'
+        params: '{"padding_top": 1, "padding_bottom": 4, "tag": "opowiadanie"}'
         scriptlet: insert_tag
         slug: opowiadanie
         tooltip: ''
         group: [22]
         label: osoba na liscie
         link: ''
-        params: '{"tag": "lista_osoba"}'
+        params: '{"padding_top": 1, "padding_bottom": 1, "tag": "lista_osoba"}'
         scriptlet: insert_tag
         slug: osoba-na-liscie
         tooltip: "nazwa osoby na liscie os\xF3b"
         group: [11]
         label: "powie\u015B\u0107"
         link: ''
-        params: '{"tag": "powiesc"}'
+        params: '{"padding_top": 1, "padding_bottom": 4, "tag": "powiesc"}'
         scriptlet: insert_tag
         slug: powiesc
         tooltip: ''
         group: [1]
         label: "rozdzia\u0142"
         link: ''
-        params: '{"tag": "naglowek_rozdzial"}'
+        params: '{"padding_top": 1, "padding_bottom": 4, "tag": "naglowek_rozdzial"}'
         scriptlet: insert_tag
         slug: rozdzial
         tooltip: ''
         group: [12, 17]
         label: strofa
         link: ''
-        params: '{"tag": "strofa"}'
+        params: '{"padding_top": 1, "padding_bottom": 3, "tag": "strofa"}'
         scriptlet: insert_stanza
         slug: strofa
         tooltip: "wstawia strof\u0119"
     pk: 48
 -   fields:
         accesskey: ''
-        group: [15]
+        group: [12, 15]
         label: "wyr\xF3\u017Cnienie"
         link: ''
         params: '{"tag": "wyroznienie"}'
         group: [11]
         label: wywiad
         link: ''
-        params: '{"tag": "wywiad"}'
+        params: '{"padding_top": 1, "padding_bottom": 4, "tag": "wywiad"}'
         scriptlet: insert_tag
         slug: wywiad
         tooltip: ''
index 953383c..949365a 100644 (file)
@@ -48,8 +48,12 @@ function ScriptletCenter()
 {
     this.scriptlets = {};
 
-    this.scriptlets['insert_tag'] = function(context, params, text, move_forward, done)
+    this.scriptlets['insert_tag'] = function(context, params, text, move_forward, move_up, done)
     {
+        var padding_top = '';
+        for (var i=params.padding_top; i; i--)
+            padding_top += '\n';
+
         var start_tag = '<'+params.tag;
         var cursor_inside = false;
 
@@ -60,6 +64,10 @@ function ScriptletCenter()
         start_tag += '>';
         var end_tag = '</'+params.tag+'>';
 
+        var padding_bottom = '';
+        for (var i=params.padding_bottom; i; i--)
+            padding_bottom += '\n';
+
         if(text.length > 0) {
             // tokenize
             var output = '';
@@ -71,40 +79,42 @@ function ScriptletCenter()
                 }
                 else { // character
                     output += token;
-                    if(output == token) output += start_tag;
+                    if(output == token) output += padding_top + start_tag;
                     token = '';
                     output += text[index];
                 }
             }
 
             if( output[output.length-1] == '\\' ) {
-                output = output.substr(0, output.length-1) + end_tag + '\\';
+                output = output.substr(0, output.length-1) + end_tag + padding_bottom + '\\';
             } else {
-                output += end_tag;
+                output += end_tag + padding_bottom;
             }
             output += token;
 
             // keep cursor inside tag if some previous scriptlet has already moved it
-            cursor_inside = move_forward != 0;
+            cursor_inside = move_forward != 0 || move_up != 0;
         }
         else {
             if(params.nocontent) {
-                output = "<"+params.tag +" />";
+                output = padding_top + "<"+params.tag +" />" + padding_bottom;
             }
             else {
-                output = start_tag + end_tag;
+                output = padding_top + start_tag + end_tag + padding_bottom;
                 cursor_inside = true;
             }
         }
 
         if (cursor_inside) {
-            move_forward -= params.tag.length+3;
+            move_forward -= params.tag.length + 3;
+            move_up += params.padding_bottom || 0;
+            alert(move_forward + ' ' + move_up)
         }
 
-        done(output, move_forward);
+        done(output, move_forward, move_up);
     }.bind(this);
 
-    this.scriptlets['lineregexp'] = function(context, params, text, move_forward, done) {
+    this.scriptlets['lineregexp'] = function(context, params, text, move_forward, move_up, done) {
                var self = this;
 
         var exprs = $.map(params.exprs, function(expr) {
@@ -117,7 +127,7 @@ function ScriptletCenter()
                 };
         });
 
-        if(!text) done(text, move_forward);
+        if(!text) done(text, move_forward, move_up);
 
         var changed = 0;
         var lines = text.split('\n');
@@ -138,11 +148,11 @@ function ScriptletCenter()
                 text = newlines.join('\n');
             };
 
-            done(text, move_forward);
+            done(text, move_forward, move_up);
                });
     }.bind(this);
 
-    this.scriptlets['fulltextregexp'] = function(context, params, text, move_forward, done) {
+    this.scriptlets['fulltextregexp'] = function(context, params, text, move_forward, move_up, done) {
                var self = this;
 
         var exprs = $.map(params.exprs, function(expr) {
@@ -156,42 +166,50 @@ function ScriptletCenter()
                 };
         });
 
-        if(!text) done(text, move_forward);
+        if(!text) done(text, move_forward, move_up);
 
                nblck_each(exprs, function(expr, index) {
                        $progress.html(600 + index);
             text = text.replace(expr.rx, expr.repl);
         }, function() {
-                       done(text, move_forward);
+                       done(text, move_forward, move_up);
                });
     }.bind(this);
 
-    this.scriptlets['macro'] = function(context, params, text, move_forward, done) {
+    this.scriptlets['macro'] = function(context, params, text, move_forward, move_up, done) {
         var self = this;
                var i = 0;
 
-               function next(text, move_forward) {
+               function next(text, move_forward, move_up) {
                if (i < params.length) {
                                var e = params[i];
                                i = i + 1;
-                               self.scriptlets[e[0]](context, e[1], text, move_forward, next);
+                               self.scriptlets[e[0]](context, e[1], text, move_forward, move_up, next);
                        }
                        else {
-                               done(text, move_forward);
+                               done(text, move_forward, move_up);
                        }
         };
 
-               next(text, move_forward);
+               next(text, move_forward, move_up);
     }.bind(this);
 
-    this.scriptlets['lowercase'] = function(context, params, text, move_forward, done)
+    this.scriptlets['lowercase'] = function(context, params, text, move_forward, move_up, done)
     {
-        if(!text) done(text, move_forward);
-        done(text.toLowerCase(), move_forward);
+        if(!text) done(text, move_forward, move_up);
+        done(text.toLowerCase(), move_forward, move_up);
     }.bind(this);
 
 
-    this.scriptlets["insert_stanza"] = function(context, params, text, move_forward, done) {
+    this.scriptlets["insert_stanza"] = function(context, params, text, move_forward, move_up, done) {
+        var padding_top = '';
+        for (var i=params.padding_top; i; i--)
+            padding_top += '\n';
+
+        var padding_bottom = '';
+        for (var i=params.padding_bottom; i; i--)
+            padding_bottom += '\n';
+
         if(text) {
             var verses = text.split('\n');
             text = ''; var buf = ''; var ebuf = '';
@@ -208,20 +226,21 @@ function ScriptletCenter()
                     ebuf += '\n' + verses[i];
                 }
             }
-            text = text + buf + '\n</strofa>' + ebuf;
+            text = padding_top + text + buf + '\n</strofa>' + padding_bottom + ebuf;
         }
         else {
-            text = "<strofa></strofa>"
+            text = padding_top + "<strofa></strofa>" + padding_bottom;
             move_forward -= "</strofa>".length;
+            move_up += params.padding_bottom || 0;
         }
 
-        done(text, move_forward);
+        done(text, move_forward, move_up);
     }.bind(this);
 
 
-    this.scriptlets['autotag'] = function(context, params, text, move_forward, done)
+    this.scriptlets['autotag'] = function(context, params, text, move_forward, move_up, done)
     {
-        if(!text.match(/^\n+$/)) done(text, move_forward);
+        if(!text.match(/^\n+$/)) done(text, move_forward, move_up);
 
         function insert_done(output, mf) {
             text += output;
@@ -254,7 +273,7 @@ function ScriptletCenter()
             }
         }
 
-        done(text, move_forward);
+        done(text, move_forward, move_up);
     }.bind(this);
 
 }
@@ -272,16 +291,16 @@ ScriptletCenter.prototype.callInteractive = function(opts) {
        $.blockUI({message: $progress, showOverlay: false});
 
     var input = self.XMLEditorSelectedText(opts.context);
-       self.scriptlets[opts.action](opts.context, opts.extra, input, 0, function(output, move_forward){
+       self.scriptlets[opts.action](opts.context, opts.extra, input, 0, 0, function(output, move_forward, move_up){
            /*if(timer)
                clearTimeout(timer);
            else */
         if (input != output) {
             self.XMLEditorReplaceSelectedText(opts.context, output)
         }
-        if (move_forward) {
+        if (move_forward || move_up) {
             try {
-                self.XMLEditorMoveCursorForward(opts.context, move_forward)
+                self.XMLEditorMoveCursorForward(opts.context, move_forward, move_up)
             }
             catch(e) {}
         }
@@ -300,9 +319,24 @@ ScriptletCenter.prototype.XMLEditorReplaceSelectedText = function(editor, replac
        editor.replaceSelection(replacement);
 };
 
-ScriptletCenter.prototype.XMLEditorMoveCursorForward = function(panel, n) {
+ScriptletCenter.prototype.XMLEditorMoveCursorForward = function(panel, right, up) {
     var pos = panel.cursorPosition();
-    panel.selectLines(pos.line, pos.character + n);
+    if (up) {
+        line = pos.line;
+        while (up < 0) {
+            line = panel.nextLine(line);
+            ++up;
+        }
+        while (up > 0) {
+            line = panel.prevLine(line);
+            --up;
+        }
+        len = panel.lineContent(line).length;
+        panel.selectLines(line, len + right);
+    }
+    else {
+        panel.selectLines(pos.line, pos.character + right);
+    }
 };
 
 var scriptletCenter;
index af8cb56..f7dbbf6 100644 (file)
@@ -129,62 +129,6 @@ const NAMESPACES = {
        "http://www.w3.org/XML/1998/namespace": "xml"
 };
 
-/*
- * PADDING for pretty-printing
- */
-const PADDING = {
-    dramat_wierszowany_l: 4,
-    dramat_wierszowany_lp: 4,
-    dramat_wspolczesny: 4,
-    wywiad: 4,
-    opowiadanie: 4,
-    powiesc: 4,
-    liryka_l: 4,
-    liryka_lp: 4,
-    naglowek_czesc: 4,
-    naglowek_akt: 4,
-    naglowek_rozdzial: 4,
-    naglowek_osoba: 4,
-    lista_osob: 4,
-
-    akap: 3,
-    akap_cd: 3,
-    akap_dialog: 3,
-    strofa: 3,
-    motto: 3,
-    miejsce_czas: 3,
-
-    autor_utworu: 2,
-    nazwa_utworu: 2,
-    dzielo_nadrzedne: 2,
-
-    didaskalia: 2,
-    motto_podpis: 2,
-    naglowek_listy: 2,
-    kwestia: 1,
-    lista_osoba: 1,
-
-       "podpis": 1,
-       "wers": 0,
-       "wers_cd": 0,
-       "wers_akap": 0,
-       "wers_wciety": 0,
-
-       "rdf:RDF": 3,
-       "rdf:Description": 1,
-};
-
-function getPadding(name) {
-
-       if(name.match(/^dc:.*$/))
-               return -1;
-
-       if(PADDING[name])
-               return PADDING[name];
-
-       return 0;
-}
-
 function HTMLSerializer() {
        // empty constructor
 }
@@ -235,6 +179,19 @@ HTMLSerializer.prototype._verseBefore = function(node) {
        return (prev !== null) && prev.hasAttribute('x-verse');
 }
 
+HTMLSerializer.prototype._nodeIgnored = function(node) {
+    return node.getAttribute('x-node') == 'wers';
+}
+
+HTMLSerializer.prototype._ignoredWithWhitespace = function(node) {
+    while (node.nodeType == ELEMENT_NODE && this._nodeIgnored(node) && node.childNodes.length > 0)
+        node = node.childNodes[0];
+    if (node.nodeType == TEXT_NODE)
+        return node.nodeValue.match(/^\s/)
+    else return false;
+}
+
+
 HTMLSerializer.prototype.serialize = function(rootElement, stripOuter)
 {
        var self = this;
@@ -245,16 +202,18 @@ HTMLSerializer.prototype.serialize = function(rootElement, stripOuter)
        else
                self._pushChildren(rootElement);
 
+    var text_buffer = '';
+
        while(self.stack.length > 0) {
                var token = self.stack.pop();
 
-               if(token.type === ELEM_END) {
-                       self.result += "</" + token.tagName + ">";
-                       for(var padding = getPadding(token.tagName); padding > 0; padding--) {
-                               self.result += "\n";
-                       }
-                       continue;
-               };
+        if(token.type === ELEM_END) {
+            self.result += text_buffer;
+            text_buffer = '';
+            if (token.tagName != '')
+                self.result += "</" + token.tagName + ">";
+            continue;
+        };
 
                if(token.type === NS_END) {
                        self._unassignNamespace(token.namespace);
@@ -275,34 +234,25 @@ HTMLSerializer.prototype.serialize = function(rootElement, stripOuter)
 
                                var xnode = token.node.getAttribute('x-node');
 
-                               if(xnode === 'wers') {
-                                       /* push children */
-                                       if(self._verseBefore(token.node))
-                                               self.result += '/\n';
-                                       self._pushChildren(token.node);
-                                       break;
-                               };
-
                                if(xnode === 'out-of-flow-text') {
                                        self._pushChildren(token.node);
                                        break;
                                }
 
-                if(token.node.hasAttribute('x-verse')) {
-                    if(self._verseBefore(token.node)) {
-                        self.result += '/';
-                    }
-                    self.result += '\n';
-                };
+                if(token.node.hasAttribute('x-verse') && self._verseBefore(token.node)) {
+                    self.result += '/';
+                    // add whitespace if there's none
+                    if (!(text_buffer.match(/^\s/) || self._ignoredWithWhitespace(token.node)))
+                        self.result += ' ';
+                }
 
+                self.result += text_buffer;
+                text_buffer = '';
                                self._serializeElement(token.node);
                                break;
                        case TEXT_NODE:
-                               // collapse previous element's padding
-                               var i = 0;
-                               while (token.node.nodeValue[i] == '\n' && self.result[self.result.length - 1] == '\n')
-                                 i ++;
-                               self.result += token.node.nodeValue.substr(i);
+                               self.result += text_buffer;
+                               text_buffer = token.node.nodeValue;
                                break;
                };
        };
@@ -356,72 +306,74 @@ HTMLSerializer.prototype._rjoin = function(prefix, name) {
 };
 
 HTMLSerializer.prototype._serializeElement = function(node) {
-       var self = this;
-
-       var ns = node.getAttribute('x-ns');
-       var nsPrefix = null;
-       var newNamespaces = [];
-
-       var nsData = self._assignNamespace(node.getAttribute('x-ns'));
+    var self = this;
 
-       if(nsData.fresh) {
-               newNamespaces.push(nsData);
-               self.stack.push({
-                       "type": NS_END,
-                       "namespace": nsData
-               });
-       }
-
-       var tagName = self._join(nsData.prefix, node.getAttribute('x-node'));
-
-       /* retrieve attributes */
-       var attributeIDs = [];
-       for (var i = 0; i < node.attributes.length; i++) {
-               var attr = node.attributes.item(i);
-
-               // check if name starts with "x-attr-name"
-               var m = attr.name.match(XATTR_RE);
-               if (m !== null)
-                       attributeIDs.push(m[1]);
-       };
-
-       /* print out */
-
-       // at least one newline before padded elements
-       if (getPadding(tagName) && self.result[self.result.length - 1] != '\n')
-               self.result += '\n';
-
-       self.result += '<' + tagName;
-
-       $.each(attributeIDs, function() {
-               var nsData = self._assignNamespace(node.getAttribute('x-attr-ns-'+this));
-
-               if(nsData.fresh) {
-                       newNamespaces.push(nsData);
-                       self.stack.push({
-                               "type": NS_END,
-                               "namespace": nsData
-                       });
-               };
-
-               self.result += ' ' + self._join(nsData.prefix, node.getAttribute('x-attr-name-'+this));
-               self.result += '="'+node.getAttribute('x-attr-value-'+this) +'"';
-       });
-
-       /* print new namespace declarations */
-       $.each(newNamespaces, function() {
-               self.result += " " + self._rjoin("xmlns", this.prefix);
-               self.result += '="' + this.uri + '"';
-       });
-
-       if (node.childNodes.length > 0) {
-               self.result += ">";
-               self._pushTagEnd(tagName);
-               self._pushChildren(node);
-       }
-       else {
-               self.result += "/>";
-       };
+    if (self._nodeIgnored(node)) {
+        self._pushTagEnd('');
+        self._pushChildren(node);
+    }
+    else {
+       var ns = node.getAttribute('x-ns');
+       var nsPrefix = null;
+       var newNamespaces = [];
+
+       var nsData = self._assignNamespace(node.getAttribute('x-ns'));
+
+       if(nsData.fresh) {
+               newNamespaces.push(nsData);
+               self.stack.push({
+                       "type": NS_END,
+                       "namespace": nsData
+               });
+       }
+
+       var tagName = self._join(nsData.prefix, node.getAttribute('x-node'));
+
+       /* retrieve attributes */
+       var attributeIDs = [];
+       for (var i = 0; i < node.attributes.length; i++) {
+               var attr = node.attributes.item(i);
+
+               // check if name starts with "x-attr-name"
+               var m = attr.name.match(XATTR_RE);
+               if (m !== null)
+                       attributeIDs.push(m[1]);
+       };
+
+       /* print out */
+
+       self.result += '<' + tagName;
+
+       $.each(attributeIDs, function() {
+               var nsData = self._assignNamespace(node.getAttribute('x-attr-ns-'+this));
+
+               if(nsData.fresh) {
+                       newNamespaces.push(nsData);
+                       self.stack.push({
+                               "type": NS_END,
+                               "namespace": nsData
+                       });
+               };
+
+               self.result += ' ' + self._join(nsData.prefix, node.getAttribute('x-attr-name-'+this));
+               self.result += '="'+node.getAttribute('x-attr-value-'+this) +'"';
+       });
+
+       /* print new namespace declarations */
+       $.each(newNamespaces, function() {
+               self.result += " " + self._rjoin("xmlns", this.prefix);
+               self.result += '="' + this.uri + '"';
+       });
+
+       if (node.childNodes.length > 0) {
+               self.result += ">";
+               self._pushTagEnd(tagName);
+               self._pushChildren(node);
+       }
+       else {
+               self.result += "/>";
+       };
+    }
 };
 
 function html2text(params) {
index 1739f62..e0c6d8b 100644 (file)
         <!-- <xsl:value-of select="." /> -->
         <xsl:param name="mixed" />
         <xsl:choose>
-            <xsl:when test="normalize-space(.) = ''" />
+            <xsl:when test="normalize-space(.) = ''">
+                <xsl:value-of select="." />
+            </xsl:when>
             <xsl:when test="not($mixed)">
                <span x-node="out-of-flow-text" class="out-of-flow-text" x-editable="true">
                        <xsl:value-of select="." />