You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There is some debate about making first-class dartdoc directives for tools like snippets, and I was thinking why don't we have "template tools", or rather tools that don't involve running dart code, but maybe just evaluating a template.
This is an extremely ugly attempt at defining what that could look like, without us inventing a new language and still giving template authors some power.
Warning
Please don't think of this as a serious proposal, it's more of an exploratory idea 🤣
dartdoc:
# What if we allowed "template tools"?template_tools:
# We could almost define something like snippets that way.snippets:
# Snippets don't have flags or options, so this is just illustrativeflags:
- warning # ArgParser.addFlag('warning') , allowing --[no]-warning (defaulting to false)options:
- language # ArgParser.addOption('language') , allowing --language=foo# We have a context dictionary as follows:# source.line# source.column# source.path# package.name# element.name# invocationIndex# input # text between {@tool snippets} and {@end-tool}# arguments.raw # space separated arguments given in {@tool} invocation# arguments.warning # true, if --warning was given in {@tool} invocation# arguments.language # value, if --language=value was given in {@tool} invocation## Using this context we can do some limited steps like:# - extract variables from context using regular expressions and save them to context again.# - assert values from context and throw an error instead of rendering a faulty template!steps:
# Create a new "description" field in the context dictionary, running pattern as regex against text
- extract: descriptiontext: '{{input}}'pattern: '^(?<content>.*)^```'multiLine: truecaseSensitive: truedotAll: true
- extract: codetext: '{{input}}'pattern: '^```(?<language>.*)\n(?<source>.*)^```'multiLine: truecaseSensitive: truedotAll: true# Evaluate assertion with package:boolean_selector (already used in package:test)# Giving template tool authors an option to sanity check data before the template is rendered.
- assert: 'code.hasMatch && description.hasMatch'message: 'Failed to extract code and language from snippet'# After running "steps" we've expanded context with:# description.hasMatch # True, if regex was matched# description.content # capture group content# code.hasMatch # True, if regex was matched!# code.language # capture group language# code.source # capture group source## We can access context in the template using mustache as illustrated below:template: | {@inject-html} <a name="{{element.name}}.{{invocationIndex}}"></a> <div class="snippet snippet-container anchor-container"> {{description}} <a class="anchor-button-overlay anchor-button" title="Copy link to clipboard" onmouseenter="fixHref(this, '{{element.name}}.{{invocationIndex}}');" onclick="fixHref(this, '{{element.name}}.{{invocationIndex}}'); copyStringToClipboard(this.href);" href="#"> <i class="material-icons anchor-image">link</i> </a> <div class="copyable-container"> <button class="copy-button-overlay copy-button" title="Copy to clipboard" onclick="copyTextToClipboard(findSiblingWithId(this, 'sample-code'));"> <i class="material-icons copy-image">content_copy</i> </button> <pre class="language-{{code.language}}" id="sample-code"><code class="language-{{code.language}}">{{code.source}}</code></pre> </div> </div> {@end-inject-html}
Note that context can probably just be Map<String, String>, we dont' have to treat foo.bar as sub-property access :D
Note:
You can still do some attacks by using degenerate regular expressions
We could probably accept that since it'll just loop indefinitely (or be slow), or,
We could evaluate the regular expressions in an isolate (which is cheap).
Regexes gives template tool authors a lot of power to do at-least something.
The steps of repeated regex evaluation is a powerful, but also horrific programming environment 🤣
I'm not sure this is the way, we could also implement a small expression language that can be safely evaluated in templates. Options range form jinja-like things, to implementing a safe subset Dart in a small interpreter. To porting json-e to Dart and feeding the output into mustache.
But we could probably get far with regexes, boolean_selector for assertions and mustache for templating.
All this being explored: We should perhaps ask the question if we want people inventing their own HTML section types. Or whether it'd be better to argue that:
(A) users should be using existing markdown constructs (there aren't much missing).
(B) We should introduce dartdoc directives when good markdown constructs are missing.
In the case of snippets, it could be argued that:
Using a ## Section title in markdown is better than a snippet macro.
All sections in dartdoc markdown should have a perma-link.
All code blocks should have a "copy to clipboard" button.
Though, we'd have to give up the special background color for snippet section blocks.
There is some debate about making first-class dartdoc directives for tools like snippets, and I was thinking why don't we have "template tools", or rather tools that don't involve running dart code, but maybe just evaluating a template.
This is an extremely ugly attempt at defining what that could look like, without us inventing a new language and still giving template authors some power.
Warning
Please don't think of this as a serious proposal, it's more of an exploratory idea 🤣
Note that context can probably just be
Map<String, String>, we dont' have to treatfoo.baras sub-property access :DNote:
I'm not sure this is the way, we could also implement a small expression language that can be safely evaluated in templates. Options range form jinja-like things, to implementing a safe subset Dart in a small interpreter. To porting json-e to Dart and feeding the output into mustache.
But we could probably get far with regexes, boolean_selector for assertions and mustache for templating.
All this being explored: We should perhaps ask the question if we want people inventing their own HTML section types. Or whether it'd be better to argue that:
In the case of snippets, it could be argued that:
## Sectiontitle in markdown is better than a snippet macro.Though, we'd have to give up the special background color for snippet section blocks.