154 lines
5.3 KiB
JavaScript
154 lines
5.3 KiB
JavaScript
goog.loadJs('electron', () => {
|
|
|
|
goog.require('path');
|
|
goog.require('Blockly');
|
|
goog.require('Mustache');
|
|
goog.require('Mixly.Env');
|
|
goog.require('Mixly.IdGenerator');
|
|
goog.require('Mixly.Electron');
|
|
goog.provide('Mixly.Electron.WikiGenerator');
|
|
|
|
const {
|
|
Env,
|
|
IdGenerator,
|
|
Electron
|
|
} = Mixly;
|
|
const fs_extra = Mixly.require('fs-extra');
|
|
const fs = Mixly.require('fs');
|
|
|
|
class WikiGenerator {
|
|
static {
|
|
this.WIKI_PAGE_FILE = goog.readFileSync(path.join(Env.templatePath, 'markdown/wiki-page-file.md'));
|
|
this.WIKI_PAGE_DIR = goog.readFileSync(path.join(Env.templatePath, 'markdown/wiki-page-dir.md'));
|
|
}
|
|
|
|
#$xml_ = null;
|
|
#desPath_ = '';
|
|
#tree_ = [];
|
|
constructor(workspace, generator, $xml, desPath) {
|
|
this.#$xml_ = $xml;
|
|
this.#desPath_ = desPath;
|
|
this.workspace = workspace;
|
|
this.generator = generator;
|
|
}
|
|
|
|
buildTree($nodes) {
|
|
let output = [];
|
|
for (let i = 0; i < $nodes.length; i++) {
|
|
let child = {};
|
|
child.id = $nodes[i].getAttribute('id') ?? IdGenerator.generate();
|
|
if ($nodes[i].nodeName == 'CATEGORY') {
|
|
child.name = $nodes[i].getAttribute('name') ?? child.id;
|
|
child.children = this.buildTree($($nodes[i]).children());
|
|
output.push(child);
|
|
} else if ($nodes[i].nodeName == 'BLOCK') {
|
|
child.name = $nodes[i].getAttribute('type') ?? child.id;
|
|
child.children = false;
|
|
child.xml = $nodes[i].outerHTML;
|
|
output.push(child);
|
|
}
|
|
}
|
|
return output;
|
|
}
|
|
|
|
async generate() {
|
|
let output = this.buildTree(this.#$xml_.children());
|
|
fs_extra.ensureDirSync('./outputBlock/');
|
|
fs_extra.emptyDirSync('./outputBlock/');
|
|
let info = await this.generateWikiPage('./outputBlock/', {
|
|
title: 'Micropython ESP32',
|
|
order: 1
|
|
}, output);
|
|
fs_extra.outputFileSync(path.join('./outputBlock/', 'README.md'), info.md);
|
|
}
|
|
|
|
generateImage(desPath) {
|
|
return new Promise((resolve, reject) => {
|
|
Blockly.Screenshot.workspaceToSvg_(this.workspace, (datauri) => {
|
|
const base64 = datauri.replace(/^data:image\/\w+;base64,/, '');
|
|
const dataBuffer = new Buffer(base64, 'base64');
|
|
fs_extra.outputFile(desPath, dataBuffer, (error) => {
|
|
resolve(error);
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
async generateWikiPage(rootPath, parentInfo, nodes) {
|
|
let config = {
|
|
id: parentInfo.id,
|
|
title: parentInfo.title,
|
|
order: parentInfo.order
|
|
};
|
|
let blocksNum = 0;
|
|
for (let node of nodes) {
|
|
if (!node.children) {
|
|
blocksNum += 1;
|
|
}
|
|
}
|
|
config.index = !!blocksNum;
|
|
if (blocksNum) {
|
|
let blocks = [];
|
|
for (let node of nodes) {
|
|
if (node.children) {
|
|
continue;
|
|
}
|
|
this.workspace.clear();
|
|
let xmlNode = Blockly.utils.xml.textToDom(`<xml>${node.xml}</xml>`);
|
|
Blockly.Xml.domToWorkspace(xmlNode, this.workspace);
|
|
let code = this.generator.workspaceToCode(this.workspace) || '';
|
|
code = code.replace(/(_E[0-9A-F]{1}_[0-9A-F]{2}_[0-9A-F]{2})+/g, function (s) {
|
|
try {
|
|
return decodeURIComponent(s.replace(/_/g, '%'));
|
|
} catch (error) {
|
|
return s;
|
|
}
|
|
});
|
|
await this.generateImage(path.join(rootPath, '../assets', parentInfo.title, node.id + '.png'))
|
|
blocks.push({
|
|
imgPath: `./assets/${parentInfo.title}/${node.id}.png`,
|
|
code: code,
|
|
type: node.name
|
|
});
|
|
}
|
|
config.blocks = blocks;
|
|
return {
|
|
file: true,
|
|
md: Mustache.render(WikiGenerator.WIKI_PAGE_FILE, config)
|
|
};
|
|
} else {
|
|
let index = 0;
|
|
for (let i in nodes) {
|
|
if (!nodes[i].children) {
|
|
continue;
|
|
}
|
|
index += 1;
|
|
let order = String(index * 5);
|
|
let mdIndex = Array(4 - Math.min(order.length, 4)).fill('0').join('') + order;
|
|
let desPath = path.join(rootPath, mdIndex + '-' + nodes[i].id);
|
|
let info = await this.generateWikiPage(desPath, {
|
|
id: nodes[i].id,
|
|
title: nodes[i].name,
|
|
order: order,
|
|
}, nodes[i].children);
|
|
if (info.file) {
|
|
fs_extra.outputFileSync(`${desPath}.md`, info.md);
|
|
} else if (!info.isEmpty) {
|
|
fs_extra.outputFileSync(path.join(desPath, 'README.md'), info.md);
|
|
} else if (info.isEmpty) {
|
|
index -= 1;
|
|
}
|
|
}
|
|
config.blocks = [];
|
|
return {
|
|
file: false,
|
|
isEmpty: !index,
|
|
md: Mustache.render(WikiGenerator.WIKI_PAGE_DIR, config)
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
Electron.WikiGenerator = WikiGenerator;
|
|
|
|
}); |