pompy.dev/packages/blog-content/src/recursiveParse/parseSeries.ts

147 lines
3.9 KiB
TypeScript

import { contentMap, seriesMap } from ".."
import { contentDirectoryPath } from "../config"
import { generateToc } from "../parseMarkdown"
import { addDocument } from "../searchIndex"
import { PostData } from "../types/types"
import { writeToFile } from "../util"
import { DataToPass } from "."
export default function parseSeries(data: DataToPass): void {
const {
path,
urlPath: _urlPath,
markdownRaw,
markdownData,
humanizedDuration,
totalWords,
} = data
// last part of the url without the slash
let lastPath = _urlPath.slice(_urlPath.lastIndexOf("/") + 1)
if (!lastPath.includes("_") && !lastPath.startsWith("0"))
throw Error(`Invalid series file name at: "${path}"`)
// if file is a series descriptor or not (not = regular series post)
const isFileDescriptor = lastPath.startsWith("0") && !lastPath.includes("_")
// series post url
if (isFileDescriptor) {
lastPath = ""
} else {
lastPath = lastPath
.slice(lastPath.indexOf("_") + 1) // get string after the series index
.replace(/\/$/, "") // remove trailing slash
}
// get url until right before the lastPath
const urlUntilLastPath = _urlPath.slice(0, _urlPath.lastIndexOf("/") + 1)
// remove trailing slash if it's a regular series post
const urlPath =
(isFileDescriptor
? urlUntilLastPath.replace(/\/$/, "")
: urlUntilLastPath) + lastPath
// todo: separate interface for series descriptor (no word count and read time)
const postData: PostData = {
title: markdownData.title as string,
date: "",
readTime: humanizedDuration,
wordCount: totalWords,
tags: [],
}
/**
* Date
*/
const postDate = new Date(markdownData.date as string)
postData.date = postDate.toLocaleString("default", {
month: "short",
day: "numeric",
year: "numeric",
})
const YYYY_MM_DD = postDate.toISOString().split("T")[0]
if (contentMap.date[YYYY_MM_DD]) {
contentMap.date[YYYY_MM_DD].push(urlPath)
} else {
contentMap.date[YYYY_MM_DD] = [urlPath]
}
/**
* Tags
*/
postData.tags = markdownData.tags as string[]
if (postData.tags) {
postData.tags.forEach((tag) => {
if (contentMap.tags[tag]) {
contentMap.tags[tag].push(urlPath)
} else {
contentMap.tags[tag] = [urlPath]
}
})
}
/**
*
*/
addDocument({
title: markdownData.title,
body: markdownData.content,
url: urlPath,
})
contentMap.posts[urlPath] = postData
// series markdown starting with 0 is a series descriptor
if (isFileDescriptor) {
contentMap.series[urlPath] = {
...postData,
order: [],
length: 0,
}
} else {
// put series post in appropriate series
for (const key of Object.keys(contentMap.series)) {
if (urlPath.includes(key)) {
const index = parseInt(
_urlPath.slice(
_urlPath.lastIndexOf("/") + 1,
_urlPath.lastIndexOf("_")
)
)
if (isNaN(index))
throw Error(`Invalid series index at: ${path}`)
const itemToPush = {
index: index,
url: urlPath,
}
if (seriesMap[key]) {
seriesMap[key].push(itemToPush)
} else {
seriesMap[key] = [itemToPush]
}
break
}
}
}
/**
* Save content
*/
writeToFile(
`${contentDirectoryPath}${urlPath}.json`,
JSON.stringify({
content: markdownData.content,
toc: generateToc(markdownRaw),
})
)
}