JArchi Scripting: Export to Markdown

I discovered and fell in love (a bit) with Markdown whilst working for the University of Sussex. My previous employer (which is now my current employer, long story) used Google Drive/Docs, and the University subscribed to Office 365. I ended up getting particularly frustrated with having to go back and use Microsoft Word, so decided to go back to basics (plus, Markdown feels techy, and I miss being a “proper” techie). Markdown allows you to style and structure a plain text file, it’s a useful tool to write in a simple way, concentrating on the content, not the design. I use Microsoft Visual Code Studio to write/preview Markdown, although other editors are available.

JArchi is the scripting language for Archi, the open source, open implementation of the ArchiMate language. Users can download JArchi by supporting Archi on Patreon. It allows a user to develop JavaScript like scripts to interact with an Archi model.

I had been looking at how I can produce documentation directly from Archi, rather than have to copy and paste and manually write the documentation, and was exploring what I could achieve when combining Markdown, Archi and JArchi.

I have developed a JArchi script to Export to Markdown, and have uploaded this to GitHub Gists.

Currently sitting at version 3.4 (at the time of writing this), this script will:

  • iterate through each element added to a view to build a table of contents,
  • export a PNG,
  • include the content of any “note” elements which don’t have relationships to other elements as an Introduction
  • iterate through each element (again) to:
    • use the name of the element and it’s type as a header
    • build a table of all properties on the element,
    • build a table of all relationships on the element, their types and hyperlinks to their related elements (as well as name and documentation on the links),
    • include the element’s documentation,
    • include any related “note” elements as quotes and then
    • iterate through any nested elements.
  • prompt the user to save the files in a location of their choosing.

It’s probably (definitely) not the most efficient code out there, but it does the job! Hopefully others may find it useful.

Example Output

Export to Markdown[^1]

Introduction

Export to Markdown

Export to Markdown: JArchi Script Example

Export to Markdown.ajs <<Script>> (Artifact)

Relationships

From Relationship To Name Description
Export to Markdown.ajs <<Script>> Realization Relationship [archi] Export to Markdown (Application Function)

C:\Users\steve\AppData\Roaming\Archi4\scripts\Import-Export\Export to Markdown.ajs

Can be downloaded from Github Gist:

[archi] jArchi Plugin (Application Function)

Properties

Website Licence
https://www.archimatetool.com/blog/2018/07/02/jarchi/ Open Source (HUMANS)

Relationships

From Relationship To Name Description
[archi] jArchi Plugin Composition Relationship [archi] Export to Markdown (Application Function)
[archi] jArchi Plugin Influence Relationship Support Archi on Patreon (Requirement)

jArchi is a JavaScript-based scripting plug-in built on the Nashorn engine. This means that the end-user can write code, or simple scripts, using JavaScript, and this is then translated into the underlying Java code that drives Archi.

jArchi Plugin <<Software>> (Artifact)

Relationships

From Relationship To Name Description
jArchi Plugin <<Software>> Realization Relationship [archi] jArchi Plugin (Application Function)

C:\Program Files\Archi4\plugins\com.archimatetool.script.commandline_0.4.3.201902121146.jar C:\Program Files\Archi4\plugins\com.archimatetool.script.premium_0.4.1.201902121146.jar C:\Program Files\Archi4\plugins\com.archimatetool.script_0.4.3.201902121146.jar

[archi] Export to Markdown (Application Function)

Properties

Website Licence
https://gist.github.com/smileham/578bbbb88dc0ed5a1403f3b98711ec25 Open Source

Relationships

From Relationship To Name Description
[archi] Export to Markdown Access Relationship Export to Markdown.md <<Markdown>> (Artifact)
[archi] Export to Markdown Access Relationship Export to Markdown.png <<Image>> (Artifact)
[archi] Export to Markdown Influence Relationship Automatic documentation generation (Goal)

Microsoft VSCode (Application Component)

Properties

Website Licence
https://code.visualstudio.com/ Open Source (MIT)

Relationships

From Relationship To Name Description
Microsoft VSCode Access Relationship Export to Markdown.md <<Markdown>> (Artifact)
Microsoft VSCode Access Relationship Export to Markdown.png <<Image>> (Artifact)

Visual Studio Code is a streamlined code editor with support for development operations like debugging, task running and version control. It aims to provide just the tools a developer needs for a quick code-build-debug cycle and leaves more complex workflows to fuller featured IDEs.

