Improve preview title and description extraction
This commit is contained in:
parent
fdbc4ffb35
commit
bbdc45eca3
2 changed files with 30 additions and 25 deletions
|
|
@ -28,23 +28,12 @@ function isElementNode(node: RootContent): node is Element {
|
|||
return node.type === "element"
|
||||
}
|
||||
|
||||
function isMeaningfulNode(node: RootContent): boolean {
|
||||
return normalizeWhitespace(toString(node)).length > 0
|
||||
function isHeadingElement(node: RootContent): node is Element {
|
||||
return isElementNode(node) && /^h[1-6]$/.test(node.tagName)
|
||||
}
|
||||
|
||||
function isDuplicateTitleHeading(node: RootContent, pageTitle?: string): boolean {
|
||||
if (!isElementNode(node) || node.tagName !== "h1") {
|
||||
return false
|
||||
}
|
||||
|
||||
const headingText = normalizeWhitespace(toString(node))
|
||||
const normalizedTitle = normalizeWhitespace(pageTitle ?? "")
|
||||
|
||||
if (headingText.length === 0) {
|
||||
return false
|
||||
}
|
||||
|
||||
return normalizedTitle.length > 0 ? headingText === normalizedTitle : true
|
||||
function isMeaningfulNode(node: RootContent): boolean {
|
||||
return normalizeWhitespace(toString(node)).length > 0
|
||||
}
|
||||
|
||||
function isStandalonePreviewTagline(node: RootContent): boolean {
|
||||
|
|
@ -67,14 +56,12 @@ function isStandalonePreviewTagline(node: RootContent): boolean {
|
|||
export function extractDescriptionText(tree: HTMLRoot, pageTitle?: string): string {
|
||||
const children = [...tree.children]
|
||||
let startIdx = 0
|
||||
let strippedTitle = false
|
||||
|
||||
while (startIdx < children.length && !isMeaningfulNode(children[startIdx])) {
|
||||
startIdx++
|
||||
}
|
||||
|
||||
if (startIdx < children.length && isDuplicateTitleHeading(children[startIdx], pageTitle)) {
|
||||
strippedTitle = true
|
||||
while (startIdx < children.length && isHeadingElement(children[startIdx])) {
|
||||
startIdx++
|
||||
}
|
||||
|
||||
|
|
@ -82,11 +69,7 @@ export function extractDescriptionText(tree: HTMLRoot, pageTitle?: string): stri
|
|||
startIdx++
|
||||
}
|
||||
|
||||
if (
|
||||
startIdx < children.length &&
|
||||
(strippedTitle || pageTitle) &&
|
||||
isStandalonePreviewTagline(children[startIdx])
|
||||
) {
|
||||
if (startIdx < children.length && pageTitle && isStandalonePreviewTagline(children[startIdx])) {
|
||||
startIdx++
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ import remarkFrontmatter from "remark-frontmatter"
|
|||
import { QuartzTransformerPlugin } from "../types"
|
||||
import yaml from "js-yaml"
|
||||
import toml from "toml"
|
||||
import { Root as MdRoot } from "mdast"
|
||||
import { toString } from "mdast-util-to-string"
|
||||
import { FilePath, FullSlug, getFileExtension, slugifyFilePath, slugTag } from "../../util/path"
|
||||
import { QuartzPluginData } from "../vfile"
|
||||
import { i18n } from "../../i18n"
|
||||
|
|
@ -52,6 +54,23 @@ function getAliasSlugs(aliases: string[]): FullSlug[] {
|
|||
return res
|
||||
}
|
||||
|
||||
function getFirstMarkdownHeading(root: MdRoot): string | undefined {
|
||||
const firstMeaningfulNode = root.children.find((node) => {
|
||||
if (node.type === "yaml") {
|
||||
return false
|
||||
}
|
||||
|
||||
return toString(node).trim().length > 0
|
||||
})
|
||||
|
||||
if (!firstMeaningfulNode || firstMeaningfulNode.type !== "heading") {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const text = toString(firstMeaningfulNode).trim()
|
||||
return text.length > 0 ? text : undefined
|
||||
}
|
||||
|
||||
export const FrontMatter: QuartzTransformerPlugin<Partial<Options>> = (userOpts) => {
|
||||
const opts = { ...defaultOptions, ...userOpts }
|
||||
return {
|
||||
|
|
@ -61,7 +80,7 @@ export const FrontMatter: QuartzTransformerPlugin<Partial<Options>> = (userOpts)
|
|||
return [
|
||||
[remarkFrontmatter, ["yaml", "toml"]],
|
||||
() => {
|
||||
return (_, file) => {
|
||||
return (tree: MdRoot, file) => {
|
||||
const fileData = Buffer.from(file.value as Uint8Array)
|
||||
const { data } = matter(fileData, {
|
||||
...opts,
|
||||
|
|
@ -74,7 +93,10 @@ export const FrontMatter: QuartzTransformerPlugin<Partial<Options>> = (userOpts)
|
|||
if (data.title != null && data.title.toString() !== "") {
|
||||
data.title = data.title.toString()
|
||||
} else {
|
||||
data.title = file.stem ?? i18n(cfg.configuration.locale).propertyDefaults.title
|
||||
data.title =
|
||||
getFirstMarkdownHeading(tree) ??
|
||||
file.stem ??
|
||||
i18n(cfg.configuration.locale).propertyDefaults.title
|
||||
}
|
||||
|
||||
const tags = coerceToArray(coalesceAliases(data, ["tags", "tag"]))
|
||||
|
|
|
|||
Loading…
Reference in a new issue