Skip to content

Commit a287433

Browse files
authored
fix: allow Renderer class in marked.use (#3118)
1 parent 44f4038 commit a287433

File tree

2 files changed

+67
-5
lines changed

2 files changed

+67
-5
lines changed

src/Instance.ts

+15-3
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,13 @@ export class Marked {
142142
if (pack.renderer) {
143143
const renderer = this.defaults.renderer || new _Renderer(this.defaults);
144144
for (const prop in pack.renderer) {
145-
if (!(prop in renderer) || prop === 'options') {
145+
if (!(prop in renderer)) {
146146
throw new Error(`renderer '${prop}' does not exist`);
147147
}
148+
if (prop === 'options') {
149+
// ignore options property
150+
continue;
151+
}
148152
const rendererProp = prop as Exclude<keyof _Renderer, 'options'>;
149153
const rendererFunc = pack.renderer[rendererProp] as GenericRendererFunction;
150154
const prevRenderer = renderer[rendererProp] as GenericRendererFunction;
@@ -162,9 +166,13 @@ export class Marked {
162166
if (pack.tokenizer) {
163167
const tokenizer = this.defaults.tokenizer || new _Tokenizer(this.defaults);
164168
for (const prop in pack.tokenizer) {
165-
if (!(prop in tokenizer) || ['options', 'rules', 'lexer'].includes(prop)) {
169+
if (!(prop in tokenizer)) {
166170
throw new Error(`tokenizer '${prop}' does not exist`);
167171
}
172+
if (['options', 'rules', 'lexer'].includes(prop)) {
173+
// ignore options, rules, and lexer properties
174+
continue;
175+
}
168176
const tokenizerProp = prop as Exclude<keyof _Tokenizer, 'options' | 'rules' | 'lexer'>;
169177
const tokenizerFunc = pack.tokenizer[tokenizerProp] as UnknownFunction;
170178
const prevTokenizer = tokenizer[tokenizerProp] as UnknownFunction;
@@ -185,9 +193,13 @@ export class Marked {
185193
if (pack.hooks) {
186194
const hooks = this.defaults.hooks || new _Hooks();
187195
for (const prop in pack.hooks) {
188-
if (!(prop in hooks) || prop === 'options') {
196+
if (!(prop in hooks)) {
189197
throw new Error(`hook '${prop}' does not exist`);
190198
}
199+
if (prop === 'options') {
200+
// ignore options property
201+
continue;
202+
}
191203
const hooksProp = prop as Exclude<keyof _Hooks, 'options'>;
192204
const hooksFunc = pack.hooks[hooksProp] as UnknownFunction;
193205
const prevHook = hooks[hooksProp] as UnknownFunction;

test/unit/instance.test.js

+52-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { marked, Marked, Renderer } from '../../lib/marked.esm.js';
2-
import { describe, it } from 'node:test';
1+
import { marked, Marked, Renderer, Tokenizer, Hooks } from '../../lib/marked.esm.js';
2+
import { describe, it, beforeEach } from 'node:test';
33
import assert from 'node:assert';
44

55
describe('Marked', () => {
@@ -89,4 +89,54 @@ describe('Marked', () => {
8989

9090
assert.strictEqual(html, 'test');
9191
});
92+
93+
describe('use class objects', () => {
94+
beforeEach(() => {
95+
marked.setOptions(marked.getDefaults());
96+
});
97+
98+
it('allow new Renderer()', () => {
99+
const marked1 = new Marked();
100+
const newRenderer = new Renderer();
101+
newRenderer.heading = () => 'im marked renderer';
102+
103+
marked1.use({ renderer: newRenderer });
104+
marked.use({ renderer: newRenderer });
105+
106+
assert.strictEqual(marked1.parse('# header'), 'im marked renderer');
107+
assert.strictEqual(marked.parse('# header'), 'im marked renderer');
108+
});
109+
110+
it('allow new Tokenizer()', () => {
111+
const marked1 = new Marked();
112+
const newTokenizer = new Tokenizer();
113+
newTokenizer.heading = function(src) {
114+
return {
115+
type: 'heading',
116+
raw: src,
117+
depth: 1,
118+
text: 'im marked tokenizer',
119+
tokens: this.lexer.inlineTokens('im marked tokenizer')
120+
};
121+
};
122+
123+
marked1.use({ tokenizer: newTokenizer });
124+
marked.use({ tokenizer: newTokenizer });
125+
126+
assert.strictEqual(marked1.parse('# header'), '<h1>im marked tokenizer</h1>\n');
127+
assert.strictEqual(marked.parse('# header'), '<h1>im marked tokenizer</h1>\n');
128+
});
129+
130+
it('allow new Hooks()', () => {
131+
const marked1 = new Marked();
132+
const newHooks = new Hooks();
133+
newHooks.preprocess = () => 'im marked hooks';
134+
135+
marked1.use({ hooks: newHooks });
136+
marked.use({ hooks: newHooks });
137+
138+
assert.strictEqual(marked1.parse('# header'), '<p>im marked hooks</p>\n');
139+
assert.strictEqual(marked.parse('# header'), '<p>im marked hooks</p>\n');
140+
});
141+
});
92142
});

0 commit comments

Comments
 (0)