Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 27 additions & 12 deletions src/Instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,9 +206,10 @@ export class Marked<ParserOutput = string, RendererOutput = string> {
// @ts-expect-error cannot type hook function dynamically
hooks[hooksProp] = (arg: unknown) => {
if (this.defaults.async && _Hooks.passThroughHooksRespectAsync.has(prop)) {
return Promise.resolve(hooksFunc.call(hooks, arg)).then(ret => {
return (async() => {
const ret = await hooksFunc.call(hooks, arg);
return prevHook.call(hooks, ret);
});
})();
}

const ret = hooksFunc.call(hooks, arg);
Expand All @@ -217,6 +218,16 @@ export class Marked<ParserOutput = string, RendererOutput = string> {
} else {
// @ts-expect-error cannot type hook function dynamically
hooks[hooksProp] = (...args: unknown[]) => {
if (this.defaults.async) {
return (async() => {
let ret = await hooksFunc.apply(hooks, args);
if (ret === false) {
ret = await prevHook.apply(hooks, args);
}
return ret;
})();
}

let ret = hooksFunc.apply(hooks, args);
if (ret === false) {
ret = prevHook.apply(hooks, args);
Expand Down Expand Up @@ -294,30 +305,34 @@ export class Marked<ParserOutput = string, RendererOutput = string> {
opt.hooks.block = blockType;
}

const lexer = opt.hooks ? opt.hooks.provideLexer() : (blockType ? _Lexer.lex : _Lexer.lexInline);
const parser = opt.hooks ? opt.hooks.provideParser() : (blockType ? _Parser.parse : _Parser.parseInline);

if (opt.async) {
return Promise.resolve(opt.hooks ? opt.hooks.preprocess(src) : src)
.then(src => lexer(src, opt))
.then(tokens => opt.hooks ? opt.hooks.processAllTokens(tokens) : tokens)
.then(tokens => opt.walkTokens ? Promise.all(this.walkTokens(tokens, opt.walkTokens)).then(() => tokens) : tokens)
.then(tokens => parser(tokens, opt))
.then(html => opt.hooks ? opt.hooks.postprocess(html) : html)
.catch(throwError);
return (async() => {
const processedSrc = opt.hooks ? await opt.hooks.preprocess(src) : src;
const lexer = opt.hooks ? await opt.hooks.provideLexer() : (blockType ? _Lexer.lex : _Lexer.lexInline);
const tokens = await lexer(processedSrc, opt);
const processedTokens = opt.hooks ? await opt.hooks.processAllTokens(tokens) : tokens;
if (opt.walkTokens) {
await Promise.all(this.walkTokens(processedTokens, opt.walkTokens));
}
const parser = opt.hooks ? await opt.hooks.provideParser() : (blockType ? _Parser.parse : _Parser.parseInline);
const html = await parser(processedTokens, opt);
return opt.hooks ? await opt.hooks.postprocess(html) : html;
})().catch(throwError);
}

try {
if (opt.hooks) {
src = opt.hooks.preprocess(src) as string;
}
const lexer = opt.hooks ? opt.hooks.provideLexer() : (blockType ? _Lexer.lex : _Lexer.lexInline);
let tokens = lexer(src, opt);
if (opt.hooks) {
tokens = opt.hooks.processAllTokens(tokens);
}
if (opt.walkTokens) {
this.walkTokens(tokens, opt.walkTokens);
}
const parser = opt.hooks ? opt.hooks.provideParser() : (blockType ? _Parser.parse : _Parser.parseInline);
let html = parser(tokens, opt);
Comment thread
UziTech marked this conversation as resolved.
if (opt.hooks) {
html = opt.hooks.postprocess(html);
Expand Down
66 changes: 66 additions & 0 deletions test/unit/Hooks.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,39 @@ describe('Hooks', () => {
assert.strictEqual(html.trim(), '<h1>text</h1>');
});

it('should provide lexer async hook', async() => {
marked.use({
async: true,
hooks: {
async provideLexer() {
await timeout();
return (src) => {
return [createHeadingToken(src)];
};
},
},
});
const html = await marked.parse('text');
assert.strictEqual(html.trim(), '<h1>text</h1>');
});
Comment thread
UziTech marked this conversation as resolved.

it('should provide async lexer from async hook', async() => {
marked.use({
async: true,
hooks: {
async provideLexer() {
await timeout();
return async(src) => {
await timeout();
return [createHeadingToken(src)];
};
},
},
});
const html = await marked.parse('text');
assert.strictEqual(html.trim(), '<h1>text</h1>');
});

it('should provide parser return object', () => {
marked.use({
hooks: {
Expand Down Expand Up @@ -258,4 +291,37 @@ describe('Hooks', () => {
const html = await marked.parse('text');
assert.strictEqual(html.trim(), 'test parser');
});

it('should provide parser async hook', async() => {
marked.use({
async: true,
hooks: {
async provideParser() {
await timeout();
return (tokens) => {
return 'test parser';
};
},
},
});
const html = await marked.parse('text');
assert.strictEqual(html.trim(), 'test parser');
});
Comment thread
UziTech marked this conversation as resolved.

it('should provide async parser from async hook', async() => {
marked.use({
async: true,
hooks: {
async provideParser() {
await timeout();
return async(tokens) => {
await timeout();
return 'test parser';
};
},
},
});
const html = await marked.parse('text');
assert.strictEqual(html.trim(), 'test parser');
});
});