From 93c3fc480974b725f839249923ed12c3735811c3 Mon Sep 17 00:00:00 2001 From: Phodal Huang Date: Thu, 12 Mar 2020 14:38:37 +0800 Subject: [PATCH] feat: add basic code render --- .../markdown-render.component.ts | 65 +++++++++++++++++-- 1 file changed, 60 insertions(+), 5 deletions(-) diff --git a/src/app/shared/components/markdown-render/markdown-render.component.ts b/src/app/shared/components/markdown-render/markdown-render.component.ts index a8097231..87e9c7fa 100644 --- a/src/app/shared/components/markdown-render/markdown-render.component.ts +++ b/src/app/shared/components/markdown-render/markdown-render.component.ts @@ -1,5 +1,5 @@ -import { Component, Input, OnInit } from '@angular/core'; -import { MarkdownService } from 'ngx-markdown'; +import {Component, Input, OnInit} from '@angular/core'; +import {MarkdownService} from 'ngx-markdown'; @Component({ selector: 'component-markdown-render', @@ -11,11 +11,30 @@ export class MarkdownRenderComponent implements OnInit { src: string; loading = true; - constructor(private markdownService: MarkdownService) { } + // marked + escapeTest = /[&<>"']/; + escapeReplace = /[&<>"']/g; + escapeTestNoEncode = /[<>"']|&(?!#?\w+;)/; + escapeReplaceNoEncode = /[<>"']|&(?!#?\w+;)/g; + escapeReplacements = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + '\'': ''' + }; + + constructor(private markdownService: MarkdownService) { + } ngOnInit(): void { const markedOptions: any = this.markdownService.options; this.markdownService.renderer.image = this.renderImage(markedOptions).bind(this); + this.markdownService.renderer.code = this.renderCode(markedOptions).bind(this); + } + + endLoading() { + this.loading = false; } private renderImage(markedOptions: any) { @@ -34,8 +53,44 @@ export class MarkdownRenderComponent implements OnInit { }; } - endLoading() { - this.loading = false; + private renderCode(options: any) { + return (code: any, infoStr: any, escaped: any) => { + const lang = (infoStr || '').match(/\S*/)[0]; + + if (options.highlight) { + const out = options.highlight(code, lang); + if (out != null && out !== code) { + escaped = true; + code = out; + } + } + + if (!lang) { + return '
' + (escaped ? code : this.escape(code, true)) + '
'; + } + + return `
+    ${escaped ? code : this.escape(code, true)}
+
`; + }; + } + + getEscapeReplacement(ch) { + return this.escapeReplacements[ch]; + } + + escape(html: string, encode: boolean) { + if (encode) { + if (this.escapeTest.test(html)) { + return html.replace(this.escapeReplace, this.getEscapeReplacement.bind(this)); + } + } else { + if (this.escapeTestNoEncode.test(html)) { + return html.replace(this.escapeReplaceNoEncode, this.getEscapeReplacement.bind(this)); + } + } + + return html; } }