Skip to content
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

Context data needed in custom renderer #391

Open
juanitocalero opened this issue Sep 16, 2024 · 2 comments
Open

Context data needed in custom renderer #391

juanitocalero opened this issue Sep 16, 2024 · 2 comments

Comments

@juanitocalero
Copy link

I'm writing a custom renderer, and I would like to modify my generated img tags to customize its url with a prefix.

That prefix depends on some extra data that depends on the current execution, but I'm unable to find a way to insert a context object in my custom render methods.

I know I could add an external prepopulated state object, but following the code, I can't find a way for that state to reach the rendering methods. The method's signature doesn't include a state. I've reviewed renderers/html.py render_token method, and it seems that the state is never used in the render functions.

How could I achieve that? The options that come to my mind are:

  • Add a property to my custom renderer class that changes before each invocation, but this could cause problems in case of multithreaded use and feels kinda ugly. I colud recreate the mistune object and/or the renderer in each invocation with my custom data, but I was looking for a better option.
  • Override the renderer core methods and call the render functions with the state included, but it seems like a lot of work and prone to errors.

Any ideas?

@lepture
Copy link
Owner

lepture commented Sep 22, 2024

You can inherit the BaseRenderer. Check code of MarkdownRenderer and rst renderer.

@juanitocalero
Copy link
Author

I finally solved it like this: My Renderer class overrides the render_token method, and there, I get the
state object and put my supplied information in the attributes dict.
This attributes dict is used in the parent render_token to dynamically call the specific render methods with the attributes unpacked.

It's a little hacky but works ok, and it doesn't affect anything else.

class WikiRenderer(mistune.HTMLRenderer):

    def render_token(self, token, state) -> str:
        attrs = token.get('attrs')
        if attrs and token['type'] in ['wikilink', 'link']:
            attrs['doc'] = state.env["doc"]
        return mistune.HTMLRenderer.render_token(self, token, state)

    def wikilink(self, text, title, doc):
        return f'<a ...'

    def link(self, text, url, title=None, doc=None):
       ...

I call the markdown rendering like this:

def markdown_view(space, doc):
    state = markdown.block.state_cls()
    state.env["doc"] =doc
    text, _ = markdown.parse(space.fs.read_text(doc.path), state)
    return text

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants