@@ -45,28 +45,38 @@ const SVG_DOT = createSVGIcon(
45
45
`<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>`
46
46
) ;
47
47
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 ) =>
57
66
html
58
67
. replaceAll ( "&" , "&" )
59
68
. replaceAll ( "<" , "<" )
60
69
. replaceAll ( ">" , ">" )
61
70
. replaceAll ( '"' , """ )
62
71
. replaceAll ( "'" , "'" ) ;
63
- const markedEscapeOpts = { renderer : rendererEscapeHTML } ;
64
72
65
73
function contentToHTML ( content : string , content_type : ContentType ) {
66
74
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 ) ) ;
68
77
} 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 ) ) ;
70
80
} else if ( content_type === "html" ) {
71
81
return unsafeHTML ( sanitizeHTML ( content ) ) ;
72
82
} else if ( content_type === "text" ) {
0 commit comments