-
Notifications
You must be signed in to change notification settings - Fork 71
Expand file tree
/
Copy pathfaq_to_json.js
More file actions
114 lines (94 loc) · 3.25 KB
/
Copy pathfaq_to_json.js
File metadata and controls
114 lines (94 loc) · 3.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
const path = require("path");
const fs = require("fs");
const { marked } = require("marked");
const usage = 'Usage: node faq_to_json.js --dir faq --out ../editor/static/json/howdoi.json';
const args = process.argv.slice(2);
if (args.length === 0) {
console.log(usage);
process.exit(-1);
}
let ind = args.indexOf('--dir');
if (ind === -1 || !args[ind + 1]) {
console.log(usage);
process.exit(-1);
}
const sourceDir = args[ind + 1];
ind = args.indexOf('--out');
if (ind === -1 || !args[ind + 1]) {
console.log(usage);
process.exit(-1);
}
const outfile = args[ind + 1];
// parse frontmatter from markdown content
const parseFrontmatter = (content) => {
// normalize line endings to \n
const normalized = content.replace(/\r\n/g, '\n');
const match = normalized.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
if (!match) {
return { frontmatter: {}, body: normalized };
}
const frontmatter = {};
match[1].split('\n').forEach(line => {
const [key, ...valueParts] = line.split(':');
if (key && valueParts.length) {
frontmatter[key.trim()] = valueParts.join(':').trim();
}
});
return { frontmatter, body: match[2] };
};
// read all markdown files from the source directory
const faqDir = path.join(__dirname, sourceDir);
let files;
try {
if (!fs.existsSync(faqDir)) {
console.error(`Error: Directory '${faqDir}' does not exist.`);
process.exit(1);
}
const stat = fs.statSync(faqDir);
if (!stat.isDirectory()) {
console.error(`Error: '${faqDir}' is not a directory.`);
process.exit(1);
}
files = fs.readdirSync(faqDir).filter(f => f.endsWith('.md'));
} catch (err) {
console.error(`Error reading directory '${faqDir}': ${err && err.message ? err.message : err}`);
process.exit(1);
}
files.sort();
const json = [];
for (const file of files) {
const content = fs.readFileSync(path.join(faqDir, file), 'utf8');
const { frontmatter, body } = parseFrontmatter(content);
let html = marked.parse(body);
// links clicked in the Editor should open a new tab
html = html.replace(/<a\b[^>]*>/g, (match) => {
// If the anchor already has a target attribute, leave it unchanged
if (/\btarget\s*=/.test(match)) {
return match;
}
// Otherwise, insert target="_blank" before the href (or at the end if no href)
if (/\shref\s*=/.test(match)) {
return match.replace(/\s+href\s*=/, ' target="_blank" href=');
}
return match.replace(/<a\b/, '<a target="_blank"');
});
// style buttons in the Editor
html = html.replace('>Learn more<', ' class="docs">View User Manual<');
html = html.replace('>View tutorial<', ' class="docs">View Tutorial<');
// add close button
html += '\n<button class="close">GOT IT</button>';
// add data to json
const keywords = frontmatter.keywords
? frontmatter.keywords.replace(/\s+/g, '').split(',')
: [];
json.push({
title: frontmatter.title || file.replace('.md', ''),
html: html,
keywords: keywords
});
}
const jsonStr = JSON.stringify(json, null, 4);
// save json file
console.log(`Saving ${outfile}...`);
fs.writeFileSync(outfile, jsonStr);
console.log('Done.');