[gobject-introspection/doc-sections] giscanner: Create AST nodes for SECTION: doc blocks; add a GIR node



commit a1ec815afd2dd4379ce443efbb4d4aca4cf97c33
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Wed Mar 27 17:09:16 2013 -0400

    giscanner: Create AST nodes for SECTION: doc blocks; add a GIR node
    
    These will eventually be paired with the sections file parser to create
    a set of sections.

 girepository/girparser.c               |    7 +++++++
 giscanner/annotationparser.py          |    8 ++++++--
 giscanner/ast.py                       |   16 ++++++++++++++++
 giscanner/docwriter.py                 |    2 ++
 giscanner/girparser.py                 |   26 +++++++++++++++++++++++++-
 giscanner/girwriter.py                 |   21 +++++++++++++++++++++
 giscanner/scannermain.py               |    2 ++
 giscanner/transformer.py               |   24 ++++++++++++++++++++++++
 tests/scanner/Regress-1.0-expected.gir |    8 ++++++++
 tests/scanner/regress.c                |   22 ++++++++++++++++++++++
 10 files changed, 133 insertions(+), 3 deletions(-)
---
diff --git a/girepository/girparser.c b/girepository/girparser.c
index 6c76866..fb6a18f 100644
--- a/girepository/girparser.c
+++ b/girepository/girparser.c
@@ -3004,6 +3004,13 @@ start_element_handler (GMarkupParseContext *context,
        goto out;
       break;
 
+    case 's':
+      if (strcmp (element_name, "section") == 0)
+        {
+          state_switch (ctx, STATE_PASSTHROUGH);
+          goto out;
+        }
+
     case 'u':
       if (start_union (context, element_name,
                       attribute_names, attribute_values,
diff --git a/giscanner/annotationparser.py b/giscanner/annotationparser.py
index afeca9c..758f606 100644
--- a/giscanner/annotationparser.py
+++ b/giscanner/annotationparser.py
@@ -1007,8 +1007,8 @@ class GtkDocCommentBlock(GtkDocAnnotatable):
     Represents a GTK-Doc comment block.
     '''
 
-    __slots__ = ('code_before', 'code_after', 'indentation',
-                 'name', 'params', 'description', 'tags')
+    __slots__ = ('code_before', 'code_after', 'indentation', 'name',
+                 'params', 'lower_params', 'description', 'tags')
 
     #: Valid annotation names for the GTK-Doc comment block identifier part.
     valid_annotations = (ANN_ATTRIBUTES, ANN_CONSTRUCTOR, ANN_FOREIGN, ANN_GET_VALUE_FUNC,
@@ -1035,6 +1035,9 @@ class GtkDocCommentBlock(GtkDocAnnotatable):
         #: applied to this :class:`GtkDocCommentBlock`.
         self.params = OrderedDict()
 
+        #: Like params, but all of its keys are in lower-case.
+        self.lower_params = OrderedDict()
+
         #: The GTK-Doc comment block description part.
         self.description = None
 
@@ -1405,6 +1408,7 @@ class GtkDocCommentBlockParser(object):
                         parameter.description = result.description
 
                 comment_block.params[param_name] = parameter
+                comment_block.lower_params[param_name.lower()] = parameter
                 current_part = parameter
                 continue
 
diff --git a/giscanner/ast.py b/giscanner/ast.py
index a9537e8..671db72 100644
--- a/giscanner/ast.py
+++ b/giscanner/ast.py
@@ -1137,3 +1137,19 @@ class Callback(Callable):
     def __init__(self, name, retval, parameters, throws, ctype=None):
         Callable.__init__(self, name, retval, parameters, throws)
         self.ctype = ctype
+
+
+class Section(Node):
+
+    def __init__(self, name, short_description, long_description,
+                 see_also, title, stability, section_id, include,
+                 image):
+        Node.__init__(self, name)
+        self.short_description = short_description
+        self.long_description = long_description
+        self.see_also = see_also
+        self.title = title
+        self.stability = stability
+        self.section_id = section_id
+        self.include = include
+        self.image = image
diff --git a/giscanner/docwriter.py b/giscanner/docwriter.py
index d888c81..abcab71 100644
--- a/giscanner/docwriter.py
+++ b/giscanner/docwriter.py
@@ -918,6 +918,8 @@ class DocWriter(object):
         self._transformer.namespace.walk(lambda node, chain: self._walk_node(output, node, chain))
 
     def _walk_node(self, output, node, chain):
+        if isinstance(node, ast.Section):
+            return False
         if isinstance(node, ast.Function) and node.moved_to is not None:
             return False
         if self._formatter.should_render_node(node):
diff --git a/giscanner/girparser.py b/giscanner/girparser.py
index 40bc49e..61fcc10 100644
--- a/giscanner/girparser.py
+++ b/giscanner/girparser.py
@@ -136,7 +136,9 @@ class GIRParser(object):
             _corens('interface'): self._parse_object_interface,
             _corens('record'): self._parse_record,
             _corens('union'): self._parse_union,
-            _glibns('boxed'): self._parse_boxed}
+            _corens('section'): self._parse_section,
+            _glibns('boxed'): self._parse_boxed,
+        }
 
         if not self._types_only:
             parser_methods[_corens('constant')] = self._parse_constant
@@ -559,6 +561,28 @@ class GIRParser(object):
         self._parse_generic_attribs(node, constant)
         self._namespace.append(constant)
 
+    def _parse_section(self, node):
+        def find_child(name):
+            child = node.find(_corens(name))
+            if child is not None:
+                return child.text
+            else:
+                return None
+
+        long_description = find_child('long-description')
+        short_description = find_child('short-description')
+        see_also = find_child('see-also')
+        section = ast.Section(node.attrib['name'],
+                              short_description,
+                              long_description,
+                              see_also,
+                              node.attrib.get('title'),
+                              node.attrib.get('stability'),
+                              node.attrib.get('section-id'),
+                              node.attrib.get('include'),
+                              node.attrib.get('image'))
+        self._namespace.append(section)
+
     def _parse_enumeration_bitfield(self, node):
         name = node.attrib.get('name')
         ctype = node.attrib.get(_cns('type'))
diff --git a/giscanner/girwriter.py b/giscanner/girwriter.py
index 3bea2a1..79799c3 100644
--- a/giscanner/girwriter.py
+++ b/giscanner/girwriter.py
@@ -115,6 +115,8 @@ class GIRWriter(XMLWriter):
             self._write_alias(node)
         elif isinstance(node, ast.Constant):
             self._write_constant(node)
+        elif isinstance(node, ast.Section):
+            self._write_section(node)
         else:
             print 'WRITER: Unhandled node', node
 
@@ -402,6 +404,25 @@ class GIRWriter(XMLWriter):
             self._write_generic(constant)
             self._write_type(constant.value_type)
 
+    def _write_section(self, section):
+        attrs = [('name', section.name),
+                 ('title', section.title),
+                 ('include', section.include),
+                 ('image', section.image),
+                 ('section-id', section.section_id)]
+        self._append_node_generic(section, attrs)
+
+        with self.tagcontext('section', attrs):
+            self._write_generic(section)
+
+            def write_child(name, content):
+                if content:
+                    self.write_tag(name, [('xml:whitespace', 'preserve')], content)
+
+            write_child('short-description', section.short_description)
+            write_child('long-description', section.long_description)
+            write_child('see-also', section.see_also)
+
     def _write_class(self, node):
         attrs = [('name', node.name),
                  ('c:symbol-prefix', node.c_symbol_prefix),
diff --git a/giscanner/scannermain.py b/giscanner/scannermain.py
index ac34030..d284d73 100755
--- a/giscanner/scannermain.py
+++ b/giscanner/scannermain.py
@@ -497,6 +497,8 @@ def scanner_main(args):
 
     transformer.namespace.shared_libraries = shlibs
 
+    transformer.fabricate_special_blocks(blocks)
+
     main = MainTransformer(transformer, blocks)
     main.transform()
 
diff --git a/giscanner/transformer.py b/giscanner/transformer.py
index 8c5e908..8e1001b 100644
--- a/giscanner/transformer.py
+++ b/giscanner/transformer.py
@@ -151,6 +151,30 @@ class Transformer(object):
         self._namespace.includes.add(include)
         self._parse_include(include_path, uninstalled=True)
 
+    def _fabricate_section(self, block):
+        def get_param(name):
+            param = block.lower_params.get(name)
+            if param:
+                return param.description
+            else:
+                return None
+
+        section = ast.Section(block.name,
+                              get_param('short_description'),
+                              get_param('long_description'),
+                              get_param('see_also'),
+                              get_param('title'),
+                              get_param('stability'),
+                              get_param('section_id'),
+                              get_param('include'),
+                              get_param('image'))
+        self._append_new_node(section)
+
+    def fabricate_special_blocks(self, blocks):
+        for name, block in blocks.iteritems():
+            if name.startswith("SECTION:"):
+                self._fabricate_section(block)
+
     def lookup_giname(self, name):
         """Given a name of the form Foo or Bar.Foo,
 return the corresponding ast.Node, or None if none
diff --git a/tests/scanner/Regress-1.0-expected.gir b/tests/scanner/Regress-1.0-expected.gir
index 1c9c300..9ed048a 100644
--- a/tests/scanner/Regress-1.0-expected.gir
+++ b/tests/scanner/Regress-1.0-expected.gir
@@ -2046,6 +2046,14 @@ exposed to language bindings.</doc>
               c:type="REGRESS_NEGATIVE_INT_CONSTANT">
       <type name="gint" c:type="gint"/>
     </constant>
+    <section name="SECTION:one" title="Test One!">
+      <short-description xml:whitespace="preserve">One test section</short-description>
+      <see-also xml:whitespace="preserve">two</see-also>
+    </section>
+    <section name="SECTION:two" title="Test Another!">
+      <short-description xml:whitespace="preserve">Another test section</short-description>
+      <see-also xml:whitespace="preserve">one</see-also>
+    </section>
     <constant name="STRING_CONSTANT"
               value="Some String"
               c:type="REGRESS_STRING_CONSTANT">
diff --git a/tests/scanner/regress.c b/tests/scanner/regress.c
index 1bad36e..00e21e3 100644
--- a/tests/scanner/regress.c
+++ b/tests/scanner/regress.c
@@ -6,6 +6,28 @@
 
 #include "regress.h"
 
+/**
+ * SECTION:one
+ * @Short_description: One test section
+ * @Title: Test One!
+ * @See_also: two
+ *
+ * Testing some docs.
+ *
+ * Do not sound the alarm.
+ */
+
+/**
+ * SECTION:two
+ * @Short_description: Another test section
+ * @Title: Test Another!
+ * @See_also: one
+ *
+ * Testing some more docs.
+ *
+ * Oh hey, this is still a test!
+ */
+
 static gboolean abort_on_error = TRUE;
 
 #define ASSERT_VALUE(condition)  \


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]