Last active
January 18, 2022 09:32
-
-
Save malys/bda40629445f12e5a3bcb90a81daab63 to your computer and use it in GitHub Desktop.
[Mark preprocessing] plantuml and external file insertion #md #confluence #plantuml #mark
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
/* | |
Prerequisites: | |
* Plantuml + Java | |
* Mark | |
* npm i -g zx | |
* zx markExport.mjs "password" | |
<!-- Attachment: ./release_stable.puml.png --> => generate automatically image from release_stable.puml | |
<!-- file://D:/example.js;10;12 --> => insert code snippets | |
*/ | |
const args = process.argv; | |
const password = args[3]; | |
const FOLDER = 'D:/Developpement/archi/all-modules/documentation'; | |
const PLANTUML = "D:/prog/plantuml.jar"; | |
$.verbose = false | |
const DRY_RUN = process.env.MARK_DRY_RUN; | |
let dryRun = ""; | |
if (DRY_RUN) { | |
dryRun = '--dry-run'; | |
} | |
const FILTER = process.env.MARK_FILTER; | |
const TRACE = process.env.MARK_TRACE; | |
let trace = ""; | |
if (TRACE) { | |
trace = "--trace"; | |
$.verbose = true; | |
} | |
const DEBUG = process.env.MARK_DEBUG; | |
let debug = ""; | |
if (DEBUG) { | |
debug = "--debug"; | |
$.verbose = true; | |
} | |
function escapeRegex(string) { | |
return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); | |
} | |
function getPath(root, file) { | |
if (file.startsWith(".")) { | |
//relative | |
return path.join(root, file).replace(/\\/g, '/'); | |
} else { | |
return file; | |
} | |
} | |
async function includeFile(root, content) { | |
let m; | |
const regex = /<!-- file:\/\/(.*)\W*-->/gm; | |
while ((m = regex.exec(content)) !== null) { | |
// This is necessary to avoid infinite loops with zero-width matches | |
if (m.index === regex.lastIndex) { | |
regex.lastIndex++; | |
} | |
let tag = m[1] | |
let parameters = tag.split(';'); | |
let lines; | |
let file = parameters[0].trim(); | |
let extension = path.extname(file).substring(1); | |
let contentToInsert = fs.readFileSync(getPath(path.dirname(root), file), 'utf-8'); | |
if (parameters.length > 2) { | |
let begin = parameters[1]; | |
let end = parameters[2]; | |
lines = contentToInsert.split('\n').slice(begin - 1, end - 1); | |
} else { | |
lines = contentToInsert.split('\n'); | |
} | |
const first = content.indexOf("<!-- file:\/\/" + tag); | |
let last; | |
if (content.indexOf("```" + extension, first + 1) !== -1 && Math.abs(content.indexOf("```" + extension, first + 1) - content.indexOf("-->", first + 1)) < 10) { | |
last = content.indexOf("```\n", first + 1) + 4; | |
} else { | |
last = content.indexOf("-->", first + 1) + 3; | |
} | |
if (last !== -1) { | |
const toReplace = content.substring(first, last); | |
const subst = "<!-- file://" + tag + "-->\n```" + extension + "\n" + lines.join('\n') + "\n```\n"; | |
content = content.replace(toReplace, subst); | |
} | |
//console.log(regexp, content.match(regex2),content); | |
} | |
return content; | |
} | |
async function attachment(root, content) { | |
//<!-- Attachment: <path-to-image> --> | |
let m; | |
const regex = /<!-- Attachment: (.*) -->/gm; | |
while ((m = regex.exec(content)) !== null) { | |
// This is necessary to avoid infinite loops with zero-width matches | |
if (m.index === regex.lastIndex) { | |
regex.lastIndex++; | |
} | |
let tag = path.join(path.dirname(root), m[1]); | |
if (tag.trim().endsWith(".puml.png")) { | |
let output = path.dirname(tag); | |
let fileName = path.basename(tag, ".png"); | |
let basename = path.basename(fileName, ".puml"); | |
let cmd = `java -jar "${PLANTUML}" "${path.join(output,fileName)}" -overwrite -checkmetadata -o "${output}"` | |
await $([cmd]); | |
await fs.rename(path.join(output, basename + '.png'), path.join(output, basename + '.puml.png')); | |
} | |
} | |
return content; | |
} | |
async function attachmentCheck(root, content) { | |
//<!-- Attachment: <path-to-image> --> | |
let m; | |
const regex = /<!-- Attachment: (.*) -->/gm; | |
while ((m = regex.exec(content)) !== null) { | |
// This is necessary to avoid infinite loops with zero-width matches | |
if (m.index === regex.lastIndex) { | |
regex.lastIndex++; | |
} | |
let tag = path.join(path.dirname(root), m[1]); | |
if (/\d/.test(tag)) { | |
console.error('--> Attachment has not to contain a digit ' + tag + ' <--'); | |
} | |
} | |
} | |
async function analyse(file) { | |
let content = fs.readFileSync(file, 'utf-8'); | |
let toWrite = false; | |
if (content.indexOf('<!-- file://') > -1) { | |
//Include external file | |
content = await includeFile(file, content); | |
toWrite = true || toWrite; | |
} | |
if (content.indexOf('Attachment' > -1)) { | |
//Include external file | |
await attachmentCheck(file, content); | |
toWrite = false || toWrite; | |
} | |
if (content.indexOf('.puml.png' > -1)) { | |
//Include external file | |
content = await attachment(file, content); | |
toWrite = false || toWrite; | |
} | |
if (toWrite) fs.writeFileSync(file, content); | |
} | |
(async () => { | |
cd(FOLDER) | |
let mds = await globby([FOLDER + '/**/*.md']); | |
mds = mds.filter(f => f.toUpperCase().indexOf('README') === -1); | |
mds = mds.filter(f => !f.toUpperCase().endsWith('_TMP.MD')); | |
if (FILTER) { | |
mds = mds.filter(f => f.toUpperCase().indexOf(FILTER.toUpperCase()) !== -1); | |
} | |
mds=mds.sort((a,b)=>{ | |
return a.localeCompare(b); | |
}) | |
//TODO avec filter modified files "git status -s" | |
for (let index = 0; index < mds.length; index++) { | |
let md = mds[index]; | |
await analyse(md); | |
console.info('--> Processing:' + md) | |
try { | |
cd(path.dirname(md)); | |
if (md.toUpperCase().indexOf('README') == -1) { | |
let cmd = `mark -u ${process.env.USERNAME} -b https://${process.env.CONFLUENCE} -p "${password}" -f ${md} --drop-h1 ${dryRun} ${trace} ${debug}` | |
let result = await $([cmd]); | |
console.log(result.stderr) | |
} | |
} catch (e) { | |
console.error(e); | |
} | |
} | |
if(mds.length === 0) { | |
console.log('No markdown files to process'); | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment