[cookbook] Build the Cookbook as a devhelp document

Instead of creating stand-alone HTML files, use XSLT to transform the
DocBook into a DevHelp file, so that we can read the Cookbook inside
DevHelp -- just like the API reference.
This commit is contained in:
Emmanuele Bassi 2009-09-02 18:11:06 +01:00
parent 9485ef81a6
commit ee9d358c45
6 changed files with 564 additions and 40 deletions

View File

@ -761,12 +761,17 @@ AS_IF([test "x$enable_manual" = "xyes"],
[
AC_PATH_PROG(JW, [jw], [no])
AS_IF([test "x$JW" = "xno"],
[AC_MSG_ERROR(['jw' program needed by the manual not found in path])]
[AC_MSG_ERROR(['jw' program needed by the manual not found in PATH])]
)
AC_PATH_PROG(XMLTO, [xmlto], [no])
AS_IF([test "x$XMLTO" = "xno"],
[AC_MSG_ERROR(['xmlto' program needed by the manual not found in path])]
[AC_MSG_ERROR(['xmlto' program needed by the manual not found in PATH])]
)
AC_PATH_PROG(XSLTPROC, [xsltproc], [no])
AS_IF([test "x$XSLTPROC" = "xno"],
[AC_MSG_ERROR(['xsltproc' needed by the manual not found in PATH])]
)
]
)

View File

@ -1,11 +1,19 @@
DOCDIR = $(DESTDIR)/$(datadir)/doc/@PACKAGE@-@CLUTTER_API_VERSION@/cookbook
HTML_FILES = html/*.html
IMAGE_FILES = images/*.png
EXTRA_DIST = \
version.xml.in \
cookbook.xsl \
style.css \
$(srcdir)/$(IMAGE_FILES)
HTML_DIR = $(datadir)/gtk-doc/html
TARGET_DIR = $(HTML_DIR)/clutter-cookbook
HTML_FILES = $(srcdir)/html/*.html
IMAGE_FILES = $(srcdir)/images/*.png
EXTRA_DIST = \
version.xml.in \
cookbook.xsl \
common.xsl \
devhelp.xsl \
html.xsl \
ref-html-style.xsl \
style.css \
$(IMAGE_FILES)
CLEANFILES = \
pdf-build.stamp \
txt-build.stamp \
@ -13,59 +21,58 @@ CLEANFILES = \
pdf-build.stamp: clutter-cookbook.xml
SP_ENCODING=XML SP_CHARSET_FIXED=YES \
$(JW) -b pdf $(srcdir)/clutter-cookbook.xml && \
mv $(srcdir)/clutter-cookbook.pdf clutter-cookbook-@CLUTTER_API_VERSION@.pdf && \
touch pdf-build.stamp
$(JW) -b pdf $(srcdir)/clutter-cookbook.xml \
&& mv -f $(srcdir)/clutter-cookbook.pdf clutter-cookbook-@CLUTTER_API_VERSION@.pdf \
&& echo timestamp > $(@F)
txt-build.stamp: clutter-cookbook.xml
$(XMLTO) txt $(srcdir)/clutter-cookbook.xml && \
mv $(srcdir)/clutter-cookbook.txt clutter-cookbook-@CLUTTER_MAJORMINOR@.txt && \
touch txt-build.stamp
htmldoc-build.stamp: clutter-cookbook.xml
$(mkinstalldirs) html && \
$(XMLTO) -m cookbook.xsl -o html/ xhtml $(srcdir)/clutter-cookbook.xml && \
cp $(srcdir)/style.css html/ && \
touch htmldoc-build.stamp
doc: txt-build.stamp htmldoc-build.stamp pdf-build.stamp
html-build.stamp: clutter-cookbook.xml
$(mkinstalldirs) html \
&& $(XSLTPROC) --nonet --xinclude -o $(srcdir)/html/ \
--path $(srcdir) \
--stringparam gtkdoc.bookname "clutter-cookbook" \
--stringparam gtkdoc.version @CLUTTER_API_VERSION@ \
$(srcdir)/ref-html-style.xsl \
$(srcdir)/clutter-cookbook.xml \
&& echo timestamp > $(@F)
if ENABLE_MANUAL
all-local: doc
all-local: html-build.stamp
else
all-local:
endif
clean-local:
rm -rf html/*.html
rm -f html/style.css
rm -f clutter-cookbook-*.txt
rm -rf html
rm -f *.pdf
rm -f *.stamp
uninstall-local:
rm -rf $(DOCDIR);
install-data-local:
installfiles=`echo $(srcdir)/html/*`; \
if test "$$installfiles" = '$(srcdir)/html/*'; then \
echo '-- Nothing to install' ; \
if test "$$installfiles" = '$(srcdir)/html/*'; \
then echo '-- Nothing to install' ; \
else \
$(mkinstalldirs) $(DOCDIR)/html/images ; \
$(mkinstalldirs) $(DESTDIR)$(TARGET_DIR) ; \
for file in `ls $(srcdir)/$(HTML_FILES)`; do \
if [ -f $$file ]; then \
basefile=`echo $$file | sed -e 's,^.*/,,'`; \
$(INSTALL_DATA) $$file $(DOCDIR)/html/$$basefile; \
$(INSTALL_DATA) $$file $(DESTDIR)$(TARGET_DIR)/$$basefile; \
fi \
done; \
fi; \
if [ -d $(srcdir)/images ]; \
then \
$(mkinstalldirs) $(DESTDIR)$(TARGET_DIR)/images ; \
for file in `ls $(srcdir)/$(IMAGE_FILES)`; do \
if [ -f $$file ]; then \
if [ -f $$file ]; \
then \
basefile=`echo $$file | sed -e 's,^.*/,,'`; \
$(INSTALL_DATA) $$file $(DOCDIR)/html/images/$$basefile; \
$(INSTALL_DATA) $$file $(DESTDIR)$(TARGET_DIR)/images/$$basefile; \
fi \
done; \
$(INSTALL_DATA) $(srcdir)/style.css $(DOCDIR)/html/style.css; \
$(INSTALL_DATA) $(srcdir)/clutter-cookbook-@CLUTTER_MAJORMINOR@.txt $(DOCDIR)/clutter-cookbook-@CLUTTER_MAJORMINOR@.txt; \
$(INSTALL_DATA) $(srcdir)/clutter-cookbook-@CLUTTER_MAJORMINOR@.pdf $(DOCDIR)/clutter-cookbook-@CLUTTER_MAJORMINOR@.pdf; \
fi
fi; \
$(INSTALL_DATA) $(srcdir)/style.css $(DESTDIR)$(TARGET_DIR)/style.css; \
$(INSTALL_DATA) $(srcdir)/html/clutter-cookbook.devhelp $(DESTDIR)$(TARGET_DIR)/clutter-cookbook.devhelp
.PHONY : doc

