[gobject-introspection/wip/docs: 10/11] Create AST nodes for sections found on doc blocks, and write them to the GIR



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

    Create AST nodes for sections found on doc blocks, and write them to the GIR
    
    These will eventually be paired with the sections file parser to create
    a set of sections.

 girepository/girparser.c               |    7 +++++++
 giscanner/annotationparser.py          |    2 ++
 giscanner/ast.py                       |   16 ++++++++++++++++
 giscanner/girparser.py                 |   23 +++++++++++++++++++++++
 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 ++++++++++++++++++++++
 9 files changed, 125 insertions(+), 0 deletions(-)
---
diff --git a/girepository/girparser.c b/girepository/girparser.c
index 5aaa6dd..50faf3b 100644
--- a/girepository/girparser.c
+++ b/girepository/girparser.c
@@ -2984,6 +2984,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 dd19dbd..565fb09 100644
--- a/giscanner/annotationparser.py
+++ b/giscanner/annotationparser.py
@@ -370,6 +370,7 @@ class DocBlock(object):
         self.tags = odict()
         self.comment = None
         self.params = odict()
+        self.lower_params = odict()
         self.position = None
 
     def __cmp__(self, other):
@@ -997,6 +998,7 @@ class AnnotationParser(object):
                     comment_block.tags[param_name] = tag
                 else:
                     comment_block.params[param_name] = tag
+                    comment_block.lower_params[param_name.lower()] = tag
                 current_param = tag
                 continue
 
diff --git a/giscanner/ast.py b/giscanner/ast.py
index 5854091..6de5a97 100644
--- a/giscanner/ast.py
+++ b/giscanner/ast.py
@@ -1098,3 +1098,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/girparser.py b/giscanner/girparser.py
index 63a3fd0..e07246a 100644
--- a/giscanner/girparser.py
+++ b/giscanner/girparser.py
@@ -140,6 +140,7 @@ class GIRParser(object):
             _corens('interface'): self._parse_object_interface,
             _corens('record'): self._parse_record,
             _corens('union'): self._parse_union,
+            _corens('section'): self._parse_section,
             _glibns('boxed'): self._parse_boxed,
             }
 
@@ -548,6 +549,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 d6b3485..6785aeb 100644
--- a/giscanner/girwriter.py
+++ b/giscanner/girwriter.py
@@ -115,6 +115,8 @@ and/or use gtk-doc annotations. ''')
             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
 
@@ -372,6 +374,25 @@ and/or use gtk-doc annotations. ''')
             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 e3c0084..38ac20e 100755
--- a/giscanner/scannermain.py
+++ b/giscanner/scannermain.py
@@ -464,6 +464,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 353f125..f0b2dd8 100644
--- a/giscanner/transformer.py
+++ b/giscanner/transformer.py
@@ -135,6 +135,30 @@ class Transformer(object):
         self._namespace.includes.add(include)
         self._parse_include(include_path, uninstalled=True)
 
+    def _fabricate_section(self, block):
+        def get_tag(name):
+            tag = block.lower_params.get(name)
+            if tag:
+                return tag.comment
+            else:
+                return None
+
+        section = ast.Section(block.name,
+                              get_tag('short_description'),
+                              get_tag('long_description'),
+                              get_tag('see_also'),
+                              get_tag('title'),
+                              get_tag('stability'),
+                              get_tag('section_id'),
+                              get_tag('include'),
+                              get_tag('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 53773ca..fd664ed 100644
--- a/tests/scanner/Regress-1.0-expected.gir
+++ b/tests/scanner/Regress-1.0-expected.gir
@@ -1966,6 +1966,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 f54c2f9..a666f50 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]