mirror of
https://github.com/tupadr3/plantuml-icon-font-sprites.git
synced 2026-01-09 19:02:01 +00:00
feat: Integrate build into this repo
This commit is contained in:
21
.editorconfig
Normal file
21
.editorconfig
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# EditorConfig helps developers define and maintain consistent
|
||||||
|
# coding styles between different editors and IDEs
|
||||||
|
# editorconfig.org
|
||||||
|
|
||||||
|
root = true
|
||||||
|
|
||||||
|
|
||||||
|
[*]
|
||||||
|
|
||||||
|
# Change these settings to your own preference
|
||||||
|
indent_style = tab
|
||||||
|
indent_size = 4
|
||||||
|
|
||||||
|
# We recommend you to keep these unchanged
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
trim_trailing_whitespace = false
|
||||||
4
.eslintignore
Normal file
4
.eslintignore
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# and /bower_components/* ignored by default
|
||||||
|
|
||||||
|
# Ignore built files except build/index.js
|
||||||
|
/node_modules/*
|
||||||
18
.eslintrc.json
Normal file
18
.eslintrc.json
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"root": true,
|
||||||
|
"extends": "eslint:recommended",
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaVersion": 2017
|
||||||
|
},
|
||||||
|
"env": {
|
||||||
|
"node": true,
|
||||||
|
"es6": true
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"no-console": 0
|
||||||
|
},
|
||||||
|
"globals": {
|
||||||
|
"console": true,
|
||||||
|
"log": true
|
||||||
|
}
|
||||||
|
}
|
||||||
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
* text=auto
|
||||||
41
.gitignore
vendored
41
.gitignore
vendored
@@ -1,2 +1,41 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
testing
|
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# npm, yarn, build etc
|
||||||
|
.vscode
|
||||||
|
.sass-cache
|
||||||
|
yarn.lock
|
||||||
|
package-lock.json
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Os
|
||||||
|
Thumbs.db
|
||||||
|
ehthumbs.db
|
||||||
|
Desktop.ini
|
||||||
|
.directory
|
||||||
|
*~
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# maven & eclipse
|
||||||
|
target/
|
||||||
|
.classpath
|
||||||
|
.project
|
||||||
|
|
||||||
|
# project specific
|
||||||
|
.tmp
|
||||||
|
|||||||
6
.prettierrc
Normal file
6
.prettierrc
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"printWidth": 100,
|
||||||
|
"useTabs": true,
|
||||||
|
"semi": true,
|
||||||
|
"singleQuote": true
|
||||||
|
}
|
||||||
31
package.json
Normal file
31
package.json
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"name": "plantuml-icon-font-sprites",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"author": "tupadr3",
|
||||||
|
"description": "A usefull description",
|
||||||
|
"license": "MIT",
|
||||||
|
"scripts": {
|
||||||
|
"devel": "node ./src/lib/index.js --devel",
|
||||||
|
"build": "rm .tmp/build -rf && node ./src/lib/index.js -c 4 --release",
|
||||||
|
"clean": "rm .tmp -rf"
|
||||||
|
},
|
||||||
|
"devDependencies": {},
|
||||||
|
"dependencies": {
|
||||||
|
"bluebird": "^3.5.1",
|
||||||
|
"command-line-args": "^5.1.1",
|
||||||
|
"command-line-usage": "^6.0.2",
|
||||||
|
"dateformat": "^3.0.3",
|
||||||
|
"eslint": "^5.9.0",
|
||||||
|
"extend": "^3.0.1",
|
||||||
|
"fs-extra": "^6.0.1",
|
||||||
|
"isomorphic-git": ">=1.8.2",
|
||||||
|
"lodash": "^4.17.10",
|
||||||
|
"minimist": "^1.2.0",
|
||||||
|
"ncp": "^2.0.0",
|
||||||
|
"os": "^0.1.1",
|
||||||
|
"pngjs": "^3.3.3",
|
||||||
|
"progress": "^2.0.0",
|
||||||
|
"winston": "^2.4.2",
|
||||||
|
"xml2js": "^0.4.19"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
src/assets/bin/plantuml.jar
Normal file
BIN
src/assets/bin/plantuml.jar
Normal file
Binary file not shown.
BIN
src/assets/bin/rsvg-convert.exe
Normal file
BIN
src/assets/bin/rsvg-convert.exe
Normal file
Binary file not shown.
114
src/lib/cliOptions.js
Normal file
114
src/lib/cliOptions.js
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
const os = require('os');
|
||||||
|
|
||||||
|
let cpuCount = os.cpus().length;
|
||||||
|
|
||||||
|
if (cpuCount > 2) {
|
||||||
|
cpuCount = Number((cpuCount / 2).toFixed(0));
|
||||||
|
if (cpuCount > 6) {
|
||||||
|
cpuCount--;
|
||||||
|
cpuCount--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let binRsvgDft = os.platform() === 'linux' ? 'rsvg-convert' : 'src/assets/bin/rsvg-convert.exe';
|
||||||
|
|
||||||
|
module.exports = [
|
||||||
|
{
|
||||||
|
name: 'limit',
|
||||||
|
type: Number,
|
||||||
|
alias: 'l',
|
||||||
|
defaultValue: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'concurrency',
|
||||||
|
type: Number,
|
||||||
|
alias: 'c',
|
||||||
|
defaultValue: cpuCount,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'progress',
|
||||||
|
type: Boolean,
|
||||||
|
alias: 'p',
|
||||||
|
defaultValue: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'verbose',
|
||||||
|
type: Boolean,
|
||||||
|
alias: 'v',
|
||||||
|
defaultValue: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'formats',
|
||||||
|
type: String,
|
||||||
|
multiple: true,
|
||||||
|
defaultValue: ['png', 'svg', 'puml'],
|
||||||
|
typeLabel: '{underline format} ...',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'release',
|
||||||
|
type: Boolean,
|
||||||
|
defaultValue: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'colors',
|
||||||
|
type: String,
|
||||||
|
multiple: true,
|
||||||
|
defaultValue: ['black'],
|
||||||
|
typeLabel: '{underline color} ...',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'sizes',
|
||||||
|
type: Number,
|
||||||
|
multiple: true,
|
||||||
|
defaultValue: [48],
|
||||||
|
typeLabel: '{underline size} ...',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'icons',
|
||||||
|
type: String,
|
||||||
|
multiple: true,
|
||||||
|
defaultValue: [],
|
||||||
|
typeLabel: '{underline icon} ...',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'fonts',
|
||||||
|
type: String,
|
||||||
|
multiple: true,
|
||||||
|
defaultValue: [],
|
||||||
|
typeLabel: '{underline font} ...',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'binPlantuml',
|
||||||
|
type: String,
|
||||||
|
defaultValue: 'src/assets/bin/plantuml.jar',
|
||||||
|
description: 'The path to the PlantUML executable (.jar) to use',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'binRsvg',
|
||||||
|
type: String,
|
||||||
|
defaultValue: binRsvgDft,
|
||||||
|
description: 'The path to the rsvg-convert executable to use',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'build',
|
||||||
|
type: String,
|
||||||
|
defaultValue: 'build',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'temp',
|
||||||
|
type: String,
|
||||||
|
defaultValue: '.tmp',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'devel',
|
||||||
|
type: Boolean,
|
||||||
|
defaultValue: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'help',
|
||||||
|
alias: 'h',
|
||||||
|
type: Boolean,
|
||||||
|
description: 'Display this usage guide.',
|
||||||
|
defaultValue: false,
|
||||||
|
},
|
||||||
|
];
|
||||||
58
src/lib/config.js
Normal file
58
src/lib/config.js
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
/**
|
||||||
|
* @authot tupadr3
|
||||||
|
*/
|
||||||
|
const cliArgs = require('command-line-args'),
|
||||||
|
cliOptions = require('./cliOptions.js'),
|
||||||
|
path = require('path');
|
||||||
|
|
||||||
|
function initConfig() {
|
||||||
|
const cfg = cliArgs(cliOptions);
|
||||||
|
const fontsDef = require('./fonts').def();
|
||||||
|
let fonts = cfg.fonts;
|
||||||
|
cfg.fonts = [];
|
||||||
|
|
||||||
|
// validate fonts
|
||||||
|
if (fonts.length > 0) {
|
||||||
|
fonts.forEach((item) => {
|
||||||
|
const found = fontsDef.find(function (element) {
|
||||||
|
return element.type === item;
|
||||||
|
});
|
||||||
|
if (found) {
|
||||||
|
cfg.fonts.push(found);
|
||||||
|
} else {
|
||||||
|
throw new Error('Font ' + item + ' not found');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
cfg.fonts = fontsDef;
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg.png = false;
|
||||||
|
cfg.puml = false;
|
||||||
|
cfg.svg = false;
|
||||||
|
|
||||||
|
if (cfg.formats) {
|
||||||
|
cfg.formats.forEach((item) => {
|
||||||
|
if (item === 'png') {
|
||||||
|
cfg.png = true;
|
||||||
|
}
|
||||||
|
if (item === 'puml') {
|
||||||
|
cfg.puml = true;
|
||||||
|
}
|
||||||
|
if (item === 'svg') {
|
||||||
|
cfg.svg = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup dirs
|
||||||
|
cfg.dirs = {};
|
||||||
|
cfg.dirs.temp = path.resolve(cfg.temp);
|
||||||
|
cfg.dirs.project = path.resolve('./');
|
||||||
|
cfg.dirs.generated = path.resolve(cfg.temp + '/generated');
|
||||||
|
cfg.dirs.build = path.resolve(cfg.temp + '/' + cfg.build);
|
||||||
|
cfg.dirs.fonts = path.resolve(cfg.temp + '/fonts');
|
||||||
|
return cfg;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = initConfig();
|
||||||
340
src/lib/fonts.js
Normal file
340
src/lib/fonts.js
Normal file
@@ -0,0 +1,340 @@
|
|||||||
|
/**
|
||||||
|
* @authot tupadr3
|
||||||
|
*/
|
||||||
|
const log = require('./logger'),
|
||||||
|
fs = require('fs-extra'),
|
||||||
|
git = require('isomorphic-git'),
|
||||||
|
http = require('isomorphic-git/http/node'),
|
||||||
|
PNG = require('pngjs').PNG;
|
||||||
|
|
||||||
|
function def() {
|
||||||
|
const fontDefs = [
|
||||||
|
{
|
||||||
|
prefix: 'FA5',
|
||||||
|
name: 'font-awesome-5',
|
||||||
|
type: 'fa5',
|
||||||
|
repo: 'https://github.com/FortAwesome/Font-Awesome.git',
|
||||||
|
branch: '5.15.3',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prefix: 'FA',
|
||||||
|
name: 'font-awesome',
|
||||||
|
type: 'fa',
|
||||||
|
repo: 'https://github.com/FortAwesome/Font-Awesome.git',
|
||||||
|
branch: 'fa-4',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prefix: 'DEV',
|
||||||
|
name: 'devicons',
|
||||||
|
type: 'dev',
|
||||||
|
repo: 'https://github.com/vorillaz/devicons.git',
|
||||||
|
branch: 'master',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prefix: 'GOV',
|
||||||
|
name: 'govicons',
|
||||||
|
type: 'gov',
|
||||||
|
repo: 'https://github.com/540co/govicons.git',
|
||||||
|
branch: '1.5.1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prefix: 'WEATHER',
|
||||||
|
name: 'weather',
|
||||||
|
type: 'weather',
|
||||||
|
repo: 'https://github.com/erikflowers/weather-icons.git',
|
||||||
|
branch: 'master',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prefix: 'MATERIAL',
|
||||||
|
name: 'material',
|
||||||
|
type: 'material',
|
||||||
|
repo: 'https://github.com/google/material-design-icons.git',
|
||||||
|
branch: '3.0.2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prefix: 'DEV2',
|
||||||
|
name: 'devicons2',
|
||||||
|
type: 'dev2',
|
||||||
|
repo: 'https://github.com/devicons/devicon.git',
|
||||||
|
branch: 'v2.12.0',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
return fontDefs;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function load(cfg) {
|
||||||
|
// Prep the folder structue
|
||||||
|
let buildFolder = cfg.dirs.build;
|
||||||
|
await fs.ensureDirSync(buildFolder);
|
||||||
|
|
||||||
|
let work = [];
|
||||||
|
for (let item of cfg.fonts) {
|
||||||
|
try {
|
||||||
|
item.path = await repo(cfg, item);
|
||||||
|
} catch (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
|
let buildSetFolder = buildFolder + '/' + item.type;
|
||||||
|
await fs.ensureDirSync(buildSetFolder);
|
||||||
|
await fs.ensureDirSync(cfg.dirs.generated);
|
||||||
|
|
||||||
|
if (cfg.svg) {
|
||||||
|
await fs.ensureDirSync(buildSetFolder + '/svg');
|
||||||
|
}
|
||||||
|
if (cfg.puml) {
|
||||||
|
await fs.ensureDirSync(buildSetFolder + '/puml');
|
||||||
|
}
|
||||||
|
if (cfg.png) {
|
||||||
|
await fs.ensureDirSync(buildSetFolder + '/png');
|
||||||
|
for (let index in cfg.sizes) {
|
||||||
|
await fs.ensureDirSync(buildSetFolder + '/png/' + cfg.sizes[index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const fontHandler = require('./handler/' + item.type);
|
||||||
|
let fontData = await fontHandler.load(cfg, item);
|
||||||
|
|
||||||
|
if (cfg.icons.length > 0) {
|
||||||
|
log.debug(`Filtering selection to ${cfg.icons}`);
|
||||||
|
fontData = fontData.filter((item) => {
|
||||||
|
if (cfg.icons.includes(`${item.type}-${item.id}`)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
work = work.concat(fontData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfg.limit > 0) {
|
||||||
|
log.debug(`Trimming selection from ${work.length} to ${cfg.limit}`);
|
||||||
|
work = work.slice(0, cfg.limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
return work;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function repo(cfg, item) {
|
||||||
|
log.info('Loading repo ' + item.repo + ' into ' + cfg.dirs.fonts);
|
||||||
|
|
||||||
|
const repoDir = cfg.dirs.fonts + '/' + item.type,
|
||||||
|
repoGitDir = cfg.dirs.fonts + '/' + item.type + '/.git';
|
||||||
|
|
||||||
|
try {
|
||||||
|
await fs.ensureDirSync(repoDir);
|
||||||
|
|
||||||
|
// check if it already exists
|
||||||
|
log.debug(`checking dir ${repoGitDir} for repo`);
|
||||||
|
const repoExists = fs.existsSync(repoGitDir);
|
||||||
|
|
||||||
|
if (!repoExists) {
|
||||||
|
await git.clone({
|
||||||
|
fs,
|
||||||
|
http,
|
||||||
|
dir: repoDir,
|
||||||
|
url: item.repo,
|
||||||
|
singleBranch: true,
|
||||||
|
ref: item.branch,
|
||||||
|
depth: 10,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug(`checkout ${item.repo} branch:${item.branch} completed to dir ${repoDir}`);
|
||||||
|
} catch (err) {
|
||||||
|
log.error('repo error', err);
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
return repoDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function generate(cfg, item) {
|
||||||
|
if (cfg.svg) {
|
||||||
|
try {
|
||||||
|
await generateSvg(cfg, item);
|
||||||
|
} catch (error) {
|
||||||
|
log.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfg.png) {
|
||||||
|
for (let index in cfg.sizes) {
|
||||||
|
try {
|
||||||
|
await generatePng(cfg, item, cfg.sizes[index]);
|
||||||
|
} catch (error) {
|
||||||
|
log.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cfg.puml) {
|
||||||
|
try {
|
||||||
|
await generatePuml(cfg, item);
|
||||||
|
} catch (error) {
|
||||||
|
log.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateSvg(cfg, item) {
|
||||||
|
log.debug('Generating svg for ' + item.type + '-' + item.id);
|
||||||
|
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
var svgCode = getSvgCode(cfg, item);
|
||||||
|
var filename = cfg.dirs.build + '/' + item.type + '/svg/' + item.id + '.svg';
|
||||||
|
log.debug('Wrting svg for ' + item.type + '-' + item.id + ' to ' + filename);
|
||||||
|
fs.writeFileSync(filename, svgCode);
|
||||||
|
resolve(filename);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSvgCode(cfg, item) {
|
||||||
|
const fontHandler = require('./handler/' + item.type);
|
||||||
|
let svgCode = fontHandler.getSvgCode(cfg, item);
|
||||||
|
return svgCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
function generatePng(cfg, item, size, path) {
|
||||||
|
return new Promise(function (resolve, reject) {
|
||||||
|
let destPath = path;
|
||||||
|
if (!destPath) {
|
||||||
|
destPath = cfg.dirs.build + '/' + item.type + '/png/' + size + '/' + item.id + '.png';
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug('Generating png for ' + item.type + '-' + item.id);
|
||||||
|
|
||||||
|
let cliparams = ['-a', '-w', size, '-h', size, '-f', 'png', '-o', destPath],
|
||||||
|
error;
|
||||||
|
log.debug(cfg.binRsvg, cliparams.join(' '));
|
||||||
|
let rsvgConvert = require('child_process').spawn(cfg.binRsvg, cliparams);
|
||||||
|
rsvgConvert.stderr.on('data', (data) => {
|
||||||
|
error += data.toString();
|
||||||
|
});
|
||||||
|
rsvgConvert.once('close', function (code) {
|
||||||
|
if (code > 0) {
|
||||||
|
return reject(error);
|
||||||
|
}
|
||||||
|
resolve(destPath);
|
||||||
|
});
|
||||||
|
rsvgConvert.stdin.end(getSvgCode(cfg, item));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function generatePuml(cfg, item) {
|
||||||
|
return new Promise(async function (resolve, reject) {
|
||||||
|
log.debug('Generating plantuml for ' + item.type + '-' + item.id);
|
||||||
|
|
||||||
|
let pngInterFileName = cfg.dirs.generated + '/' + item.type + '-png-48-' + item.id + '.png';
|
||||||
|
let pngFileName = await generatePng(cfg, item, 48, pngInterFileName);
|
||||||
|
|
||||||
|
// now we need to modify the png a little bit
|
||||||
|
fs.createReadStream(pngFileName)
|
||||||
|
.pipe(
|
||||||
|
new PNG({
|
||||||
|
colorType: 2,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.on('error', function (err) {
|
||||||
|
log.error(err);
|
||||||
|
})
|
||||||
|
.on('parsed', async function () {
|
||||||
|
log.debug('Modifing for puml generation for icon ' + item.type + '-' + item.id);
|
||||||
|
|
||||||
|
for (var y = 0; y < this.height; y++) {
|
||||||
|
for (var x = 0; x < this.width; x++) {
|
||||||
|
var idx = (this.width * y + x) << 2;
|
||||||
|
// invert color
|
||||||
|
if (this.data[idx] > 0) {
|
||||||
|
this.data[idx] = 0;
|
||||||
|
this.data[idx + 1] = 0;
|
||||||
|
this.data[idx + 2] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// i don't know if we have to wait
|
||||||
|
this.pack().pipe(fs.createWriteStream(pngInterFileName));
|
||||||
|
|
||||||
|
let pumlCode;
|
||||||
|
try {
|
||||||
|
pumlCode = await getPumlCode(cfg, item, pngInterFileName);
|
||||||
|
} catch (error) {
|
||||||
|
reject(error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var filename = cfg.dirs.build + '/' + item.type + '/puml/' + item.id + '.puml';
|
||||||
|
await fs.writeFileSync(filename, pumlCode);
|
||||||
|
resolve(filename);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPumlCode(cfg, item, pngPath) {
|
||||||
|
return new Promise(function (resolve, reject) {
|
||||||
|
var plantumlJar,
|
||||||
|
result = '',
|
||||||
|
error = '';
|
||||||
|
|
||||||
|
var template =
|
||||||
|
'@startuml' +
|
||||||
|
'\n' +
|
||||||
|
'{sprite}' +
|
||||||
|
'\n' +
|
||||||
|
'!define {set}_{entity}(_alias) ENTITY(rectangle,black,{id},_alias,{set} {entity})' +
|
||||||
|
'\n' +
|
||||||
|
'!define {set}_{entity}(_alias, _label) ENTITY(rectangle,black,{id},_label, _alias,{set} {entity})' +
|
||||||
|
'\n' +
|
||||||
|
'!define {set}_{entity}(_alias, _label, _shape) ENTITY(_shape,black,{id},_label, _alias,{set} {entity})' +
|
||||||
|
'\n' +
|
||||||
|
'!define {set}_{entity}(_alias, _label, _shape, _color) ENTITY(_shape,_color,{id},_label, _alias,{set} {entity})' +
|
||||||
|
'\n' +
|
||||||
|
'skinparam folderBackgroundColor<<{set} {entity}>> White' +
|
||||||
|
'\n' +
|
||||||
|
'@enduml';
|
||||||
|
|
||||||
|
var plantumlParams = [
|
||||||
|
'-Djava.awt.headless=true',
|
||||||
|
'-jar',
|
||||||
|
cfg.binPlantuml,
|
||||||
|
'-encodesprite',
|
||||||
|
'16',
|
||||||
|
pngPath,
|
||||||
|
];
|
||||||
|
|
||||||
|
log.debug('java ' + plantumlParams.join(' '));
|
||||||
|
|
||||||
|
plantumlJar = require('child_process').spawn('java', plantumlParams);
|
||||||
|
plantumlJar.stdout.on('data', (data) => {
|
||||||
|
result += data.toString();
|
||||||
|
});
|
||||||
|
plantumlJar.stderr.on('data', (data) => {
|
||||||
|
error += data.toString();
|
||||||
|
});
|
||||||
|
plantumlJar.once('close', function (code) {
|
||||||
|
if (code > 0) {
|
||||||
|
reject(error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var out = template.substr(0);
|
||||||
|
|
||||||
|
var params = {
|
||||||
|
sprite: result.replace('$' + item.type, '$' + item.id.replace(/-/g, '_')),
|
||||||
|
set: item.prefix.toUpperCase(),
|
||||||
|
entity: item.id.replace(/-/g, '_').toUpperCase(),
|
||||||
|
id: item.id.replace(/-/g, '_'),
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.keys(params).forEach(function (key) {
|
||||||
|
out = out.replace(new RegExp('{' + key + '}', 'g'), params[key]);
|
||||||
|
});
|
||||||
|
resolve(out);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
def: def,
|
||||||
|
load: load,
|
||||||
|
generate: generate,
|
||||||
|
};
|
||||||
107
src/lib/handler/dev.js
Normal file
107
src/lib/handler/dev.js
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
const fs = require('fs-extra'),
|
||||||
|
util = require('util'),
|
||||||
|
log = require('./../logger'),
|
||||||
|
readFile = util.promisify(fs.readFile),
|
||||||
|
loadash = require('lodash'),
|
||||||
|
parseXml = util.promisify(require('xml2js').parseString);
|
||||||
|
|
||||||
|
async function load(cfg, item) {
|
||||||
|
let iconList = await loadIcons(cfg, item);
|
||||||
|
let icons = await loadFontData(cfg, item, iconList);
|
||||||
|
return icons;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadIcons(cfg, item) {
|
||||||
|
log.debug("Loading devicons id's");
|
||||||
|
|
||||||
|
let content = await readFile(item.path + '/css/devicons.css');
|
||||||
|
let lines = content.toString();
|
||||||
|
|
||||||
|
let match,
|
||||||
|
result = [];
|
||||||
|
|
||||||
|
const regex = /devicons-([\w-]*).*\s.*"\S([0-9a-f]+)"/gm;
|
||||||
|
while ((match = regex.exec(lines))) {
|
||||||
|
result.push({
|
||||||
|
id: match[1],
|
||||||
|
unicodeHex: match[2],
|
||||||
|
unicodeDec: parseInt(match[2], 16)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadFontData(cfg, item, iconList) {
|
||||||
|
log.debug('Loading devicons font-data');
|
||||||
|
|
||||||
|
let content = await readFile(item.path + '/fonts/devicons.svg');
|
||||||
|
content = content.toString('utf-8');
|
||||||
|
|
||||||
|
let parsedXml = await parseXml(content),
|
||||||
|
glyph = parsedXml.svg.defs[0].font[0].glyph,
|
||||||
|
svghorz = parsedXml.svg.defs[0].font[0].$['horiz-adv-x'],
|
||||||
|
offset = parsedXml.svg.defs[0].font[0]['font-face'][0].$['descent'],
|
||||||
|
size = parsedXml.svg.defs[0].font[0]['font-face'][0].$['units-per-em'];
|
||||||
|
|
||||||
|
let fontData = glyph
|
||||||
|
.filter(data => {
|
||||||
|
if (!data.$.unicode) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.map(data => {
|
||||||
|
return {
|
||||||
|
data: data.$,
|
||||||
|
unicodeDec: data.$.unicode.charCodeAt(0)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
let indexFontData = await loadash.keyBy(fontData, 'unicodeDec');
|
||||||
|
|
||||||
|
let icons = iconList.map(icon => {
|
||||||
|
let iconConfig = {
|
||||||
|
id: icon.id.split('-').join('_'),
|
||||||
|
type: item.type,
|
||||||
|
prefix: item.prefix,
|
||||||
|
unicodeHex: icon.unicodeHex,
|
||||||
|
unicodeDec: icon.unicodeDec,
|
||||||
|
data: indexFontData[icon.unicodeDec].data
|
||||||
|
};
|
||||||
|
iconConfig.advWidth = parseInt(iconConfig.data['horiz-adv-x'] || svghorz);
|
||||||
|
iconConfig.offset = parseInt(offset);
|
||||||
|
iconConfig.size = parseInt(size);
|
||||||
|
return iconConfig;
|
||||||
|
});
|
||||||
|
|
||||||
|
return icons;
|
||||||
|
}
|
||||||
|
function getSvgCode(cfg, item) {
|
||||||
|
log.debug('Getting svg code for ' + item.type + '-' + item.id);
|
||||||
|
|
||||||
|
let params = {
|
||||||
|
color: cfg.color || 'black',
|
||||||
|
path: item.data.d,
|
||||||
|
width: item.advWidth,
|
||||||
|
height: item.size,
|
||||||
|
shiftX: 0,
|
||||||
|
shiftY: -item.size - item.offset
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
`<svg width="${params.height}" height="${params.height}"` +
|
||||||
|
` viewBox="0 0 ${params.height} ${params.height}" preserveAspectRatio="xMinYMid slice">\n` +
|
||||||
|
`\t<svg width="${params.height}" height="${params.height}"` +
|
||||||
|
` viewBox="0 0 ${params.width} ${params.height}">\n` +
|
||||||
|
`\t\t<g transform="scale(1 -1) translate(${params.shiftX} ${params.shiftY})">\n` +
|
||||||
|
`\t\t\t<path d="${params.path}" fill="${params.color}" />\n` +
|
||||||
|
`\t\t</g>\n` +
|
||||||
|
`\t</svg>\n` +
|
||||||
|
`</svg>`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
load: load,
|
||||||
|
getSvgCode: getSvgCode
|
||||||
|
};
|
||||||
108
src/lib/handler/dev2.js
Normal file
108
src/lib/handler/dev2.js
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
const fs = require('fs-extra'),
|
||||||
|
util = require('util'),
|
||||||
|
log = require('./../logger'),
|
||||||
|
readFile = util.promisify(fs.readFile),
|
||||||
|
lodash = require('lodash'),
|
||||||
|
parseXml = util.promisify(require('xml2js').parseString);
|
||||||
|
|
||||||
|
async function load(cfg, item) {
|
||||||
|
return await loadFontData(cfg, item, await loadIcons(cfg, item));
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadIcons(cfg, item) {
|
||||||
|
log.debug("Loading devicons2 id's");
|
||||||
|
|
||||||
|
let content = await readFile(item.path + '/devicon.css');
|
||||||
|
let lines = content.toString();
|
||||||
|
|
||||||
|
let match,
|
||||||
|
result = [];
|
||||||
|
|
||||||
|
const regex = /.devicon-([\w-]*):before\s?{\s*content:\s?"\\([\w|\d]*)";\s*}/;
|
||||||
|
while ((match = regex.exec(lines))) {
|
||||||
|
log.verbose('DEV2 - found ' + match[1]);
|
||||||
|
result.push({
|
||||||
|
id: match[1].replace('-plain', ''),
|
||||||
|
unicodeHex: match[2],
|
||||||
|
unicodeDec: parseInt(match[2], 16)
|
||||||
|
});
|
||||||
|
lines = lines.replace(match[0], '');
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadFontData(cfg, item, iconList) {
|
||||||
|
log.debug('Loading devicons2 font-data');
|
||||||
|
|
||||||
|
let content = await readFile(item.path + '/fonts/devicon.svg');
|
||||||
|
content = content.toString('utf-8');
|
||||||
|
|
||||||
|
let parsedXml = await parseXml(content),
|
||||||
|
glyph = parsedXml.svg.defs[0].font[0].glyph,
|
||||||
|
svghorz = parsedXml.svg.defs[0].font[0].$['horiz-adv-x'],
|
||||||
|
offset = parsedXml.svg.defs[0].font[0]['font-face'][0].$['descent'],
|
||||||
|
size = parsedXml.svg.defs[0].font[0]['font-face'][0].$['units-per-em'];
|
||||||
|
|
||||||
|
let fontData = glyph
|
||||||
|
.filter(data => {
|
||||||
|
if (!data.$.unicode) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.map(data => {
|
||||||
|
return {
|
||||||
|
data: data.$,
|
||||||
|
unicodeDec: data.$.unicode.charCodeAt(0)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
let indexFontData = await lodash.keyBy(fontData, 'unicodeDec');
|
||||||
|
|
||||||
|
let icons = iconList.map(icon => {
|
||||||
|
let iconConfig = {
|
||||||
|
id: icon.id.split('-').join('_'),
|
||||||
|
type: item.type,
|
||||||
|
prefix: item.prefix,
|
||||||
|
unicodeHex: icon.unicodeHex,
|
||||||
|
unicodeDec: icon.unicodeDec,
|
||||||
|
data: indexFontData[icon.unicodeDec].data
|
||||||
|
};
|
||||||
|
iconConfig.advWidth = parseInt(iconConfig.data['horiz-adv-x'] || svghorz);
|
||||||
|
iconConfig.offset = parseInt(offset);
|
||||||
|
iconConfig.size = parseInt(size);
|
||||||
|
return iconConfig;
|
||||||
|
});
|
||||||
|
|
||||||
|
return icons;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSvgCode(cfg, item) {
|
||||||
|
log.debug('Getting svg code for ' + item.type + '-' + item.id);
|
||||||
|
|
||||||
|
let params = {
|
||||||
|
color: cfg.color || 'black',
|
||||||
|
path: item.data.d,
|
||||||
|
width: item.advWidth,
|
||||||
|
height: item.size,
|
||||||
|
shiftX: 0,
|
||||||
|
shiftY: -item.size - item.offset
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
`<svg width="${params.height}" height="${params.height}"` +
|
||||||
|
` viewBox="0 0 ${params.height} ${params.height}" preserveAspectRatio="xMinYMid slice">\n` +
|
||||||
|
`\t<svg width="${params.height}" height="${params.height}"` +
|
||||||
|
` viewBox="0 0 ${params.width} ${params.height}">\n` +
|
||||||
|
`\t\t<g transform="scale(1 -1) translate(${params.shiftX} ${params.shiftY})">\n` +
|
||||||
|
`\t\t\t<path d="${params.path}" fill="${params.color}" />\n` +
|
||||||
|
`\t\t</g>\n` +
|
||||||
|
`\t</svg>\n` +
|
||||||
|
`</svg>`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
load: load,
|
||||||
|
getSvgCode: getSvgCode
|
||||||
|
};
|
||||||
108
src/lib/handler/fa.js
Normal file
108
src/lib/handler/fa.js
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
const fs = require('fs-extra'),
|
||||||
|
util = require('util'),
|
||||||
|
log = require('./../logger'),
|
||||||
|
readFile = util.promisify(fs.readFile),
|
||||||
|
loadash = require('lodash'),
|
||||||
|
parseXml = util.promisify(require('xml2js').parseString),
|
||||||
|
extend = require('extend');
|
||||||
|
|
||||||
|
async function load(cfg, item) {
|
||||||
|
let iconList = await loadIcons(cfg, item);
|
||||||
|
let icons = await loadFontData(cfg, item, iconList);
|
||||||
|
return icons;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadIcons(cfg, item) {
|
||||||
|
log.debug("Loading fa id's");
|
||||||
|
let content = await readFile(item.path + '/less/variables.less');
|
||||||
|
let lines = content.toString();
|
||||||
|
|
||||||
|
let match,
|
||||||
|
result = [];
|
||||||
|
|
||||||
|
const regex = /@fa-var-([\w-]+):\s*"\\([0-9a-f]+)";/g;
|
||||||
|
while ((match = regex.exec(lines))) {
|
||||||
|
result.push({
|
||||||
|
id: match[1],
|
||||||
|
unicodeHex: match[2],
|
||||||
|
unicodeDec: parseInt(match[2], 16)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadFontData(cfg, item, iconList) {
|
||||||
|
log.debug('Loading fa font-data');
|
||||||
|
let content = await readFile(item.path + '/fonts/fontawesome-webfont.svg');
|
||||||
|
content = content.toString('utf-8');
|
||||||
|
|
||||||
|
let parsedXml = await parseXml(content),
|
||||||
|
glyph = parsedXml.svg.defs[0].font[0].glyph,
|
||||||
|
svghorz = parsedXml.svg.defs[0].font[0].$['horiz-adv-x'],
|
||||||
|
offset = parsedXml.svg.defs[0].font[0]['font-face'][0].$['descent'],
|
||||||
|
size = parsedXml.svg.defs[0].font[0]['font-face'][0].$['units-per-em'];
|
||||||
|
|
||||||
|
let fontData = glyph
|
||||||
|
.filter(data => {
|
||||||
|
if (!data.$.unicode) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.map(data => {
|
||||||
|
return {
|
||||||
|
data: data.$,
|
||||||
|
unicodeDec: data.$.unicode.charCodeAt(0)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
let indexFontData = await loadash.keyBy(fontData, 'unicodeDec');
|
||||||
|
|
||||||
|
let icons = iconList.map(icon => {
|
||||||
|
let iconConfig = {
|
||||||
|
id: icon.id.split('-').join('_'),
|
||||||
|
type: item.type,
|
||||||
|
prefix: item.prefix,
|
||||||
|
unicodeHex: icon.unicodeHex,
|
||||||
|
unicodeDec: icon.unicodeDec,
|
||||||
|
data: indexFontData[icon.unicodeDec].data
|
||||||
|
};
|
||||||
|
iconConfig.advWidth = parseInt(iconConfig.data['horiz-adv-x'] || svghorz);
|
||||||
|
iconConfig.offset = parseInt(offset);
|
||||||
|
iconConfig.size = parseInt(size);
|
||||||
|
return iconConfig;
|
||||||
|
});
|
||||||
|
|
||||||
|
return icons;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSvgCode(cfg, item) {
|
||||||
|
log.debug('Getting svg code for ' + item.type + '-' + item.id);
|
||||||
|
|
||||||
|
let params = {
|
||||||
|
color: cfg.color || 'black',
|
||||||
|
path: item.data.d,
|
||||||
|
width: item.advWidth,
|
||||||
|
height: item.size,
|
||||||
|
shiftX: item.advWidth / 10 / 2,
|
||||||
|
shiftY: -item.size - item.offset - item.size / 10 / 2
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
`<svg width="${params.height}" height="${params.height}"` +
|
||||||
|
` viewBox="0 0 ${params.height} ${params.height}" preserveAspectRatio="xMinYMid slice">\n` +
|
||||||
|
`\t<svg width="${params.height}" height="${params.height}"` +
|
||||||
|
` viewBox="0 0 ${params.width} ${params.height}">\n` +
|
||||||
|
`\t\t<g transform="scale(1 -1) scale(0.9)` +
|
||||||
|
` translate(${params.shiftX} ${params.shiftY})">\n` +
|
||||||
|
`\t\t\t<path d="${params.path}" fill="${params.color}" />\n` +
|
||||||
|
`\t\t</g>\n` +
|
||||||
|
`\t</svg>\n` +
|
||||||
|
`</svg>`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
load: load,
|
||||||
|
getSvgCode: getSvgCode
|
||||||
|
};
|
||||||
132
src/lib/handler/fa5.js
Normal file
132
src/lib/handler/fa5.js
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
const fs = require('fs-extra'),
|
||||||
|
util = require('util'),
|
||||||
|
log = require('./../logger'),
|
||||||
|
readFile = util.promisify(fs.readFile),
|
||||||
|
loadash = require('lodash'),
|
||||||
|
parseXml = util.promisify(require('xml2js').parseString);
|
||||||
|
|
||||||
|
async function load(cfg, item) {
|
||||||
|
let iconList = await loadIcons(cfg, item);
|
||||||
|
let icons = await loadFontData(cfg, item, iconList);
|
||||||
|
return icons;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadIcons(cfg, item) {
|
||||||
|
log.debug("Loading fa id's");
|
||||||
|
let content = await readFile(item.path + '/less/_variables.less');
|
||||||
|
let lines = content.toString();
|
||||||
|
|
||||||
|
let match,
|
||||||
|
result = [];
|
||||||
|
|
||||||
|
const regex = /@fa-var-([\w-]+):\s*"\\([0-9a-f]+)";/g;
|
||||||
|
while ((match = regex.exec(lines))) {
|
||||||
|
result.push({
|
||||||
|
id: match[1],
|
||||||
|
unicodeHex: match[2],
|
||||||
|
unicodeDec: parseInt(match[2], 16)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadFontData(cfg, item, iconList) {
|
||||||
|
log.debug('Loading fa5 font-data');
|
||||||
|
|
||||||
|
let filesList = [
|
||||||
|
item.path + '/webfonts/fa-regular-400.svg',
|
||||||
|
item.path + '/webfonts/fa-brands-400.svg',
|
||||||
|
item.path + '/webfonts/fa-solid-900.svg'
|
||||||
|
];
|
||||||
|
|
||||||
|
let fontData = [];
|
||||||
|
for (let key in filesList) {
|
||||||
|
let item = filesList[key];
|
||||||
|
let content = await readFile(item);
|
||||||
|
content = content.toString('utf-8');
|
||||||
|
|
||||||
|
let parsedXml = await parseXml(content),
|
||||||
|
glyph = parsedXml.svg.defs[0].font[0].glyph,
|
||||||
|
svghorz = parsedXml.svg.defs[0].font[0].$['horiz-adv-x'],
|
||||||
|
offset = parsedXml.svg.defs[0].font[0]['font-face'][0].$['descent'],
|
||||||
|
size = parsedXml.svg.defs[0].font[0]['font-face'][0].$['units-per-em'];
|
||||||
|
|
||||||
|
let fontDataItem = glyph
|
||||||
|
.filter(data => {
|
||||||
|
if (!data.$.unicode) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.map(data => {
|
||||||
|
return {
|
||||||
|
data: data.$,
|
||||||
|
unicodeDec: data.$.unicode.charCodeAt(0),
|
||||||
|
svghorz: svghorz,
|
||||||
|
offset: -offset,
|
||||||
|
size: size
|
||||||
|
};
|
||||||
|
});
|
||||||
|
fontData = fontData.concat(fontDataItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
let indexFontData = await loadash.keyBy(fontData, 'unicodeDec');
|
||||||
|
|
||||||
|
let icons = iconList
|
||||||
|
.filter(icon => {
|
||||||
|
if (!indexFontData[icon.unicodeDec]) {
|
||||||
|
log.debug(`Skipping ${icon.unicodeHex}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.map(icon => {
|
||||||
|
let iconData = indexFontData[icon.unicodeDec];
|
||||||
|
|
||||||
|
let iconConfig = {
|
||||||
|
id: icon.id.split('-').join('_'),
|
||||||
|
type: item.type,
|
||||||
|
prefix: item.prefix,
|
||||||
|
unicodeHex: icon.unicodeHex,
|
||||||
|
unicodeDec: icon.unicodeDec,
|
||||||
|
data: iconData.data,
|
||||||
|
offset: parseInt(iconData.offset),
|
||||||
|
size: parseInt(iconData.size),
|
||||||
|
advWidth: parseInt(iconData.data['horiz-adv-x'] || iconData.svghorz)
|
||||||
|
};
|
||||||
|
return iconConfig;
|
||||||
|
});
|
||||||
|
|
||||||
|
return icons;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSvgCode(cfg, item) {
|
||||||
|
log.debug('Getting svg code for ' + item.type + '-' + item.id);
|
||||||
|
|
||||||
|
let params = {
|
||||||
|
color: cfg.color || 'black',
|
||||||
|
path: item.data.d,
|
||||||
|
width: item.advWidth,
|
||||||
|
height: item.size,
|
||||||
|
shiftX: item.advWidth / 10 / 2,
|
||||||
|
shiftY: -item.size +item.offset -item.size / 10 / 2
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
`<svg width="${params.height}" height="${params.height}"` +
|
||||||
|
` viewBox="0 0 ${params.height} ${params.height}" preserveAspectRatio="xMinYMid slice">\n` +
|
||||||
|
`\t<svg width="${params.height}" height="${params.height}"` +
|
||||||
|
` viewBox="0 0 ${params.width} ${params.height}">\n` +
|
||||||
|
`\t\t<g transform="scale(1 -1) scale(0.9)` +
|
||||||
|
` translate(${params.shiftX} ${params.shiftY})">\n` +
|
||||||
|
`\t\t\t<path d="${params.path}" fill="${params.color}" />\n` +
|
||||||
|
`\t\t</g>\n` +
|
||||||
|
`\t</svg>\n` +
|
||||||
|
`</svg>`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
load: load,
|
||||||
|
getSvgCode: getSvgCode
|
||||||
|
};
|
||||||
128
src/lib/handler/gov.js
Normal file
128
src/lib/handler/gov.js
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
const fs = require('fs-extra'),
|
||||||
|
util = require('util'),
|
||||||
|
log = require('./../logger'),
|
||||||
|
readFile = util.promisify(fs.readFile),
|
||||||
|
loadash = require('lodash'),
|
||||||
|
parseXml = util.promisify(require('xml2js').parseString);
|
||||||
|
|
||||||
|
async function load(cfg, item) {
|
||||||
|
let iconList = await loadIcons(cfg, item);
|
||||||
|
let icons = await loadFontData(cfg, item, iconList);
|
||||||
|
return icons;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadIcons(cfg, item) {
|
||||||
|
log.debug("Loading fa id's");
|
||||||
|
let content = await readFile(item.path + '/less/variables.less');
|
||||||
|
let lines = content.toString();
|
||||||
|
|
||||||
|
let match,
|
||||||
|
result = [];
|
||||||
|
|
||||||
|
const regex = /@gi-([\w-]+):\s*"\\([0-9a-f]+)";/g;
|
||||||
|
while ((match = regex.exec(lines))) {
|
||||||
|
result.push({
|
||||||
|
id: match[1],
|
||||||
|
unicodeHex: match[2],
|
||||||
|
unicodeDec: parseInt(match[2], 16)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadFontData(cfg, item, iconList) {
|
||||||
|
log.debug('Loading fa5 font-data');
|
||||||
|
|
||||||
|
let filesList = [item.path + '/fonts/govicons-webfont.svg'];
|
||||||
|
|
||||||
|
let fontData = [];
|
||||||
|
for (let key in filesList) {
|
||||||
|
let item = filesList[key];
|
||||||
|
let content = await readFile(item);
|
||||||
|
content = content.toString('utf-8');
|
||||||
|
|
||||||
|
let parsedXml = await parseXml(content),
|
||||||
|
glyph = parsedXml.svg.defs[0].font[0].glyph,
|
||||||
|
svghorz = parsedXml.svg.defs[0].font[0].$['horiz-adv-x'],
|
||||||
|
offset = parsedXml.svg.defs[0].font[0]['font-face'][0].$['descent'],
|
||||||
|
size = parsedXml.svg.defs[0].font[0]['font-face'][0].$['units-per-em'];
|
||||||
|
|
||||||
|
let fontDataItem = glyph
|
||||||
|
.filter(data => {
|
||||||
|
if (!data.$.unicode) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.map(data => {
|
||||||
|
return {
|
||||||
|
data: data.$,
|
||||||
|
unicodeDec: data.$.unicode.charCodeAt(0),
|
||||||
|
svghorz: svghorz,
|
||||||
|
offset: offset,
|
||||||
|
size: size
|
||||||
|
};
|
||||||
|
});
|
||||||
|
fontData = fontData.concat(fontDataItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
let indexFontData = await loadash.keyBy(fontData, 'unicodeDec');
|
||||||
|
|
||||||
|
let icons = iconList
|
||||||
|
.filter(icon => {
|
||||||
|
if (!indexFontData[icon.unicodeDec]) {
|
||||||
|
log.debug(`Skipping ${icon.unicodeHex}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.map(icon => {
|
||||||
|
let iconData = indexFontData[icon.unicodeDec];
|
||||||
|
|
||||||
|
let iconConfig = {
|
||||||
|
id: icon.id.split('-').join('_'),
|
||||||
|
type: item.type,
|
||||||
|
prefix: item.prefix,
|
||||||
|
unicodeHex: icon.unicodeHex,
|
||||||
|
unicodeDec: icon.unicodeDec,
|
||||||
|
data: iconData.data,
|
||||||
|
offset: parseInt(iconData.offset),
|
||||||
|
size: parseInt(iconData.size),
|
||||||
|
advWidth: parseInt(iconData.data['horiz-adv-x'] || iconData.svghorz)
|
||||||
|
};
|
||||||
|
return iconConfig;
|
||||||
|
});
|
||||||
|
|
||||||
|
return icons;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSvgCode(cfg, item) {
|
||||||
|
log.debug('Getting svg code for ' + item.type + '-' + item.id);
|
||||||
|
|
||||||
|
let params = {
|
||||||
|
color: cfg.color || 'black',
|
||||||
|
path: item.data.d,
|
||||||
|
width: item.advWidth,
|
||||||
|
height: item.size,
|
||||||
|
shiftX: item.advWidth / 10 / 2,
|
||||||
|
shiftY: -item.size - item.offset - item.size / 10 / 2
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
`<svg width="${params.height}" height="${params.height}"` +
|
||||||
|
` viewBox="0 0 ${params.height} ${params.height}" preserveAspectRatio="xMinYMid slice">\n` +
|
||||||
|
`\t<svg width="${params.height}" height="${params.height}"` +
|
||||||
|
` viewBox="0 0 ${params.width} ${params.height}">\n` +
|
||||||
|
`\t\t<g transform="scale(1 -1) scale(0.9)` +
|
||||||
|
` translate(${params.shiftX} ${params.shiftY})">\n` +
|
||||||
|
`\t\t\t<path d="${params.path}" fill="${params.color}" />\n` +
|
||||||
|
`\t\t</g>\n` +
|
||||||
|
`\t</svg>\n` +
|
||||||
|
`</svg>`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
load: load,
|
||||||
|
getSvgCode: getSvgCode
|
||||||
|
};
|
||||||
106
src/lib/handler/material.js
Normal file
106
src/lib/handler/material.js
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
const fs = require('fs-extra'),
|
||||||
|
util = require('util'),
|
||||||
|
log = require('./../logger'),
|
||||||
|
readFile = util.promisify(fs.readFile),
|
||||||
|
parseXml = util.promisify(require('xml2js').parseString);
|
||||||
|
|
||||||
|
async function load(cfg, item) {
|
||||||
|
let icons = await loadFontData(cfg, item);
|
||||||
|
return icons;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadFontData(cfg, item) {
|
||||||
|
log.debug(`Loading ${item.type} font-data`);
|
||||||
|
|
||||||
|
let filesList = [item.path + '/iconfont/MaterialIcons-Regular.svg'];
|
||||||
|
|
||||||
|
let fontData = [];
|
||||||
|
for (let key in filesList) {
|
||||||
|
let item = filesList[key];
|
||||||
|
let content = await readFile(item);
|
||||||
|
content = content.toString('utf-8');
|
||||||
|
|
||||||
|
let parsedXml = await parseXml(content),
|
||||||
|
glyph = parsedXml.svg.defs[0].font[0].glyph,
|
||||||
|
svghorz = parsedXml.svg.defs[0].font[0].$['horiz-adv-x'],
|
||||||
|
offset = parsedXml.svg.defs[0].font[0]['font-face'][0].$['descent'],
|
||||||
|
size = parsedXml.svg.defs[0].font[0]['font-face'][0].$['units-per-em'];
|
||||||
|
|
||||||
|
let fontDataItem = glyph
|
||||||
|
.filter(data => {
|
||||||
|
if (!data.$.unicode) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!data.$.d) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (data.$.d === 'M0 0z') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.map(data => {
|
||||||
|
return {
|
||||||
|
data: data.$,
|
||||||
|
unicodeDec: data.$.unicode.charCodeAt(0),
|
||||||
|
svghorz: svghorz,
|
||||||
|
offset: offset,
|
||||||
|
size: size
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
fontData = fontData.concat(fontDataItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
let icons = fontData.map(icon => {
|
||||||
|
let iconData = icon.data;
|
||||||
|
|
||||||
|
let iconConfig = {
|
||||||
|
id: icon.data['glyph-name'].split('-').join('_'),
|
||||||
|
type: item.type,
|
||||||
|
prefix: item.prefix,
|
||||||
|
unicodeHex: icon.unicodeHex,
|
||||||
|
unicodeDec: icon.unicodeDec,
|
||||||
|
data: iconData,
|
||||||
|
offset: parseInt(icon.offset),
|
||||||
|
size: parseInt(icon.size),
|
||||||
|
advWidth: parseInt(iconData['horiz-adv-x'] || icon.svghorz)
|
||||||
|
};
|
||||||
|
|
||||||
|
log.verbose('MATERIAL - found ' + iconConfig.id);
|
||||||
|
return iconConfig;
|
||||||
|
});
|
||||||
|
|
||||||
|
return icons;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSvgCode(cfg, item) {
|
||||||
|
log.debug('Getting svg code for ' + item.type + '-' + item.id);
|
||||||
|
|
||||||
|
let params = {
|
||||||
|
color: cfg.color || 'black',
|
||||||
|
path: item.data.d,
|
||||||
|
width: item.advWidth,
|
||||||
|
height: item.size,
|
||||||
|
shiftX: 0,
|
||||||
|
shiftY: -item.size - item.offset
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
`<svg width="${params.height}" height="${params.height}"` +
|
||||||
|
` viewBox="0 0 ${params.height} ${params.height}" preserveAspectRatio="xMinYMid slice">\n` +
|
||||||
|
`\t<svg width="${params.height}" height="${params.height}"` +
|
||||||
|
` viewBox="0 0 ${params.width} ${params.height}">\n` +
|
||||||
|
`\t\t<g transform="scale(1 -1) translate(${params.shiftX} ${params.shiftY})">\n` +
|
||||||
|
`\t\t\t<path d="${params.path}" fill="${params.color}" />\n` +
|
||||||
|
`\t\t</g>\n` +
|
||||||
|
`\t</svg>\n` +
|
||||||
|
`</svg>`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
load: load,
|
||||||
|
getSvgCode: getSvgCode
|
||||||
|
};
|
||||||
128
src/lib/handler/weather.js
Normal file
128
src/lib/handler/weather.js
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
const fs = require('fs-extra'),
|
||||||
|
util = require('util'),
|
||||||
|
log = require('./../logger'),
|
||||||
|
readFile = util.promisify(fs.readFile),
|
||||||
|
loadash = require('lodash'),
|
||||||
|
parseXml = util.promisify(require('xml2js').parseString);
|
||||||
|
|
||||||
|
async function load(cfg, item) {
|
||||||
|
let iconList = await loadIcons(cfg, item);
|
||||||
|
let icons = await loadFontData(cfg, item, iconList);
|
||||||
|
return icons;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadIcons(cfg, item) {
|
||||||
|
log.debug("Loading fa id's");
|
||||||
|
let content = await readFile(item.path + '/css/weather-icons.css');
|
||||||
|
let lines = content.toString();
|
||||||
|
|
||||||
|
let match,
|
||||||
|
result = [];
|
||||||
|
|
||||||
|
const regex = /wi-([\w-]*).*\s.*"\S([0-9a-f]+)"/g;
|
||||||
|
while ((match = regex.exec(lines))) {
|
||||||
|
result.push({
|
||||||
|
id: match[1],
|
||||||
|
unicodeHex: match[2],
|
||||||
|
unicodeDec: parseInt(match[2], 16)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadFontData(cfg, item, iconList) {
|
||||||
|
log.debug('Loading fa5 font-data');
|
||||||
|
|
||||||
|
let filesList = [item.path + '/font/weathericons-regular-webfont.svg'];
|
||||||
|
|
||||||
|
let fontData = [];
|
||||||
|
for (let key in filesList) {
|
||||||
|
let item = filesList[key];
|
||||||
|
let content = await readFile(item);
|
||||||
|
content = content.toString('utf-8');
|
||||||
|
|
||||||
|
let parsedXml = await parseXml(content),
|
||||||
|
glyph = parsedXml.svg.defs[0].font[0].glyph,
|
||||||
|
svghorz = parsedXml.svg.defs[0].font[0].$['horiz-adv-x'],
|
||||||
|
offset = parsedXml.svg.defs[0].font[0]['font-face'][0].$['descent'],
|
||||||
|
size = parsedXml.svg.defs[0].font[0]['font-face'][0].$['units-per-em'];
|
||||||
|
|
||||||
|
let fontDataItem = glyph
|
||||||
|
.filter(data => {
|
||||||
|
if (!data.$.unicode) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.map(data => {
|
||||||
|
return {
|
||||||
|
data: data.$,
|
||||||
|
unicodeDec: data.$.unicode.charCodeAt(0),
|
||||||
|
svghorz: svghorz,
|
||||||
|
offset: offset,
|
||||||
|
size: size
|
||||||
|
};
|
||||||
|
});
|
||||||
|
fontData = fontData.concat(fontDataItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
let indexFontData = await loadash.keyBy(fontData, 'unicodeDec');
|
||||||
|
|
||||||
|
let icons = iconList
|
||||||
|
.filter(icon => {
|
||||||
|
if (!indexFontData[icon.unicodeDec]) {
|
||||||
|
log.debug(`Skipping ${icon.unicodeHex}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.map(icon => {
|
||||||
|
let iconData = indexFontData[icon.unicodeDec];
|
||||||
|
|
||||||
|
let iconConfig = {
|
||||||
|
id: icon.id.split('-').join('_'),
|
||||||
|
type: item.type,
|
||||||
|
prefix: item.prefix,
|
||||||
|
unicodeHex: icon.unicodeHex,
|
||||||
|
unicodeDec: icon.unicodeDec,
|
||||||
|
data: iconData.data,
|
||||||
|
offset: parseInt(iconData.offset),
|
||||||
|
size: parseInt(iconData.size),
|
||||||
|
advWidth: parseInt(iconData.data['horiz-adv-x'] || iconData.svghorz)
|
||||||
|
};
|
||||||
|
return iconConfig;
|
||||||
|
});
|
||||||
|
|
||||||
|
return icons;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSvgCode(cfg, item) {
|
||||||
|
log.debug('Getting svg code for ' + item.type + '-' + item.id);
|
||||||
|
|
||||||
|
let params = {
|
||||||
|
color: cfg.color || 'black',
|
||||||
|
path: item.data.d,
|
||||||
|
width: item.advWidth,
|
||||||
|
height: item.size,
|
||||||
|
shiftX: item.advWidth / ((10 / 2) * 2),
|
||||||
|
shiftY: -item.size - item.offset - item.size / ((10 / 2) * 2)
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
`<svg width="${params.height}" height="${params.height}"` +
|
||||||
|
` viewBox="0 0 ${params.height} ${params.height}" preserveAspectRatio="xMinYMid slice">\n` +
|
||||||
|
`\t<svg width="${params.height}" height="${params.height}"` +
|
||||||
|
` viewBox="0 0 ${params.width} ${params.height}">\n` +
|
||||||
|
`\t\t<g transform="scale(1 -1) scale(0.8)` +
|
||||||
|
` translate(${params.shiftX} ${params.shiftY})">\n` +
|
||||||
|
`\t\t\t<path d="${params.path}" fill="${params.color}" />\n` +
|
||||||
|
`\t\t</g>\n` +
|
||||||
|
`\t</svg>\n` +
|
||||||
|
`</svg>`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
load: load,
|
||||||
|
getSvgCode: getSvgCode
|
||||||
|
};
|
||||||
237
src/lib/index.js
Normal file
237
src/lib/index.js
Normal file
@@ -0,0 +1,237 @@
|
|||||||
|
const Bluebird = require('bluebird'),
|
||||||
|
cliOptions = require('./cliOptions.js'),
|
||||||
|
cliUsage = require('command-line-usage'),
|
||||||
|
fs = require('fs-extra'),
|
||||||
|
path = require('path'),
|
||||||
|
ProgressBar = require('progress'),
|
||||||
|
utils = require('./utils');
|
||||||
|
|
||||||
|
// config
|
||||||
|
const cfg = require('./config');
|
||||||
|
const log = require('./logger');
|
||||||
|
|
||||||
|
if (cfg.devel) {
|
||||||
|
cfg.limit = cfg.limit == 0 ? 5 : cfg.limit;
|
||||||
|
cfg.verbose = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfg.verbose) {
|
||||||
|
log.level = 'debug';
|
||||||
|
} else {
|
||||||
|
log.level = 'warn';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfg.help) {
|
||||||
|
const usage = cliUsage([
|
||||||
|
{
|
||||||
|
header: 'Options',
|
||||||
|
optionList: cliOptions,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
process.stdout.write(usage);
|
||||||
|
} else {
|
||||||
|
printInfo();
|
||||||
|
generate();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function generate() {
|
||||||
|
const fonts = require('./fonts');
|
||||||
|
let work = [],
|
||||||
|
icons = [];
|
||||||
|
|
||||||
|
if (cfg.github) {
|
||||||
|
cfg.png = true;
|
||||||
|
cfg.puml = true;
|
||||||
|
cfg.colors = ['black'];
|
||||||
|
cfg.sizes = [48];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfg.devel) {
|
||||||
|
cfg.png = true;
|
||||||
|
cfg.puml = true;
|
||||||
|
cfg.svg = true;
|
||||||
|
cfg.limit = 25;
|
||||||
|
cfg.sizes = [128];
|
||||||
|
cfg.icons = [
|
||||||
|
'fa5-user_alt',
|
||||||
|
'fa5-gitlab',
|
||||||
|
'fa5-server',
|
||||||
|
'fa5-database',
|
||||||
|
'fa-gears',
|
||||||
|
'fa-fire',
|
||||||
|
'fa-clock_o',
|
||||||
|
'fa-lock',
|
||||||
|
'fa-cloud',
|
||||||
|
'fa-server',
|
||||||
|
'dev-nginx',
|
||||||
|
'dev-mysql',
|
||||||
|
'dev-redis',
|
||||||
|
'dev-docker',
|
||||||
|
'dev-linux',
|
||||||
|
'dev2-html5',
|
||||||
|
'gov-ambulance',
|
||||||
|
'weather-night_alt_thunderstorm',
|
||||||
|
'material-3d_rotation',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
icons = await fonts.load(cfg);
|
||||||
|
} catch (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug(`Starting work for ${icons.length} icons`);
|
||||||
|
|
||||||
|
let progressBar = new ProgressBar('working [:bar] :percent :etas :info', {
|
||||||
|
complete: '=',
|
||||||
|
incomplete: ' ',
|
||||||
|
width: 50,
|
||||||
|
total: icons.length,
|
||||||
|
});
|
||||||
|
|
||||||
|
work.push(
|
||||||
|
Bluebird.map(
|
||||||
|
icons,
|
||||||
|
(item) => {
|
||||||
|
if (cfg.progress) {
|
||||||
|
progressBar.tick({
|
||||||
|
info: item.type + '-' + item.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return fonts.generate(cfg, item);
|
||||||
|
},
|
||||||
|
{
|
||||||
|
concurrency: cfg.concurrency,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
await Promise.all(work);
|
||||||
|
|
||||||
|
if (cfg.release) {
|
||||||
|
// copy icons to project
|
||||||
|
for (let item of cfg.fonts) {
|
||||||
|
log.debug('Copying ' + item.name);
|
||||||
|
|
||||||
|
let releasePath = cfg.dirs.project + '/' + item.name,
|
||||||
|
pngPath = cfg.dirs.build + '/' + item.type + '/png/' + cfg.sizes[0],
|
||||||
|
pumlPath = cfg.dirs.build + '/' + item.type + '/puml';
|
||||||
|
|
||||||
|
await fs.ensureDirSync(releasePath);
|
||||||
|
await fs.emptyDirSync(releasePath);
|
||||||
|
|
||||||
|
let files = await utils.getFiles(pngPath);
|
||||||
|
files = files
|
||||||
|
.map((file) => {
|
||||||
|
return {
|
||||||
|
file: path.parse(file).name + path.parse(file).ext,
|
||||||
|
name: path.parse(file).name,
|
||||||
|
ext: path.parse(file).ext,
|
||||||
|
path: file,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.sort(function (a, b) {
|
||||||
|
return a.name > b.name ? 1 : b.name > a.name ? -1 : 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
log.debug('Found ' + item.name + ' ' + files.length);
|
||||||
|
|
||||||
|
let indexFileName = releasePath + '/index.md';
|
||||||
|
let indexContent = `# ${item.name}\n\n\n`;
|
||||||
|
indexContent += `### Overview\n`;
|
||||||
|
indexContent += `| Name | Macro | Image | Url |\n`;
|
||||||
|
indexContent += `|-------|--------|-------|-----|\n`;
|
||||||
|
|
||||||
|
for (let file of files) {
|
||||||
|
await fs.copyFileSync(file.path, releasePath + '/' + file.file);
|
||||||
|
|
||||||
|
indexContent += `${file.name} |`;
|
||||||
|
indexContent += `${item.type.toUpperCase()}_${file.name.toUpperCase()} |`;
|
||||||
|
indexContent += ` |`;
|
||||||
|
indexContent += `${file.name}.puml |\n`;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.writeFileSync(indexFileName, indexContent);
|
||||||
|
|
||||||
|
let pumlFiles = await utils.getFiles(pumlPath);
|
||||||
|
pumlFiles = pumlFiles
|
||||||
|
.map((file) => {
|
||||||
|
return {
|
||||||
|
file: path.parse(file).name + path.parse(file).ext,
|
||||||
|
name: path.parse(file).name,
|
||||||
|
ext: path.parse(file).ext,
|
||||||
|
path: file,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.sort(function (a, b) {
|
||||||
|
return a.name > b.name ? 1 : b.name > a.name ? -1 : 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
for (let file of pumlFiles) {
|
||||||
|
await fs.copyFileSync(file.path, releasePath + '/' + file.file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Render examples
|
||||||
|
let examplesPath = cfg.dirs.project + '/examples';
|
||||||
|
let exampleFiles = await utils.getFiles(examplesPath);
|
||||||
|
exampleFiles = exampleFiles.filter((file) => path.parse(file).ext === '.puml');
|
||||||
|
|
||||||
|
for (let file of exampleFiles) {
|
||||||
|
await renderPuml(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Done');
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderPuml(path) {
|
||||||
|
return new Promise(function (resolve, reject) {
|
||||||
|
var plantumlJar,
|
||||||
|
error = '';
|
||||||
|
|
||||||
|
var plantumlParams = ['-Djava.awt.headless=true', '-jar', cfg.binPlantuml, path];
|
||||||
|
|
||||||
|
log.debug('java ' + plantumlParams.join(' '));
|
||||||
|
|
||||||
|
plantumlJar = require('child_process').spawn('java', plantumlParams);
|
||||||
|
plantumlJar.stderr.on('data', (data) => {
|
||||||
|
error += data.toString();
|
||||||
|
});
|
||||||
|
plantumlJar.once('close', function (code) {
|
||||||
|
if (code > 0) {
|
||||||
|
reject(error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function printInfo() {
|
||||||
|
// info
|
||||||
|
let msg = '\nSettings:\n';
|
||||||
|
if (cfg.icons.length > 0) {
|
||||||
|
msg += 'icons: ';
|
||||||
|
cfg.icons.forEach((element) => (msg += ' ' + element));
|
||||||
|
} else {
|
||||||
|
msg += 'fonts: ';
|
||||||
|
cfg.fonts.forEach((element) => (msg += ' ' + element.name));
|
||||||
|
}
|
||||||
|
|
||||||
|
msg += '\nformats:';
|
||||||
|
msg += cfg.puml ? ' puml' : '';
|
||||||
|
msg += cfg.png ? ' png' : '';
|
||||||
|
msg += cfg.svg ? ' svg' : '';
|
||||||
|
|
||||||
|
msg += cfg.limit > 0 ? ' \nlimit: ' + cfg.limit : '';
|
||||||
|
|
||||||
|
msg += '\ncolors: ';
|
||||||
|
cfg.colors.forEach((element) => (msg += ' ' + element));
|
||||||
|
|
||||||
|
msg += '\nsizes: ';
|
||||||
|
cfg.sizes.forEach((element) => (msg += ' ' + element));
|
||||||
|
|
||||||
|
log.debug(msg);
|
||||||
|
}
|
||||||
54
src/lib/logger.js
Normal file
54
src/lib/logger.js
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
/**
|
||||||
|
* Based on https://gist.github.com/spmason/1670196
|
||||||
|
*/
|
||||||
|
const util = require('util'),
|
||||||
|
winston = require('winston'),
|
||||||
|
logger = new winston.Logger(),
|
||||||
|
env = (process.env.NODE_ENV || '').toLowerCase(),
|
||||||
|
dateFormat = require('dateformat');
|
||||||
|
|
||||||
|
// Override the built-in console methods with winston hooks
|
||||||
|
switch (env) {
|
||||||
|
case 'production':
|
||||||
|
logger.add(winston.transports.File, {
|
||||||
|
filename: __dirname + '/application.log',
|
||||||
|
handleExceptions: true,
|
||||||
|
exitOnError: false
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'test':
|
||||||
|
// Don't set up the logger overrides
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
logger.add(winston.transports.Console, {
|
||||||
|
colorize: true,
|
||||||
|
timestamp: function() {
|
||||||
|
return dateFormat(new Date(), 'HH:MM:ss');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatArgs(args) {
|
||||||
|
return [util.format.apply(util.format, Array.prototype.slice.call(args))];
|
||||||
|
}
|
||||||
|
console.log = function() {
|
||||||
|
logger.debug.apply(logger, formatArgs(arguments));
|
||||||
|
};
|
||||||
|
console.info = function() {
|
||||||
|
logger.info.apply(logger, formatArgs(arguments));
|
||||||
|
};
|
||||||
|
console.warn = function() {
|
||||||
|
logger.warn.apply(logger, formatArgs(arguments));
|
||||||
|
};
|
||||||
|
console.error = function() {
|
||||||
|
logger.error.apply(logger, formatArgs(arguments));
|
||||||
|
};
|
||||||
|
console.debug = function() {
|
||||||
|
logger.debug.apply(logger, formatArgs(arguments));
|
||||||
|
};
|
||||||
|
console.progress = function() {
|
||||||
|
logger.debug.apply(logger, formatArgs(arguments));
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = logger;
|
||||||
54
src/lib/utils.js
Normal file
54
src/lib/utils.js
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
const fs = require('fs-extra'),
|
||||||
|
git = require('isomorphic-git'),
|
||||||
|
http = require('isomorphic-git/http/node'),
|
||||||
|
log = require('./logger'),
|
||||||
|
{ promisify } = require('util'),
|
||||||
|
{ resolve } = require('path'),
|
||||||
|
readdir = promisify(fs.readdir),
|
||||||
|
stat = promisify(fs.stat);
|
||||||
|
|
||||||
|
async function repo(repo, branch, target) {
|
||||||
|
log.debug('Loading Repo ' + repo + ' into ' + target);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await fs.ensureDirSync(target);
|
||||||
|
|
||||||
|
// check if it already exists
|
||||||
|
log.debug(`checking dir ${target}/.git for repo`);
|
||||||
|
const repoExists = fs.existsSync(target + '/.git');
|
||||||
|
|
||||||
|
if (!repoExists) {
|
||||||
|
await git.clone({
|
||||||
|
fs,
|
||||||
|
http,
|
||||||
|
dir: target,
|
||||||
|
url: repo,
|
||||||
|
singleBranch: true,
|
||||||
|
ref: branch,
|
||||||
|
depth: 10,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info(`checkout ${repo} branch:${branch} completed to dir ${target}`);
|
||||||
|
} catch (err) {
|
||||||
|
log.error('repo error', err);
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getFiles(dir) {
|
||||||
|
const subdirs = await readdir(dir);
|
||||||
|
const files = await Promise.all(
|
||||||
|
subdirs.map(async (subdir) => {
|
||||||
|
const res = resolve(dir, subdir);
|
||||||
|
return (await stat(res)).isDirectory() ? getFiles(res) : res;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
return files.reduce((a, f) => a.concat(f), []);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
repo: repo,
|
||||||
|
getFiles: getFiles,
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user