Skip to content

Commit

Permalink
fix: Remove useNewRenderer (#3342)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: Remove old renderer
  • Loading branch information
UziTech authored Aug 7, 2024
1 parent b5a5004 commit e64f226
Show file tree
Hide file tree
Showing 3 changed files with 3 additions and 266 deletions.
4 changes: 0 additions & 4 deletions docs/USING_PRO.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,6 @@ Marked provides methods for directly overriding the `renderer` and `tokenizer` f

<h2 id="renderer">The Renderer : <code>renderer</code></h2>

<!-- TODO: Remove this after next major version -->

🚨 Marked v13 changed the renderer to accept tokens. To opt in to these new renderer functions add `useNewRenderer: true` to the extension. See [the v13 release notes](https://github.com/markedjs/marked/releases/tag/v13.0.0) for an example 🚨

The renderer defines the HTML output of a given token. If you supply a `renderer` in the options object passed to `marked.use()`, any functions in the object will override the default handling of that token type.

Calling `marked.use()` to override the same function multiple times will give priority to the version that was assigned *last*. Overriding functions can return `false` to fall back to the previous override in the sequence, or resume default behavior if all overrides return `false`. Returning any other value (including nothing) will prevent fallback behavior.
Expand Down
257 changes: 2 additions & 255 deletions src/Instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ import { _Hooks } from './Hooks.ts';
import { _Renderer } from './Renderer.ts';
import { _Tokenizer } from './Tokenizer.ts';
import { _TextRenderer } from './TextRenderer.ts';
import {
escape,
unescape,
} from './helpers.ts';
import { escape } from './helpers.ts';
import type { MarkedExtension, MarkedOptions } from './MarkedOptions.ts';
import type { Token, Tokens, TokensList } from './Tokens.ts';

Expand Down Expand Up @@ -152,11 +149,7 @@ export class Marked {
continue;
}
const rendererProp = prop as Exclude<keyof _Renderer, 'options' | 'parser'>;
let rendererFunc = pack.renderer[rendererProp] as GenericRendererFunction;
if (!pack.useNewRenderer) {
// TODO: Remove this in next major version
rendererFunc = this.#convertRendererFunction(rendererFunc, rendererProp, renderer) as GenericRendererFunction;
}
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
renderer[rendererProp] = (...args: unknown[]) => {
Expand Down Expand Up @@ -255,252 +248,6 @@ export class Marked {
return this;
}

// TODO: Remove this in next major release
#convertRendererFunction(func: GenericRendererFunction, prop: string, renderer: _Renderer) {
switch (prop) {
case 'heading':
return function(this: _Renderer, 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.call(
this,
renderer.parser.parseInline(token.tokens),
token.depth,
unescape(renderer.parser.parseInline(token.tokens, renderer.parser.textRenderer)),
);
};
case 'code':
return function(this: _Renderer, 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.call(
this,
token.text,
token.lang,
!!token.escaped,
);
};
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 = '';
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.call(this, header, body);
};
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.call(this, 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;

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.call(this, body, ordered, start);
};
case 'html':
return function(this: _Renderer, 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.call(this, 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.call(this, this.parser.parseInline(token.tokens));
};
case 'escape':
return function(this: _Renderer, 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.call(this, 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.call(this, token.href, token.title, this.parser.parseInline(token.tokens));
};
case 'image':
return function(this: _Renderer, 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.call(this, 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.call(this, 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.call(this, this.parser.parseInline(token.tokens));
};
case 'codespan':
return function(this: _Renderer, 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.call(this, 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.call(this, this.parser.parseInline(token.tokens));
};
case 'text':
return function(this: _Renderer, 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.call(this, token.text);
};
default:
// do nothing
}
return func;
}

setOptions(opt: MarkedOptions) {
this.defaults = { ...this.defaults, ...opt };
return this;
Expand Down
8 changes: 1 addition & 7 deletions src/MarkedOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,15 +109,9 @@ export interface MarkedExtension {
* The return value of the function is ignored.
*/
walkTokens?: ((token: Token) => void | Promise<void>) | 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<MarkedExtension, 'useNewRenderer' | 'hooks' | 'renderer' | 'tokenizer' | 'extensions' | 'walkTokens'> {
export interface MarkedOptions extends Omit<MarkedExtension, 'hooks' | 'renderer' | 'tokenizer' | 'extensions' | 'walkTokens'> {
/**
* Hooks are methods that hook into some part of marked.
*/
Expand Down

0 comments on commit e64f226

Please sign in to comment.