Edgewall Software
Modify

Opened 16 years ago

Closed 15 years ago

Last modified 15 years ago

#8204 closed enhancement (fixed)

Unify wiki processors and macros

Reported by: Remy Blank Owned by: Remy Blank
Priority: normal Milestone: 0.12
Component: wiki system Version: 0.12dev
Severity: normal Keywords: wikiprocessor span
Cc: Branch:
Release Notes:
API Changes:
Internal 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 (3)

8204-processor-args-macro-r8371.patch (2.7 KB ) - added by Remy Blank 15 years ago.
Pass wiki processor arguments to macros.
wikiprocessors-or-macros-r9193.patch (4.0 KB ) - added by Christian Boos 15 years ago.
WikiProcessors: fix a potential problem with processor arguments.
span-blocks-r9193.patch (3.9 KB ) - added by Christian Boos 15 years ago.
WikiProcessors: span can be called as a wiki processor.

Download all attachments as: .zip

Change History (14)

by Remy Blank, 15 years ago

Pass wiki processor arguments to macros.

comment:1 by Remy Blank, 15 years ago

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 by Christian Boos, 15 years ago

Patch reviewed, ok to apply.

Don't forget to update TracDev/ApiChanges/0.12.

comment:3 by Remy Blank, 15 years ago

Thanks, applied in [8372].

comment:4 by Remy Blank, 15 years ago

Resolution: fixed
Status: newclosed

And documentation updated in TracDev/ApiChanges/0.12@2.

comment:5 by Christian Boos, 15 years ago

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  
    157157        return elt
    158158
    159159    def _div_processor(self, text):
     160        if 'class' not in self.args:
     161            self.args['class'] = 'wikipage'
    160162        return self._elt_processor('div', format_to_html, text, self.args)
    161163
    162164    def _span_processor(self, text):
     
    802804                values = [(v and v[0] in '"\'' and [v[1:-1]] or [v])[0]
    803805                          for v in args[1::2]]
    804806                args = dict(zip(keys, values))
    805                 if 'class' not in args:
    806                     args['class'] = 'wikipage'
    807807                self.code_processor = WikiProcessor(self, name, args)
    808808            else:
    809809                self.code_buf.append(line)

What do you think?

comment:6 by Remy Blank, 15 years ago

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.

in reply to:  6 comment:7 by Christian Boos, 15 years ago

Replying to rblank: Ok, applied in [8374]

in reply to:  1 ; comment:8 by Christian Boos, 15 years ago

Keywords: wikiprocessor span added
Resolution: fixed
Status: closedreopened

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.

by Christian Boos, 15 years ago

WikiProcessors: fix a potential problem with processor arguments.

by Christian Boos, 15 years ago

Attachment: span-blocks-r9193.patch added

WikiProcessors: span can be called as a wiki processor.

in reply to:  8 ; comment:9 by Remy Blank, 15 years ago

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 {}?

in reply to:  9 ; comment:10 by Christian Boos, 15 years ago

Resolution: fixed
Status: reopenedclosed

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 {}?

Done in r9199 (with docstrings updated) and r9200.

in reply to:  10 comment:11 by Remy Blank, 15 years ago

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" ;-)

Modify Ticket

Change Properties
Set your email in Preferences
Action
as closed The owner will remain Remy Blank.
The resolution will be deleted. Next status will be 'reopened'.
to The owner will be changed from Remy Blank to the specified user.

Add Comment


E-mail address and name can be saved in the Preferences .
 
Note: See TracTickets for help on using tickets.