Created
January 9, 2020 08:38
-
-
Save rsp9u/c600fc0f25707a630bef9bbe925d1c0b to your computer and use it in GitHub Desktop.
Convertor for drawing a plantuml gantt chart with new syntax in Growi. This should be added to Custom Script.
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
@startgantt | |
project starts the 2020/1/1 | |
-- milestones -- | |
[マイルストーンA] as msA | |
[マイルストーンB] as msB | |
[マイルストーンC] as msC | |
-- tasks -- | |
[タスク1] as task1 | |
[タスク2] as task2 | |
[タスク3] as task3 | |
-- マイルストーン -- | |
msA | |
>! 2020/1/1 | |
.! 2020/1/1 | |
msB | |
>! 2020/1/3 | |
.! 2020/1/4 | |
msC | |
>! 2020/1/5 | |
-- タスク -- | |
task1 | |
>> 2020/1/1 | |
>= 10 days @bob | |
.> 2020/1/2 | |
.= 9 days | |
task2 | |
>> task1's end | |
>= 5 days @alice | |
task3 | |
>> task2's end | |
>< 2020/1/6 | |
@endgantt |
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
function extractGanttContents(plantstr) { | |
var arr = [...plantstr.matchAll(/^@startgantt$[\s\S]+?^@endgantt$/gm)]; | |
return arr.map(function (x) {return x[0]}); | |
} | |
function extractTasksOrMilestones(identity, ganttstr) { | |
let r = []; | |
let rm = []; | |
let b = false; | |
for (var line of ganttstr.split("\n")) { | |
if (line === `-- ${identity} --`) { | |
b = true; | |
} else if (b === true && line.startsWith("--")) { | |
b = false; | |
rm.push(line); | |
} else if (b === true) { | |
var sp = line.split(/\s+/); | |
if (sp.length === 3 && sp[1] === "as") { | |
r.push({text: sp[0], alias: sp[2]}); | |
} | |
} else { | |
rm.push(line); | |
} | |
} | |
return { | |
list: r, | |
removed: rm.join("\n"), | |
} | |
} | |
function joinChildren(ganttstr) { | |
var ret = []; | |
var prev = ""; | |
var b = false; | |
for (var line of ganttstr.split("\n")) { | |
if (line.startsWith(" ")) { | |
if (b === false) { | |
ret = ret.slice(0, -1); | |
b = true; | |
} | |
ret.push([prev, line.trim()].join(" ")); | |
} else { | |
ret.push(line); | |
b = false; | |
prev = line; | |
} | |
} | |
return ret.join("\n"); | |
} | |
function replaceVerbs(ganttstr) { | |
var ret = []; | |
for (var line of ganttstr.split("\n")) { | |
var col = line.split(/\s+/); | |
if (col.length < 2) { | |
continue; | |
} | |
if (col[1].startsWith(".")) { | |
col[0] = col[0].slice(0, -1) + " ]"; | |
var colored = col[0] + " is colored in Violet/DarkViolet"; | |
if (!ret.includes(colored)) { | |
ret.push(colored); | |
} | |
} | |
if (col[1].startsWith(">")) { | |
var colored = col[0] + " is colored in GreenYellow/Green"; | |
if (!ret.includes(colored)) { | |
ret.push(colored); | |
} | |
} | |
if (col[1].startsWith(">=") || col[1].startsWith(">>") || col[1].startsWith("><")) { | |
if (line.includes("@")) { | |
var i = 0; | |
for (var c of col) { | |
if (c.startsWith("@")) { | |
col[0] += ` on {${c.slice(1)}}`; | |
break; | |
} | |
i += 1; | |
} | |
col.splice(i, 1); | |
} | |
} | |
if (col[1].match(/[>.]!/)) { | |
var s = [col[0], "happens at"]; | |
Array.prototype.push.apply(s, col.slice(2)); | |
ret.push(s.join(" ")); | |
} else if (col[1].match(/[>.]=/)) { | |
var s = [col[0], "lasts"]; | |
Array.prototype.push.apply(s, col.slice(2)); | |
ret.push(s.join(" ")); | |
} else if (col[1].match(/[>.]>/)) { | |
var s = [col[0], "starts at"]; | |
Array.prototype.push.apply(s, col.slice(2)); | |
ret.push(s.join(" ")); | |
} else if (col[1].match(/[>.]</)) { | |
var s = [col[0], "ends at"]; | |
Array.prototype.push.apply(s, col.slice(2)); | |
ret.push(s.join(" ")); | |
} else { | |
ret.push(line); | |
} | |
} | |
return ret.join("\n"); | |
} | |
function convertGantt(plantstr) { | |
var ret = plantstr; | |
var contents = extractGanttContents(plantstr); | |
for (var c of contents) { | |
var tasks = extractTasksOrMilestones("tasks", c); | |
var milestones = extractTasksOrMilestones("milestones", tasks.removed); | |
var newC = milestones.removed; | |
// replace aliases | |
for (var task of tasks.list) { | |
var regex = new RegExp(task.alias, "g"); | |
newC = newC.replace(regex, task.text); | |
} | |
for (var milestone of milestones.list) { | |
var regex = new RegExp(milestone.alias, "g"); | |
newC = newC.replace(regex, milestone.text); | |
} | |
newC = joinChildren(newC); | |
newC = replaceVerbs(newC); | |
ret = ret.replace(c, ["@startuml", newC, "@enduml"].join("\n")); | |
} | |
ret = ret.replace(/@startgantt/, "") | |
ret = ret.replace(/@endgantt/, "") | |
return ret; | |
} | |
window.addEventListener('load', (event) => { | |
growiRenderer.preProcessors.push({process: convertGantt}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment