Skip to content
Snippets Groups Projects
use-markdown-parser.ts 4.37 KiB
Newer Older
import { ServiceContent } from 'types/ServiceContent'
import fs from 'fs'
import path from 'path'
import { remark } from 'remark'
import html from 'remark-html'
import { ChildResource, LabelTag, StatusTag, Tag, TypeTag } from 'types/content/'

export default function loadAndPrepareMarkdown(selectedServiceName: string) {
    const markdownFileContent: string = loadMarkdown(selectedServiceName)
    const content: ServiceContent = prepareContentFromMarkdown(markdownFileContent, selectedServiceName)
    return content
}

function loadMarkdown(selectedServiceName: string) {
    const fullPath: string = path.join(process.cwd(), 'content', 'resources', `${selectedServiceName}`, `${selectedServiceName}.md`)
    const markdownContent: string = fs.readFileSync(fullPath, 'utf8')
    return markdownContent
}

function prepareContentFromMarkdown(markdownContent: string, selectedServiceName: string) {
    // eslint-disable-next-line no-unused-vars
    const [header, metadata, text] = markdownContent.split('---')
    const content: ServiceContent = parseMetadata(metadata)
    content.slug = selectedServiceName
    content.text = parseTextToHTMLString(text)
    return content
}

function parseTextToHTMLString(markdownText: string) {
    const sanitizedMarkdownText: string = sanitizeMarkdownText(markdownText)
    const processedContent = remark().use(html).processSync(sanitizedMarkdownText)
    const htmlContent: string = processedContent.toString()
    return htmlContent
}

function parseMetadata(metadata: string): ServiceContent {
    const lines: string[] = metadata.split('\n')
    const content: ServiceContent = new ServiceContent()
    lines.forEach((line: string) => {
        // Skips empty line

        // Current line is a key
            // handels nested objects like contactInformation and developer
            parentKey = line.slice(0, -1)
            return
        }

        if (line.startsWith('shortDescription')) {
            const [key, value] = convertLineIntoTuple(line)
            content[key] = value
            parentKey = key
        // Current line is shortDescription text
        if (parentKey === 'shortDescription' && startsWithTwoSpaces(line)) {
            content.shortDescription = content.shortDescription + ' ' + line.trim()

        // Convert line into tupel
        const [key, value] = convertLineIntoTuple(line)

        if (parentKey === 'childResources') {
            if (key === '- name') {
                content.childResources.push(new ChildResource({ name: value, slug: '' }))
                return
            }
            content.childResources[content.childResources.length - 1].slug = value
            return
        }
        // Check for explicit keys
        if (parentKey === 'contactInformation' || parentKey === 'developer' || parentKey === 'logo') {
            if (content[parentKey][key] === '') {
                content[parentKey][key] = value
            }
            // check if contactInformation / developer are correctly assigned
            if (content[parentKey].initialized) {
                parentKey = ''
        if (parentKey === 'tags') {
            const tag: Tag | undefined = createTag(key, value)
            if (tag) {
                content[parentKey].push(tag)
            }
        // Assign simple key value tuple
        content[key] = value
    return new ServiceContent(content)
function createTag(key: string, value: string) {
    if (key.includes('type')) {
        return new TypeTag(value)
    } else if (key.includes('status')) {
        return new StatusTag(value)
    } else if (key.includes('label')) {
        return new LabelTag(value)
    }
}
function convertLineIntoTuple(lineString: string) {
    const trimmedLine: string = lineString.trim()
    const [key, value] = trimmedLine.split(/:(.*)/s)
    const trimmedValue = value?.trim()
    return [key, trimmedValue]
}
function startsWithTwoSpaces(stringToCheck: string) {
    return /^\s{2}/.test(stringToCheck)
}
function sanitizeMarkdownText(markdownText: string) {
    // trim whitespaces; replace line breaks with and remove multiple whitespaces
    return markdownText.trim().replace(/ +(?= )/g, ' ')