123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- var _ = require("underscore");
- exports.writer = writer;
- function writer(options) {
- options = options || {};
- if (options.prettyPrint) {
- return prettyWriter();
- } else {
- return simpleWriter();
- }
- }
- var indentedElements = {
- div: true,
- p: true,
- ul: true,
- li: true
- };
- function prettyWriter() {
- var indentationLevel = 0;
- var indentation = " ";
- var stack = [];
- var start = true;
- var inText = false;
- var writer = simpleWriter();
- function open(tagName, attributes) {
- if (indentedElements[tagName]) {
- 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();
- var text = isInPre() ? value : value.replace("\n", "\n" + indentation);
- writer.text(text);
- }
- function selfClosing(tagName, attributes) {
- indent();
- writer.selfClosing(tagName, attributes);
- }
- 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() && !isInPre()) {
- writer._append("\n");
- for (var i = 0; i < indentationLevel; i++) {
- writer._append(indentation);
- }
- }
- }
- function isInPre() {
- return _.some(stack, function(tagName) {
- return tagName === "pre";
- });
- }
- return {
- asString: writer.asString,
- open: open,
- close: close,
- text: text,
- selfClosing: selfClosing
- };
- }
- function simpleWriter() {
- var fragments = [];
- function open(tagName, attributes) {
- var attributeString = generateAttributeString(attributes);
- fragments.push("<" + tagName + attributeString + ">");
- }
- function close(tagName) {
- fragments.push("</" + tagName + ">");
- }
- function selfClosing(tagName, attributes) {
- var attributeString = generateAttributeString(attributes);
- fragments.push("<" + tagName + attributeString + " />");
- }
- function generateAttributeString(attributes) {
- return _.map(attributes, function(value, key) {
- return " " + key + '="' + escapeHtmlAttribute(value) + '"';
- }).join("");
- }
- function text(value) {
- fragments.push(escapeHtmlText(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 escapeHtmlText(value) {
- return value
- .replace(/&/g, '&')
- .replace(/</g, '<')
- .replace(/>/g, '>');
- }
- function escapeHtmlAttribute(value) {
- return value
- .replace(/&/g, '&')
- .replace(/"/g, '"')
- .replace(/</g, '<')
- .replace(/>/g, '>');
- }
|