forked from amebalabs/Esse
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Jira <-> Markdown convertion scripts
- Loading branch information
Showing
2 changed files
with
228 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
/** | ||
{ | ||
"id": "co.ameba.Esse.ExternalFunctions.JiraToMD", | ||
"name": "Jira to Markdown", | ||
"description": "Converts Jira markup to GitHub flavored markdown", | ||
"category":"Convert", | ||
"author":"Ameba Labs", | ||
} | ||
**/ | ||
|
||
//adopted from https://github.com/FokkeZB/J2M | ||
|
||
function main(input) { | ||
input = input.replace(/^bq\.(.*)$/gm, function (match, content) { | ||
return '> ' + content + "\n"; | ||
}); | ||
|
||
input = input.replace(/([*_])(.*)\1/g, function (match,wrapper,content) { | ||
var to = (wrapper === '*') ? '**' : '*'; | ||
return to + content + to; | ||
}); | ||
|
||
// multi-level numbered list | ||
input = input.replace(/^((?:#|-|\+|\*)+) (.*)$/gm, function (match, level, content) { | ||
var len = 2; | ||
var prefix = '1.'; | ||
if (level.length > 1) { | ||
len = parseInt((level.length - 1) * 4) + 2; | ||
} | ||
|
||
// take the last character of the level to determine the replacement | ||
var prefix = level[level.length - 1]; | ||
if (prefix == '#') prefix = '1.'; | ||
|
||
return Array(len).join(" ") + prefix + ' ' + content; | ||
}); | ||
|
||
// headers, must be after numbered lists | ||
input = input.replace(/^h([0-6])\.(.*)$/gm, function (match,level,content) { | ||
return Array(parseInt(level) + 1).join('#') + content; | ||
}); | ||
|
||
input = input.replace(/\{\{([^}]+)\}\}/g, '`$1`'); | ||
input = input.replace(/\?\?((?:.[^?]|[^?].)+)\?\?/g, '<cite>$1</cite>'); | ||
input = input.replace(/\+([^+]*)\+/g, '<ins>$1</ins>'); | ||
input = input.replace(/\^([^^]*)\^/g, '<sup>$1</sup>'); | ||
input = input.replace(/~([^~]*)~/g, '<sub>$1</sub>'); | ||
input = input.replace(/-([^-]*)-/g, '-$1-'); | ||
|
||
input = input.replace(/\{code(:([a-z]+))?\}([^]*?)\{code\}/gm, '```$2$3```'); | ||
input = input.replace(/\{quote\}([^]*)\{quote\}/gm, function(match, content) { | ||
lines = content.split(/\r?\n/gm); | ||
|
||
for (var i = 0; i < lines.length; i++) { | ||
lines[i] = '> ' + lines[i]; | ||
} | ||
|
||
return lines.join("\n"); | ||
}); | ||
|
||
// Images with alt= among their parameters | ||
input = input.replace(/!([^|\n\s]+)\|([^\n!]*)alt=([^\n!\,]+?)(,([^\n!]*))?!/g, '![$3]($1)'); | ||
// Images with just other parameters (ignore them) | ||
input = input.replace(/!([^|\n\s]+)\|([^\n!]*)!/g, '![]($1)'); | ||
// Images without any parameters or alt | ||
input = input.replace(/!([^\n\s!]+)!/g, '![]($1)'); | ||
|
||
input = input.replace(/\[([^|]+)\|(.+?)\]/g, '[$1]($2)'); | ||
input = input.replace(/\[(.+?)\]([^\(]+)/g, '<$1>$2'); | ||
|
||
input = input.replace(/{noformat}/g, '```'); | ||
input = input.replace(/{color:([^}]+)}([^]*?){color}/gm, '<span style="color:$1">$2</span>'); | ||
|
||
// Convert header rows of tables by splitting input on lines | ||
lines = input.split(/\r?\n/gm); | ||
lines_to_remove = [] | ||
for (var i = 0; i < lines.length; i++) { | ||
line_content = lines[i]; | ||
|
||
seperators = line_content.match(/\|\|/g); | ||
if (seperators != null) { | ||
lines[i] = lines[i].replace(/\|\|/g, "|"); | ||
console.log(seperators) | ||
|
||
// Add a new line to mark the header in Markdown, | ||
// we require that at least 3 -'s are between each | | ||
header_line = ""; | ||
for (var j = 0; j < seperators.length-1; j++) { | ||
header_line += "|---"; | ||
} | ||
|
||
header_line += "|"; | ||
|
||
lines.splice(i+1, 0, header_line); | ||
|
||
} | ||
} | ||
|
||
// Join the split lines back | ||
input = "" | ||
for (var i = 0; i < lines.length; i++) { | ||
input += lines[i] + "\n" | ||
} | ||
|
||
return input; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
/** | ||
{ | ||
"id": "co.ameba.Esse.ExternalFunctions.MDToJira", | ||
"name": "Markdown to Jira", | ||
"description": "Converts GitHub flavored markdown to Jira Markup", | ||
"category":"Convert", | ||
"author":"Ameba Labs", | ||
} | ||
**/ | ||
|
||
//adopted from https://github.com/FokkeZB/J2M | ||
|
||
function main(input) { | ||
// remove sections that shouldn't be recursively processed | ||
var START = 'J2MBLOCKPLACEHOLDER'; | ||
var replacementsList = []; | ||
var counter = 0; | ||
|
||
input = input.replace(/`{3,}(\w+)?((?:\n|.)+?)`{3,}/g, function(match, synt, content) { | ||
var code = '{code'; | ||
|
||
if (synt) { | ||
code += ':' + synt; | ||
} | ||
|
||
code += '}' + content + '{code}'; | ||
var key = START + counter++ + '%%'; | ||
replacementsList.push({key: key, value: code}); | ||
return key; | ||
}); | ||
|
||
input = input.replace(/`([^`]+)`/g, function(match, content) { | ||
var code = '{{'+ content + '}}'; | ||
var key = START + counter++ + '%%'; | ||
replacementsList.push({key: key, value: code}); | ||
return key; | ||
}); | ||
|
||
input = input.replace(/`([^`]+)`/g, '{{$1}}'); | ||
|
||
input = input.replace(/^(.*?)\n([=-])+$/gm, function (match,content,level) { | ||
return 'h' + (level[0] === '=' ? 1 : 2) + '. ' + content; | ||
}); | ||
|
||
input = input.replace(/^([#]+)(.*?)$/gm, function (match,level,content) { | ||
return 'h' + level.length + '.' + content; | ||
}); | ||
|
||
input = input.replace(/([*_]+)(.*?)\1/g, function (match,wrapper,content) { | ||
var to = (wrapper.length === 1) ? '_' : '*'; | ||
return to + content + to; | ||
}); | ||
|
||
// multi-level bulleted list | ||
input = input.replace(/^(\s*)- (.*)$/gm, function (match,level,content) { | ||
var len = 2; | ||
if(level.length > 0) { | ||
len = parseInt(level.length/4.0) + 2; | ||
} | ||
return Array(len).join("-") + ' ' + content; | ||
}); | ||
|
||
// multi-level numbered list | ||
input = input.replace(/^(\s+)1. (.*)$/gm, function (match, level, content) { | ||
var len = 2; | ||
if (level.length > 1) { | ||
len = parseInt(level.length / 4) + 2; | ||
} | ||
return Array(len).join("#") + ' ' + content; | ||
}); | ||
|
||
var map = { | ||
cite: '??', | ||
del: '-', | ||
ins: '+', | ||
sup: '^', | ||
sub: '~' | ||
}; | ||
|
||
input = input.replace(new RegExp('<(' + Object.keys(map).join('|') + ')>(.*?)<\/\\1>', 'g'), function (match,from,content) { | ||
//console.log(from); | ||
var to = map[from]; | ||
return to + content + to; | ||
}); | ||
|
||
input = input.replace(/<span style="color:(#[^"]+)">([^]*?)<\/span>/gm, '{color:$1}$2{color}'); | ||
|
||
input = input.replace(/~~(.*?)~~/g, '-$1-'); | ||
|
||
// Images without alt | ||
input = input.replace(/!\[\]\(([^)\n\s]+)\)/g, '!$1!'); | ||
// Images with alt | ||
input = input.replace(/!\[([^\]\n]+)\]\(([^)\n\s]+)\)/g, '!$2|alt=$1!'); | ||
|
||
input = input.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '[$1|$2]'); | ||
input = input.replace(/<([^>]+)>/g, '[$1]'); | ||
|
||
// restore extracted sections | ||
for(var i =0; i < replacementsList.length; i++){ | ||
var sub = replacementsList[i]; | ||
input = input.replace(sub["key"], sub["value"]); | ||
} | ||
|
||
// Convert header rows of tables by splitting input on lines | ||
lines = input.split(/\r?\n/gm); | ||
lines_to_remove = [] | ||
for (var i = 0; i < lines.length; i++) { | ||
line_content = lines[i]; | ||
|
||
if (line_content.match(/\|---/g) != null) { | ||
lines[i-1] = lines[i-1].replace(/\|/g, "||") | ||
lines.splice(i, 1) | ||
} | ||
} | ||
|
||
// Join the split lines back | ||
input = "" | ||
for (var i = 0; i < lines.length; i++) { | ||
input += lines[i] + "\n" | ||
} | ||
return input; | ||
} |