diff options
| author | Stoo <stoo.goff@gmail.com> | 2015-02-02 15:34:04 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2015-02-04 18:27:51 +0000 |
| commit | e6ebb8bb83127695084ce7e0fc78047fa0d76de0 (patch) | |
| tree | 4db9bed1bd7734d99cd6b3fd3c69685ec23b09a0 /lib | |
| parent | bfe6bd131845138fe09a97e7471c4b68ef42a763 (diff) | |
Added test cases for markdown-writer and fixed bugs which arose
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/markdown-writer.js | 98 |
1 files changed, 72 insertions, 26 deletions
diff --git a/lib/markdown-writer.js b/lib/markdown-writer.js index 1bfa942..b63d104 100644 --- a/lib/markdown-writer.js +++ b/lib/markdown-writer.js @@ -1,55 +1,94 @@ +var _ = require("underscore"); + function mdElement(start, end) { if (end === undefined) end = start; - this.open = function(attributes) { + this.open = function(attrs) { return start; }; this.close = function() { return end; }; + + this.empty = function(attrs) { + return this.open(attrs) + this.close(); + }; } function mdLink(link, text) { var attrs = {}; this.open = function(attributes) { - attrs = attributes; + attrs = attributes || {}; + return "["; }; this.close = function() { return (attrs[text] || "") + "](" + (attrs[link] || "") + ")"; }; + + this.empty = function(attrs) { + // don't display empty content (this is mainly to remove images with no src data) + var content = this.open(attrs) + this.close(); + + if(content === "[]()") { + return ""; + } + + return content; + }; +} +function mdList() { + this.open = function(attrs) { + return attrs.indent > -1 ? "\n" : ""; + }; + + this.close = function(attrs) { + return attrs.indent > -1 ? "" : "\n"; + }; + + this.empty = function(attrs) { + return this.open(attrs) + this.close(); + }; } function mdListItem() { - this.open = function(attributes) { + this.open = function(attrs) { var output = ""; - for(var i = 0; i < attributes["indent"]; ++i) + for(var i = 0; i < attrs.indent; ++i) { output += "\t"; + } - return output + (attributes["type"] === "ul" ? "-" : attributes["count"] + ".") + " "; + return output + (attrs.type === "ul" ? "-" : attrs.count + ".") + " "; }; this.close = function() { return "\n"; }; + + this.empty = function(attrs) { + return this.open(attrs) + this.close(); + }; } // map HTML tags to Markdown syntax var htmlmd = { - "h1": new mdElement("# ", "\n\n"), - "h2": new mdElement("## ", "\n\n"), - "h3": new mdElement("### ", "\n\n"), - "h4": new mdElement("#### ", "\n\n"), - "h5": new mdElement("##### ", "\n\n"), - "h6": new mdElement("###### ", "\n\n"), - "p": new mdElement("", "\n\n"), + // paragraphs elements use three line feeds to close + // this prevents them being caught by collapsing list elements in `asString` + // while still allowing them to be collapsed when multiple empty lines are removed + "h1": new mdElement("# ", "\n\n\n"), + "h2": new mdElement("## ", "\n\n\n"), + "h3": new mdElement("### ", "\n\n\n"), + "h4": new mdElement("#### ", "\n\n\n"), + "h5": new mdElement("##### ", "\n\n\n"), + "h6": new mdElement("###### ", "\n\n\n"), + "p": new mdElement("", "\n\n\n"), "br": new mdElement("", " \n"), - "ul": new mdElement("\n", ""), - "ol": new mdElement("\n", ""), + "ul": new mdList(), + "ol": new mdList(), "li": new mdListItem(), "strong": new mdElement("**"), "em": new mdElement("*"), @@ -59,6 +98,7 @@ var htmlmd = { function mdWriter() { var fragments = []; + var listStack = []; var list = { indent: -1, type: "ul", @@ -66,21 +106,27 @@ function mdWriter() { }; function isList(tagName) { - return tagName == "ul" || tagName == "ol"; + return tagName === "ul" || tagName === "ol"; } function open(tagName, attributes) { if(htmlmd[tagName]) { - if(tagName == "li") { - attributes = attributes || {}; - attributes["indent"] = list.indent; - attributes["type"] = list.type; - attributes["count"] = ++list.count; + attributes = attributes || {}; + + if(tagName === "li") { + attributes.indent = list.indent; + attributes.type = list.type; + attributes.count = ++list.count; + } + else if(isList(tagName)) { + attributes.indent = list.indent; } fragments.push(htmlmd[tagName].open(attributes)); if(isList(tagName)) { + listStack.push(_.clone(list)); + list.type = tagName; list.indent++; list.count = 0; @@ -90,18 +136,17 @@ function mdWriter() { function close(tagName) { if(htmlmd[tagName]) { - fragments.push(htmlmd[tagName].close()); - if(isList(tagName)) { - list.indent--; + list = listStack.pop(); } + + fragments.push(htmlmd[tagName].close(list)); } } function selfClosing(tagName, attributes) { if(htmlmd[tagName]) { - fragments.push(htmlmd[tagName].open(attributes)); - fragments.push(htmlmd[tagName].close()); + fragments.push(htmlmd[tagName].empty(attributes)); } } @@ -114,7 +159,8 @@ function mdWriter() { } function asString() { - return fragments.join("").replace(/\n{2,}/, "\n\n"); + // massage the output to collapse mulitple empty lines and empty lines between nested lists + return fragments.join("").replace(/\n{2}(\t*)([2-9]\d*\.|- )/g, "\n$1$2").replace(/\n{3,}/g, "\n\n"); } return { |
