Skip to content

Instantly share code, notes, and snippets.

@iPenguin
Created November 25, 2012 04:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iPenguin/4142447 to your computer and use it in GitHub Desktop.
Save iPenguin/4142447 to your computer and use it in GitHub Desktop.
CMake docbook cross platform documentation
Project structure:
[PROJECT]/
+cmake/modules/
| DocbookGen.cmake
+docs/
index.docbook.in
myStyle.xsl.in
images/cover.png
By using configure_file on index.docbook.in you can use variables in cmake to generate the common
values that are needed in the documentation as well as the package and software.
To make the pdf compile you'll also need to create a cover image for the pdf.
What you'll need:
-cmake (http://cmake.org/cmake/resources/software.html)
-docbook-xsl-ns (http://sourceforge.net/projects/docbook/files/docbook-xsl-ns/)
-xsltproc (native on Mac, use cygwin on Windows)
-The official docbook guide (for syntax reference) - http://docbook.org/tdg51/en/html/
For pdf on all platforms:
-fop (http://xmlgraphics.apache.org/fop/download.html)
For htmlhelp on Windows:
-hhc.exe - Microsoft HTML Help SDK ( http://msdn.microsoft.com/en-us/library/windows/desktop/ms669985(v=vs.85).aspx )
# Appends the cmake/modules path to MAKE_MODULE_PATH variable.
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules ${CMAKE_MODULE_PATH})
include(DocbookGen)
configure_file(${CMAKE_SOURCE_DIR}/docs/index.docbook.in
${CMAKE_CURRENT_BINARY_DIR}/index.docbook)
set(docbookFile "${CMAKE_CURRENT_BINARY_DIR}/index.docbook")
message(STATUS "Createing documentation: html")
docbook_generate(html "${docbookFile}" "${VERSION_SHORT}")
message(STATUS "Createing documentation: pdf")
docbook_generate(pdf "${docbookFile}" "${VERSION_SHORT}")
#Build documentation based on the platform
if(WIN32)
message(STATUS "Createing documentation: Windows")
docbook_generate(htmlhelp "${docbookFile}" "${VERSION_SHORT}")
endif()
#Modify as appropriate
install(FILES "${CMAKE_BINARY_DIR}/docs/pdf/${PROJECT_NAME}_User_Guide_${VERSION_SHORT}.pdf" DESTINATION bin)
#
# Copyright (c) 2012 Brian C. Milco <bcmilco AT gmail DOT com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2
# of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# This file contains functions to generate documentation from docbook files.
# TODO: make sure that docbook-xsl-ns package is installed
#
# OUTPUT FORMATS:
# html: generic html with a folder of images.
# pdf: a PDF
# htmlhelp: MS Windows specific html help pages
MACRO(MAKE_WINDOWS_PATH pathname)
# An extra \\ escape is necessary to get a \ through CMake's processing.
STRING(REPLACE "/" "\\" ${pathname} "${${pathname}}")
# Enclose with UNESCAPED quotes. This means we need to escape our
# quotes once here, i.e. with \"
SET(${pathname} ${${pathname}})
ENDMACRO(MAKE_WINDOWS_PATH)
#
#Ex. docbook_generate(pdf "${docbook_source_file}" "${software_version}")
#
function(DOCBOOK_GENERATE format input version)
set(working "${CMAKE_CURRENT_BINARY_DIR}/${format}")
make_directory(${working})
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/images DESTINATION ${working})
set(xsltproc "/usr/bin/xsltproc")
set(docbookBasePath "/usr/share/xml/docbook/stylesheet/docbook-xsl-ns")
if(APPLE)
#extract the fop package to /opt/fop/
set(fop "/opt/fop/fop")
elseif(WIN32)
set(xsltproc "xsltproc")
set(fop "fop.cmd")
#set(docbookBasePath "/usr/share/xml/docbook/stylesheet/docbook-xsl-ns")
set(docbookBasePath "C:/cygwin/usr/share/xml/docbook/stylesheet/docbook-xsl-ns")
set(hhc "hhc")
else()
set(fop "/usr/bin/fop")
endif()
set(DOCBOOK_XSL_NS_PATH ${docbookBasePath})
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/myStyle.xsl.in
${CMAKE_CURRENT_BINARY_DIR}/myStyle.xsl)
if(format STREQUAL "html")
set(xslFile "${docbookBasePath}/html/docbook.xsl")
#TODO: include a custom CSS Style sheet:
#file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/myStyle.css DESTINATION ${working})
#--stringparam html.stylesheet myStyle.css
execute_process(
COMMAND "${xsltproc}" --xinclude -o "${working}/index.html" "${xslFile}" "${input}"
OUTPUT_VARIABLE _output)
elseif(format STREQUAL "pdf")
set(outputBaseName "${working}/${PROJECT_NAME}_User_Guide_${version}")
set(xslFile "${CMAKE_CURRENT_BINARY_DIR}/myStyle.xsl")
execute_process(
COMMAND "${xsltproc}" -o "${outputBaseName}.fo" --stringparam fop1.extensions 1 "${xslFile}" "${input}"
OUTPUT_VARIABLE _output)
execute_process(
COMMAND "${fop}" -fo "${outputBaseName}.fo" -pdf "${outputBaseName}.pdf"
OUTPUT_VARIABLE _output)
elseif(format STREQUAL "htmlhelp")
set(xslFile "${docbookBasePath}/htmlhelp/htmlhelp.xsl")
execute_process(
COMMAND "${xsltproc}" "${xslFile}" "${input}"
WORKING_DIRECTORY "${working}"
OUTPUT_VARIABLE _output)
#hhc requires a Windows path.
MAKE_WINDOWS_PATH(working)
execute_process(
COMMAND "${hhc}" "${working}\\htmlhelp.hhp"
WORKING_DIRECTORY "${working}"
OUTPUT_VARIABLE _output)
file(RENAME "${working}\\htmlhelp.chm" "${working}\\${PROJECT_NAME}.chm")
else()
message ( FATAL_ERROR "${format} is not supported by this cmake module. Please choose from html, pdf, pages, or htmlhelp" )
endif()
set(${outList} ${${outList}} PARENT_SCOPE)
endfunction()
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE book>
<book xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:db="http://docbook.org/ns/docbook"
id="@PROJECT_NAME@-user-guide" lang="en" version="5.0">
<bookinfo>
<title>The Official @PROJECT_NAME@ User Guide</title>
<subtitle>For Version @PROJECT_VERSION@</subtitle>
<productname>@PROJECT_NAME@</productname>
<productnumber>@PROJECT_VERSION@</productnumber>
<edition>@PROJECT_VERSION@</edition>
<copyright>
<year>@PROJECT_LIFE@</year>
<holder>@PROJECT_VENDOR@</holder>
</copyright>
<author>
<firstname></firstname><surname></surname>
<affiliation>
<jobtitle>Software Engineer</jobtitle>
<orgname>@PROJECT_VENDOR@</orgname>
</affiliation>
<address>
<city></city>
<street></street>
<postcode></postcode>
<country>USA</country>
</address>
</author>
<abstract>
<para>
<application>@PROJECT_NAME@</application>
This document will describe the features and abilities of <application>@PROJECT_NAME@</application>.
</para>
</abstract>
<mediaobject>
<imageobject>
<imagedata fileref="images/cover.png" format="PNG" />
</imageobject>
</mediaobject>
</bookinfo>
<preface id="introduction" version="5.0" xmlns="http://docbook.org/ns/docbook">
<title>Introduction</title>
</preface>
<chapter id="installation">
<title>Installation</title>
</chapter>
</book>
<?xml version="1.0"?>
<!DOCTYPE book>
<xsl:stylesheet version='1.0' xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:d="http://docbook.org/ns/docbook">
<!-- docbooks cannot do conditional imports so we're using cmake to conditionally set the path -->
<xsl:import href="@DOCBOOK_XSL_NS_PATH@/fo/docbook.xsl" />
<!-- create a cover with an image -->
<xsl:template name="book.titlepage.recto">
<xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="d:bookinfo/d:title"/>
<fo:block text-align="center">
<fo:external-graphic src="url(images/cover.png)"/>
</fo:block>
<xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="d:bookinfo/d:subtitle"/>
<xsl:apply-templates mode="book.titlepage.recto.auto.mode" select="d:bookinfo/d:author/d:affiliation/d:orgname"/>
</xsl:template>
<!-- create a block that says "by [orgname]" for the cover -->
<xsl:template match="d:orgname" mode="book.titlepage.recto.auto.mode">
<fo:block xsl:use-attribute-sets="book.titlepage.recto.style">
<xsl:text>by </xsl:text>
<xsl:apply-templates mode="titlepage.mode"/>
</fo:block>
</xsl:template>
<!-- create a text block that says "[author], [jobtitle] \n [orgname]" -->
<xsl:template match="d:author" mode="titlepage.mode">
<fo:block linefeed-treatment="preserve">
<xsl:call-template name="anchor"/>
<xsl:call-template name="person.name"/>
<xsl:if test="d:affiliation/d:jobtitle">
<xsl:text>, </xsl:text>
<xsl:apply-templates select="(d:affiliation/d:jobtitle)[1]"/>
</xsl:if>
<xsl:if test="d:affiliation/d:orgname">
<xsl:text>&#xA;</xsl:text> <!-- new line -->
<xsl:apply-templates select="d:affiliation/d:orgname" mode="titlepage.mode"/>
</xsl:if>
<xsl:if test="d:email|d:affiliation/d:address/d:email">
<xsl:text> </xsl:text>
<xsl:apply-templates select="(d:email|d:affiliation/d:address/d:email)[1]"/>
</xsl:if>
</fo:block>
</xsl:template>
<!-- Tell ulink to use the href.properties properties for styling the link -->
<xsl:template match="d:ulink" name="ulink">
<xsl:param name="url" select="@url"/>
<xsl:variable name ="ulink.url">
<xsl:call-template name="fo-external-image">
<xsl:with-param name="filename" select="$url"/>
</xsl:call-template>
</xsl:variable>
<fo:basic-link xsl:use-attribute-sets="href.properties"
external-destination="{$ulink.url}">
<xsl:choose>
<xsl:when test="count(child::node())=0">
<xsl:call-template name="hyphenate-url">
<xsl:with-param name="url" select="$url"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates/>
</xsl:otherwise>
</xsl:choose>
</fo:basic-link>
<!-- * Call the template for determining whether the URL for this -->
<!-- * hyperlink is displayed, and how to display it (either inline or -->
<!-- * as a numbered footnote). -->
<xsl:call-template name="hyperlink.url.display">
<xsl:with-param name="url" select="$url"/>
<xsl:with-param name="ulink.url" select="$ulink.url"/>
</xsl:call-template>
</xsl:template>
<xsl:template match="d:guibutton">
<xsl:call-template name="inline.boldseq"/>
</xsl:template>
<xsl:template match="d:guiicon">
<xsl:call-template name="inline.boldseq"/>
</xsl:template>
<xsl:template match="d:guilabel">
<xsl:call-template name="inline.boldseq"/>
</xsl:template>
<xsl:template match="d:guimenu">
<xsl:call-template name="inline.boldseq"/>
</xsl:template>
<xsl:template match="d:guimenuitem">
<xsl:call-template name="inline.boldseq"/>
</xsl:template>
<xsl:template match="d:guisubmenu">
<xsl:call-template name="inline.boldseq"/>
</xsl:template>
<xsl:template match="d:caption">
<fo:block>
<xsl:if test="@align = 'right' or @align = 'left' or @align='center'">
<xsl:attribute name="text-align"><xsl:value-of
select="@align"/></xsl:attribute>
</xsl:if>
<xsl:call-template name="inline.italicseq" />
</fo:block>
</xsl:template>
<!-- style <link> -->
<xsl:attribute-set name="xref.properties">
<xsl:attribute name="color">blue</xsl:attribute>
</xsl:attribute-set>
<!-- style <ulink> -->
<xsl:param name="ulink.show" select="0" />
<xsl:attribute-set name="href.properties">
<xsl:attribute name="color">blue</xsl:attribute>
<xsl:attribute name="text-decoration">underline</xsl:attribute>
</xsl:attribute-set>
<!-- Style <term> -->
<xsl:attribute-set name="variablelist.term.properties">
<xsl:attribute name="font-weight">bold</xsl:attribute>
</xsl:attribute-set>
</xsl:stylesheet>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment