From 66d24b764380281295593330aee54b9394270df4 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Wed, 20 Oct 2021 17:15:36 +0200 Subject: [PATCH 1/3] Made plugin compatible with TypeDoc 0.22.x --- package.json | 4 +- src/index.ts | 14 +- src/plugin.ts | 187 ++++++++----------------- test/__snapshots__/plugin.test.ts.snap | 20 +-- test/e2e.test.ts | 59 -------- test/plugin.test.ts | 28 +--- tsconfig.json | 2 +- yarn.lock | 97 +++++-------- 8 files changed, 106 insertions(+), 305 deletions(-) delete mode 100644 test/e2e.test.ts diff --git a/package.json b/package.json index 979f105..b843bea 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "html-escaper": "^3.0.0" }, "peerDependencies": { - "typedoc": ">=0.21.0" + "typedoc": ">=0.22.0" }, "devDependencies": { "@types/html-escaper": "^3.0.0", @@ -56,7 +56,7 @@ "rollup": "^2.53.3", "rollup-plugin-typescript2": "^0.30.0", "ts-jest": "^27.0.4", - "typedoc": "^0.21.4", + "typedoc": "^0.22.6", "typescript": "^4.3.5" } } diff --git a/src/index.ts b/src/index.ts index f608988..fdd35ad 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,14 +1,6 @@ -import { Application } from 'typedoc/dist/lib/application'; +import { Application } from 'typedoc'; import { MermaidPlugin } from './plugin'; -export function load(PluginHost: Application): void { - const app = PluginHost.owner; - if (app.converter.hasComponent('mermaid')) { - return; - } - - /** - * Add the plugin to the converter instance - */ - app.converter.addComponent('mermaid', new MermaidPlugin(app.converter)); +export function load(app: Application): void { + new MermaidPlugin().addToApplication(app); } diff --git a/src/plugin.ts b/src/plugin.ts index 5018c6b..2c4f4a4 100644 --- a/src/plugin.ts +++ b/src/plugin.ts @@ -1,155 +1,82 @@ import * as html from 'html-escaper'; -import { Converter } from 'typedoc/dist/lib/converter'; -import { Component, ConverterComponent } from 'typedoc/dist/lib/converter/components'; -import { Context } from 'typedoc/dist/lib/converter/context'; -import { Comment, CommentTag } from 'typedoc/dist/lib/models/comments'; -import { MarkdownEvent, PageEvent } from 'typedoc/dist/lib/output/events'; +import { Converter, Context, PageEvent, Application, ReflectionKind } from 'typedoc'; /** - * Mermaid plugin component. + * 1. Load mermaid.js library. + * 2. Initialize mermaid. */ -@Component({ name: 'mermaid' }) -export class MermaidPlugin extends ConverterComponent { - /** - * 1. Load mermaid.js library. - * 2. Initialize mermaid. - * 3. Close body tag. - */ - private static customScriptsAndBodyClosingTag = ` - - - - `; - - private static markdownStartMermaid = '\n```mermaid\n'; - private static markdownEndMermaid = '\n```\n'; - - /** - * filter logic for Comment exist - */ - private static filterComment(comment: undefined | Comment): comment is Comment { - return comment !== undefined && !!comment; - } - - /** - * filter logic for CommentTags exist - */ - private static filterCommentTags(tags: CommentTag[] | undefined): tags is CommentTag[] { - return tags !== undefined && !!tags; - } +const script = + '' + + ''; - /** - * return turn when tag's paramName is 'mermaid' - */ - private static isMermaidCommentTag(tag: CommentTag): boolean { - return tag.tagName === 'mermaid'; - } - - /** - * get CommentTags for using `@mermaid` annotation from Context. - */ - private static mermaidTags(context: Context): CommentTag[] { - return Object.values(context.project.reflections) // get reflection from context - .map((reflection) => reflection.comment) // get Comment from Reflection - .filter(this.filterComment) // filter only comment exist - .map((comment) => comment.tags) // get CommentTags from Comment - .filter(this.filterCommentTags) // filter only CommentTags exist - .reduce((a, b) => a.concat(b), []) // merge all CommentTags - .filter(this.isMermaidCommentTag); // filter tag that paramName is 'mermaid' - } +const mermaidBlockStart = '
'; +const mermaidBlockEnd = '
'; - /** - * Regex literal that matches body closing tag. - */ - private readonly BODY_CLOSING_TAG = /<\/body>/; +export class MermaidPlugin { + public addToApplication(app: Application): void { + app.converter.on(Converter.EVENT_RESOLVE_BEGIN, (context: Context) => { + this.onConverterResolveBegin(context); + }); - /** - * The first line of text wraps h4. - * The other wraps by div classed mermaid. - */ - public convertCommentTagText(tagText: string): string { - const texts = tagText.split('\n'); - // take first line - const title = texts.shift(); - // the other - const mermaid = texts.join('\n'); - return `#### ${title} \n\n
${mermaid}
`; + app.renderer.on({ + [PageEvent.END]: (event: PageEvent) => { + this.onEndPage(event); + }, + }); } - /** - * Insert custom script before closing body tag. - */ - public convertPageContents(contents: string): string { - if (this.BODY_CLOSING_TAG.test(contents)) { - return contents.replace(this.BODY_CLOSING_TAG, MermaidPlugin.customScriptsAndBodyClosingTag); + private onConverterResolveBegin(context: Context): void { + for (const reflection of context.project.getReflectionsByKind(ReflectionKind.All)) { + const { comment } = reflection; + if (comment) { + comment.text = this.handleMermaidCodeBlocks(comment.text); + for (const tag of comment.tags) { + if (tag.tagName === 'mermaid') { + tag.text = this.handleMermaidTag(tag.text); + } else { + tag.text = this.handleMermaidCodeBlocks(tag.text); + } + } + } } - return contents; } - /** - * listen to event on initialization + * Convert the text of `@mermaid` tags. + * + * This first line will be the title. It will be wrapped in an h4. + * All other lines are mermaid code and will be converted into a mermaid block. */ - public initialize(): void { - this.listenTo(this.owner, { - [Converter.EVENT_RESOLVE_BEGIN]: this.onResolveBegin, - }) - .listenTo(this.application.renderer, { - [PageEvent.END]: this.onPageEnd, - }) - .listenTo( - this.application.renderer, - { - [MarkdownEvent.PARSE]: this.onParseMarkdown, - }, - undefined, - 100, - ); - } + public handleMermaidTag(text: string): string { + const title = /^.*/.exec(text)?.[0] ?? ''; + const code = text.slice(title.length); + return `#### ${title}\n\n${this.toMermaidBlock(code)}`; + } /** - * Triggered when the converter begins converting a project. + * Replaces mermaid code blocks in Markdown text with mermaid blocks. */ - public onResolveBegin(context: Context): void { - MermaidPlugin.mermaidTags(context).forEach((tag) => { - // convert - tag.text = this.convertCommentTagText(tag.text); + public handleMermaidCodeBlocks(text: string): string { + return text.replace(/^```mermaid[ \t\r]*\n([\s\S]*?)^```[ \t]*$/gm, (m, code) => { + return this.toMermaidBlock(code); }); } - /** - * Triggered after a document has been rendered, just before it is written to disc. - * Remove duplicate lines to tidy up output + * Creates a mermaid block for the given mermaid code. */ - public onPageEnd(page: PageEvent): void { - if (page.contents !== undefined) { - // convert - page.contents = this.convertPageContents(page.contents); - } + private toMermaidBlock(mermaidCode: string): string { + return mermaidBlockStart + html.escape(mermaidCode.trim()) + mermaidBlockEnd; } - public onParseMarkdown(event: MarkdownEvent): void { - event.parsedText = this.replaceMarkdownMermaidCodeBlocks(event.parsedText); - } - - public replaceMarkdownMermaidCodeBlocks(s: string): string { - let out = ''; - let i = 0; - for ( - let j = s.indexOf(MermaidPlugin.markdownStartMermaid, i); - j >= 0; - j = s.indexOf(MermaidPlugin.markdownStartMermaid, i) - ) { - const start = j + MermaidPlugin.markdownStartMermaid.length; - const end = s.indexOf(MermaidPlugin.markdownEndMermaid, start); - out += `${s.slice(i, j + 1)}
${html.escape(s.slice(start, end))}
`; - i = end + MermaidPlugin.markdownEndMermaid.length - 1; + private onEndPage(event: PageEvent): void { + if (event.contents === undefined) { + return; } - return out + s.slice(i); + if (!event.contents.includes(mermaidBlockStart)) { + // this page doesn't need to load mermaid + } + + // find the closing tag and insert our mermaid scripts + const bodyEndIndex = event.contents.lastIndexOf(''); + event.contents = event.contents.slice(0, bodyEndIndex) + script + event.contents.slice(bodyEndIndex); } } diff --git a/test/__snapshots__/plugin.test.ts.snap b/test/__snapshots__/plugin.test.ts.snap index 2d618d5..a30a5bb 100644 --- a/test/__snapshots__/plugin.test.ts.snap +++ b/test/__snapshots__/plugin.test.ts.snap @@ -1,9 +1,9 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`MermaidPlugin convert CommentTag 1`] = ` -"#### title +"#### title -
graph
" +
graph
" `; exports[`MermaidPlugin convert Markdown snippet returns same value if body closing tag not exist 1`] = ` @@ -14,19 +14,3 @@ exports[`MermaidPlugin convert Markdown snippet returns same value if body closi more text" `; - -exports[`MermaidPlugin convert PageContents returns same value if body closing tag not exist 1`] = `"hoge"`; - -exports[`MermaidPlugin convert PageContents returns script tag for mermaid.js, initialize mermaid script, and body closing tag 1`] = ` -" - - - - " -`; diff --git a/test/e2e.test.ts b/test/e2e.test.ts deleted file mode 100644 index beec28f..0000000 --- a/test/e2e.test.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { DUMMY_APPLICATION_OWNER } from 'typedoc/dist/lib/utils/component'; -import { MermaidPlugin } from '../src/plugin'; - -const plugin = new MermaidPlugin(DUMMY_APPLICATION_OWNER); - -describe('MermaidPlugin e2e', () => { - it('onBegin not to throw Exception', () => { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const contexts: any[] = [ - { - project: { - reflections: { - 1: { - comment: { - tags: [ - { - paramName: '', - tagName: 'mermaid', - text: 'aaa', - }, - ], - }, - }, - }, - }, - }, - { - project: { - reflections: {}, - }, - }, - { - project: { - reflections: { - 1: {}, - }, - }, - }, - { - project: { - reflections: { - 1: { - comment: {}, - }, - }, - }, - }, - ]; - - contexts.forEach((context) => expect(() => plugin.onResolveBegin(context)).not.toThrow()); - }); - - it('onPageEnd not to throw Exception', () => { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const pageEvents: any[] = [{ contents: '' }, {}]; - - pageEvents.forEach((pageEvent) => expect(() => plugin.onPageEnd(pageEvent)).not.toThrow()); - }); -}); diff --git a/test/plugin.test.ts b/test/plugin.test.ts index 75047ac..667c0aa 100644 --- a/test/plugin.test.ts +++ b/test/plugin.test.ts @@ -1,41 +1,19 @@ -import { Application } from 'typedoc/dist/lib/application'; import { MermaidPlugin } from '../src/plugin'; describe('MermaidPlugin', () => { - let plugin: MermaidPlugin; - - beforeEach(() => { - const app = new Application(); - plugin = new MermaidPlugin(app.converter); - }); + const plugin = new MermaidPlugin(); it('convert CommentTag', () => { const input = 'title\ngraph'; - const result = plugin.convertCommentTagText(input); + const result = plugin.handleMermaidTag(input); expect(result).toMatch('#### title'); expect(result).toMatch('
graph
'); expect(result).toMatchSnapshot(); }); - it('convert PageContents returns script tag for mermaid.js, initialize mermaid script, and body closing tag', () => { - const input = ''; - const result = plugin.convertPageContents(input); - expect(result).toMatch(''); - expect(result).toMatch('mermaid.initialize({'); - expect(result).toMatch(/src="https:\/\/unpkg.com\/mermaid\/dist\/mermaid.min.js"/); - expect(result).toMatchSnapshot(); - }); - - it('convert PageContents returns same value if body closing tag not exist', () => { - const input = 'hoge'; - const result = plugin.convertPageContents(input); - expect(result).toEqual('hoge'); - expect(result).toMatchSnapshot(); - }); - it('convert Markdown snippet returns same value if body closing tag not exist', () => { const input = '#### title\n\n```mermaid\ngraph LR\n --> \n```\n\nmore text'; - const result = plugin.replaceMarkdownMermaidCodeBlocks(input); + const result = plugin.handleMermaidCodeBlocks(input); expect(result).toMatch('#### title\n'); expect(result).toMatch('
graph LR\n <a> --> <b>
'); expect(result).toMatch('\nmore text'); diff --git a/tsconfig.json b/tsconfig.json index 963adfc..beb8407 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,7 @@ { "compilerOptions": { "target": "ESNext", - "experimentalDecorators": true, + "moduleResolution": "node", "allowJs": false, "noImplicitAny": true, "noImplicitReturns": true, diff --git a/yarn.lock b/yarn.lock index d46d18f..3be8669 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1279,11 +1279,6 @@ combined-stream@^1.0.8: dependencies: delayed-stream "~1.0.0" -commander@~2.20.3: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -1946,7 +1941,7 @@ glob@^7.1.2, glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.1.4, glob@^7.1.7: +glob@^7.1.4: version "7.1.7" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== @@ -1958,6 +1953,18 @@ glob@^7.1.4, glob@^7.1.7: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + globals@^11.1.0: version "11.12.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" @@ -1992,18 +1999,6 @@ graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== -handlebars@^4.7.7: - version "4.7.7" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" - integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== - dependencies: - minimist "^1.2.5" - neo-async "^2.6.0" - source-map "^0.6.1" - wordwrap "^1.0.0" - optionalDependencies: - uglify-js "^3.1.4" - has-bigints@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" @@ -2811,6 +2806,11 @@ json5@^2.1.2, json5@^2.2.0: dependencies: minimist "^1.2.5" +jsonc-parser@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.0.0.tgz#abdd785701c7e7eaca8a9ec8cf070ca51a745a22" + integrity sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA== + jsonfile@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" @@ -2932,10 +2932,10 @@ makeerror@1.0.x: dependencies: tmpl "1.0.x" -marked@^2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/marked/-/marked-2.1.3.tgz#bd017cef6431724fd4b27e0657f5ceb14bff3753" - integrity sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA== +marked@^3.0.4: + version "3.0.7" + resolved "https://registry.yarnpkg.com/marked/-/marked-3.0.7.tgz#343aad9e91b96249b495c99c512ea09cfe06de1e" + integrity sha512-ctKqbnLuNbsHbI26cfMyOlKgXGfl1orOv1AvWWDX7AkgfMOwCWvmuYc+mVLeWhQ9W6hdWVBynOs96VkcscKo0Q== merge-stream@^2.0.0: version "2.0.0" @@ -2972,7 +2972,7 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -minimatch@^3.0.0, minimatch@^3.0.4: +minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== @@ -3004,11 +3004,6 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= -neo-async@^2.6.0: - version "2.6.1" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" - integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== - node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -3305,7 +3300,7 @@ pretty-format@^27.0.6: ansi-styles "^5.0.0" react-is "^17.0.1" -progress@^2.0.0, progress@^2.0.3: +progress@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== @@ -3492,12 +3487,12 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -shiki@^0.9.3: - version "0.9.5" - resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.9.5.tgz#c8da81a05fbfd1810729c6873901a729a72ec541" - integrity sha512-XFn+rl3wIowDjzdr5DlHoHgQphXefgUTs2bNp/bZu4WF9gTrTLnKwio3f28VjiFG6Jpip7yQn/p4mMj6OrjrtQ== +shiki@^0.9.11: + version "0.9.12" + resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.9.12.tgz#70cbc8c1bb78ff7b356f84a7eecdb040efddd247" + integrity sha512-VXcROdldv0/Qu0w2XvzU4IrvTeBNs/Kj/FCmtcEXGz7Tic/veQzliJj6tEiAgoKianhQstpYmbPDStHU5Opqcw== dependencies: - json5 "^2.2.0" + jsonc-parser "^3.0.0" onigasm "^2.2.5" vscode-textmate "5.2.0" @@ -3835,38 +3830,22 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -typedoc-default-themes@^0.12.10: - version "0.12.10" - resolved "https://registry.yarnpkg.com/typedoc-default-themes/-/typedoc-default-themes-0.12.10.tgz#614c4222fe642657f37693ea62cad4dafeddf843" - integrity sha512-fIS001cAYHkyQPidWXmHuhs8usjP5XVJjWB8oZGqkTowZaz3v7g3KDZeeqE82FBrmkAnIBOY3jgy7lnPnqATbA== - -typedoc@^0.21.4: - version "0.21.4" - resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.21.4.tgz#fced3cffdc30180db60a5dbfec9dbbb273cb5b31" - integrity sha512-slZQhvD9U0d9KacktYAyuNMMOXJRFNHy+Gd8xY2Qrqq3eTTTv3frv3N4au/cFnab9t3T5WA0Orb6QUjMc+1bDA== +typedoc@^0.22.6: + version "0.22.6" + resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.22.6.tgz#1122f83a6eb5cd7dbb26d1924de1f9de9e8c7c7e" + integrity sha512-ePbJqOaz0GNkU2ehRwFwBpLD4Gp6m7jbJfHysXmDdjVKc1g8DFJ83r/LOZ9TZrkC661vgpoIY3FjSPEtUilHNA== dependencies: - glob "^7.1.7" - handlebars "^4.7.7" + glob "^7.2.0" lunr "^2.3.9" - marked "^2.1.1" - minimatch "^3.0.0" - progress "^2.0.3" - shiki "^0.9.3" - typedoc-default-themes "^0.12.10" + marked "^3.0.4" + minimatch "^3.0.4" + shiki "^0.9.11" typescript@^4.3.5: version "4.3.5" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4" integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA== -uglify-js@^3.1.4: - version "3.7.6" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.7.6.tgz#0783daa867d4bc962a37cc92f67f6e3238c47485" - integrity sha512-yYqjArOYSxvqeeiYH2VGjZOqq6SVmhxzaPjJC1W2F9e+bqvFL9QXQ2osQuKUFjM2hGjKG2YclQnRKWQSt/nOTQ== - dependencies: - commander "~2.20.3" - source-map "~0.6.1" - unbox-primitive@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" @@ -3991,7 +3970,7 @@ word-wrap@^1.2.3: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== -wordwrap@^1.0.0, wordwrap@~1.0.0: +wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= From 1fac7067e059a5786f2bb1af06b76dc1e1780b7d Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Wed, 20 Oct 2021 17:23:02 +0200 Subject: [PATCH 2/3] Revert back to unpkg.com --- src/plugin.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugin.ts b/src/plugin.ts index 2c4f4a4..6396eb3 100644 --- a/src/plugin.ts +++ b/src/plugin.ts @@ -6,7 +6,7 @@ import { Converter, Context, PageEvent, Application, ReflectionKind } from 'type * 2. Initialize mermaid. */ const script = - '' + + '' + ''; const mermaidBlockStart = '
'; From 957f6afe0360cf70beeb862772c3ff04a1c152c2 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Wed, 20 Oct 2021 17:24:12 +0200 Subject: [PATCH 3/3] Added more tests --- src/plugin.ts | 13 ++++++++----- test/__snapshots__/plugin.test.ts.snap | 4 ++++ test/plugin.test.ts | 16 ++++++++++++++++ 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/plugin.ts b/src/plugin.ts index 6396eb3..54b0d90 100644 --- a/src/plugin.ts +++ b/src/plugin.ts @@ -68,15 +68,18 @@ export class MermaidPlugin { } private onEndPage(event: PageEvent): void { - if (event.contents === undefined) { - return; + if (event.contents !== undefined) { + event.contents = this.insertMermaidScript(event.contents); } - if (!event.contents.includes(mermaidBlockStart)) { + } + public insertMermaidScript(html: string): string { + if (!html.includes(mermaidBlockStart)) { // this page doesn't need to load mermaid + return html; } // find the closing tag and insert our mermaid scripts - const bodyEndIndex = event.contents.lastIndexOf(''); - event.contents = event.contents.slice(0, bodyEndIndex) + script + event.contents.slice(bodyEndIndex); + const bodyEndIndex = html.lastIndexOf(''); + return html.slice(0, bodyEndIndex) + script + html.slice(bodyEndIndex); } } diff --git a/test/__snapshots__/plugin.test.ts.snap b/test/__snapshots__/plugin.test.ts.snap index a30a5bb..0f8034f 100644 --- a/test/__snapshots__/plugin.test.ts.snap +++ b/test/__snapshots__/plugin.test.ts.snap @@ -14,3 +14,7 @@ exports[`MermaidPlugin convert Markdown snippet returns same value if body closi more text" `; + +exports[`MermaidPlugin convert PageContents returns same value if body closing tag not exist 1`] = `"hoge"`; + +exports[`MermaidPlugin convert PageContents returns script tag for mermaid.js, initialize mermaid script, and body closing tag 1`] = `"
"`; diff --git a/test/plugin.test.ts b/test/plugin.test.ts index 667c0aa..866778c 100644 --- a/test/plugin.test.ts +++ b/test/plugin.test.ts @@ -11,6 +11,22 @@ describe('MermaidPlugin', () => { expect(result).toMatchSnapshot(); }); + it('convert PageContents returns script tag for mermaid.js, initialize mermaid script, and body closing tag', () => { + const input = '
'; + const result = plugin.insertMermaidScript(input); + expect(result).toMatch(''); + expect(result).toMatch('mermaid.initialize({'); + expect(result).toMatch(/src="https:\/\/unpkg.com\/mermaid\/dist\/mermaid.min.js"/); + expect(result).toMatchSnapshot(); + }); + + it('convert PageContents returns same value if body closing tag not exist', () => { + const input = 'hoge'; + const result = plugin.insertMermaidScript(input); + expect(result).toEqual('hoge'); + expect(result).toMatchSnapshot(); + }); + it('convert Markdown snippet returns same value if body closing tag not exist', () => { const input = '#### title\n\n```mermaid\ngraph LR\n
--> \n```\n\nmore text'; const result = plugin.handleMermaidCodeBlocks(input);