Ticket #8204 (closed enhancement: fixed)
Opened 3 years ago
Last modified 2 years ago
Unify wiki processors and macros
| Reported by: | rblank | Owned by: | rblank |
|---|---|---|---|
| Priority: | normal | Milestone: | 0.12 |
| Component: | wiki system | Version: | 0.12dev |
| Severity: | normal | Keywords: | wikiprocessor span |
| Cc: | |||
| Release Notes: | |||
| API Changes: | |||
Description
Currently, wiki macros can be called in two different ways:
- Macro syntax: [[Macro(params)]]
- Wiki processor syntax: {{{#!Macro}}}
Both ways also allow calling MIME renderers and special-purpose processors, defined in WikiProcessor.
Wiki processors and macros are actually almost the same thing, except for the following differences:
- Wiki processors can take additional arguments, defined on the #! line. When calling a macro using the processor syntax, these arguments are lost.
- There is no extension point for defining wiki processors, they have to be implemented in WikiProcessor.
Instead of adding a new extension point to define wiki processors, I'd like to add an additional argument to IWikiMacroProvider.expand_macro() to pass the arguments of the wiki processor syntax. The interface would become:
def expand_macro(formatter, name, content, args=None): pass
When called with the macro syntax, args would be None. Otherwise, it would pass the .args attribute of WikiProcessor, which is a dictionary of arguments.
The existing processors defined in WikiProcessor could then be moved out into their own macro component, but this is optional.
To ensure backwards compatibility with existing macros and call sites, the following measures will be taken:
- The existing expand_macro call sites will check if the method expects the additional argument or not, and only pass it in the former case.
- The new args argument should have a default value of None, to ensure that call sites not in Trac core that still expect the old interface continue to work.
I should have a patch ready in a few days. Comments welcome.
Attachments
Change History
Changed 3 years ago by rblank
- Attachment 8204-processor-args-macro-r8371.patch added
comment:1 follow-up: ↓ 8 Changed 3 years ago by rblank
The patch above adds the new optional argument args to IWikiMacroProvider.expand_macro(), though it uses a default of {}, as WikiProcessor is also used for expanding [[Macro()]] syntax. So there's currently no way of differentiating between both forms of calls, which IMO is actually a good thing, as a macro should be written for either of the syntaxes, but normally not both.
The whole change is completely backwards compatible, and will allow implementing the commitlog macro for #1507.
The patch also fixes a minor off-by-two error in Formatter, where the #! at the start of a processor call was not taken into account (it doesn't make a difference, though, as the first item in the result list is dropped anyway).
comment:2 Changed 3 years ago by cboos
Patch reviewed, ok to apply.
Don't forget to update TracDev/ApiChanges/0.12.
comment:3 Changed 3 years ago by rblank
Thanks, applied in [8372].
comment:4 Changed 3 years ago by rblank
- Resolution set to fixed
- Status changed from new to closed
And documentation updated in TracDev/ApiChanges/0.12@2.
comment:5 Changed 3 years ago by cboos
Concerning the additional argument 'class': 'wikipage', I think I should fix that, by adding class='wikipage' in the div processor only:
-
trac/wiki/formatter.py
diff --git a/trac/wiki/formatter.py b/trac/wiki/formatter.py
a b 157 157 return elt 158 158 159 159 def _div_processor(self, text): 160 if 'class' not in self.args: 161 self.args['class'] = 'wikipage' 160 162 return self._elt_processor('div', format_to_html, text, self.args) 161 163 162 164 def _span_processor(self, text): … … 802 804 values = [(v and v[0] in '"\'' and [v[1:-1]] or [v])[0] 803 805 for v in args[1::2]] 804 806 args = dict(zip(keys, values)) 805 if 'class' not in args:806 args['class'] = 'wikipage'807 807 self.code_processor = WikiProcessor(self, name, args) 808 808 else: 809 809 self.code_buf.append(line)
What do you think?
comment:6 follow-up: ↓ 7 Changed 3 years ago by rblank
I was indeed wondering if that argument was used elsewhere, but haven't taken the time to look. It does look like the div processor is the only user, so yes, please go ahead. I'll remove the comment from the API change documentation.
comment:7 in reply to: ↑ 6 Changed 3 years ago by cboos
comment:8 in reply to: ↑ 1 ; follow-up: ↓ 9 Changed 2 years ago by cboos
- Keywords wikiprocessor span added
- Resolution fixed deleted
- Status changed from closed to reopened
Replying to rblank:
The patch above adds the new optional argument args to IWikiMacroProvider.expand_macro(), though it uses a default of {},
Putting {} (or []) as the default value for a parameter is almost always a bug.
I could have fixed it by assigning {} to self.args later, so that the code retains the following property:
there's currently no way of differentiating between both forms of calls,
which IMO is actually a good thing, as a macro should be written for either of the syntaxes, but normally not both.
But I think that being able to differentiate between those could be useful, as switching between both styles of call makes sense in some cases. A typical example would be the span processor, which should also become callable using a #!span block.
Hence wikiprocessors-or-macros-r9193.patch and span-blocks-r9193.patch.
Changed 2 years ago by cboos
- Attachment wikiprocessors-or-macros-r9193.patch added
WikiProcessors: fix a potential problem with processor arguments.
Changed 2 years ago by cboos
- Attachment span-blocks-r9193.patch added
WikiProcessors: span can be called as a wiki processor.
comment:9 in reply to: ↑ 8 ; follow-up: ↓ 10 Changed 2 years ago by rblank
Replying to cboos:
Putting {} (or []) as the default value for a parameter is almost always a bug.
That's a bit an exaggeration IMO, it's fine as long as you don't mutate the argument. But ok.
But I think that being able to differentiate between those could be useful, as switching between both styles of call makes sense in some cases. A typical example would be the span processor, which should also become callable using a #!span block.
Wasn't that already the case? IIRC, you can call the macro with both [[Span()]] and #!Span. Ah, except that you couldn't use the processor arguments for attributes, but you had to place them in the content (as was the case before). Ok, that's pretty useful (and an oversight on my part). Patches look good, please apply. Maybe also change the interface definition to show a default argument of None instead of {}?
comment:10 in reply to: ↑ 9 ; follow-up: ↓ 11 Changed 2 years ago by cboos
- Resolution set to fixed
- Status changed from reopened to closed
Replying to rblank:
Replying to cboos:
Putting {} (or []) as the default value for a parameter is almost always a bug.
That's a bit an exaggeration IMO, it's fine as long as you don't mutate the argument.
... which can be done in a different place that in the method in question, as was the case there, so this can make things a bit more difficult to maintain. I think we should better avoid it, unless we really, really, REALLY need it :-).
Patches look good, please apply. Maybe also change the interface definition to show a default argument of None instead of {}?
comment:11 in reply to: ↑ 10 Changed 2 years ago by rblank
Replying to cboos:
... which can be done in a different place that in the method in question, as was the case there, so this can make things a bit more difficult to maintain.
Sure. What I meant is that it is not a bug per se, rather a "bug waiting to happen" ;-)



Pass wiki processor arguments to macros.