|
|
@@ -0,0 +1,67 @@
|
|
|
+const slug = require('slug');
|
|
|
+
|
|
|
+function makeSlug(title) {
|
|
|
+ return slug(title, {lower: true});
|
|
|
+}
|
|
|
+
|
|
|
+function extractTitleAndPath(markdown) {
|
|
|
+ const titleRegex = /^#\s(.*)/mi;
|
|
|
+ let title;
|
|
|
+ try {
|
|
|
+ [, title] = markdown.match(titleRegex);
|
|
|
+ } catch(e) {
|
|
|
+ throw new Error('Could not find h1 title');
|
|
|
+ }
|
|
|
+ const path = `/${makeSlug(title)}`;
|
|
|
+ return { title, path };
|
|
|
+}
|
|
|
+
|
|
|
+function findNextSubtitleIndex(lines) {
|
|
|
+ const subtitleRegex = /^##\s(.*)/i;
|
|
|
+ for (let i = 0; i < lines.length; i++) {
|
|
|
+ const line = lines[i];
|
|
|
+ const matches = line.match(subtitleRegex);
|
|
|
+ if (matches) {
|
|
|
+ return i;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return -1;
|
|
|
+}
|
|
|
+
|
|
|
+function getSection(lines, start, end) {
|
|
|
+ return lines.slice(start, end).join('\n');
|
|
|
+}
|
|
|
+
|
|
|
+function extractSections(markdown) {
|
|
|
+ let lines = markdown.split('\n');
|
|
|
+ const subtitleRegex = /^##\s.*/gm;
|
|
|
+ const contents = markdown.split(/^##\s.*/gm)
|
|
|
+ .map(c => {
|
|
|
+ let start = 0;
|
|
|
+ while(c[start] === '\n') {
|
|
|
+ start++;
|
|
|
+ }
|
|
|
+ let end = c.length - 1;
|
|
|
+ while(c[end] === '\n') {
|
|
|
+ end--;
|
|
|
+ }
|
|
|
+ return c.substring(start, end + 1);
|
|
|
+ });
|
|
|
+ contents.shift();
|
|
|
+ const titles = lines.filter(l => /^##\s.*/.test(l))
|
|
|
+ .map(l => l.substr(3));
|
|
|
+
|
|
|
+ return titles.map((title, i) => ({
|
|
|
+ title,
|
|
|
+ path: `/${makeSlug(title)}`,
|
|
|
+ content: contents[i]
|
|
|
+ }));
|
|
|
+}
|
|
|
+
|
|
|
+function extract(markdown) {
|
|
|
+ const { title, path } = extractTitleAndPath(markdown);
|
|
|
+ const items = extractSections(markdown);
|
|
|
+ return { title, path, items };
|
|
|
+}
|
|
|
+
|
|
|
+module.exports = extract;
|