我在 Angular 16 应用程序中使用 ngx-markdown 库以及其他一些库,尤其是 Katex。
当我的后端(LLM)返回带有所有必要的降价的响应并且在渲染此文本时,与 Katex 分隔符存在冲突时,我的问题出现了。
我使用了Katex的默认分隔符(https://katex.org/docs/autorender):
[
{left: "$$", right: "$$", display: true},
{left: '$', right: '$', display: false}, // I added
{left: "\\(", right: "\\)", display: false},
{left: "\(", right: "\)", display: false}, // I added
{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}, // I added
]
我添加了一些分隔符以尝试正确渲染。但是,当返回的文本包含 ( ) 或 [ ]、Katex、Angular 或 ngx-markdown 时,会将其视为分隔符并触发 Katex 的分隔符。因此,它渲染不正确。
以下是 Angular 脚本的主要部分:
HTML-
<markdown lineNumbers katex [katexOptions]="optionsKatex" clipboard [clipboardButtonTemplate]="buttonTemplate">
{{ mensagem.content }}
</markdown>
Angular TypeScript 组件:
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}, // I added
{left: "\\(", right: "\\)", display: false},
{left: "\(", right: "\)", display: false}, // I added
{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}, // I added
]
};
listMessagesQA: questionAnswer[] = [];
ngOnInit(): void { }
ngAfterViewInit(): void {
this.listMessagesQA.push({ content: 'A Meta é uma empresa de tecnologia que teve sua fundação em 1990, em São Leopoldo, no Rio Grande do Sul, Brasil[3]. Atualmente, a empresa opera não só no Brasil, mas também no exterior, estando presente em mais de 100 cidades ao redor do mundo, com sedes em São Paulo, Miami e Waterloo, e é parceira da multinacional alemã SAP[3]. A Meta tem como foco realizar consultoria estratégica para implementar soluções de tecnologia e transformação digital, auxiliando seus clientes a atualizarem seus modelos de negócios[3].\n\nAlém disso, a Meta foi reconhecida como uma das melhores empresas de TI para se trabalhar em 2020 e 2021, pelo Great Place to Work[3]. A empresa busca acelerar resultados de grandes e médias companhias, tanto no Brasil quanto no exterior, implementando soluções inovadoras[3].\n\nA empresa também projeta aquisições em áreas como experiência do usuário (UX), inteligência artificial (IA) e segmento SAP, buscando promover um ecossistema de inovação que conecta startups, investidores, empresas, parceiros, universidades, laboratórios de pesquisa e sociedade, por meio de seu braço de Venture Capital e investimentos, a Meta Ventures[3].\n\nReferências:\n1. https://pt.wikipedia.org/wiki/Meta_(empresa_de_tecnologia)\n2. https://pt.wikipedia.org/w/index.php?title=Meta_(empresa_de_tecnologia)&oldid=67577792', type: 'Answer', keyChat:0, likeSelected: false, dislikeSelected: false, isActive: true, isButtonsDisabled: false });
this.listMessagesQA.push({ content: "O cálculo do delta (\( \Delta \)) de uma equação de segundo grau na forma \( ax^2 + bx + c = 0 \) é feito pela fórmula: \[ \Delta = b^2 - 4ac \] onde: - \( a \), \( b \) e \( c \) são os coeficientes da equação de segundo grau; - \( \Delta \) é o discriminante, que é utilizado para determinar a natureza das raízes da equação. O valor do discriminante (\( \Delta \)) é fundamental para identificar se a equação possui duas raízes reais distintas (\( \Delta > 0 \)), uma raiz real (\( \Delta = 0 \)) ou raízes complexas conjugadas (\( \Delta < 0 \)).", type: 'Answer', keyChat:0, likeSelected: false, dislikeSelected: false, isActive: true, isButtonsDisabled: false });
this.listMessagesQA.push({ content: `A fórmula de Bhaskara é utilizada para encontrar as raízes de uma equação de segundo grau na forma \\( ax^2 + bx + c = 0 \\). A fórmula é dada por:\n\n\\[x = \\frac{{-b \\pm \\sqrt{{b^2 - 4ac}}}}{{2a}}\\]\n\nonde:\n- \\( a \\), \\( b \\) e \\( c \\) são os coeficientes da equação de segundo grau;\n- O termo \\( b^2 - 4ac \\) é chamado de discriminante.\n\nEssa fórmula é fundamental para resolver equações quadráticas e encontrar os valores de \\( x \\) que satisfazem a equação dada.`, type: 'Answer', keyChat:0, likeSelected: false, dislikeSelected: false, isActive: true, isButtonsDisabled: false });
this.listMessagesQA.push({ content: 'A fórmula do discriminante (delta) da equação quadrática $ ax^2 + bx + c = 0 $ é:\n\n$$ \\Delta = b^2 - 4ac $$', type: 'Answer', keyChat:0, likeSelected: false, dislikeSelected: false, isActive: true, isButtonsDisabled: false });
}
}
应用程序模块 -
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 { }
角度 json -
"styles": [
"src/styles.scss",
"node_modules/prismjs/themes/prism-okaidia.css",
"node_modules/prismjs/plugins/line-numbers/prism-line-numbers.css",
"node_modules/katex/dist/katex.min.css"
],
"scripts": [
"node_modules/marked/marked.min.js",
"node_modules/prismjs/prism.js",
"node_modules/prismjs/plugins/line-numbers/prism-line-numbers.js",
"node_modules/katex/dist/katex.min.js",
"node_modules/katex/dist/contrib/auto-render.min.js",
"node_modules/clipboard/dist/clipboard.min.js",
"node_modules/prismjs/components/prism-python.min.js",
"node_modules/prismjs/components/prism-css.min.js",
"node_modules/prismjs/components/prism-cobol.min.js",
"node_modules/prismjs/components/prism-java.min.js",
"node_modules/prismjs/components/prism-fortran.min.js",
"node_modules/prismjs/components/prism-csv.min.js",
"node_modules/prismjs/components/prism-markup.min.js",
"node_modules/prismjs/components/prism-javascript.min.js",
"node_modules/prismjs/components/prism-abap.min.js",
"node_modules/prismjs/components/prism-bash.min.js",
"node_modules/prismjs/components/prism-basic.min.js",
"node_modules/prismjs/components/prism-batch.min.js",
"node_modules/prismjs/components/prism-csharp.min.js",
"node_modules/prismjs/components/prism-docker.min.js",
"node_modules/prismjs/components/prism-excel-formula.min.js",
"node_modules/prismjs/components/prism-git.min.js",
"node_modules/prismjs/components/prism-go.min.js",
"node_modules/prismjs/components/prism-graphql.min.js",
"node_modules/prismjs/components/prism-http.min.js",
"node_modules/prismjs/components/prism-json.min.js",
"node_modules/prismjs/components/prism-julia.min.js",
"node_modules/prismjs/components/prism-kotlin.min.js",
"node_modules/prismjs/components/prism-latex.min.js",
"node_modules/prismjs/components/prism-markdown.min.js",
"node_modules/prismjs/components/prism-matlab.min.js",
"node_modules/prismjs/components/prism-mongodb.min.js",
"node_modules/prismjs/components/prism-nginx.min.js",
"node_modules/prismjs/components/prism-pascal.min.js",
"node_modules/prismjs/components/prism-powershell.min.js",
"node_modules/prismjs/components/prism-r.min.js",
"node_modules/prismjs/components/prism-regex.min.js",
"node_modules/prismjs/components/prism-rust.min.js",
"node_modules/prismjs/components/prism-scss.min.js",
"node_modules/prismjs/components/prism-scheme.min.js",
"node_modules/prismjs/components/prism-sql.min.js",
"node_modules/prismjs/components/prism-typescript.min.js",
"node_modules/prismjs/components/prism-vim.min.js",
"node_modules/prismjs/components/prism-visual-basic.min.js",
"node_modules/prismjs/components/prism-yaml.min.js"
]
Angular 版本依赖项 -
"dependencies": {
"@angular/animations": "^16.2.0",
"@angular/common": "^16.2.0",
"@angular/compiler": "^16.2.0",
"@angular/core": "^16.2.0",
"@angular/forms": "^16.2.0",
"@angular/platform-browser": "^16.2.0",
"@angular/platform-browser-dynamic": "^16.2.0",
"@angular/router": "^16.2.0",
"@reactivex/rxjs": "^6.6.7",
"@rxjs/rx": "^4.1.0",
"bootstrap": "^5.3.1",
"bootstrap-icons": "^1.11.0",
"clipboard": "^2.0.11",
"comon": "^1.0.4",
"jwt-decode": "^4.0.0",
"katex": "^0.16.9",
"marked": "^4.3.0",
"ng2-cookies": "^1.0.12",
"ng2-pdf-viewer": "^10.0.0",
"ngx-markdown": "^16.0.0",
"prismjs": "^1.28.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.13.0"
}
我用于实现 ngx-markdown 的参考资料: