In my Angular 16 application, I utilize the ngx-markdown library alongside Katex and other dependencies. A challenging situation arises when the backend (an LLM) responds with markdown text that conflicts with Katex delimiters during rendering.
I attempted to address this conflict by tweaking Katex's default delimiters as follows:
[
{left: "$$", right: "$$", display: true},
{left: '$', right: '$', display: false},
{left: "\\(", right: "\\)", display: false},
{left: "\(", right: "\)", display: false},
{left: "\\begin{equation}", right: "\\end{equation}", display: true},
{left: "\\begin{align}", right: "\\end{align}", display: true},
{left: "\\begin{alignat}", right: "\\end{alignat}", display: true},
{left: "\\begin{gather}", right: "\\end{gather}", display: true},
{left: "\\begin{CD}", right: "\\end{CD}", display: true},
{left: "\\[", right: "\\]", display: true},
{left: "\[", right: "\]", display: true},
]
Despite adding some custom delimiters to improve rendering, issues persisted when the text contained characters like ( ) or [ ], causing conflicts in interpreting delimiters between Katex, Angular, and ngx-markdown, leading to incorrect rendering.
An illustration of the problematic rendering can be seen here: https://i.stack.imgur.com/1veLj.png
Below are snippets of the essential parts of the Angular script:
HTML -
<markdown lineNumbers katex [katexOptions]="optionsKatex" clipboard [clipboardButtonTemplate]="buttonTemplate">
{{ mensagem.content }}
</markdown>
Angular TypeScript Component:
import { Component, OnInit, AfterViewInit } from '@angular/core';
import { KatexOptions } from 'ngx-markdown';
type questionAnswer={
type: "Question" | "Answer",
content: string,
keyChat: number,
likeSelected: boolean,
dislikeSelected: boolean,
isActive: boolean,
isButtonsDisabled: boolean
}
export class TestComponent implements OnInit, AfterViewInit {
public optionsKatex: KatexOptions = {
delimiters: [
{left: "$$", right: "$$", display: true},
{left: '$', right: '$', display: false},
{left: "\\(", right: "\\)", display: false},
{left: "\(", right: "\)", display: false},
{left: "\\begin{equation}", right: "\\end{equation}", display: true},
{left: "\\begin{align}", right: "\\end{align}", display: true},
{left: "\\begin{alignat}", right: "\\end{alignat}", display: true},
{left: "\\begin{gather}", right: "\\end{gather}", display: true},
{left: "\\begin{CD}", right: "\\end{CD}", display: true},
{left: "\\[", right: "\\]", display: true},
{left: "\[", right: "\]", display: true},
]
};
listMessagesQA: questionAnswer[] = [];
ngOnInit(): void { }
ngAfterViewInit(): void {
// Sample data for demonstration purposes added to listMessagesQA array
}
}
AppModule -
import { MarkdownModule, MarkedOptions } from 'ngx-markdown';
@NgModule({
declarations: [
AppComponent,
TestComponent
],
imports: [
BrowserModule,
MarkdownModule.forRoot({
markedOptions: {
provide: MarkedOptions,
useValue: {
gfm: true,
breaks: true
}
}
})
]
})
export class AppModule { }
Other relevant configurations and scripts have been included in the respective sections of the code snippet.
For a further understanding and additional references related to ngx-markdown setup, refer to the documentation links provided below:
- ngx-markdown Documentation
- Katex Autorender Documentation