47 | | As a snapshot of the work in progress, here are the new interfaces: |
48 | | - `IWikiSyntaxProvider`, for providing new syntax. [[br]] |
49 | | The default Trac syntax is in most part defined by syntax provider components. |
50 | | The interface remains compatible with Trac [milestone:0.10] |
51 | | (lesson learned ;-) ) |
52 | | - `IWikiFormatterContributor`, for providing new or extending existing |
53 | | formatting flavors. [[br]] |
54 | | The default Trac formatters are entirely provided by formatter contributors. |
55 | | [[br]] (''new interface'') |
56 | | |
57 | | {{{ |
58 | | #!python |
59 | | class IWikiSyntaxProvider(Interface): |
60 | | |
61 | | def get_wiki_syntax(): |
62 | | """Return an iterable that provides additional wiki syntax. |
63 | | |
64 | | A new syntax rule is a `(priority, regexp, callback)` triple. |
65 | | The `priority` is used to globally order the rules. |
66 | | |
67 | | The `regexp` must be of the form `"(?P<...>...)"`, where |
68 | | `<...>` contains a globally unique name that will be used |
69 | | to identify the rule. |
70 | | |
71 | | The `callback` expects a `parser` argument of type `WikiParser`, |
72 | | and will use it to participate to the construction of the |
73 | | Wiki DOM tree. |
74 | | |
75 | | Before 0.11, the additional wiki syntax corresponded |
76 | | simply to a `(regexp, callback)` pair. The priority of such |
77 | | rules is set to `50`, which introduces them after the simple |
78 | | text style rules and before the other ones, as they used to be. |
79 | | |
80 | | However, the old `callback` function was of the form |
81 | | `handler(formatter, ns, match, fullmatch)`, i.e. it was |
82 | | actually expected to take care of the ''formatting'' as well. |
83 | | """ |
84 | | |
85 | | def get_link_resolvers(): |
86 | | """Generate new handlers for new TracLinks prefixes. |
87 | | |
88 | | A handler is a `(namespace, callback)` pair, where the |
89 | | `callback` is a function expected a `parser` argument |
90 | | (the `WikiParser` instance currently driving the parsing). |
91 | | |
92 | | Before 0.11, the generated value were `(namespace, formatter)` |
93 | | pairs, where the `formatter` was a function of the form |
94 | | `fmt(formatter, ns, target, label)`, and would return some |
95 | | HTML fragment. |
96 | | The `label` is already HTML escaped, whereas the `target` is not. |
97 | | """ |
98 | | |
99 | | def get_valid_parents(): |
100 | | """Generate rules for element embedding. |
101 | | |
102 | | Each rule is of the form `(nodetype, valid_parent_nodetypes)`, |
103 | | which means that an instance node of the given `nodetype` type |
104 | | can be parented in instance nodes of the `valid_parent_nodetypes` |
105 | | types. |
106 | | |
107 | | Example: `(Inline, Anchor)` means that any `Inline` node can |
108 | | be set to be a child of an `Anchor` node. |
109 | | |
110 | | (`valid_parent_nodetypes` can be a single class or a tuple |
111 | | of classes, all subclasses of `WikiDomNode`) |
112 | | """ |
113 | | |
114 | | |
115 | | class IWikiFormatterContributor(Interface): |
116 | | |
117 | | def get_wiki_formatters(): |
118 | | """Generate `(flavor, nodetype, formatter_callback)` triples. |
119 | | |
120 | | This enables the wiki system to register the `formatter_callback` |
121 | | for handling `nodetype` nodes when rendering a parse tree to |
122 | | the specified `flavor` kind of output. |
123 | | If for a given node, there's no callback registered directly for |
124 | | its class, a callback registered for one of its ancestor class |
125 | | will be used, following the method resolution order. |
126 | | |
127 | | The `formatter_callback` itself is a function accepting a |
128 | | `Formatter` argument and the `WikiDomNode` instance currently |
129 | | being rendered and must return a result which is appropriate |
130 | | for the kind of formatting being done. |
131 | | """ |
132 | | }}} |
133 | | |
134 | | The main utility functions for parsing and formatting wiki text will be: |
135 | | {{{ |
136 | | #!python |
137 | | |
138 | | # -- Utility functions |
139 | | |
140 | | def parse_wiki(ctx, wikitext): |
141 | | """Parse `wikitext` and produce a Wiki DOM tree. |
142 | | |
143 | | Return the `WikiDocument` root node of that tree. |
144 | | """ |
145 | | return WikiSystem(ctx.env).parse(wikitext) |
146 | | |
147 | | def format_to(flavor, ctx, wikidom, **kwargs): |
148 | | """Format to `flavor` the given `wikidom` parsed wiki text, |
149 | | in the given `ctx`. |
150 | | |
151 | | `wikidom` can be simply text instead of a Wiki DOM tree, |
152 | | and it will be parsed on the fly. |
153 | | """ |
154 | | return WikiSystem(ctx.env).format(ctx, wikidom, flavor, **kwargs) |
155 | | |
156 | | def format_to_html(ctx, wikidom, escape_newlines=False): |
157 | | return WikiSystem(ctx.env).format(ctx, wikidom, 'default', |
158 | | escape_newlines=escape_newlines) |
159 | | # etc. |
160 | | }}} |
161 | | |
162 | | ''implementations details to be updated as the code progresses'' |
| 47 | Some early ideas are visible in [[.@6#Implementation|version 6]] of this document. |
| 48 | |
| 49 | The parsing logic is described in VerticalHorizontalParsing. |