aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorStoo <stoo.goff@gmail.com>2015-02-02 15:34:04 +0000
committerMichael Williamson <mike@zwobble.org>2015-02-04 18:27:51 +0000
commite6ebb8bb83127695084ce7e0fc78047fa0d76de0 (patch)
tree4db9bed1bd7734d99cd6b3fd3c69685ec23b09a0 /lib
parentbfe6bd131845138fe09a97e7471c4b68ef42a763 (diff)
Added test cases for markdown-writer and fixed bugs which arose
Diffstat (limited to 'lib')
-rw-r--r--lib/markdown-writer.js98
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 {