-
Notifications
You must be signed in to change notification settings - Fork 3.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to write an async renderer? #2626
Comments
That is essentially what it does. Having async functions in the renderer or tokenizer would require lots of duplicate code in order to not break things or slow down marked for anyone who doesn't need it to be async. You can see an example of how to make marked async in the docs. |
So the question remains, how can I achieve the same using |
Can you give some example markdown and expected output? |
I basically want to override the link text in certain conditions, and using a renderer would work fine, the problem is that I need to perform some async operations in doing that. From: [some-text](url) to: <a href="url">some-other-text</a> |
The text for a link is tokenized since it can have other markdown tokens inside of it. Here is an example that changes the link text and re tokenizes it: import { marked } from 'marked';
const myAsyncExtension = {
async: true,
async walkTokens(token) {
if (token.type === 'link') {
const newText = await somethingAsync(token);
// `this` in a walkTokens function is `marked`.
// tokenize the `newText` so the renderer can render it correctly.
// `newText` can be inline markdown.
token.tokens = this.Lexer.lexInline(newText)
}
}
};
async function somethingAsync(token) {
await new Promise(r => setTimeout(r, 100));
return token.text + ' async';
}
marked.use(myAsyncExtension);
const md = `
[test](/url "title")
`;
console.log(await marked.parse(md));
// <p><a href="/url" title="title">test async</a></p> |
Awesome, that will do it. Thank you so much for the quick support! |
Here I have the solution which fitted my use case, if someone needs it: const seo: MarkedExtension = {
async: true,
async walkTokens(token) {
if (token.type === "image") {
const { href } = token;
const { width, height } = await inferRemoteSize(href);
// @ts-ignore - add new property to token
token.sizes = { width, height };
}
},
renderer: {
// @ts-ignore - using new property
image({ href, text, sizes }) {
return `<img src="${href}" alt="${text}" width="${sizes.width}" height="${sizes.height}" loading="lazy" decoding="async" />`;
},
},
}; |
Marked version: v4.1.1
Describe the bug
Despite #2474 fixes #458, I don't see how I can write an async renderer, it seems that the former merely allows to write an async version of the
walkTokens
function.To Reproduce
Steps to reproduce the behavior:
Expected behavior
I expected to see
x
in the output, and not<p>[object Promise]</p>
.The text was updated successfully, but these errors were encountered: