Files
penx/lib/remark-plugins.tsx
2024-08-05 10:06:02 +08:00

69 lines
1.6 KiB
TypeScript

import { ReactNode } from 'react'
import Link from 'next/link'
import { visit } from 'unist-util-visit'
export function replaceLinks({
href,
children,
}: {
href?: string
children: ReactNode
}) {
// this is technically not a remark plugin but it
// replaces internal links with <Link /> component
// and external links with <a target="_blank" />
return href?.startsWith('/') || href === '' ? (
<Link href={href} className="cursor-pointer">
{children}
</Link>
) : (
<a href={href} target="_blank" rel="noopener noreferrer">
{children}
</a>
)
}
export function replaceTweets() {
return (tree: any) =>
new Promise<void>(async (resolve, reject) => {
const nodesToChange = new Array()
visit(tree, 'link', (node: any) => {
if (
node.url.match(
/https?:\/\/twitter\.com\/(?:#!\/)?(\w+)\/status(?:es)?\/(\d+)([^\?])(\?.*)?/g,
)
) {
nodesToChange.push({
node,
})
}
})
for (const { node } of nodesToChange) {
try {
const regex = /\/status\/(\d+)/gm
const matches = regex.exec(node.url)
if (!matches) throw new Error(`Failed to get tweet: ${node}`)
const id = matches[1]
node.type = 'mdxJsxFlowElement'
node.name = 'Tweet'
node.attributes = [
{
type: 'mdxJsxAttribute',
name: 'id',
value: id,
},
]
} catch (e) {
console.log('ERROR', e)
return reject(e)
}
}
resolve()
})
}