Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DocBook Library (tentative name) #111

Closed
dourouc05 opened this issue Dec 18, 2018 · 33 comments
Closed

DocBook Library (tentative name) #111

dourouc05 opened this issue Dec 18, 2018 · 33 comments

Comments

@dourouc05
Copy link

@dourouc05 dourouc05 commented Dec 18, 2018

Following the discussion in #108. Supersedes #107, #108, #109, #110. I also added languages that provide these kinds of constructs (among those that I have used enough to have an opinion on how libraries could be documented), sometimes with a slight discussion; also, always with a DocBook equivalent when it makes sense (large parts have been mostly copy-pasted ).

New Element Definitions

The following elements have been added to support needs arising in code documentation:

  • namespace: a container for a name space with modifiers in a programming language. Similar to ooclass.
  • namespacename: the name of a name space. For instance, implemented in C++, Java, C#, XML. Similar to classname.
  • namespacesynopsis: a container for a name space and its contents (which can be recursive). For instance, implemented in C++, Java, C#. Similar to classsynopsis.
  • namespacesynopsisinfo: information supplementing the contents of a namespacesynopsis. Similar to classsynopsisinfo.
  • macro: the name of a macro. For instance, implemented in C, C++, Scala, Julia (the latter has a specific syntax for calling macros, as opposed to functions; for all languages, macros have very distinct semantics compared to functions — actually, on par with the contrast between a constructor and a method, both of which have different tags). Similar to function.
  • macrosynopsis: a container for the description of a macro. Similar to funcsynopsis.
  • macrosynopsisinfo: information supplementing the contents of a macrosynopsis. Similar to funcsynopsisinfo.
  • macroprototype: prototype of a macro (its name and its arguments). For instance, implemented in C, C++ (without type information for arguments), Scala, Julia (with facultative type information). Similar to funcprototype.
  • macrodef: definition of a macro (return type and name). For instance, Scala and Julia may require the distinction between a macrodef and a macro (macros may return a value). Similar to funcdef.
  • enumname: the name of an enumerated type. For instance, implemented in C, C++, Scala, Julia.
  • enumvalue: a possible value of an enumeration constant. For instance, implemented in C, C++, Scala, Julia.
  • enumvalue: a possible value of an enumeration constant (usually, an integer). For instance, implemented in C, C++, Scala, Julia.
  • enumidentifier: the mnemonic of an enumeration constant (usually, similar to a constant). For instance, implemented in C, C++, Scala, Julia.
  • enumsynopsis: a container for the description of an enumeration and its enumerated values.
  • enumsynopsisinfo: information supplementing the contents of an enumsynopsis.
  • enumitem: a container for an enumerated value (both a value and an identifier).
  • typedefname: the name of a type alias. For instance, implemented in C, C++, Scala (all with the keyword typedef).
  • typedefsynopsis: a container for the description of a type alias.

Here are some parts that should be more carefully thought about.

  • Need for separate namespace and namespacename? I did this by consistency with classes, but I do not think there is a need for this.
  • Should macros be modelled after functions (funcsynopsis) or methods (methodsynopsis)? The first one feels a bit awkward in DocBook (at least in 2018).

Here is an RNC description of all these tags:

default namespace = "http://docbook.org/ns/docbook"
include "docbookxi.rnc" {
  db.classsynopsis =
    element classsynopsis {
      db.classsynopsis.attlist,
      db.oo.inlines+,
      (db.classsynopsisinfo
       | db.methodsynopsis
       | db.constructorsynopsis
       | db.destructorsynopsis
       | db.fieldsynopsis
       | db.synopsis)*
    }
}
db.synopsis = db.enumsynopsis | db.typedefsynopsis

# Deal with namespaces. 
div {
    ## First the inline elements. 
    db.programming.inlines |= db.namespace | db.namespacename

    db.namespace.role.attribute = attribute role { text }
    db.namespace.attlist =
       db.namespace.role.attribute?
       & db.common.attributes
       & db.common.linking.attributes
    db.namespace = element namespace { db.namespace.attlist, db.namespacename }

    db.namespacename.role.attribute = attribute role { text }
    db.namespacename.attlist =
       db.namespacename.role.attribute?
       & db.common.attributes
       & db.common.linking.attributes
    db.namespacename = element namespacename { db.namespacename.attlist, db._text }
    
    ## Then the synopsis.
    db.synopsis.blocks |= db.namespacesynopsis
    
    db.namespacesynopsisinfo.role.attribute = attribute role { text }
    db.namespacesynopsisinfo.attlist =
      db.namespacesynopsisinfo.role.attribute?
      & db.common.attributes
      & db.common.linking.attributes
      & db.verbatim.attributes
    db.namespacesynopsisinfo =
      element namespacesynopsisinfo {
        db.namespacesynopsisinfo.attlist, db.verbatim.contentmodel
      }
    
    db.namespacesynopsis.role.attribute = attribute role { text }
    db.namespacesynopsis.attlist =
      db.namespacesynopsis.role.attribute?
      & db.common.attributes
      & db.common.linking.attributes
      & db.language.attribute?
    db.namespacesynopsis = 
      element namespacesynopsis { 
        db.namespacesynopsis.attlist,
        db.programming.inlines+,
        (db.namespacesynopsisinfo
        | db.classsynopsis
        | db.funcsynopsis
        | db.fieldsynopsis
        | db.typedefsynopsis
        | db.macrosynopsis
        | db.enumsynopsis)*
      }
}

# Deal with macros. Adapted from db.funcsynopsis.
div {
    ## First the inline elements. 
    db.programming.inlines |= db.macro
        
    db.macro.role.attribute = attribute role { text }
    db.macro.attlist =
      db.macro.role.attribute?
      & db.common.attributes
      & db.common.linking.attributes
    db.macro =
      element macro { db.function.attlist, db._text }
    
    ## Then the synopsis.
    db.synopsis.blocks |= db.macrosynopsis
    
    db.macrosynopsis.role.attribute = attribute role { text }
    db.macrosynopsis.attlist =
      db.macrosynopsis.role.attribute?
      & db.common.attributes
      & db.common.linking.attributes
      & db.language.attribute?
    db.macrosynopsis.info = db._info.title.forbidden
    db.macrosynopsis =
      element macrosynopsis {
        db.macrosynopsis.attlist,
        db.macrosynopsis.info,
        (db.macrosynopsisinfo | db.macroprototype)+
      }
    
   db.macrosynopsisinfo.role.attribute = attribute role { text }
   db.macrosynopsisinfo.attlist =
     db.macrosynopsisinfo.role.attribute?
     & db.common.attributes
     & db.common.linking.attributes
     & db.verbatim.attributes
   db.macrosynopsisinfo =
     element macrosynopsisinfo {
       db.macrosynopsisinfo.attlist, db.verbatim.contentmodel
     }
     
    db.macroprototype.role.attribute = attribute role { text }
    db.macroprototype.attlist =
      db.macroprototype.role.attribute?
      & db.common.attributes
      & db.common.linking.attributes
    db.macroprototype =
      element macroprototype {
        db.macroprototype.attlist,
        db.modifier*,
        db.macrodef,
        (db.void
         | db.varargs
         | ((db.paramdef | db.group.paramdef)+, db.varargs?)),
        db.modifier*
      }
      
      db.macrodef.role.attribute = attribute role { text }
      db.macrodef.attlist =
        db.macrodef.role.attribute?
        & db.common.attributes
        & db.common.linking.attributes
      db.macrodef =
        element macrodef {
          db.macrodef.attlist, (db._text | db.type | db.macro)*
        }
}
    
