hexo-theme-stellar/scripts/events/lib/notebooks.js

154 lines
4.0 KiB
JavaScript
Raw Normal View History

2024-05-13 09:45:38 +08:00
/**
* notebooks.js v1
*/
'use strict'
class NotePage {
constructor(page) {
this.id = page._id
this.notebook = page.notebook
this.title = page.title
this.tags = page.tags
this.path = page.path
this.path_key = page.path.replace('.html', '')
this.layout = page.layout
this.date = page.date
this.updated = page.updated || page.date
const pin = page.pin ?? page.sticky ?? 0
if (pin === true) {
this.pin = 1
} else if (pin === false) {
this.pin = 0
} else {
this.pin = pin
}
}
}
function splitTag(tag) {
return tag.split('/').filter(t => t.length > 0)
}
function prepareNotebook(id, info, ctx) {
const notebook = info
notebook.id = id
if (notebook.base_dir) {
if (notebook.base_dir.startsWith('/')) {
notebook.base_dir = notebook.base_dir.substring(1)
}
if (notebook.base_dir.endsWith('/')) {
notebook.base_dir = notebook.base_dir.substring(0, notebook.base_dir.length - 1)
}
} else {
const notebooksBaseDir = ctx.theme.config.site_tree.notebooks.base_dir
notebook.base_dir = notebooksBaseDir ? `${notebooksBaseDir}/${id}` : id
}
notebook.sort ||= 0
notebook.auto_excerpt ||= ctx.theme.config.notebook.auto_excerpt || 0
notebook.per_page ??= ctx.theme.config.notebook.per_page ?? ctx.config.per_page ?? 10
notebook.order_by ||= ctx.theme.config.notebook.order_by || '-updated'
notebook.menu_id ??= ctx.theme.config.site_tree.notes.menu_id
notebook.license ??= ctx.theme.config.notebook.license
notebook.share ??= ctx.theme.config.notebook.share
notebook.leftbar ??= ctx.theme.config.site_tree.notes.leftbar
notebook.rightbar ??= ctx.theme.config.site_tree.notes.rightbar
notebook.note_leftbar ??= ctx.theme.config.site_tree.note.leftbar
notebook.note_rightbar ??= ctx.theme.config.site_tree.note.rightbar
const tagMap = new Map() // tagId: tagInfo
notebook.tagTree = tagMap
const rootTag = {
id: '',
name: '',
part: '',
path: notebook.base_dir,
parent: null, // parent tag id
childSet: new Set(), // child tag ids
noteSet: new Set(), // note ids
}
tagMap.set(rootTag.id, rootTag)
// Iterate through all notes in the notebook, build the tag tree.
const allPages = ctx.locals.get('pages')
const pages = allPages.filter(p => p.notebook === notebook.id)
for (const page of pages.data) {
rootTag.noteSet.add(page._id)
if (!page.tags) {
continue
}
for (const hierarchyTag of page.tags) {
const parts = splitTag(hierarchyTag)
let parent = rootTag
for (const part of parts) {
const tagName = parent.name ? `${parent.name}/${part}` : part
const tagId = tagName.toLowerCase()
let tag = tagMap.get(tagId)
if (tag == null) {
tag = {
id: tagId,
name: tagName,
part: part,
path: `${notebook.base_dir}/tags/${tagId}`,
parent: parent.id,
childSet: new Set(),
noteSet: new Set(),
}
tagMap.set(tagId, tag)
parent.childSet.add(tagId)
}
tag.noteSet.add(page._id)
parent = tag
}
}
}
notebook.noteMap = pages.map(p => new NotePage(p)).reduce((map, note) => {
map.set(note.id, note)
return map
}, new Map())
// Sort child tags for each tag.
for (const [_, tag] of tagMap) {
tag.children = Array.from(tag.childSet)
tag.children.sort()
}
return notebook
}
function getNotebooksObject(ctx) {
const notebooks = {
tree: {},
}
const data = ctx.locals.get('data')
const list = []
for (const [key, info] of Object.entries(data)) {
if (!key.startsWith('notebooks/') || key.endsWith('.DS_Store')) {
continue
}
const id = key.substring(10)
list.push(prepareNotebook(id, info, ctx))
}
list.sort((a, b) => a.sort - b.sort)
for (const info of list) {
notebooks.tree[info.id] = info
}
return notebooks
}
module.exports = ctx => {
const notebooks = getNotebooksObject(ctx)
ctx.theme.config.notebooks = notebooks
}