Simplify footnote plugin to only render inline citations

• Remove footnote definition collection
• Remove footnote references section
• Simplify HTML output with placeholder links
• Keep only inline citation rendering
• Remove unused imports and types
This commit is contained in:
yangdx 2025-09-25 17:57:03 +08:00
parent 72039e0b4e
commit 275146fa0b

View file

@ -1,37 +1,11 @@
import { visit } from 'unist-util-visit'
import type { Plugin } from 'unified'
import type { Root, Text, Paragraph, Html } from 'mdast'
import type { Root, Text } from 'mdast'
// Simple footnote plugin for remark
// Simple footnote plugin for remark - only renders inline citations
export const remarkFootnotes: Plugin<[], Root> = () => {
return (tree: Root) => {
const footnoteDefinitions = new Map<string, string>()
// First pass: collect footnote definitions and remove them
const nodesToRemove: Array<{ parent: any; index: number }> = []
visit(tree, 'paragraph', (node: Paragraph, index, parent) => {
if (!parent || typeof index !== 'number') return
// Check if this paragraph contains only a footnote definition
if (node.children.length === 1 && node.children[0].type === 'text') {
const text = (node.children[0] as Text).value
const match = text.match(/^\[\^([^\]]+)\]:\s*(.+)$/)
if (match) {
const [, id, content] = match
footnoteDefinitions.set(id, content.trim())
nodesToRemove.push({ parent, index })
return
}
}
})
// Remove footnote definition paragraphs
nodesToRemove.reverse().forEach(({ parent, index }) => {
parent.children.splice(index, 1)
})
// Second pass: find footnote references and replace them
// Find footnote references and replace them with inline citations
visit(tree, 'text', (node: Text, index, parent) => {
if (!parent || typeof index !== 'number') return
@ -53,10 +27,10 @@ export const remarkFootnotes: Plugin<[], Root> = () => {
})
}
// Add footnote reference as HTML
// Add footnote reference as HTML with placeholder link
replacements.push({
type: 'html',
value: `<sup><a href="#fn-${id}" id="fnref-${id}" class="footnote-ref">${id}</a></sup>`
value: `<sup><a href="#footnote" class="footnote-ref">${id}</a></sup>`
})
lastIndex = startIndex + fullMatch.length
@ -75,42 +49,5 @@ export const remarkFootnotes: Plugin<[], Root> = () => {
parent.children.splice(index, 1, ...replacements)
}
})
// Third pass: add footnotes section at the end if we have definitions
if (footnoteDefinitions.size > 0) {
const footnotesList: any[] = []
footnoteDefinitions.forEach((content, id) => {
footnotesList.push({
type: 'listItem',
children: [{
type: 'paragraph',
children: [{
type: 'html',
value: `<span id="fn-${id}">${content} <a href="#fnref-${id}" class="footnote-backref">↩</a></span>`
}]
}]
})
})
// Add footnotes section
tree.children.push({
type: 'html',
value: '<div class="footnotes">'
} as Html)
tree.children.push({
type: 'list',
ordered: true,
start: 1,
spread: false,
children: footnotesList
})
tree.children.push({
type: 'html',
value: '</div>'
} as Html)
}
}
}