UNPKG

3.65 kBJavaScriptView Raw
1
2
3import fs from 'fs'
4import path from 'path'
5import glob from 'glob'
6import matter from 'gray-matter';
7import removeMd from 'remove-markdown';
8import { stripHtml } from "string-strip-html";
9
10const DEFAULT_LANGUAGE = 'ru'
11const CONTENT_PATH = 'content/**'
12const OUTPUT_INDEX_FILE = 'public/search-index.json'
13
14class HugoIndexer {
15
16 constructor() {
17 this.input = CONTENT_PATH
18 this.output = OUTPUT_INDEX_FILE;
19 this.baseDir = path.dirname(this.input);
20 this.extensions = ['.md', '.html']
21
22 this.indexData = {} // result index
23 this.indexData[DEFAULT_LANGUAGE] = []
24
25 this._parseArgs()
26 }
27
28 _parseArgs() {
29 if (process.argv.indexOf("-i") != -1) {
30 // input
31 this.input = process.argv[process.argv.indexOf("-i") + 1];
32 console.log(process.argv.indexOf("-i"))
33 }
34 if (process.argv.indexOf("-o") != -1) {
35 // output
36 this.output = process.argv[process.argv.indexOf("-o") + 1];
37 }
38 }
39
40 parseContent(dirPath) {
41 const files = glob.sync(dirPath)
42 for (let file of files) {
43 const stats = fs.lstatSync(file)
44 if (stats.isFile()) {
45 this.parseFile(file)
46 }
47 }
48 }
49
50 parseFile(filePath) {
51 const ext = path.extname(filePath)
52
53 if (!this.extensions.includes(ext)) {
54 return // not .md or .html
55 }
56
57 const meta = matter.read(filePath);
58 const { data: postMeta, content: postContent } = meta
59
60 let plainText = ""
61 if (ext == '.md') {
62 plainText = removeMd(postContent);
63 } else if (ext == '.html') {
64 plainText = stripHtml(postContent);
65 } else {
66 console.log("Sikpped file: " + filePath)
67 }
68
69 let tags = [];
70
71 if (postMeta.tags != undefined) {
72 tags = postMeta.tags;
73 }
74
75 let [lang, uri] = this._getPostUrl(filePath, postMeta)
76
77 const item = {
78 'uri': uri,
79 'title': postMeta.title,
80 'content': plainText,
81 'tags': tags
82 };
83
84 if (lang) {
85 item['lang'] = lang
86 } else {
87 lang = DEFAULT_LANGUAGE
88 }
89
90 const indexPosts = this.indexData[lang] || []
91 indexPosts.push(item)
92 this.indexData[lang] = indexPosts
93
94 }
95
96 _getPostUrl(filePath, postMeta) {
97
98 let uri = '/' + filePath.substring(0, filePath.lastIndexOf('.')); // remove extension .md || .html
99 uri = uri.replace(this.baseDir + '/', '');
100
101 let lang = path.extname(uri);
102
103 if (lang) {
104 // remove lang extension [.en] etc
105 lang = lang.replace('.', '')
106 uri = uri.substring(0, uri.lastIndexOf('.'));
107 }
108
109 if (uri.endsWith('/index')) {
110 uri = uri.slice(0, -5)
111 }
112
113 if (postMeta.slug != undefined) {
114 uri = path.dirname(uri) + postMeta.slug;
115 }
116
117 if (postMeta.url != undefined) {
118 uri = postMeta.url
119 }
120
121 return [lang, uri]
122
123 }
124
125 _setInput(dirPath) {
126 this.input = dirPath
127 }
128
129 setOutput(filePath) {
130 this.output = filePath
131 }
132
133 createIndex() {
134
135 console.log(`Arguments: input: ${this.input}, output: ${this.output}`)
136
137 this.stream = fs.createWriteStream(this.output);
138
139 this.parseContent(this.input)
140
141 this.stream.write(JSON.stringify(this.indexData, null, 4));
142 this.stream.end()
143
144 console.info(`Saved index: ${this.output}`)
145
146 }
147
148}
149
150export { HugoIndexer, CONTENT_PATH, OUTPUT_INDEX_FILE }
\No newline at end of file