|
const fs = require("fs"); |
|
|
|
const filename = process.argv[2]; |
|
const md = fs.readFileSync(filename || 0, "utf-8"); // read file or stdin |
|
console.log(toJira(md)); |
|
|
|
function toJira(str) { |
|
var map = { |
|
//cite: '??', |
|
del: "-", |
|
ins: "+", |
|
sup: "^", |
|
sub: "~" |
|
}; |
|
|
|
return ( |
|
str |
|
// Bold, Italic, and Combined (bold+italic) |
|
.replace(/([*_]+)(\S.*?)\1/g, function(match, wrapper, content) { |
|
switch (wrapper.length) { |
|
case 1: |
|
return "_" + content + "_"; |
|
case 2: |
|
return "*" + content + "*"; |
|
case 3: |
|
return "_*" + content + "*_"; |
|
default: |
|
return wrapper + content * wrapper; |
|
} |
|
}) |
|
// All Headers (# format) |
|
.replace(/^([#]+)(.*?)$/gm, function(match, level, content) { |
|
return "h" + level.length + "." + content; |
|
}) |
|
// Headers (H1 and H2 underlines) |
|
.replace(/^(.*?)\n([=-]+)$/gm, function(match, content, level) { |
|
return "h" + (level[0] === "=" ? 1 : 2) + ". " + content; |
|
}) |
|
// Ordered lists |
|
.replace(/^([ \t]*)\d+\.\s+/gm, function(match, spaces) { |
|
return Array(Math.floor(spaces.length / 2 + 1)).join("#") + "# "; |
|
}) |
|
// Un-Ordered Lists |
|
.replace(/^([ \t]*)\*\s+/gm, function(match, spaces) { |
|
return Array(Math.floor(spaces.length / 2 + 1)).join("*") + "* "; |
|
}) |
|
// Headers (h1 or h2) (lines "underlined" by ---- or =====) |
|
// Citations, Inserts, Subscripts, Superscripts, and Strikethroughs |
|
.replace( |
|
new RegExp("<(" + Object.keys(map).join("|") + ")>(.*?)</\\1>", "g"), |
|
function(match, from, content) { |
|
var to = map[from]; |
|
return to + content + to; |
|
} |
|
) |
|
// Other kind of strikethrough |
|
.replace(/\s+~~(.*?)~~\s+/g, " -$1- ") |
|
// Named/Un-Named Code Block |
|
.replace(/`{3,}(\w+)?((?:\n|[^`])+)`{3,}/g, function( |
|
match, |
|
synt, |
|
content |
|
) { |
|
var code = "{code"; |
|
if (synt) code += ":" + synt; |
|
return code + "}" + content + "{code}"; |
|
}) |
|
// Inline-Preformatted Text |
|
.replace(/`([^`]+)`/g, "{{$1}}") |
|
// Named Link |
|
.replace(/\[([^\]]+)\]\(([^)]+)\)/g, "[$1|$2]") |
|
// Un-Named Link |
|
.replace(/<([^>]+)>/g, "[$1]") |
|
// Single Paragraph Blockquote |
|
.replace(/^>/gm, "bq.") |
|
// tables |
|
.replace( |
|
/^\n((?:\|.*?)+\|)[ \t]*\n((?:\|\s*?\-{3,}\s*?)+\|)[ \t]*\n((?:(?:\|.*?)+\|[ \t]*\n)*)$/gm, |
|
function(match, headerLine, separatorLine, rowstr) { |
|
var headers = headerLine.match(/[^|]+(?=\|)/g); |
|
var separators = separatorLine.match(/[^|]+(?=\|)/g); |
|
if (headers.length !== separators.length) { |
|
return match; |
|
} |
|
var rows = rowstr.split("\n"); |
|
if (rows.length === 1 + 1 && headers.length === 1) { |
|
// panel |
|
return ( |
|
"{panel:title=" + |
|
headers[0].trim() + |
|
"}\n" + |
|
rowstr.replace(/^\|(.*)[ \t]*\|/, "$1").trim() + |
|
"\n{panel}\n" |
|
); |
|
} else { |
|
return "||" + headers.join("||") + "||\n" + rowstr; |
|
} |
|
} |
|
) |
|
); |
|
}; |