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
20 * Florian Brosch <flo.brosch@gmail.com>
23 using Valadoc
.Content
;
28 public abstract class Valadoc
.Html
.BasicDoclet
: Api
.Visitor
, Doclet
{
29 public Html
.LinkHelper linker
{
34 public Settings settings
{
39 public string wiki_index_name
{
40 default = "index.valadoc";
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";
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
;
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
);
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 () {
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
;
157 assert (pos is TypeSymbol
);
158 return (TypeSymbol
) pos
;
166 protected void write_navi_entry_html_template (string style
, string content
, bool is_deprecated
) {
167 writer
.start_tag ("li", {"class", style
});
170 writer
.start_tag ("span", {"class", css_deprecated
});
171 writer
.text (content
);
172 writer
.end_tag ("span");
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
});
186 writer
.start_tag ("span", {"class", css_deprecated
});
187 writer
.link (link
, content
);
188 writer
.end_tag ("span");
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)
201 if (full_name
== true && element is Namespace
) {
202 string tmp
= element
.get_full_name();
203 name
= (tmp
== null)?
"Global Namespace" : tmp
;
205 string tmp
= element
.name
;
206 name
= (tmp
== null)?
"Global Namespace" : tmp
;
209 bool is_deprecated
= element is Symbol
&& ((Symbol
) element
).is_deprecated
;
212 this
.write_navi_entry_html_template_with_link (style
,
213 this
.get_link (element
, pos
),
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
,
224 if (tree
.wikitree
== null) {
228 if (tree
.wikitree
== null) {
232 Vala
.Collection
<WikiPage
> pages
= tree
.wikitree
.get_pages();
233 if (pages
.size
== 0) {
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"),
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);
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) {
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) {
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) {
405 writer
.start_tag ("div", {"class", css_package_note
});
406 writer
.start_tag ("b")
410 .start_tag ("a", {"href", get_link (element
.package
, element
)})
413 writer
.end_tag ("div");
416 protected void write_namespace_note (Api
.Node element
) {
417 Namespace? ns
= element
.nspace
;
422 if (ns
.name
== null) {
426 writer
.start_tag ("div", {"class", css_namespace_note
});
427 writer
.start_tag ("b")
431 .start_tag ("a", {"href", get_link (ns
, element
)})
432 .text (ns
.get_full_name())
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) {
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
);
465 if (doctree
== null && !is_deprecated
) {
470 writer
.start_tag ("div", {"class", css_description
});
471 _renderer
.set_owner (element
);
473 // deprecation warning:
475 Symbol symbol
= (Symbol
) element
;
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");
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
));
497 writer
.text (" since %s".printf (since
.get_value_as_string ()));
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
);
511 string? link
= get_link (replacement_node
, pos
);
513 string css
= cssresolver
.resolve (replacement_node
);
514 writer
.link (link
, replacement_node
.get_full_name (), css
);
516 writer
.start_tag ("code")
517 .text (replacement_node
.get_full_name ())
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
559 || node is Api
.Struct
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
);
573 writer
.end_tag ("li");
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
})
594 writer
.simple_tag ("hr", {"class", css_headline_hr
});
596 WikiPage? wikiindex
= (tree
.wikitree
== 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
})
607 writer
.start_tag ("h3", {"class", css_title
})
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
)) {
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) {
635 var html_id
= "box-content-" + html_id_counter
.to_string ();
639 writer
.start_tag ("div", {"class", css_box
});
642 writer
.start_tag ("div", {"class", css_box_headline
, "onclick", "toggle_box (this, '%s')".printf (html_id
)})
645 //writer.start_tag ("div", {"class", css_box_headline_text, "onclick", "toggle_box (this, '%s')".printf (html_id)})
648 //writer.start_tag ("div", {"class", css_box_headline_toggle});
649 //writer.start_tag ("img", {"onclick",
650 // "toggle_box (this, '" + html_id + "')",
652 // Path.build_filename (get_icon_directory (),
653 // "coll_open.png")});
654 //writer.raw_text (" ");
655 //writer.end_tag ("div");
656 //writer.end_tag ("div");
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
);
680 writer
.text (node
.name
);
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
})
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:")
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
);
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 (),
722 } else if (node is Interface
) {
723 var iface
= node as Interface
;
724 write_known_symbols_note (iface
.get_known_implementations (),
726 "All known implementing classes:");
727 write_known_symbols_note (iface
.get_known_related_interfaces (),
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 (),
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
,
754 Api
.NodeType
.DELEGATE
,
757 Api
.NodeType
.PROPERTY
,
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
);
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
= {
794 NodeType
.STATIC_METHOD
,
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:")
810 private void write_inherited_symbols_note_for_class (Class cl
, Api
.Node container
) {
811 bool headline_printed
= false;
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
)) {
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;
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
;
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
)) {
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),
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),
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),
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),
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),
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),
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),
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),
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) {
922 if (namespaces
.size
== 1) {
923 if (namespaces
.get(0).name
== null) {
928 bool with_childs
= parent
!= null && parent is Package
;
930 writer
.start_tag ("h3", {"class", css_title
})
931 .text ("Namespaces:")
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
)) {
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) {
965 writer
.start_tag ("h2", {"class", css_title
})
966 .text ("Dependencies:")
968 writer
.start_tag ("ul", {"class", css_inline_navigation
});
969 foreach (Package p
in deps
) {
970 string? link
= this
.get_link (p
, parent
);
972 writer
.start_tag ("li", {"class", cssresolver
.resolve (p
), "id", p
.name
})
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
})
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");
1000 writer
.link (get_link (child
, container
), child
.name
);
1002 if (has_brief_description (child
)) {
1003 writer
.text (" - ");
1004 write_brief_description (child
, container
);
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");
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:")
1037 writer
.simple_tag ("img", {"class",
1040 "#"+element
.get_full_name (),
1042 "Object hierarchy for %s".printf (element
.name
),
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 ())
1054 writer
.simple_tag ("hr", {"class", css_hr
});
1055 writer
.start_tag ("h2", {"class", css_title
})
1056 .text ("Description:")
1059 this
.write_documentation (node
, parent
);
1061 writer
.start_tag ("h2", {"class", css_title
})
1065 if (node
.name
== null) {
1066 this
.write_child_namespaces ((Package
) node
.parent
, parent
);
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
})
1088 writer
.simple_tag ("hr", {"class", css_headline_hr
});
1089 writer
.start_tag ("h2", {"class", css_title
})
1090 .text ("Description:")
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
})
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")
1133 writer
.start_tag ("title")
1135 .text (" – Vala Binding Reference")
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");