1
0
Fork 0
freesewing/sites/shared/prebuild/docs.mjs

177 lines
5 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import fs from 'fs'
import path from 'path'
import rdir from 'recursive-readdir'
import { unified } from 'unified'
import remarkParser from 'remark-parse'
import remarkCompiler from 'remark-stringify'
import remarkFrontmatter from 'remark-frontmatter'
import remarkFrontmatterExtractor from 'remark-extract-frontmatter'
import { readSync } from 'to-vfile'
import yaml from 'js-yaml'
import { mdIntro } from './md-intro.mjs'
// Some arbitrary future time
const future = new Date('10-12-2026').getTime()
export const header = `/*
*
* This page was auto-generated by the prebuild script
* Any changes you make to it will be lost on the next (pre)build.
*/
`
/*
* There's an issue in crowdin where it changes the frontmatter marker:
* ---
* into this:
* - - -
* which breaks stuff. So this method takes the input and replaces all
* - - - with ---
*/
export const fixCrowdinBugs = (md) => {
md.value = md.value.split('- - -\n').join('---\n')
return md
}
/*
* Helper method to get the title and meta data from an MDX file
*
* Parameters:
*
* - file: the full path to the file
*/
export const mdxMetaInfo = async (file) => {
let result
try {
result = await unified()
.use(remarkParser)
.use(remarkCompiler)
.use(remarkFrontmatter)
.use(remarkFrontmatterExtractor, { yaml: yaml.load })
.process(fixCrowdinBugs(readSync(file, { encoding: 'utf-8' })))
} catch (err) {
console.log(err)
}
return result
}
/*
* Helper method to get a list of MDX files in a folder.
* Will traverse recursively to get all files from a given root folder.
*
* Parameters:
*
* - folder: the root folder to look in
* - lang: the language files to looks for
*
* Exported because it's also used by the Algolia index script
*/
export const getMdxFileList = async (folder, lang) => {
let allFiles
try {
allFiles = await rdir(folder)
} catch (err) {
console.log(err)
return false
}
// Filter out all that's not a language-specific markdown file
// and avoid including the 'ui' files
const files = []
for (const file of allFiles) {
if (file.slice(-5) === `${lang}.md`) files.push(file)
}
return files.sort()
}
/*
* Helper method to get the website slug (path) from the file path
*/
export const fileToSlug = (file, site, lang) =>
file.slice(-6) === `/${lang}.md` ? file.split(`/markdown/${site}/`).pop().slice(0, -6) : false
export const loadMdxForPrebuild = async (site, folder, locales) => {
const pages = {}
// Loop over languages
for (const lang of locales) {
pages[lang] = {}
// Get list of filenames
const list = await getMdxFileList(folder, lang)
// Loop over files
for (const file of list) {
const slug = fileToSlug(file, site, lang)
const meta = await mdxMetaInfo(file)
// minify the metadat
if (meta.data?.title) {
const minMeta = { t: meta.data.title }
if (meta.data.order) minMeta.o = `${meta.data.order}${meta.data.title}`
else if (meta.data.date) {
minMeta.d = meta.data.date
minMeta.o = (future - new Date(meta.data.date).getTime()) / 100000
}
if (meta.data.image) minMeta.i = meta.data.image
if (meta.data.author) minMeta.a = meta.data.author
if (meta.data.maker) minMeta.a = meta.data.maker
pages[lang][slug] = minMeta
} else {
if (pages.en[slug]) {
console.log(`l Falling back to EN metadata for ${lang} ${slug}`)
pages[lang][slug] = pages.en[slug]
} else {
console.log(`❌ [${lang}] Failed to extract meta info from: ${slug}`)
if (meta.messages.length > 0) console.log(meta.messages)
}
}
const intros = {}
intros[lang] = await mdIntro(lang, site, slug)
//if (process.env.GENERATE_OG_IMAGES) {
// // Create og image
// await generateOgImage({ lang, site, slug, title: meta.data.title, intro: intros[lang] })
//}
}
}
return pages
}
/*
* Main method that does what needs doing
*/
export const prebuildDocs = async (site) => {
// Say hi
console.log()
console.log(`Compiling list of docs pages for freesewing.${site}`)
// Languages
const locales = site === 'dev' ? ['en'] : ['en', 'fr', 'es', 'nl', 'de', 'uk']
// Setup MDX root path
const root = ['..', '..', 'markdown', site]
if (site === 'org') root.push('docs')
const mdxRoot = path.resolve(...root)
const pages = await loadMdxForPrebuild(site, mdxRoot, locales)
// Write files with MDX paths
let allPaths = ``
for (const lang of locales) {
fs.writeFileSync(
path.resolve('..', site, 'prebuild', `mdx-paths.${lang}.mjs`),
`${header}export const mdxPaths = ${JSON.stringify(Object.keys(pages[lang]))}`
)
allPaths += `import { mdxPaths as ${lang} } from './mdx-paths.${lang}.mjs'` + '\n'
}
// Write umbrella file
fs.writeFileSync(
path.resolve('..', site, 'prebuild', `mdx-paths.mjs`),
`${allPaths}${header}
export const mdxPaths = { ${locales.join(',')} }`
)
return pages
}