# Deal with enums. 
div {
    ## First the inline elements. 
    db.programming.inlines |= db.enumname | db.enumvalue | db.enumidentifier

    db.enumname.role.attribute = attribute role { text }
    db.enumname.attlist =
       db.enumname.role.attribute?
       & db.common.attributes
       & db.common.linking.attributes
    db.enumname = element enumname { db.enumname.attlist, db._text }
    
    db.enumvalue.role.attribute = attribute role { text }
    db.enumvalue.attlist =
       db.enumvalue.role.attribute?
       & db.common.attributes
       & db.common.linking.attributes
    db.enumvalue = element enumvalue { db.enumvalue.attlist, db._text }
    
    db.enumidentifier.role.attribute = attribute role { text }
    db.enumidentifier.attlist =
       db.enumidentifier.role.attribute?
       & db.common.attributes
       & db.common.linking.attributes
    db.enumidentifier = element enumidentifier { db.enumidentifier.attlist, db._text }

    ## Then the synopsis.
    db.synopsis.blocks |= db.enumsynopsis
    
    db.enumitem.role.attribute = attribute role { text }
    db.enumitem.attlist =
       db.enumitem.role.attribute?
       & db.common.attributes
       & db.common.linking.attributes
    db.enumitem = element enumitem { db.enumvalue.attlist, db.enumidentifier, db.enumvalue? }
    
    db.enumsynopsisinfo =
      element enumsynopsisinfo {
        db.funcsynopsisinfo.attlist, db.verbatim.contentmodel
      }
    
    db.enumsynopsis.attlist = 
       db.common.attributes
       & db.common.linking.attributes
       & db.language.attribute?
    db.enumsynopsis = 
      element enumsynopsis {
        db.enumsynopsis.attlist, 
        db.programming.inlines+, 
        db.enumsynopsisinfo*,
        db.enumitem*
      }
}
  
# Deal with typedefs.
div {
    ## First the inline elements. 
    db.programming.inlines |= db.typedefname
    
    db.typedefname.role.attribute = attribute role { text }
    db.typedefname.attlist =
       db.typedefname.role.attribute?
       & db.common.attributes
       & db.common.linking.attributes
    db.typedefname = element typedefname { db.typedefname.attlist, db._text }
    
    ## Then the synopsis.
    db.synopsis.blocks |= db.typedefsynopsis
    
    db.typedefsynopsis.attlist = 
       db.common.attributes
       & db.common.linking.attributes
       & db.language.attribute?
    db.typedefsynopsis = 
      element typedefsynopsis {
        db.typedefsynopsis.attlist, 
        db.typedefname, 
        db.programming.inlines*
      }
}
@dourouc05
Copy link
Author

@dourouc05 dourouc05 commented Mar 18, 2019

To address the comments I see in https://lists.oasis-open.org/archives/docbook-tc/201902/msg00017.html:

  • I do not see a problem with only one generic synopsisinfo tag. I don't think it would be suitable to name it info, as the kind of information that would be stored in a synopsisinfo would be quite different: whereas info is a wrapper around metadata, a synopsisinfo is designed just to store one specific piece of information (e.g., inheritance for a class, the C/C++ header to include, whether a Java class is final).
  • However, for consistency, the generic synopsisinfo should be allowed everywhere classsynopsisinfo and funcsynopsisinfo are allowed, for sheer consistency (maybe deprecate it?).
  • Semantic inline tags are provided more to ensure some consistency with existing DocBook tags. They are also very useful to indicate the name of the element being documented (like the name of a macro within a macrosynopsis).
@LarryRowland
Copy link

@LarryRowland LarryRowland commented May 8, 2019

You have obviously put a lot of effort into this. I appreciate the work.

I did a pass at trying to represent an enumerated type in preparation for the most recent DocBook meeting and have a few comments that came up from attempting to use the schema. I thought it might be worth getting your insight on them.

Notes on enumsynopsis

  1. How to describe purpose of the enumerated type? Would a description or purpose element be appropriate?
  2. How to describe the significance of the enum identifier -- again, would an element specifically to represent this information be appropriate?
    a. some are obvious (color: red, blue, undefined)
    b. some need extra information (setup: fast, normal, secure)
  3. How to provide hints on how to render (table, similar to glossary, next level of section, etc.)
  4. How to indicate whether it is ordered or not.
  5. It's good that enumvalue is optional since not all languages allow manipulation of the values directly like C-derived languages do.
  6. Is enumtype more reflective of programming than enumname?
  7. Do we need to be able to represent implicit declaration of an enumeration (which could possibly make enumname optional?):
var
    suit: (clubs, diamonds, hearts, spades);
  1. How to deal with "additional attributes":
Shuffle : constant array(Cardsuit) of Cardsuit :=
   (Clubs => Cardsuit'Succ(Clubs), -- see attributes of enumerations 'First, 'Last, 'Succ, 'Pred
    Diamonds => Hearts, --an explicit value
    Hearts => Cardsuit'First, --first enumeration value of type Cardsuit e.g., clubs
    Spades => Cardsuit'Last --last enumeration value of type Cardsuit e.g., spades
   );
  1. enumsynopsis has a lot of legal children and not much help on what is expected/required. In oXygen, an enumsynopsis becomes valid one an enumname is added -- I think it probably should require a least one enumitem (which auto-populates with an enumidentifier, which makes it much easier to use). I would suggest making an enumname required as well as one or more enumitems.
  2. We need to make sure that the descriptions bound into the schema are helpful since some of the elements could be a bit confusing.
  3. It would really help to have some samples of intended usage. Starting from scratch with the schema is not easy to come up with a reasonable sample.
@dourouc05
Copy link
Author

@dourouc05 dourouc05 commented May 9, 2019

Thanks for your feedback! (In the following, I got rid the of *synopsisinfo to replace them with a generic synopsisinfo.)

[1, 2] Very much like a classsynopsis, this is not supported right now. The planned use is rather to have a section per item to document, then to start the section with a synopsis. The rest of the section would then describe the enum. I thought the proposed synopses are machine-readable, and not really as text. Nevertheless, having a possibility to include text within the elements would make sense, depending on how people want to use the tags.

