[libvirt] [PATCH v2 0/7] documentation improvements

Hi. Version 2 of this series incorporates the following changes: - patch #1 fail if documentation is missing - reword subject line of patch #3 as suggessted by Eric Incidently, patch #1 truthfully makes the build fail because of missing documentation. Go figure :) I'll submit a single patch with a fix shortly. Claudio Bley (7): docs: abort when missing return or argument documention docs: only generate function argument info for args with a description docs: use div, not table, for notices on opaque types docs: process code blocks similar to markdown docs: add class "description" to div's containing descriptions docs: define style of code blocks inside descriptions docs: syntax highlight code blocks using SHJS docs/apibuild.py | 15 +++- docs/libvirt.css | 8 ++ docs/newapi.xsl | 209 +++++++++++++++++++++++++++++-------------------- docs/page.xsl | 5 +- docs/sh_c.min.js | 1 + docs/sh_emacs.min.css | 1 + docs/sh_main.min.js | 4 + 7 files changed, 157 insertions(+), 86 deletions(-) create mode 100644 docs/sh_c.min.js create mode 100644 docs/sh_emacs.min.css create mode 100644 docs/sh_main.min.js -- 1.7.9.5

When a function has no associated information to one of its arguments or its return type we report it and stop with an error. Signed-off-by: Claudio Bley <cbley@av-test.de> --- docs/apibuild.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/docs/apibuild.py b/docs/apibuild.py index 9a29c42..0ca6e7c 100755 --- a/docs/apibuild.py +++ b/docs/apibuild.py @@ -1962,12 +1962,17 @@ class docBuilder: self.xref = {} self.index = {} self.basename = name + self.errors = 0 def warning(self, msg): global warnings warnings = warnings + 1 print msg + def error(self, msg): + self.errors += 1 + print >>sys.stderr, "Error:", msg + def indexString(self, id, str): if str == None: return @@ -2185,6 +2190,8 @@ class docBuilder: if ret[0] != None: if ret[0] == "void": output.write(" <return type='void'/>\n") + elif ret[1] == None or ret[1] == '': + self.error("Missing documentation for return of function `%s'." % name) else: output.write(" <return type='%s' info='%s'/>\n" % ( ret[0], escape(ret[1]))) @@ -2192,8 +2199,8 @@ class docBuilder: for param in params: if param[0] == 'void': continue - if param[2] == None: - output.write(" <arg name='%s' type='%s' info=''/>\n" % (param[1], param[0])) + if param[2] == None or param[2] == '': + self.error("Missing documentation for arg `%s' of function `%s'." % (name, param[1])) else: output.write(" <arg name='%s' type='%s' info='%s'/>\n" % (param[1], param[0], escape(param[2]))) self.indexString(name, param[2]) @@ -2462,6 +2469,10 @@ class docBuilder: output.write("</api>\n") output.close() + if self.errors > 0: + print >>sys.stderr, "apibuild.py: %d error(s) encountered during generation. Stop." % self.errors + sys.exit(3) + filename = "%s/%s-refs.xml" % (self.path, self.name) if not quiet: print "Saving XML Cross References %s" % (filename) -- 1.7.9.5

