-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Expand file tree
/
Copy pathrenderMarkdown.ts
More file actions
72 lines (60 loc) · 2.57 KB
/
renderMarkdown.ts
File metadata and controls
72 lines (60 loc) · 2.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import {
betterLinkDocumentMod,
parseDocumentFragmentFromString,
serializeDocumentFragmentIntoString,
type HighlightCodeFn
} from 'botframework-webchat-component/internal.js';
import katex from 'katex';
import { micromark } from 'micromark';
import { gfm, gfmHtml } from 'micromark-extension-gfm';
import createStreamingRenderer, {
type StreamingNextOptions,
type StreamingNextResult,
type StreamingRenderer,
type StreamingRenderOptions
} from './createStreamingRenderer';
import { math, mathHtml } from './mathExtension';
import { createDecorate } from './private/createDecorate';
import iterateLinkDefinitions from './private/iterateLinkDefinitions';
import { pre as respectCRLFPre } from './private/respectCRLF';
type RenderInit = Readonly<{
codeBlockCopyButtonTagName: string;
externalLinkAlt: string;
highlightCode: HighlightCodeFn;
}>;
export default function render(
markdown: string,
{ markdownRespectCRLF, markdownRenderHTML }: Readonly<{ markdownRespectCRLF: boolean; markdownRenderHTML?: boolean }>,
{ externalLinkAlt }: RenderInit
): string {
const linkDefinitions = Array.from(iterateLinkDefinitions(markdown));
if (markdownRespectCRLF) {
markdown = respectCRLFPre(markdown);
}
const decorate = createDecorate(linkDefinitions, externalLinkAlt);
const htmlAfterMarkdown = micromark(markdown, {
allowDangerousHtml: markdownRenderHTML ?? true,
// We need to handle links like cite:1 or other URL handlers.
// And we will remove dangerous protocol during sanitization.
allowDangerousProtocol: true,
extensions: [gfm(), math()],
htmlExtensions: [
gfmHtml(),
mathHtml({
renderMath: (content, isDisplay) =>
katex.renderToString(content, {
displayMode: isDisplay,
output: 'mathml'
})
})
]
});
// TODO: [P1] In some future, we should apply "better link" and "sanitization" outside of the Markdown engine.
// Particularly, apply them at `useRenderMarkdownAsHTML` instead of inside the default `renderMarkdown`.
// If web devs want to bring their own Markdown engine, they don't need to rebuild "better link" and sanitization themselves.
const documentFragmentAfterMarkdown = parseDocumentFragmentFromString(htmlAfterMarkdown);
betterLinkDocumentMod(documentFragmentAfterMarkdown, decorate);
return serializeDocumentFragmentIntoString(documentFragmentAfterMarkdown).trim();
}
render.createStreamingRenderer = createStreamingRenderer;
export { type StreamingNextOptions, type StreamingNextResult, type StreamingRenderer, type StreamingRenderOptions };