/// /// Copyright © 2016-2021 The Thingsboard Authors /// /// Licensed under the Apache License, Version 2.0 (the "License"); /// you may not use this file except in compliance with the License. /// You may obtain a copy of the License at /// /// http://www.apache.org/licenses/LICENSE-2.0 /// /// Unless required by applicable law or agreed to in writing, software /// distributed under the License is distributed on an "AS IS" BASIS, /// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. /// See the License for the specific language governing permissions and /// limitations under the License. /// import { MarkedOptions, MarkedRenderer } from 'ngx-markdown'; import { Inject, Injectable } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; import { DOCUMENT } from '@angular/common'; import { WINDOW } from '@core/services/window.service'; import { Tokenizer } from 'marked'; import * as marked from 'marked'; const copyCodeBlock = '{:copy-code}'; const autoBlock = '{:auto}'; const targetBlankBlock = '{:target="_blank"}'; // @dynamic @Injectable({ providedIn: 'root' }) export class MarkedOptionsService extends MarkedOptions { renderer = new MarkedRenderer(); headerIds = true; gfm = true; breaks = false; pedantic = false; smartLists = true; smartypants = false; mangle = false; private renderer2 = new MarkedRenderer(); private id = 1; constructor(private translate: TranslateService, @Inject(WINDOW) private readonly window: Window, @Inject(DOCUMENT) private readonly document: Document) { super(); // @ts-ignore const tokenizer: Tokenizer = { autolink(src: string, mangle: (cap: string) => string): marked.Tokens.Link { if (src.endsWith(copyCodeBlock)) { return undefined; } else { // @ts-ignore return false; } }, url(src: string, mangle: (cap: string) => string): marked.Tokens.Link { if (src.endsWith(copyCodeBlock)) { return undefined; } else { // @ts-ignore return false; } } }; marked.use({tokenizer}); this.renderer.code = (code: string, language: string | undefined, isEscaped: boolean) => { if (code.endsWith(copyCodeBlock)) { code = code.substring(0, code.length - copyCodeBlock.length); const content = postProcessCodeContent(this.renderer2.code(code, language, isEscaped), code); this.id++; return this.wrapCopyCode(this.id, content, code); } else { return this.wrapDiv(postProcessCodeContent(this.renderer2.code(code, language, isEscaped), code)); } }; this.renderer.table = (header: string, body: string) => { let autoLayout = false; if (header.includes(autoBlock)) { autoLayout = true; header = header.replace(autoBlock, ''); } let table = this.renderer2.table(header, body); if (autoLayout) { table = table.replace('