19
doc/cookbook/common.xsl Normal file
View File

@ -0,0 +1,19 @@
<?xml version='1.0'?>
<!DOCTYPE xsl:stylesheet [
]>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version='1.0'>
<xsl:template match="parameter">
<xsl:choose>
<xsl:when test="@role = 'keyword'">
<xsl:call-template name="inline.boldmonoseq"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="inline.italicmonoseq"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

154
doc/cookbook/devhelp.xsl Normal file
View File

@ -0,0 +1,154 @@
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version='1.0'
xmlns="http://www.devhelp.net/book"
exclude-result-prefixes="#default">
<xsl:template name="generate.devhelp">
<xsl:call-template name="write.chunk">
<xsl:with-param name="filename">
<xsl:choose>
<xsl:when test="$gtkdoc.bookname">
<xsl:value-of select="$gtkdoc.bookname"/>
</xsl:when>
<xsl:otherwise>
<xsl:text>book</xsl:text>
</xsl:otherwise>
</xsl:choose>
<xsl:text>.devhelp</xsl:text>
</xsl:with-param>
<xsl:with-param name="method" select="'xml'"/>
<xsl:with-param name="indent" select="'yes'"/>
<xsl:with-param name="encoding" select="'utf-8'"/>
<xsl:with-param name="content">
<xsl:call-template name="devhelp"/>
</xsl:with-param>
</xsl:call-template>
</xsl:template>
<xsl:template name="devhelp">
<xsl:variable name="title">
<xsl:apply-templates select="." mode="generate.devhelp.toc.title.mode"/>
</xsl:variable>
<xsl:variable name="link">
<xsl:call-template name="href.target"/>
</xsl:variable>
<xsl:variable name="author">
<xsl:if test="articleinfo|bookinfo">
<xsl:apply-templates mode="generate.devhelp.authors"
select="articleinfo|bookinfo"/>
</xsl:if>
</xsl:variable>
<xsl:variable name="toc.nodes" select="part|reference|preface|chapter|
appendix|article|bibliography|
glossary|index|refentry|
bridgehead|sect1"/>
<book title="{$title}" link="{$link}" author="{$author}" name="{$gtkdoc.bookname}">
<xsl:if test="$toc.nodes">
<chapters>
<xsl:apply-templates select="$toc.nodes"
mode="generate.devhelp.toc.mode"/>
</chapters>
</xsl:if>
<functions>
<xsl:apply-templates select="//refsect1"
mode="generate.devhelp.constructor.index.mode"/>
<xsl:apply-templates select="//refsect2"
mode="generate.devhelp.index.mode"/>
</functions>
</book>
</xsl:template>
<xsl:template match="*" mode="generate.devhelp.toc.mode">
<xsl:variable name="title">
<xsl:apply-templates select="." mode="generate.devhelp.toc.title.mode"/>
</xsl:variable>
<xsl:variable name="target">
<xsl:variable name="anchor" select="title/anchor"/>
<xsl:choose>
<xsl:when test="$anchor">
<xsl:call-template name="href.target">
<xsl:with-param name="object" select="$anchor"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="href.target"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<sub name="{$title}" link="{$target}">
<xsl:apply-templates select="section|sect1|
refentry|refsect|
bridgehead|part|chapter"
mode="generate.devhelp.toc.mode"/>
</sub>
</xsl:template>
<xsl:template match="*" mode="generate.devhelp.index.mode">
<xsl:variable name="title" select="title"/>
<xsl:variable name="anchor" select="title/anchor"/>
<xsl:variable name="target">
<xsl:choose>
<xsl:when test="$anchor">
<xsl:call-template name="href.target">
<xsl:with-param name="object" select="$anchor"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="href.target"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<function name="{$title}" link="{$target}"/>
</xsl:template>
<xsl:template match="*" mode="generate.devhelp.constructor.index.mode">
<xsl:variable name="title" select="title"/>
<xsl:variable name="anchor" select="title/anchor"/>
<xsl:variable name="target">
<xsl:choose>
<xsl:when test="$anchor">
<xsl:call-template name="href.target">
<xsl:with-param name="object" select="$anchor"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="href.target"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:if test="$title='Constructor'">
<xsl:variable name ="constructor" select="programlisting//methodname"/>
<function name="{$constructor}" link="{$target}"/>
</xsl:if>
</xsl:template>
<!-- get title -->
<xsl:template match="article" mode="generate.devhelp.toc.title.mode">
<xsl:value-of select="articleinfo/title"/>
</xsl:template>
<xsl:template match="book" mode="generate.devhelp.toc.title.mode">
<xsl:value-of select="bookinfo/title"/>
</xsl:template>
<xsl:template match="refentry" mode="generate.devhelp.toc.title.mode">
<xsl:value-of select="refnamediv/refname"/>
</xsl:template>
<xsl:template match="*" mode="generate.devhelp.toc.title.mode">
<xsl:value-of select="title"/>
</xsl:template>
<!-- generate list of authors ... -->
<xsl:template match="articleinfo|bookinfo" mode="generate.devhelp.authors">
<xsl:for-each select="authorgroup/author">
<xsl:value-of select="firstname"/>
<xsl:text> </xsl:text>
<xsl:value-of select="surname"/>
<xsl:if test="not(last())">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

