-
Notifications
You must be signed in to change notification settings - Fork 99
Expand file tree
/
Copy pathbuildSearch.mjs
More file actions
145 lines (126 loc) · 4.29 KB
/
Copy pathbuildSearch.mjs
File metadata and controls
145 lines (126 loc) · 4.29 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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#!/usr/bin/env node
/**
* This library generates a Lunr full-text search index to be used on the
* docs site. It finds all Markdown files in `/docs` folder and adds them
* to the Lunr index. The index is then saved as a JSON file in the docs
* site to be loaded on demand.
*/
import fs from 'fs';
import { sync } from 'glob';
import lodash from 'lodash';
import lunr from 'lunr';
import { marked } from 'marked';
import path from 'path';
import shell from 'shelljs';
import stripChars from '../app/libs/stripChars.mjs';
// atomizer rules
import atomizerRules from '../packages/atomizer/src/rules.js';
// consts
const DOCS_PATH = path.join(process.cwd(), 'docs');
const INDEX_DB_FILE = path.join(DOCS_PATH, 'assets', 'lunr.json');
const DESCRIPTION_REGEX = /^description:\s(.*)$/im;
// Find the description from jekyll frontmatter
const findDescription = (str) => {
const matches = str && str.match(DESCRIPTION_REGEX);
return matches && matches[1];
};
// docs like `i18n` end up as `I 18 N` after lodash
// formats it. this removes the space
const fixNumeronym = (file) => {
if (/[A-Z]\s(\d+)\s[A-Z]/.test(file)) {
file = file.replace(/\s+/g, '');
}
return file;
};
const formatTitle = (file) => {
// remove extension
file = file.replace('.md', '');
// split file e.g. dev/ci.md
const split = file.split('/');
// some docs don't have categories
let category = '';
if (split[1]) {
category = `${lodash.startCase(split[0])} - `;
}
const filename = fixNumeronym(lodash.startCase(split[1] || split[0]));
return category + filename;
};
// set default options
marked.setOptions({
renderer: new marked.Renderer(),
gfm: true,
tables: true,
breaks: false,
pedantic: false,
smartLists: true,
smartypants: false,
});
// used as a look up for doc information against a lunr search query
const docs = {};
// file docs to parse
const pattern = '**/*.md';
const globOpts = {
cwd: DOCS_PATH,
ignore: ['**/index.md', '404.md', 'README.md'],
};
const files = sync(pattern, globOpts);
// setup index
const index = lunr(function () {
console.log('Creating lunr index');
this.ref('id');
this.field('title', { boost: 10 });
this.field('body', { boost: 5 });
this.field('description', { boost: 3 });
this.field('permalink');
// add files to index
if (files.length) {
console.log('Generating index...');
for (let i = 0; i < files.length; i++) {
const file = files[i];
const filepath = path.join(DOCS_PATH, file);
const markdown = fs.readFileSync(filepath, 'utf-8').split('---');
const description = findDescription(markdown[1]);
const body = markdown.slice(2, markdown.length).join('');
const doc = {
id: file,
description,
title: formatTitle(file),
body,
permalink: `/${file.replace('.md', '.html')}`,
};
// use marked to generate tokens for snippet generation later
doc.tokens = marked
.lexer(body)
.filter((tokens) => tokens.type === 'html')
.map((token) => {
// parse the markdown and strip tags
token.text = marked(token.text).replace(/(<([^>]+)>)/gi, '');
return token;
});
this.add(doc);
docs[doc.id] = doc;
}
}
// add rules to index
for (const rule of atomizerRules) {
// ignore rules which would confuse users
if (rule.name.includes('deprecated')) {
continue;
}
const id = stripChars(rule.name);
const doc = {
id,
title: `${rule.matcher}() - ${Object.keys(rule.styles)[0]}: value`,
body: `${rule.name} - ${rule.matcher}`,
permalink: `/reference.html#${id}`,
};
this.add(doc);
docs[id] = doc;
}
});
// save index to file to load in jekyll docs
console.log('Saving index...');
fs.writeFileSync(INDEX_DB_FILE, JSON.stringify({ docs, index: index.toJSON() }));
// copy lunr library to docs site to use in browser
console.log('Copying "lunr.min.js" library to /docs/assets/js...');
shell.exec('cp node_modules/lunr/lunr.min.js docs/assets/js/');