summaryrefslogtreecommitdiff
path: root/libvaladoc/html/basicdoclet.vala
diff options
context:
space:
mode:
Diffstat (limited to 'libvaladoc/html/basicdoclet.vala')
-rw-r--r--libvaladoc/html/basicdoclet.vala1159
1 files changed, 1159 insertions, 0 deletions
diff --git a/libvaladoc/html/basicdoclet.vala b/libvaladoc/html/basicdoclet.vala
new file mode 100644
index 000000000..8e51234a2
--- /dev/null
+++ b/libvaladoc/html/basicdoclet.vala
@@ -0,0 +1,1159 @@
+/* basicdoclet.vala
+ *
+ * Copyright (C) 2008-2012 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+using Valadoc.Content;
+using Valadoc.Api;
+
+
+
+public abstract class Valadoc.Html.BasicDoclet : Api.Visitor, Doclet {
+ public Html.LinkHelper linker {
+ protected set;
+ get;
+ }
+
+ public Settings settings {
+ protected set;
+ get;
+ }
+
+ public string wiki_index_name {
+ default = "index.valadoc";
+ protected set;
+ get;
+ }
+
+ protected Api.Tree tree;
+ protected HtmlRenderer _renderer;
+ protected Html.MarkupWriter writer;
+ protected Html.CssClassResolver cssresolver;
+ protected Charts.Factory image_factory;
+ protected ErrorReporter reporter;
+ protected string package_list_link = "../index.html";
+
+ // CSS:
+ private const string css_inline_navigation = "navi_inline";
+ private const string css_package_index = "package_index";
+ private const string css_brief_description = "brief_description";
+ private const string css_description = "description";
+ private const string css_known_list = "known_nodes";
+ private const string css_leaf_brief_description = "leaf_brief_description";
+ private const string css_leaf_code_definition = "leaf_code_definition";
+
+ private const string css_box_headline_text = "text";
+ private const string css_box_headline_toggle = "toggle";
+ private const string css_box_headline = "headline";
+ private const string css_box_content = "content";
+ private const string css_box_column = "column";
+ private const string css_box = "box";
+
+ private const string css_namespace_note = "namespace_note";
+ private const string css_package_note = "package_note";
+
+ private const string css_site_header = "site_header";
+ private const string css_navi = "navi_main";
+ private const string css_navi_hr = "navi_hr";
+ private const string css_errordomain_table_name = "main_errordomain_table_name";
+ private const string css_errordomain_table_text = "main_errordomain_table_text";
+ private const string css_errordomain_table = "main_errordomain_table";
+ private const string css_enum_table_name = "main_enum_table_name";
+ private const string css_enum_table_text = "main_enum_table_text";
+ private const string css_enum_table = "main_enum_table";
+ private const string css_diagram = "main_diagram";
+ private const string css_see_list = "main_see_list";
+ private const string css_wiki_table = "main_table";
+ private const string css_notification_area = "main_notification";
+ private const string css_source_sample = "main_sourcesample";
+ private const string css_exception_table = "main_parameter_table";
+ private const string css_parameter_table_text = "main_parameter_table_text";
+ private const string css_parameter_table_name = "main_parameter_table_name";
+ private const string css_parameter_table = "main_parameter_table";
+ private const string css_title = "main_title";
+ private const string css_other_type = "main_other_type";
+ private const string css_basic_type = "main_basic_type";
+ private const string css_keyword = "main_keyword";
+ private const string css_optional_parameter = "main_optional_parameter";
+ private const string css_code_definition = "main_code_definition";
+ private const string css_headline_hr = "main_hr";
+ private const string css_hr = "main_hr";
+ private const string css_list_errdom = "main_list_errdom";
+ private const string css_list_en = "main_list_en";
+ private const string css_list_ns = "main_list_ns";
+ private const string css_list_cl = "main_list_cl";
+ private const string css_list_iface = "main_list_iface";
+ private const string css_list_stru = "main_list_stru";
+ private const string css_list_field = "main_list_field";
+ private const string css_list_prop = "main_list_prop";
+ private const string css_list_del = "main_list_del";
+ private const string css_list_sig = "main_list_sig";
+ private const string css_list_m = "main_list_m";
+ private const string css_style_navigation = "site_navigation";
+ private const string css_style_content = "site_content";
+ private const string css_style_body = "site_body";
+ private const string css_deprecated = "deprecated";
+
+ public virtual void process (Settings settings, Api.Tree tree, ErrorReporter reporter) {
+ this.reporter = reporter;
+ this.settings = settings;
+ this.tree = tree;
+
+ this.cssresolver = new CssClassResolver ();
+ this.linker = new LinkHelper ();
+
+ _renderer = new HtmlRenderer (settings, this.linker, this.cssresolver);
+ this.image_factory = new SimpleChartFactory (settings, linker);
+ }
+
+
+ // paths:
+ protected string? get_link (Api.Node to, Api.Node from) {
+ return linker.get_relative_link (from, to, settings);
+ }
+
+ protected virtual string get_img_path_html (Api.Node element, string type) {
+ return Path.build_filename ("img", element.get_full_name () + "." + type);
+ }
+
+ protected virtual string get_img_path (Api.Node element, string type) {
+ return Path.build_filename (settings.path, element.package.name, "img",
+ element.get_full_name () + "." + type);
+ }
+
+ protected virtual string get_icon_directory () {
+ return "..";
+ }
+
+
+ private TypeSymbol? unpack_type_reference (TypeReference? type_reference) {
+ Api.Item pos = type_reference;
+
+ while (pos != null) {
+ if (pos is TypeReference) {
+ pos = ((TypeReference) pos).data_type;
+ } else if (pos is Api.Array) {
+ pos = ((Api.Array) pos).data_type;
+ } else if (pos is Pointer) {
+ pos = ((Pointer) pos).data_type;
+ } else {
+ assert (pos is TypeSymbol);
+ return (TypeSymbol) pos;
+ }
+ }
+
+ return null;
+ }
+
+
+ protected void write_navi_entry_html_template (string style, string content, bool is_deprecated) {
+ writer.start_tag ("li", {"class", style});
+
+ if (is_deprecated) {
+ writer.start_tag ("span", {"class", css_deprecated});
+ writer.text (content);
+ writer.end_tag ("span");
+ } else {
+ writer.text (content);
+ }
+
+ writer.end_tag ("li");
+ }
+
+ protected void write_navi_entry_html_template_with_link (string style, string link,
+ string content, bool is_deprecated)
+ {
+ writer.start_tag ("li", {"class", style});
+
+ if (is_deprecated) {
+ writer.start_tag ("span", {"class", css_deprecated});
+ writer.link (link, content);
+ writer.end_tag ("span");
+ } else {
+ writer.link (link, content);
+ }
+
+ writer.end_tag ("li");
+ }
+
+ protected void write_navi_entry (Api.Node element, Api.Node? pos, string style,
+ bool link, bool full_name = false)
+ {
+ string name;
+
+ if (full_name == true && element is Namespace) {
+ string tmp = element.get_full_name();
+ name = (tmp == null)? "Global Namespace" : tmp;
+ } else {
+ string tmp = element.name;
+ name = (tmp == null)? "Global Namespace" : tmp;
+ }
+
+ bool is_deprecated = element is Symbol && ((Symbol) element).is_deprecated;
+
+ if (link == true) {
+ this.write_navi_entry_html_template_with_link (style,
+ this.get_link (element, pos),
+ name,
+ is_deprecated);
+ } else {
+ this.write_navi_entry_html_template (style, name, is_deprecated);
+ }
+ }
+
+ protected void write_wiki_pages (Api.Tree tree, string css_path_wiki, string js_path_wiki,
+ string contentp)
+ {
+ if (tree.wikitree == null) {
+ return ;
+ }
+
+ if (tree.wikitree == null) {
+ return ;
+ }
+
+ Gee.Collection<WikiPage> pages = tree.wikitree.get_pages();
+ if (pages.size == 0) {
+ return ;
+ }
+
+ DirUtils.create (contentp, 0777);
+
+ DirUtils.create (Path.build_filename (contentp, "img"), 0777);
+
+ foreach (WikiPage page in pages) {
+ if (page.name != wiki_index_name) {
+ write_wiki_page (page, contentp, css_path_wiki, js_path_wiki, this.settings.pkg_name);
+ }
+ }
+ }
+
+ protected virtual void write_wiki_page (WikiPage page, string contentp, string css_path,
+ string js_path, string pkg_name)
+ {
+ GLib.FileStream file = GLib.FileStream.open (
+ Path.build_filename (contentp, page.name.substring (0, page.name.length-7).replace ("/", ".")+"htm"),
+ "w");
+
+ writer = new MarkupWriter (file);
+ _renderer.set_writer (writer);
+ this.write_file_header (css_path, js_path, pkg_name);
+ _renderer.set_container (page);
+ _renderer.render (page.documentation);
+ this.write_file_footer ();
+ }
+
+ protected void write_navi_top_entry (Api.Node element, Api.Node? parent) {
+ string style = cssresolver.resolve (element);
+
+ writer.start_tag ("ul", {"class", css_navi});
+
+ if (element == parent || parent == null) {
+ this.write_navi_entry (element, parent, style, false);
+ } else {
+ this.write_navi_entry (element, parent, style, true);
+ }
+
+ writer.end_tag ("ul");
+ writer.simple_tag ("hr", {"class", css_navi_hr});
+ }
+
+ protected void write_top_element_template (string link) {
+ writer.start_tag ("ul", {"class", css_navi});
+ writer.start_tag ("li", {"class", css_package_index});
+ writer.link (link, "Packages");
+ writer.end_tag ("li");
+ writer.end_tag ("ul");
+ writer.simple_tag ("hr", {"class", css_navi_hr});
+ }
+
+ protected void write_top_elements (Api.Node element, Api.Node? parent) {
+ Gee.ArrayList<Api.Node> lst = new Gee.ArrayList<Api.Node> ();
+ Api.Node pos = element;
+
+ this.write_top_element_template (package_list_link);
+
+ while (pos != null) {
+ lst.add (pos);
+ pos = (Api.Node)pos.parent;
+ }
+
+ for (int i = lst.size-1; i >= 0 ; i--) {
+ Api.Node el = lst.get (i);
+
+ if (el.name != null) {
+ this.write_navi_top_entry (el, parent);
+ }
+ }
+ }
+
+ protected void fetch_subnamespace_names (Api.Node node, Gee.ArrayList<Namespace> namespaces) {
+ Gee.ArrayList<Api.Node> sorted_list = new Gee.ArrayList<Api.Node> ();
+ sorted_list.add_all (node.get_children_by_type (Api.NodeType.NAMESPACE));
+ sorted_list.sort ();
+
+ foreach (Api.Node child in sorted_list) {
+ namespaces.add ((Namespace) child);
+ this.fetch_subnamespace_names (child, namespaces);
+ }
+ }
+
+ protected void write_navi_package (Package package) {
+ Gee.ArrayList<Namespace> ns_list = new Gee.ArrayList<Namespace> ();
+ this.fetch_subnamespace_names (package, ns_list);
+
+ writer.start_tag ("div", {"class", css_style_navigation});
+ write_top_elements (package, package);
+ writer.start_tag ("ul", {"class", css_navi});
+
+ Namespace globals = null;
+
+ foreach (Namespace ns in ns_list) {
+ if (ns.name == null) {
+ globals = ns;
+ } else {
+ this.write_navi_entry (ns, package, cssresolver.resolve (ns), true, true);
+ }
+ }
+
+ if (globals != null) {
+ write_navi_children (globals, Api.NodeType.ERROR_CODE, package);
+ write_navi_children (globals, Api.NodeType.ENUM_VALUE, package);
+ write_navi_children (globals, Api.NodeType.ENUM, package);
+ write_navi_children (globals, Api.NodeType.INTERFACE, package);
+ write_navi_children (globals, Api.NodeType.CLASS, package);
+ write_navi_children (globals, Api.NodeType.STRUCT, package);
+ write_navi_children (globals, Api.NodeType.CONSTANT, package);
+ write_navi_children (globals, Api.NodeType.PROPERTY, package);
+ write_navi_children (globals, Api.NodeType.DELEGATE, package);
+ write_navi_children (globals, Api.NodeType.STATIC_METHOD, package);
+ write_navi_children (globals, Api.NodeType.CREATION_METHOD, package);
+ write_navi_children (globals, Api.NodeType.METHOD, package);
+ write_navi_children (globals, Api.NodeType.SIGNAL, package);
+ write_navi_children (globals, Api.NodeType.FIELD, package);
+ }
+
+ writer.end_tag ("ul");
+ writer.end_tag ("div");
+ }
+
+ protected void write_navi_symbol (Api.Node node) {
+ writer.start_tag ("div", {"class", css_style_navigation});
+ write_top_elements (node, node);
+ write_navi_symbol_inline (node, node);
+ writer.end_tag ("div");
+ }
+
+ protected void write_navi_leaf_symbol (Api.Node node) {
+ writer.start_tag ("div", {"class", css_style_navigation});
+ write_top_elements ((Api.Node) node.parent, node);
+ write_navi_symbol_inline ((Api.Node) node.parent, node);
+ writer.end_tag ("div");
+ }
+
+ protected void write_navi_symbol_inline (Api.Node node, Api.Node? parent) {
+ writer.start_tag ("ul", {"class", css_navi});
+ write_navi_children (node, Api.NodeType.NAMESPACE, parent);
+ write_navi_children (node, Api.NodeType.ERROR_CODE, parent);
+ write_navi_children (node, Api.NodeType.ENUM_VALUE, parent);
+ write_navi_children (node, Api.NodeType.ENUM, parent);
+ write_navi_children (node, Api.NodeType.INTERFACE, parent);
+ write_navi_children (node, Api.NodeType.CLASS, parent);
+ write_navi_children (node, Api.NodeType.STRUCT, parent);
+ write_navi_children (node, Api.NodeType.CONSTANT, parent);
+ write_navi_children (node, Api.NodeType.PROPERTY, parent);
+ write_navi_children (node, Api.NodeType.DELEGATE, parent);
+ write_navi_children (node, Api.NodeType.STATIC_METHOD, parent);
+ write_navi_children (node, Api.NodeType.CREATION_METHOD, parent);
+ write_navi_children (node, Api.NodeType.METHOD, parent);
+ write_navi_children (node, Api.NodeType.SIGNAL, parent);
+ write_navi_children (node, Api.NodeType.FIELD, parent);
+ writer.end_tag ("ul");
+ }
+
+ protected void write_navi_children (Api.Node node, Api.NodeType type, Api.Node? parent) {
+ var children = node.get_children_by_type (type);
+ children.sort ();
+ foreach (Api.Node child in children) {
+ write_navi_entry (child, parent, cssresolver.resolve (child), child != parent);
+ }
+ }
+
+ protected void write_package_note (Api.Node element) {
+ string package = element.package.name;
+ if (package == null) {
+ return;
+ }
+
+ writer.start_tag ("div", {"class", css_package_note});
+ writer.start_tag ("b")
+ .text ("Package:")
+ .end_tag ("b");
+ writer.text (" ")
+ .start_tag ("a", {"href", get_link (element.package, element)})
+ .text (package)
+ .end_tag ("a");
+ writer.end_tag ("div");
+ }
+
+ protected void write_namespace_note (Api.Node element) {
+ Namespace? ns = element.nspace;
+ if (ns == null) {
+ return;
+ }
+
+ if (ns.name == null) {
+ return;
+ }
+
+ writer.start_tag ("div", {"class", css_namespace_note});
+ writer.start_tag ("b")
+ .text ("Namespace:")
+ .end_tag ("b");
+ writer.text (" ")
+ .start_tag ("a", {"href", get_link (ns, element)})
+ .text (ns.get_full_name())
+ .end_tag ("a");
+ writer.end_tag ("div");
+ }
+
+ private bool has_brief_description (Api.Node element) {
+ return element.documentation != null;
+ }
+
+ private void write_brief_description (Api.Node element , Api.Node? pos) {
+ Content.Comment? doctree = element.documentation;
+ if (doctree == null) {
+ return;
+ }
+
+ Gee.List<Block> description = doctree.content;
+ if (description.size > 0) {
+ writer.start_tag ("span", {"class", css_brief_description});
+
+ _renderer.set_container (pos);
+ _renderer.set_owner (element);
+ _renderer.render_children (description.get (0));
+ _renderer.set_owner (null);
+
+ writer.end_tag ("span");
+ }
+ }
+
+ private void write_documentation (Api.Node element , Api.Node? pos) {
+ Content.Comment? doctree = element.documentation;
+ bool is_deprecated = (element is Symbol && ((Symbol) element).is_deprecated);
+
+ // avoid empty divs
+ if (doctree == null && !is_deprecated) {
+ return;
+ }
+
+
+ writer.start_tag ("div", {"class", css_description});
+ _renderer.set_owner (element);
+
+ // deprecation warning:
+ if (is_deprecated) {
+ Symbol symbol = (Symbol) element;
+ Attribute? version;
+ Attribute? deprecated;
+ AttributeArgument? replacement;
+ AttributeArgument? since;
+ if ((version = symbol.get_attribute ("Version")) != null) {
+ replacement = version.get_argument ("replacement");
+ since = version.get_argument ("deprecated_since");
+ } else if ((deprecated = symbol.get_attribute ("Deprecated")) != null) {
+ replacement = deprecated.get_argument ("replacement");
+ since = deprecated.get_argument ("version");
+ } else {
+ assert_not_reached ();
+ }
+
+ writer.start_tag ("p");
+ writer.start_tag ("b");
+ writer.text ("Warning:");
+ writer.end_tag ("b");
+ writer.text (" %s is deprecated".printf (element.name));
+
+ if (since != null) {
+ writer.text (" since %s".printf (since.get_value_as_string ()));
+ }
+
+ writer.text (".");
+
+ if (replacement != null) {
+ string replacement_name = replacement.get_value_as_string ();
+ Api.Node? replacement_node = tree.search_symbol_str (pos,
+ replacement_name.substring (1, replacement_name.length - 2));
+
+ writer.text (" Use ");
+ if (replacement_node == null) {
+ writer.text (replacement_name);
+ } else {
+ string? link = get_link (replacement_node, pos);
+ if (link != null) {
+ string css = cssresolver.resolve (replacement_node);
+ writer.link (link, replacement_node.get_full_name (), css);
+ } else {
+ writer.start_tag ("code")
+ .text (replacement_node.get_full_name ())
+ .end_tag ("code");
+ }
+ }
+ writer.text (".");
+ }
+
+ writer.end_tag ("p");
+ }
+
+ if (doctree != null) {
+ _renderer.set_container (pos);
+ _renderer.render (doctree);
+ }
+
+
+ _renderer.set_owner (null);
+ writer.end_tag ("div");
+ }
+
+ private void write_attributes (Api.Symbol element, Api.Node? pos) {
+ writer.set_wrap (false);
+ _renderer.set_container (pos);
+ foreach (Attribute att in element.get_attributes ()) {
+ _renderer.render (att.signature);
+ writer.simple_tag ("br");
+ }
+ writer.set_wrap (true);
+ }
+
+ private void write_signature (Api.Node element , Api.Node? pos) {
+ writer.set_wrap (false);
+ _renderer.set_container (pos);
+ _renderer.render (element.signature);
+ writer.set_wrap (true);
+ }
+
+ protected bool is_internal_node (Api.Node node) {
+ return node is Package
+ || node is Api.Namespace
+ || node is Api.Interface
+ || node is Api.Class
+ || node is Api.Struct
+ || node is Api.Enum
+ || node is Api.EnumValue
+ || node is Api.ErrorDomain
+ || node is Api.ErrorCode;
+ }
+
+ public void write_navi_packages_inline (Api.Tree tree) {
+ writer.start_tag ("ul", {"class", css_navi});
+ foreach (Package pkg in tree.get_package_list()) {
+ if (pkg.is_browsable (settings)) {
+ writer.start_tag ("li", {"class", cssresolver.resolve (pkg)});
+ writer.link (linker.get_package_link (pkg, settings), pkg.name);
+ // brief description
+ writer.end_tag ("li");
+ } else {
+ writer.start_tag ("li", {"class", cssresolver.resolve (pkg)});
+ writer.text (pkg.name);
+ writer.end_tag ("li");
+ }
+ }
+ writer.end_tag ("ul");
+ }
+
+ public void write_navi_packages (Api.Tree tree) {
+ writer.start_tag ("div", {"class", css_style_navigation});
+ this.write_navi_packages_inline (tree);
+ writer.end_tag ("div");
+ }
+
+ public void write_package_index_content (Api.Tree tree) {
+ writer.start_tag ("div", {"class", css_style_content});
+ writer.start_tag ("h1", {"class", css_title})
+ .text ("Packages:")
+ .end_tag ("h1");
+ writer.simple_tag ("hr", {"class", css_headline_hr});
+
+ WikiPage? wikiindex = (tree.wikitree == null)
+ ? null
+ : tree.wikitree.search (wiki_index_name);
+ if (wikiindex != null) {
+ _renderer.set_container (wikiindex);
+ _renderer.render (wikiindex.documentation);
+ }
+
+ writer.start_tag ("h2", {"class", css_title})
+ .text ("Content:")
+ .end_tag ("h2");
+ writer.start_tag ("h3", {"class", css_title})
+ .text ("Packages:")
+ .end_tag ("h3");
+ this.write_navi_packages_inline (tree);
+ writer.end_tag ("div");
+ }
+
+ private uint html_id_counter = 0;
+
+ private inline Gee.Collection<Api.Node> get_accessible_nodes_from_list (Gee.Collection<Api.Node> nodes) {
+ var list = new Gee.ArrayList<Api.Node> ();
+
+ foreach (var node in nodes) {
+ if (node.is_browsable(_settings)) {
+ list.add (node);
+ }
+ }
+
+ return list;
+ }
+
+ private void write_known_symbols_note (Gee.Collection<Api.Node> nodes2, Api.Node container, string headline) {
+ var nodes = get_accessible_nodes_from_list (nodes2);
+ if (nodes.size == 0) {
+ return ;
+ }
+
+ // Box:
+ var html_id = "box-content-" + html_id_counter.to_string ();
+ html_id_counter++;
+
+
+ writer.start_tag ("div", {"class", css_box});
+
+ // headline:
+ writer.start_tag ("div", {"class", css_box_headline, "onclick", "toggle_box (this, '%s')".printf (html_id)})
+ .text (headline)
+ .end_tag ("div");
+ //writer.start_tag ("div", {"class", css_box_headline_text, "onclick", "toggle_box (this, '%s')".printf (html_id)})
+ // .text (headline)
+ // .end_tag ("div");
+ //writer.start_tag ("div", {"class", css_box_headline_toggle});
+ //writer.start_tag ("img", {"onclick",
+ // "toggle_box (this, '" + html_id + "')",
+ // "src",
+ // Path.build_filename (get_icon_directory (),
+ // "coll_open.png")});
+ //writer.raw_text ("&nbsp;");
+ //writer.end_tag ("div");
+ //writer.end_tag ("div");
+
+
+ // content:
+ int[] list_sizes = {0, 0, 0};
+ list_sizes[0] = nodes.size;
+ list_sizes[2] = list_sizes[0]/3;
+ list_sizes[0] -= list_sizes[2];
+ list_sizes[1] = list_sizes[0]/2;
+ list_sizes[0] -= list_sizes[1];
+
+ writer.start_tag ("div", {"class", css_box_content, "id", html_id});
+
+ var iter = nodes.iterator ();
+
+ for (int i = 0; i < list_sizes.length; i++) {
+ writer.start_tag ("div", {"class", css_box_column});
+ writer.start_tag ("ul", {"class", css_inline_navigation});
+
+ for (int p = 0; p < list_sizes[i] && iter.next (); p++) {
+ var node = iter.get ();
+ writer.start_tag ("li", {"class", cssresolver.resolve (node)});
+ string link = get_link (node, container);
+ if (link == null) {
+ writer.text (node.name);
+ } else {
+ writer.link (link, node.name);
+ }
+ writer.end_tag ("li");
+ }
+
+ writer.end_tag ("ul");
+ writer.end_tag ("div");
+ }
+
+ writer.end_tag ("div"); // end content
+
+ writer.end_tag ("div"); // end box
+ }
+
+ public void write_symbol_content (Api.Node node) {
+ writer.start_tag ("div", {"class", css_style_content});
+ writer.start_tag ("h1", {"class", css_title})
+ .text (node.name)
+ .end_tag ("h1");
+ writer.simple_tag ("hr", {"class", css_headline_hr});
+ this.write_image_block (node);
+ writer.start_tag ("h2", {"class", css_title})
+ .text ("Description:")
+ .end_tag ("h2");
+ writer.start_tag ("div", {"class", css_code_definition});
+ if (node is Symbol) {
+ this.write_attributes ((Symbol) node, node);
+ }
+ this.write_signature (node, node);
+ writer.end_tag ("div");
+ this.write_documentation (node, node);
+
+ if (node is Class) {
+ var cl = node as Class;
+ write_known_symbols_note (cl.get_known_child_classes (),
+ cl,
+ "All known sub-classes:");
+ write_known_symbols_note (cl.get_known_derived_interfaces (),
+ cl,
+ "Required by:");
+ } else if (node is Interface) {
+ var iface = node as Interface;
+ write_known_symbols_note (iface.get_known_implementations (),
+ iface,
+ "All known implementing classes:");
+ write_known_symbols_note (iface.get_known_related_interfaces (),
+ iface,
+ "All known sub-interfaces:");
+ } else if (node is Struct) {
+ var stru = node as Struct;
+ write_known_symbols_note (stru.get_known_child_structs (),
+ stru,
+ "All known sub-structs:");
+ }
+
+ if (node.parent is Namespace) {
+ writer.simple_tag ("br");
+ write_namespace_note (node);
+ write_package_note (node);
+ }
+
+ if (!(node is Method || node is Delegate || node is Api.Signal)) {
+ // avoids exception listings & implementations
+
+ if (node.has_children ({
+ Api.NodeType.ERROR_CODE,
+ Api.NodeType.ENUM_VALUE,
+ Api.NodeType.CREATION_METHOD,
+ Api.NodeType.STATIC_METHOD,
+ Api.NodeType.CLASS,
+ Api.NodeType.STRUCT,
+ Api.NodeType.ENUM,
+ Api.NodeType.DELEGATE,
+ Api.NodeType.METHOD,
+ Api.NodeType.SIGNAL,
+ Api.NodeType.PROPERTY,
+ Api.NodeType.FIELD,
+ Api.NodeType.CONSTANT
+ }))
+ {
+ writer.start_tag ("h2", {"class", css_title}).text ("Content:").end_tag ("h2");
+ write_children (node, Api.NodeType.ERROR_CODE, "Error codes", node);
+ write_children (node, Api.NodeType.ENUM_VALUE, "Enum values", node);
+ write_children (node, Api.NodeType.CLASS, "Classes", node);
+ write_children (node, Api.NodeType.STRUCT, "Structs", node);
+ write_children (node, Api.NodeType.ENUM, "Enums", node);
+ write_children (node, Api.NodeType.CONSTANT, "Constants", node);
+ write_children (node, Api.NodeType.PROPERTY, "Properties", node);
+ write_children (node, Api.NodeType.DELEGATE, "Delegates", node);
+ write_children (node, Api.NodeType.STATIC_METHOD, "Static methods", node);
+ write_children (node, Api.NodeType.CREATION_METHOD, "Creation methods", node);
+ write_children (node, Api.NodeType.METHOD, "Methods", node);
+ write_children (node, Api.NodeType.SIGNAL, "Signals", node);
+ write_children (node, Api.NodeType.FIELD, "Fields", node);
+ }
+ }
+
+ if (node is Class) {
+ write_inherited_symbols_note_for_class ((Class) node, node);
+ } else if (node is Interface) {
+ write_inherited_symbols_note_for_interface ((Interface) node, node);
+ } else if (node is Struct) {
+ write_inherited_symbols_note_for_struct ((Struct) node, node);
+ }
+
+ writer.end_tag ("div");
+ }
+
+ private static NodeType[] inheritable_members = {
+ NodeType.CONSTANT,
+ NodeType.PROPERTY,
+ NodeType.DELEGATE,
+ NodeType.STATIC_METHOD,
+ NodeType.METHOD,
+ NodeType.SIGNAL,
+ NodeType.FIELD
+ };
+
+ private inline bool has_visible_inheritable_children (TypeSymbol symbol) {
+ return symbol.has_visible_children_by_types (inheritable_members, _settings);
+ }
+
+ private void write_inherited_members_headline () {
+ writer.start_tag ("h3", {"class", css_title})
+ .text ("Inherited Members:")
+ .end_tag ("h3");
+ }
+
+ private void write_inherited_symbols_note_for_class (Class cl, Api.Node container) {
+ bool headline_printed = false;
+
+ // class hierarchy:
+ Class base_class = unpack_type_reference (cl.base_type) as Class;
+ while (base_class != null) {
+ if (!headline_printed && has_visible_inheritable_children (base_class)) {
+ write_inherited_members_headline ();
+ headline_printed = true;
+ }
+
+ write_inherited_symbols_note (base_class, "class", container);
+ base_class = unpack_type_reference (base_class.base_type) as Class;
+ }
+
+
+ // implemented interfaces
+ Gee.LinkedList<Interface> printed_interfaces = new Gee.LinkedList<Interface> ();
+ foreach (TypeReference iface_ref in cl.get_full_implemented_interface_list ()) {
+ Interface iface = (Interface) unpack_type_reference (iface_ref);
+
+ if (!headline_printed && has_visible_inheritable_children (iface)) {
+ write_inherited_members_headline ();
+ headline_printed = true;
+ } else if (printed_interfaces.contains (iface)) {
+ continue ;
+ }
+
+ write_inherited_symbols_note (iface, "interface", container);
+ printed_interfaces.add (iface);
+ }
+ }
+
+ private void write_inherited_symbols_note_for_interface (Interface iface, Api.Node container) {
+ bool headline_printed = false;
+
+ // class hierarchy:
+ Class base_class = unpack_type_reference (iface.base_type) as Class;
+ while (base_class != null) {
+ if (!headline_printed && has_visible_inheritable_children (base_class)) {
+ write_inherited_members_headline ();
+ headline_printed = true;
+ }
+
+ write_inherited_symbols_note (base_class, "class", container);
+ base_class = unpack_type_reference (base_class.base_type) as Class;
+ }
+
+
+ // interfaces:
+ Gee.LinkedList<Interface> printed_interfaces = new Gee.LinkedList<Interface> ();
+ foreach (TypeReference pre_ref in iface.get_full_implemented_interface_list ()) {
+ Interface pre = (Interface) unpack_type_reference (pre_ref);
+
+ if (!headline_printed && has_visible_inheritable_children (pre)) {
+ write_inherited_members_headline ();
+ headline_printed = true;
+ } else if (printed_interfaces.contains (pre)) {
+ continue ;
+ }
+
+ write_inherited_symbols_note (pre, "interface", container);
+ printed_interfaces.add (pre);
+ }
+ }
+
+ private void write_inherited_symbols_note_for_struct (Struct str, Api.Node container) {
+ Struct base_struct = unpack_type_reference (str.base_type) as Struct;
+ if (base_struct != null && has_visible_inheritable_children (base_struct)) {
+ write_inherited_members_headline ();
+ write_inherited_symbols_note (base_struct, "struct", container);
+ }
+ }
+
+ private void write_inherited_symbols_note (TypeSymbol symbol, string type, Api.Node container) {
+ write_known_symbols_note (symbol.get_children_by_types (inheritable_members, false),
+ container,
+ "All known members inherited from %s %s".printf (type, symbol.get_full_name ()));
+
+ /*
+ write_known_symbols_note (symbol.get_children_by_type (NodeType.CONSTANT, false),
+ container,
+ "All known constants inherited from %s %s".printf (type, symbol.get_full_name ()));
+ write_known_symbols_note (symbol.get_children_by_type (NodeType.PROPERTY, false),
+ container,
+ "All known properties inherited from %s %s".printf (type, symbol.get_full_name ()));
+ write_known_symbols_note (symbol.get_children_by_type (NodeType.DELEGATE, false),
+ container,
+ "All known delegates inherited from %s %s".printf (type, symbol.get_full_name ()));
+ write_known_symbols_note (symbol.get_children_by_type (NodeType.STATIC_METHOD, false),
+ container,
+ "All known static methods inherited from %s %s".printf (type, symbol.get_full_name ()));
+ write_known_symbols_note (symbol.get_children_by_type (NodeType.METHOD, false),
+ container,
+ "All known methods inherited from %s %s".printf (type, symbol.get_full_name ()));
+ write_known_symbols_note (symbol.get_children_by_type (NodeType.SIGNAL, false),
+ container,
+ "All known signals inherited from %s %s".printf (type, symbol.get_full_name ()));
+ write_known_symbols_note (symbol.get_children_by_type (NodeType.FIELD, false),
+ container,
+ "All known fields inherited from %s %s".printf (type, symbol.get_full_name ()));
+ */
+ }
+
+ protected void write_child_namespaces (Api.Node node, Api.Node? parent) {
+ Gee.ArrayList<Namespace> namespaces = new Gee.ArrayList<Namespace> ();
+ this.fetch_subnamespace_names (node, namespaces);
+
+ if (namespaces.size == 0) {
+ return;
+ }
+
+ if (namespaces.size == 1) {
+ if (namespaces.get(0).name == null) {
+ return;
+ }
+ }
+
+ bool with_childs = parent != null && parent is Package;
+
+ writer.start_tag ("h3", {"class", css_title})
+ .text ("Namespaces:")
+ .end_tag ("h3");
+ writer.start_tag ("ul", {"class", css_inline_navigation});
+ foreach (Namespace child in namespaces) {
+ if (child.name != null) {
+ writer.start_tag ("li", {"class", cssresolver.resolve (child)});
+ writer.link (get_link (child, parent), child.name);
+ if (has_brief_description (child)) {
+ writer.text (" - ");
+ this.write_brief_description (child, parent);
+ }
+ writer.end_tag ("li");
+ if (with_childs == true) {
+ write_children (child, Api.NodeType.INTERFACE, "Interfaces", parent);
+ write_children (child, Api.NodeType.CLASS, "Classes", parent);
+ write_children (child, Api.NodeType.STRUCT, "Structs", parent);
+ write_children (child, Api.NodeType.ENUM, "Enums", parent);
+ write_children (child, Api.NodeType.ERROR_DOMAIN, "Error domains", parent);
+ write_children (child, Api.NodeType.CONSTANT, "Constants", parent);
+ write_children (child, Api.NodeType.DELEGATE, "Delegates", parent);
+ write_children (child, Api.NodeType.METHOD, "Methods", parent);
+ write_children (child, Api.NodeType.FIELD, "Fields", parent);
+ }
+ }
+ }
+ writer.end_tag ("ul");
+ }
+
+ protected void write_child_dependencies (Package package, Api.Node? parent) {
+ Gee.Collection<Package>? deps = package.get_full_dependency_list ();
+ if (deps.size == 0) {
+ return;
+ }
+
+ writer.start_tag ("h2", {"class", css_title})
+ .text ("Dependencies:")
+ .end_tag ("h2");
+ writer.start_tag ("ul", {"class", css_inline_navigation});
+ foreach (Package p in deps) {
+ string? link = this.get_link (p, parent);
+ if (link == null) {
+ writer.start_tag ("li", {"class", cssresolver.resolve (p), "id", p.name})
+ .text (p.name)
+ .end_tag ("li");
+ } else {
+ writer.start_tag ("li", {"class", cssresolver.resolve (p)});
+ writer.link (get_link (p, parent), p.name);
+ writer.end_tag ("li");
+ }
+ }
+ writer.end_tag ("ul");
+ }
+
+ protected void write_children (Api.Node node, Api.NodeType type, string type_string, Api.Node? container) {
+ var children = node.get_children_by_type (type);
+ if (children.size > 0) {
+ writer.start_tag ("h3", {"class", css_title})
+ .text (type_string)
+ .text (":")
+ .end_tag ("h3");
+ writer.start_tag ("ul", {"class", css_inline_navigation});
+ foreach (Api.Node child in children) {
+ writer.start_tag ("li", {"class", cssresolver.resolve (child)});
+ if (is_internal_node (child)) {
+ if (child is Symbol && ((Symbol) child).is_deprecated) {
+ writer.start_tag ("span", {"class", css_deprecated});
+ writer.link (get_link (child, container), child.name);
+ writer.end_tag ("span");
+ } else {
+ writer.link (get_link (child, container), child.name);
+ }
+ if (has_brief_description (child)) {
+ writer.text (" - ");
+ write_brief_description (child, container);
+ }
+ } else {
+ writer.start_tag ("span", {"class", css_leaf_code_definition});
+ if (child is Symbol && ((Symbol) child).is_deprecated) {
+ writer.start_tag ("span", {"class", css_deprecated});
+ write_signature (child, container);
+ writer.end_tag ("span");
+ } else {
+ write_signature (child, container);
+ }
+ writer.end_tag ("span");
+
+ writer.start_tag ("div", {"class", css_leaf_brief_description});
+ write_brief_description (child, container);
+ writer.end_tag ("div");
+ }
+ writer.end_tag ("li");
+ }
+ writer.end_tag ("ul");
+ }
+ }
+
+ protected void write_image_block (Api.Node element) {
+ if (element is Class || element is Interface || element is Struct) {
+ unowned string format = (settings.use_svg_images ? "svg" : "png");
+ var chart = new Charts.Hierarchy (image_factory, element);
+ chart.save (this.get_img_path (element, format), format);
+
+ writer.start_tag ("h2", {"class", css_title})
+ .text ("Object Hierarchy:")
+ .end_tag ("h2");
+
+ writer.simple_tag ("img", {"class",
+ css_diagram,
+ "usemap",
+ "#"+element.get_full_name (),
+ "alt",
+ "Object hierarchy for %s".printf (element.name),
+ "src",
+ this.get_img_path_html (element, format)});
+ writer.add_usemap (chart);
+ }
+ }
+
+ public void write_namespace_content (Namespace node, Api.Node? parent) {
+ writer.start_tag ("div", {"class", css_style_content});
+ writer.start_tag ("h1", {"class", css_title})
+ .text (node.name == null ? "Global Namespace" : node.get_full_name ())
+ .end_tag ("h1");
+ writer.simple_tag ("hr", {"class", css_hr});
+ writer.start_tag ("h2", {"class", css_title})
+ .text ("Description:")
+ .end_tag ("h2");
+
+ this.write_documentation (node, parent);
+
+ writer.start_tag ("h2", {"class", css_title})
+ .text ("Content:")
+ .end_tag ("h2");
+
+ if (node.name == null) {
+ this.write_child_namespaces ((Package) node.parent, parent);
+ } else {
+ this.write_child_namespaces (node, parent);
+ }
+
+ write_children (node, Api.NodeType.INTERFACE, "Interfaces", parent);
+ write_children (node, Api.NodeType.CLASS, "Classes", parent);
+ write_children (node, Api.NodeType.STRUCT, "Structs", parent);
+ write_children (node, Api.NodeType.ENUM, "Enums", parent);
+ write_children (node, Api.NodeType.ERROR_DOMAIN, "Error domains", parent);
+ write_children (node, Api.NodeType.CONSTANT, "Constants", parent);
+ write_children (node, Api.NodeType.DELEGATE, "Delegates", parent);
+ write_children (node, Api.NodeType.METHOD, "Functions", parent);
+ write_children (node, Api.NodeType.FIELD, "Fields", parent);
+ writer.end_tag ("div");
+ }
+
+ protected void write_package_content (Package node, Api.Node? parent) {
+ writer.start_tag ("div", {"class", css_style_content});
+ writer.start_tag ("h1", {"class", css_title, "id", node.name})
+ .text (node.name)
+ .end_tag ("h1");
+ writer.simple_tag ("hr", {"class", css_headline_hr});
+ writer.start_tag ("h2", {"class", css_title})
+ .text ("Description:")
+ .end_tag ("h2");
+
+
+ WikiPage? wikipage = (tree.wikitree == null)? null : tree.wikitree.search (wiki_index_name);
+ if (wikipage != null) {
+ _renderer.set_container (parent);
+ _renderer.render (wikipage.documentation);
+ }
+
+ writer.start_tag ("h2", {"class", css_title})
+ .text ("Content:")
+ .end_tag ("h2");
+
+ this.write_child_namespaces (node, parent);
+
+ foreach (Api.Node child in node.get_children_by_type (Api.NodeType.NAMESPACE)) {
+ if (child.name == null) {
+ write_children (child, Api.NodeType.INTERFACE, "Interfaces", parent);
+ write_children (child, Api.NodeType.CLASS, "Classes", parent);
+ write_children (child, Api.NodeType.STRUCT, "Structs", parent);
+ write_children (child, Api.NodeType.ENUM, "Enums", parent);
+ write_children (child, Api.NodeType.ERROR_DOMAIN, "Error domains", parent);
+ write_children (child, Api.NodeType.CONSTANT, "Constants", parent);
+ write_children (child, Api.NodeType.DELEGATE, "Delegates", parent);
+ write_children (child, Api.NodeType.METHOD, "Functions", parent);
+ write_children (child, Api.NodeType.FIELD, "Fields", parent);
+ }
+ }
+
+ this.write_child_dependencies (node, parent);
+ writer.end_tag ("div");
+ }
+
+ protected void write_file_header (string css, string js, string? title) {
+ writer.start_tag ("html");
+ writer.start_tag ("head");
+ writer.simple_tag ("meta", {"charset", "UTF-8"});
+ if (title == null) {
+ writer.start_tag ("title")
+ .text ("Vala Binding Reference")
+ .end_tag ("title");
+ } else {
+ writer.start_tag ("title")
+ .text (title)
+ .text (" &ndash; Vala Binding Reference")
+ .end_tag ("title");
+ }
+ writer.stylesheet_link (css);
+ writer.javascript_link (js);
+ writer.end_tag ("head");
+ writer.start_tag ("body");
+ writer.start_tag ("div", {"class", css_site_header});
+ writer.text ("%s Reference Manual".printf (title == null ? "" : title));
+ writer.end_tag ("div");
+ writer.start_tag ("div", {"class", css_style_body});
+ }
+
+ protected void write_file_footer () {
+ writer.end_tag ("div");
+ writer.simple_tag ("br");
+ writer.start_tag ("div", {"class", "site_footer"});
+ writer.text ("Generated by ");
+ writer.link ("http://www.valadoc.org/", "Valadoc");
+ writer.end_tag ("div");
+ writer.end_tag ("body");
+ writer.end_tag ("html");
+ }
+}
+