MS VSCode <<Software>> (Artifact)

Relationships

From Relationship To Name Description
MS VSCode <<Software>> Realization Relationship Microsoft VSCode (Application Component)

C:\Program Files\Microsoft VS Code

Automatic documentation generation (Goal)

Support Archi on Patreon (Requirement)

Only supporters of ArchiTool on Patreon can access the binary download of the jArchi plugin (as well as other exclusive content)

Documentation <<Folder>> (Artifact)

Relationships

From Relationship To Name Description
Documentation <<Folder>> Composition Relationship Export to Markdown.png <<Image>> (Artifact)
Documentation <<Folder>> Composition Relationship Export to Markdown.md <<Markdown>> (Artifact)

Local folder to store EA documentation.

Export to Markdown.md <<Markdown>> (Artifact)

Markdown formatted documentation of the Export to Markdown Archi view.

Export to Markdown.png <<Image>> (Artifact)

PNG format image of Export to Markdown Archi view.

Core Archi (Diagram Model Group)

Develop Enterprise Architecture Model (Business Process)

[archi] Archi 4.3.3 (Application Component)

Properties

Website Licence
https://www.archimatetool.com/ Open Source (MIT)

Relationships

From Relationship To Name Description
[archi] Archi 4.3.3 Assignment Relationship [archi] jArchi Plugin (Application Function) Plugin
[archi] Archi 4.3.3 Serving Relationship Develop Enterprise Architecture Model (Business Process)

Archi fulfils the needs of most Enterprise Architects and associated stakeholders, and has been designed to elegantly provide the main features required for ArchiMate modelling and is used globally by banks, insurance companies, industry, EA consultants, training organisations, universities, and students. It is the world’s most popular ArchiMate modelling tool and is downloaded between two and three thousand times every month.

Desktop Computer (Device)

Relationships

From Relationship To Name Description
Desktop Computer Assignment Relationship Archi 4.3.3 <<Software>> (Artifact)
Desktop Computer Assignment Relationship jArchi Plugin <<Software>> (Artifact)
Desktop Computer Assignment Relationship Export to Markdown.ajs <<Script>> (Artifact)
Desktop Computer Assignment Relationship MS VSCode <<Software>> (Artifact)
Desktop Computer Assignment Relationship Documentation <<Folder>> (Artifact)

A device is a physical IT resource upon which system software and artifacts may be stored or deployed for execution. — ArchiMate 3

Smileham: The usage of ArchiMate and Archi models should be derived from the questions that you want to answer. When I first began modelling, I wanted to seperate the logical server (node) from the physical or virtual server (device) on which they were executing. This seperation allows an architect to query the model to find where all particular makes/models/configurations of physical devices are used in the architecture.

Archi 4.3.3 <<Software>> (Artifact)

Relationships

From Relationship To Name Description
Archi 4.3.3 <<Software>> Realization Relationship [archi] Archi 4.3.3 (Application Component)

C:\Program Files\Archi4

[^1]: Generated: Sat Mar 09 2019 19:56:49 GMT+0000 (GMT)

Code

