Merge branch 'markdown-links'
This commit is contained in:
commit
59c90fa812
|
|
@ -1,23 +1,48 @@
|
||||||
export function renderMarkdown(text: string): string {
|
export function renderMarkdown(text: string): string {
|
||||||
// Strip code fences (``` and ```language) — we're already in a terminal
|
// Extract fenced code blocks before anything else
|
||||||
let result = text.replace(/^```\w*\n?/gm, "")
|
const codeBlocks: string[] = []
|
||||||
|
let result = text.replace(/^```\w*\n([\s\S]*?)^```\s*$/gm, (_, content) => {
|
||||||
|
codeBlocks.push(content)
|
||||||
|
return `\x00CODEBLOCK${codeBlocks.length - 1}\x00`
|
||||||
|
})
|
||||||
|
|
||||||
// Extract code spans first so their contents aren't processed as bold/italic
|
// Extract backslash escapes so they aren't processed as markdown
|
||||||
|
const escapes: string[] = []
|
||||||
|
result = result.replace(/\\([\\`*_~\[\]()#>!-])/g, (_, ch) => {
|
||||||
|
escapes.push(ch)
|
||||||
|
return `\x00ESC${escapes.length - 1}\x00`
|
||||||
|
})
|
||||||
|
|
||||||
|
// Extract code spans so their contents aren't processed as bold/italic
|
||||||
const codeSpans: string[] = []
|
const codeSpans: string[] = []
|
||||||
result = result.replace(/`([^`]+)`/g, (_, code) => {
|
result = result.replace(/`([^`]+)`/g, (_, code) => {
|
||||||
codeSpans.push(code)
|
codeSpans.push(code)
|
||||||
return `\x00CODE${codeSpans.length - 1}\x00`
|
return `\x00CODE${codeSpans.length - 1}\x00`
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Links: [text](url) → OSC 8 terminal hyperlink, underlined blue
|
||||||
|
// Must run before H1/bold/italic so ANSI `[` chars don't confuse the link regex
|
||||||
|
result = result.replace(/(?<!!)\[([^\]]+)\]\(([^)]+)\)/g, (_, text, href) => {
|
||||||
|
const url = href.replace(/\s+"[^"]*"$/, "") // strip optional title
|
||||||
|
return `\x1b]8;;${url}\x07\x1b[4;38;5;75m${text}\x1b[24;39m\x1b]8;;\x07`
|
||||||
|
})
|
||||||
|
|
||||||
// H1: # Header → bold+italic+underline
|
// H1: # Header → bold+italic+underline
|
||||||
result = result.replace(/^# (.+)$/gm, "\x1b[1;3;4m$1\x1b[22;23;24m")
|
result = result.replace(/^# (.+)$/gm, "\x1b[1;3;4m$1\x1b[22;23;24m")
|
||||||
|
|
||||||
// H2/H3: ## Header / ### Header → bold
|
// H2/H3: ## Header / ### Header → bold
|
||||||
result = result.replace(/^#{2,3} (.+)$/gm, "\x1b[1m$1\x1b[22m")
|
result = result.replace(/^#{2,6} (.+)$/gm, "\x1b[1m$1\x1b[22m")
|
||||||
|
|
||||||
// Blockquotes: > text → dim+italic
|
// Blockquotes: > text → dim+italic
|
||||||
result = result.replace(/^> (.+)$/gm, "\x1b[2;3m$1\x1b[22;23m")
|
result = result.replace(/^> (.+)$/gm, "\x1b[2;3m$1\x1b[22;23m")
|
||||||
|
|
||||||
|
// Bare blockquote lines: > with no text
|
||||||
|
result = result.replace(/^>\s*$/gm, "")
|
||||||
|
|
||||||
|
// Task lists: - [x] → ✓ green, - [ ] → ○ dim
|
||||||
|
result = result.replace(/^(\s*)[-*] \[x\] (.+)$/gm, "$1\x1b[32m✓\x1b[39m $2")
|
||||||
|
result = result.replace(/^(\s*)[-*] \[ \] (.+)$/gm, "$1\x1b[2m☐\x1b[22m $2")
|
||||||
|
|
||||||
// Bold: **text**
|
// Bold: **text**
|
||||||
result = result.replace(/\*\*(.+?)\*\*/g, "\x1b[1m$1\x1b[22m")
|
result = result.replace(/\*\*(.+?)\*\*/g, "\x1b[1m$1\x1b[22m")
|
||||||
|
|
||||||
|
|
@ -29,6 +54,12 @@ export function renderMarkdown(text: string): string {
|
||||||
return `\x1b[38;5;147m${codeSpans[parseInt(i)]}\x1b[39m`
|
return `\x1b[38;5;147m${codeSpans[parseInt(i)]}\x1b[39m`
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Restore backslash escapes as literal characters
|
||||||
|
result = result.replace(/\x00ESC(\d+)\x00/g, (_, i) => escapes[parseInt(i)])
|
||||||
|
|
||||||
|
// Restore fenced code blocks as plain text
|
||||||
|
result = result.replace(/\x00CODEBLOCK(\d+)\x00/g, (_, i) => codeBlocks[parseInt(i)])
|
||||||
|
|
||||||
// Breathe: add blank line before list starts when preceded by non-empty text
|
// Breathe: add blank line before list starts when preceded by non-empty text
|
||||||
const lines = result.split("\n")
|
const lines = result.split("\n")
|
||||||
for (let i = lines.length - 1; i > 0; i--) {
|
for (let i = lines.length - 1; i > 0; i--) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user