Skip to content

Commit af84e64

Browse files
committed
Close #1972: Improve styling/readability of markdown tables
1 parent 646e69f commit af84e64

File tree

3 files changed

+42
-29
lines changed

3 files changed

+42
-29
lines changed

js/markdown-stream/markdown-stream.ts

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,28 +45,38 @@ const SVG_DOT = createSVGIcon(
4545
`<svg width="12" height="12" xmlns="http://www.w3.org/2000/svg" class="${SVG_DOT_CLASS}" style="margin-left:.25em;margin-top:-.25em"><circle cx="6" cy="6" r="6"/></svg>`
4646
);
4747

48-
// For rendering chat output, we use typical Markdown behavior of passing through raw
49-
// HTML (albeit sanitizing afterwards).
50-
//
51-
// For echoing chat input, we escape HTML. This is not for security reasons but just
52-
// because it's confusing if the user is using tag-like syntax to demarcate parts of
53-
// their prompt for other reasons (like <User>/<Assistant> for providing examples to the
54-
// chat model), and those tags simply vanish.
55-
const rendererEscapeHTML = new Renderer();
56-
rendererEscapeHTML.html = (html: string) =>
48+
// 'markdown' renderer (for assistant messages)
49+
const markdownRenderer = new Renderer();
50+
51+
// Add some basic Bootstrap styling to markdown tables
52+
markdownRenderer.table = (header: string, body: string) => {
53+
return `<table class="table table-striped table-bordered">
54+
<thead>${header}</thead>
55+
<tbody>${body}</tbody>
56+
</table>`;
57+
};
58+
59+
// 'semi-markdown' renderer (for user messages)
60+
const semiMarkdownRenderer = new Renderer();
61+
62+
// Escape HTML, not for security reasons, but just because it's confusing if the user is
63+
// using tag-like syntax to demarcate parts of their prompt for other reasons (like
64+
// <User>/<Assistant> for providing examples to the model), and those tags vanish.
65+
semiMarkdownRenderer.html = (html: string) =>
5766
html
5867
.replaceAll("&", "&amp;")
5968
.replaceAll("<", "&lt;")
6069
.replaceAll(">", "&gt;")
6170
.replaceAll('"', "&quot;")
6271
.replaceAll("'", "&#039;");
63-
const markedEscapeOpts = { renderer: rendererEscapeHTML };
6472

6573
function contentToHTML(content: string, content_type: ContentType) {
6674
if (content_type === "markdown") {
67-
return unsafeHTML(sanitizeHTML(parse(content) as string));
75+
const html = parse(content, { renderer: markdownRenderer });
76+
return unsafeHTML(sanitizeHTML(html as string));
6877
} else if (content_type === "semi-markdown") {
69-
return unsafeHTML(sanitizeHTML(parse(content, markedEscapeOpts) as string));
78+
const html = parse(content, { renderer: semiMarkdownRenderer });
79+
return unsafeHTML(sanitizeHTML(html as string));
7080
} else if (content_type === "html") {
7181
return unsafeHTML(sanitizeHTML(content));
7282
} else if (content_type === "text") {

0 commit comments

Comments
 (0)