On 01/29/2013 08:05 AM, Claudio Bley wrote:
When a function has no associated information to one of its arguments or its return type we report it and stop with an error.
s/documention/documentation/ in the subject.
Signed-off-by: Claudio Bley <cbley@av-test.de> --- docs/apibuild.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
In isolation, this fails 'make check' and 'make syntax-check'; please fix your series to have this patch apply cleanly, and/or call out the prerequisite patches that must be reviewed and applied first.
@@ -2462,6 +2469,10 @@ class docBuilder: output.write("</api>\n") output.close()
+ if self.errors > 0: + print >>sys.stderr, "apibuild.py: %d error(s) encountered during generation. Stop." % self.errors
"Stop." doesn't add anything to the error message; it's already obvious from 'make' exiting that things stopped abnormally. Here's what I suggest squashing in to fix the 'make syntax-check' side of things: diff --git i/docs/apibuild.py w/docs/apibuild.py index 0ca6e7c..79b8795 100755 --- i/docs/apibuild.py +++ w/docs/apibuild.py @@ -2191,7 +2191,7 @@ class docBuilder: if ret[0] == "void": output.write(" <return type='void'/>\n") elif ret[1] == None or ret[1] == '': - self.error("Missing documentation for return of function `%s'." % name) + self.error("Missing documentation for return of function `%s'" % name) else: output.write(" <return type='%s' info='%s'/>\n" % ( ret[0], escape(ret[1]))) @@ -2200,7 +2200,7 @@ class docBuilder: if param[0] == 'void': continue if param[2] == None or param[2] == '': - self.error("Missing documentation for arg `%s' of function `%s'." % (name, param[1])) + self.error("Missing documentation for arg `%s' of function `%s'" % (name, param[1])) else: output.write(" <arg name='%s' type='%s' info='%s'/>\n" % (param[1], param[0], escape(param[2]))) self.indexString(name, param[2]) @@ -2470,7 +2470,7 @@ class docBuilder: output.close() if self.errors > 0: - print >>sys.stderr, "apibuild.py: %d error(s) encountered during generation. Stop." % self.errors + print >>sys.stderr, "apibuild.py: %d error(s) encountered during generation" % self.errors sys.exit(3) filename = "%s/%s-refs.xml" % (self.path, self.name) Then we do have our hands full with some missing docs: GEN apibuild.py.stamp Error: Missing documentation for return of function `virConnCopyLastError' Error: Missing documentation for arg `virConnCopyLastError' of function `conn' Error: Missing documentation for arg `virConnCopyLastError' of function `to' Error: Missing documentation for return of function `virConnGetLastError' Error: Missing documentation for arg `virConnGetLastError' of function `conn' Error: Missing documentation for arg `virConnResetLastError' of function `conn' Error: Missing documentation for arg `virConnSetErrorFunc' of function `conn' Error: Missing documentation for arg `virConnSetErrorFunc' of function `userData' Error: Missing documentation for arg `virConnSetErrorFunc' of function `handler' Error: Missing documentation for arg `virConnectCloseFunc' of function `conn' Error: Missing documentation for arg `virConnectCloseFunc' of function `reason' Error: Missing documentation for arg `virConnectCloseFunc' of function `opaque' Error: Missing documentation for arg `virConnectDomainEventBlockJobCallback' of function `disk' Error: Missing documentation for arg `virConnectDomainEventBlockJobCallback' of function `opaque' Error: Missing documentation for return of function `virConnectDomainEventCallback' Error: Missing documentation for return of function `virCopyLastError' Error: Missing documentation for arg `virCopyLastError' of function `to' Error: Missing documentation for arg `virDefaultErrorFunc' of function `err' Error: Missing documentation for return of function `virEventAddHandle' Error: Missing documentation for arg `virEventAddHandle' of function `fd' Error: Missing documentation for arg `virEventAddHandle' of function `events' Error: Missing documentation for arg `virEventAddHandle' of function `cb' Error: Missing documentation for arg `virEventAddHandle' of function `opaque' Error: Missing documentation for arg `virEventAddHandle' of function `ff' Error: Missing documentation for return of function `virEventAddTimeout' Error: Missing documentation for arg `virEventAddTimeout' of function `timeout' Error: Missing documentation for arg `virEventAddTimeout' of function `cb' Error: Missing documentation for arg `virEventAddTimeout' of function `opaque' Error: Missing documentation for arg `virEventAddTimeout' of function `ff' Error: Missing documentation for return of function `virEventRemoveHandle' Error: Missing documentation for arg `virEventRemoveHandle' of function `watch' Error: Missing documentation for return of function `virEventRemoveHandleFunc' Error: Missing documentation for return of function `virEventRemoveTimeout' Error: Missing documentation for arg `virEventRemoveTimeout' of function `timer' Error: Missing documentation for arg `virEventUpdateHandle' of function `watch' Error: Missing documentation for arg `virEventUpdateHandle' of function `events' Error: Missing documentation for arg `virEventUpdateTimeout' of function `timer' Error: Missing documentation for arg `virEventUpdateTimeout' of function `timeout' Error: Missing documentation for arg `virFreeError' of function `err' Error: Missing documentation for return of function `virGetLastError' Error: Missing documentation for arg `virResetError' of function `err' Error: Missing documentation for return of function `virSaveLastError' Error: Missing documentation for arg `virSetErrorFunc' of function `userData' Error: Missing documentation for arg `virSetErrorFunc' of function `handler' apibuild.py: 44 error(s) encountered during generation -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

At Tue, 29 Jan 2013 12:02:35 -0700, Eric Blake wrote:
[1 <text/plain; UTF-8 (quoted-printable)>] On 01/29/2013 08:05 AM, Claudio Bley wrote:
When a function has no associated information to one of its arguments or its return type we report it and stop with an error.
s/documention/documentation/ in the subject.
Fixed.
Signed-off-by: Claudio Bley <cbley@av-test.de> --- docs/apibuild.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
In isolation, this fails 'make check' and 'make syntax-check'; please fix your series to have this patch apply cleanly, and/or call out the prerequisite patches that must be reviewed and applied first.
OK, will do.
@@ -2462,6 +2469,10 @@ class docBuilder: output.write("</api>\n") output.close()
+ if self.errors > 0: + print >>sys.stderr, "apibuild.py: %d error(s) encountered during generation. Stop." % self.errors
"Stop." doesn't add anything to the error message; it's already obvious from 'make' exiting that things stopped abnormally.
Here's what I suggest squashing in to fix the 'make syntax-check' side of things:
OK, squashed in.
Then we do have our hands full with some missing docs:
GEN apibuild.py.stamp Error: Missing documentation for return of function `virConnCopyLastError' Error: Missing documentation for arg `virConnCopyLastError' of function `conn' Error: Missing documentation for arg `virConnCopyLastError' of function `to' Error: Missing documentation for return of function `virConnGetLastError' Error: Missing documentation for arg `virConnGetLastError' of function `conn' Error: Missing documentation for arg `virConnResetLastError' of function `conn' Error: Missing documentation for arg `virConnSetErrorFunc' of function `conn' Error: Missing documentation for arg `virConnSetErrorFunc' of function `userData' Error: Missing documentation for arg `virConnSetErrorFunc' of function `handler' Error: Missing documentation for arg `virConnectCloseFunc' of function `conn' Error: Missing documentation for arg `virConnectCloseFunc' of function `reason' Error: Missing documentation for arg `virConnectCloseFunc' of function `opaque' Error: Missing documentation for arg `virConnectDomainEventBlockJobCallback' of function `disk' Error: Missing documentation for arg `virConnectDomainEventBlockJobCallback' of function `opaque' Error: Missing documentation for return of function `virConnectDomainEventCallback' Error: Missing documentation for return of function `virCopyLastError' Error: Missing documentation for arg `virCopyLastError' of function `to' Error: Missing documentation for arg `virDefaultErrorFunc' of function `err' Error: Missing documentation for return of function `virEventAddHandle' Error: Missing documentation for arg `virEventAddHandle' of function `fd' Error: Missing documentation for arg `virEventAddHandle' of function `events' Error: Missing documentation for arg `virEventAddHandle' of function `cb' Error: Missing documentation for arg `virEventAddHandle' of function `opaque' Error: Missing documentation for arg `virEventAddHandle' of function `ff' Error: Missing documentation for return of function `virEventAddTimeout' Error: Missing documentation for arg `virEventAddTimeout' of function `timeout' Error: Missing documentation for arg `virEventAddTimeout' of function `cb' Error: Missing documentation for arg `virEventAddTimeout' of function `opaque' Error: Missing documentation for arg `virEventAddTimeout' of function `ff' Error: Missing documentation for return of function `virEventRemoveHandle' Error: Missing documentation for arg `virEventRemoveHandle' of function `watch' Error: Missing documentation for return of function `virEventRemoveHandleFunc' Error: Missing documentation for return of function `virEventRemoveTimeout' Error: Missing documentation for arg `virEventRemoveTimeout' of function `timer' Error: Missing documentation for arg `virEventUpdateHandle' of function `watch' Error: Missing documentation for arg `virEventUpdateHandle' of function `events' Error: Missing documentation for arg `virEventUpdateTimeout' of function `timer' Error: Missing documentation for arg `virEventUpdateTimeout' of function `timeout' Error: Missing documentation for arg `virFreeError' of function `err' Error: Missing documentation for return of function `virGetLastError' Error: Missing documentation for arg `virResetError' of function `err' Error: Missing documentation for return of function `virSaveLastError' Error: Missing documentation for arg `virSetErrorFunc' of function `userData' Error: Missing documentation for arg `virSetErrorFunc' of function `handler' apibuild.py: 44 error(s) encountered during generation
With commit 790d364ca282893b12afc9fa2779ba2ff70aa4de in place (ref. https://www.redhat.com/archives/libvir-list/2013-January/msg02029.html), we're down to 26 errors. Of those, 19 are internal functions being part of the "ignored_functions" dictionary in apibuild.py. I'm just going to ignore them too, ie. will not generate an error if documentation is missing. Then, these are the remaining errors: GEN apibuild.py.stamp Error: Missing documentation for arg `conn' of function `virConnectCloseFunc' Error: Missing documentation for arg `reason' of function `virConnectCloseFunc' Error: Missing documentation for arg `opaque' of function `virConnectCloseFunc' Error: Missing documentation for arg `disk' of function `virConnectDomainEventBlockJobCallback' Error: Missing documentation for arg `opaque' of function `virConnectDomainEventBlockJobCallback' Error: Missing documentation for return of function `virConnectDomainEventCallback' Error: Missing documentation for return of function `virEventRemoveHandleFunc' apibuild.py: 7 error(s) encountered during generation When having https://www.redhat.com/archives/libvir-list/2013-January/msg02071.html applied there are only the last two errors left. Regarding virEventRemoveHandleFunc, I just overlooked this when throwing together the above mentioned series. A followup patch is coming. It seems to me, that currently the return value of virConnectDomainEventCallback isn't used at all. Should we just add Returns [unused] you should always return 0. Or should we just use the usual "-1 on error, 0 on success" wording? But what are the consequences if you return -1 from this callback? -- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern

When function arguments or return values lack a description there's no use in generating a meaningless "ARG1: " stanza. Signed-off-by: Claudio Bley <cbley@av-test.de> --- docs/newapi.xsl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/newapi.xsl b/docs/newapi.xsl index 0d32e55..fb95c44 100644 --- a/docs/newapi.xsl +++ b/docs/newapi.xsl @@ -533,9 +533,9 @@ </xsl:call-template> </div><xsl:text> </xsl:text> - <xsl:if test="arg | return/@info"> + <xsl:if test="arg[@info] | return/@info"> <dl class="variablelist"> - <xsl:for-each select="arg"> + <xsl:for-each select="arg[@info]"> <dt><xsl:value-of select="@name"/></dt> <dd> <xsl:call-template name="dumptext"> -- 1.7.9.5

It's simpler to render and it prevents wrapping the line too early because of the table spacing, border et cetera. Signed-off-by: Claudio Bley <cbley@av-test.de> --- docs/libvirt.css | 1 + docs/newapi.xsl | 110 +++++++++++++++++++++++++++--------------------------- 2 files changed, 55 insertions(+), 56 deletions(-) diff --git a/docs/libvirt.css b/docs/libvirt.css index 5dc5d9b..8a00d12 100644 --- a/docs/libvirt.css +++ b/docs/libvirt.css @@ -447,6 +447,7 @@ table.data tbody td.n { letter-spacing: .3ex; font-weight: bolder; text-transform: uppercase; + margin-left: 2em; } .api .directive { diff --git a/docs/newapi.xsl b/docs/newapi.xsl index fb95c44..09395ea 100644 --- a/docs/newapi.xsl +++ b/docs/newapi.xsl @@ -213,14 +213,51 @@ <xsl:text> { </xsl:text> </pre> - <table> - <xsl:for-each select="field"> - <xsl:choose> - <xsl:when test='@type = "union"'> - <tr><td><span class="keyword">union</span> {</td></tr> - <tr> - <td><table> - <xsl:for-each select="union/field"> + <xsl:if test="field"> + <table> + <xsl:for-each select="field"> + <xsl:choose> + <xsl:when test='@type = "union"'> + <tr><td><span class="keyword">union</span> {</td></tr> + <tr> + <td><table> + <xsl:for-each select="union/field"> + <tr> + <td> + <span class="type"> + <xsl:call-template name="dumptext"> + <xsl:with-param name="text" select="@type"/> + </xsl:call-template> + </span> + </td> + <td><xsl:value-of select="@name"/></td> + <xsl:if test="@info != ''"> + <td> + <div class="comment"> + <xsl:call-template name="dumptext"> + <xsl:with-param name="text" select="@info"/> + </xsl:call-template> + </div> + </td> + </xsl:if> + </tr> + </xsl:for-each> + </table></td> + <td></td></tr> + <tr><td>}</td> + <td><xsl:value-of select="@name"/></td> + <xsl:if test="@info != ''"> + <td> + <div class="comment"> + <xsl:call-template name="dumptext"> + <xsl:with-param name="text" select="@info"/> + </xsl:call-template> + </div> + </td> + </xsl:if> + <td></td></tr> + </xsl:when> + <xsl:otherwise> <tr> <td> <span class="type"> @@ -234,59 +271,20 @@ <td> <div class="comment"> <xsl:call-template name="dumptext"> - <xsl:with-param name="text" select="@info"/> + <xsl:with-param name="text" select="@info"/> </xsl:call-template> </div> </td> </xsl:if> </tr> - </xsl:for-each> - </table></td> - <td></td></tr> - <tr><td>}</td> - <td><xsl:value-of select="@name"/></td> - <xsl:if test="@info != ''"> - <td> - <div class="comment"> - <xsl:call-template name="dumptext"> - <xsl:with-param name="text" select="@info"/> - </xsl:call-template> - </div> - </td> - </xsl:if> - <td></td></tr> - </xsl:when> - <xsl:otherwise> - <tr> - <td> - <span class="type"> - <xsl:call-template name="dumptext"> - <xsl:with-param name="text" select="@type"/> - </xsl:call-template> - </span> - </td> - <td><xsl:value-of select="@name"/></td> - <xsl:if test="@info != ''"> - <td> - <div class="comment"> - <xsl:call-template name="dumptext"> - <xsl:with-param name="text" select="@info"/> - </xsl:call-template> - </div> - </td> - </xsl:if> - </tr> - </xsl:otherwise> - </xsl:choose> - </xsl:for-each> - <xsl:if test="not(field)"> - <tr> - <td colspan="3"> - <span class="undisclosed">The content of this structure is not made public by the API</span> - </td> - </tr> - </xsl:if> - </table> + </xsl:otherwise> + </xsl:choose> + </xsl:for-each> + </table> + </xsl:if> + <xsl:if test="not(field)"> + <div class="undisclosed">The content of this structure is not made public by the API</div> + </xsl:if> <pre> <xsl:text> } -- 1.7.9.5

Wrap pre-formatted example code in <code> elements. This works similar to markdown code blocks. Every line indented with at least 2 spaces is considered a code block and gets wrapped in <pre> and <code> tags. Signed-off-by: Claudio Bley <cbley@av-test.de> --- docs/newapi.xsl | 89 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 67 insertions(+), 22 deletions(-) diff --git a/docs/newapi.xsl b/docs/newapi.xsl index 09395ea..b11ce9c 100644 --- a/docs/newapi.xsl +++ b/docs/newapi.xsl @@ -83,6 +83,60 @@ </xsl:for-each> </xsl:template> + + <!-- process blocks of text. blocks are separated by two consecutive line --> + <!-- breaks. --> + <!-- --> + <!-- blocks indented with at least 2 spaces are considered code blocks. --> + <!-- --> + <!-- consecutive code blocks are collapsed into a single code block. --> + <xsl:template name="formatblock"> + <xsl:param name="block"/> + <xsl:param name="rest"/> + + <xsl:variable name="multipleCodeBlocks" + select="starts-with($block, ' ') and starts-with($rest, ' ')"/> + + <xsl:choose> + <xsl:when test="$multipleCodeBlocks"> + <xsl:call-template name="formatblock"> + <xsl:with-param name="block"> + <xsl:choose> + <xsl:when test="contains($rest, ' ')"> + <xsl:value-of select="concat($block, ' ', + substring-before($rest, ' '))" /> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="concat($block, ' ', $rest)" /> + </xsl:otherwise> + </xsl:choose> + </xsl:with-param> + <xsl:with-param name="rest" select="substring-after($rest, ' ')"/> + </xsl:call-template> + </xsl:when> + <xsl:when test="starts-with($block, ' ')"> + <pre class="code"><xsl:for-each select="str:tokenize($block, ' ')"> + <xsl:value-of select="substring(., 3)"/> + <xsl:if test="position() != last()"> + <xsl:text> </xsl:text> + </xsl:if> + </xsl:for-each></pre> + </xsl:when> + <xsl:otherwise> + <p> + <xsl:call-template name="dumptext"> + <xsl:with-param name="text" select="$block"/> + </xsl:call-template> + </p> + </xsl:otherwise> + </xsl:choose> + <xsl:if test="not($multipleCodeBlocks)"> + <xsl:call-template name="formattext"> + <xsl:with-param name="text" select="$rest"/> + </xsl:call-template> + </xsl:if> + </xsl:template> + <xsl:template name="formattext"> <xsl:param name="text" /> @@ -90,28 +144,19 @@ <xsl:variable name="head" select="substring-before($text, ' ')"/> <xsl:variable name="rest" select="substring-after($text, ' ')"/> - <xsl:choose> - <xsl:when test="$head"> - <p> - <xsl:call-template name="dumptext"> - <xsl:with-param name="text" select="$head"/> - </xsl:call-template> - </p> - </xsl:when> - <xsl:when test="not($rest)"> - <p> - <xsl:call-template name="dumptext"> - <xsl:with-param name="text" select="$text"/> - </xsl:call-template> - </p> - </xsl:when> - </xsl:choose> - - <xsl:if test="$rest"> - <xsl:call-template name="formattext"> - <xsl:with-param name="text" select="$rest"/> - </xsl:call-template> - </xsl:if> + <xsl:call-template name="formatblock"> + <xsl:with-param name="block"> + <xsl:choose> + <xsl:when test="contains($text, ' ')"> + <xsl:value-of select="$head"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$text"/> + </xsl:otherwise> + </xsl:choose> + </xsl:with-param> + <xsl:with-param name="rest" select="$rest"/> + </xsl:call-template> </xsl:if> </xsl:template> -- 1.7.9.5

Signed-off-by: Claudio Bley <cbley@av-test.de> --- docs/newapi.xsl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/newapi.xsl b/docs/newapi.xsl index b11ce9c..29ed94f 100644 --- a/docs/newapi.xsl +++ b/docs/newapi.xsl @@ -342,7 +342,7 @@ <xsl:variable name="name" select="string(@name)"/> <h3><a name="{$name}"><code><xsl:value-of select="$name"/></code></a></h3> <pre class="api"><span class="directive">#define</span><xsl:text> </xsl:text><xsl:value-of select="$name"/></pre> - <div> + <div class="description"> <xsl:call-template name="formattext"> <xsl:with-param name="text" select="info"/> </xsl:call-template> @@ -494,7 +494,7 @@ <xsl:text>) </xsl:text> </pre> - <div> + <div class="description"> <xsl:call-template name="formattext"> <xsl:with-param name="text" select="info"/> </xsl:call-template> @@ -570,7 +570,7 @@ </xsl:for-each> <xsl:text>)</xsl:text> </pre> - <div> + <div class="description"> <xsl:call-template name="formattext"> <xsl:with-param name="text" select="info"/> </xsl:call-template> -- 1.7.9.5

Signed-off-by: Claudio Bley <cbley@av-test.de> --- docs/libvirt.css | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/libvirt.css b/docs/libvirt.css index 8a00d12..c9e8beb 100644 --- a/docs/libvirt.css +++ b/docs/libvirt.css @@ -477,3 +477,10 @@ dl.variablelist > dt { dl.variablelist > dt:after { content: ": "; } + +div.description pre.code { + border: 1px dashed grey; + background-color: inherit; + padding: 5px 10px 5px 10px; + margin-left: 2.5em; +} -- 1.7.9.5

Add minimized CSS and Javascript files of SHJS (http://shjs.sourceforge.net/) required for highlighting C code. Call sh_highlightDocument() in onload event handler. Signed-off-by: Claudio Bley <cbley@av-test.de> --- docs/newapi.xsl | 2 +- docs/page.xsl | 5 ++++- docs/sh_c.min.js | 1 + docs/sh_emacs.min.css | 1 + docs/sh_main.min.js | 4 ++++ 5 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 docs/sh_c.min.js create mode 100644 docs/sh_emacs.min.css create mode 100644 docs/sh_main.min.js diff --git a/docs/newapi.xsl b/docs/newapi.xsl index 29ed94f..a975ba8 100644 --- a/docs/newapi.xsl +++ b/docs/newapi.xsl @@ -115,7 +115,7 @@ </xsl:call-template> </xsl:when> <xsl:when test="starts-with($block, ' ')"> - <pre class="code"><xsl:for-each select="str:tokenize($block, ' ')"> + <pre class="code sh_c"><xsl:for-each select="str:tokenize($block, ' ')"> <xsl:value-of select="substring(., 3)"/> <xsl:if test="position() != last()"> <xsl:text> </xsl:text> diff --git a/docs/page.xsl b/docs/page.xsl index bc8ea2a..bf7c446 100644 --- a/docs/page.xsl +++ b/docs/page.xsl @@ -136,10 +136,13 @@ <head> <link rel="stylesheet" type="text/css" href="{$href_base}main.css"/> <link rel="SHORTCUT ICON" href="{$href_base}32favicon.png"/> + <script type="text/javascript" src="{$href_base}sh_main.min.js"/> + <script type="text/javascript" src="{$href_base}sh_c.min.js"/> + <link rel="stylesheet" type="text/css" href="{$href_base}sh_emacs.min.css"/> <title>libvirt: <xsl:value-of select="html/body/h1"/></title> <meta name="description" content="libvirt, virtualization, virtualization API"/> </head> - <body> + <body onload="sh_highlightDocument();"> <div id="header"> <div id="headerLogo"/> <div id="headerSearch"> diff --git a/docs/sh_c.min.js b/docs/sh_c.min.js new file mode 100644 index 0000000..fd91118 --- /dev/null +++ b/docs/sh_c.min.js @@ -0,0 +1 @@ +if(!this.sh_languages){this.sh_languages={}}sh_languages.c=[[[/\/\/\//g,"sh_comment",1],[/\/\//g,"sh_comment",7],[/\/\*\*/g,"sh_comment",8],[/\/\*/g,"sh_comment",9],[/(\bstruct)([ \t]+)([A-Za-z0-9_]+)/g,["sh_keyword","sh_normal","sh_classname"],-1],[/^[ \t]*#(?:[ \t]*include)/g,"sh_preproc",10,1],[/^[ \t]*#(?:[ \t]*[A-Za-z0-9_]*)/g,"sh_preproc",-1],[/\b[+-]?(?:(?:0x[A-Fa-f0-9]+)|(?:(?:[\d]*\.)?[\d]+(?:[eE][+-]?[\d]+)?))u?(?:(?:int(?:8|16|32|64))|L)?\b/g,"sh_number",-1],[/"/g,"sh_string",13],[/'/g,"sh_string",14],[/\b(?:__asm|__cdecl|__declspec|__export|__far16|__fastcall|__fortran|__import|__pascal|__rtti|__stdcall|_asm|_cdecl|__except|_export|_far16|_fastcall|__finally|_fortran|_import|_pascal|_stdcall|__thread|__try|asm|auto|break|case|catch|cdecl|const|continue|default|do|else|enum|extern|for|goto|if|pascal|register|return|sizeof|static|struct|switch|typedef|union|volatile|while)\b/g,"sh_keyword",-1],[/\b(?:bool|char|double|float|int|long|short|signed|unsigned|void|wchar_ t)\b/g,"sh_type",-1],[/~|!|%|\^|\*|\(|\)|-|\+|=|\[|\]|\\|:|;|,|\.|\/|\?|&|<|>|\|/g,"sh_symbol",-1],[/\{|\}/g,"sh_cbracket",-1],[/(?:[A-Za-z]|_)[A-Za-z0-9_]*(?=[ \t]*\()/g,"sh_function",-1],[/([A-Za-z](?:[^`~!@#$%&*()_=+{}|;:",<.>\/?'\\[\]\^\-\s]|[_])*)((?:<.*>)?)(\s+(?=[*&]*[A-Za-z][^`~!@#$%&*()_=+{}|;:",<.>\/?'\\[\]\^\-\s]*\s*[`~!@#$%&*()_=+{}|;:",<.>\/?'\\[\]\^\-\[\]]+))/g,["sh_usertype","sh_usertype","sh_normal"],-1]],[[/$/g,null,-2],[/(?:<?)[A-Za-z0-9_\.\/\-_~]+@[A-Za-z0-9_\.\/\-_~]+(?:>?)|(?:<?)[A-Za-z0-9_]+:\/\/[A-Za-z0-9_\.\/\-_~]+(?:>?)/g,"sh_url",-1],[/<\?xml/g,"sh_preproc",2,1],[/<!DOCTYPE/g,"sh_preproc",4,1],[/<!--/g,"sh_comment",5],[/<(?:\/)?[A-Za-z](?:[A-Za-z0-9_:.-]*)(?:\/)?>/g,"sh_keyword",-1],[/<(?:\/)?[A-Za-z](?:[A-Za-z0-9_:.-]*)/g,"sh_keyword",6,1],[/&(?:[A-Za-z0-9]+);/g,"sh_preproc",-1],[/<(?:\/)?[A-Za-z][A-Za-z0-9]*(?:\/)?>/g,"sh_keyword",-1],[/<(?:\/)?[A-Za-z][A-Za-z0-9]*/g,"sh_keyword",6,1],[/@[A-Za-z]+/g,"sh_type",-1],[/(?:TODO|FIXME|BUG)(?:[:]?)/g,"sh _todo",-1]],[[/\?>/g,"sh_preproc",-2],[/([^=" \t>]+)([ \t]*)(=?)/g,["sh_type","sh_normal","sh_symbol"],-1],[/"/g,"sh_string",3]],[[/\\(?:\\|")/g,null,-1],[/"/g,"sh_string",-2]],[[/>/g,"sh_preproc",-2],[/([^=" \t>]+)([ \t]*)(=?)/g,["sh_type","sh_normal","sh_symbol"],-1],[/"/g,"sh_string",3]],[[/-->/g,"sh_comment",-2],[/<!--/g,"sh_comment",5]],[[/(?:\/)?>/g,"sh_keyword",-2],[/([^=" \t>]+)([ \t]*)(=?)/g,["sh_type","sh_normal","sh_symbol"],-1],[/"/g,"sh_string",3]],[[/$/g,null,-2]],[[/\*\//g,"sh_comment",-2],[/(?:<?)[A-Za-z0-9_\.\/\-_~]+@[A-Za-z0-9_\.\/\-_~]+(?:>?)|(?:<?)[A-Za-z0-9_]+:\/\/[A-Za-z0-9_\.\/\-_~]+(?:>?)/g,"sh_url",-1],[/<\?xml/g,"sh_preproc",2,1],[/<!DOCTYPE/g,"sh_preproc",4,1],[/<!--/g,"sh_comment",5],[/<(?:\/)?[A-Za-z](?:[A-Za-z0-9_:.-]*)(?:\/)?>/g,"sh_keyword",-1],[/<(?:\/)?[A-Za-z](?:[A-Za-z0-9_:.-]*)/g,"sh_keyword",6,1],[/&(?:[A-Za-z0-9]+);/g,"sh_preproc",-1],[/<(?:\/)?[A-Za-z][A-Za-z0-9]*(?:\/)?>/g,"sh_keyword",-1],[/<(?:\/)?[A-Za-z][A-Za-z0-9]*/g,"sh_keyword" ,6,1],[/@[A-Za-z]+/g,"sh_type",-1],[/(?:TODO|FIXME|BUG)(?:[:]?)/g,"sh_todo",-1]],[[/\*\//g,"sh_comment",-2],[/(?:<?)[A-Za-z0-9_\.\/\-_~]+@[A-Za-z0-9_\.\/\-_~]+(?:>?)|(?:<?)[A-Za-z0-9_]+:\/\/[A-Za-z0-9_\.\/\-_~]+(?:>?)/g,"sh_url",-1],[/(?:TODO|FIXME|BUG)(?:[:]?)/g,"sh_todo",-1]],[[/$/g,null,-2],[/</g,"sh_string",11],[/"/g,"sh_string",12],[/\/\/\//g,"sh_comment",1],[/\/\//g,"sh_comment",7],[/\/\*\*/g,"sh_comment",8],[/\/\*/g,"sh_comment",9]],[[/$/g,null,-2],[/>/g,"sh_string",-2]],[[/$/g,null,-2],[/\\(?:\\|")/g,null,-1],[/"/g,"sh_string",-2]],[[/"/g,"sh_string",-2],[/\\./g,"sh_specialchar",-1]],[[/'/g,"sh_string",-2],[/\\./g,"sh_specialchar",-1]]]; \ No newline at end of file diff --git a/docs/sh_emacs.min.css b/docs/sh_emacs.min.css new file mode 100644 index 0000000..b7aed87 --- /dev/null +++ b/docs/sh_emacs.min.css @@ -0,0 +1 @@ +pre.sh_sourceCode{background-color:#fff;color:#000;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_keyword{color:#9c20ee;font-weight:bold;font-style:normal;}pre.sh_sourceCode .sh_type{color:#208920;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_string{color:#bd8d8b;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_regexp{color:#bd8d8b;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_specialchar{color:#bd8d8b;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_comment{color:#ac2020;font-weight:normal;font-style:italic;}pre.sh_sourceCode .sh_number{color:#000;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_preproc{color:#000;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_function{color:#000;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_url{color:#bd8d8b;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_date{color:#9c20ee;font-weight:bold;font-style:normal;}pre.sh_sourceCode . sh_time{color:#9c20ee;font-weight:bold;font-style:normal;}pre.sh_sourceCode .sh_file{color:#9c20ee;font-weight:bold;font-style:normal;}pre.sh_sourceCode .sh_ip{color:#bd8d8b;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_name{color:#bd8d8b;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_variable{color:#00f;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_oldfile{color:#bd8d8b;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_newfile{color:#bd8d8b;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_difflines{color:#9c20ee;font-weight:bold;font-style:normal;}pre.sh_sourceCode .sh_selector{color:#00f;font-weight:normal;font-style:normal;}pre.sh_sourceCode .sh_property{color:#9c20ee;font-weight:bold;font-style:normal;}pre.sh_sourceCode .sh_value{color:#bd8d8b;font-weight:normal;font-style:normal;} \ No newline at end of file diff --git a/docs/sh_main.min.js b/docs/sh_main.min.js new file mode 100644 index 0000000..31d1ba0 --- /dev/null +++ b/docs/sh_main.min.js @@ -0,0 +1,4 @@ +/* Copyright (C) 2007, 2008 gnombat@users.sourceforge.net */ +/* License: http://shjs.sourceforge.net/doc/gplv3.html */ + +if(!this.sh_languages){this.sh_languages={}}var sh_requests={};function sh_isEmailAddress(a){if(/^mailto:/.test(a)){return false}return a.indexOf("@")!==-1}function sh_setHref(b,c,d){var a=d.substring(b[c-2].pos,b[c-1].pos);if(a.length>=2&&a.charAt(0)==="<"&&a.charAt(a.length-1)===">"){a=a.substr(1,a.length-2)}if(sh_isEmailAddress(a)){a="mailto:"+a}b[c-2].node.href=a}function sh_konquerorExec(b){var a=[""];a.index=b.length;a.input=b;return a}function sh_highlightString(B,o){if(/Konqueror/.test(navigator.userAgent)){if(!o.konquered){for(var F=0;F<o.length;F++){for(var H=0;H<o[F].length;H++){var G=o[F][H][0];if(G.source==="$"){G.exec=sh_konquerorExec}}}o.konquered=true}}var N=document.createElement("a");var q=document.createElement("span");var A=[];var j=0;var n=[];var C=0;var k=null;var x=function(i,a){var p=i.length;if(p===0){return}if(!a){var Q=n.length;if(Q!==0){var r=n[Q-1];if(!r[3]){a=r[1]}}}if(k!==a){if(k){A[j++]={pos:C};if(k==="sh_url"){sh_setHref(A,j,B)}}if(a){var P;i f(a==="sh_url"){P=N.cloneNode(false)}else{P=q.cloneNode(false)}P.className=a;A[j++]={node:P,pos:C}}}C+=p;k=a};var t=/\r\n|\r|\n/g;t.lastIndex=0;var d=B.length;while(C<d){var v=C;var l;var w;var h=t.exec(B);if(h===null){l=d;w=d}else{l=h.index;w=t.lastIndex}var g=B.substring(v,l);var M=[];for(;;){var I=C-v;var D;var y=n.length;if(y===0){D=0}else{D=n[y-1][2]}var O=o[D];var z=O.length;var m=M[D];if(!m){m=M[D]=[]}var E=null;var u=-1;for(var K=0;K<z;K++){var f;if(K<m.length&&(m[K]===null||I<=m[K].index)){f=m[K]}else{var c=O[K][0];c.lastIndex=I;f=c.exec(g);m[K]=f}if(f!==null&&(E===null||f.index<E.index)){E=f;u=K;if(f.index===I){break}}}if(E===null){x(g.substring(I),null);break}else{if(E.index>I){x(g.substring(I,E.index),null)}var e=O[u];var J=e[1];var b;if(J instanceof Array){for(var L=0;L<J.length;L++){b=E[L+1];x(b,J[L])}}else{b=E[0];x(b,J)}switch(e[2]){case -1:break;case -2:n.pop();break;case -3:n.length=0;break;default:n.push(e);break}}}if(k){A[j++]={pos:C};if(k==="sh_url"){sh_s etHref(A,j,B)}k=null}C=w}return A}function sh_getClasses(d){var a=[];var b=d.className;if(b&&b.length>0){var e=b.split(" ");for(var c=0;c<e.length;c++){if(e[c].length>0){a.push(e[c])}}}return a}function sh_addClass(c,a){var d=sh_getClasses(c);for(var b=0;b<d.length;b++){if(a.toLowerCase()===d[b].toLowerCase()){return}}d.push(a);c.className=d.join(" ")}function sh_extractTagsFromNodeList(c,a){var f=c.length;for(var d=0;d<f;d++){var e=c.item(d);switch(e.nodeType){case 1:if(e.nodeName.toLowerCase()==="br"){var b;if(/MSIE/.test(navigator.userAgent)){b="\r"}else{b="\n"}a.text.push(b);a.pos++}else{a.tags.push({node:e.cloneNode(false),pos:a.pos});sh_extractTagsFromNodeList(e.childNodes,a);a.tags.push({pos:a.pos})}break;case 3:case 4:a.text.push(e.data);a.pos+=e.length;break}}}function sh_extractTags(c,b){var a={};a.text=[];a.tags=b;a.pos=0;sh_extractTagsFromNodeList(c.childNodes,a);return a.text.join("")}function sh_mergeTags(d,f){var a=d.length;if(a===0){return f}var c=f.length;if (c===0){return d}var i=[];var e=0;var b=0;while(e<a&&b<c){var h=d[e];var g=f[b];if(h.pos<=g.pos){i.push(h);e++}else{i.push(g);if(f[b+1].pos<=h.pos){b++;i.push(f[b]);b++}else{i.push({pos:h.pos});f[b]={node:g.node.cloneNode(false),pos:h.pos}}}}while(e<a){i.push(d[e]);e++}while(b<c){i.push(f[b]);b++}return i}function sh_insertTags(k,h){var g=document;var l=document.createDocumentFragment();var e=0;var d=k.length;var b=0;var j=h.length;var c=l;while(b<j||e<d){var i;var a;if(e<d){i=k[e];a=i.pos}else{a=j}if(a<=b){if(i.node){var f=i.node;c.appendChild(f);c=f}else{c=c.parentNode}e++}else{c.appendChild(g.createTextNode(h.substring(b,a)));b=a}}return l}function sh_highlightElement(d,g){sh_addClass(d,"sh_sourceCode");var c=[];var e=sh_extractTags(d,c);var f=sh_highlightString(e,g);var b=sh_mergeTags(c,f);var a=sh_insertTags(b,e);while(d.hasChildNodes()){d.removeChild(d.firstChild)}d.appendChild(a)}function sh_getXMLHttpRequest(){if(window.ActiveXObject){return new ActiveXObject("Msxml2 .XMLHTTP")}else{if(window.XMLHttpRequest){return new XMLHttpRequest()}}throw"No XMLHttpRequest implementation available"}function sh_load(language,element,prefix,suffix){if(language in sh_requests){sh_requests[language].push(element);return}sh_requests[language]=[element];var request=sh_getXMLHttpRequest();var url=prefix+"sh_"+language+suffix;request.open("GET",url,true);request.onreadystatechange=function(){if(request.readyState===4){try{if(!request.status||request.status===200){eval(request.responseText);var elements=sh_requests[language];for(var i=0;i<elements.length;i++){sh_highlightElement(elements[i],sh_languages[language])}}else{throw"HTTP error: status "+request.status}}finally{request=null}}};request.send(null)}function sh_highlightDocument(g,k){var b=document.getElementsByTagName("pre");for(var e=0;e<b.length;e++){var f=b.item(e);var a=sh_getClasses(f);for(var c=0;c<a.length;c++){var h=a[c].toLowerCase();if(h==="sh_sourcecode"){continue}if(h.substr(0,3)==="sh_"){va r d=h.substring(3);if(d in sh_languages){sh_highlightElement(f,sh_languages[d])}else{if(typeof(g)==="string"&&typeof(k)==="string"){sh_load(d,f,g,k)}else{throw'Found <pre> element with class="'+h+'", but no such language exists'}}break}}}}; \ No newline at end of file -- 1.7.9.5

At Tue, 29 Jan 2013 16:05:38 +0100, Claudio Bley wrote:
Add minimized CSS and Javascript files of SHJS (http://shjs.sourceforge.net/) required for highlighting C code.
docs/sh_c.min.js | 1 + docs/sh_emacs.min.css | 1 + docs/sh_main.min.js | 4 ++++
I did download those files directly from SourceForge without changing them. Since these files lack a final newline character "make check" fails on them. Should we a) add EOF to those files b) relax the rules for "make check"? -- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern

On 01/30/2013 04:39 AM, Claudio Bley wrote:
At Tue, 29 Jan 2013 16:05:38 +0100, Claudio Bley wrote:
Add minimized CSS and Javascript files of SHJS (http://shjs.sourceforge.net/) required for highlighting C code.
docs/sh_c.min.js | 1 + docs/sh_emacs.min.css | 1 + docs/sh_main.min.js | 4 ++++
I did download those files directly from SourceForge without changing them. Since these files lack a final newline character "make check" fails on them.
Should we
a) add EOF to those files b) relax the rules for "make check"?
If we end up using the files, I'd vote for reformatting them to fit our conventions. We don't have to do verbatim copying of bad style. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

At Tue, 29 Jan 2013 16:05:31 +0100, Claudio Bley wrote:
Hi.
Version 2 of this series incorporates the following changes:
- patch #1 fail if documentation is missing - reword subject line of patch #3 as suggessted by Eric
Incidently, patch #1 truthfully makes the build fail because of missing documentation. Go figure :)
I'll submit a single patch with a fix shortly.
I reworked the patches and have integrated the prerequisite documentation fixes into the series. Watch out for v3 coming up in a moment. Claudio -- AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany Phone: +49 341 265 310 19 Web:<http://www.av-test.org> Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076) Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern
participants (2)
-
Claudio Bley
-
Eric Blake