aboutsummaryrefslogtreecommitdiff
path: root/lib/writers/html-writer.js
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2015-02-04 18:41:12 +0000
committerMichael Williamson <mike@zwobble.org>2015-02-04 18:41:12 +0000
commitb2ccfa5cc2cd4d7f8f80f0555e2586387375a98e (patch)
treee4ce2260bf93a03865400adb4c389720140cf3d1 /lib/writers/html-writer.js
parent774ff6722f9df9fec9f350288023aa500f49df61 (diff)
Move writers into a separate directory
Diffstat (limited to 'lib/writers/html-writer.js')
-rw-r--r--lib/writers/html-writer.js156
1 files changed, 156 insertions, 0 deletions
diff --git a/lib/writers/html-writer.js b/lib/writers/html-writer.js
new file mode 100644
index 0000000..33441cb
--- /dev/null
+++ b/lib/writers/html-writer.js
@@ -0,0 +1,156 @@
+var util = require("util");
+var _ = require("underscore");
+
+exports.writer = writer;
+
+function writer(options) {
+ options = options || {};
+ if(options.prettyPrint) {
+ return prettyWriter();
+ }
+ else if(options.markdown) {
+ var markdown = require("./markdown-writer");
+
+ return markdown.writer();
+ }
+ else {
+ return simpleWriter();
+ }
+}
+
+
+var indentedElements = {
+ div: true,
+ p: true,
+ ul: true
+};
+
+
+function prettyWriter() {
+ var indentationLevel = 0;
+ var indentation = " ";
+ var stack = [];
+ var start = true;
+ var inText = false;
+
+ var writer = simpleWriter();
+
+ function open(tagName, attributes) {
+ indent();
+ stack.push(tagName);
+ writer.open(tagName, attributes);
+ if (indentedElements[tagName]) {
+ indentationLevel++;
+ }
+ start = false;
+ }
+
+ function close(tagName) {
+ if (indentedElements[tagName]) {
+ indentationLevel--;
+ }
+ indent();
+ stack.pop();
+ writer.close(tagName);
+ }
+
+ function text(value) {
+ startText();
+ writer.text(value.replace("\n", "\n" + indentation));
+ }
+
+ function selfClosing(tagName, attributes) {
+ indent();
+ writer.selfClosing(tagName, attributes);
+ }
+
+ function append(html) {
+ startText();
+ writer.append(html.replace("\n", "\n" + indentation));
+ }
+
+ function insideIndentedElement() {
+ return stack.length === 0 || indentedElements[stack[stack.length - 1]];
+ }
+
+ function startText() {
+ if (!inText) {
+ indent();
+ inText = true;
+ }
+ }
+
+ function indent() {
+ inText = false;
+ if (!start && insideIndentedElement()) {
+ writer.append("\n");
+ for (var i = 0; i < indentationLevel; i++) {
+ writer.append(indentation);
+ }
+ }
+ }
+
+ return {
+ asString: writer.asString,
+ open: open,
+ close: close,
+ text: text,
+ selfClosing: selfClosing,
+ append: append
+ };
+}
+
+
+function simpleWriter() {
+ var fragments = [];
+
+ function open(tagName, attributes) {
+ var attributeString = generateAttributeString(attributes);
+ fragments.push(util.format("<%s%s>", tagName, attributeString));
+ }
+
+ function close(tagName) {
+ fragments.push(util.format("</%s>", tagName));
+ }
+
+ function selfClosing(tagName, attributes) {
+ var attributeString = generateAttributeString(attributes);
+ fragments.push(util.format("<%s%s />", tagName, attributeString));
+ }
+
+ function generateAttributeString(attributes) {
+ return _.map(attributes, function(value, key) {
+ return util.format(' %s="%s"', key, escapeHtml(value));
+ }).join("");
+ }
+
+ function text(value) {
+ fragments.push(escapeHtml(value));
+ }
+
+ function append(html) {
+ fragments.push(html);
+ }
+
+ function asString() {
+ return fragments.join("");
+ }
+
+ return {
+ asString: asString,
+ open: open,
+ close: close,
+ text: text,
+ selfClosing: selfClosing,
+ append: append
+ };
+}
+
+
+function escapeHtml(value) {
+ return value
+ .replace(/&/g, '&amp;')
+ .replace(/"/g, '&quot;')
+ .replace(/</g, '&lt;')
+ .replace(/>/g, '&gt;');
+}