285
doc/cookbook/html.xsl Normal file
View File

@ -0,0 +1,285 @@
<?xml version='1.0'?>
<!DOCTYPE xsl:stylesheet [
<!ENTITY RE "&#10;">
<!ENTITY nbsp "&#160;">
]>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version='1.0'>
<xsl:param name="html.stylesheet">style.css</xsl:param>
<xsl:param name="use.id.as.filename" select="1"/>
<xsl:param name="chunk.fast" select="1"/>
<xsl:param name="chunker.output.encoding" select="'utf-8'"/>
<xsl:param name="linenumbering.extension" select="1"/>
<xsl:param name="variablelist.as.table" select="1"/>
<xsl:template match="blockquote">
<div class="{local-name(.)}">
<xsl:if test="@lang or @xml:lang">
<xsl:call-template name="language.attribute"/>
</xsl:if>
<xsl:call-template name="anchor"/>
<xsl:choose>
<xsl:when test="attribution">
<table border="0" width="100%"
cellspacing="0" cellpadding="0" class="blockquote"
summary="Block quote">
<tr>
<td width="10%" valign="top">&#160;</td>
<td width="80%" valign="top">
<xsl:apply-templates select="child::*[local-name(.)!='attribution']"/>
</td>
<td width="10%" valign="top">&#160;</td>
</tr>
<tr>
<td colspan="2" align="right" valign="top">
<xsl:text>--</xsl:text>
<xsl:apply-templates select="attribution"/>
</td>
<td width="10%" valign="top">&#160;</td>
</tr>
</table>
</xsl:when>
<xsl:when test="@role = 'properties' or @role = 'prototypes'">
<table width="100%" border="0" bgcolor="#E0E0E0">
<tr>
<td valign="top">
<xsl:apply-templates select="child::*[local-name(.)!='attribution']"/>
</td>
</tr>
</table>
</xsl:when>
<xsl:otherwise>
<blockquote class="{local-name(.)}">
<xsl:apply-templates/>
</blockquote>
</xsl:otherwise>
</xsl:choose>
</div>
</xsl:template>
<!-- support for Python language for synopsises -->
<xsl:template match="classsynopsis
|fieldsynopsis
|methodsynopsis
|constructorsynopsis
|destructorsynopsis">
<xsl:param name="language">
<xsl:choose>
<xsl:when test="@language">
<xsl:value-of select="@language"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$default-classsynopsis-language"/>
</xsl:otherwise>
</xsl:choose>
</xsl:param>
<xsl:choose>
<xsl:when test="$language='python'">
<xsl:apply-templates select="." mode="python"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-imports/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="classsynopsis" mode="python">
<table bgcolor="#D0E0F0" width="100%">
<tr><td>
<pre class="{name(.)}">
<xsl:text>class </xsl:text>
<xsl:apply-templates select="ooclass[1]" mode="python"/>
<xsl:if test="ooclass[position() &gt; 1]">
<xsl:text>(</xsl:text>
<xsl:apply-templates select="ooclass[position() &gt; 1]" mode="python"/> <xsl:text>)</xsl:text>
</xsl:if>
<xsl:text>:&RE;</xsl:text>
<xsl:apply-templates select="constructorsynopsis
|destructorsynopsis
|fieldsynopsis
|methodsynopsis
|classsynopsisinfo" mode="python"/>
</pre></td></tr></table>
</xsl:template>
<xsl:template match="classsynopsisinfo" mode="python">
<xsl:apply-templates mode="python"/>
</xsl:template>
<xsl:template match="ooclass|oointerface|ooexception" mode="python">
<xsl:if test="position() &gt; 1">
<xsl:text>, </xsl:text>
</xsl:if>
<span class="{name(.)}">
<xsl:apply-templates mode="python"/>
</span>
</xsl:template>
<xsl:template match="modifier" mode="python">
<span class="{name(.)}">
<xsl:apply-templates mode="python"/>
<xsl:text>&nbsp;</xsl:text>
</span>
</xsl:template>
<xsl:template match="classname" mode="python">
<xsl:if test="name(preceding-sibling::*[1]) = 'classname'">
<xsl:text>, </xsl:text>
</xsl:if>
<span class="{name(.)}">
<xsl:apply-templates mode="python"/>
</span>
</xsl:template>
<xsl:template match="interfacename" mode="python">
<xsl:if test="name(preceding-sibling::*[1]) = 'interfacename'">
<xsl:text>, </xsl:text>
</xsl:if>
<span class="{name(.)}">
<xsl:apply-templates mode="python"/>
</span>
</xsl:template>
<xsl:template match="exceptionname" mode="python">
<xsl:if test="name(preceding-sibling::*[1]) = 'exceptionname'">
<xsl:text>, </xsl:text>
</xsl:if>
<span class="{name(.)}">
<xsl:apply-templates mode="python"/>
</span>
</xsl:template>
<xsl:template match="fieldsynopsis" mode="python">
<code class="{name(.)}">
<xsl:text>&nbsp;&nbsp;&nbsp;&nbsp;</xsl:text>
<xsl:apply-templates mode="python"/>
</code>
<xsl:call-template name="synop-break"/>
</xsl:template>
<xsl:template match="type" mode="python">
<span class="{name(.)}">
<xsl:apply-templates mode="python"/>
<xsl:text>&nbsp;</xsl:text>
</span>
</xsl:template>
<xsl:template match="varname" mode="python">
<span class="{name(.)}">
<xsl:apply-templates mode="python"/>
<xsl:text>&nbsp;</xsl:text>
</span>
</xsl:template>
<xsl:template match="initializer" mode="python">
<span class="{name(.)}">
<xsl:text>=</xsl:text>
<xsl:apply-templates mode="python"/>
</span>
</xsl:template>
<xsl:template match="void" mode="python">
<span class="{name(.)}">
<xsl:text>void&nbsp;</xsl:text>
</span>
</xsl:template>
<xsl:template match="methodname" mode="python">
<span class="{name(.)}">
<xsl:apply-templates mode="python"/>
</span>
</xsl:template>
<xsl:template match="methodparam" mode="python">
<xsl:if test="position() &gt; 1">
<xsl:text>, </xsl:text>
</xsl:if>
<span class="{name(.)}">
<xsl:apply-templates mode="python"/>
</span>
</xsl:template>
<xsl:template mode="python"
match="destructorsynopsis|methodsynopsis">
<code class="{name(.)}">
<xsl:text> def </xsl:text>
<xsl:apply-templates select="methodname" mode="python"/>
<xsl:text>(</xsl:text>
<xsl:apply-templates select="methodparam" mode="python"/>
<xsl:text>)</xsl:text>
</code>
<xsl:call-template name="synop-break"/>
</xsl:template>
<xsl:template mode="python"
match="constructorsynopsis">
<code class="{name(.)}">
<xsl:text> </xsl:text>
<xsl:apply-templates select="methodname" mode="python"/>
<xsl:text>(</xsl:text>
<xsl:apply-templates select="methodparam" mode="python"/>
<xsl:text>)</xsl:text>
</code>
<xsl:call-template name="synop-break"/>
</xsl:template>
<!-- this was the original parameter python mode styling
<xsl:template match="parameter" mode="python">
<span class="{name(.)}">
<xsl:apply-templates mode="python"/>
</span>
</xsl:template>
-->
<!-- hack -->
<xsl:template match="link" mode="python">
<xsl:apply-templates select="."/>
</xsl:template>
<!-- ========================================================= -->
<!-- template to output gtkdoclink elements for the unknown targets -->
<xsl:template match="link">
<xsl:choose>
<xsl:when test="id(@linkend)">
<xsl:apply-imports/>
</xsl:when>
<xsl:otherwise>
<PYGTKDOCLINK HREF="{@linkend}">
<xsl:apply-templates/>
</PYGTKDOCLINK>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="parameter" mode="python">
<span class="{name(.)}">
<xsl:choose>
<xsl:when test="@role = 'keyword'">
<xsl:call-template name="inline.boldmonoseq"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="inline.italicmonoseq"/>
</xsl:otherwise>
</xsl:choose>
</span>
</xsl:template>
<xsl:template match="variablelist">
<table border="0" width="100%" bgcolor="#FFECCE">
<col align="left" valign="top" width="0*">
</col>
<tbody>
<xsl:apply-templates select="varlistentry" mode="varlist-table"/>
</tbody>
</table>
</xsl:template>
</xsl:stylesheet>