/*
* Export View to Markdown
*
* Requires jArchi – https://www.archimatetool.com/blog/2018/07/02/jarchi/
*
* Markdown – https://www.markdownguide.org/
*
* Version 2: Updated to support Diagram Groups
* Version 2.1: Add check for Selected View
* Version 2.2: Change to regex, added date of export
* Version 2.3: Include notes in documentation
* Version 3: Updated to include Relationships
* Version 3.1: Include name and description
* Version 3.2: Support repeated elements
* Version 3.3: Fix for relationships table
* Version 3.4: Fix for connected notes,
* Quotes in documenation,
* Embed view (experimental)
* Version 3.5: Added support for jArchi 4.4 (additional attributes)
* Version 3.6: Added support for Label Values and fixed issue with CR/LF in tables.
* Version 3.7: Added support for multiple views to be exported & fix for comments
* Version 3.8: Added support for specializations, refactored to improve code.
* Version 3.9: Added support for Index and ViewTypes
* Version 4: Added support to include "hidden" relationships
* Version 5: Added support for "Layering"
* Version 6: Added support for external Gemini AI script – https://gist.github.com/smileham/8cbb3116db7f0ee80bcab4f1a57d14a8
* Version 6.1: Include "Used in Views" as option, Replaced Options Screen, Enable multiple exports.
* Version 6.2: Fix for "Junction" components
* Version 6.2.1: Include "UID" against components.
* Version 6.2.2: Include "UID" for relationships.
* Verison 6.3: Added option to make TOC optional.
*
* (c) 2025 Steven Mileham
*
*/
console.show();
console.clear();
console.log("Export to Markdown");
const strategyLayer = {"label":"Strategy", "components":["resource","capability","course-of-action","value-stream"]};
const motivationLayer = {"label":"Motivation","components":["stakeholder","driver","assessment","goal","outcome","principle","requirement","constraint","meaning","value"]};
const migrationLayer = {"label":"Implementation and Migration", "components":["work-package","deliverable","implementation-event","plateau","gap"]};
const businessLayer ={"label":"Business", "components":["business-actor", "business-role","business-collaboration","business-interface","business-process","business-function","business-interaction", "business-event", "business-service", "contract", "product", "representation"]};
const dataLayer = {"label":"Data","components":["business-object", "data-object", "artifact"]};
const applicationLayer = {"label":"Application", "components":["application-component","application-collaboration","application-interface","application-function","application-process","application-interaction", "application-event", "application-service"]};
const technologyLayer = {"label":"Technology", "components":["node","device", "system-software", "technology-collaboration", "technology-interface","path", "communication-network", "technology-function", "technology-process", "technology-interaction", "technology-event", "technology-service", "equipment", "facility","location", "distribution-network", "material"]};
const layers = [migrationLayer,strategyLayer,motivationLayer,businessLayer,dataLayer, applicationLayer, technologyLayer];
function listSelection(title, choices) {
var ListSelectionDialog = Java.type("org.eclipse.ui.dialogs.ListSelectionDialog");
var LabelProvider = Java.type('org.eclipse.jface.viewers.LabelProvider');
var ArrayContentProvider = Java.type('org.eclipse.jface.viewers.ArrayContentProvider');
var dialog = new ListSelectionDialog(shell, choices, ArrayContentProvider.getInstance(),
new LabelProvider(), title);
dialog.open();
result = dialog.getResult();
return result ? new String(result) : null;
}
function executeMarkdownScript() {
let theOptions =["Include TOC","Embed Image in Markdown", "Generate Layered Document", "Include Hidden Relationships", "Include Component View List", "Include UID for Components"];
const theViews = $(selection).filter("archimate-diagram-model");
if (!theViews || theViews.length==0) {
console.log("> Please Select a View");
exit();
}
const multiMode = theViews.length>1;
if (multiMode) {
theOptions.push("Generate a Single Document from the selected views");
}
const options = listSelection("Options", theOptions);
if (options == null) {
console.log("Options dialog cancelled. Exiting.");
exit();
}
const embed = options.includes("Embed");
const layered = options.includes("Layered");
const includeHiddenRelationships = options.includes("Hidden");
const showViews = options.includes("View");
const singleDoc = options.includes("Single");
const inclObjUID = options.includes("UID for Components");
const inclTOC = options.includes("TOC");
let megaDoc = "";
const theIndexMap = new Map();
theViews.each(function(theView){
console.log("Exporting View:"+theView);
theDocument = "";
let markdownContent = generateMarkdown(theView, includeHiddenRelationships, layered,embed, showViews, inclObjUID, inclTOC);
if (!singleDoc) {
let theFilename = saveMarkdownToFile(theView, markdownContent,embed);
if (multiMode) {
theIndexMap.set(theView.name,theFilename);
}
}
else {
megaDoc += `${markdownContent}\n—\n`;
}
});
if (multiMode) {
if (singleDoc) {
saveIndexToFile(megaDoc);
}
else {
const theIndex = generateIndex(theIndexMap);
saveIndexToFile(theIndex);
}
}
}
function _getPath(theComponent) {
var theParent = $(theComponent).parent()[0];
if (theParent && theParent.name) {
return `${_getPath(theParent)}\\${theComponent.name}`;
}
else {
return theComponent.name;
}
}
function _usedInViews(element) {
let viewContent = "**Used In Views**\n\n"
let theViews = $(element.concept).viewRefs();
theViews.each(function (theView) {
viewContent += `* ${_getPath(theView)}/${theView.name}\n`;
});
return viewContent;
}
function generateIndex(theIndexMap) {
theIndexMarkdown = `# ${model.name} Export[^1]\n`;
theIndexMap.forEach(function (value, key, map) {
if (value!=null) {
theIndexMarkdown += `* [${_escapeMD(key)}](${generateIndexLink(value)})\n`;
}
})
theIndexMarkdown+=`\n[^1]: Generated: ${new Date().toLocaleString()}\n`;
return theIndexMarkdown;
}
function convertToText(type) {
return type.replaceAll("-", " ").split(" ").map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(" ").trim();
}
function _escapeMD(str) {
return str.replaceAll("<", "&lt;").replaceAll("\n>", "\n~QUOTE~").substring(0, 1) + str.substring(1).replaceAll(">", "&gt;").replaceAll("~QUOTE~", ">");
}
function generateLink(str) {
return `#${str.toLowerCase().replace(/[\[\]\(\)\#\\\/\"]/gi, "").replaceAll(" ", "-").replaceAll("\<", "lt").replaceAll("\>", "gt")}`;
}
function _escapeCR(str) {
return str.replaceAll("\r\n", "<br>").replaceAll("\n", "<br>").replaceAll("\r", "<br>");
}
function generateIndexLink(str) {
return str.replaceAll(" ","%20");
}
function generateToc(element, depth, tocMap, tocContentWrapper) {
let theComponents = _sortComponents($(element).children().not("relationship"));
theComponents.each(function (e) {
if (e.name) {
let headerDepth = " ".repeat(depth);
const conceptText = convertToText(`${e.type}`);
let theHash = generateLink(`${e.name} (${conceptText})`);
tocMap[theHash] = (tocMap[theHash] || 0) + 1;
const linkNum = tocMap[theHash] > 1 ? `-${tocMap[theHash]}` : "";
tocContentWrapper.str += `\n${headerDepth}* [${_escapeMD(e.name)} (${conceptText})${linkNum.replace("\-", " ")}](${theHash}${linkNum})`;
if ($(e).children().not("relationship").length > 0) {
generateToc(e, depth + 1, tocMap, tocContentWrapper);
}
}
});
}
function generateLayeredToc (layers, tocContentWrapper) {
layers.forEach(function (layer){
tocContentWrapper.str += `\n* [${layer.label} Architecture](#${layer.label}%20Architecture)`;
});
}
function generatePropertiesTable(element, inclObjUID) {
const props = element.prop();
const sortedProperties = […props].sort();
let header = "|", line = "|", body = "|";
if (inclObjUID) {
header += "UID|";
line += "—|";
body += `${element.concept !=null? element.concept.id:element.id}|`;
}
if (element.specialization) {
header += "Specialization|";
line += "—|";
body += `${element.specialization}|`;
}
for (const prop of sortedProperties) {
header += `${prop}|`;
line += "—|";
body += `${element.prop(prop)}|`;
}
return `**Properties**\n\n${header}\n${line}\n${body}\n`;
}
function _contains(element, collection) {
let response = false;
collection.each(function (e) {
if (e.type !== "diagram-model-connection" && e.concept.id == element.concept.id) {
response = true;
}
});
return response
}
function _relationshipRow(element, includeHidden, viewRels, inclObjUID){
let table ="";
if (includeHidden) {
hiddenElement = !_contains(element,viewRels);
}
else {
hiddenElement = false;
}
if ((includeHidden && hiddenElement) || !hiddenElement) {
if (element.type !== "diagram-model-connection") {
let row = `|${element.source.name} (${convertToText(element.source.type)})|${convertToText(element.type)}`;
if (inclObjUID) row = `|${element.concept !=null? element.concept.id:element.id}${row}`;
if (element.concept.accessType) row += ` (${element.concept.accessType})`;
if (element.concept.influenceStrength) row += ` (${element.concept.influenceStrength})`;
if (element.concept.specialization) row += ` «${element.concept.specialization}»`;
row += `${hiddenElement?" (Hidden)":""}|[${_escapeMD(element.target.name)} (${convertToText(element.target.type)})](${generateLink(`${element.target.name} (${convertToText(element.target.type)})`)})|${element.labelValue ? element.labelValue.replaceAll("\\n", " ").replaceAll("\\r", " ") : element.name}|${element.documentation.replaceAll("\n", " ").replaceAll("\r", " ")}|\n`;
table += row;
}
}
return table
}
function generateRelationshipsTable(element, includeHidden, inclObjUID) {
let header = "|From|Relationship|To|Name/Label|Description|";
let line = "|—|—|—|—|—|";
if (inclObjUID) {
header = `|UID${header}`;
line += "—|";
}
let table = `${header}\n${line}\n`;
if (includeHidden) {
viewRelationships = $(element).rels();
allRelationships = $(element.concept).rels();
}
else {
allRelationships = $(element).rels();
viewRelationships = allRelationships;
}
//console.log(allRelationships);
allRelationships.each(function (r) {
table+= _relationshipRow(r, includeHidden, viewRelationships, inclObjUID);
});
return `**Relationships**\n\n${table}`;
}
function generateNestedDocumentation(element, depth, bodyMap, documentContentWrapper, includeHiddenRelationships, showViews, inclObjUID) {
// console.log(`${element}`);
let theNotes = _sortComponents($(element).children("diagram-model-note"));
theNotes.each(function (e) {
if ($(e).rels().length === 0) {
documentContentWrapper.str += `\n> ${_escapeMD(e.text).replaceAll("\n", "\n> ")}\n`;
}
});
let theComponents = _sortComponents($(element).children().not("relationship"));
theComponents.each(function (e) {
// console.log(`CHILD: ${e}`);
if (e.name) {
const headerDepth = "#".repeat(depth + 2);
const conceptText = convertToText(`${e.type}`);
let theHash = generateLink(`${e.name} (${conceptText})`);
bodyMap[theHash] = (bodyMap[theHash] || 0) + 1;
const linkNum = bodyMap[theHash] > 1 ? ` ${bodyMap[theHash]}` : "";
documentContentWrapper.str += `\n${headerDepth} ${_escapeMD(e.name)} (${conceptText})${linkNum}\n`;
if (e.documentation) {
documentContentWrapper.str += `\n${_escapeMD(e.documentation)}\n`;
}
if (e.type=='junction') {
documentContentWrapper.str += `\nType: ${e.concept.getJunctionType()}\n`;
}
if (e.prop().length > 0 || e.specialization || inclObjUID) {
documentContentWrapper.str += `\n${_escapeMD(generatePropertiesTable(e, inclObjUID))}`;
}
if ($(e).outRels().length > 0 || ($(e.concept).rels().length > 0 && includeHiddenRelationships) ) {
documentContentWrapper.str += `\n${_escapeMD(generateRelationshipsTable(e, includeHiddenRelationships, inclObjUID))}`;
}
$(e).rels().ends().each(function (r) {
if (r.text) {
documentContentWrapper.str += `\n> ${_escapeMD(r.text).replaceAll("\n", "\n> ")}\n`;
}
});
if (showViews) {
documentContentWrapper.str += `\n${_usedInViews(e)}`;
}
if ($(e).children().length > 0) {
generateNestedDocumentation(e, depth + 1, bodyMap, documentContentWrapper, includeHiddenRelationships,showViews, inclObjUID);
}
}
});
}
function generateIntroduction(view) {
let theIntroduction = "";
// Notes with no relationships
$(view).find("diagram-model-note").each(function (note){
if ($(note).rels().length==0 && note.text.length()>3 && $(note).parent.type=="archimate-diagram-model"){
theIntroduction += `\n> ${_escapeMD(note.text).replaceAll("\n", "\n> ")}\n`;
}
});
return theIntroduction;
}
const generateMarkdown = (view, includeHiddenRelationships, layered, embed, showViews, inclObjUID, inclTOC) => {
let bodyMap = {};
let documentContentWrapper = {str: `# ${view.name}[^1]\nFolder: ${_getPath(view)}\n`};
// Javascript will pass an object reference!
let tocContentWrapper = {str:"* [Introduction](#introduction)"};
//toc(0,theView);
let tocMap = {};
if (inclTOC) {
if (!layered) {
generateToc(view,0,tocMap,tocContentWrapper);
}
else {
generateLayeredToc(layers, tocContentWrapper);
}
documentContentWrapper.str += `\n## Table of Contents\n${tocContentWrapper.str}\n\n## Introduction\n`;
}
else
{
documentContentWrapper.str += `\n## Introduction\n`;
}
if (embed) {
const bytes = $.model.renderViewAsBase64(view, "PNG", { scale: 2, margin: 10 });
documentContentWrapper.str += `\n![${view.name}](data:image/png;base64,${bytes})\n`;
} else {
documentContentWrapper.str += `\n![${view.name}][embedView]\n`;
}
if (view.documentation) {
documentContentWrapper.str += `\n${_escapeMD(view.documentation)}\n`;
}
if (view.viewpoint && view.viewpoint.name!="None") {
documentContentWrapper.str+= `Viewpoint: ${view.viewpoint.name}\n`;
}
documentContentWrapper.str+= generateIntroduction(view);
if (!layered) {
generateNestedDocumentation(view, 0, bodyMap, documentContentWrapper, includeHiddenRelationships,showViews, inclObjUID);
}
else {
generateLayeredDocumentation(view, documentContentWrapper);
}
documentContentWrapper.str+=`\n[^1]: Generated: ${new Date().toLocaleString()}\n`;
return documentContentWrapper.str;
}
function generateLayeredDocumentation(view, documentContentWrapper) {
let theLayer="";
layers.forEach(function (layer){
theTable= generateComponentTable(layer.components, view);
if (theTable!="") {
theLayer +=`\n## ${layer.label} Architecture\n\n${theTable}`;
}
});
documentContentWrapper.str+=theLayer;
//console.log(`${documentContentWrapper.str}`);
}
function _sortComponents(collection) {
collection.sort(function(a, b) {
// Access the 'name' property of each element and use localeCompare for string sorting
return a.name.localeCompare(b.name);
});
return collection;
}
function _uniqueComponents(collection) {
let uniqueCollection = new Map();
collection.forEach(function(component) {
if (uniqueCollection.get(`${component.name}:${component.type}`)==null){
uniqueCollection.set(`${component.name}:${component.type}`,component);
}
});
return uniqueCollection;
}
function generateComponentTable(layer, view) {
const theHeader ="|Component|Type|Description|\n|—|—|—|\n";
const theHeaderWithNotes ="|Component|Type|Description|Notes|\n|—|—|—|—|\n";
let theTable ="";
let includesNotes = false;
layer.forEach(function(component) {
components = $(view).find(component);
let sortedComponents = _sortComponents(components);
let uniqueComponents = _uniqueComponents(sortedComponents);
uniqueComponents.forEach(function (e) {
let notes = "";
$(e).rels().ends().filter("diagram-model-note").each(function (note){
notes+=note.text+"\n";
includesNotes=true;
})
theTable += `|${_escapeMD(e.name)}|${convertToText(e.type)}${e.specialization!=null?" «"+e.specialization+"»":""}|${_escapeCR(_escapeMD(e.documentation))}|${notes!=""?_escapeCR(_escapeMD(notes))+"|":""}\n`;
});
});
if (theTable!="") {
if (includesNotes){
return theHeaderWithNotes+theTable;
}
else {
return theHeader+theTable;
}
}
else {
return "";
}
}
function saveMarkdownToFile(view, markdownContent,embed) {
const defaultFileName = view.name ? `${model.name}-${view.name}.md` : "Exported View.md";
const exportFile = window.promptSaveFile({ title: "Export to Markdown", filterExtensions: ["*.md"], fileName: defaultFileName });
if(exportFile) {
if (!embed) {
const imageURL = exportFile.substring(0,exportFile.length-3).replaceAll(" ","%20")+".png";
const relativeURL = imageURL.split("\\");
var bytes = $.model.renderViewAsBase64(view, "PNG", {scale: 2, margin: 10});
$.fs.writeFile(exportFile.substring(0,exportFile.length-3) +".png", bytes, "BASE64");
markdownContent+=`\n[embedView]: ${relativeURL[relativeURL.length-1]}`;
}
$.fs.writeFile(exportFile, markdownContent);
console.log("> Export done");
return exportFile;
}
else {
console.log("> Export cancelled");
}
}
function saveIndexToFile(markdownContent) {
const defaultFileName = `${model.name}.md`;
const exportFile = window.promptSaveFile({ title: "Export to Markdown", filterExtensions: ["*.md"], fileName: defaultFileName });
if(exportFile) {
$.fs.writeFile(exportFile, markdownContent);
console.log("> Export done");
return exportFile;
}
else {
console.log("> Export cancelled");
}
}
try {
if (typeof library===undefined || !library) {
}
}
catch (e){
executeMarkdownScript();
};
module.exports=generateMarkdown;

4 comments

  1. Hello, those scripts are amazing!! just a question, do you know how debug Jarchi scripts with VS code ?

    Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.