On 05/02/2012 04:01 AM, Tim Starling wrote:
How about frame.args.name as an abbreviation for
frame:getArgument('name'):expandTo( 'text/x-mediawiki' ) ?
Yep, that looks good to me. Maybe the specialized wikitext argument
variant could be called 'wikitextArgs' so that the general variant can
be used for ParserValues instead of the getArgument method?
And how about frame.plainArgs.name as an abbreviation
for
frame:getArgument('name'):expandTo( 'text/plain' ) ?
Adding more xxxArgs methods does not seem to scale that well, and would
introduce a lot of extra method names to remember. It would also
encourage users to pick one representation when they would not need to
care about it, especially if they just pass through some content.
I know you're not really asking for a review of
Parsoid and its
interfaces, but I worry as to whether your use of text/plain to
indicate wikitext with comments stripped is appropriate.
I am not that happy with the text/plain bit too. text/x-mediawiki with a
separate progress or 'processing stage' component might be better, as it
would not conflate processing stage with the format. I am using a
numerical 'rank' value to track progress internally in Parsoid, but a
string would likely be user-friendlier for an external API like this.
There is an example for this further down in this post.
If I were to provide Lua with a richer interface to
PPFrame::expand(),
I would be inclined to support at least some of those flags via named
options, rather than rolling them up into a single string parameter.
So instead of expandTo( 'text/plain' ) we might have:
frame:getArgument('name'):expand{
expand_args = false,
expand_templates = false,
respect_noinclude = false,
strip_comments = true }
Or, if forwards-compatibility requires that we don't support so many
orthogonal options, some of the options could be rolled in together.
The preceding could perhaps be written as:
frame:getArgument('name'):expand{ plain = true }
That doesn't preclude the use of overrides:
frame:getArgument('name'):expand{
plain = true,
strip_comments = false }
But it does seem like a can of worms.
Some grepping through core and extension code left me with the
impression that there are relatively few common sets of flags used. As
an example, NO_ARGS and NO_TEMPLATES always seem to be used as a pair in
situations where just comment and noinclude (and company) handling is
needed.
If there remain use cases for fully orthogonal flags, then those could
still be supported with optional (named) argument of course, as you note.
How about providing
getArgument(), which will return an opaque ParserValue object with a
single method called expand(). This method would theoretically take
named parameters, but currently, none are defined. With no parameters,
it provides some kind of reasonable template-expanding behaviour. Then
frame.args would provide an abbreviated syntax for expand() with no
parameters.
Yes, this looks very good to me. ParseValue with a heavily defaulted
expand() method should be a good compromise between convenience for the
currently common case without compromising the ability to work with
other content types, or specify the processing stage through a name or
flags. So the 'plain' example could look somewhat like this:
arg:expand( format = 'tokens/x-mediawiki',
phase = '0.1_noComments' ) --- named processing phase
The conversion
of wikitext or other formats to an opaque value object
could be achieved using an object constructor:
--- 'value text' is parsed lazily
ParserValue( 'text/x-mediawiki', 'value text', frame )
The frame might be the passed-in parent frame, or a custom one
constructed with args assembled from other ParserValues.
Yes, this is an interesting idea. But I think I would prefer the
factory to be a frame method rather than a global function.
I'd be happy with that too. Custom child frames could still be created
using a frame:newChild method.
Also,
again, I am skeptical about the value of using a MIME type. How about
an interface allowing either:
frame:newParserValue( 'value text' )
or named arguments:
frame:newParserValue{
text = 'value text',
fruitiness = 'high',
}
+1, but I think some way to indicate the type and processing state of
the passed-in value will be needed if non-wikitext values are to be
supported. Further processing of a ParserValue depends on this
knowledge. Optional (named) arguments could be employed for this too:
frame:newParserValue{
type = 'tokens/x-mediawiki',
value = { { type = 'tag',
name = 'a',
attribs = { href = 'http://foo' }
},
"Some link text",
{ type = 'endtag', name = 'a' }
}
}
Defaulting to wikitext and fully-preprocessed text for the processing
phase would be fine with me. Any kind of type identifiers (MIME or not)
could of course be used. MIME has the advantage of being somewhat known
already, but other type identifiers might have other advantages.
frame:newTemplateParserValue{title = 'tpl',
args = args}:expand()
abbreviated to:
frame:expandTemplate{title = 'tpl', args = args}
+1
It doesn't just make the text shorter, it also
reduces the number of
concepts that the user has to understand before they are able to use
the interface.
I know that adding such concepts gives greater flexibility, but an
increase in the number of concepts will steepen the learning curve,
and the terminology required to explain them risks being daunting. For
example, if someone has never programmed before, you can't expect them
to understand terms like "opaque object".
I pretty much agree. The abbreviated interface adds some complication by
providing a second way to do the same thing. This still seems to be
worth it if it helps people to get started.
Gabriel