Release 0.41.92
[vala-gnome.git] / libvaladoc / html / basicdoclet.vala
blob37c731c22ea35124f412c3e9883c66b1fc283d2c
1 /* basicdoclet.vala
3 * Copyright (C) 2008-2012 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
19 * Author:
20 * Florian Brosch <flo.brosch@gmail.com>
23 using Valadoc.Content;
24 using Valadoc.Api;
28 public abstract class Valadoc.Html.BasicDoclet : Api.Visitor, Doclet {
29 public Html.LinkHelper linker {
30 protected set;
31 get;
34 public Settings settings {
35 protected set;
36 get;
39 public string wiki_index_name {
40 default = "index.valadoc";
41 protected set;
42 get;
45 protected Api.Tree tree;
46 protected HtmlRenderer _renderer;
47 protected Html.MarkupWriter writer;
48 protected Html.CssClassResolver cssresolver;
49 protected Charts.Factory image_factory;
50 protected ErrorReporter reporter;
51 protected string package_list_link = "../index.html";
53 // CSS:
54 private const string css_inline_navigation = "navi_inline";
55 private const string css_package_index = "package_index";
56 private const string css_brief_description = "brief_description";
57 private const string css_description = "description";
58 private const string css_known_list = "known_nodes";
59 private const string css_leaf_brief_description = "leaf_brief_description";
60 private const string css_leaf_code_definition = "leaf_code_definition";
62 private const string css_box_headline_text = "text";
63 private const string css_box_headline_toggle = "toggle";
64 private const string css_box_headline = "headline";
65 private const string css_box_content = "content";
66 private const string css_box_column = "column";
67 private const string css_box = "box";
69 private const string css_namespace_note = "namespace_note";
70 private const string css_package_note = "package_note";
72 private const string css_site_header = "site_header";
73 private const string css_navi = "navi_main";
74 private const string css_navi_hr = "navi_hr";
75 private const string css_errordomain_table_name = "main_errordomain_table_name";
76 private const string css_errordomain_table_text = "main_errordomain_table_text";
77 private const string css_errordomain_table = "main_errordomain_table";
78 private const string css_enum_table_name = "main_enum_table_name";
79 private const string css_enum_table_text = "main_enum_table_text";
80 private const string css_enum_table = "main_enum_table";
81 private const string css_diagram = "main_diagram";
82 private const string css_see_list = "main_see_list";
83 private const string css_wiki_table = "main_table";
84 private const string css_notification_area = "main_notification";
85 private const string css_source_sample = "main_sourcesample";
86 private const string css_exception_table = "main_parameter_table";
87 private const string css_parameter_table_text = "main_parameter_table_text";
88 private const string css_parameter_table_name = "main_parameter_table_name";
89 private const string css_parameter_table = "main_parameter_table";
90 private const string css_title = "main_title";
91 private const string css_other_type = "main_other_type";
92 private const string css_basic_type = "main_basic_type";
93 private const string css_keyword = "main_keyword";
94 private const string css_optional_parameter = "main_optional_parameter";
95 private const string css_code_definition = "main_code_definition";
96 private const string css_headline_hr = "main_hr";
97 private const string css_hr = "main_hr";
98 private const string css_list_errdom = "main_list_errdom";
99 private const string css_list_en = "main_list_en";
100 private const string css_list_ns = "main_list_ns";
101 private const string css_list_cl = "main_list_cl";
102 private const string css_list_iface = "main_list_iface";
103 private const string css_list_stru = "main_list_stru";
104 private const string css_list_field = "main_list_field";
105 private const string css_list_prop = "main_list_prop";
106 private const string css_list_del = "main_list_del";
107 private const string css_list_sig = "main_list_sig";
108 private const string css_list_m = "main_list_m";
109 private const string css_style_navigation = "site_navigation";
110 private const string css_style_content = "site_content";
111 private const string css_style_body = "site_body";
112 private const string css_deprecated = "deprecated";
114 public virtual void process (Settings settings, Api.Tree tree, ErrorReporter reporter) {
115 this.reporter = reporter;
116 this.settings = settings;
117 this.tree = tree;
119 this.cssresolver = new CssClassResolver ();
120 this.linker = new LinkHelper ();
122 _renderer = new HtmlRenderer (settings, this.linker, this.cssresolver);
123 this.image_factory = new SimpleChartFactory (settings, linker);
127 // paths:
128 protected string? get_link (Api.Node to, Api.Node from) {
129 return linker.get_relative_link (from, to, settings);
132 protected virtual string get_img_path_html (Api.Node element, string type) {
133 return Path.build_filename ("img", element.get_full_name () + "." + type);
136 protected virtual string get_img_path (Api.Node element, string type) {
137 return Path.build_filename (settings.path, element.package.name, "img",
138 element.get_full_name () + "." + type);
141 protected virtual string get_icon_directory () {
142 return "..";
146 private TypeSymbol? unpack_type_reference (TypeReference? type_reference) {
147 Api.Item pos = type_reference;
149 while (pos != null) {
150 if (pos is TypeReference) {
151 pos = ((TypeReference) pos).data_type;
152 } else if (pos is Api.Array) {
153 pos = ((Api.Array) pos).data_type;
154 } else if (pos is Pointer) {
155 pos = ((Pointer) pos).data_type;
156 } else {
157 assert (pos is TypeSymbol);
158 return (TypeSymbol) pos;
162 return null;
166 protected void write_navi_entry_html_template (string style, string content, bool is_deprecated) {
167 writer.start_tag ("li", {"class", style});
169 if (is_deprecated) {
170 writer.start_tag ("span", {"class", css_deprecated});
171 writer.text (content);
172 writer.end_tag ("span");
173 } else {
174 writer.text (content);
177 writer.end_tag ("li");
180 protected void write_navi_entry_html_template_with_link (string style, string link,
181 string content, bool is_deprecated)
183 writer.start_tag ("li", {"class", style});
185 if (is_deprecated) {
186 writer.start_tag ("span", {"class", css_deprecated});
187 writer.link (link, content);
188 writer.end_tag ("span");
189 } else {
190 writer.link (link, content);
193 writer.end_tag ("li");
196 protected void write_navi_entry (Api.Node element, Api.Node? pos, string style,
197 bool link, bool full_name = false)
199 string name;
201 if (full_name == true && element is Namespace) {
202 string tmp = element.get_full_name();
203 name = (tmp == null)? "Global Namespace" : tmp;
204 } else {
205 string tmp = element.name;
206 name = (tmp == null)? "Global Namespace" : tmp;
209 bool is_deprecated = element is Symbol && ((Symbol) element).is_deprecated;
211 if (link == true) {
212 this.write_navi_entry_html_template_with_link (style,
213 this.get_link (element, pos),
214 name,
215 is_deprecated);
216 } else {
217 this.write_navi_entry_html_template (style, name, is_deprecated);
221 protected void write_wiki_pages (Api.Tree tree, string css_path_wiki, string js_path_wiki,
222 string contentp)
224 if (tree.wikitree == null) {
225 return ;
228 if (tree.wikitree == null) {
229 return ;
232 Vala.Collection<WikiPage> pages = tree.wikitree.get_pages();
233 if (pages.size == 0) {
234 return ;
237 DirUtils.create (contentp, 0777);
239 DirUtils.create (Path.build_filename (contentp, "img"), 0777);
241 foreach (WikiPage page in pages) {
242 if (page.name != wiki_index_name) {
243 write_wiki_page (page, contentp, css_path_wiki, js_path_wiki, this.settings.pkg_name);
248 protected virtual void write_wiki_page (WikiPage page, string contentp, string css_path,
249 string js_path, string pkg_name)
251 GLib.FileStream file = GLib.FileStream.open (
252 Path.build_filename (contentp, page.name.substring (0, page.name.length-7).replace ("/", ".")+"htm"),
253 "w");
255 writer = new MarkupWriter (file);
256 _renderer.set_writer (writer);
257 this.write_file_header (css_path, js_path, pkg_name);
258 _renderer.set_container (page);
259 _renderer.render (page.documentation);
260 this.write_file_footer ();
263 protected void write_navi_top_entry (Api.Node element, Api.Node? parent) {
264 string style = cssresolver.resolve (element);
266 writer.start_tag ("ul", {"class", css_navi});
268 if (element == parent || parent == null) {
269 this.write_navi_entry (element, parent, style, false);
270 } else {
271 this.write_navi_entry (element, parent, style, true);
274 writer.end_tag ("ul");
275 writer.simple_tag ("hr", {"class", css_navi_hr});
278 protected void write_top_element_template (string link) {
279 writer.start_tag ("ul", {"class", css_navi});
280 writer.start_tag ("li", {"class", css_package_index});
281 writer.link (link, "Packages");
282 writer.end_tag ("li");
283 writer.end_tag ("ul");
284 writer.simple_tag ("hr", {"class", css_navi_hr});
287 protected void write_top_elements (Api.Node element, Api.Node? parent) {
288 Vala.ArrayList<Api.Node> lst = new Vala.ArrayList<Api.Node> ();
289 Api.Node pos = element;
291 this.write_top_element_template (package_list_link);
293 while (pos != null) {
294 lst.add (pos);
295 pos = (Api.Node)pos.parent;
298 for (int i = lst.size-1; i >= 0 ; i--) {
299 Api.Node el = lst.get (i);
301 if (el.name != null) {
302 this.write_navi_top_entry (el, parent);
307 protected void fetch_subnamespace_names (Api.Node node, Vala.ArrayList<Namespace> namespaces) {
308 Vala.ArrayList<Api.Node> sorted_list = new Vala.ArrayList<Api.Node> ();
309 sorted_list.add_all (node.get_children_by_type (Api.NodeType.NAMESPACE));
310 sorted_list.sort ((CompareDataFunc) Api.Node.compare_to);
312 foreach (Api.Node child in sorted_list) {
313 namespaces.add ((Namespace) child);
314 this.fetch_subnamespace_names (child, namespaces);
318 protected void write_navi_package (Package package) {
319 Vala.ArrayList<Namespace> ns_list = new Vala.ArrayList<Namespace> ();
320 this.fetch_subnamespace_names (package, ns_list);
322 writer.start_tag ("div", {"class", css_style_navigation});
323 write_top_elements (package, package);
324 writer.start_tag ("ul", {"class", css_navi});
326 Namespace globals = null;
328 foreach (Namespace ns in ns_list) {
329 if (ns.name == null) {
330 globals = ns;
331 } else {
332 this.write_navi_entry (ns, package, cssresolver.resolve (ns), true, true);
336 if (globals != null) {
337 write_navi_children (globals, Api.NodeType.ERROR_CODE, package);
338 write_navi_children (globals, Api.NodeType.ENUM_VALUE, package);
339 write_navi_children (globals, Api.NodeType.ENUM, package);
340 write_navi_children (globals, Api.NodeType.INTERFACE, package);
341 write_navi_children (globals, Api.NodeType.CLASS, package);
342 write_navi_children (globals, Api.NodeType.STRUCT, package);
343 write_navi_children (globals, Api.NodeType.CONSTANT, package);
344 write_navi_children (globals, Api.NodeType.PROPERTY, package);
345 write_navi_children (globals, Api.NodeType.DELEGATE, package);
346 write_navi_children (globals, Api.NodeType.STATIC_METHOD, package);
347 write_navi_children (globals, Api.NodeType.CREATION_METHOD, package);
348 write_navi_children (globals, Api.NodeType.METHOD, package);
349 write_navi_children (globals, Api.NodeType.SIGNAL, package);
350 write_navi_children (globals, Api.NodeType.FIELD, package);
353 writer.end_tag ("ul");
354 writer.end_tag ("div");
357 protected void write_navi_symbol (Api.Node node) {
358 writer.start_tag ("div", {"class", css_style_navigation});
359 write_top_elements (node, node);
360 write_navi_symbol_inline (node, node);
361 writer.end_tag ("div");
364 protected void write_navi_leaf_symbol (Api.Node node) {
365 writer.start_tag ("div", {"class", css_style_navigation});
366 write_top_elements ((Api.Node) node.parent, node);
367 write_navi_symbol_inline ((Api.Node) node.parent, node);
368 writer.end_tag ("div");
371 protected void write_navi_symbol_inline (Api.Node node, Api.Node? parent) {
372 writer.start_tag ("ul", {"class", css_navi});
373 write_navi_children (node, Api.NodeType.NAMESPACE, parent);
374 write_navi_children (node, Api.NodeType.ERROR_CODE, parent);
375 write_navi_children (node, Api.NodeType.ENUM_VALUE, parent);
376 write_navi_children (node, Api.NodeType.ENUM, parent);
377 write_navi_children (node, Api.NodeType.INTERFACE, parent);
378 write_navi_children (node, Api.NodeType.CLASS, parent);
379 write_navi_children (node, Api.NodeType.STRUCT, parent);
380 write_navi_children (node, Api.NodeType.CONSTANT, parent);
381 write_navi_children (node, Api.NodeType.PROPERTY, parent);
382 write_navi_children (node, Api.NodeType.DELEGATE, parent);
383 write_navi_children (node, Api.NodeType.STATIC_METHOD, parent);
384 write_navi_children (node, Api.NodeType.CREATION_METHOD, parent);
385 write_navi_children (node, Api.NodeType.METHOD, parent);
386 write_navi_children (node, Api.NodeType.SIGNAL, parent);
387 write_navi_children (node, Api.NodeType.FIELD, parent);
388 writer.end_tag ("ul");
391 protected void write_navi_children (Api.Node node, Api.NodeType type, Api.Node? parent) {
392 var children = node.get_children_by_type (type);
393 children.sort ((CompareDataFunc) Api.Node.compare_to);
394 foreach (Api.Node child in children) {
395 write_navi_entry (child, parent, cssresolver.resolve (child), child != parent);
399 protected void write_package_note (Api.Node element) {
400 string package = element.package.name;
401 if (package == null) {
402 return;
405 writer.start_tag ("div", {"class", css_package_note});
406 writer.start_tag ("b")
407 .text ("Package:")
408 .end_tag ("b");
409 writer.text (" ")
410 .start_tag ("a", {"href", get_link (element.package, element)})
411 .text (package)
412 .end_tag ("a");
413 writer.end_tag ("div");
416 protected void write_namespace_note (Api.Node element) {
417 Namespace? ns = element.nspace;
418 if (ns == null) {
419 return;
422 if (ns.name == null) {
423 return;
426 writer.start_tag ("div", {"class", css_namespace_note});
427 writer.start_tag ("b")
428 .text ("Namespace:")
429 .end_tag ("b");
430 writer.text (" ")
431 .start_tag ("a", {"href", get_link (ns, element)})
432 .text (ns.get_full_name())
433 .end_tag ("a");
434 writer.end_tag ("div");
437 private bool has_brief_description (Api.Node element) {
438 return element.documentation != null;
441 private void write_brief_description (Api.Node element , Api.Node? pos) {
442 Content.Comment? doctree = element.documentation;
443 if (doctree == null) {
444 return;
447 Vala.List<Block> description = doctree.content;
448 if (description.size > 0) {
449 writer.start_tag ("span", {"class", css_brief_description});
451 _renderer.set_container (pos);
452 _renderer.set_owner (element);
453 _renderer.render_children (description.get (0));
454 _renderer.set_owner (null);
456 writer.end_tag ("span");
460 private void write_documentation (Api.Node element , Api.Node? pos) {
461 Content.Comment? doctree = element.documentation;
462 bool is_deprecated = (element is Symbol && ((Symbol) element).is_deprecated);
464 // avoid empty divs
465 if (doctree == null && !is_deprecated) {
466 return;
470 writer.start_tag ("div", {"class", css_description});
471 _renderer.set_owner (element);
473 // deprecation warning:
474 if (is_deprecated) {
475 Symbol symbol = (Symbol) element;
476 Attribute? version;
477 Attribute? deprecated;
478 AttributeArgument? replacement;
479 AttributeArgument? since;
480 if ((version = symbol.get_attribute ("Version")) != null) {
481 replacement = version.get_argument ("replacement");
482 since = version.get_argument ("deprecated_since");
483 } else if ((deprecated = symbol.get_attribute ("Deprecated")) != null) {
484 replacement = deprecated.get_argument ("replacement");
485 since = deprecated.get_argument ("version");
486 } else {
487 assert_not_reached ();
490 writer.start_tag ("p");
491 writer.start_tag ("b");
492 writer.text ("Warning:");
493 writer.end_tag ("b");
494 writer.text (" %s is deprecated".printf (element.name));
496 if (since != null) {
497 writer.text (" since %s".printf (since.get_value_as_string ()));
500 writer.text (".");
502 if (replacement != null) {
503 string replacement_name = replacement.get_value_as_string ();
504 Api.Node? replacement_node = tree.search_symbol_str (pos,
505 replacement_name.substring (1, replacement_name.length - 2));
507 writer.text (" Use ");
508 if (replacement_node == null) {
509 writer.text (replacement_name);
510 } else {
511 string? link = get_link (replacement_node, pos);
512 if (link != null) {
513 string css = cssresolver.resolve (replacement_node);
514 writer.link (link, replacement_node.get_full_name (), css);
515 } else {
516 writer.start_tag ("code")
517 .text (replacement_node.get_full_name ())
518 .end_tag ("code");
521 writer.text (".");
524 writer.end_tag ("p");
527 if (doctree != null) {
528 _renderer.set_container (pos);
529 _renderer.render (doctree);
533 _renderer.set_owner (null);
534 writer.end_tag ("div");
537 private void write_attributes (Api.Symbol element, Api.Node? pos) {
538 writer.set_wrap (false);
539 _renderer.set_container (pos);
540 foreach (Attribute att in element.get_attributes ()) {
541 _renderer.render (att.signature);
542 writer.simple_tag ("br");
544 writer.set_wrap (true);
547 private void write_signature (Api.Node element , Api.Node? pos) {
548 writer.set_wrap (false);
549 _renderer.set_container (pos);
550 _renderer.render (element.signature);
551 writer.set_wrap (true);
554 protected bool is_internal_node (Api.Node node) {
555 return node is Package
556 || node is Api.Namespace
557 || node is Api.Interface
558 || node is Api.Class
559 || node is Api.Struct
560 || node is Api.Enum
561 || node is Api.EnumValue
562 || node is Api.ErrorDomain
563 || node is Api.ErrorCode;
566 public void write_navi_packages_inline (Api.Tree tree) {
567 writer.start_tag ("ul", {"class", css_navi});
568 foreach (Package pkg in tree.get_package_list()) {
569 if (pkg.is_browsable (settings)) {
570 writer.start_tag ("li", {"class", cssresolver.resolve (pkg)});
571 writer.link (linker.get_package_link (pkg, settings), pkg.name);
572 // brief description
573 writer.end_tag ("li");
574 } else {
575 writer.start_tag ("li", {"class", cssresolver.resolve (pkg)});
576 writer.text (pkg.name);
577 writer.end_tag ("li");
580 writer.end_tag ("ul");
583 public void write_navi_packages (Api.Tree tree) {
584 writer.start_tag ("div", {"class", css_style_navigation});
585 this.write_navi_packages_inline (tree);
586 writer.end_tag ("div");
589 public void write_package_index_content (Api.Tree tree) {
590 writer.start_tag ("div", {"class", css_style_content});
591 writer.start_tag ("h1", {"class", css_title})
592 .text ("Packages:")
593 .end_tag ("h1");
594 writer.simple_tag ("hr", {"class", css_headline_hr});
596 WikiPage? wikiindex = (tree.wikitree == null)
597 ? null
598 : tree.wikitree.search (wiki_index_name);
599 if (wikiindex != null) {
600 _renderer.set_container (wikiindex);
601 _renderer.render (wikiindex.documentation);
604 writer.start_tag ("h2", {"class", css_title})
605 .text ("Content:")
606 .end_tag ("h2");
607 writer.start_tag ("h3", {"class", css_title})
608 .text ("Packages:")
609 .end_tag ("h3");
610 this.write_navi_packages_inline (tree);
611 writer.end_tag ("div");
614 private uint html_id_counter = 0;
616 private inline Vala.Collection<Api.Node> get_accessible_nodes_from_list (Vala.Collection<Api.Node> nodes) {
617 var list = new Vala.ArrayList<Api.Node> ();
619 foreach (var node in nodes) {
620 if (node.is_browsable(_settings)) {
621 list.add (node);
625 return list;
628 private void write_known_symbols_note (Vala.Collection<Api.Node> nodes2, Api.Node container, string headline) {
629 var nodes = get_accessible_nodes_from_list (nodes2);
630 if (nodes.size == 0) {
631 return ;
634 // Box:
635 var html_id = "box-content-" + html_id_counter.to_string ();
636 html_id_counter++;
639 writer.start_tag ("div", {"class", css_box});
641 // headline:
642 writer.start_tag ("div", {"class", css_box_headline, "onclick", "toggle_box (this, '%s')".printf (html_id)})
643 .text (headline)
644 .end_tag ("div");
645 //writer.start_tag ("div", {"class", css_box_headline_text, "onclick", "toggle_box (this, '%s')".printf (html_id)})
646 // .text (headline)
647 // .end_tag ("div");
648 //writer.start_tag ("div", {"class", css_box_headline_toggle});
649 //writer.start_tag ("img", {"onclick",
650 // "toggle_box (this, '" + html_id + "')",
651 // "src",
652 // Path.build_filename (get_icon_directory (),
653 // "coll_open.png")});
654 //writer.raw_text ("&nbsp;");
655 //writer.end_tag ("div");
656 //writer.end_tag ("div");
659 // content:
660 int[] list_sizes = {0, 0, 0};
661 list_sizes[0] = nodes.size;
662 list_sizes[2] = list_sizes[0]/3;
663 list_sizes[0] -= list_sizes[2];
664 list_sizes[1] = list_sizes[0]/2;
665 list_sizes[0] -= list_sizes[1];
667 writer.start_tag ("div", {"class", css_box_content, "id", html_id});
669 var iter = nodes.iterator ();
671 for (int i = 0; i < list_sizes.length; i++) {
672 writer.start_tag ("div", {"class", css_box_column});
673 writer.start_tag ("ul", {"class", css_inline_navigation});
675 for (int p = 0; p < list_sizes[i] && iter.next (); p++) {
676 var node = iter.get ();
677 writer.start_tag ("li", {"class", cssresolver.resolve (node)});
678 string link = get_link (node, container);
679 if (link == null) {
680 writer.text (node.name);
681 } else {
682 writer.link (link, node.name);
684 writer.end_tag ("li");
687 writer.end_tag ("ul");
688 writer.end_tag ("div");
691 writer.end_tag ("div"); // end content
693 writer.end_tag ("div"); // end box
696 public void write_symbol_content (Api.Node node) {
697 writer.start_tag ("div", {"class", css_style_content});
698 writer.start_tag ("h1", {"class", css_title})
699 .text (node.name)
700 .end_tag ("h1");
701 writer.simple_tag ("hr", {"class", css_headline_hr});
702 this.write_image_block (node);
703 writer.start_tag ("h2", {"class", css_title})
704 .text ("Description:")
705 .end_tag ("h2");
706 writer.start_tag ("div", {"class", css_code_definition});
707 if (node is Symbol) {
708 this.write_attributes ((Symbol) node, node);
710 this.write_signature (node, node);
711 writer.end_tag ("div");
712 this.write_documentation (node, node);
714 if (node is Class) {
715 var cl = node as Class;
716 write_known_symbols_note (cl.get_known_child_classes (),
718 "All known sub-classes:");
719 write_known_symbols_note (cl.get_known_derived_interfaces (),
721 "Required by:");
722 } else if (node is Interface) {
723 var iface = node as Interface;
724 write_known_symbols_note (iface.get_known_implementations (),
725 iface,
726 "All known implementing classes:");
727 write_known_symbols_note (iface.get_known_related_interfaces (),
728 iface,
729 "All known sub-interfaces:");
730 } else if (node is Struct) {
731 var stru = node as Struct;
732 write_known_symbols_note (stru.get_known_child_structs (),
733 stru,
734 "All known sub-structs:");
737 if (node.parent is Namespace) {
738 writer.simple_tag ("br");
739 write_namespace_note (node);
740 write_package_note (node);
743 if (!(node is Method || node is Delegate || node is Api.Signal)) {
744 // avoids exception listings & implementations
746 if (node.has_children ({
747 Api.NodeType.ERROR_CODE,
748 Api.NodeType.ENUM_VALUE,
749 Api.NodeType.CREATION_METHOD,
750 Api.NodeType.STATIC_METHOD,
751 Api.NodeType.CLASS,
752 Api.NodeType.STRUCT,
753 Api.NodeType.ENUM,
754 Api.NodeType.DELEGATE,
755 Api.NodeType.METHOD,
756 Api.NodeType.SIGNAL,
757 Api.NodeType.PROPERTY,
758 Api.NodeType.FIELD,
759 Api.NodeType.CONSTANT
762 writer.start_tag ("h2", {"class", css_title}).text ("Content:").end_tag ("h2");
763 write_children (node, Api.NodeType.ERROR_CODE, "Error codes", node);
764 write_children (node, Api.NodeType.ENUM_VALUE, "Enum values", node);
765 write_children (node, Api.NodeType.CLASS, "Classes", node);
766 write_children (node, Api.NodeType.STRUCT, "Structs", node);
767 write_children (node, Api.NodeType.ENUM, "Enums", node);
768 write_children (node, Api.NodeType.CONSTANT, "Constants", node);
769 write_children (node, Api.NodeType.PROPERTY, "Properties", node);
770 write_children (node, Api.NodeType.DELEGATE, "Delegates", node);
771 write_children (node, Api.NodeType.STATIC_METHOD, "Static methods", node);
772 write_children (node, Api.NodeType.CREATION_METHOD, "Creation methods", node);
773 write_children (node, Api.NodeType.METHOD, "Methods", node);
774 write_children (node, Api.NodeType.SIGNAL, "Signals", node);
775 write_children (node, Api.NodeType.FIELD, "Fields", node);
779 if (node is Class) {
780 write_inherited_symbols_note_for_class ((Class) node, node);
781 } else if (node is Interface) {
782 write_inherited_symbols_note_for_interface ((Interface) node, node);
783 } else if (node is Struct) {
784 write_inherited_symbols_note_for_struct ((Struct) node, node);
787 writer.end_tag ("div");
790 private static NodeType[] inheritable_members = {
791 NodeType.CONSTANT,
792 NodeType.PROPERTY,
793 NodeType.DELEGATE,
794 NodeType.STATIC_METHOD,
795 NodeType.METHOD,
796 NodeType.SIGNAL,
797 NodeType.FIELD
800 private inline bool has_visible_inheritable_children (TypeSymbol symbol) {
801 return symbol.has_visible_children_by_types (inheritable_members, _settings);
804 private void write_inherited_members_headline () {
805 writer.start_tag ("h3", {"class", css_title})
806 .text ("Inherited Members:")
807 .end_tag ("h3");
810 private void write_inherited_symbols_note_for_class (Class cl, Api.Node container) {
811 bool headline_printed = false;
813 // class hierarchy:
814 Class base_class = unpack_type_reference (cl.base_type) as Class;
815 while (base_class != null) {
816 if (!headline_printed && has_visible_inheritable_children (base_class)) {
817 write_inherited_members_headline ();
818 headline_printed = true;
821 write_inherited_symbols_note (base_class, "class", container);
822 base_class = unpack_type_reference (base_class.base_type) as Class;
826 // implemented interfaces
827 Vala.Collection<Interface> printed_interfaces = new Vala.ArrayList<Interface> ();
828 foreach (TypeReference iface_ref in cl.get_full_implemented_interface_list ()) {
829 Interface iface = (Interface) unpack_type_reference (iface_ref);
831 if (!headline_printed && has_visible_inheritable_children (iface)) {
832 write_inherited_members_headline ();
833 headline_printed = true;
834 } else if (printed_interfaces.contains (iface)) {
835 continue ;
838 write_inherited_symbols_note (iface, "interface", container);
839 printed_interfaces.add (iface);
843 private void write_inherited_symbols_note_for_interface (Interface iface, Api.Node container) {
844 bool headline_printed = false;
846 // class hierarchy:
847 Class base_class = unpack_type_reference (iface.base_type) as Class;
848 while (base_class != null) {
849 if (!headline_printed && has_visible_inheritable_children (base_class)) {
850 write_inherited_members_headline ();
851 headline_printed = true;
854 write_inherited_symbols_note (base_class, "class", container);
855 base_class = unpack_type_reference (base_class.base_type) as Class;
859 // interfaces:
860 Vala.Collection<Interface> printed_interfaces = new Vala.ArrayList<Interface> ();
861 foreach (TypeReference pre_ref in iface.get_full_implemented_interface_list ()) {
862 Interface pre = (Interface) unpack_type_reference (pre_ref);
864 if (!headline_printed && has_visible_inheritable_children (pre)) {
865 write_inherited_members_headline ();
866 headline_printed = true;
867 } else if (printed_interfaces.contains (pre)) {
868 continue ;
871 write_inherited_symbols_note (pre, "interface", container);
872 printed_interfaces.add (pre);
876 private void write_inherited_symbols_note_for_struct (Struct str, Api.Node container) {
877 Struct base_struct = unpack_type_reference (str.base_type) as Struct;
878 if (base_struct != null && has_visible_inheritable_children (base_struct)) {
879 write_inherited_members_headline ();
880 write_inherited_symbols_note (base_struct, "struct", container);
884 private void write_inherited_symbols_note (TypeSymbol symbol, string type, Api.Node container) {
885 write_known_symbols_note (symbol.get_children_by_types (inheritable_members, false),
886 container,
887 "All known members inherited from %s %s".printf (type, symbol.get_full_name ()));
890 write_known_symbols_note (symbol.get_children_by_type (NodeType.CONSTANT, false),
891 container,
892 "All known constants inherited from %s %s".printf (type, symbol.get_full_name ()));
893 write_known_symbols_note (symbol.get_children_by_type (NodeType.PROPERTY, false),
894 container,
895 "All known properties inherited from %s %s".printf (type, symbol.get_full_name ()));
896 write_known_symbols_note (symbol.get_children_by_type (NodeType.DELEGATE, false),
897 container,
898 "All known delegates inherited from %s %s".printf (type, symbol.get_full_name ()));
899 write_known_symbols_note (symbol.get_children_by_type (NodeType.STATIC_METHOD, false),
900 container,
901 "All known static methods inherited from %s %s".printf (type, symbol.get_full_name ()));
902 write_known_symbols_note (symbol.get_children_by_type (NodeType.METHOD, false),
903 container,
904 "All known methods inherited from %s %s".printf (type, symbol.get_full_name ()));
905 write_known_symbols_note (symbol.get_children_by_type (NodeType.SIGNAL, false),
906 container,
907 "All known signals inherited from %s %s".printf (type, symbol.get_full_name ()));
908 write_known_symbols_note (symbol.get_children_by_type (NodeType.FIELD, false),
909 container,
910 "All known fields inherited from %s %s".printf (type, symbol.get_full_name ()));
914 protected void write_child_namespaces (Api.Node node, Api.Node? parent) {
915 Vala.ArrayList<Namespace> namespaces = new Vala.ArrayList<Namespace> ();
916 this.fetch_subnamespace_names (node, namespaces);
918 if (namespaces.size == 0) {
919 return;
922 if (namespaces.size == 1) {
923 if (namespaces.get(0).name == null) {
924 return;
928 bool with_childs = parent != null && parent is Package;
930 writer.start_tag ("h3", {"class", css_title})
931 .text ("Namespaces:")
932 .end_tag ("h3");
933 writer.start_tag ("ul", {"class", css_inline_navigation});
934 foreach (Namespace child in namespaces) {
935 if (child.name != null) {
936 writer.start_tag ("li", {"class", cssresolver.resolve (child)});
937 writer.link (get_link (child, parent), child.name);
938 if (has_brief_description (child)) {
939 writer.text (" - ");
940 this.write_brief_description (child, parent);
942 writer.end_tag ("li");
943 if (with_childs == true) {
944 write_children (child, Api.NodeType.INTERFACE, "Interfaces", parent);
945 write_children (child, Api.NodeType.CLASS, "Classes", parent);
946 write_children (child, Api.NodeType.STRUCT, "Structs", parent);
947 write_children (child, Api.NodeType.ENUM, "Enums", parent);
948 write_children (child, Api.NodeType.ERROR_DOMAIN, "Error domains", parent);
949 write_children (child, Api.NodeType.CONSTANT, "Constants", parent);
950 write_children (child, Api.NodeType.DELEGATE, "Delegates", parent);
951 write_children (child, Api.NodeType.METHOD, "Methods", parent);
952 write_children (child, Api.NodeType.FIELD, "Fields", parent);
956 writer.end_tag ("ul");
959 protected void write_child_dependencies (Package package, Api.Node? parent) {
960 Vala.Collection<Package>? deps = package.get_full_dependency_list ();
961 if (deps.size == 0) {
962 return;
965 writer.start_tag ("h2", {"class", css_title})
966 .text ("Dependencies:")
967 .end_tag ("h2");
968 writer.start_tag ("ul", {"class", css_inline_navigation});
969 foreach (Package p in deps) {
970 string? link = this.get_link (p, parent);
971 if (link == null) {
972 writer.start_tag ("li", {"class", cssresolver.resolve (p), "id", p.name})
973 .text (p.name)
974 .end_tag ("li");
975 } else {
976 writer.start_tag ("li", {"class", cssresolver.resolve (p)});
977 writer.link (get_link (p, parent), p.name);
978 writer.end_tag ("li");
981 writer.end_tag ("ul");
984 protected void write_children (Api.Node node, Api.NodeType type, string type_string, Api.Node? container) {
985 var children = node.get_children_by_type (type);
986 if (children.size > 0) {
987 writer.start_tag ("h3", {"class", css_title})
988 .text (type_string)
989 .text (":")
990 .end_tag ("h3");
991 writer.start_tag ("ul", {"class", css_inline_navigation});
992 foreach (Api.Node child in children) {
993 writer.start_tag ("li", {"class", cssresolver.resolve (child)});
994 if (is_internal_node (child)) {
995 if (child is Symbol && ((Symbol) child).is_deprecated) {
996 writer.start_tag ("span", {"class", css_deprecated});
997 writer.link (get_link (child, container), child.name);
998 writer.end_tag ("span");
999 } else {
1000 writer.link (get_link (child, container), child.name);
1002 if (has_brief_description (child)) {
1003 writer.text (" - ");
1004 write_brief_description (child, container);
1006 } else {
1007 writer.start_tag ("span", {"class", css_leaf_code_definition});
1008 if (child is Symbol && ((Symbol) child).is_deprecated) {
1009 writer.start_tag ("span", {"class", css_deprecated});
1010 write_signature (child, container);
1011 writer.end_tag ("span");
1012 } else {
1013 write_signature (child, container);
1015 writer.end_tag ("span");
1017 writer.start_tag ("div", {"class", css_leaf_brief_description});
1018 write_brief_description (child, container);
1019 writer.end_tag ("div");
1021 writer.end_tag ("li");
1023 writer.end_tag ("ul");
1027 protected void write_image_block (Api.Node element) {
1028 if (element is Class || element is Interface || element is Struct) {
1029 unowned string format = (settings.use_svg_images ? "svg" : "png");
1030 var chart = new Charts.Hierarchy (image_factory, element);
1031 chart.save (this.get_img_path (element, format), format);
1033 writer.start_tag ("h2", {"class", css_title})
1034 .text ("Object Hierarchy:")
1035 .end_tag ("h2");
1037 writer.simple_tag ("img", {"class",
1038 css_diagram,
1039 "usemap",
1040 "#"+element.get_full_name (),
1041 "alt",
1042 "Object hierarchy for %s".printf (element.name),
1043 "src",
1044 this.get_img_path_html (element, format)});
1045 writer.add_usemap (chart);
1049 public void write_namespace_content (Namespace node, Api.Node? parent) {
1050 writer.start_tag ("div", {"class", css_style_content});
1051 writer.start_tag ("h1", {"class", css_title})
1052 .text (node.name == null ? "Global Namespace" : node.get_full_name ())
1053 .end_tag ("h1");
1054 writer.simple_tag ("hr", {"class", css_hr});
1055 writer.start_tag ("h2", {"class", css_title})
1056 .text ("Description:")
1057 .end_tag ("h2");
1059 this.write_documentation (node, parent);
1061 writer.start_tag ("h2", {"class", css_title})
1062 .text ("Content:")
1063 .end_tag ("h2");
1065 if (node.name == null) {
1066 this.write_child_namespaces ((Package) node.parent, parent);
1067 } else {
1068 this.write_child_namespaces (node, parent);
1071 write_children (node, Api.NodeType.INTERFACE, "Interfaces", parent);
1072 write_children (node, Api.NodeType.CLASS, "Classes", parent);
1073 write_children (node, Api.NodeType.STRUCT, "Structs", parent);
1074 write_children (node, Api.NodeType.ENUM, "Enums", parent);
1075 write_children (node, Api.NodeType.ERROR_DOMAIN, "Error domains", parent);
1076 write_children (node, Api.NodeType.CONSTANT, "Constants", parent);
1077 write_children (node, Api.NodeType.DELEGATE, "Delegates", parent);
1078 write_children (node, Api.NodeType.METHOD, "Functions", parent);
1079 write_children (node, Api.NodeType.FIELD, "Fields", parent);
1080 writer.end_tag ("div");
1083 protected void write_package_content (Package node, Api.Node? parent) {
1084 writer.start_tag ("div", {"class", css_style_content});
1085 writer.start_tag ("h1", {"class", css_title, "id", node.name})
1086 .text (node.name)
1087 .end_tag ("h1");
1088 writer.simple_tag ("hr", {"class", css_headline_hr});
1089 writer.start_tag ("h2", {"class", css_title})
1090 .text ("Description:")
1091 .end_tag ("h2");
1094 WikiPage? wikipage = (tree.wikitree == null)? null : tree.wikitree.search (wiki_index_name);
1095 if (wikipage != null) {
1096 _renderer.set_container (parent);
1097 _renderer.render (wikipage.documentation);
1100 writer.start_tag ("h2", {"class", css_title})
1101 .text ("Content:")
1102 .end_tag ("h2");
1104 this.write_child_namespaces (node, parent);
1106 foreach (Api.Node child in node.get_children_by_type (Api.NodeType.NAMESPACE)) {
1107 if (child.name == null) {
1108 write_children (child, Api.NodeType.INTERFACE, "Interfaces", parent);
1109 write_children (child, Api.NodeType.CLASS, "Classes", parent);
1110 write_children (child, Api.NodeType.STRUCT, "Structs", parent);
1111 write_children (child, Api.NodeType.ENUM, "Enums", parent);
1112 write_children (child, Api.NodeType.ERROR_DOMAIN, "Error domains", parent);
1113 write_children (child, Api.NodeType.CONSTANT, "Constants", parent);
1114 write_children (child, Api.NodeType.DELEGATE, "Delegates", parent);
1115 write_children (child, Api.NodeType.METHOD, "Functions", parent);
1116 write_children (child, Api.NodeType.FIELD, "Fields", parent);
1120 this.write_child_dependencies (node, parent);
1121 writer.end_tag ("div");
1124 protected void write_file_header (string css, string js, string? title) {
1125 writer.start_tag ("html");
1126 writer.start_tag ("head");
1127 writer.simple_tag ("meta", {"charset", "UTF-8"});
1128 if (title == null) {
1129 writer.start_tag ("title")
1130 .text ("Vala Binding Reference")
1131 .end_tag ("title");
1132 } else {
1133 writer.start_tag ("title")
1134 .text (title)
1135 .text (" &ndash; Vala Binding Reference")
1136 .end_tag ("title");
1138 writer.stylesheet_link (css);
1139 writer.javascript_link (js);
1140 writer.end_tag ("head");
1141 writer.start_tag ("body");
1142 writer.start_tag ("div", {"class", css_site_header});
1143 writer.text ("%s Reference Manual".printf (title == null ? "" : title));
1144 writer.end_tag ("div");
1145 writer.start_tag ("div", {"class", css_style_body});
1148 protected void write_file_footer () {
1149 writer.end_tag ("div");
1150 writer.simple_tag ("br");
1151 writer.start_tag ("div", {"class", "site_footer"});
1152 writer.text ("Generated by ");
1153 writer.link ("https://wiki.gnome.org/Projects/Valadoc", "<kbd>valadoc</kbd>");
1154 writer.end_tag ("div");
1155 writer.end_tag ("body");
1156 writer.end_tag ("html");