diff options
| author | Michael Williamson <mike@zwobble.org> | 2013-03-29 21:04:09 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2013-03-29 21:04:09 +0000 |
| commit | 0f90a6de310fd86472c29e945f06fe94c666fa2c (patch) | |
| tree | 1005bc92e87240fe4e6be5235bad494a9f09ac44 /lib | |
| parent | 33c8de2a7b6162e6e0dac8c4d5888317776c7ecf (diff) | |
Add styles with nested elements
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/documents.js | 77 | ||||
| -rw-r--r-- | lib/styles.js | 7 |
2 files changed, 70 insertions, 14 deletions
diff --git a/lib/documents.js b/lib/documents.js index b91c3b1..8d9b665 100644 --- a/lib/documents.js +++ b/lib/documents.js @@ -2,6 +2,8 @@ var util = require("util"); var q = require("q"); +var styles = require("./styles"); + exports.DocumentConverter = DocumentConverter; exports.Document = Document; exports.Paragraph = Paragraph; @@ -15,39 +17,45 @@ function DocumentConverter(options) { var paragraphStyleMap = options.paragraphStyleMap; function convertToHtml(document) { - var html = document.children.map(elementToHtml).join(""); + var html = new HtmlGenerator(); + convertElements(document.children, html); return q.when({ - html: html + html: html.asString() }); } + + function convertElements(elements, html) { + elements.forEach(function(element) { + elementToHtml(element, html); + }); + } - function elementToHtml(element) { + function elementToHtml(element, html) { var handler = elementConverters[element.type]; if (handler) { - return handler(element); + return handler(element, html); } else { return ""; } } - function convertParagraph(element) { - var innerHtml = element.children.map(elementToHtml).join(""); - var tagName = styleForParagraph(element); - return util.format("<%s>%s</%s>", tagName, innerHtml, tagName); + function convertParagraph(element, html) { + html.style(styleForParagraph(element)); + convertElements(element.children, html); } function styleForParagraph(element) { - return paragraphStyleMap[element.properties.styleName] || "p"; + return paragraphStyleMap[element.properties.styleName] || styles.topLevelElement("p"); } var elementConverters = { "paragraph": convertParagraph, - "run": function(element) { - return element.children.map(elementToHtml).join(""); + "run": function(element, html) { + convertElements(element.children, html); }, - "text": function(element) { - return escapeHtml(element.value); + "text": function(element, html) { + html.text(element.value); } }; return { @@ -55,6 +63,49 @@ function DocumentConverter(options) { } } +function HtmlGenerator() { + var stack = []; + var fragments = []; + + function text(value) { + fragments.push(escapeHtml(value)) + } + + function asString() { + popAll(); + return fragments.join(""); + } + + function style(style) { + popAll(); + style.forEach(function(tagName) { + push(tagName); + }); + } + + function push(element) { + stack.push(element); + fragments.push(util.format("<%s>", element)); + } + + function pop() { + var element = stack.pop(); + fragments.push(util.format("</%s>", element)); + } + + function popAll() { + while (stack.length > 0) { + pop(); + } + } + + return { + style: style, + text: text, + asString: asString + }; +} + function Document(children) { return { type: "document", diff --git a/lib/styles.js b/lib/styles.js index 3c5a3ff..d3aa0a4 100644 --- a/lib/styles.js +++ b/lib/styles.js @@ -1,5 +1,10 @@ exports.topLevelElement = topLevelElement; +exports.elements = elements; function topLevelElement(tagName) { - return tagName; + return elements([tagName]); +} + +function elements(tagNames) { + return tagNames; } |
