mirror of
https://github.com/Xahau/xahau-web.git
synced 2025-11-19 19:05:48 +00:00
169 lines
4.8 KiB
TypeScript
169 lines
4.8 KiB
TypeScript
import { readFileSync } from 'node:fs'
|
|
import { visit } from 'unist-util-visit'
|
|
|
|
const parseRules: {
|
|
path: string
|
|
parse: (content: string) => { label: string; url: string }[]
|
|
}[] = [
|
|
{
|
|
path: 'src/content/references/global.md',
|
|
parse: (content: string) => {
|
|
const lines = content.split('\n')
|
|
const result: { label: string; url: string }[] = []
|
|
for (const line of lines) {
|
|
const match = line.match(/^\[([^\]]+)\]:\s*(.+)$/)
|
|
if (match) {
|
|
const [, label, url] = match
|
|
result.push({ label, url: url.trim() })
|
|
}
|
|
}
|
|
return result
|
|
},
|
|
},
|
|
{
|
|
path: 'src/content/references/transactions.md',
|
|
parse: (content: string) => {
|
|
const lines = content.split('\n')
|
|
const result: { label: string; url: string }[] = []
|
|
for (const line of lines) {
|
|
if (line.length > 0) {
|
|
const url = `/docs/protocol-reference/transactions/transaction-types/${line.toLowerCase()}`
|
|
result.push({ label: `${line}`, url })
|
|
result.push({ label: `${line} transaction`, url })
|
|
result.push({ label: `${line} transactions`, url })
|
|
}
|
|
}
|
|
return result
|
|
},
|
|
},
|
|
{
|
|
path: 'src/content/references/pseudo-transactions.md',
|
|
parse: (content: string) => {
|
|
const lines = content.split('\n')
|
|
const result: { label: string; url: string }[] = []
|
|
for (const line of lines) {
|
|
if (line.length > 0) {
|
|
const url = `/docs/protocol-reference/transactions/pseudo-transaction-types/${line.toLowerCase()}`
|
|
result.push({ label: `${line}`, url })
|
|
result.push({ label: `${line} transaction`, url })
|
|
result.push({ label: `${line} transactions`, url })
|
|
}
|
|
}
|
|
return result
|
|
},
|
|
},
|
|
]
|
|
|
|
/**
|
|
* Remark plugin to resolve reference-style links from global.md
|
|
*/
|
|
export function remarkGlobalReferences() {
|
|
let globalRefs: Record<string, string> | null = null
|
|
|
|
function loadGlobalReferences() {
|
|
if (globalRefs !== null) return globalRefs
|
|
|
|
try {
|
|
globalRefs = {}
|
|
for (const rule of parseRules) {
|
|
const content = readFileSync(rule.path, 'utf-8')
|
|
const refs = rule.parse(content)
|
|
for (const ref of refs) {
|
|
globalRefs[ref.label] = ref.url
|
|
}
|
|
}
|
|
|
|
return globalRefs
|
|
} catch (error: any) {
|
|
console.warn('Could not load global.md references:', error.message)
|
|
globalRefs = {}
|
|
return globalRefs
|
|
}
|
|
}
|
|
|
|
return function transformer(tree: any) {
|
|
const refs = loadGlobalReferences()
|
|
|
|
// Find all reference-style links in the format [text][]
|
|
visit(tree, 'linkReference', (node) => {
|
|
if (
|
|
node.referenceType === 'shortcut' ||
|
|
node.referenceType === 'collapsed'
|
|
) {
|
|
const label = node.label || node.children?.[0]?.value
|
|
|
|
if (label && refs[label]) {
|
|
// Convert linkReference to a regular link
|
|
node.type = 'link'
|
|
node.url = refs[label]
|
|
delete node.referenceType
|
|
delete node.identifier
|
|
delete node.label
|
|
}
|
|
}
|
|
})
|
|
|
|
// Also look for escaped reference-style links in text nodes: \[label]\[]
|
|
visit(tree, 'text', (node, index, parent) => {
|
|
if (!node.value) return
|
|
|
|
// Find escaped reference-style links: \[label]\[]
|
|
const pattern = /\\?\[([^\]]+)\\?\]\\?\[\]/g
|
|
const replacements = []
|
|
let match: RegExpExecArray | null = null
|
|
|
|
match = pattern.exec(node.value)
|
|
while (match !== null) {
|
|
const [fullMatch, label] = match
|
|
if (refs[label]) {
|
|
replacements.push({
|
|
start: match.index,
|
|
end: match.index + fullMatch.length,
|
|
label,
|
|
url: refs[label],
|
|
})
|
|
}
|
|
match = pattern.exec(node.value)
|
|
}
|
|
|
|
// Apply replacements from right to left to maintain indices
|
|
if (replacements.length > 0) {
|
|
const newNodes = []
|
|
let lastIndex = 0
|
|
|
|
for (const replacement of replacements) {
|
|
// Add text before the replacement
|
|
if (replacement.start > lastIndex) {
|
|
newNodes.push({
|
|
type: 'text',
|
|
value: node.value.slice(lastIndex, replacement.start),
|
|
})
|
|
}
|
|
|
|
// Add the link
|
|
newNodes.push({
|
|
type: 'link',
|
|
url: replacement.url,
|
|
children: [{ type: 'text', value: replacement.label }],
|
|
})
|
|
|
|
lastIndex = replacement.end
|
|
}
|
|
|
|
// Add remaining text
|
|
if (lastIndex < node.value.length) {
|
|
newNodes.push({
|
|
type: 'text',
|
|
value: node.value.slice(lastIndex),
|
|
})
|
|
}
|
|
|
|
// Replace the current node with the new nodes
|
|
if (parent && typeof index === 'number') {
|
|
parent.children.splice(index, 1, ...newNodes)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|