mirror of
https://github.com/xoofx/markdig.git
synced 2026-02-08 05:44:58 +00:00
Any way of accessing (external) contextual data in a parser? #262
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @patriksvensson on GitHub (Jan 10, 2019).
I've written a MarkDig parser and in the parser I would want to get access to some contextual information about the document being parsed (that's not available in the document itself).
Is there any way of passing contextual data to a parser on a parse basis (just like I can in Scriban when rendering)?
If there is no work around for my problem, I would be happy to provide a pull request for this functionality if you think it would be a good fit for MarkDig.
@xoofx commented on GitHub (Jan 10, 2019):
You mean a Block processor or inline processor?
@MihaZupan commented on GitHub (Jan 10, 2019):
You can add context by including it when you create the pipeline - for every parsing, pass the proper context to the parser instance you include in the pipeline.
@patriksvensson commented on GitHub (Jan 10, 2019):
@xoofx An inline processor. Would prefer not to recreate the pipeline on each render, that's why I ask.
@MihaZupan commented on GitHub (Jan 11, 2019):
Essentially something like this then
c1ad27670e?Accessible from parsers via
processor.Document.CustomState@xoofx commented on GitHub (Jan 11, 2019):
Hm... if it is only a parser information, this could be made available via a
MarkdownParserContext, accessible via aMarkdownParser.Contextproperty. By default, this property would be null (and readonly, only passed at construction time)A
MarkdownParserContextwould be a class with only adictionary<object, object> Propertiesin it... passed down from Markdown.Parse/ToHtml methods as a last argument (null by default)Not sure it would cover your needs?
@patriksvensson commented on GitHub (Jan 11, 2019):
@xoofx That would be perfect! Do you want me to send a PR for this?
@xoofx commented on GitHub (Jan 11, 2019):
Yes, please
@MihaZupan commented on GitHub (Jan 11, 2019):
Is a dictionary necessary if it's essentially only one object?
@xoofx commented on GitHub (Jan 11, 2019):
The problem is that if all extensions are coming with all their own object, it will not be possible to push for a common object, so it is easier to say the context is dynamic with a single dictionary (and the class is sealed)
@MihaZupan commented on GitHub (Jan 11, 2019):
How about adding the passed objects into the MarkdownObject, since a key/value collection for different parsers is already implemented there
@xoofx commented on GitHub (Jan 11, 2019):
Indeed, forgot about the codebase actually... 😅
@patriksvensson could you use directly the
MarkdownDocument(accessible from both BlockProcessor and InlineProcessor) as an indirect context (as you can add your own SetData/GetData on it directly)?@patriksvensson commented on GitHub (Jan 11, 2019):
@xoofx I can try and do that.
From an API perspective I think it would be more discoverable though by explicitly having a context (just my two cents).
@xoofx commented on GitHub (Jan 11, 2019):
Yeah, but the document object is already used by parsers as a context, so it is unnecessary to introduce something new here. The more I wait to write a documentation + the fact that I don't use the project, the more I forget about all these details... at least the GitHub issues can help folks out there... 😅
@patriksvensson commented on GitHub (Jan 11, 2019):
@xoofx Since I'm setting the data directly on the
MarkdownDocumentI assume I need to implement locking around the parsing (I can't process more than one document at a time since this the document is tied to the pipeline)? Or is the data stored in thread local storage or similar?@xoofx commented on GitHub (Jan 11, 2019):
No, the parser assume that the document is not being modified by another thread while parsing, so you don't need any locking. The processors on the other hand should not store data because they are shared across a pipeline, which is supposed to be thread safe (there are cases where the processors could be modified externally but it is not recommended to do that)
@patriksvensson commented on GitHub (Jan 11, 2019):
@xoofx I'm sorry and excuse me for taking up so much of your time with this.
I'm not sure how to do this to be frankly. Is there any source code I can look at to understand what I'm supposed to do? I'm super confused.
@xoofx commented on GitHub (Jan 11, 2019):
Precisely, you have nothing to do ☺️
Just use MarkdownDocument that you can access from the inline and block processor the Document instance (check for example LinkInlineParser)
@patriksvensson commented on GitHub (Jan 11, 2019):
Yes, but how do I set that from outside the parser in my code?
@xoofx commented on GitHub (Jan 11, 2019):
You should give an example. I'm now confused what you want to do exactly. 😉
@patriksvensson commented on GitHub (Jan 11, 2019):
Ah, sorry.
In my case I'm renderering markdown for a custom format.
Currently I'm writing a parser that transforms identifiers like
@1234to a link. So before rendering the template, I want to make sure that my InlineParser have access to contextual data for the markdown data being rendered.Which given something like:
would render to:
Given that the document was rendered with
LinkBaseForDocumentset tohttps://foo.com@xoofx commented on GitHub (Jan 11, 2019):
I see, so let's go back to the MarkdownParserContext then, as a MarkdownDocument is more used for internal parser states, not external, so in that case a context is fine. PR welcome (sorry for the ping pong!)
@patriksvensson commented on GitHub (Jan 11, 2019):
@xoofx No problem at all! I know how important it is to discuss an issue properly with the maintainers to make sure that there is proper buy-in 😄
@leotsarev commented on GitHub (Jan 24, 2019):
Hi @xoofx !
I'm also do same in my code, but don't have any problems with context — I just rebuilt pipeline for every rendering attempt. I wonder if I'm doing that's wrong and I'm supposed to cache pipeline and use this approach with context...
@xoofx commented on GitHub (Jan 24, 2019):
Usually pipeline are supposed to be cachable
@leotsarev commented on GitHub (Jan 25, 2019):
Thanks for answer. Waiting for you to new release!