aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2013-03-29 21:04:09 +0000
committerMichael Williamson <mike@zwobble.org>2013-03-29 21:04:09 +0000
commit0f90a6de310fd86472c29e945f06fe94c666fa2c (patch)
tree1005bc92e87240fe4e6be5235bad494a9f09ac44 /lib
parent33c8de2a7b6162e6e0dac8c4d5888317776c7ecf (diff)
Add styles with nested elements
Diffstat (limited to 'lib')
-rw-r--r--lib/documents.js77
-rw-r--r--lib/styles.js7
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;
}