Last active
November 6, 2020 17:27
-
-
Save ajmas/4e172acb3c5d80a8c8bdadc007ece564 to your computer and use it in GitHub Desktop.
Converts Markdown formatted text representing a FAQ to an array of FAQ entries
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const md = require('markdown-it')() | |
.use(require('markdown-it-attrs')) | |
.use(require('markdown-it-header-sections')); | |
const { XMLSerializer, DOMParser } = require('xmldom') | |
const sampleMarkdown = ` | |
# XYZ | |
## Question 1 | |
some text | |
## Question 2 | |
some other text | |
## Question 3 {.faq-entry} | |
some more text | |
`; | |
function contentToString (element) { | |
let str = ''; | |
const xmlSerlizer = new XMLSerializer(); | |
const childNodes = element.childNodes; | |
for (let i = 0; i < childNodes.length; i++) { | |
str += xmlSerlizer.serializeToString(childNodes[i]); | |
} | |
return str; | |
} | |
/** | |
* Takes markdown formatted text, representing an FAQ and converts it | |
* into an arrary of entries that represent a question and answer. | |
* | |
* An entry is in the form: | |
* | |
* ``` | |
* { | |
* question: 'my question', | |
* answer: 'the answer' | |
* } | |
* ``` | |
* | |
* By default, the h2 is treated as the question and the body of | |
* the section as the answer | |
* | |
* @param {string} markdownText | |
* @param {string} headerTag, default is 'h2' | |
*/ | |
function convertMarkedDownFAQ (markdownText, headerTag = 'h2') { | |
const faq = []; | |
// Convert markdown to html, then to XML and then | |
// select the 'section' elements | |
const html = md.render(markdownText); | |
const doc = new DOMParser().parseFromString(html); | |
const elements = doc.getElementsByTagName('section'); | |
// Loop through each section that has an h2 and break it up into | |
// question and answer blocks | |
for (let i = 0; i < elements.length; i++) { | |
const headers = elements[i].getElementsByTagName(headerTag); | |
// We are only interested in sections with immediate header | |
if (!headers || headers.length === 0|| headers[0].parentNode !== elements[i]) { | |
continue; | |
} | |
const question = contentToString(headers[0]); | |
elements[i].removeChild(headers[0]); | |
const answer = contentToString(elements[i]).trim(); | |
faq.push({ | |
question, answer | |
}) | |
} | |
return faq; | |
} | |
console.log(convertMarkedDownFAQ(sampleMarkdown)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment