[tracker/sam/ontology-docs: 15/22] docs: Show 'additional properties' in ontology docs



commit cc89b368e5f4659a1a3b33cd4511ed0309a9b5a2
Author: Sam Thursfield <sam afuera me uk>
Date:   Sun Apr 12 19:22:47 2020 +0200

    docs: Show 'additional properties' in ontology docs
    
    An ontology can define properties which apply to a class defined
    outside the ontology. For example, the Dublin Core ontology defines
    properties which apply to rdfs:Resource. These are now listed in
    the ontology docs.

 docs/tools/ttl_xml.c         | 147 ++++++++++++++++++++++++++++++++++++++-----
 docs/tools/ttlresource2xml.c |  41 +++++++++---
 docs/tools/ttlresource2xml.h |   4 ++
 3 files changed, 169 insertions(+), 23 deletions(-)
---
diff --git a/docs/tools/ttl_xml.c b/docs/tools/ttl_xml.c
index 4937bedbe..ef185e137 100644
--- a/docs/tools/ttl_xml.c
+++ b/docs/tools/ttl_xml.c
@@ -131,14 +131,64 @@ print_xml_footer (FILE *f, OntologyDescription *desc)
        g_fprintf (f, "</refentry>\n");
 }
 
+/* By default we list properties under their respective class.
+ *
+ * Ontologies can contain properties whose class is in a different
+ * ontology, and we treat these specially as 'extra properties'.
+ *
+ * This functions returns a hash table mapping class name to the
+ * extra properties provided for that class.
+ */
+static GHashTable *
+get_extra_properties (GList *classes,
+                      GList *properties)
+{
+       GList *l, *c;
+       GHashTable *extra_properties;
+
+       extra_properties = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+       for (l = properties; l; l = l->next) {
+               OntologyProperty *prop = l->data;
+               gboolean has_domain_in_this_ontology = FALSE;
+
+               for (c = classes; c; c = c->next) {
+                       OntologyClass *klass;
+
+                       klass = c->data;
+                       if (g_list_find_custom (prop->domain, klass->classname, (GCompareFunc)strcmp)) {
+                               has_domain_in_this_ontology = TRUE;
+                               break;
+                       }
+               }
+
+               if (!has_domain_in_this_ontology) {
+                       for (c = prop->domain; c; c = c->next) {
+                               const gchar *classname;
+                               GList *list;
+
+                               classname = c->data;
+                               list = g_hash_table_lookup (extra_properties, classname);
+                               list = g_list_append (list, prop->propertyname);
+                               g_hash_table_insert (extra_properties, g_strdup (classname), list);
+                       }
+               }
+       }
+
+       return extra_properties;
+}
+
 static void
-print_class_list (FILE       *f,
-                  Ontology   *ontology,
-                  const char *id,
-                  GList      *classes)
+print_toc_classes (FILE       *f,
+                   Ontology   *ontology,
+                   const char *id,
+                   GList      *classes)
 {
        GList *l;
 
+       if (!classes)
+               return;
+
        g_fprintf (f, "<refsect1 id=\"%s.classes\">", id);
        g_fprintf (f, "<title>Classes</title>");
 
@@ -162,15 +212,56 @@ print_class_list (FILE       *f,
        g_fprintf (f, "</refsect1>");
 }
 
+static void
+print_toc_extra_properties (FILE       *f,
+                            Ontology   *ontology,
+                            const char *id,
+                            GHashTable *extra_properties)
+{
+       GHashTableIter iter;
+       const gchar *classname;
+       GList *props_for_class, *l;
+
+       if (g_hash_table_size (extra_properties) == 0)
+               return;
+
+       g_fprintf (f, "<refsect1 id=\"%s.extra_properties\">", id);
+       g_fprintf (f, "<title>Properties</title>");
+
+       g_fprintf (f, "<simplelist>\n");
+       g_hash_table_iter_init (&iter, extra_properties);
+       while (g_hash_table_iter_next (&iter, (gpointer*) &classname, (gpointer*) &props_for_class)) {
+               for (l = props_for_class; l; l = l->next) {
+                       OntologyProperty *prop;
+                       g_autofree char *basename = NULL, *id = NULL;
+
+                       prop = g_hash_table_lookup (ontology->properties, l->data);
+
+                       basename = ttl_model_name_to_basename (ontology, prop->propertyname);
+                       id = ttl_model_name_to_shortname (ontology, prop->propertyname, "-");
+                       g_fprintf (f, "<member>");
+                       g_fprintf (f, "<link linkend=\"%s\">%s</link>", id, basename);
+                       if (prop->description) {
+                               g_fprintf (f, ": %s", prop->description);
+                       }
+                       g_fprintf (f, "</member>\n");
+               }
+       }
+       g_fprintf (f, "</simplelist>\n");
+
+       g_fprintf (f, "</refsect1>");
+}
+
+/* Generate docbook XML document for one ontology. */
 void
 ttl_xml_print (OntologyDescription *description,
-                Ontology            *ontology,
-                GFile               *file,
-                const gchar         *description_dir)
+               Ontology            *ontology,
+               GFile               *file,
+               const gchar         *description_dir)
 {
-       GHashTableIter iter;
        gchar *upper_name, *path, *introduction, *basename;
-       GList *classes, *l;
+       GList *classes, *properties, *l;
+       GHashTable *extra_properties;
        FILE *f;
 
        path = g_file_get_path (file);
@@ -180,10 +271,14 @@ ttl_xml_print (OntologyDescription *description,
 
        upper_name = g_ascii_strup (description->localPrefix, -1);
        classes = g_hash_table_get_values (ontology->classes);
+       properties = g_hash_table_get_values (ontology->properties);
+
+       extra_properties = get_extra_properties (classes, properties);
 
        print_xml_header (f, description);
 
-       print_class_list (f, ontology, description->localPrefix, classes);
+       print_toc_classes (f, ontology, description->localPrefix, classes);
+       print_toc_extra_properties (f, ontology, description->localPrefix, extra_properties);
 
        basename = g_strdup_printf ("%s-introduction.xml", description->localPrefix);
        introduction = g_build_filename (description_dir, basename, NULL);
@@ -194,18 +289,38 @@ ttl_xml_print (OntologyDescription *description,
                           introduction);
        }
 
-    g_fprintf (f, "<refsect1 id='%s-classes'>\n", description->localPrefix);
-       g_fprintf (f, "<title>%s Ontology Classes</title>\n", upper_name);
-       g_hash_table_iter_init (&iter, ontology->classes);
+       if (classes != NULL) {
+       g_fprintf (f, "<refsect1 id='%s-classes'>\n", description->localPrefix);
+               g_fprintf (f, "<title>%s Ontology Classes</title>\n", upper_name);
 
-       for (l = classes; l; l = l->next) {
-               print_ontology_class (ontology, l->data, f);
+               for (l = classes; l; l = l->next) {
+                       print_ontology_class (ontology, l->data, f);
+               }
+
+               g_fprintf (f, "</refsect1>\n");
+       }
+
+       if (g_hash_table_size (extra_properties) > 0) {
+               GHashTableIter iter;
+               const gchar *classname;
+               GList *properties_for_class;
+
+               g_fprintf (f, "<refsect1 id='%s-extra-properties'>\n", description->localPrefix);
+               g_fprintf (f, "<title>%s Ontology Properties</title>\n", upper_name);
+
+               g_hash_table_iter_init (&iter, extra_properties);
+               while (g_hash_table_iter_next (&iter, (gpointer *)&classname, (gpointer 
*)&properties_for_class)) {
+                       print_ontology_extra_properties (ontology, classname, properties_for_class, f);
+               }
+
+               g_fprintf (f, "</refsect1>\n");
        }
 
-    g_fprintf (f, "</refsect1>\n");
        print_xml_footer (f, description);
 
        g_list_free (classes);
+       g_list_free (properties);
+       g_hash_table_unref (extra_properties);
 
        g_free (upper_name);
        g_free (introduction);
diff --git a/docs/tools/ttlresource2xml.c b/docs/tools/ttlresource2xml.c
index 2d842653c..212f430c0 100644
--- a/docs/tools/ttlresource2xml.c
+++ b/docs/tools/ttlresource2xml.c
@@ -558,17 +558,18 @@ print_class_hierarchy (FILE          *f,
 }
 
 static void
-print_properties (FILE          *f,
-                  OntologyClass *klass,
-                  Ontology      *ontology)
+print_property_table (FILE          *f,
+                      Ontology      *ontology,
+                      const char    *classname,
+                      GList         *properties)
 {
        g_autofree gchar *id = NULL;
        GList *l;
 
-       if (!klass->in_domain_of)
+       if (!properties)
                return;
 
-       id = ttl_model_name_to_shortname (ontology, klass->classname, "-");
+       id = ttl_model_name_to_shortname (ontology, classname, "-");
        g_fprintf (f, "<refsect3 id='%s.properties'>", id);
        g_fprintf (f, "<title>Properties</title>");
 
@@ -576,7 +577,7 @@ print_properties (FILE          *f,
        g_fprintf (f, "<thead><tr><td>Name</td><td>Type</td><td>Description</td></tr></thead>");
 
        g_fprintf (f, "<tbody>");
-       for (l = klass->in_domain_of; l; l = l->next) {
+       for (l = properties; l; l = l->next) {
                OntologyProperty *prop;
                g_autofree gchar *shortname = NULL, *basename = NULL, *type_name = NULL, *type_class_id = 
NULL, *prop_id = NULL;
 
@@ -698,6 +699,32 @@ print_ontology_class (Ontology      *ontology,
        print_class_hierarchy (f, klass, ontology);
        print_predefined_instances (f, klass, ontology);
        print_fts_properties (f, klass, ontology);
-       print_properties (f, klass, ontology);
+
+       print_property_table (f, ontology, klass->classname, klass->in_domain_of);
+
+       g_fprintf (f, "</refsect2>\n");
+}
+
+void
+print_ontology_extra_properties (Ontology      *ontology,
+                                 const char    *classname,
+                                 GList         *properties_for_class,
+                                 FILE          *f)
+{
+       g_autofree gchar *id = NULL;
+
+       g_return_if_fail (f != NULL);
+
+       id = ttl_model_name_to_shortname (ontology, classname, "-");
+
+       g_fprintf (f, "<refsect2 id='%s'>\n", id);
+       g_fprintf (f, "<title>Properties for %s</title>\n", id);
+
+       g_fprintf (f, "<refsect3 id='%s.description'>\n", id);
+       g_fprintf (f, "  <title>Description</title>\n");
+       g_fprintf (f, "  <para>Properties which can be used for %s resources.</para>", id);
+       g_fprintf (f, "</refsect3>\n");
+
+       print_property_table (f, ontology, classname, properties_for_class);
        g_fprintf (f, "</refsect2>\n");
 }
diff --git a/docs/tools/ttlresource2xml.h b/docs/tools/ttlresource2xml.h
index a4d3c5f56..f35f32a57 100644
--- a/docs/tools/ttlresource2xml.h
+++ b/docs/tools/ttlresource2xml.h
@@ -30,6 +30,10 @@ G_BEGIN_DECLS
 void print_ontology_class (Ontology      *ontology,
                            OntologyClass *klass,
                            FILE          *f);
+void print_ontology_extra_properties (Ontology      *ontology,
+                                      const char    *classname,
+                                      GList         *properties_for_class,
+                                      FILE          *f);
 
 G_END_DECLS
 


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