Skip to content

Instantly share code, notes, and snippets.

@ajmas
Last active November 6, 2020 17:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ajmas/4e172acb3c5d80a8c8bdadc007ece564 to your computer and use it in GitHub Desktop.
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
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