summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Chimento <philip.chimento@gmail.com>2015-11-21 21:02:02 -0800
committerrockon999 <rockon999@users.noreply.github.com>2018-08-06 02:53:45 -0500
commit9719dd21669084b6ccaaef07899db8416e235a74 (patch)
tree42274386b8e376db2d4945f70d728dd6db6b1b31
parent7f67146d8254464f396b289ed41c8954d61fe03d (diff)
downloadgobject-introspection-9719dd21669084b6ccaaef07899db8416e235a74.tar.gz
devdocs: Render a summary at the top of each page
This summary, heavily inspired by the one from pgi-docs, is useful when browsing the page rather than searching for a specific term. It's also similar to the summary at the top of gtk-doc pages.
-rw-r--r--Makefile-giscanner.am1
-rw-r--r--giscanner/doctemplates/devdocs/Gjs/_index.tmpl156
-rw-r--r--giscanner/doctemplates/devdocs/Gjs/base.tmpl1
-rw-r--r--giscanner/docwriter.py19
4 files changed, 176 insertions, 1 deletions
diff --git a/Makefile-giscanner.am b/Makefile-giscanner.am
index c51cbf23..4336a140 100644
--- a/Makefile-giscanner.am
+++ b/Makefile-giscanner.am
@@ -107,6 +107,7 @@ nobase_dist_template_DATA = \
giscanner/doctemplates/mallard/Gjs/record.tmpl \
giscanner/doctemplates/mallard/Gjs/signal.tmpl \
giscanner/doctemplates/mallard/Gjs/vfunc.tmpl \
+ giscanner/doctemplates/devdocs/Gjs/_index.tmpl \
giscanner/doctemplates/devdocs/Gjs/_method.tmpl \
giscanner/doctemplates/devdocs/Gjs/_methods.tmpl \
giscanner/doctemplates/devdocs/Gjs/_properties.tmpl \
diff --git a/giscanner/doctemplates/devdocs/Gjs/_index.tmpl b/giscanner/doctemplates/devdocs/Gjs/_index.tmpl
new file mode 100644
index 00000000..8d45e871
--- /dev/null
+++ b/giscanner/doctemplates/devdocs/Gjs/_index.tmpl
@@ -0,0 +1,156 @@
+<%
+ ancestors = []
+ if isinstance(node, ast.Class):
+ ancestors = formatter.get_inheritable_types(node)
+
+ def get_ancestor_counts(*kinds):
+ counts = {}
+ for a in ancestors:
+ count = sum([len(getattr(a, kind, [])) for kind in kinds])
+ if count:
+ counts[a] = count
+ return counts
+
+ def should_render(*kinds):
+ has_nonempty = any([getattr(node, kind, []) for kind in kinds])
+ return has_nonempty or get_ancestor_counts(*kinds)
+%>
+
+<%def name="inherited(*kinds)">
+ <% counts = get_ancestor_counts(*kinds) %>
+ % if counts:
+ <%
+ links = ', '.join(['{} ({})'.format(formatter.format_xref(a), count)
+ for a, count in counts.items()])
+ %>
+ ${formatter.format(node, '**Inherited:** ' + links)}
+ % endif
+</%def>
+
+% if should_render('static_methods', 'constructors', 'methods'):
+ <h2 id="index-methods">Methods</h2>
+ ${inherited('static_methods', 'constructors', 'methods')}
+ <%
+ static_methods = getattr(node, 'static_methods', []) + getattr(node, 'constructors', [])
+ methods = static_methods + getattr(node, 'methods', [])
+ %>
+ % if methods:
+ <table>
+ <tbody>
+ % for m in methods:
+ <tr>
+ % if m in static_methods:
+ <td class="static-method-indicator">static</td>
+ % else:
+ <td></td>
+ % endif
+ <td>
+ <a href="#${formatter.make_anchor(m)}">
+ ${formatter.format_function_name(m)}<!-- no space
+ --></a><!-- no space
+ -->(${formatter.format_in_parameters(m)})
+ </td>
+ </tr>
+ % endfor
+ </tbody>
+ </table>
+ % endif
+% endif
+
+% if should_render('virtual_methods'):
+ <h2 id="index-vfuncs">Virtual methods</h2>
+ ${inherited('virtual_methods')}
+ % if getattr(node, 'virtual_methods', []):
+ <table>
+ <tbody>
+ % for m in node.virtual_methods:
+ <tr>
+ <td>
+ <a href="#${formatter.make_anchor(m)}">
+ ${formatter.format_function_name(m)}<!-- no space
+ --></a><!-- no space
+ -->(${formatter.format_in_parameters(m)})
+ </td>
+ </tr>
+ % endfor
+ </tbody>
+ </table>
+ % endif
+% endif
+
+% if should_render('properties'):
+ <h2 id="index-properties">Properties</h2>
+ ${inherited('properties')}
+ % if getattr(node, 'properties', []):
+ <table>
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Type</th>
+ <th>Flags</th>
+ </tr>
+ </thead>
+ <tbody>
+ % for p in node.properties:
+ <tr>
+ <td><a href="#${formatter.make_anchor(p)}">${p.name}</a></td>
+ <td>${formatter.format_type(p.type)}</td>
+ <td>${formatter.format_property_flags(p, abbrev=True)}</td>
+ </tr>
+ % endfor
+ </tbody>
+ </table>
+ % endif
+% endif
+
+% if should_render('signals'):
+ <h2 id="index-signals">Signals</h2>
+ ${inherited('signals')}
+ % if getattr(node, 'signals', []):
+ <table>
+ <tbody>
+ % for s in node.signals:
+ <tr>
+ <td>
+ <a href="#${formatter.make_anchor(s)}">${s.name}</a><!-- no space
+ -->(${formatter.format_in_parameters(s)})
+ </td>
+ </tr>
+ % endfor
+ </tbody>
+ </table>
+ % endif
+% endif
+
+% if should_render('fields'):
+ <h2 id="index-fields">Fields</h2>
+ ${inherited('fields')}
+ % if getattr(node, 'fields', []):
+ <table>
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Type</th>
+ <th>Access</th>
+ <th>Description</th>
+ </tr>
+ </thead>
+ <tbody>
+ % for f in node.fields:
+ <tr>
+ <td><span class="entry" href="#${formatter.make_anchor(f)}">${f.name}</span></td>
+ <td>${formatter.format_type(f.type)}</td>
+ <td>${formatter.format_property_flags(f, abbrev=True)}</td>
+ ## Fields almost never warrant a detailed entry, we'll just make this
+ ## the entry to be indexed by DevDocs
+ <td>
+ % if f.doc:
+ ${formatter.format_inline(node, f.doc)}
+ % endif
+ </td>
+ </tr>
+ % endfor
+ </tbody>
+ </table>
+ % endif
+% endif
diff --git a/giscanner/doctemplates/devdocs/Gjs/base.tmpl b/giscanner/doctemplates/devdocs/Gjs/base.tmpl
index 95800da8..91ffa105 100644
--- a/giscanner/doctemplates/devdocs/Gjs/base.tmpl
+++ b/giscanner/doctemplates/devdocs/Gjs/base.tmpl
@@ -2,6 +2,7 @@
<body>
<section>
<h1 class="${page_kind}">${formatter.format_page_name(node)}</h1>
+ <%include file="_index.tmpl"/>
<h2>Details</h2>
${formatter.format(node, node.doc)}
<%include file="_staticmethods.tmpl"/>
diff --git a/giscanner/docwriter.py b/giscanner/docwriter.py
index f26ed5b1..cba8a5d8 100644
--- a/giscanner/docwriter.py
+++ b/giscanner/docwriter.py
@@ -454,7 +454,7 @@ class DocFormatter(object):
def field_is_writable(self, field):
return True
- def format_property_flags(self, property_, construct_only=False):
+ def format_property_flags(self, property_, construct_only=False, abbrev=False):
flags = []
if property_.readable and not construct_only:
@@ -468,6 +468,9 @@ class DocFormatter(object):
if property_.construct_only:
flags.append("Construct Only")
+ if abbrev:
+ return "/".join([''.join([word[0] for word in flag.lower().split()])
+ for flag in flags])
return " / ".join(flags)
def format_signal_flags(self, signal):
@@ -512,6 +515,20 @@ class DocFormatter(object):
parent_chain.reverse()
return parent_chain
+ def get_inheritable_types(self, node):
+ """Return an ast.Node object for each type (ast.Class and ast.Interface
+ types) from which an ast.Class @node might inherit methods, properties,
+ and signals."""
+
+ assert isinstance(node, ast.Class)
+
+ parent_chain = self.get_class_hierarchy(node)
+ types = []
+ for p in parent_chain:
+ types += [self._transformer.lookup_typenode(t) for t in p.interfaces]
+ types += [t for t in parent_chain if t is not node]
+ return types
+
def format_prerequisites(self, node):
assert isinstance(node, ast.Interface)