Skip to content

Commit 3b115d7

Browse files
qzhou1607-zzalrra
authored andcommitted
Add a script to copy files and add frontmatter
* Given a path, extract the correct `category`, `title`, `toc-title` and `permalink` information from each file. * Given a path, add front matter to each file. * Move the docs index page to a separate folder so that it won't be replaced during the copying of files. * Use regex to find `title` in each file to generate TOC. * Use `path` module to process the the filePaths and generate front matter content. * If the file already has front matter, update the existing front matter and avoid duplicity. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1 parent 1799ae5 commit 3b115d7

File tree

5 files changed

+173
-83
lines changed

5 files changed

+173
-83
lines changed

package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
"hexo-renderer-stylus": "^0.3.1",
1414
"hexo-server": "^0.2.0",
1515
"js-yaml": "^3.8.3",
16-
"lodash": "^4.17.4"
16+
"klaw": "^1.3.1",
17+
"lodash": "^4.17.4",
18+
"pify": "^2.3.0"
1719
},
1820
"devDependencies": {
1921
"@alrra/travis-scripts": "^3.0.1",
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
category: default
2+
permalink: docs/index.html
23
---
34
* [Developer Guide](developer-guide/collectors/how-to-develop-a-collector.html)
45
* [User Guide](user-guide/rules/disallowed-headers.html)

themes/documentation/helper/index.js

+93-82
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module.exports = function () {
2-
return {
2+
return {
33
/**
44
* Handlebars Comparison Helpers
55
* Copyright (c) 2013 Jon Schlinkert, Brian Woodward, contributors
@@ -28,95 +28,106 @@ module.exports = function () {
2828
* The value is lower than 10
2929
* {{/compare}}
3030
*/
31-
compare: function (left, operator, right, options) { // eslint-disable-line object-shorthand
32-
if (arguments.length < 3) {
33-
throw new Error('Handlebars Helper "compare" needs 2 parameters');
34-
}
31+
compare: function (left, operator, right, options) { // eslint-disable-line object-shorthand
32+
if (arguments.length < 3) {
33+
throw new Error('Handlebars Helper "compare" needs 2 parameters');
34+
}
3535

36-
if (!options) {
37-
/*eslint-disable no-param-reassign*/
38-
options = right;
39-
right = operator;
40-
operator = '===';
41-
/*eslint-enable no-param-reassign*/
42-
}
36+
/* eslint-disable no-param-reassign */
37+
if (!options) {
38+
options = right;
39+
right = operator;
40+
operator = '===';
41+
}
42+
/* eslint-enable no-param-reassign */
4343

44-
const operators = {
45-
'!=': (l, r) => {
46-
return l !== r;
47-
},
48-
'!==': (l, r) => {
49-
return l !== r;
50-
},
51-
'<': (l, r) => {
52-
return l < r;
53-
},
54-
'<=': (l, r) => {
55-
return l <= r;
56-
},
57-
'==': (l, r) => {
58-
return l === r;
59-
},
60-
'===': (l, r) => {
61-
return l === r;
62-
},
63-
'>': (l, r) => {
64-
return l > r;
65-
},
66-
'>=': (l, r) => {
67-
return l >= r;
68-
},
69-
typeof: (l, r) => {
70-
return typeof l === r;
71-
},
72-
'||': (l, r) => {
73-
return l || r;
74-
}
75-
};
44+
const operators = {
45+
'!=': (l, r) => {
46+
return l !== r;
47+
},
48+
'!==': (l, r) => {
49+
return l !== r;
50+
},
51+
'<': (l, r) => {
52+
return l < r;
53+
},
54+
'<=': (l, r) => {
55+
return l <= r;
56+
},
57+
'==': (l, r) => {
58+
return l === r;
59+
},
60+
'===': (l, r) => {
61+
return l === r;
62+
},
63+
'>': (l, r) => {
64+
return l > r;
65+
},
66+
'>=': (l, r) => {
67+
return l >= r;
68+
},
69+
typeof: (l, r) => {
70+
return typeof l === r;
71+
},
72+
'||': (l, r) => {
73+
return l || r;
74+
}
75+
};
7676

77-
if (!operators[operator]) {
78-
throw new Error(`Handlebars Helper "compare" doesn't know the operator ${operator}`);
79-
}
77+
if (!operators[operator]) {
78+
throw new Error(`Handlebars Helper "compare" doesn't know the operator ${operator}`);
79+
}
8080

81-
const result = operators[operator](left, right);
81+
const result = operators[operator](left, right);
8282

83-
if (result) {
84-
return options.fn(this);
85-
}
83+
if (result) {
84+
return options.fn(this);
85+
}
8686

87-
return options.inverse(this);
88-
},
89-
getAboutItems: (navs) => {
90-
// `navs` is the menu data saved in `menu.yml`.
91-
return navs[2].items;
92-
},
93-
getDocumentItems: (navs) => {
94-
// `navs` is the menu data saved in `menu.yml`.
95-
return navs[1].items;
96-
},
97-
getSubPages: function (allPages, category) { // eslint-disable-line object-shorthand
98-
return allPages.reduce((acc, page) => {
99-
if (page.category === category) {
100-
const tocTitle = page['toc-title'];
87+
return options.inverse(this);
88+
},
89+
getAboutItems: (navs) => {
90+
// `navs` is the menu data saved in `menu.yml`.
91+
return navs[2].items;
92+
},
93+
getDocumentItems: (navs) => {
94+
// `navs` is the menu data saved in `menu.yml`.
95+
return navs[1].items;
96+
},
97+
getSubPages: function (allPages, category) { // eslint-disable-line object-shorthand
98+
return allPages.reduce((acc, page) => {
99+
if (page.category === category) {
100+
const tocTitle = page['toc-title'];
101101

102-
if (!acc[tocTitle]) {
103-
acc[tocTitle] = [page];
104-
} else {
105-
acc[tocTitle].push(page);
106-
}
107-
}
102+
if (!acc[tocTitle]) {
103+
acc[tocTitle] = [page];
104+
} else {
105+
acc[tocTitle].push(page);
106+
}
107+
}
108108

109-
return acc;
110-
}, {});
111-
},
112-
hasSubPage: function (id, options) { // eslint-disable-line object-shorthand
113-
const result = (id === 'docs' || id === 'about');
109+
return acc;
110+
}, {});
111+
},
112+
hasSubPage: function (id, options) { // eslint-disable-line object-shorthand
113+
const result = (id === 'docs' || id === 'about');
114114

115-
if (result) {
116-
return options.fn(this);
117-
}
115+
if (result) {
116+
return options.fn(this);
117+
}
118118

119-
return options.inverse(this);
120-
}
121-
};
119+
return options.inverse(this);
120+
},
121+
hasTocTitle: (tocTitle, options) => {
122+
// Some files are placed directly under `developer-guide` or `user-guide`.
123+
// These files don't contain `toc-title` entries in their front matter.
124+
const result = (tocTitle !== 'undefined');
125+
126+
if (result) {
127+
return options.fn(this);
128+
}
129+
130+
return options.inverse(this);
131+
}
132+
};
122133
};

themes/documentation/layout/partials/sub-page.hbs

+2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@
2727
</div>
2828
<div class="module module--secondary table-of-contents" role="navigation">
2929
{{#each pages}}
30+
{{#hasTocTitle @key}}
3031
<p class="toc-section-title--active">{{@key}}</p>
32+
{{/hasTocTitle}}
3133
<ul class="toc-subsection-title">
3234
{{#each this}}
3335
<li>

updater.js

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
const klaw = require('klaw');
2+
const _ = require('lodash');
3+
const path = require('path');
4+
const pify = require('pify');
5+
6+
const directory = path.resolve(process.argv[2]); // path to the folder that contains md files
7+
const filePaths = [];
8+
9+
const fs = pify(require('fs'));
10+
11+
console.log('Updater is initiated.');
12+
13+
const generateFrontMatterInfo = (filePath, title) => {
14+
const relativePath = path.relative(directory, filePath);
15+
const baseName = path.basename(relativePath, '.md');
16+
17+
const [category, tocTitle] = path.dirname(relativePath).split(path.sep);
18+
const permaLink = path.join('docs', path.dirname(relativePath), `${baseName}.html`);
19+
20+
const categoryFrontMatter = `category: ${category}`;
21+
const titleFrontMatter = `title: ${title}`;
22+
const permalinkFrontMatter = `permalink: ${permaLink}`;
23+
const divider = '---';
24+
const frontMatter = [categoryFrontMatter, titleFrontMatter, permalinkFrontMatter, divider];
25+
26+
if (tocTitle) {
27+
const tocTitleFrontMatter = `toc-title: ${tocTitle}`;
28+
29+
frontMatter.unshift(tocTitleFrontMatter);
30+
}
31+
32+
return frontMatter.join('\n');
33+
};
34+
35+
const addFrontMatter = async (filePath) => {
36+
let content;
37+
const data = await fs.readFile(filePath, 'utf8');
38+
39+
if (data.includes('---')) {
40+
// front matter already exists in this file, will update it
41+
[, content] = data.split('---\n');
42+
} else {
43+
content = data;
44+
}
45+
46+
const title = _.trim(content.match(/# (.*)\n\n/).pop().replace(/\(.*\)/, ''));
47+
48+
const frontMatter = generateFrontMatterInfo(filePath, title);
49+
50+
const newData = `${frontMatter}\n${content}`;
51+
52+
await fs.writeFile(filePath, newData);
53+
};
54+
55+
56+
57+
// Iterate all the files in the dest folder and add frontmatter to each file
58+
klaw(directory)
59+
.on('data', (item) => {
60+
if (_.endsWith(item.path, '.md')) {
61+
filePaths.push(item.path);
62+
}
63+
})
64+
.on('error', (err, item) => {
65+
console.log(err.message, item.path);
66+
})
67+
.on('end', async () => {
68+
const promises = filePaths.map(addFrontMatter);
69+
70+
await Promise.all(promises);
71+
72+
console.log('Front Matter added to each file.')
73+
});
74+

0 commit comments

Comments
 (0)