Troubles with Katex/ngx-markdown Display in Angular 16

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:

  1. ngx-markdown Documentation
  2. Katex Autorender Documentation

Answer №1

Dealing with a similar problem. The string I'm working with has instances of \n - I opted to replace them with <br>

const str = input.replaceAll('\n', '<br>');

original

updated

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Injection of environmental variables into app services

Through the use of Nx, I have created multiple apps that each have their own environment with different API URLs. The Nx Workspace library includes shared services that are utilized among all apps, however, it is necessary to pass the environment-api-url w ...

Using Jasmine to simulate an if/else statement in Angular/Typescript unit testing

After making a minor change to an existing function, it has been flagged as new code during our quality checks. This means I need to create a unit test specifically for the new 4 lines of code. The challenge is that there was never a unit test in place for ...

"Enhancing User Experience with Angular 2: Customizing Component Selection and Sty

I am currently working on an Angular application that fetches a configuration file in .json format. My goal is to dynamically choose components and apply inline styles to them. Below is an example of the structure of the configuration data obtained from a ...

Infinite scrolling pagination feature in ag-grid not functioning properly with Angular

Upon the initial component load, all data appears as expected. However, when switching to the next page, the grid clears and an error is shown in the console: ERROR Error: ag-Grid: unable to draw rows while already drawing rows. It seems that a grid API ...

The data structure does not match the exact object type

Why isn't this code snippet functioning as expected? It seems that 'beta' has keys of type string and their values are compatible (id is a number type, and temp is also a number type). Additionally, the Record function should make the values ...

The confirm alert from Material UI is being obscured by the dialog

How can I ensure that a material ui dialog does not hide the alert behind it when confirming an action? Is there a way to adjust the z index of the alert so that it appears in front of the dialog? import Dialog from "@material-ui/core/Dialog"; i ...

Component coding in Angular 2 allows for seamless integration and customization of Material

I am looking to initiate the start.toggle() function (associated with Angular 2 material md-sidenav-layout component) when the test() method is triggered. How can I execute md-sidenav-layout's start.toggle() in the app.component.ts file? app.componen ...

Using Typescript generics within a callback function

I am currently working on developing a versatile service that can fetch data from a remote source and create objects based on that data. @Injectable() export class tService<T> { private _data: BehaviorSubject<T[]> = new BehaviorSubject([]) ...

TypeScript equivalent to Python's method for removing non-whitespace characters is achieved by

I understand that I can utilize .trim() to eliminate trailing spaces Is there a method to trim non-space characters instead? In [1]: str = 'abc/def/ghi/' In [2]: s.strip('/') Out[2]: 'abc/def/ghi' I am referring to the funct ...

Using routerLink for linking to multiple components

Below is the anchor tag provided: <a class="uppercase" routerLink="settings/pressure" routerLinkActive="text-success" (click)="closeModal()" > <div class="pad-btm"> PRESSURE </div> </a> I need to include another route ...

Parsing of the module failed due to an unexpected character appearing when trying to insert a TTF file into the stylesheet

As a newcomer to Angular, I recently completed the tutorial and am now working on my first app. While trying to add an OTF file, everything went smoothly. However, when I made a change to my app.component.css file and included this code snippet: @font-fa ...

How do I access the current state in Ngrx Store without the need to subscribe, specifically for use in a route Resolve?

Presently, my Resolve implementation is quite straightforward: export class UserResolve implements Resolve<any>{ constructor(private userService: UserService){} resolve(route: ActivatedRouteSnapshot){ return this.userService.get(route. ...

Using a directive template to invoke a service method

Imagine you have a custom directive: <product> <img ng-src='{{someImage}}' /> </product> This directive is defined like this: app.directive("product", function() { return { scope: {}, restrict: 'E& ...

A Fresh Approach for Generating Unique UUIDs without Bitwise Operators

To generate UUIDs in TypeScript, I have implemented a method inspired by the solution provided on Stack Overflow. The code effectively converts JavaScript to TypeScript. generateUUID(): string { let date = new Date().getTime(); if (window.performa ...

Angular 6 Calendar Template issues with parsing: Unable to link to 'view' as it is not recognized as a valid property of 'div'

I am in the process of developing an application that utilizes this angular calendar. My tech stack includes Angular 6 with AngularFire2 and Firebase. Below is my app.module.ts file: import { BrowserModule } from '@angular/platform-browser'; imp ...

Is there a way to restrict props.children.some to only accept image types?

Currently troubleshooting the following issue: An error is occurring: 'Property 'type' does not exist on type 'true | ReactChild | ReactFragment | ReactPortal'. Property 'type' does not exist on type 'string'. ...

AngularJS: Getting language details in AngularJS based on language code

When working with Android, it is possible to obtain language information directly from the language code using the Locale class. The example below demonstrates this: Locale locale = new Locale("fr"); locale.getDisplayName(locale); // Français locale.getD ...

"Encountering a duplicate key error when performing a bulk upsert operation with LoopbackJS and MongoDB

Attempting to perform batch upserts of multiple documents at once using a PUT request to a loopback-based Rest API. The request body consists of an array of JSON objects. [ {"_id" : "1", "data" : "foo" }, {"_id" : "2", "data" : "bar" ...

Utilizing PrimeNG Datatable to Connect with an Array of Objects in a Dynamic Manner

I currently have an array of objects with various properties such as: "rows": [ { "id": 1, "createdAt": "2017-07-21T06:05:38.000Z", "updatedAt": "2017-07-21T06:05:38.000Z", "createdBy": null, "modifiedBy": null, "name": "ABC", "owner": "Dian ...

Learn how to reposition the mat-option easily

I have an angular app with an autocomplete field that I need to adjust the position of. I have consulted the official documentation under the method updatePosition, which states: "Updates the position of the autocomplete suggestion panel to ensure that it ...