update
This commit is contained in:
1 parent
31dd2b0049
commit
7039b10df2
32 files changed
+415
-192
No files matched your search
@@ -3,6 +3,8 @@ import path from 'path'
|
||||
|
||||
import dotenv from 'dotenv'
|
||||
|
||||
import { THEME_FILENAME } from '../server/theme'
|
||||
|
||||
dotenv.config({ path: '../../.env' })
|
||||
dotenv.config()
|
||||
|
||||
@@ -11,11 +13,10 @@ export const CONTENT_PATH = path.resolve(
|
||||
(fs.existsSync('../../_posts') ? '../..' : 'content')
|
||||
)
|
||||
|
||||
export const srcPostPath = (...ps: string[]): string =>
|
||||
path.join(CONTENT_PATH, '_posts', ...ps)
|
||||
|
||||
export const srcMediaPath = (...ps: string[]): string =>
|
||||
path.join(CONTENT_PATH, '_media', ...ps)
|
||||
export const srcPath = (
|
||||
root: '_post' | '_media' | typeof THEME_FILENAME,
|
||||
...ps: string[]
|
||||
): string => path.join(CONTENT_PATH, root, ...ps)
|
||||
|
||||
export const builtPath = (...ps: string[]): string =>
|
||||
path.join(__dirname, '../built', ...ps)
|
||||
|
||||
@@ -2,10 +2,11 @@ import crypto from 'crypto'
|
||||
|
||||
import scopeCss from '@patarapolw/scope-css'
|
||||
import cheerio from 'cheerio'
|
||||
import jieba from 'nodejieba'
|
||||
import showdown from 'showdown'
|
||||
|
||||
export class MakeHTML {
|
||||
$ = cheerio.load('');
|
||||
$ = cheerio.load('')
|
||||
|
||||
mdConverter = new showdown.Converter({
|
||||
noHeaderId: true,
|
||||
@@ -20,10 +21,10 @@ export class MakeHTML {
|
||||
backslashEscapesHTMLTags: true,
|
||||
emoji: true,
|
||||
underline: true,
|
||||
metadata: true
|
||||
});
|
||||
metadata: true,
|
||||
})
|
||||
|
||||
constructor (private slug: string) {
|
||||
constructor(private slug: string) {
|
||||
/**
|
||||
* ! For some reasons default underscore italic fails to render...
|
||||
*/
|
||||
@@ -31,13 +32,13 @@ export class MakeHTML {
|
||||
{
|
||||
type: 'lang',
|
||||
regex: /([^\\])_{1}(.*?[^\\])_{1}/g,
|
||||
replace: '$1<i>$2</i>'
|
||||
replace: '$1<i>$2</i>',
|
||||
},
|
||||
'underscore-italic'
|
||||
)
|
||||
}
|
||||
|
||||
parse (md: string): string {
|
||||
parse(md: string): string {
|
||||
const id =
|
||||
'md-' +
|
||||
crypto
|
||||
@@ -51,17 +52,20 @@ export class MakeHTML {
|
||||
$div.html(this.mdConverter.makeHtml(md))
|
||||
$div.find('style').each((_, el) => {
|
||||
const $el = this.$(el)
|
||||
$el.html(scopeCss($el.html(), `#${id}`))
|
||||
const html = $el.html() || ''
|
||||
if (html.trim()) {
|
||||
$el.html(scopeCss(html, `#${id}`))
|
||||
}
|
||||
})
|
||||
|
||||
return this.$('<div>').append($div).html()
|
||||
return this.$('<div>').append($div).html() || ''
|
||||
}
|
||||
|
||||
clean (md: string): string {
|
||||
clean(md: string): string {
|
||||
const $div = this.$('<div>')
|
||||
$div.html(this.mdConverter.makeHtml(md))
|
||||
$div.remove('style')
|
||||
|
||||
return $div.html()
|
||||
return jieba.cutForSearch($div.html() || '').join(' ')
|
||||
}
|
||||
}
|
||||
@@ -2,53 +2,40 @@ import fg from 'fast-glob'
|
||||
import fs from 'fs-extra'
|
||||
import yaml from 'js-yaml'
|
||||
import rimraf from 'rimraf'
|
||||
import * as z from 'zod'
|
||||
|
||||
import { Database } from '../assets/schema'
|
||||
import { builtPath, dstMediaPath, srcMediaPath, srcPostPath } from './dir'
|
||||
import { Database, IMatter } from '../server/db'
|
||||
import { THEME_FILENAME } from '../server/theme'
|
||||
import { builtPath, dstMediaPath, srcPath } from './dir'
|
||||
import { MakeHTML } from './make-html'
|
||||
|
||||
async function main() {
|
||||
rimraf.sync(dstMediaPath())
|
||||
rimraf.sync(builtPath())
|
||||
|
||||
await fs.copy(srcMediaPath(), dstMediaPath())
|
||||
await fs.copy(srcPath('_media'), dstMediaPath())
|
||||
await fs.ensureDir(builtPath())
|
||||
|
||||
await fs.copyFile(srcPath(THEME_FILENAME), builtPath(THEME_FILENAME))
|
||||
|
||||
const db = new Database(builtPath('data.db'))
|
||||
db.init()
|
||||
|
||||
const files = await fg('**/*.md', {
|
||||
cwd: srcPostPath(),
|
||||
cwd: srcPath('_post'),
|
||||
})
|
||||
|
||||
// eslint-disable-next-line array-callback-return
|
||||
files.map((f) => {
|
||||
const slug = f.replace(/^.+\//, '').replace(/\.md$/, '')
|
||||
let header: Record<string, unknown> = {}
|
||||
let markdown = fs.readFileSync(srcPostPath(f), 'utf8')
|
||||
const path = f.replace(/\.md$/, '')
|
||||
let markdown = fs.readFileSync(srcPath('_post', f), 'utf8')
|
||||
|
||||
if (markdown.startsWith('---\n')) {
|
||||
const [h, c = ''] = markdown.substr(4).split(/---\n(.*)$/s)
|
||||
header = yaml.safeLoad(h, {
|
||||
schema: yaml.JSON_SCHEMA,
|
||||
}) as Record<string, unknown>
|
||||
markdown = c
|
||||
}
|
||||
const [h, c = ''] = markdown.substr(4).split(/---\n(.*)$/s)
|
||||
const header = yaml.safeLoad(h, {
|
||||
schema: yaml.JSON_SCHEMA,
|
||||
}) as IMatter
|
||||
markdown = c
|
||||
|
||||
const makeHtml = new MakeHTML(slug)
|
||||
|
||||
const { title, date, image, tag } = (() => {
|
||||
const { title, date, image, tag } = header
|
||||
return z
|
||||
.object({
|
||||
title: z.string(),
|
||||
date: z.date().optional(),
|
||||
image: z.string().optional(),
|
||||
tag: z.array(z.string()).optional(),
|
||||
})
|
||||
.parse({ title, date, image, tag })
|
||||
})()
|
||||
const makeHtml = new MakeHTML(path)
|
||||
|
||||
const content = makeHtml.clean(markdown)
|
||||
const excerptHtml = makeHtml.parse(
|
||||
@@ -57,11 +44,8 @@ async function main() {
|
||||
const contentHtml = makeHtml.parse(markdown)
|
||||
|
||||
db.insert({
|
||||
slug,
|
||||
title,
|
||||
date,
|
||||
image,
|
||||
tag,
|
||||
...header,
|
||||
path,
|
||||
content,
|
||||
excerptHtml,
|
||||
contentHtml,
|
||||
|
||||
Reference in new issue
Block a user