[3] As such, these elements are not made to be rendered. In my use case, all of this is generated, and a human-readable version is spit out (mostly a section title).

[4] What about a new attribute for this? What would be a sensible default value? (There must be a default value. In my use cases, where I generate automatically a large quantity of documentation, there is no way of getting this kind of information, unfortunately...)

[5, 6] I followed what was already done in DocBook, with tags like classname. Similarly, a class describes a type, so I think it's the same issue.

[7] I made the name optional. The same could be done for classes, as anonymous classes also exist (I can only think of Java, though).

[8] I don't really get your point. What are these "additional attributes"? Can't you think of them as values? (I don't really understand your syntax either.)

[9] I really reduced the number of allowed items, many of them indeed made no sense.

[11] See later, I include a few of them.


First, here is the updated description. List of changes:

  • updated for a generic synopsisinfo
  • added an ordered attribute for enumsynopsis
  • the first tag of a synopsis must be a *name tag (instead of any programming inline)
  • at least one enumitem per enumsynopsis
  • macro became macroname for consistency
  • macro no more has an info tag
  • namespace allows for modifiers (which was originally intended)
  • namespacesynopsis can be used recursively (as namespaces can sometimes be nested, e.g. in C++)
  • macrodef no more allows text, to make it easier to use; it now must start with zero or more types (return values) and end with a macroname
  • macrosynopsis forces to use at least one macroprototype (in languages like Julia, there might be some dispatching also on macros)
  • likewise, typedefsynopsis forces at least one programming inline after the name (what is being typedef'd)

The following elements have been added to support needs arising in code documentation:

  • namespace: a container for a name space with modifiers in a programming language. Similar to ooclass.
  • namespacename: the name of a name space. For instance, implemented in C++, Java, C#, XML. Similar to classname.
  • namespacesynopsis: a container for a name space and its contents (which can be recursive). For instance, implemented in C++, Java, C#. Similar to classsynopsis.
  • macroname: the name of a macro. For instance, implemented in C, C++, Scala, Julia (the latter has a specific syntax for calling macros, as opposed to functions; for all languages, macros have very distinct semantics compared to functions — actually, on par with the contrast between a constructor and a method, both of which have different tags). Similar to function.
  • macrosynopsis: a container for the description of a macro. Similar to funcsynopsis.
  • macroprototype: prototype of a macro (its name and its arguments). For instance, implemented in C, C++ (without type information for arguments), Scala, Julia (with facultative type information). Similar to funcprototype.
  • macrodef: definition of a macro (return type and name). For instance, Scala and Julia may require the distinction between a macrodef and a macro (macros may return a value). Similar to funcdef.
  • enumname: the name of an enumerated type. For instance, implemented in C, C++, Scala, Julia.
  • enumvalue: a possible value of an enumeration constant (usually, an integer). For instance, implemented in C, C++, Scala, Julia.
  • enumidentifier: the mnemonic of an enumeration constant (usually, similar to a constant). For instance, implemented in C, C++, Scala, Julia.
  • enumsynopsis: a container for the description of an enumeration and its enumerated values.
  • enumitem: a container for an enumerated value (both a value and an identifier).
  • typedefname: the name of a type alias. For instance, implemented in C, C++, Scala (all with the keyword typedef).
  • typedefsynopsis: a container for the description of a type alias.
  • synopsisinfo: information supplementing the contents of another item. Similar to classsynopsisinfo.

Here is an RNC description of all these tags:

default namespace = "http://docbook.org/ns/docbook"
include "docbookxi.rnc" {
  db.classsynopsis =
    element classsynopsis {
      db.classsynopsis.attlist,
      db.oo.inlines+,
      (db.classsynopsisinfo # Existing tag
       | db.synopsisinfo # New tag, intending to replace the previous one
       | db.methodsynopsis
       | db.constructorsynopsis
       | db.destructorsynopsis
       | db.fieldsynopsis
       | db.synopsis)*
    }
}
db.synopsis = db.enumsynopsis | db.typedefsynopsis

# Generic synopsisinfo. 
db.synopsisinfo.role.attribute = attribute role { text }
db.synopsisinfo.attlist =
  db.synopsisinfo.role.attribute?
  & db.common.attributes
  & db.common.linking.attributes
  & db.verbatim.attributes
db.synopsisinfo =
  element synopsisinfo {
    db.synopsisinfo.attlist, db.verbatim.contentmodel
  }

# Deal with namespaces. 
div {
    ## First the inline elements. 
    db.programming.inlines |= db.namespace | db.namespacename

    db.namespace.role.attribute = attribute role { text }
    db.namespace.attlist =
       db.namespace.role.attribute?
       & db.common.attributes
       & db.common.linking.attributes
    db.namespace = element namespace { db.namespace.attlist, db.modifier*, db.namespacename, db.modifier* }

    db.namespacename.role.attribute = attribute role { text }
    db.namespacename.attlist =
       db.namespacename.role.attribute?
       & db.common.attributes
       & db.common.linking.attributes
    db.namespacename = element namespacename { db.namespacename.attlist, db._text }
    
    ## Then the synopsis.
    db.synopsis.blocks |= db.namespacesynopsis
    
    db.namespacesynopsis.role.attribute = attribute role { text }
    db.namespacesynopsis.attlist =
      db.namespacesynopsis.role.attribute?
      & db.common.attributes
      & db.common.linking.attributes
      & db.language.attribute?
    db.namespacesynopsis = 
      element namespacesynopsis { 
        db.namespacesynopsis.attlist,
        (db.namespace | db.namespacename),
        (db.synopsisinfo
        | db.classsynopsis
        | db.funcsynopsis
        | db.fieldsynopsis
        | db.typedefsynopsis
        | db.macrosynopsis
        | db.enumsynopsis
        | db.namespacesynopsis)*
      }
}

# Deal with macros. Adapted from db.funcsynopsis.
div {
    ## First the inline elements. 
    db.programming.inlines |= db.macroname
        
    db.macroname.role.attribute = attribute role { text }
    db.macroname.attlist =
      db.macroname.role.attribute?
      & db.common.attributes
      & db.common.linking.attributes
    db.macroname =
      element macroname { db.function.attlist, db._text }
    
    ## Then the synopsis.
    db.synopsis.blocks |= db.macrosynopsis
    
    db.macrosynopsis.role.attribute = attribute role { text }
    db.macrosynopsis.attlist =
      db.macrosynopsis.role.attribute?
      & db.common.attributes
      & db.common.linking.attributes
      & db.language.attribute?
    db.macrosynopsis =
      element macrosynopsis {
        db.macrosynopsis.attlist,
        db.macroname,
        db.synopsisinfo*,
        db.macroprototype+,
        db.synopsisinfo*
      }
     
    db.macroprototype.role.attribute = attribute role { text }
    db.macroprototype.attlist =
      db.macroprototype.role.attribute?
      & db.common.attributes
      & db.common.linking.attributes
    db.macroprototype =
      element macroprototype {
        db.macroprototype.attlist,
        db.modifier*,
        db.macrodef,
        (db.void
         | db.varargs
         | ((db.paramdef | db.group.paramdef)+, db.varargs?)),
        db.modifier*
      }
      
      db.macrodef.role.attribute = attribute role { text }
      db.macrodef.attlist =
        db.macrodef.role.attribute?
        & db.common.attributes
        & db.common.linking.attributes
      db.macrodef =
        element macrodef {
          db.macrodef.attlist, db.type*, db.macroname
        }
}
    
# Deal with enums. 
div {
    ## First the inline elements. 
    db.programming.inlines |= db.enumname | db.enumvalue | db.enumidentifier

    db.enumname.role.attribute = attribute role { text }
    db.enumname.attlist =
       db.enumname.role.attribute?
       & db.common.attributes
       & db.common.linking.attributes
    db.enumname = element enumname { db.enumname.attlist, db._text }
    
    db.enumvalue.role.attribute = attribute role { text }
    db.enumvalue.attlist =
       db.enumvalue.role.attribute?
       & db.common.attributes
       & db.common.linking.attributes
    db.enumvalue = element enumvalue { db.enumvalue.attlist, db._text }
    
    db.enumidentifier.role.attribute = attribute role { text }
    db.enumidentifier.attlist =
       db.enumidentifier.role.attribute?
       & db.common.attributes
       & db.common.linking.attributes
    db.enumidentifier = element enumidentifier { db.enumidentifier.attlist, db._text }

    ## Then the synopsis.
    db.synopsis.blocks |= db.enumsynopsis
    
    db.enumitem.role.attribute = attribute role { text }
    db.enumitem.attlist =
       db.enumitem.role.attribute?
       & db.common.attributes
       & db.common.linking.attributes
    db.enumitem = element enumitem { db.enumvalue.attlist, db.enumidentifier, db.enumvalue? }
    
    db.enumitem.ordered.attribute = attribute ordered { text }
    db.enumsynopsis.attlist = 
       db.common.attributes
       & db.common.linking.attributes
       & db.language.attribute?
       & db.enumitem.ordered.attribute
    db.enumsynopsis = 
      element enumsynopsis {
        db.enumsynopsis.attlist, 
        db.enumname?, 
        db.synopsisinfo*,
        db.enumitem+
      }
}
  
# Deal with typedefs.
div {
    ## First the inline elements. 
    db.programming.inlines |= db.typedefname
    
    db.typedefname.role.attribute = attribute role { text }
    db.typedefname.attlist =
       db.typedefname.role.attribute?
       & db.common.attributes
       & db.common.linking.attributes
    db.typedefname = element typedefname { db.typedefname.attlist, db._text }
    
    ## Then the synopsis.
    db.synopsis.blocks |= db.typedefsynopsis
    
    db.typedefsynopsis.attlist = 
       db.common.attributes
       & db.common.linking.attributes
       & db.language.attribute?
    db.typedefsynopsis = 
      element typedefsynopsis {
        db.typedefsynopsis.attlist, 
        db.typedefname, 
        db.programming.inlines+
      }
}

Here are a few examples of how I use the tag set right now (edited for brevity).

A part of QFileInfo:

<?xml version="1.0" encoding="UTF-8"?>
<db:article xmlns:db="http://docbook.org/ns/docbook"
            xmlns:xlink="http://www.w3.org/1999/xlink"
            version="5.2">
   <db:info>
      <db:title>QFileInfo</db:title>
      <db:abstract>
         <db:para>System-independent file information</db:para>
      </db:abstract>
      <db:pubdate>2018-09-08+02:00</db:pubdate>
      <db:date>2018-09-08+02:00</db:date>
      <db:productname>Qt</db:productname>
      <db:productnumber>1.2</db:productnumber>
   </db:info>
   <db:classsynopsis>
      <db:ooclass>
         <db:classname>QFileInfo</db:classname>
      </db:ooclass>
      <db:classsynopsisinfo role="threadsafety">reentrant</db:classsynopsisinfo>
      <db:classsynopsisinfo role="module">QtCore</db:classsynopsisinfo>
      <db:classsynopsisinfo role="headers">#include &lt;qfileinfo.h&gt;</db:classsynopsisinfo>
      <db:classsynopsisinfo role="group">io</db:classsynopsisinfo>
      <db:classsynopsisinfo role="group">shared</db:classsynopsisinfo>
   </db:classsynopsis>
   <db:section xml:id="details">
      <db:title>Detailed Description</db:title>
      <db:para>The <db:code><db:link xlink:href="qfileinfo.html" xrefstyle="class" annotations="QFileInfo">QFileInfo</db:link></db:code> class provides system-independent file information.</db:para>
   </db:section>
   <db:section>
      <db:title>Member Types Documentation</db:title>
      <db:section>
         <db:title>typedef QFileInfoList</db:title>
         <db:typedefsynopsis>
            <db:typedefname>QFileInfoList</db:typedefname>
         </db:typedefsynopsis>
         <db:para>Synonym for <db:code><db:link xlink:href="qlist.html" xrefstyle="class" annotations="QList">QList</db:link></db:code>&lt;<db:code><db:link xlink:href="qfileinfo.html" xrefstyle="class" annotations="QFileInfo">QFileInfo</db:link></db:code>&gt;.</db:para>
      </db:section>
   </db:section>
</db:article>

A short excerpt of Qt Namespace:

<?xml version="1.0" encoding="UTF-8"?>
<db:article xmlns:db="http://docbook.org/ns/docbook"
            xmlns:xlink="http://www.w3.org/1999/xlink">
   <db:info>
      <db:title>Qt</db:title>
      <db:abstract>
         <db:para>Contains miscellaneous identifiers used throughout the Qt library</db:para>
      </db:abstract>
   </db:info>
   <db:namespacesynopsis>
      <db:namespace>
         <db:namespacename>Qt</db:namespacename>
      </db:namespace>
      <db:namespacesynopsisinfo role="module">QtCore</db:namespacesynopsisinfo>
      <db:namespacesynopsisinfo role="headers">#include &lt;qnamespace.h&gt;</db:namespacesynopsisinfo>
   </db:namespacesynopsis>
   <db:section xml:id="details">
      <db:title>Detailed Description</db:title>
   </db:section>
   <db:section>
      <db:title>Member Type Documentation</db:title>
      <db:section>
         <db:title>enum Qt::AlignmentFlag, flags Qt::Alignment</db:title>
         <db:enumsynopsis>
            <db:enumname>Qt::AlignmentFlag</db:enumname>
            <db:enumitem>
               <db:enumidentifier>AlignLeft</db:enumidentifier>
               <db:enumvalue>0x0001</db:enumvalue>
            </db:enumitem>
            <db:enumitem>
               <db:enumidentifier>AlignLeading</db:enumidentifier>
               <db:enumvalue>AlignLeft</db:enumvalue>
            </db:enumitem>
            <db:enumitem>
               <db:enumidentifier>AlignRight</db:enumidentifier>
               <db:enumvalue>0x0002</db:enumvalue>
            </db:enumitem>
            <db:enumitem>
               <db:enumidentifier>AlignTrailing</db:enumidentifier>
               <db:enumvalue>AlignRight</db:enumvalue>
            </db:enumitem>
            <db:enumitem>
               <db:enumidentifier>AlignHCenter</db:enumidentifier>
               <db:enumvalue>0x0004</db:enumvalue>
            </db:enumitem>
            <db:enumitem>
               <db:enumidentifier>AlignJustify</db:enumidentifier>
               <db:enumvalue>0x0008</db:enumvalue>
            </db:enumitem>
            <db:enumitem>
               <db:enumidentifier>AlignAbsolute</db:enumidentifier>
               <db:enumvalue>0x0010</db:enumvalue>
            </db:enumitem>
            <db:enumitem>
               <db:enumidentifier>AlignHorizontal_Mask</db:enumidentifier>
               <db:enumvalue>AlignLeft | AlignRight | AlignHCenter | AlignJustify | AlignAbsolute</db:enumvalue>
            </db:enumitem>
            <db:enumitem>
               <db:enumidentifier>AlignTop</db:enumidentifier>
               <db:enumvalue>0x0020</db:enumvalue>
            </db:enumitem>
            <db:enumitem>
               <db:enumidentifier>AlignBottom</db:enumidentifier>
               <db:enumvalue>0x0040</db:enumvalue>
            </db:enumitem>
            <db:enumitem>
               <db:enumidentifier>AlignVCenter</db:enumidentifier>
               <db:enumvalue>0x0080</db:enumvalue>
            </db:enumitem>
            <db:enumitem>
               <db:enumidentifier>AlignBaseline</db:enumidentifier>
               <db:enumvalue>0x0100</db:enumvalue>
            </db:enumitem>
            <db:enumitem>
               <db:enumidentifier>AlignVertical_Mask</db:enumidentifier>
               <db:enumvalue>AlignTop | AlignBottom | AlignVCenter | AlignBaseline</db:enumvalue>
            </db:enumitem>
            <db:enumitem>
               <db:enumidentifier>AlignCenter</db:enumidentifier>
               <db:enumvalue>AlignVCenter | AlignHCenter</db:enumvalue>
            </db:enumitem>
         </db:enumsynopsis>
         <db:typedefsynopsis>
            <db:typedefname>Qt::Alignment</db:typedefname>
         </db:typedefsynopsis>
         <db:para>This enum type is used to describe alignment. It contains horizontal and vertical flags that can be combined to produce the required effect.</db:para>
         <db:para>The horizontal flags are:</db:para>
         <db:informaltable>
            <db:thead>
               <db:tr>
                  <db:th>
                     <db:para>Constant</db:para>
                  </db:th>
                  <db:th>
                     <db:para>Value</db:para>
                  </db:th>
                  <db:th>
                     <db:para>Description</db:para>
                  </db:th>
               </db:tr>
            </db:thead>
            <db:tbody>
               <db:tr>
                  <db:td>Qt::AlignLeft</db:td>
                  <db:td>0x0001</db:td>
                  <db:td>
                     <db:para>Aligns with the left edge.</db:para>
                  </db:td>
               </db:tr>
               <db:tr>
                  <db:td>Qt::AlignRight</db:td>
                  <db:td>0x0002</db:td>
                  <db:td>
                     <db:para>Aligns with the right edge.</db:para>
                  </db:td>
               </db:tr>
               <db:tr>
                  <db:td>Qt::AlignHCenter</db:td>
                  <db:td>0x0004</db:td>
                  <db:td>
                     <db:para>Centers horizontally in the available space.</db:para>
                  </db:td>
               </db:tr>
               <db:tr>
                  <db:td>Qt::AlignJustify</db:td>
                  <db:td>0x0008</db:td>
                  <db:td>
                     <db:para>Justifies the text in the available space.</db:para>
                  </db:td>
               </db:tr>
            </db:tbody>
         </db:informaltable>
         <db:para>The <db:code>Alignment</db:code> type is a typedef for <db:code>QFlags&lt;AlignmentFlag&gt;</db:code>. It stores an OR combination of  values.</db:para>
      </db:section>
   </db:section>
</db:article>

Now, a new version allowing for text inside. I considered these elements as equivalent to sections. The expected rendering would be to create a new section, the title being the *name tag at the beginning of the synopsis. After this title, the textual content of the synopsis tag should be output; then the items of the synopsis (enumitems, contents of a namespace, methods of a class).

The modifications: allow the synopses as top-level tags or anywhere a section is allowed; after the programming tags, allow text (including sections). It might make sense to disallow other programming synopses within this text (I suppose it is allowed with this RNC). Namespaces are an exception, with text allowed before the other synopses (a namespace can be very long, I guess the best mental model is to first have the description of the namespace, then its contents with their descriptions); the same reasoning could apply to classes as well.

Following your comments, I also added the enumitemdescription tag (I'm not exactly proud of the name...), to describe in detail a specific value of an enumeration (same content model as simpara).

default namespace = "http://docbook.org/ns/docbook"
include "docbookxi.rnc" {
  db.classsynopsis =
    element classsynopsis {
      db.classsynopsis.attlist,
      db.oo.inlines+,
      (db.classsynopsisinfo # Existing tag
       | db.synopsisinfo # New tag, intending to replace the previous one
       | db.methodsynopsis
       | db.constructorsynopsis
       | db.destructorsynopsis
       | db.fieldsynopsis
       | db.synopsis)*
    }
}
db.synopsis = db.enumsynopsis | db.typedefsynopsis

db.programmingsynopsis = db.namespacesynopsis | db.macrosynopsis | db.typedefsynopsis | db.enumsynopsis
start |= db.programmingsynopsis
db.toplevel.sections |= db.programmingsynopsis

# Generic synopsisinfo. 
db.synopsisinfo.role.attribute = attribute role { text }
db.synopsisinfo.attlist =
  db.synopsisinfo.role.attribute?
  & db.common.attributes
  & db.common.linking.attributes
  & db.verbatim.attributes
db.synopsisinfo =
  element synopsisinfo {
    db.synopsisinfo.attlist, db.verbatim.contentmodel
  }

# Deal with namespaces. 
div {
    ## First the inline elements. 
    db.programming.inlines |= db.namespace | db.namespacename

    db.namespace.role.attribute = attribute role { text }
    db.namespace.attlist =
       db.namespace.role.attribute?
       & db.common.attributes
       & db.common.linking.attributes
    db.namespace = element namespace { db.namespace.attlist, db.modifier*, db.namespacename, db.modifier* }

    db.namespacename.role.attribute = attribute role { text }
    db.namespacename.attlist =
       db.namespacename.role.attribute?
       & db.common.attributes
       & db.common.linking.attributes
    db.namespacename = element namespacename { db.namespacename.attlist, db._text }
    
    ## Then the synopsis.
    db.synopsis.blocks |= db.namespacesynopsis
    
    db.namespacesynopsis.role.attribute = attribute role { text }
    db.namespacesynopsis.attlist =
      db.namespacesynopsis.role.attribute?
      & db.common.attributes
      & db.common.linking.attributes
      & db.language.attribute?
    db.namespacesynopsis = 
      element namespacesynopsis { 
        db.namespacesynopsis.attlist,
        (db.namespace | db.namespacename),
        db.recursive.blocks.or.sections?, 
        (db.synopsisinfo
        | db.classsynopsis
        | db.funcsynopsis
        | db.fieldsynopsis
        | db.typedefsynopsis
        | db.macrosynopsis
        | db.enumsynopsis
        | db.namespacesynopsis)*, 
        db.recursive.blocks.or.sections?
      }
}

# Deal with macros. Adapted from db.funcsynopsis.
div {
    ## First the inline elements. 
    db.programming.inlines |= db.macroname
        
    db.macroname.role.attribute = attribute role { text }
    db.macroname.attlist =
      db.macroname.role.attribute?
      & db.common.attributes
      & db.common.linking.attributes
    db.macroname =
      element macroname { db.function.attlist, db._text }
    
    ## Then the synopsis.
    db.synopsis.blocks |= db.macrosynopsis
    
    db.macrosynopsis.role.attribute = attribute role { text }
    db.macrosynopsis.attlist =
      db.macrosynopsis.role.attribute?
      & db.common.attributes
      & db.common.linking.attributes
      & db.language.attribute?
    db.macrosynopsis =
      element macrosynopsis {
        db.macrosynopsis.attlist,
        db.macroname,
        db.synopsisinfo*,
        db.macroprototype+,
        db.synopsisinfo*, 
        db.recursive.blocks.or.sections?
      }
     
    db.macroprototype.role.attribute = attribute role { text }
    db.macroprototype.attlist =
      db.macroprototype.role.attribute?
      & db.common.attributes
      & db.common.linking.attributes
    db.macroprototype =
      element macroprototype {
        db.macroprototype.attlist,
        db.modifier*,
        db.macrodef,
        (db.void
         | db.varargs
         | ((db.paramdef | db.group.paramdef)+, db.varargs?)),
        db.modifier*
      }
      
      db.macrodef.role.attribute = attribute role { text }
      db.macrodef.attlist =
        db.macrodef.role.attribute?
        & db.common.attributes
        & db.common.linking.attributes
      db.macrodef =
        element macrodef {
          db.macrodef.attlist, db.type*, db.macroname
        }
}
    
# Deal with enums. 
div {
    ## First the inline elements. 
    db.programming.inlines |= db.enumname | db.enumvalue | db.enumidentifier

    db.enumname.role.attribute = attribute role { text }
    db.enumname.attlist =
       db.enumname.role.attribute?
       & db.common.attributes
       & db.common.linking.attributes
    db.enumname = element enumname { db.enumname.attlist, db._text }
    
    db.enumvalue.role.attribute = attribute role { text }
    db.enumvalue.attlist =
       db.enumvalue.role.attribute?
       & db.common.attributes
       & db.common.linking.attributes
    db.enumvalue = element enumvalue { db.enumvalue.attlist, db._text }
    
    db.enumitemdescription.role.attribute = attribute role { text }
    db.enumitemdescription.attlist =
       db.enumitemdescription.role.attribute?
       & db.common.attributes
       & db.common.linking.attributes
    db.enumitemdescription = element enumitemdescription { db.enumitemdescription.attlist, db.all.inlines* }
    
    db.enumidentifier.role.attribute = attribute role { text }
    db.enumidentifier.attlist =
       db.enumidentifier.role.attribute?
       & db.common.attributes
       & db.common.linking.attributes
    db.enumidentifier = element enumidentifier { db.enumidentifier.attlist, db._text }

    ## Then the synopsis.
    db.synopsis.blocks |= db.enumsynopsis
    
    db.enumitem.role.attribute = attribute role { text }
    db.enumitem.attlist =
       db.enumitem.role.attribute?
       & db.common.attributes
       & db.common.linking.attributes
    db.enumitem = element enumitem { db.enumvalue.attlist, db.enumidentifier, db.enumvalue? }
    
    db.enumitem.ordered.attribute = attribute ordered { text }
    db.enumsynopsis.attlist = 
       db.common.attributes
       & db.common.linking.attributes
       & db.language.attribute?
       & db.enumitem.ordered.attribute
    db.enumsynopsis = 
      element enumsynopsis {
        db.enumsynopsis.attlist, 
        db.enumname?, 
        db.synopsisinfo*,
        db.enumitem+, 
        db.recursive.blocks.or.sections?
      }
}
  
# Deal with typedefs.
div {
    ## First the inline elements. 
    db.programming.inlines |= db.typedefname
    
    db.typedefname.role.attribute = attribute role { text }
    db.typedefname.attlist =
       db.typedefname.role.attribute?
       & db.common.attributes
       & db.common.linking.attributes
    db.typedefname = element typedefname { db.typedefname.attlist, db._text }
    
    ## Then the synopsis.
    db.synopsis.blocks |= db.typedefsynopsis
    
    db.typedefsynopsis.attlist = 
       db.common.attributes
       & db.common.linking.attributes
       & db.language.attribute?
    db.typedefsynopsis = 
      element typedefsynopsis {
        db.typedefsynopsis.attlist, 
        db.typedefname, 
        db.programming.inlines+, 
        db.recursive.blocks.or.sections?
      }
}

From now on, it may be easier for everyone to use a pull request, so I could directly modify the DocBook schema locally (keeping in mind this is an extension), instead of having large chunks of code in comments. Should I go with or without descriptions within the synopses?

@bobstayton
Copy link
Contributor

@bobstayton bobstayton commented Jun 12, 2019

Last month I posted to the Docbook mailing list your proposed schema changes to see if anyone had a comment. One response pointed out that a Google Summer of Code project had done something similar for C++, along with a stylesheet. That project was never adopted because it was too specific (C++ only). The DocBook TC was hoping you could take a look at this previous work to see: a) if your proposal covers the same territory but in more general terms to cover more languages, and b) if it contributes any new ideas for your proposal. Here is a link to that subproject on Github:
https://github.com/docbook/xslt10-stylesheets/tree/api/docbook/relaxng/api

@dourouc05
Copy link
Author

@dourouc05 dourouc05 commented Jun 12, 2019

I responded on the mailing list; do you need anything else? There are indeed a few functionalities that could be added, but nothing that revolutionises this proposal; I was waiting for an answer on whether text should be allowed in the synopses or not (see my previous comment) before going on in that direction.

@dourouc05
Copy link
Author

@dourouc05 dourouc05 commented Jun 22, 2019

Just to make it easier to collaborate, I uploaded the schema and the samples on a new repository: https://github.com/dourouc05/DocBookLibrary. I plan on adding new things from the existing API schema (and samples).

API (Boost) Library (this proposal)
class-specialization new specializedtemplate
link-test, link-fail-test, source, compile-test, if-fails, requirement, run-test, run-fail-test, compile-fail-test, testsuite suppressed (tests are out of scope)
typedef new typedefsynopsis
static-constant existing fieldsynopsis with modifier="static"
code duplicates existing functionality (computeroutput)
destructor existing destructorsynopsis
template-type-parameter, template-arg, template, template-nontype-parameter new template/templateid
template-varargs new template
description, postconditions, notes, precondition, returns, purpose, requires, effects, rationale suppressed (put the relevant text inside a synopsis or in the section around the synopsis) -- highly specific for Boost, I don't think it's relevant to standardise
librarylist suppressed (overkill: could just be an itemizedlist)
library-reference, api, header, librarycategory, librarypurpose, librarycategorydef, library, librarycategorylist, lib, libraryname, libraryinfo suppressed (seems to act as a root tag, then list contents file-by-file: just use an article, with one section per file, possibly using abstracts?)
union new unionsynopsis/unionname/union
inherit, headername new synopsisinfo within classsynopsis
function existing funcsynopsis
macroname new macroname/macrosynopsis
method existing methodsynopsis
snippet redundant with programlisting and XInclude, as I understand it
constructor existing constructorsynopsis
namespace new namespacesynopsis
free-function-group, using-class, using-namespace free functions can be specified just after the corresponding class
specialization, union-specialization, struct-specialization specialization of other things
functionname existing function
data-member existing fieldsynopsis
throws new synopsisinfo
globalname to be added
method-group to be added
paramtype existing type
copy-assignment highly specific to C++; could just be a methodsynopsis whose name is operator=
default existing initializer (but only for methodsynopsis)
parameter existing parameter (but only for methodsynopsis), existing paramdef (but only for funcsynopsis)
signature, overloaded-function, overloaded-method new synopsisinfo
access existing modifier
class existing classsynopsis
type existing type and void
enumvalue new enumvalue
programlisting existing programlisting
enumname new enumname
struct existing classsynopsis (in C++, structs are equivalent to enums; in other languages, the equivalent of structs are rather called data classes, like Kotlin or Python), potentially with a new synopsisinfo
@dourouc05
Copy link
Author

@dourouc05 dourouc05 commented Aug 22, 2019

I've just updated both the table, the RNG, and the samples to include templates/generics/parametric types, with examples in C++, Java, and Julia (as the syntax is quite different in these three languages).

@LarryRowland
Copy link

@LarryRowland LarryRowland commented Sep 11, 2019

Sorry it has taken me so long to get back to you. Things have been pretty busy at work and that really slows down my participation in the DocBook TC.

I am not entirely confident with elevating these new elements to section-level equivalents. I think they are closer in concept to something like a formal table (or other formal elements that have titles). I suspect the RefEntry in DocBook (https://tdg.docbook.org/tdg/5.0/refentry.html) would be roughly the equivalent to what you are talking about (we should make the *synopsis elements valid children of refsynopsisdiv). This sounds much more like a formal element (basically, elements that have titles, so that they can show up in a list of tables, list of figures, etc.). I would lean towards continuing to use refentry elements to contain structured content associated with the *synopsis elements rather than spawn a new element that shows up in parallel with other structural elements when the element content is so highly specialized.

If the RefEntry element is too highly structured (it was originally developed to represent content that mapped to Unix Man pages which is very prescriptive to make it easy to summarize automatically) it would also be possible to use regular sections to contain additional content associated with a specific *synopsis element if the *synopsis elements block elements the same way the synopsis element is.

I hope I haven't missed what was driving you towards making these section-equivalent level elements, because I am very impressed with all that has gone into this so far.

@dourouc05
Copy link
Author

@dourouc05 dourouc05 commented Sep 20, 2019

Actually, my original plan was not to have the new synopses as equivalent to sections (what I have in mind is to start a section for documenting a function, an enum, whatsoever, then have a synopsis to formalise things, then more text for the doc). That equivalence came after your first set of comments (I thought it was your idea, with allowing text within the synopses), and has now been removed.

I don't think it's worth it to rework refentry to allow these synopses, as the content model is quite far away (much more prescriptive), the standard sections are more than enough.

@dourouc05
Copy link
Author

@dourouc05 dourouc05 commented Oct 15, 2019

Just for the record: this proposal is currently used in some tools I develop (https://github.com/dourouc05/QtDocTools), plus is getting integrated into Qt's qdoc (https://codereview.qt-project.org/c/qt/qttools/+/276759).

@ndw
Copy link
Contributor

@ndw ndw commented Dec 12, 2019

There are a lot of new synopses in this proposal. A few illustrative examples of each new synopsis type would be helpful.

@dourouc05
Copy link
Author

@dourouc05 dourouc05 commented Dec 12, 2019

There are quite a few examples there: https://github.com/dourouc05/DocBookLibrary. Or would you need more of them?

@bobstayton
Copy link
Contributor

@bobstayton bobstayton commented Dec 12, 2019

@dourouc05
Copy link
Author

@dourouc05 dourouc05 commented Dec 28, 2019

Following https://lists.oasis-open.org/archives/docbook-tc/201912/msg00003.html, if you need any help to create samples, doc, I can provide some (including PRs to the Definitive Guide).

qtprojectorg pushed a commit to qt/qttools that referenced this issue Jan 3, 2020
The use of this code would be to overhaul the translation project of
the documentation in French, for Developpez.com (which is now stuck
at Qt 4.7 due to outdated tools: https://qt.developpez.com/doc/).
This means that this code will be used and maintained, whatever the
decision follows QTBUG-71493, for instance.

The DocBook support is not 100% vanilla DocBook, as some tags are
missing, but rather an extension (which could be officialised soon:
docbook/docbook#111). These tags are used
to encode metadata about the code being commented (classes, fields,
functions, etc.). More precisely, the required tags are:
[enum|macro|namespace|typedef|union][|name|synopsis],
enum[value|identifier|item], [specialized]template[id].
These extensions can be enabled by the docbook-extensions parameter.

If you want to see the history:
https://github.com/dourouc05/qttools/tree/dourouc05-qdoc-docbook

Change-Id: I919976d8680b41c5ca69bdb79a0b824c29b89d05
Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
Reviewed-by: Paul Wicking <paul.wicking@qt.io>
Reviewed-by: Martin Smith <martin.smith@qt.io>
@kosek
Copy link
Contributor

@kosek kosek commented Apr 15, 2020

Hi, I have been tasked to incorporate this into a next beta release of DocBook schema.

I have found some inconsistencies, I will create separate reply for each of them so discussion.

First one: methodparam in can specify only one of either type or templateid:

(db.type | db.templateid)?

but DocBook allows multiple type elements at this position

db.type*

Proposed change is not backwards compatible and could render some existing content as invalid. I don't know if specifying multiple types for methodparam makes sense (but I can imagine that some languages allow for this). If multiple types are OK then we probably should use

(db.type+ | db.templateid)?
@dourouc05
Copy link
Author

@dourouc05 dourouc05 commented Apr 15, 2020

I'm not sure if multiple types really make sense, but why not. In this case, I suppose templateid should be treated the same, with something like this:

(db.type | db.templateid)+

After all, a template ID is just a placeholder for a type, so that would be consistent. In the end, it's the user's job to encode something that makes sense for their use case.

@kosek
Copy link
Contributor

@kosek kosek commented Apr 18, 2020

Next one:
proposed changes to methodparam element ends with

      db.para* # Just paragraphs: a parameter should not need much more (unlike the method itself). 

It seems quite inconsistent to allow only para if all blocks are supported in similar contexts. So for the sake of consistency having db.recursive.blocks.or.sections should be used there as well.

@kosek
Copy link
Contributor

@kosek kosek commented Apr 18, 2020

Another one:

 db.type =
    element type { 
      db.type.attlist, 
      (db._text | db.templateid | db.programming.inlines)* 
    }

Why db.programming.inlines is added here? Existing definitions is:

(db._text | db.type)*

So nested types are allowed, adding templateid makes sense. What is use-case for allowing additional inline elements here?

@kosek
Copy link
Contributor

@kosek kosek commented Apr 18, 2020

Another one:

Content mode for synopsisnfo is

(db.verbatim.contentmodel | (db.programming.inlines?, db.para*))

Allowing db.programming inlines followed by paras seems quite strange. I don't think that such model where inline and block elements can be combined on the same level is already used somewhere else in the DocBook.

Also restricting content to only paras seem perhaps too restrictive. What about:

(db.verbatim.contentmodel | db.all.blocks+)
@dourouc05
Copy link
Author

@dourouc05 dourouc05 commented Apr 18, 2020

#111 (comment)

With this change, you can represent more types in C, like structs (encoded as DocBook classes, since it's the closest and I'm not sure it's worth it to make an explicit distinction — especially since in C++ you can add methods to structs…):

struct X { … };
<para>
    We use a variable of type <type><classname>X</classname></type>. 
</para>
<!-- Without it, it looks more dubious, mixing a name and a keyword that has nothing to do with types: -->
<para>
    We use a variable of type <type>struct X</type>. 
</para>
@dourouc05
Copy link
Author

@dourouc05 dourouc05 commented Apr 18, 2020

#111 (comment)

This is more of a remainder of a previous iteration on this.

However, the mix of inlines and blocks is still used in other parts of the proposed changes, for instance in namespacesynopsis: first, the name of the name space (akin to a title for a section); then, its documentation.

@kosek
Copy link
Contributor

@kosek kosek commented Apr 19, 2020

#111 (comment)

OK, I will keep programming inlines as allowed in the type content type.

@kosek
Copy link
Contributor

@kosek kosek commented Apr 19, 2020

#111 (comment)

namespacesynopsis content model looks fine to me. I have looked into samples (sorry I'm going over your changes piece by piece as I found slots of free time). So I see why inline element is there, but I think we should allow all bloks, not only paragraphs, ie.

(db.verbatim.contentmodel | (db.programming.inlines?, db.all.blocks*))

ok?

@kosek
Copy link
Contributor

@kosek kosek commented Apr 19, 2020

I have noticed that elements template and specializedtemplate are declared without having any common attributes. I suppose that this was just unintended omission.

@kosek
Copy link
Contributor

@kosek kosek commented Apr 19, 2020

What is purpose and allowed values for the following attribute:

    db.enumitem.ordered.attribute = attribute ordered { text }

I don't see any example.

kosek added a commit to kosek/docbook that referenced this issue Apr 19, 2020
@kosek
Copy link
Contributor

@kosek kosek commented Apr 19, 2020

@dourouc05 could you please look at https://github.com/kosek/docbook/blob/docbook-5.2-dev/relaxng/schemas/docbook/programming.rnc and fill in missing one sentence descriptions of new elements into placeholders marked with "FIXME". Ideally do this as a PR. Then I will be able to create PR against master schema repo and generated new beta release of DocBook schema with your additions.

@dourouc05
Copy link
Author

@dourouc05 dourouc05 commented Apr 19, 2020

#111 (comment)

That's fine for me!

@dourouc05
Copy link
Author

@dourouc05 dourouc05 commented Apr 19, 2020

#111 (comment)

That's more a lack of skill and/or habit with RelaxNG on my side :).

@dourouc05
Copy link
Author

@dourouc05 dourouc05 commented Apr 19, 2020

#111 (comment)

It's for modelling some enums like you have in C++, where you don't have to specify values for each enumerated value. In that case, you do not necessarily have a enumvalue for each enumitem, but you can compute it, as long as you don't change anything in the order of the enumitems.

enum Foo { a = 1, b, c };
<enumsynopsis ordered="true">
	<enumname>Foo</enumname>
	<enumitem><enumidentifier>a</enumidentifier><enumvalue>1</enumvalue></enumitem>
	<enumitem><enumidentifier>b</enumidentifier></enumitem>
	<enumitem><enumidentifier>c</enumidentifier></enumitem>
</enumsynopsis>
@dourouc05
Copy link
Author

@dourouc05 dourouc05 commented Apr 19, 2020

#111 (comment)

I just made a PR for this: kosek#1.

@kosek
Copy link
Contributor

@kosek kosek commented Apr 20, 2020

#111 (comment)

OK, I see. So this attribute can appear both on enumsynopsis and unionsynopsis elements as union can contain enum type. Right?

One more thing. We have to enumerate values for ordered attribute in the schema. For few boolean values DocBook used values 0 and 1 and not false and true. I have also added short description for these two values (see kosek@53ba6a4) Please let me know if description should be changed/improved.

kosek added a commit that referenced this issue Apr 20, 2020
Added new markup for libraries #111
@kosek
Copy link
Contributor

@kosek kosek commented Apr 20, 2020

This has been included in base schema in PR #134

@kosek kosek closed this Apr 20, 2020
@dourouc05
Copy link
Author

@dourouc05 dourouc05 commented Apr 20, 2020

Great 👍 !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
5 participants
You can’t perform that action at this time.