3 * Copyright (C) 2011 Florian Brosch
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 * Florian Brosch <flo.brosch@gmail.com>
24 using Valadoc
.Content
;
26 public class Valadoc
.GtkdocRenderer
: ContentRenderer
{
27 private GtkDocMarkupWriter writer
= new
GtkDocMarkupWriter ();
28 protected Settings settings
;
29 private bool separated
;
31 private string?
get_cname (Api
.Item item
) {
32 if (item is Api
.Method
) {
33 return ((Api
.Method
)item
).get_cname ();
34 } else if (item is Api
.FormalParameter
) {
35 return ((Api
.FormalParameter
)item
).name
;
36 } else if (item is Api
.Constant
) {
37 return ((Api
.Constant
)item
).get_cname ();
38 } else if (item is Api
.Property
) {
39 return ((Api
.Property
)item
).get_cname ();
40 } else if (item is Api
.Signal
) {
41 var name
= ((Api
.Signal
)item
).get_cname ();
42 return name
.replace ("_", "-");
43 } else if (item is Api
.Class
) {
44 return ((Api
.Class
)item
).get_cname ();
45 } else if (item is Api
.Struct
) {
46 return ((Api
.Struct
)item
).get_cname ();
47 } else if (item is Api
.Interface
) {
48 return ((Api
.Interface
)item
).get_cname ();
49 } else if (item is Api
.ErrorDomain
) {
50 return ((Api
.ErrorDomain
)item
).get_cname ();
51 } else if (item is Api
.ErrorCode
) {
52 return ((Api
.ErrorCode
)item
).get_cname ();
53 } else if (item is Api
.Delegate
) {
54 return ((Api
.Delegate
)item
).get_cname ();
55 } else if (item is Api
.Enum
) {
56 return ((Api
.Enum
)item
).get_cname ();
57 } else if (item is Api
.EnumValue
) {
58 return ((Api
.EnumValue
)item
).get_cname ();
64 public void write_docbook_link (Api
.Item item
) {
65 writer
.set_wrap (false);
67 if (item is Api
.Method
) {
68 writer
.start_tag ("function")
69 .text (((Api
.Method
)item
).get_cname ())
70 .end_tag ("function");
71 } else if (item is Api
.FormalParameter
) {
72 writer
.start_tag ("parameter").
73 text (((Api
.FormalParameter
)item
).name ??
"...")
74 .end_tag ("parameter");
75 } else if (item is Api
.Constant
) {
76 writer
.start_tag ("constant").text (((Api
.Constant
)item
)
78 .end_tag ("constant");
79 } else if (item is Api
.Property
) {
80 // TODO: use docbook-tags instead
81 writer
.text ("#").text (get_cname(item
.parent
))
83 .text (((Api
.Property
)item
)
84 .get_cname ().replace ("_", "-"));
85 } else if (item is Api
.Signal
) {
86 // TODO: use docbook-tags instead
87 writer
.text ("#").text (get_cname(item
.parent
))
89 .text (((Api
.Signal
)item
).get_cname ().replace ("_", "-"));
90 } else if (item is Api
.Namespace
) {
91 writer
.text (((Api
.Namespace
) item
).get_full_name ());
93 writer
.start_tag ("type")
94 .text (get_cname (item
))
98 writer
.set_wrap (true);
101 public GtkdocRenderer () {
104 public override void render (ContentElement element
) {
106 element
.accept (this
);
109 public void render_symbol (Content
.Comment? documentation
) {
110 render (documentation
);
112 append_exceptions (documentation
.find_taglets (null, typeof(Taglets
.Throws
)));
113 append_see (documentation
.find_taglets (null, typeof(Taglets
.See
)));
114 append_since (documentation
.find_taglets (null, typeof(Taglets
.Since
)));
117 public override void render_children (ContentElement element
) {
119 element
.accept_children (this
);
122 private void reset () {
127 public unowned
string content
{
129 if (writer
.content
.has_prefix ("\n")) {
130 return writer
.content
.next_char ();
133 return writer
.content
;
137 public override void visit_comment (Comment element
) {
138 element
.accept_children (this
);
141 public override void visit_embedded (Embedded element
) {
142 writer
.start_tag ("figure");
143 if (element
.caption
!= null) {
144 writer
.start_tag ("title")
145 .text (element
.caption
)
149 writer
.start_tag ("mediaobject");
151 writer
.start_tag ("imageobject")
152 .simple_tag ("imagedata", {"fileref", element
.url
})
153 .end_tag ("imageobject");
155 if (element
.caption
!= null) {
156 writer
.start_tag ("textobject")
157 .start_tag ("phrase")
158 .text (element
.caption
)
160 .end_tag ("textobject");
163 writer
.end_tag ("mediaobject");
164 writer
.end_tag ("figure");
167 public override void visit_headline (Headline element
) {
168 assert_not_reached ();
171 public override void visit_wiki_link (WikiLink element
) {
172 // wiki pages are not supported by gir
173 if (element
.content
.size
> 0) {
174 element
.accept_children (this
);
176 write_string (element
.name
);
180 public override void visit_link (Link element
) {
181 writer
.start_tag ("ulink", {"url", element
.url
});
182 element
.accept_children (this
);
183 writer
.end_tag ("ulink");
186 public override void visit_symbol_link (SymbolLink element
) {
187 if (element
.content
.size
> 0) {
189 element
.accept_children (this
);
190 writer
.text ("\" (");
191 write_symbol_link (element
);
194 write_symbol_link (element
);
198 public void write_symbol_link (SymbolLink element
) {
199 if (element
.symbol
== null) {
200 writer
.text (element
.given_symbol_name
);
202 write_docbook_link (element
.symbol
);
206 public override void visit_list (Content
.List element
) {
207 string tag
= "orderedlist";
208 switch (element
.bullet
) {
209 case Content
.List
.Bullet
.NONE
:
210 writer
.start_tag ("itemizedlist", {"mark", "none"});
211 tag
= "itemizedlist";
214 case Content
.List
.Bullet
.UNORDERED
:
215 writer
.start_tag ("itemizedlist");
216 tag
= "itemizedlist";
219 case Content
.List
.Bullet
.ORDERED
:
220 writer
.start_tag ("orderedlist");
223 case Content
.List
.Bullet
.ORDERED_NUMBER
:
224 writer
.start_tag ("orderedlist", {"numeration", "arabic"});
227 case Content
.List
.Bullet
.ORDERED_LOWER_CASE_ALPHA
:
228 writer
.start_tag ("orderedlist", {"numeration", "loweralpha"});
231 case Content
.List
.Bullet
.ORDERED_UPPER_CASE_ALPHA
:
232 writer
.start_tag ("orderedlist", {"numeration", "upperalpha"});
235 case Content
.List
.Bullet
.ORDERED_LOWER_CASE_ROMAN
:
236 writer
.start_tag ("orderedlist", {"numeration", "lowerroman"});
239 case Content
.List
.Bullet
.ORDERED_UPPER_CASE_ROMAN
:
240 writer
.start_tag ("orderedlist", {"numeration", "upperroman"});
244 assert_not_reached ();
247 element
.accept_children (this
);
249 writer
.end_tag (tag
);
252 public override void visit_list_item (ListItem element
) {
253 writer
.start_tag ("listitem");
254 element
.accept_children (this
);
255 writer
.end_tag ("listitem");
258 public override void visit_page (Page element
) {
259 element
.accept_children (this
);
262 public override void visit_paragraph (Paragraph element
) {
263 writer
.start_tag ("para");
264 element
.accept_children (this
);
265 writer
.end_tag ("para");
268 public override void visit_warning (Warning element
) {
269 writer
.start_tag ("warning");
270 element
.accept_children (this
);
271 writer
.end_tag ("warning");
274 public override void visit_note (Note element
) {
275 writer
.start_tag ("note");
276 element
.accept_children (this
);
277 writer
.end_tag ("note");
280 public override void visit_run (Run element
) {
283 switch (element
.style
) {
285 writer
.start_tag ("emphasis", {"role", "bold"});
289 case Run
.Style
.ITALIC
:
290 writer
.start_tag ("emphasis");
294 case Run
.Style
.UNDERLINED
:
295 writer
.start_tag ("emphasis", {"role", "underline"});
299 case Run
.Style
.MONOSPACED
:
300 writer
.start_tag ("blockquote");
305 element
.accept_children (this
);
308 writer
.end_tag (tag
);
312 public override void visit_source_code (SourceCode element
) {
313 writer
.start_tag ("example")
314 .start_tag ("programlisting");
315 writer
.text (element
.code
);
316 writer
.end_tag ("programlisting")
317 .end_tag ("example");
320 public override void visit_table (Table element
) {
321 writer
.start_tag ("table", {"align", "center"});
322 element
.accept_children (this
);
323 writer
.end_tag ("table");
326 public override void visit_table_cell (TableCell element
) {
327 writer
.start_tag ("td", {"colspan", element
.colspan
.to_string (), "rowspan", element
.rowspan
.to_string ()});
328 element
.accept_children (this
);
329 writer
.end_tag ("td");
332 public override void visit_table_row (TableRow element
) {
333 writer
.start_tag ("tr");
334 element
.accept_children (this
);
335 writer
.end_tag ("tr");
338 public override void visit_text (Text element
) {
339 write_string (element
.content
);
342 private void write_string (string content
) {
343 unichar chr
= content
[0];
347 for (i
= 0; chr
!= '\0' ; i
++, chr
= content
[i
]) {
350 writer
.raw_text (content
.substring (lpos
, i
-lpos
));
351 writer
.raw_text ("<");
356 writer
.raw_text (content
.substring (lpos
, i
-lpos
));
357 writer
.raw_text (">");
362 writer
.raw_text (content
.substring (lpos
, i
-lpos
));
363 writer
.raw_text (""");
368 writer
.raw_text (content
.substring (lpos
, i
-lpos
));
369 writer
.raw_text ("'");
374 writer
.raw_text (content
.substring (lpos
, i
-lpos
));
375 writer
.raw_text ("&");
380 writer
.raw_text (content
.substring (lpos
, i
-lpos
));
381 writer
.raw_text ("#");
386 writer
.raw_text (content
.substring (lpos
, i
-lpos
));
387 writer
.raw_text ("%");
392 writer
.raw_text (content
.substring (lpos
, i
-lpos
));
393 writer
.raw_text ("@");
398 writer
.raw_text (content
.substring (lpos
, i
-lpos
));
399 writer
.raw_text ("(");
404 writer
.raw_text (content
.substring (lpos
, i
-lpos
));
405 writer
.raw_text (")");
410 writer
.raw_text (content
.substring (lpos
, i
-lpos
));
411 writer
.simple_tag ("br");
417 writer
.raw_text (content
.substring (lpos
, i
-lpos
));
420 public void append_since (Vala
.List
<Content
.Taglet
> taglets
) {
421 foreach (Content
.Taglet _taglet
in taglets
) {
422 Taglets
.Since taglet
= _taglet as Taglets
.Since
;
423 if (taglet
== null || taglet
.version
== null) {
424 // ignore unexpected taglets
428 if (separated
== false) {
432 writer
.set_wrap (false);
433 writer
.text ("\nSince: ")
434 .text (taglet
.version
);
435 writer
.set_wrap (true);
438 // ignore multiple occurrences
443 public void append_see (Vala
.List
<Content
.Taglet
> taglets
) {
445 foreach (Content
.Taglet _taglet
in taglets
) {
446 Taglets
.See taglet
= _taglet as Taglets
.See
;
447 if (taglet
== null || taglet
.symbol
== null) {
448 // ignore unexpected taglets
453 writer
.start_tag ("para").text ("See also: ");
458 write_docbook_link (taglet
.symbol
);
462 if (first
== false) {
463 writer
.end_tag ("para");
467 public void append_exceptions (Vala
.List
<Content
.Taglet
> taglets
) {
469 foreach (Content
.Taglet _taglet
in taglets
) {
470 Taglets
.Throws taglet
= _taglet as Taglets
.Throws
;
471 if (taglet
== null || taglet
.error_domain
== null) {
472 // ignore unexpected taglets
477 writer
.start_tag ("para")
478 .text ("This function may throw:")
480 writer
.start_tag ("table");
483 writer
.start_tag ("tr");
485 writer
.start_tag ("td");
486 write_docbook_link (taglet
.error_domain
);
487 writer
.end_tag ("td");
489 writer
.start_tag ("td");
490 taglet
.accept_children (this
);
491 writer
.end_tag ("td");
493 writer
.end_tag ("tr");
498 if (first
== false) {
499 writer
.end_tag ("table");