Files
RSSHub/docs/.format/format.js
2021-11-27 07:06:38 +00:00

127 lines
3.7 KiB
JavaScript

const file = require('./file');
const sgf = require('staged-git-files');
const path = require('path');
const sortByHeading = require('./sortByHeading');
const chineseFormat = require('./chineseFormat');
const util = require('util');
const exec = util.promisify(require('child_process').exec);
/**
* Processors are objects contains two methods:
* `rules(list)`, and `handler(str)`
* rules filters required file document object
* and handler get document string and return formatted document
*/
const processors = [sortByHeading, chineseFormat];
// Helpers
const loopSideBar = (children, type, lang, prefix) =>
children
.filter((e) => e !== '')
.map((x) => ({
path: path.resolve(__dirname, '..', prefix, `./${x}.md`),
type,
lang,
}));
const loopNav = (nav, lang) =>
nav.flatMap((e) => {
if (e.items) {
return loopNav(e.items, lang);
}
if (e.link.endsWith('/')) {
return {
path: path.resolve(__dirname, '..', e.link.slice(1), 'README.md'),
type: file.NAV_TYPE,
lang,
};
} else {
return {
path: path.resolve(__dirname, '..', `${e.link.replace(/^\//, '')}.md`),
type: file.NAV_TYPE,
lang,
};
}
});
const loopType = (sidebar, lang, prefix) => loopSideBar(sidebar[0].children, file.GUIDE_TYPE, lang, prefix).concat(loopSideBar(sidebar[1].children, file.ROUTE_TYPE, lang, prefix));
/**
* Iterate config and build document object:
* E.g.
* {
path: 'docs/en/other.md', <-- full path here
type: 'route', <--- Defined in file.js
lang: 'en' <-- Defined in file.js
}
*/
const buildFileList = async () => {
const config = require(`../.vuepress/config`);
let fileList = [];
Object.keys(config.themeConfig.locales).forEach((key) => {
const locale = config.themeConfig.locales[key];
const key_path = key.slice(1);
if (locale.hasOwnProperty('sidebar')) {
fileList = fileList.concat(loopType(locale.sidebar[key], locale.lang, key_path));
}
if (locale.hasOwnProperty('nav')) {
fileList = fileList.concat(loopNav(locale.nav, locale.lang));
}
});
return fileList;
};
/**
* Select files that only being modified
* Same format as `buildFileList()`
*/
const buildStagedList = async () => {
const stagedFiles = await sgf();
const stagedFileList = [];
stagedFiles.forEach((e) => {
if (e.filename.endsWith('.md')) {
stagedFileList.push(e.filename);
}
});
const fullFileList = await buildFileList();
const result = [];
stagedFileList.forEach((e) => {
const f = fullFileList.find((x) => x.path.indexOf(e) !== -1);
if (f) {
result.push(f);
}
});
return result;
};
/** Entry
* Usage: node format.js --full/--staged
*/
(async () => {
// Mode
const flag = process.argv[2] || '--full';
let fileList = [];
switch (flag) {
case '--staged':
fileList = await buildStagedList();
break;
case '--full':
default:
fileList = await buildFileList();
}
// console.log(fileList);
// return
const stagedFiles = await sgf();
for (const processor of processors) {
for (const e of processor.rules(fileList)) {
let formatted = await file.readFile(e.path);
formatted = await processor.handler(formatted);
await file.writeFile(e.path, formatted);
if (stagedFiles.find((x) => e.path.indexOf(x.filename) !== -1)) {
await exec(`git add ${e.path}`);
}
}
}
})();