From 6df4b0e813b98598d218172d58c3b1f66c10c896 Mon Sep 17 00:00:00 2001 From: Tony Brix Date: Tue, 14 May 2024 21:45:22 -0600 Subject: [PATCH 01/14] fix types --- src/Instance.ts | 4 ++-- src/MarkedOptions.ts | 2 +- src/Parser.ts | 8 +++----- src/Renderer.ts | 18 +++++++++++------- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/Instance.ts b/src/Instance.ts index eb460e0642..5fcd9bd61f 100644 --- a/src/Instance.ts +++ b/src/Instance.ts @@ -146,11 +146,11 @@ export class Marked { if (!(prop in renderer)) { throw new Error(`renderer '${prop}' does not exist`); } - if (prop === 'options') { + if (['options', 'parser'].includes(prop)) { // ignore options property continue; } - const rendererProp = prop as Exclude; + const rendererProp = prop as Exclude; const rendererFunc = pack.renderer[rendererProp] as GenericRendererFunction; const prevRenderer = renderer[rendererProp] as GenericRendererFunction; // Replace renderer with func to run extension, but fall back if false diff --git a/src/MarkedOptions.ts b/src/MarkedOptions.ts index 78754f23fe..6be9d2f5fc 100644 --- a/src/MarkedOptions.ts +++ b/src/MarkedOptions.ts @@ -39,7 +39,7 @@ type HooksObject = { [K in keyof HooksApi]?: (...args: Parameters) => ReturnType | Promise> }; -type RendererApi = Omit<_Renderer, 'constructor' | 'options'>; +type RendererApi = Omit<_Renderer, 'constructor' | 'options' | 'parser'>; type RendererObject = { [K in keyof RendererApi]?: (...args: Parameters) => ReturnType | false }; diff --git a/src/Parser.ts b/src/Parser.ts index d1be35f80f..0a53c08b6a 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -19,6 +19,7 @@ export class _Parser { this.options.renderer = this.options.renderer || new _Renderer(); this.renderer = this.options.renderer; this.renderer.options = this.options; + this.renderer.parser = this; this.textRenderer = new _TextRenderer(); } @@ -75,9 +76,7 @@ export class _Parser { } case 'code': { const codeToken = token as Tokens.Code; - out += this.renderer.code(codeToken.text, - codeToken.lang, - !!codeToken.escaped); + out += this.renderer.code(codeToken); continue; } case 'table': { @@ -113,8 +112,7 @@ export class _Parser { } case 'blockquote': { const blockquoteToken = token as Tokens.Blockquote; - const body = this.parse(blockquoteToken.tokens); - out += this.renderer.blockquote(body); + out += this.renderer.blockquote(blockquoteToken); continue; } case 'list': { diff --git a/src/Renderer.ts b/src/Renderer.ts index e00868c977..59c5a8dd4e 100644 --- a/src/Renderer.ts +++ b/src/Renderer.ts @@ -4,36 +4,40 @@ import { escape } from './helpers.ts'; import type { MarkedOptions } from './MarkedOptions.ts'; +import type { Tokens } from './Tokens.ts'; +import type { _Parser } from './Parser.ts'; /** * Renderer */ export class _Renderer { options: MarkedOptions; + parser!: _Parser; // set by the parser constructor(options?: MarkedOptions) { this.options = options || _defaults; } - code(code: string, infostring: string | undefined, escaped: boolean): string { - const lang = (infostring || '').match(/^\S*/)?.[0]; + code({ text, lang, escaped }: Tokens.Code): string { + const langString = (lang || '').match(/^\S*/)?.[0]; - code = code.replace(/\n$/, '') + '\n'; + const code = text.replace(/\n$/, '') + '\n'; - if (!lang) { + if (!langString) { return '
'
         + (escaped ? code : escape(code, true))
         + '
\n'; } return '
'
       + (escaped ? code : escape(code, true))
       + '
\n'; } - blockquote(quote: string): string { - return `
\n${quote}
\n`; + blockquote({ tokens }: Tokens.Blockquote): string { + const body = this.parser.parse(tokens); + return `
\n${body}
\n`; } html(html: string, block?: boolean) : string { From 16798bc8aa6f94dcdb9cb17ba34a0d9e83c89dd1 Mon Sep 17 00:00:00 2001 From: Tony Brix Date: Wed, 15 May 2024 00:39:54 -0600 Subject: [PATCH 02/14] test --- package-lock.json | 459 ++++++++++++++++++--------------------- src/Parser.ts | 87 ++++---- src/Renderer.ts | 38 ++-- src/TextRenderer.ts | 18 +- src/Tokens.ts | 8 +- test/unit/marked.test.js | 18 +- 6 files changed, 298 insertions(+), 330 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5dc85a9040..de6abcf38b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5531,9 +5531,9 @@ } }, "node_modules/npm": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/npm/-/npm-10.5.0.tgz", - "integrity": "sha512-Ejxwvfh9YnWVU2yA5FzoYLTW52vxHCz+MHrOFg9Cc8IFgF/6f5AGPAvb5WTay5DIUP1NIfN3VBZ0cLlGO0Ys+A==", + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/npm/-/npm-10.7.0.tgz", + "integrity": "sha512-FXylyYSXNjgXx3l82BT8RSQvCoGIQ3h8YdRFGKNvo3Pv/bKscK4pdWkx/onwTpHDqGw+oeLf4Rxln9WVyxAxlQ==", "bundleDependencies": [ "@isaacs/string-locale-compare", "@npmcli/arborist", @@ -5542,6 +5542,7 @@ "@npmcli/map-workspaces", "@npmcli/package-json", "@npmcli/promise-spawn", + "@npmcli/redact", "@npmcli/run-script", "@sigstore/tuf", "abbrev", @@ -5550,8 +5551,6 @@ "chalk", "ci-info", "cli-columns", - "cli-table3", - "columnify", "fastest-levenshtein", "fs-minipass", "glob", @@ -5587,7 +5586,6 @@ "npm-profile", "npm-registry-fetch", "npm-user-validate", - "npmlog", "p-map", "pacote", "parse-conflict-json", @@ -5612,66 +5610,64 @@ "@npmcli/arborist": "^7.2.1", "@npmcli/config": "^8.0.2", "@npmcli/fs": "^3.1.0", - "@npmcli/map-workspaces": "^3.0.4", - "@npmcli/package-json": "^5.0.0", + "@npmcli/map-workspaces": "^3.0.6", + "@npmcli/package-json": "^5.1.0", "@npmcli/promise-spawn": "^7.0.1", - "@npmcli/run-script": "^7.0.4", - "@sigstore/tuf": "^2.3.1", + "@npmcli/redact": "^2.0.0", + "@npmcli/run-script": "^8.1.0", + "@sigstore/tuf": "^2.3.2", "abbrev": "^2.0.0", "archy": "~1.0.0", "cacache": "^18.0.2", "chalk": "^5.3.0", "ci-info": "^4.0.0", "cli-columns": "^4.0.0", - "cli-table3": "^0.6.3", - "columnify": "^1.6.0", "fastest-levenshtein": "^1.0.16", "fs-minipass": "^3.0.3", - "glob": "^10.3.10", + "glob": "^10.3.12", "graceful-fs": "^4.2.11", "hosted-git-info": "^7.0.1", - "ini": "^4.1.1", - "init-package-json": "^6.0.0", - "is-cidr": "^5.0.3", + "ini": "^4.1.2", + "init-package-json": "^6.0.2", + "is-cidr": "^5.0.5", "json-parse-even-better-errors": "^3.0.1", "libnpmaccess": "^8.0.1", "libnpmdiff": "^6.0.3", - "libnpmexec": "^7.0.4", + "libnpmexec": "^8.0.0", "libnpmfund": "^5.0.1", "libnpmhook": "^10.0.0", "libnpmorg": "^6.0.1", - "libnpmpack": "^6.0.3", + "libnpmpack": "^7.0.0", "libnpmpublish": "^9.0.2", "libnpmsearch": "^7.0.0", "libnpmteam": "^6.0.0", - "libnpmversion": "^5.0.1", - "make-fetch-happen": "^13.0.0", - "minimatch": "^9.0.3", + "libnpmversion": "^6.0.0", + "make-fetch-happen": "^13.0.1", + "minimatch": "^9.0.4", "minipass": "^7.0.4", "minipass-pipeline": "^1.2.4", "ms": "^2.1.2", - "node-gyp": "^10.0.1", + "node-gyp": "^10.1.0", "nopt": "^7.2.0", "normalize-package-data": "^6.0.0", "npm-audit-report": "^5.0.0", "npm-install-checks": "^6.3.0", - "npm-package-arg": "^11.0.1", + "npm-package-arg": "^11.0.2", "npm-pick-manifest": "^9.0.0", - "npm-profile": "^9.0.0", - "npm-registry-fetch": "^16.1.0", + "npm-profile": "^9.0.2", + "npm-registry-fetch": "^17.0.0", "npm-user-validate": "^2.0.0", - "npmlog": "^7.0.1", "p-map": "^4.0.0", - "pacote": "^17.0.6", + "pacote": "^18.0.3", "parse-conflict-json": "^3.0.1", - "proc-log": "^3.0.0", + "proc-log": "^4.2.0", "qrcode-terminal": "^0.12.0", - "read": "^2.1.0", + "read": "^3.0.1", "semver": "^7.6.0", - "spdx-expression-parse": "^3.0.1", + "spdx-expression-parse": "^4.0.0", "ssri": "^10.0.5", "supports-color": "^9.4.0", - "tar": "^6.2.0", + "tar": "^6.2.1", "text-table": "~0.2.0", "tiny-relative-date": "^1.3.0", "treeverse": "^3.0.0", @@ -5699,16 +5695,6 @@ "node": ">=8" } }, - "node_modules/npm/node_modules/@colors/colors": { - "version": "1.5.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.1.90" - } - }, "node_modules/npm/node_modules/@isaacs/cliui": { "version": "8.0.2", "dev": true, @@ -5783,7 +5769,7 @@ "license": "ISC" }, "node_modules/npm/node_modules/@npmcli/agent": { - "version": "2.2.1", + "version": "2.2.2", "dev": true, "inBundle": true, "license": "ISC", @@ -5792,44 +5778,45 @@ "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.1", "lru-cache": "^10.0.1", - "socks-proxy-agent": "^8.0.1" + "socks-proxy-agent": "^8.0.3" }, "engines": { "node": "^16.14.0 || >=18.0.0" } }, "node_modules/npm/node_modules/@npmcli/arborist": { - "version": "7.4.0", + "version": "7.5.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", "@npmcli/fs": "^3.1.0", - "@npmcli/installed-package-contents": "^2.0.2", + "@npmcli/installed-package-contents": "^2.1.0", "@npmcli/map-workspaces": "^3.0.2", - "@npmcli/metavuln-calculator": "^7.0.0", + "@npmcli/metavuln-calculator": "^7.1.0", "@npmcli/name-from-folder": "^2.0.0", "@npmcli/node-gyp": "^3.0.0", - "@npmcli/package-json": "^5.0.0", + "@npmcli/package-json": "^5.1.0", "@npmcli/query": "^3.1.0", - "@npmcli/run-script": "^7.0.2", + "@npmcli/redact": "^2.0.0", + "@npmcli/run-script": "^8.1.0", "bin-links": "^4.0.1", "cacache": "^18.0.0", "common-ancestor-path": "^1.0.1", "hosted-git-info": "^7.0.1", "json-parse-even-better-errors": "^3.0.0", "json-stringify-nice": "^1.1.4", - "minimatch": "^9.0.0", + "minimatch": "^9.0.4", "nopt": "^7.0.0", "npm-install-checks": "^6.2.0", - "npm-package-arg": "^11.0.1", + "npm-package-arg": "^11.0.2", "npm-pick-manifest": "^9.0.0", - "npm-registry-fetch": "^16.0.0", - "npmlog": "^7.0.1", - "pacote": "^17.0.4", + "npm-registry-fetch": "^17.0.0", + "pacote": "^18.0.1", "parse-conflict-json": "^3.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.2.0", + "proggy": "^2.0.0", "promise-all-reject-late": "^1.0.0", "promise-call-limit": "^3.0.1", "read-package-json-fast": "^3.0.2", @@ -5846,16 +5833,16 @@ } }, "node_modules/npm/node_modules/@npmcli/config": { - "version": "8.2.0", + "version": "8.3.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "@npmcli/map-workspaces": "^3.0.2", "ci-info": "^4.0.0", - "ini": "^4.1.0", + "ini": "^4.1.2", "nopt": "^7.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.2.0", "read-package-json-fast": "^3.0.2", "semver": "^7.3.5", "walk-up-path": "^3.0.1" @@ -5867,7 +5854,6 @@ "node_modules/npm/node_modules/@npmcli/disparity-colors": { "version": "3.0.0", "dev": true, - "inBundle": true, "license": "ISC", "dependencies": { "ansi-styles": "^4.3.0" @@ -5879,7 +5865,6 @@ "node_modules/npm/node_modules/@npmcli/disparity-colors/node_modules/ansi-styles": { "version": "4.3.0", "dev": true, - "inBundle": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -5904,7 +5889,7 @@ } }, "node_modules/npm/node_modules/@npmcli/git": { - "version": "5.0.4", + "version": "5.0.6", "dev": true, "inBundle": true, "license": "ISC", @@ -5912,7 +5897,7 @@ "@npmcli/promise-spawn": "^7.0.0", "lru-cache": "^10.0.1", "npm-pick-manifest": "^9.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.0.0", "promise-inflight": "^1.0.1", "promise-retry": "^2.0.1", "semver": "^7.3.5", @@ -5923,7 +5908,7 @@ } }, "node_modules/npm/node_modules/@npmcli/installed-package-contents": { - "version": "2.0.2", + "version": "2.1.0", "dev": true, "inBundle": true, "license": "ISC", @@ -5932,14 +5917,14 @@ "npm-normalize-package-bin": "^3.0.0" }, "bin": { - "installed-package-contents": "lib/index.js" + "installed-package-contents": "bin/index.js" }, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/npm/node_modules/@npmcli/map-workspaces": { - "version": "3.0.4", + "version": "3.0.6", "dev": true, "inBundle": true, "license": "ISC", @@ -5954,14 +5939,15 @@ } }, "node_modules/npm/node_modules/@npmcli/metavuln-calculator": { - "version": "7.0.0", + "version": "7.1.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "cacache": "^18.0.0", "json-parse-even-better-errors": "^3.0.0", - "pacote": "^17.0.0", + "pacote": "^18.0.0", + "proc-log": "^4.1.0", "semver": "^7.3.5" }, "engines": { @@ -5987,7 +5973,7 @@ } }, "node_modules/npm/node_modules/@npmcli/package-json": { - "version": "5.0.0", + "version": "5.1.0", "dev": true, "inBundle": true, "license": "ISC", @@ -5997,7 +5983,7 @@ "hosted-git-info": "^7.0.0", "json-parse-even-better-errors": "^3.0.0", "normalize-package-data": "^6.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.0.0", "semver": "^7.5.3" }, "engines": { @@ -6028,8 +6014,17 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/npm/node_modules/@npmcli/redact": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, "node_modules/npm/node_modules/@npmcli/run-script": { - "version": "7.0.4", + "version": "8.1.0", "dev": true, "inBundle": true, "license": "ISC", @@ -6038,6 +6033,7 @@ "@npmcli/package-json": "^5.0.0", "@npmcli/promise-spawn": "^7.0.0", "node-gyp": "^10.0.0", + "proc-log": "^4.0.0", "which": "^4.0.0" }, "engines": { @@ -6055,19 +6051,19 @@ } }, "node_modules/npm/node_modules/@sigstore/bundle": { - "version": "2.2.0", + "version": "2.3.1", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@sigstore/protobuf-specs": "^0.3.0" + "@sigstore/protobuf-specs": "^0.3.1" }, "engines": { "node": "^16.14.0 || >=18.0.0" } }, "node_modules/npm/node_modules/@sigstore/core": { - "version": "1.0.0", + "version": "1.1.0", "dev": true, "inBundle": true, "license": "Apache-2.0", @@ -6076,23 +6072,23 @@ } }, "node_modules/npm/node_modules/@sigstore/protobuf-specs": { - "version": "0.3.0", + "version": "0.3.1", "dev": true, "inBundle": true, "license": "Apache-2.0", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^16.14.0 || >=18.0.0" } }, "node_modules/npm/node_modules/@sigstore/sign": { - "version": "2.2.3", + "version": "2.3.0", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@sigstore/bundle": "^2.2.0", + "@sigstore/bundle": "^2.3.0", "@sigstore/core": "^1.0.0", - "@sigstore/protobuf-specs": "^0.3.0", + "@sigstore/protobuf-specs": "^0.3.1", "make-fetch-happen": "^13.0.0" }, "engines": { @@ -6100,7 +6096,7 @@ } }, "node_modules/npm/node_modules/@sigstore/tuf": { - "version": "2.3.1", + "version": "2.3.2", "dev": true, "inBundle": true, "license": "Apache-2.0", @@ -6113,14 +6109,14 @@ } }, "node_modules/npm/node_modules/@sigstore/verify": { - "version": "1.1.0", + "version": "1.2.0", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@sigstore/bundle": "^2.2.0", - "@sigstore/core": "^1.0.0", - "@sigstore/protobuf-specs": "^0.3.0" + "@sigstore/bundle": "^2.3.1", + "@sigstore/core": "^1.1.0", + "@sigstore/protobuf-specs": "^0.3.1" }, "engines": { "node": "^16.14.0 || >=18.0.0" @@ -6158,7 +6154,7 @@ } }, "node_modules/npm/node_modules/agent-base": { - "version": "7.1.0", + "version": "7.1.1", "dev": true, "inBundle": true, "license": "MIT", @@ -6218,7 +6214,6 @@ "node_modules/npm/node_modules/are-we-there-yet": { "version": "4.0.2", "dev": true, - "inBundle": true, "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" @@ -6246,12 +6241,15 @@ } }, "node_modules/npm/node_modules/binary-extensions": { - "version": "2.2.0", + "version": "2.3.0", "dev": true, "inBundle": true, "license": "MIT", "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/npm/node_modules/brace-expansion": { @@ -6264,7 +6262,7 @@ } }, "node_modules/npm/node_modules/builtins": { - "version": "5.0.1", + "version": "5.1.0", "dev": true, "inBundle": true, "license": "MIT", @@ -6332,7 +6330,7 @@ } }, "node_modules/npm/node_modules/cidr-regex": { - "version": "4.0.3", + "version": "4.0.5", "dev": true, "inBundle": true, "license": "BSD-2-Clause", @@ -6365,30 +6363,6 @@ "node": ">= 10" } }, - "node_modules/npm/node_modules/cli-table3": { - "version": "0.6.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "string-width": "^4.2.0" - }, - "engines": { - "node": "10.* || >= 12.*" - }, - "optionalDependencies": { - "@colors/colors": "1.5.0" - } - }, - "node_modules/npm/node_modules/clone": { - "version": "1.0.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, "node_modules/npm/node_modules/cmd-shim": { "version": "6.0.2", "dev": true, @@ -6419,25 +6393,11 @@ "node_modules/npm/node_modules/color-support": { "version": "1.1.3", "dev": true, - "inBundle": true, "license": "ISC", "bin": { "color-support": "bin.js" } }, - "node_modules/npm/node_modules/columnify": { - "version": "1.6.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "strip-ansi": "^6.0.1", - "wcwidth": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/npm/node_modules/common-ancestor-path": { "version": "1.0.1", "dev": true, @@ -6447,7 +6407,6 @@ "node_modules/npm/node_modules/console-control-strings": { "version": "1.1.0", "dev": true, - "inBundle": true, "license": "ISC" }, "node_modules/npm/node_modules/cross-spawn": { @@ -6514,18 +6473,6 @@ "inBundle": true, "license": "MIT" }, - "node_modules/npm/node_modules/defaults": { - "version": "1.0.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "clone": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/npm/node_modules/diff": { "version": "5.2.0", "dev": true, @@ -6627,7 +6574,6 @@ "node_modules/npm/node_modules/gauge": { "version": "5.0.1", "dev": true, - "inBundle": true, "license": "ISC", "dependencies": { "aproba": "^1.0.3 || ^2.0.0", @@ -6644,16 +6590,16 @@ } }, "node_modules/npm/node_modules/glob": { - "version": "10.3.10", + "version": "10.3.12", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", + "jackspeak": "^2.3.6", "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" + "minipass": "^7.0.4", + "path-scurry": "^1.10.2" }, "bin": { "glob": "dist/esm/bin.mjs" @@ -6674,11 +6620,10 @@ "node_modules/npm/node_modules/has-unicode": { "version": "2.0.1", "dev": true, - "inBundle": true, "license": "ISC" }, "node_modules/npm/node_modules/hasown": { - "version": "2.0.1", + "version": "2.0.2", "dev": true, "inBundle": true, "license": "MIT", @@ -6777,7 +6722,7 @@ } }, "node_modules/npm/node_modules/ini": { - "version": "4.1.1", + "version": "4.1.2", "dev": true, "inBundle": true, "license": "ISC", @@ -6786,15 +6731,15 @@ } }, "node_modules/npm/node_modules/init-package-json": { - "version": "6.0.0", + "version": "6.0.2", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { + "@npmcli/package-json": "^5.0.0", "npm-package-arg": "^11.0.0", "promzard": "^1.0.0", - "read": "^2.0.0", - "read-package-json": "^7.0.0", + "read": "^3.0.1", "semver": "^7.3.5", "validate-npm-package-license": "^3.0.4", "validate-npm-package-name": "^5.0.0" @@ -6816,12 +6761,6 @@ "node": ">= 12" } }, - "node_modules/npm/node_modules/ip-address/node_modules/sprintf-js": { - "version": "1.1.3", - "dev": true, - "inBundle": true, - "license": "BSD-3-Clause" - }, "node_modules/npm/node_modules/ip-regex": { "version": "5.0.0", "dev": true, @@ -6835,12 +6774,12 @@ } }, "node_modules/npm/node_modules/is-cidr": { - "version": "5.0.3", + "version": "5.0.5", "dev": true, "inBundle": true, "license": "BSD-2-Clause", "dependencies": { - "cidr-regex": "4.0.3" + "cidr-regex": "^4.0.4" }, "engines": { "node": ">=14" @@ -6943,52 +6882,50 @@ "license": "MIT" }, "node_modules/npm/node_modules/libnpmaccess": { - "version": "8.0.2", + "version": "8.0.5", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-package-arg": "^11.0.1", - "npm-registry-fetch": "^16.0.0" + "npm-package-arg": "^11.0.2", + "npm-registry-fetch": "^17.0.0" }, "engines": { "node": "^16.14.0 || >=18.0.0" } }, "node_modules/npm/node_modules/libnpmdiff": { - "version": "6.0.7", + "version": "6.1.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "@npmcli/arborist": "^7.2.1", - "@npmcli/disparity-colors": "^3.0.0", - "@npmcli/installed-package-contents": "^2.0.2", - "binary-extensions": "^2.2.0", + "@npmcli/installed-package-contents": "^2.1.0", + "binary-extensions": "^2.3.0", "diff": "^5.1.0", - "minimatch": "^9.0.0", - "npm-package-arg": "^11.0.1", - "pacote": "^17.0.4", - "tar": "^6.2.0" + "minimatch": "^9.0.4", + "npm-package-arg": "^11.0.2", + "pacote": "^18.0.1", + "tar": "^6.2.1" }, "engines": { "node": "^16.14.0 || >=18.0.0" } }, "node_modules/npm/node_modules/libnpmexec": { - "version": "7.0.8", + "version": "8.1.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "@npmcli/arborist": "^7.2.1", - "@npmcli/run-script": "^7.0.2", + "@npmcli/run-script": "^8.1.0", "ci-info": "^4.0.0", - "npm-package-arg": "^11.0.1", - "npmlog": "^7.0.1", - "pacote": "^17.0.4", - "proc-log": "^3.0.0", - "read": "^2.0.0", + "npm-package-arg": "^11.0.2", + "pacote": "^18.0.1", + "proc-log": "^4.2.0", + "read": "^3.0.1", "read-package-json-fast": "^3.0.2", "semver": "^7.3.7", "walk-up-path": "^3.0.1" @@ -6998,7 +6935,7 @@ } }, "node_modules/npm/node_modules/libnpmfund": { - "version": "5.0.5", + "version": "5.0.9", "dev": true, "inBundle": true, "license": "ISC", @@ -7010,57 +6947,57 @@ } }, "node_modules/npm/node_modules/libnpmhook": { - "version": "10.0.1", + "version": "10.0.4", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "aproba": "^2.0.0", - "npm-registry-fetch": "^16.0.0" + "npm-registry-fetch": "^17.0.0" }, "engines": { "node": "^16.14.0 || >=18.0.0" } }, "node_modules/npm/node_modules/libnpmorg": { - "version": "6.0.2", + "version": "6.0.5", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "aproba": "^2.0.0", - "npm-registry-fetch": "^16.0.0" + "npm-registry-fetch": "^17.0.0" }, "engines": { "node": "^16.14.0 || >=18.0.0" } }, "node_modules/npm/node_modules/libnpmpack": { - "version": "6.0.7", + "version": "7.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "@npmcli/arborist": "^7.2.1", - "@npmcli/run-script": "^7.0.2", - "npm-package-arg": "^11.0.1", - "pacote": "^17.0.4" + "@npmcli/run-script": "^8.1.0", + "npm-package-arg": "^11.0.2", + "pacote": "^18.0.1" }, "engines": { "node": "^16.14.0 || >=18.0.0" } }, "node_modules/npm/node_modules/libnpmpublish": { - "version": "9.0.4", + "version": "9.0.7", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "ci-info": "^4.0.0", "normalize-package-data": "^6.0.0", - "npm-package-arg": "^11.0.1", - "npm-registry-fetch": "^16.0.0", - "proc-log": "^3.0.0", + "npm-package-arg": "^11.0.2", + "npm-registry-fetch": "^17.0.0", + "proc-log": "^4.2.0", "semver": "^7.3.7", "sigstore": "^2.2.0", "ssri": "^10.0.5" @@ -7070,40 +7007,40 @@ } }, "node_modules/npm/node_modules/libnpmsearch": { - "version": "7.0.1", + "version": "7.0.4", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-registry-fetch": "^16.0.0" + "npm-registry-fetch": "^17.0.0" }, "engines": { "node": "^16.14.0 || >=18.0.0" } }, "node_modules/npm/node_modules/libnpmteam": { - "version": "6.0.1", + "version": "6.0.4", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "aproba": "^2.0.0", - "npm-registry-fetch": "^16.0.0" + "npm-registry-fetch": "^17.0.0" }, "engines": { "node": "^16.14.0 || >=18.0.0" } }, "node_modules/npm/node_modules/libnpmversion": { - "version": "5.0.2", + "version": "6.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/git": "^5.0.3", - "@npmcli/run-script": "^7.0.2", + "@npmcli/git": "^5.0.6", + "@npmcli/run-script": "^8.1.0", "json-parse-even-better-errors": "^3.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.2.0", "semver": "^7.3.7" }, "engines": { @@ -7111,7 +7048,7 @@ } }, "node_modules/npm/node_modules/lru-cache": { - "version": "10.2.0", + "version": "10.2.2", "dev": true, "inBundle": true, "license": "ISC", @@ -7120,7 +7057,7 @@ } }, "node_modules/npm/node_modules/make-fetch-happen": { - "version": "13.0.0", + "version": "13.0.1", "dev": true, "inBundle": true, "license": "ISC", @@ -7134,6 +7071,7 @@ "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "negotiator": "^0.6.3", + "proc-log": "^4.2.0", "promise-retry": "^2.0.1", "ssri": "^10.0.0" }, @@ -7142,7 +7080,7 @@ } }, "node_modules/npm/node_modules/minimatch": { - "version": "9.0.3", + "version": "9.0.4", "dev": true, "inBundle": true, "license": "ISC", @@ -7350,7 +7288,7 @@ } }, "node_modules/npm/node_modules/node-gyp": { - "version": "10.0.1", + "version": "10.1.0", "dev": true, "inBundle": true, "license": "MIT", @@ -7373,6 +7311,15 @@ "node": "^16.14.0 || >=18.0.0" } }, + "node_modules/npm/node_modules/node-gyp/node_modules/proc-log": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/npm/node_modules/nopt": { "version": "7.2.0", "dev": true, @@ -7446,13 +7393,13 @@ } }, "node_modules/npm/node_modules/npm-package-arg": { - "version": "11.0.1", + "version": "11.0.2", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "hosted-git-info": "^7.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.0.0", "semver": "^7.3.5", "validate-npm-package-name": "^5.0.0" }, @@ -7488,31 +7435,32 @@ } }, "node_modules/npm/node_modules/npm-profile": { - "version": "9.0.0", + "version": "9.0.2", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-registry-fetch": "^16.0.0", - "proc-log": "^3.0.0" + "npm-registry-fetch": "^17.0.0", + "proc-log": "^4.0.0" }, "engines": { "node": "^16.14.0 || >=18.0.0" } }, "node_modules/npm/node_modules/npm-registry-fetch": { - "version": "16.1.0", + "version": "17.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { + "@npmcli/redact": "^2.0.0", "make-fetch-happen": "^13.0.0", "minipass": "^7.0.2", "minipass-fetch": "^3.0.0", "minipass-json-stream": "^1.0.1", "minizlib": "^2.1.2", "npm-package-arg": "^11.0.0", - "proc-log": "^3.0.0" + "proc-log": "^4.0.0" }, "engines": { "node": "^16.14.0 || >=18.0.0" @@ -7530,7 +7478,6 @@ "node_modules/npm/node_modules/npmlog": { "version": "7.0.1", "dev": true, - "inBundle": true, "license": "ISC", "dependencies": { "are-we-there-yet": "^4.0.0", @@ -7558,26 +7505,25 @@ } }, "node_modules/npm/node_modules/pacote": { - "version": "17.0.6", + "version": "18.0.3", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "@npmcli/git": "^5.0.0", "@npmcli/installed-package-contents": "^2.0.1", + "@npmcli/package-json": "^5.1.0", "@npmcli/promise-spawn": "^7.0.0", - "@npmcli/run-script": "^7.0.0", + "@npmcli/run-script": "^8.0.0", "cacache": "^18.0.0", "fs-minipass": "^3.0.0", "minipass": "^7.0.2", "npm-package-arg": "^11.0.0", "npm-packlist": "^8.0.0", "npm-pick-manifest": "^9.0.0", - "npm-registry-fetch": "^16.0.0", - "proc-log": "^3.0.0", + "npm-registry-fetch": "^17.0.0", + "proc-log": "^4.0.0", "promise-retry": "^2.0.1", - "read-package-json": "^7.0.0", - "read-package-json-fast": "^3.0.0", "sigstore": "^2.2.0", "ssri": "^10.0.0", "tar": "^6.1.11" @@ -7613,12 +7559,12 @@ } }, "node_modules/npm/node_modules/path-scurry": { - "version": "1.10.1", + "version": "1.10.2", "dev": true, "inBundle": true, "license": "BlueOak-1.0.0", "dependencies": { - "lru-cache": "^9.1.1 || ^10.0.0", + "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { @@ -7629,7 +7575,7 @@ } }, "node_modules/npm/node_modules/postcss-selector-parser": { - "version": "6.0.15", + "version": "6.0.16", "dev": true, "inBundle": true, "license": "MIT", @@ -7642,7 +7588,16 @@ } }, "node_modules/npm/node_modules/proc-log": { - "version": "3.0.0", + "version": "4.2.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/proggy": { + "version": "2.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -7688,12 +7643,12 @@ } }, "node_modules/npm/node_modules/promzard": { - "version": "1.0.0", + "version": "1.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "read": "^2.0.0" + "read": "^3.0.1" }, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" @@ -7708,12 +7663,12 @@ } }, "node_modules/npm/node_modules/read": { - "version": "2.1.0", + "version": "3.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "mute-stream": "~1.0.0" + "mute-stream": "^1.0.0" }, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" @@ -7731,7 +7686,6 @@ "node_modules/npm/node_modules/read-package-json": { "version": "7.0.0", "dev": true, - "inBundle": true, "license": "ISC", "dependencies": { "glob": "^10.2.2", @@ -7802,7 +7756,6 @@ "node_modules/npm/node_modules/set-blocking": { "version": "2.0.0", "dev": true, - "inBundle": true, "license": "ISC" }, "node_modules/npm/node_modules/shebang-command": { @@ -7839,17 +7792,17 @@ } }, "node_modules/npm/node_modules/sigstore": { - "version": "2.2.2", + "version": "2.3.0", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@sigstore/bundle": "^2.2.0", + "@sigstore/bundle": "^2.3.1", "@sigstore/core": "^1.0.0", - "@sigstore/protobuf-specs": "^0.3.0", - "@sigstore/sign": "^2.2.3", + "@sigstore/protobuf-specs": "^0.3.1", + "@sigstore/sign": "^2.3.0", "@sigstore/tuf": "^2.3.1", - "@sigstore/verify": "^1.1.0" + "@sigstore/verify": "^1.2.0" }, "engines": { "node": "^16.14.0 || >=18.0.0" @@ -7866,7 +7819,7 @@ } }, "node_modules/npm/node_modules/socks": { - "version": "2.8.0", + "version": "2.8.3", "dev": true, "inBundle": true, "license": "MIT", @@ -7875,17 +7828,17 @@ "smart-buffer": "^4.2.0" }, "engines": { - "node": ">= 16.0.0", + "node": ">= 10.0.0", "npm": ">= 3.0.0" } }, "node_modules/npm/node_modules/socks-proxy-agent": { - "version": "8.0.2", + "version": "8.0.3", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "agent-base": "^7.0.2", + "agent-base": "^7.1.1", "debug": "^4.3.4", "socks": "^2.7.1" }, @@ -7903,6 +7856,16 @@ "spdx-license-ids": "^3.0.0" } }, + "node_modules/npm/node_modules/spdx-correct/node_modules/spdx-expression-parse": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, "node_modules/npm/node_modules/spdx-exceptions": { "version": "2.5.0", "dev": true, @@ -7910,7 +7873,7 @@ "license": "CC-BY-3.0" }, "node_modules/npm/node_modules/spdx-expression-parse": { - "version": "3.0.1", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "MIT", @@ -7925,6 +7888,12 @@ "inBundle": true, "license": "CC0-1.0" }, + "node_modules/npm/node_modules/sprintf-js": { + "version": "1.1.3", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause" + }, "node_modules/npm/node_modules/ssri": { "version": "10.0.5", "dev": true, @@ -8004,7 +7973,7 @@ } }, "node_modules/npm/node_modules/tar": { - "version": "6.2.0", + "version": "6.2.1", "dev": true, "inBundle": true, "license": "ISC", @@ -8128,6 +8097,16 @@ "spdx-expression-parse": "^3.0.0" } }, + "node_modules/npm/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, "node_modules/npm/node_modules/validate-npm-package-name": { "version": "5.0.0", "dev": true, @@ -8146,15 +8125,6 @@ "inBundle": true, "license": "ISC" }, - "node_modules/npm/node_modules/wcwidth": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "defaults": "^1.0.3" - } - }, "node_modules/npm/node_modules/which": { "version": "4.0.0", "dev": true, @@ -8182,7 +8152,6 @@ "node_modules/npm/node_modules/wide-align": { "version": "1.1.5", "dev": true, - "inBundle": true, "license": "ISC", "dependencies": { "string-width": "^1.0.2 || 2 || 3 || 4" diff --git a/src/Parser.ts b/src/Parser.ts index 0a53c08b6a..e7d524ce03 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -1,10 +1,7 @@ import { _Renderer } from './Renderer.ts'; import { _TextRenderer } from './TextRenderer.ts'; import { _defaults } from './defaults.ts'; -import { - unescape -} from './helpers.ts'; -import type { Token, Tokens } from './Tokens.ts'; +import type { TokenWithoutGeneric, Token, Tokens } from './Tokens.ts'; import type { MarkedOptions } from './MarkedOptions.ts'; /** @@ -46,11 +43,11 @@ export class _Parser { let out = ''; for (let i = 0; i < tokens.length; i++) { - const token = tokens[i]; + const anyToken = tokens[i]; // Run any renderer extensions - if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) { - const genericToken = token as Tokens.Generic; + if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[anyToken.type]) { + const genericToken = anyToken as Tokens.Generic; const ret = this.options.extensions.renderers[genericToken.type].call({ parser: this }, genericToken); if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(genericToken.type)) { out += ret || ''; @@ -58,25 +55,22 @@ export class _Parser { } } + const token = anyToken as TokenWithoutGeneric; + switch (token.type) { case 'space': { continue; } case 'hr': { - out += this.renderer.hr(); + out += this.renderer.hr(token); continue; } case 'heading': { - const headingToken = token as Tokens.Heading; - out += this.renderer.heading( - this.parseInline(headingToken.tokens), - headingToken.depth, - unescape(this.parseInline(headingToken.tokens, this.textRenderer))); + out += this.renderer.heading(token); continue; } case 'code': { - const codeToken = token as Tokens.Code; - out += this.renderer.code(codeToken); + out += this.renderer.code(token); continue; } case 'table': { @@ -111,8 +105,7 @@ export class _Parser { continue; } case 'blockquote': { - const blockquoteToken = token as Tokens.Blockquote; - out += this.renderer.blockquote(blockquoteToken); + out += this.renderer.blockquote(token); continue; } case 'list': { @@ -155,23 +148,30 @@ export class _Parser { continue; } case 'html': { - const htmlToken = token as Tokens.HTML; - out += this.renderer.html(htmlToken.text, htmlToken.block); + out += this.renderer.html(token); continue; } case 'paragraph': { - const paragraphToken = token as Tokens.Paragraph; - out += this.renderer.paragraph(this.parseInline(paragraphToken.tokens)); + out += this.renderer.paragraph(token); continue; } case 'text': { - let textToken = token as Tokens.Text; - let body = textToken.tokens ? this.parseInline(textToken.tokens) : textToken.text; + let textToken = token; + let body = 'tokens' in textToken && textToken.tokens ? this.parseInline(textToken.tokens) : textToken.text; while (i + 1 < tokens.length && tokens[i + 1].type === 'text') { textToken = tokens[++i] as Tokens.Text; body += '\n' + (textToken.tokens ? this.parseInline(textToken.tokens) : textToken.text); } - out += top ? this.renderer.paragraph(body) : body; + if (top) { + out += this.renderer.paragraph({ + type: 'paragraph', + raw: body, + text: body, + tokens: [{ type: 'text', raw: body, text: body }] + }); + } else { + out += body; + } continue; } @@ -198,65 +198,58 @@ export class _Parser { let out = ''; for (let i = 0; i < tokens.length; i++) { - const token = tokens[i]; + const anyToken = tokens[i]; // Run any renderer extensions - if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) { - const ret = this.options.extensions.renderers[token.type].call({ parser: this }, token); - if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(token.type)) { + if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[anyToken.type]) { + const ret = this.options.extensions.renderers[anyToken.type].call({ parser: this }, anyToken); + if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(anyToken.type)) { out += ret || ''; continue; } } + const token = anyToken as TokenWithoutGeneric; + switch (token.type) { case 'escape': { - const escapeToken = token as Tokens.Escape; - out += renderer.text(escapeToken.text); + out += renderer.text(token); break; } case 'html': { - const tagToken = token as Tokens.Tag; - out += renderer.html(tagToken.text); + out += renderer.html(token); break; } case 'link': { - const linkToken = token as Tokens.Link; - out += renderer.link(linkToken.href, linkToken.title, this.parseInline(linkToken.tokens, renderer)); + out += renderer.link(token); break; } case 'image': { - const imageToken = token as Tokens.Image; - out += renderer.image(imageToken.href, imageToken.title, imageToken.text); + out += renderer.image(token); break; } case 'strong': { - const strongToken = token as Tokens.Strong; - out += renderer.strong(this.parseInline(strongToken.tokens, renderer)); + out += renderer.strong(token); break; } case 'em': { - const emToken = token as Tokens.Em; - out += renderer.em(this.parseInline(emToken.tokens, renderer)); + out += renderer.em(token); break; } case 'codespan': { - const codespanToken = token as Tokens.Codespan; - out += renderer.codespan(codespanToken.text); + out += renderer.codespan(token); break; } case 'br': { - out += renderer.br(); + out += renderer.br(token); break; } case 'del': { - const delToken = token as Tokens.Del; - out += renderer.del(this.parseInline(delToken.tokens, renderer)); + out += renderer.del(token); break; } case 'text': { - const textToken = token as Tokens.Text; - out += renderer.text(textToken.text); + out += renderer.text(token); break; } default: { diff --git a/src/Renderer.ts b/src/Renderer.ts index 59c5a8dd4e..17e49c4d0c 100644 --- a/src/Renderer.ts +++ b/src/Renderer.ts @@ -40,16 +40,15 @@ export class _Renderer { return `
\n${body}
\n`; } - html(html: string, block?: boolean) : string { - return html; + html({ text }: Tokens.HTML | Tokens.Tag) : string { + return text; } - heading(text: string, level: number, raw: string): string { - // ignore IDs - return `${text}\n`; + heading({ tokens, depth }: Tokens.Heading): string { + return `${this.parser.parseInline(tokens)}\n`; } - hr(): string { + hr(token: Tokens.Hr): string { return '
\n'; } @@ -69,8 +68,8 @@ export class _Renderer { + 'disabled="" type="checkbox">'; } - paragraph(text: string): string { - return `

${text}

\n`; + paragraph({ tokens }: Tokens.Paragraph): string { + return `

${this.parser.parseInline(tokens)}

\n`; } table(header: string, body: string): string { @@ -102,27 +101,28 @@ export class _Renderer { /** * span level renderer */ - strong(text: string): string { - return `${text}`; + strong({ tokens }: Tokens.Strong): string { + return `${this.parser.parseInline(tokens)}`; } - em(text: string): string { - return `${text}`; + em({ tokens }: Tokens.Em): string { + return `${this.parser.parseInline(tokens)}`; } - codespan(text: string): string { + codespan({ text }: Tokens.Codespan): string { return `${text}`; } - br(): string { + br(token: Tokens.Br): string { return '
'; } - del(text: string): string { - return `${text}`; + del({ tokens }: Tokens.Del): string { + return `${this.parser.parseInline(tokens)}`; } - link(href: string, title: string | null | undefined, text: string): string { + link({ href, title, tokens }: Tokens.Link): string { + const text = this.parser.parseInline(tokens); const cleanHref = cleanUrl(href); if (cleanHref === null) { return text; @@ -136,7 +136,7 @@ export class _Renderer { return out; } - image(href: string, title: string | null, text: string): string { + image({ href, title, text }: Tokens.Image): string { const cleanHref = cleanUrl(href); if (cleanHref === null) { return text; @@ -151,7 +151,7 @@ export class _Renderer { return out; } - text(text: string) : string { + text({ text }: Tokens.Text | Tokens.Escape | Tokens.Tag) : string { return text; } } diff --git a/src/TextRenderer.ts b/src/TextRenderer.ts index 038b6db031..a83b754811 100644 --- a/src/TextRenderer.ts +++ b/src/TextRenderer.ts @@ -1,38 +1,40 @@ +import type { Tokens } from './Tokens.ts'; + /** * TextRenderer * returns only the textual part of the token */ export class _TextRenderer { // no need for block level renderers - strong(text: string) { + strong({ text }: Tokens.Strong) { return text; } - em(text: string) { + em({ text }: Tokens.Em) { return text; } - codespan(text: string) { + codespan({ text }: Tokens.Codespan) { return text; } - del(text: string) { + del({ text }: Tokens.Del) { return text; } - html(text: string) { + html({ text }: Tokens.HTML | Tokens.Tag) { return text; } - text(text: string) { + text({ text }: Tokens.Text | Tokens.Escape | Tokens.Tag) { return text; } - link(href: string, title: string | null | undefined, text: string) { + link({ text }: Tokens.Link) { return '' + text; } - image(href: string, title: string | null, text: string) { + image({ text }: Tokens.Image) { return '' + text; } diff --git a/src/Tokens.ts b/src/Tokens.ts index c5c846a557..fecafc8a2a 100644 --- a/src/Tokens.ts +++ b/src/Tokens.ts @@ -1,5 +1,6 @@ /* eslint-disable no-use-before-define */ -export type Token = ( + +export type TokenWithoutGeneric = ( Tokens.Space | Tokens.Code | Tokens.Heading @@ -20,7 +21,10 @@ export type Token = ( | Tokens.Em | Tokens.Codespan | Tokens.Br - | Tokens.Del + | Tokens.Del); + +export type Token = ( + TokenWithoutGeneric | Tokens.Generic); export namespace Tokens { diff --git a/test/unit/marked.test.js b/test/unit/marked.test.js index c9c0925a12..7cfe2d6928 100644 --- a/test/unit/marked.test.js +++ b/test/unit/marked.test.js @@ -38,7 +38,7 @@ describe('marked unit', () => { const md = 'HTML Image: MY IMAGE'; marked.parse(md, { renderer }); - assert.strictEqual(renderer.html.mock.calls[0].arguments[0], 'MY IMAGE'); + assert.strictEqual(renderer.html.mock.calls[0].arguments[0].raw, 'MY IMAGE'); }); }); @@ -490,7 +490,7 @@ describe('marked unit', () => { } }, renderer: { - heading(text, depth, raw) { + heading({ text, depth }) { if (text === name) { return `${text}\n`; } @@ -692,7 +692,7 @@ used extension2 walked

it('should use renderer', () => { const extension = { renderer: { - paragraph(text) { + paragraph() { return 'extension'; } } @@ -700,7 +700,7 @@ used extension2 walked

mock.method(extension.renderer, 'paragraph'); marked.use(extension); const html = marked.parse('text'); - assert.strictEqual(extension.renderer.paragraph.mock.calls[0].arguments[0], 'text'); + assert.strictEqual(extension.renderer.paragraph.mock.calls[0].arguments[0].raw, 'text'); assert.strictEqual(html, 'extension'); }); @@ -773,17 +773,17 @@ used extension2 walked

it('should use last extension function and not override others', () => { const extension1 = { renderer: { - paragraph(text) { + paragraph() { return 'extension1 paragraph\n'; }, - html(html) { + html() { return 'extension1 html\n'; } } }; const extension2 = { renderer: { - paragraph(text) { + paragraph() { return 'extension2 paragraph\n'; } } @@ -803,7 +803,7 @@ paragraph it('should use previous extension when returning false', () => { const extension1 = { renderer: { - paragraph(text) { + paragraph({ text }) { if (text !== 'original') { return 'extension1 paragraph\n'; } @@ -813,7 +813,7 @@ paragraph }; const extension2 = { renderer: { - paragraph(text) { + paragraph({ text }) { if (text !== 'extension1' && text !== 'original') { return 'extension2 paragraph\n'; } From bad0d6be361f047ddb3372b10f8656db8d52ecc1 Mon Sep 17 00:00:00 2001 From: Tony Brix Date: Wed, 15 May 2024 01:10:51 -0600 Subject: [PATCH 03/14] add list --- src/Parser.ts | 37 +------------------------------- src/Renderer.ts | 46 ++++++++++++++++++++++++++++++++++------ src/Tokens.ts | 4 ++++ test/unit/Parser.test.js | 2 ++ 4 files changed, 46 insertions(+), 43 deletions(-) diff --git a/src/Parser.ts b/src/Parser.ts index e7d524ce03..431f6ec15e 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -109,42 +109,7 @@ export class _Parser { continue; } case 'list': { - const listToken = token as Tokens.List; - const ordered = listToken.ordered; - const start = listToken.start; - const loose = listToken.loose; - - let body = ''; - for (let j = 0; j < listToken.items.length; j++) { - const item = listToken.items[j]; - const checked = item.checked; - const task = item.task; - - let itemBody = ''; - if (item.task) { - const checkbox = this.renderer.checkbox(!!checked); - if (loose) { - if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') { - item.tokens[0].text = checkbox + ' ' + item.tokens[0].text; - if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') { - item.tokens[0].tokens[0].text = checkbox + ' ' + item.tokens[0].tokens[0].text; - } - } else { - item.tokens.unshift({ - type: 'text', - text: checkbox + ' ' - } as Tokens.Text); - } - } else { - itemBody += checkbox + ' '; - } - } - - itemBody += this.parse(item.tokens, loose); - body += this.renderer.listitem(itemBody, task, !!checked); - } - - out += this.renderer.list(body, ordered, start); + out += this.renderer.list(token); continue; } case 'html': { diff --git a/src/Renderer.ts b/src/Renderer.ts index 17e49c4d0c..b6f1900f21 100644 --- a/src/Renderer.ts +++ b/src/Renderer.ts @@ -52,17 +52,49 @@ export class _Renderer { return '
\n'; } - list(body: string, ordered: boolean, start: number | ''): string { + list(token: Tokens.List): string { + const ordered = token.ordered; + const start = token.start; + + let body = ''; + for (let j = 0; j < token.items.length; j++) { + const item = token.items[j]; + body += this.listitem(item); + } + const type = ordered ? 'ol' : 'ul'; - const startatt = (ordered && start !== 1) ? (' start="' + start + '"') : ''; - return '<' + type + startatt + '>\n' + body + '\n'; - } + const startAttr = (ordered && start !== 1) ? (' start="' + start + '"') : ''; + return '<' + type + startAttr + '>\n' + body + '\n'; + } + + listitem(item: Tokens.ListItem): string { + let itemBody = ''; + if (item.task) { + const checkbox = this.checkbox({ checked: !!item.checked }); + if (item.loose) { + if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') { + item.tokens[0].text = checkbox + ' ' + item.tokens[0].text; + if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') { + item.tokens[0].tokens[0].text = checkbox + ' ' + item.tokens[0].tokens[0].text; + } + } else { + item.tokens.unshift({ + type: 'text', + raw: checkbox + ' ', + text: checkbox + ' ' + }); + } + } else { + itemBody += checkbox + ' '; + } + } + + itemBody += this.parser.parse(item.tokens, !!item.loose); - listitem(text: string, task: boolean, checked: boolean): string { - return `
  • ${text}
  • \n`; + return `
  • ${itemBody}
  • \n`; } - checkbox(checked: boolean): string { + checkbox({ checked }: Tokens.Checkbox): string { return ''; diff --git a/src/Tokens.ts b/src/Tokens.ts index fecafc8a2a..f8ca7a6bfa 100644 --- a/src/Tokens.ts +++ b/src/Tokens.ts @@ -94,6 +94,10 @@ export namespace Tokens { tokens: Token[]; } + export interface Checkbox { + checked: boolean; + } + export interface Paragraph { type: 'paragraph'; raw: string; diff --git a/test/unit/Parser.test.js b/test/unit/Parser.test.js index 5e2a6f3f53..38bf92fbdb 100644 --- a/test/unit/Parser.test.js +++ b/test/unit/Parser.test.js @@ -273,6 +273,7 @@ describe('Parser', () => { { task: false, checked: undefined, + loose: true, tokens: [ { type: 'text', @@ -284,6 +285,7 @@ describe('Parser', () => { { task: false, checked: undefined, + loose: true, tokens: [ { type: 'text', From ff0cc66d801962ca88143b45cd9f557f277d1b95 Mon Sep 17 00:00:00 2001 From: Tony Brix Date: Wed, 15 May 2024 01:20:10 -0600 Subject: [PATCH 04/14] add table --- src/Parser.ts | 29 +---------------------------- src/Renderer.ts | 46 ++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 39 insertions(+), 36 deletions(-) diff --git a/src/Parser.ts b/src/Parser.ts index 431f6ec15e..a6ddc37015 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -74,34 +74,7 @@ export class _Parser { continue; } case 'table': { - const tableToken = token as Tokens.Table; - let header = ''; - - // header - let cell = ''; - for (let j = 0; j < tableToken.header.length; j++) { - cell += this.renderer.tablecell( - this.parseInline(tableToken.header[j].tokens), - { header: true, align: tableToken.align[j] } - ); - } - header += this.renderer.tablerow(cell); - - let body = ''; - for (let j = 0; j < tableToken.rows.length; j++) { - const row = tableToken.rows[j]; - - cell = ''; - for (let k = 0; k < row.length; k++) { - cell += this.renderer.tablecell( - this.parseInline(row[k].tokens), - { header: false, align: tableToken.align[k] } - ); - } - - body += this.renderer.tablerow(cell); - } - out += this.renderer.table(header, body); + out += this.renderer.table(token); continue; } case 'blockquote': { diff --git a/src/Renderer.ts b/src/Renderer.ts index b6f1900f21..274e0515af 100644 --- a/src/Renderer.ts +++ b/src/Renderer.ts @@ -4,7 +4,7 @@ import { escape } from './helpers.ts'; import type { MarkedOptions } from './MarkedOptions.ts'; -import type { Tokens } from './Tokens.ts'; +import type { Tokens, Token } from './Tokens.ts'; import type { _Parser } from './Parser.ts'; /** @@ -104,7 +104,35 @@ export class _Renderer { return `

    ${this.parser.parseInline(tokens)}

    \n`; } - table(header: string, body: string): string { + table(token: Tokens.Table): string { + let header = ''; + + // header + let cell = ''; + for (let j = 0; j < token.header.length; j++) { + cell += this.tablecell({ + tokens: token.header[j].tokens, + header: true, + align: token.align[j] + }); + } + header += this.tablerow({ text: cell }); + + let body = ''; + for (let j = 0; j < token.rows.length; j++) { + const row = token.rows[j]; + + cell = ''; + for (let k = 0; k < row.length; k++) { + cell += this.tablecell({ + tokens: row[k].tokens, + header: false, + align: token.align[k] + }); + } + + body += this.tablerow({ text: cell }); + } if (body) body = `${body}`; return '\n' @@ -115,17 +143,19 @@ export class _Renderer { + '
    \n'; } - tablerow(content: string): string { - return `\n${content}\n`; + tablerow({ text }: { text: string }): string { + return `\n${text}\n`; } - tablecell(content: string, flags: { + tablecell(token: { + tokens: Token[]; header: boolean; align: 'center' | 'left' | 'right' | null; }): string { - const type = flags.header ? 'th' : 'td'; - const tag = flags.align - ? `<${type} align="${flags.align}">` + const content = this.parser.parseInline(token.tokens); + const type = token.header ? 'th' : 'td'; + const tag = token.align + ? `<${type} align="${token.align}">` : `<${type}>`; return tag + content + `\n`; } From 45dd2c305d70d23be284b95cc4b86c795a0045a9 Mon Sep 17 00:00:00 2001 From: Tony Brix Date: Wed, 15 May 2024 01:22:26 -0600 Subject: [PATCH 05/14] add space renderer --- src/Parser.ts | 1 + src/Renderer.ts | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/Parser.ts b/src/Parser.ts index a6ddc37015..4ec937eee7 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -59,6 +59,7 @@ export class _Parser { switch (token.type) { case 'space': { + out += this.renderer.space(token); continue; } case 'hr': { diff --git a/src/Renderer.ts b/src/Renderer.ts index 274e0515af..c02a5b70fd 100644 --- a/src/Renderer.ts +++ b/src/Renderer.ts @@ -17,6 +17,10 @@ export class _Renderer { this.options = options || _defaults; } + space(token: Tokens.Space): string { + return ''; + } + code({ text, lang, escaped }: Tokens.Code): string { const langString = (lang || '').match(/^\S*/)?.[0]; From 87ae47e938c647c1cf26c0d78ffd6ed6c8e889ee Mon Sep 17 00:00:00 2001 From: Tony Brix Date: Wed, 15 May 2024 01:31:55 -0600 Subject: [PATCH 06/14] use text renderer --- src/Parser.ts | 6 +++--- src/Renderer.ts | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Parser.ts b/src/Parser.ts index 4ec937eee7..a93887c0c5 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -96,10 +96,10 @@ export class _Parser { } case 'text': { let textToken = token; - let body = 'tokens' in textToken && textToken.tokens ? this.parseInline(textToken.tokens) : textToken.text; + let body = this.renderer.text(textToken); while (i + 1 < tokens.length && tokens[i + 1].type === 'text') { - textToken = tokens[++i] as Tokens.Text; - body += '\n' + (textToken.tokens ? this.parseInline(textToken.tokens) : textToken.text); + textToken = tokens[++i] as Tokens.Text | Tokens.Tag; + body += '\n' + this.renderer.text(textToken); } if (top) { out += this.renderer.paragraph({ diff --git a/src/Renderer.ts b/src/Renderer.ts index c02a5b70fd..9dd3fe0d1e 100644 --- a/src/Renderer.ts +++ b/src/Renderer.ts @@ -217,7 +217,7 @@ export class _Renderer { return out; } - text({ text }: Tokens.Text | Tokens.Escape | Tokens.Tag) : string { - return text; + text(token: Tokens.Text | Tokens.Escape | Tokens.Tag) : string { + return 'tokens' in token && token.tokens ? this.parser.parseInline(token.tokens) : token.text; } } From 40e0f61453648ee6e9afaf0317b2e82da2bd655f Mon Sep 17 00:00:00 2001 From: Tony Brix Date: Wed, 15 May 2024 22:39:48 -0600 Subject: [PATCH 07/14] fix types --- src/Renderer.ts | 22 +++--------- src/Tokenizer.ts | 14 +++++--- src/Tokens.ts | 6 ++++ test/types/marked.ts | 51 ++++++++++++++-------------- test/unit/Lexer.test.js | 72 ++++++++++++++++++++++++++++++---------- test/unit/Parser.test.js | 16 ++++++--- 6 files changed, 112 insertions(+), 69 deletions(-) diff --git a/src/Renderer.ts b/src/Renderer.ts index 9dd3fe0d1e..b790803a90 100644 --- a/src/Renderer.ts +++ b/src/Renderer.ts @@ -4,7 +4,7 @@ import { escape } from './helpers.ts'; import type { MarkedOptions } from './MarkedOptions.ts'; -import type { Tokens, Token } from './Tokens.ts'; +import type { Tokens } from './Tokens.ts'; import type { _Parser } from './Parser.ts'; /** @@ -114,11 +114,7 @@ export class _Renderer { // header let cell = ''; for (let j = 0; j < token.header.length; j++) { - cell += this.tablecell({ - tokens: token.header[j].tokens, - header: true, - align: token.align[j] - }); + cell += this.tablecell(token.header[j]); } header += this.tablerow({ text: cell }); @@ -128,11 +124,7 @@ export class _Renderer { cell = ''; for (let k = 0; k < row.length; k++) { - cell += this.tablecell({ - tokens: row[k].tokens, - header: false, - align: token.align[k] - }); + cell += this.tablecell(row[k]); } body += this.tablerow({ text: cell }); @@ -147,15 +139,11 @@ export class _Renderer { + '\n'; } - tablerow({ text }: { text: string }): string { + tablerow({ text }: Tokens.TableRow): string { return `\n${text}\n`; } - tablecell(token: { - tokens: Token[]; - header: boolean; - align: 'center' | 'left' | 'right' | null; - }): string { + tablecell(token: Tokens.TableCell): string { const content = this.parser.parseInline(token.tokens); const type = token.header ? 'th' : 'td'; const tag = token.align diff --git a/src/Tokenizer.ts b/src/Tokenizer.ts index 10b31454e2..f3ef1c5686 100644 --- a/src/Tokenizer.ts +++ b/src/Tokenizer.ts @@ -438,18 +438,22 @@ export class _Tokenizer { } } - for (const header of headers) { + for (let i = 0; i < headers.length; i++) { item.header.push({ - text: header, - tokens: this.lexer.inline(header) + text: headers[i], + tokens: this.lexer.inline(headers[i]), + header: true, + align: item.align[i] }); } for (const row of rows) { - item.rows.push(splitCells(row, item.header.length).map(cell => { + item.rows.push(splitCells(row, item.header.length).map((cell, i) => { return { text: cell, - tokens: this.lexer.inline(cell) + tokens: this.lexer.inline(cell), + header: false, + align: item.align[i] }; })); } diff --git a/src/Tokens.ts b/src/Tokens.ts index f8ca7a6bfa..e2fb1618cf 100644 --- a/src/Tokens.ts +++ b/src/Tokens.ts @@ -58,9 +58,15 @@ export namespace Tokens { rows: TableCell[][]; } + export interface TableRow { + text: string; + } + export interface TableCell { text: string; tokens: Token[]; + header: boolean; + align: 'center' | 'left' | 'right' | null; } export interface Hr { diff --git a/test/types/marked.ts b/test/types/marked.ts index 8bf2997b2e..b8d373bbb3 100644 --- a/test/types/marked.ts +++ b/test/types/marked.ts @@ -64,6 +64,7 @@ console.log(marked.parseInline('9) I am using __markdown__.')); console.log(marked.parseInline('10) I am using __markdown__.', options)); const text = 'Something'; +const raw = 'Raw'; const tokens: TokensList = marked.lexer(text, options); console.log(marked.parser(tokens)); @@ -79,8 +80,8 @@ const re: Record>> = marked.Lexer. const lexerOptions: MarkedOptions = lexer.options; const renderer = new marked.Renderer(); -renderer.heading = (text, level, raw) => { - return text + level.toString(); +renderer.heading = ({ text, depth }) => { + return text + depth.toString(); }; renderer.hr = () => { return `
    \n`; @@ -90,31 +91,31 @@ renderer.checkbox = checked => { }; class ExtendedRenderer extends marked.Renderer { - code = (code: string, language: string | undefined, isEscaped: boolean): string => super.code(code, language, isEscaped); - blockquote = (quote: string): string => super.blockquote(quote); - html = (html: string): string => super.html(html); - heading = (text: string, level: 1 | 2 | 3 | 4 | 5 | 6, raw: string): string => super.heading(text, level, raw); - hr = (): string => super.hr(); - list = (body: string, ordered: boolean, start: number): string => super.list(body, ordered, start); - listitem = (text: string, task: boolean, checked: boolean): string => super.listitem(text, task, checked); - checkbox = (checked: boolean): string => super.checkbox(checked); - paragraph = (text: string): string => super.paragraph(text); - table = (header: string, body: string): string => super.table(header, body); - tablerow = (content: string): string => super.tablerow(content); - tablecell = (content: string, flags: { header: boolean; align: 'center' | 'left' | 'right' | null }): string => super.tablecell(content, flags); - strong = (text: string): string => super.strong(text); - em = (text: string): string => super.em(text); - codespan = (code: string): string => super.codespan(code); - br = (): string => super.br(); - del = (text: string): string => super.del(text); - link = (href: string, title: string, text: string): string => super.link(href, title, text); - image = (href: string, title: string, text: string): string => super.image(href, title, text); + code = ({ type, raw, text, codeBlockStyle, lang, escaped }: Tokens.Code): string => super.code({ type, raw, text, codeBlockStyle, lang, escaped }); + blockquote = ({ type, raw, text, tokens }: Tokens.Blockquote): string => super.blockquote({ type, raw, text, tokens }); + html = ({ type, raw, text, pre, block }: Tokens.HTML): string => super.html({ type, raw, text, pre, block }); + heading = ({ type, raw, text, depth, tokens }: Tokens.Heading): string => super.heading({ type, raw, text, depth, tokens }); + hr = ({ type, raw }: Tokens.Hr): string => super.hr({ type, raw }); + list = ({ type, raw, ordered, start, loose, items }: Tokens.List): string => super.list({ type, raw, ordered, start, loose, items}); + listitem = ({ type, raw, task, checked, loose, text, tokens }: Tokens.ListItem): string => super.listitem({ type, raw, task, checked, loose, text, tokens }); + checkbox = ({ checked }: Tokens.Checkbox): string => super.checkbox({ checked }); + paragraph = ({ type, raw, pre, text, tokens }: Tokens.Paragraph): string => super.paragraph({ type, raw, pre, text, tokens }); + table = ({ type, raw, align, header, rows }: Tokens.Table): string => super.table({ type, raw, align, header, rows }); + tablerow = ({ text }: Tokens.TableRow): string => super.tablerow({ text }); + tablecell = ({ text, tokens, header, align }: Tokens.TableCell): string => super.tablecell({ text, tokens, header, align }); + strong = ({ type, raw, text, tokens }: Tokens.Strong): string => super.strong({ type, raw, text, tokens }); + em = ({ type, raw, text, tokens }: Tokens.Em): string => super.em({ type, raw, text, tokens }); + codespan = ({ type, raw, text }: Tokens.Codespan): string => super.codespan({ type, raw, text }); + br = ({ type, raw }: Tokens.Br): string => super.br({ type, raw }); + del = ({ type, raw, text, tokens }: Tokens.Del): string => super.del({ type, raw, text, tokens }); + link = ({ type, raw, href, title, text, tokens }: Tokens.Link): string => super.link({ type, raw, href, title, text, tokens }); + image = ({ type, raw, href, title, text }: Tokens.Image): string => super.image({ type, raw, href, title, text }); } const rendererOptions: MarkedOptions = renderer.options; const textRenderer = new marked.TextRenderer(); -console.log(textRenderer.strong(text)); +console.log(textRenderer.strong({ type : 'strong', raw, text, tokens })); const parseTestText = '- list1\n - list1.1\n\n listend'; const parseTestTokens: TokensList = marked.lexer(parseTestText, options); @@ -135,14 +136,14 @@ marked.use({ renderer }, { tokenizer }); marked.use({ renderer: { - heading(text, level) { - if (level > 3) { + heading({ text, depth }) { + if (depth > 3) { return `

    ${text}

    `; } return false; }, - listitem(text, task, checked) { + listitem({ text, task, checked }) { if (task) return `
  • ${text}
  • \n`; else return `
  • ${text}
  • \n`; } diff --git a/test/unit/Lexer.test.js b/test/unit/Lexer.test.js index 8a331fbbe7..fbf932090a 100644 --- a/test/unit/Lexer.test.js +++ b/test/unit/Lexer.test.js @@ -196,22 +196,30 @@ lheading 2 header: [ { text: 'a', - tokens: [{ type: 'text', raw: 'a', text: 'a' }] + tokens: [{ type: 'text', raw: 'a', text: 'a' }], + header: true, + align: null }, { text: 'b', - tokens: [{ type: 'text', raw: 'b', text: 'b' }] + tokens: [{ type: 'text', raw: 'b', text: 'b' }], + header: true, + align: null } ], rows: [ [ { text: '1', - tokens: [{ type: 'text', raw: '1', text: '1' }] + tokens: [{ type: 'text', raw: '1', text: '1' }], + header: false, + align: null }, { text: '2', - tokens: [{ type: 'text', raw: '2', text: '2' }] + tokens: [{ type: 'text', raw: '2', text: '2' }], + header: false, + align: null } ] ] @@ -243,22 +251,30 @@ paragraph 1 header: [ { text: 'a', - tokens: [{ type: 'text', raw: 'a', text: 'a' }] + tokens: [{ type: 'text', raw: 'a', text: 'a' }], + header: true, + align: null }, { text: 'b', - tokens: [{ type: 'text', raw: 'b', text: 'b' }] + tokens: [{ type: 'text', raw: 'b', text: 'b' }], + header: true, + align: null } ], rows: [ [ { text: '1', - tokens: [{ type: 'text', raw: '1', text: '1' }] + tokens: [{ type: 'text', raw: '1', text: '1' }], + header: false, + align: null }, { text: '2', - tokens: [{ type: 'text', raw: '2', text: '2' }] + tokens: [{ type: 'text', raw: '2', text: '2' }], + header: false, + align: null } ] ] @@ -284,30 +300,42 @@ paragraph 1 header: [ { text: 'a', - tokens: [{ type: 'text', raw: 'a', text: 'a' }] + tokens: [{ type: 'text', raw: 'a', text: 'a' }], + header: true, + align: 'left' }, { text: 'b', - tokens: [{ type: 'text', raw: 'b', text: 'b' }] + tokens: [{ type: 'text', raw: 'b', text: 'b' }], + header: true, + align: 'center' }, { text: 'c', - tokens: [{ type: 'text', raw: 'c', text: 'c' }] + tokens: [{ type: 'text', raw: 'c', text: 'c' }], + header: true, + align: 'right' } ], rows: [ [ { text: '1', - tokens: [{ type: 'text', raw: '1', text: '1' }] + tokens: [{ type: 'text', raw: '1', text: '1' }], + header: false, + align: 'left' }, { text: '2', - tokens: [{ type: 'text', raw: '2', text: '2' }] + tokens: [{ type: 'text', raw: '2', text: '2' }], + header: false, + align: 'center' }, { text: '3', - tokens: [{ type: 'text', raw: '3', text: '3' }] + tokens: [{ type: 'text', raw: '3', text: '3' }], + header: false, + align: 'right' } ] ] @@ -333,22 +361,30 @@ a | b header: [ { text: 'a', - tokens: [{ type: 'text', raw: 'a', text: 'a' }] + tokens: [{ type: 'text', raw: 'a', text: 'a' }], + header: true, + align: null }, { text: 'b', - tokens: [{ type: 'text', raw: 'b', text: 'b' }] + tokens: [{ type: 'text', raw: 'b', text: 'b' }], + header: true, + align: null } ], rows: [ [ { text: '1', - tokens: [{ type: 'text', raw: '1', text: '1' }] + tokens: [{ type: 'text', raw: '1', text: '1' }], + header: false, + align: null }, { text: '2', - tokens: [{ type: 'text', raw: '2', text: '2' }] + tokens: [{ type: 'text', raw: '2', text: '2' }], + header: false, + align: null } ] ] diff --git a/test/unit/Parser.test.js b/test/unit/Parser.test.js index 38bf92fbdb..c8b151c2ea 100644 --- a/test/unit/Parser.test.js +++ b/test/unit/Parser.test.js @@ -77,22 +77,30 @@ describe('Parser', () => { header: [ { text: 'a', - tokens: [{ type: 'text', raw: 'a', text: 'a' }] + tokens: [{ type: 'text', raw: 'a', text: 'a' }], + header: true, + align: 'left' }, { text: 'b', - tokens: [{ type: 'text', raw: 'b', text: 'b' }] + tokens: [{ type: 'text', raw: 'b', text: 'b' }], + header: true, + align: 'right' } ], rows: [ [ { text: '1', - tokens: [{ type: 'text', raw: '1', text: '1' }] + tokens: [{ type: 'text', raw: '1', text: '1' }], + header: false, + align: 'left' }, { text: '2', - tokens: [{ type: 'text', raw: '2', text: '2' }] + tokens: [{ type: 'text', raw: '2', text: '2' }], + header: false, + align: 'right' } ] ] From 260d41e8ec921881ed423b91abf624c1da9bb549 Mon Sep 17 00:00:00 2001 From: Tony Brix Date: Thu, 16 May 2024 00:07:49 -0600 Subject: [PATCH 08/14] update docs --- docs/USING_PRO.md | 109 ++++++++++++++++++++++------------------------ 1 file changed, 53 insertions(+), 56 deletions(-) diff --git a/docs/USING_PRO.md b/docs/USING_PRO.md index c4e1ddd8d2..a147ad1cc4 100644 --- a/docs/USING_PRO.md +++ b/docs/USING_PRO.md @@ -68,16 +68,16 @@ import { marked } from 'marked'; // Override function const renderer = { - heading(text, level) { + heading({ text, depth }) { const escapedText = text.toLowerCase().replace(/[^\w]+/g, '-'); return ` - + ${text} - `; + `; } }; @@ -97,7 +97,7 @@ console.log(marked.parse('# heading+')); heading+ ``` -**Note:** Calling `marked.use()` in the following way will avoid overriding the `heading` token output but create a new renderer in the process. +**Note:** Calling `marked.use()` in the following way will avoid overriding the `heading` token output but create a new `heading` renderer in the process. ```js marked.use({ @@ -112,38 +112,32 @@ marked.use({ ### Block-level renderer methods -- **code**(*string* code, *string* infostring, *boolean* escaped) -- **blockquote**(*string* quote) -- **html**(*string* html, *boolean* block) -- **heading**(*string* text, *number* level, *string* raw) -- **hr**() -- **list**(*string* body, *boolean* ordered, *number* start) -- **listitem**(*string* text, *boolean* task, *boolean* checked) -- **checkbox**(*boolean* checked) -- **paragraph**(*string* text) -- **table**(*string* header, *string* body) -- **tablerow**(*string* content) -- **tablecell**(*string* content, *object* flags) +- **space**(token: *Tokens.Space*): *string* +- **code**(token: *Tokens.Code*): *string* +- **blockquote**(token: *Tokens.Blockquote*): *string* +- **html**(token: *Tokens.HTML | Tokens.Tag*): *string* +- **heading**(token: *Tokens.Heading*): *string* +- **hr**(token: *Tokens.Hr*): *string* +- **list**(token: *Tokens.List*): *string* +- **listitem**(token: *Tokens.ListItem*): *string* +- **checkbox**(token: *Tokens.Checkbox*): *string* +- **paragraph**(token: *Tokens.Paragraph*): *string* +- **table**(token: *Tokens.Table*): *string* +- **tablerow**(token: *Tokens.TableRow*): *string* +- **tablecell**(token: *Tokens.TableCell*): *string* ### Inline-level renderer methods -- **strong**(*string* text) -- **em**(*string* text) -- **codespan**(*string* code) -- **br**() -- **del**(*string* text) -- **link**(*string* href, *string* title, *string* text) -- **image**(*string* href, *string* title, *string* text) -- **text**(*string* text) +- **strong**(token: *Tokens.Strong*): *string* +- **em**(token: *Tokens.Em*): *string* +- **codespan**(token: *Tokens.Codespan*): *string* +- **br**(token: *Tokens.Br*): *string* +- **del**(token: *Tokens.Del*): *string* +- **link**(token: *Tokens.Link*): *string* +- **image**(token: *Tokens.Image*): *string* +- **text**(token: *Tokens.Text | Tokens.Escape | Tokens.Tag*): *string* -`flags` has the following properties: - -```js -{ - header: true || false, - align: 'center' || 'left' || 'right' -} -``` +The Tokens.* properties can be found [here](https://github.com/markedjs/marked/blob/master/src/Tokens.ts). *** @@ -192,33 +186,35 @@ console.log(marked.parse('$ latex code $\n\n` other code `')); ### Block level tokenizer methods -- **space**(*string* src) -- **code**(*string* src) -- **fences**(*string* src) -- **heading**(*string* src) -- **hr**(*string* src) -- **blockquote**(*string* src) -- **list**(*string* src) -- **html**(*string* src) -- **def**(*string* src) -- **table**(*string* src) -- **lheading**(*string* src) -- **paragraph**(*string* src) -- **text**(*string* src) +- **space**(src: *string*): *Tokens.Space* +- **code**(src: *string*): *Tokens.Code* +- **fences**(src: *string*): *Tokens.Code* +- **heading**(src: *string*): *Tokens.Heading* +- **hr**(src: *string*): *Tokens.Hr* +- **blockquote**(src: *string*): *Tokens.Blockquote* +- **list**(src: *string*): *Tokens.List* +- **html**(src: *string*): *Tokens.HTML* +- **def**(src: *string*): *Tokens.Def* +- **table**(src: *string*): *Tokens.Table* +- **lheading**(src: *string*): *Tokens.Heading* +- **paragraph**(src: *string*): *Tokens.Paragraph* +- **text**(src: *string*): *Tokens.Text* ### Inline level tokenizer methods -- **escape**(*string* src) -- **tag**(*string* src) -- **link**(*string* src) -- **reflink**(*string* src, *object* links) -- **emStrong**(*string* src, *string* maskedSrc, *string* prevChar) -- **codespan**(*string* src) -- **br**(*string* src) -- **del**(*string* src) -- **autolink**(*string* src) -- **url**(*string* src) -- **inlineText**(*string* src) +- **escape**(src: *string*): *Tokens.Escape* +- **tag**(src: *string*): *Tokens.Tag* +- **link**(src: *string*): *Tokens.Link | Tokens.Image* +- **reflink**(src: *string*, links: *object*): *Tokens.Link | Tokens.Image | Tokens.Text* +- **emStrong**(src: *string*, maskedSrc: *string*, prevChar: *string*): *Tokens.Em | Tokens.Strong* +- **codespan**(src: *string*): *Tokens.Codespan* +- **br**(src: *string*): *Tokens.Br* +- **del**(src: *string*): *Tokens.Del* +- **autolink**(src: *string*): *Tokens.Link* +- **url**(src: *string*): *Tokens.Link* +- **inlineText**(src: *string*): *Tokens.Text* + +The Tokens.* properties can be found [here](https://github.com/markedjs/marked/blob/master/src/Tokens.ts). *** @@ -263,6 +259,7 @@ Hooks are methods that hook into some part of marked. The following hooks are av |-----------|-------------| | `preprocess(markdown: string): string` | Process markdown before sending it to marked. | | `postprocess(html: string): string` | Process html after marked has finished parsing. | +| `processAllTokens(tokens: Token[]): Token[]` | Process all tokens before walk tokens. | `marked.use()` can be called multiple times with different `hooks` functions. Each function will be called in order, starting with the function that was assigned *last*. From eae8807759888167463d899836a8a013a51324f7 Mon Sep 17 00:00:00 2001 From: Tony Brix Date: Thu, 16 May 2024 00:15:06 -0600 Subject: [PATCH 09/14] rename MarkedToken --- src/Parser.ts | 6 +++--- src/Tokens.ts | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Parser.ts b/src/Parser.ts index a93887c0c5..dfac9b6d54 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -1,7 +1,7 @@ import { _Renderer } from './Renderer.ts'; import { _TextRenderer } from './TextRenderer.ts'; import { _defaults } from './defaults.ts'; -import type { TokenWithoutGeneric, Token, Tokens } from './Tokens.ts'; +import type { MarkedToken, Token, Tokens } from './Tokens.ts'; import type { MarkedOptions } from './MarkedOptions.ts'; /** @@ -55,7 +55,7 @@ export class _Parser { } } - const token = anyToken as TokenWithoutGeneric; + const token = anyToken as MarkedToken; switch (token.type) { case 'space': { @@ -148,7 +148,7 @@ export class _Parser { } } - const token = anyToken as TokenWithoutGeneric; + const token = anyToken as MarkedToken; switch (token.type) { case 'escape': { diff --git a/src/Tokens.ts b/src/Tokens.ts index e2fb1618cf..1dd5a9ea3f 100644 --- a/src/Tokens.ts +++ b/src/Tokens.ts @@ -1,6 +1,6 @@ /* eslint-disable no-use-before-define */ -export type TokenWithoutGeneric = ( +export type MarkedToken = ( Tokens.Space | Tokens.Code | Tokens.Heading @@ -24,7 +24,7 @@ export type TokenWithoutGeneric = ( | Tokens.Del); export type Token = ( - TokenWithoutGeneric + MarkedToken | Tokens.Generic); export namespace Tokens { From fe1e46021e56754b6a352a8426ebb69fca64b0fc Mon Sep 17 00:00:00 2001 From: Tony Brix Date: Mon, 10 Jun 2024 00:04:04 -0600 Subject: [PATCH 10/14] renderer extensions can opt in to new renderer signature --- src/Instance.ts | 162 ++++++++++++++++++++++++++++++++++++++++++- src/MarkedOptions.ts | 8 ++- 2 files changed, 167 insertions(+), 3 deletions(-) diff --git a/src/Instance.ts b/src/Instance.ts index 5fcd9bd61f..019ae3bb63 100644 --- a/src/Instance.ts +++ b/src/Instance.ts @@ -6,7 +6,8 @@ import { _Renderer } from './Renderer.ts'; import { _Tokenizer } from './Tokenizer.ts'; import { _TextRenderer } from './TextRenderer.ts'; import { - escape + escape, + unescape } from './helpers.ts'; import type { MarkedExtension, MarkedOptions } from './MarkedOptions.ts'; import type { Token, Tokens, TokensList } from './Tokens.ts'; @@ -151,10 +152,14 @@ export class Marked { continue; } const rendererProp = prop as Exclude; - const rendererFunc = pack.renderer[rendererProp] as GenericRendererFunction; + let rendererFunc = pack.renderer[rendererProp] as GenericRendererFunction; const prevRenderer = renderer[rendererProp] as GenericRendererFunction; // Replace renderer with func to run extension, but fall back if false renderer[rendererProp] = (...args: unknown[]) => { + if (!pack.useNewRenderer) { + // Remove this in next major version + rendererFunc = this.#convertRendererFunction(rendererFunc, rendererProp, renderer) as GenericRendererFunction; + } let ret = rendererFunc.apply(renderer, args); if (ret === false) { ret = prevRenderer.apply(renderer, args); @@ -250,6 +255,159 @@ export class Marked { return this; } + #convertRendererFunction(func: GenericRendererFunction, prop: string, renderer: _Renderer) { + switch (prop) { + case 'heading': + return function(token: Tokens.Heading) { + return func( + renderer.parser.parseInline(token.tokens), + token.depth, + unescape(renderer.parser.parseInline(token.tokens, renderer.parser.textRenderer)) + ); + }; + case 'code': + return function(token: Tokens.Code) { + return func( + token.text, + token.lang, + !!token.escaped + ); + }; + case 'table': + return function(this: _Renderer, token: Tokens.Table) { + let header = ''; + // header + let cell = ''; + for (let j = 0; j < token.header.length; j++) { + cell += this.tablecell( + { + text: token.header[j].text, + tokens: token.header[j].tokens, + header: true, + align: token.align[j] + } + ); + } + header += this.tablerow({ text: cell }); + + let body = ''; + for (let j = 0; j < token.rows.length; j++) { + const row = token.rows[j]; + + cell = ''; + for (let k = 0; k < row.length; k++) { + cell += this.tablecell( + { + text: row[k].text, + tokens: row[k].tokens, + header: false, + align: token.align[k] + } + ); + } + + body += this.tablerow({ text: cell }); + } + + return func(header, body); + }; + case 'blockquote': + return function(this: _Renderer, token: Tokens.Blockquote) { + const body = this.parser.parse(token.tokens); + return func(body); + }; + case 'list': + return function(this: _Renderer, token: Tokens.List) { + const ordered = token.ordered; + const start = token.start; + const loose = token.loose; + + let body = ''; + for (let j = 0; j < token.items.length; j++) { + const item = token.items[j]; + const checked = item.checked; + const task = item.task; + + let itemBody = ''; + if (item.task) { + const checkbox = this.checkbox({ checked: !!checked }); + if (loose) { + if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') { + item.tokens[0].text = checkbox + ' ' + item.tokens[0].text; + if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') { + item.tokens[0].tokens[0].text = checkbox + ' ' + item.tokens[0].tokens[0].text; + } + } else { + item.tokens.unshift({ + type: 'text', + text: checkbox + ' ' + } as Tokens.Text); + } + } else { + itemBody += checkbox + ' '; + } + } + + itemBody += this.parser.parse(item.tokens, loose); + body += this.listitem({ + type: 'list_item', + raw: itemBody, + text: itemBody, + task, + checked: !!checked, + loose, + tokens: item.tokens + }); + } + + return func(body, ordered, start); + }; + case 'html': + return function(token: Tokens.HTML) { + return func(token.text, token.block); + }; + case 'paragraph': + return function(this: _Renderer, token: Tokens.Paragraph) { + return func(this.parser.parseInline(token.tokens)); + }; + case 'escape': + return function(token: Tokens.Escape) { + return func(token.text); + }; + case 'link': + return function(this: _Renderer, token: Tokens.Link) { + return func(token.href, token.title, this.parser.parseInline(token.tokens)); + }; + case 'image': + return function(token: Tokens.Image) { + return func(token.href, token.title, token.text); + }; + case 'strong': + return function(this: _Renderer, token: Tokens.Strong) { + return func(this.parser.parseInline(token.tokens)); + }; + case 'em': + return function(this: _Renderer, token: Tokens.Em) { + return func(this.parser.parseInline(token.tokens)); + }; + case 'codespan': + return function(token: Tokens.Codespan) { + return func(token.text); + }; + case 'del': + return function(this: _Renderer, token: Tokens.Del) { + return func(this.parser.parseInline(token.tokens)); + }; + case 'text': + return function(token: Tokens.Text) { + return func(token.text); + }; + default: + // do nothing + } + return func; + } + setOptions(opt: MarkedOptions) { this.defaults = { ...this.defaults, ...opt }; return this; diff --git a/src/MarkedOptions.ts b/src/MarkedOptions.ts index 6be9d2f5fc..8b0d0ea780 100644 --- a/src/MarkedOptions.ts +++ b/src/MarkedOptions.ts @@ -109,9 +109,15 @@ export interface MarkedExtension { * The return value of the function is ignored. */ walkTokens?: ((token: Token) => void | Promise) | undefined | null; + + /** + * Use the new renderer that accepts an object instead of individual parameters. + * This option will be removed and default to true in the next major version. + */ + useNewRenderer?: boolean | undefined; } -export interface MarkedOptions extends Omit { +export interface MarkedOptions extends Omit { /** * Hooks are methods that hook into some part of marked. */ From d2b960e8a8db0055cbcfc856ec5d3e83a348d36e Mon Sep 17 00:00:00 2001 From: Tony Brix Date: Mon, 10 Jun 2024 00:16:09 -0600 Subject: [PATCH 11/14] fix tests --- test/unit/marked.test.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/unit/marked.test.js b/test/unit/marked.test.js index 7cfe2d6928..52fe86c0f0 100644 --- a/test/unit/marked.test.js +++ b/test/unit/marked.test.js @@ -489,6 +489,7 @@ describe('marked unit', () => { return false; } }, + useNewRenderer: true, renderer: { heading({ text, depth }) { if (text === name) { @@ -691,6 +692,7 @@ used extension2 walked

    it('should use renderer', () => { const extension = { + useNewRenderer: true, renderer: { paragraph() { return 'extension'; @@ -772,6 +774,7 @@ used extension2 walked

    it('should use last extension function and not override others', () => { const extension1 = { + useNewRenderer: true, renderer: { paragraph() { return 'extension1 paragraph\n'; @@ -782,6 +785,7 @@ used extension2 walked

    } }; const extension2 = { + useNewRenderer: true, renderer: { paragraph() { return 'extension2 paragraph\n'; @@ -802,6 +806,7 @@ paragraph it('should use previous extension when returning false', () => { const extension1 = { + useNewRenderer: true, renderer: { paragraph({ text }) { if (text !== 'original') { @@ -812,6 +817,7 @@ paragraph } }; const extension2 = { + useNewRenderer: true, renderer: { paragraph({ text }) { if (text !== 'extension1' && text !== 'original') { @@ -835,6 +841,7 @@ original it('should get options with this.options', () => { const extension = { + useNewRenderer: true, renderer: { heading: () => { return this && this.options ? 'arrow options\n' : 'arrow no options\n'; From f0ec308df065b7fbbb89faf6c9157f2b16281234 Mon Sep 17 00:00:00 2001 From: Tony Brix Date: Mon, 10 Jun 2024 23:27:19 -0600 Subject: [PATCH 12/14] fix docs --- src/Instance.ts | 91 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/src/Instance.ts b/src/Instance.ts index 019ae3bb63..6f372e7615 100644 --- a/src/Instance.ts +++ b/src/Instance.ts @@ -255,10 +255,17 @@ export class Marked { return this; } + // Remove this in next major release #convertRendererFunction(func: GenericRendererFunction, prop: string, renderer: _Renderer) { switch (prop) { case 'heading': return function(token: Tokens.Heading) { + if (!token.type || token.type !== prop) { + // @ts-ignore + // eslint-disable-next-line prefer-rest-params + return func.apply(this, arguments); + } + return func( renderer.parser.parseInline(token.tokens), token.depth, @@ -267,6 +274,12 @@ export class Marked { }; case 'code': return function(token: Tokens.Code) { + if (!token.type || token.type !== prop) { + // @ts-ignore + // eslint-disable-next-line prefer-rest-params + return func.apply(this, arguments); + } + return func( token.text, token.lang, @@ -275,6 +288,12 @@ export class Marked { }; case 'table': return function(this: _Renderer, token: Tokens.Table) { + if (!token.type || token.type !== prop) { + // @ts-ignore + // eslint-disable-next-line prefer-rest-params + return func.apply(this, arguments); + } + let header = ''; // header let cell = ''; @@ -313,11 +332,23 @@ export class Marked { }; case 'blockquote': return function(this: _Renderer, token: Tokens.Blockquote) { + if (!token.type || token.type !== prop) { + // @ts-ignore + // eslint-disable-next-line prefer-rest-params + return func.apply(this, arguments); + } + const body = this.parser.parse(token.tokens); return func(body); }; case 'list': return function(this: _Renderer, token: Tokens.List) { + if (!token.type || token.type !== prop) { + // @ts-ignore + // eslint-disable-next-line prefer-rest-params + return func.apply(this, arguments); + } + const ordered = token.ordered; const start = token.start; const loose = token.loose; @@ -364,42 +395,102 @@ export class Marked { }; case 'html': return function(token: Tokens.HTML) { + if (!token.type || token.type !== prop) { + // @ts-ignore + // eslint-disable-next-line prefer-rest-params + return func.apply(this, arguments); + } + return func(token.text, token.block); }; case 'paragraph': return function(this: _Renderer, token: Tokens.Paragraph) { + if (!token.type || token.type !== prop) { + // @ts-ignore + // eslint-disable-next-line prefer-rest-params + return func.apply(this, arguments); + } + return func(this.parser.parseInline(token.tokens)); }; case 'escape': return function(token: Tokens.Escape) { + if (!token.type || token.type !== prop) { + // @ts-ignore + // eslint-disable-next-line prefer-rest-params + return func.apply(this, arguments); + } + return func(token.text); }; case 'link': return function(this: _Renderer, token: Tokens.Link) { + if (!token.type || token.type !== prop) { + // @ts-ignore + // eslint-disable-next-line prefer-rest-params + return func.apply(this, arguments); + } + return func(token.href, token.title, this.parser.parseInline(token.tokens)); }; case 'image': return function(token: Tokens.Image) { + if (!token.type || token.type !== prop) { + // @ts-ignore + // eslint-disable-next-line prefer-rest-params + return func.apply(this, arguments); + } + return func(token.href, token.title, token.text); }; case 'strong': return function(this: _Renderer, token: Tokens.Strong) { + if (!token.type || token.type !== prop) { + // @ts-ignore + // eslint-disable-next-line prefer-rest-params + return func.apply(this, arguments); + } + return func(this.parser.parseInline(token.tokens)); }; case 'em': return function(this: _Renderer, token: Tokens.Em) { + if (!token.type || token.type !== prop) { + // @ts-ignore + // eslint-disable-next-line prefer-rest-params + return func.apply(this, arguments); + } + return func(this.parser.parseInline(token.tokens)); }; case 'codespan': return function(token: Tokens.Codespan) { + if (!token.type || token.type !== prop) { + // @ts-ignore + // eslint-disable-next-line prefer-rest-params + return func.apply(this, arguments); + } + return func(token.text); }; case 'del': return function(this: _Renderer, token: Tokens.Del) { + if (!token.type || token.type !== prop) { + // @ts-ignore + // eslint-disable-next-line prefer-rest-params + return func.apply(this, arguments); + } + return func(this.parser.parseInline(token.tokens)); }; case 'text': return function(token: Tokens.Text) { + if (!token.type || token.type !== prop) { + // @ts-ignore + // eslint-disable-next-line prefer-rest-params + return func.apply(this, arguments); + } + return func(token.text); }; default: From 7f173775703cac4e1240c9502cfe9bcb23704b8b Mon Sep 17 00:00:00 2001 From: Tony Brix Date: Tue, 11 Jun 2024 08:06:34 -0600 Subject: [PATCH 13/14] Update src/Instance.ts Co-authored-by: Steven --- src/Instance.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Instance.ts b/src/Instance.ts index 6f372e7615..d0de96e0b3 100644 --- a/src/Instance.ts +++ b/src/Instance.ts @@ -157,7 +157,7 @@ export class Marked { // Replace renderer with func to run extension, but fall back if false renderer[rendererProp] = (...args: unknown[]) => { if (!pack.useNewRenderer) { - // Remove this in next major version + // TODO: Remove this in next major version rendererFunc = this.#convertRendererFunction(rendererFunc, rendererProp, renderer) as GenericRendererFunction; } let ret = rendererFunc.apply(renderer, args); From b26f7c52282dad52d1c2c1a957760e3ad1eaf7b0 Mon Sep 17 00:00:00 2001 From: Tony Brix Date: Tue, 11 Jun 2024 08:06:44 -0600 Subject: [PATCH 14/14] Update src/Instance.ts Co-authored-by: Steven --- src/Instance.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Instance.ts b/src/Instance.ts index d0de96e0b3..9019301731 100644 --- a/src/Instance.ts +++ b/src/Instance.ts @@ -255,7 +255,7 @@ export class Marked { return this; } - // Remove this in next major release + // TODO: Remove this in next major release #convertRendererFunction(func: GenericRendererFunction, prop: string, renderer: _Renderer) { switch (prop) { case 'heading':