View File

@ -0,0 +1,54 @@
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version='1.0'>
<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/html/chunk.xsl"/>
<xsl:include href="common.xsl"/>
<xsl:include href="html.xsl"/>
<xsl:include href="devhelp.xsl"/>
<!-- ========================================================= -->
<!-- template to create the index.sgml anchor index -->
<xsl:template name="generate.index">
<xsl:call-template name="write.text.chunk">
<xsl:with-param name="filename" select="'index.sgml'"/>
<xsl:with-param name="content">
<!-- check all anchor and refentry elements -->
<xsl:apply-templates select="//anchor|//refentry|//refsect1|//refsect2|//book"
mode="generate.index.mode"/>
</xsl:with-param>
<xsl:with-param name="encoding" select="'utf-8'"/>
</xsl:call-template>
</xsl:template>
<xsl:template match="*" mode="generate.index.mode">
<xsl:if test="not(@href)">
<xsl:if test="@id">
<xsl:text>&lt;ANCHOR id=&quot;</xsl:text>
<xsl:value-of select="@id"/>
<xsl:text>&quot; href=&quot;</xsl:text>
<xsl:if test="$gtkdoc.bookname">
<xsl:value-of select="$gtkdoc.bookname"/>
<xsl:text>/</xsl:text>
</xsl:if>
<xsl:call-template name="href.target"/>
<xsl:text>&quot;&gt;
</xsl:text>
</xsl:if>
</xsl:if>
</xsl:template>
<xsl:param name="gtkdoc.version" select="''"/>
<xsl:param name="gtkdoc.bookname" select="''"/>
<xsl:param name="refentry.generate.name" select="0"/>
<xsl:param name="refentry.generate.title" select="1"/>
<xsl:param name="chapter.autolabel" select="0"/>
<xsl:template match="book|article">
<xsl:apply-imports/>
<xsl:call-template name="generate.devhelp"/>
<xsl:call-template name="generate.index"/>
</xsl:template>
</xsl:stylesheet>