MCPcopy
hub / github.com/npmx-dev/npmx.dev / parseMarkdown

Function parseMarkdown

app/composables/useMarkdown.ts:75–113  ·  view source on GitHub ↗
({ text, plain }: UseMarkdownOptions)

Source from the content-addressed store, hash-verified

73
74// Parse simple inline markdown to HTML
75function parseMarkdown({ text, plain }: UseMarkdownOptions): string {
76 if (!text) return ''
77
78 // First strip HTML tags and escape remaining HTML
79 let html = stripAndEscapeHtml(text)
80
81 // Bold: **text** or __text__
82 html = html.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
83 html = html.replace(/__(.+?)__/g, '<strong>$1</strong>')
84
85 // Italic: *text* or _text_
86 html = html.replace(/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g, '<em>$1</em>')
87 html = html.replace(/\b_(.+?)_\b/g, '<em>$1</em>')
88
89 // Inline code: `code`
90 html = html.replace(/`([^`]+)`/g, '<code>$1</code>')
91
92 // Strikethrough: ~~text~~
93 html = html.replace(/~~(.+?)~~/g, '<del>$1</del>')
94
95 // Links: [text](url) - only allow https, mailto
96 html = html.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_match, textGroup, url) => {
97 // In plain mode, just render the link text without the anchor
98 if (plain) {
99 return textGroup
100 }
101 const decodedUrl = url.replace(/&amp;/g, '&')
102 try {
103 const { protocol, href } = new URL(decodedUrl)
104 if (['https:', 'mailto:'].includes(protocol)) {
105 const safeUrl = href.replace(/"/g, '&quot;')
106 return `<a href="${safeUrl}" rel="nofollow noreferrer noopener" target="_blank">${textGroup}</a>`
107 }
108 } catch {}
109 return `${textGroup} (${url})`
110 })
111
112 return html
113}

Callers 1

useMarkdownFunction · 0.85

Calls 1

stripAndEscapeHtmlFunction · 0.85

Tested by

no test coverage detected