Index: trunk/extensions/VisualEditor/modules/es/serializers/es.HtmlSerializer.js |
— | — | @@ -91,8 +91,81 @@ |
92 | 92 | }; |
93 | 93 | |
94 | 94 | es.HtmlSerializer.prototype.list = function( node ) { |
95 | | - // TODO: Convert list from flat to structured format and output it as HTML |
96 | | - return '<!-- TODO: Support list and listItem nodes -->'; |
| 95 | + var out = [], // List of list nodes |
| 96 | + bstack = [], // Bullet stack, previous element's listStyles |
| 97 | + bnext = [], // Next element's listStyles |
| 98 | + closeTags = []; // Stack of close tags for currently active lists |
| 99 | + |
| 100 | + var commonPrefixLength = function (x, y) { |
| 101 | + var minLength = Math.min(x.length, y.length); |
| 102 | + for(var i = 0; i < minLength; i++) { |
| 103 | + if (x[i] !== y[i] |
| 104 | + // Both definitiondata and definitionterm are |
| 105 | + // inside dls, so consider them equivalent here. |
| 106 | + && [x[i], y[i]].sort() |
| 107 | + !== ['definitiondata', 'definitionterm'] ) |
| 108 | + { |
| 109 | + break; |
| 110 | + } |
| 111 | + } |
| 112 | + return i; |
| 113 | + } |
| 114 | + |
| 115 | + var popTags = function ( n ) { |
| 116 | + for (var i = 0; i < n; i++ ) { |
| 117 | + out.push(closeTags.pop()); |
| 118 | + } |
| 119 | + } |
| 120 | + |
| 121 | + var openLists = function ( bs, bn, attribs ) { |
| 122 | + var prefix = commonPrefixLength (bs, bn); |
| 123 | + // pop close tags from stack |
| 124 | + popTags(closeTags.length - prefix); |
| 125 | + for(var i = prefix; i < bn.length; i++) { |
| 126 | + var c = bn[i]; |
| 127 | + switch (c) { |
| 128 | + case 'bullet': |
| 129 | + out.push(es.Html.makeOpeningTag('ul', attribs)); |
| 130 | + closeTags.push(es.Html.makeClosingTag('ul')); |
| 131 | + break; |
| 132 | + case 'number': |
| 133 | + out.push(es.Html.makeOpeningTag('ol', attribs)); |
| 134 | + closeTags.push(es.Html.makeClosingTag('ol')); |
| 135 | + break; |
| 136 | + case 'definitionterm': |
| 137 | + case 'definitiondata': |
| 138 | + out.push(es.Html.makeOpeningTag('dl', attribs)); |
| 139 | + closeTags.push(es.Html.makeClosingTag('dl')); |
| 140 | + break; |
| 141 | + default: |
| 142 | + throw("Unknown node prefix " + c); |
| 143 | + } |
| 144 | + }; |
| 145 | + } |
| 146 | + |
| 147 | + var childrenLength = node.children.length; |
| 148 | + for (var i = 0; i < childrenLength; i++) { |
| 149 | + var e = node.children[i]; |
| 150 | + bnext = e.attributes.styles; |
| 151 | + delete e.attributes['styles']; |
| 152 | + openLists( bstack, bnext, e.attributes ); |
| 153 | + var tag; |
| 154 | + switch(bnext[bnext.length - 1]) { |
| 155 | + case 'definitionterm': |
| 156 | + tag = 'dt'; break; |
| 157 | + case 'definitiondata': |
| 158 | + tag = 'dd'; break; |
| 159 | + default: |
| 160 | + tag = 'li'; break; |
| 161 | + } |
| 162 | + out.push( es.Html.makeTag(tag, e.attributes, |
| 163 | + this.content(e.content) |
| 164 | + ) |
| 165 | + ); |
| 166 | + bstack = bnext; |
| 167 | + }; |
| 168 | + popTags(closeTags.length); |
| 169 | + return out.join("\n"); |
97 | 170 | }; |
98 | 171 | |
99 | 172 | es.HtmlSerializer.prototype.table = function( node ) { |
Index: trunk/extensions/VisualEditor/modules/parser/pegParser.pegjs.txt |
— | — | @@ -81,6 +81,25 @@ |
82 | 82 | return dumped_text; |
83 | 83 | |
84 | 84 | } |
| 85 | + |
| 86 | + // Convert list prefixes to a list of WikiDom list styles |
| 87 | + var bulletsToTypes = function (bullets) { |
| 88 | + var bTypes = []; |
| 89 | + var blen = bullets.length; |
| 90 | + for (var i = 0; i < bullets.length; i++) { |
| 91 | + switch (bullets[i]) { |
| 92 | + case '*': |
| 93 | + bTypes.push('bullet'); break; |
| 94 | + case '#': |
| 95 | + bTypes.push('number'); break; |
| 96 | + case ';': |
| 97 | + bTypes.push('definitionterm'); break; |
| 98 | + case ':': |
| 99 | + bTypes.push('definitiondata'); break; |
| 100 | + } |
| 101 | + } |
| 102 | + return bTypes; |
| 103 | + } |
85 | 104 | } |
86 | 105 | |
87 | 106 | start |
— | — | @@ -93,7 +112,7 @@ |
94 | 113 | else |
95 | 114 | es.push(ei); |
96 | 115 | }); |
97 | | - dp(print_r(es)); |
| 116 | + dp(es); |
98 | 117 | return { |
99 | 118 | type: 'page', |
100 | 119 | content: es |
— | — | @@ -547,86 +566,32 @@ |
548 | 567 | |
549 | 568 | lists = es:(dtdd / li)+ |
550 | 569 | { |
551 | | - var out = [], // List of list nodes |
552 | | - bstack = "", // Bullet stack, previous element's listStyle |
553 | | - bnext = "", // Next element's listStyle |
554 | | - nodes = []; // Stack of currently active, nested list nodes |
555 | | - |
556 | | - var commonPrefixLength = function (x, y) { |
557 | | - var minLength = Math.min(x.length, y.length); |
558 | | - for(var i = 0; i < minLength; i++) { |
559 | | - if (x[i] != y[i]) |
560 | | - break; |
561 | | - } |
562 | | - return i; |
563 | | - } |
564 | | - |
565 | | - var pushN = function ( n ) { |
566 | | - if (nodes.length > 0) { |
567 | | - nodes[nodes.length - 1].content.push(n); |
| 570 | + // flatten es |
| 571 | + var esLen = es.length; |
| 572 | + var flatEs = []; |
| 573 | + for (var i = 0; i < esLen; i++) { |
| 574 | + if (es[i].constructor === Array) { |
| 575 | + flatEs.concat(es[i]); |
568 | 576 | } else { |
569 | | - out.push(n); |
570 | | - nodes.push(n); |
| 577 | + flatEs.push(es[i]); |
571 | 578 | } |
572 | | - |
573 | 579 | } |
574 | | - |
575 | | - var openLists = function ( bs, bn ) { |
576 | | - var prefix = commonPrefixLength (bs, bn); |
577 | | - nodes = nodes.slice(0, prefix); |
578 | | - $.each(bn.slice(prefix, bn.length), function (i, c) { |
579 | | - switch (c) { |
580 | | - case '*': |
581 | | - pushN({type: 'ul', content: []}); |
582 | | - break; |
583 | | - case '#': |
584 | | - pushN({type: 'ol', content: []}); |
585 | | - break; |
586 | | - case ';': |
587 | | - case ':': |
588 | | - pushN({type: 'dl', content: []}); |
589 | | - break; |
590 | | - default: |
591 | | - throw("Unknown node prefix " + c); |
592 | | - } |
593 | | - }); |
| 580 | + return { |
| 581 | + type: 'list', |
| 582 | + children: es |
594 | 583 | } |
595 | | - |
596 | | - |
597 | | - $.each(es, function(i, e) { |
598 | | - if (e.type == 'dtdd') { |
599 | | - bnext = e.content[0].listStyle; |
600 | | - lnode = openLists( bstack, bnext ); |
601 | | - |
602 | | - nodes[nodes.length - 1].content = |
603 | | - nodes[nodes.length - 1].content.concat(e.content); |
604 | | - } else { |
605 | | - bnext = e.listStyle; |
606 | | - openLists( bstack, bnext, nodes ); |
607 | | - nodes[nodes.length - 1].content.push(e); |
608 | | - } |
609 | | - bstack = bnext; |
610 | | - }); |
611 | | - //dp("out: " + print_r(out, 5)); |
612 | | - return out; |
613 | 584 | } |
614 | 585 | |
615 | 586 | li = bullets:list_char+ |
616 | 587 | c:(inlineline / anyline) |
617 | 588 | newline |
618 | 589 | { |
619 | | - var type; |
620 | | - switch (bullets[bullets.length - 1]) { |
621 | | - case '#': |
622 | | - case '*': |
623 | | - type = 'li'; break; |
624 | | - case ';': type = 'dt'; break; |
625 | | - case ':': type = 'dd'; break; |
626 | | - } |
627 | 590 | return { |
628 | | - type: type, |
629 | | - listStyle: bullets, |
630 | | - content: c |
| 591 | + type: 'listItem', |
| 592 | + attributes: { |
| 593 | + styles: bulletsToTypes(bullets) |
| 594 | + }, |
| 595 | + content: c[0] |
631 | 596 | }; |
632 | 597 | } |
633 | 598 | |
— | — | @@ -640,21 +605,18 @@ |
641 | 606 | if (bullets[bullets.length - 1] != ';') { |
642 | 607 | return null; |
643 | 608 | } else { |
644 | | - return { |
645 | | - type: 'dtdd', |
646 | | - content: [ |
647 | | - { |
648 | | - type: 'dt', |
649 | | - listStyle: bullets, |
650 | | - content: c |
651 | | - }, { |
652 | | - type: 'dd', |
653 | | - listStyle: bullets.slice(0, bullets.length - 1) + ':', |
654 | | - content: d |
655 | | - } |
656 | | - |
657 | | - ] |
658 | | - } |
| 609 | + return [ |
| 610 | + { |
| 611 | + type: 'listItem', |
| 612 | + attributes: {styles: bulletsToTypes(bullets)}, |
| 613 | + content: c[0] |
| 614 | + }, { |
| 615 | + type: 'listItem', |
| 616 | + attributes: {styles: bulletsToTypes( |
| 617 | + bullets.slice(0, bullets.length - 1) + ':')}, |
| 618 | + content: d[0] |
| 619 | + } |
| 620 | + ] |
659 | 621 | } |
660 | 622 | } |
661 | 623 | |