[project @ 2004-08-15 20:28:02 by panne]
authorpanne <unknown>
Sun, 15 Aug 2004 20:28:08 +0000 (20:28 +0000)
committerpanne <unknown>
Sun, 15 Aug 2004 20:28:08 +0000 (20:28 +0000)
<fanfare>Finally: Support for DocBook XML!</fanfare>

After endless frustrating hours, I came to the conclusion that using (Open)Jade
for DocBook XML is virtually impossible, there are *tons* of problems with it:
Wildly differing paths, incorrect stylesheets, broken catalogs at funny places,
broken wrapper scripts, missing support on Cygwin etc.  >:-P * * *

So we follow the ubiquitous XSL hype and use xsltproc + DocBook XSL stylesheets
to transform DocBook XML to HTML and FO. From FO there are two routes to PDF and
PostScript: Either via FOP (preferred) or via PassiveTeX. Validation can be done
via xmllint using the new make target "validate". When PassiveTeX is available,
DVI can be generated, too.  A new make target "no-chunks-html" is available for
generating an all-in-one HTML document. Currently there is no way to generate
plain text or RTF, but at least the former could easily be added.

Generating HTML works out-of-the-box on Cygwin now, but you will have to install
FOP for other formats, because there seems to be no standard package for it.

The HTML appearance can be controlled via CSS, but the current location of the
master stylesheet below fptools/mk is a bit debatable. Better suggestions are
welcome.

Currently there is still support for SGML documents, but it will be dropped when
all documents are converted to DocBook XML. The build system is complex enough
already with the support for a *single* kind of DocBook...

Makefile
aclocal.m4
configure.ac
mk/config.mk.in
mk/fptools.css [new file with mode: 0644]
mk/opts.mk
mk/paths.mk
mk/suffix.mk
mk/target.mk

index e4b5614..593783e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -287,14 +287,14 @@ ifneq "$(DOCBOOK_CATALOG)" ""
        @for i in $(BIN_DIST_DIRS); do                          \
          if test -d "$$i"; then                                \
            $(MAKE) -C $$i $(MFLAGS) $(BINDIST_DOC_WAYS);       \
-           echo $(MAKE) -C $$i $(MFLAGS) install-docs SGMLDocWays="$(BINDIST_DOC_WAYS)" \
+           echo $(MAKE) -C $$i $(MFLAGS) install-docs SGMLDocWays="$(BINDIST_DOC_WAYS)" XMLDocWays="$(BINDIST_DOC_WAYS)" \
                prefix=$(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)      \
                exec_prefix=$(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME) \
                bindir=$(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/bin/$(TARGETPLATFORM) \
                libdir=$(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/lib/$(TARGETPLATFORM) \
                libexecdir=$(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/lib/$(TARGETPLATFORM) \
                datadir=$(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/share; \
-           $(MAKE) -C $$i $(MFLAGS) install-docs SGMLDocWays="$(BINDIST_DOC_WAYS)" \
+           $(MAKE) -C $$i $(MFLAGS) install-docs SGMLDocWays="$(BINDIST_DOC_WAYS)" XMLDocWays="$(BINDIST_DOC_WAYS)" \
                prefix=$(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)      \
                exec_prefix=$(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME) \
                bindir=$(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/bin/$(TARGETPLATFORM) \
index d5a3c83..e2c46f7 100644 (file)
@@ -5,7 +5,7 @@
 
 
 # FP_EVAL_STDERR(COMMAND)
-# ------------------------
+# -----------------------
 # Eval COMMAND, save its stderr (without lines resulting from shell tracing)
 # into the file conftest.err and the exit status in the variable fp_status.
 AC_DEFUN([FP_EVAL_STDERR],
@@ -18,7 +18,7 @@ AC_DEFUN([FP_EVAL_STDERR],
 
 
 # FP_CHECK_FLAG(FLAG, [ACTION-IF-SUPPORTED], [ACTION-IF-NOT-SUPPORTED])
-# -----------------------------------------------------------------------
+# ---------------------------------------------------------------------
 # Check to see whether the compiler for the current language supports a
 # particular option.
 #
@@ -76,7 +76,7 @@ AC_SUBST(ContextDiffCmd, [$fp_cv_context_diff])
 
 
 # FP_DECL_ALTZONE
-# -------------------
+# ---------------
 # Defines HAVE_DECL_ALTZONE to 1 if declared, 0 otherwise.
 #
 # Used by base package.
@@ -97,7 +97,7 @@ AC_CHECK_DECLS([altzone], [], [],[#if TIME_WITH_SYS_TIME
 
 
 # FP_COMPUTE_INT(EXPRESSION, VARIABLE, INCLUDES, IF-FAILS)
-# ---------------------------------------------------------
+# --------------------------------------------------------
 # Assign VARIABLE the value of the compile-time EXPRESSION using INCLUDES for
 # compilation. Execute IF-FAILS when unable to determine the value. Works for
 # cross-compilation, too.
@@ -135,7 +135,7 @@ m4_popdef([fp_Cache])[]dnl
 
 
 # FP_CHECK_CONST(EXPRESSION, [INCLUDES = DEFAULT-INCLUDES], [VALUE-IF-FAIL = -1])
-# ---------------------------------------------------------------------------------
+# -------------------------------------------------------------------------------
 # Defines CONST_EXPRESSION to the value of the compile-time EXPRESSION, using
 # INCLUDES. If the value cannot be determined, use VALUE-IF-FAIL.
 AC_DEFUN([FP_CHECK_CONST],
@@ -150,7 +150,7 @@ AS_VAR_POPDEF([fp_Cache])[]dnl
 
 
 # FP_CHECK_CONSTS_TEMPLATE(EXPRESSION...)
-# ----------------------------------
+# ---------------------------------------
 # autoheader helper for FP_CHECK_CONSTS
 m4_define([FP_CHECK_CONSTS_TEMPLATE],
 [AC_FOREACH([fp_Const], [$1],
@@ -160,7 +160,7 @@ m4_define([FP_CHECK_CONSTS_TEMPLATE],
 
 
 # FP_CHECK_CONSTS(EXPRESSION..., [INCLUDES = DEFAULT-INCLUDES], [VALUE-IF-FAIL = -1])
-# -------------------------------------------------------------------------------------
+# -----------------------------------------------------------------------------------
 # List version of FP_CHECK_CONST
 AC_DEFUN(FP_CHECK_CONSTS,
 [FP_CHECK_CONSTS_TEMPLATE([$1])dnl
@@ -830,6 +830,130 @@ AS_VAR_POPDEF([fp_func])dnl
 ])# FP_CHECK_FUNC
 
 
+# FP_GEN_DOCBOOK_XML
+# ------------------
+# Generates a DocBook XML V4.2 document in conftest.xml.
+AC_DEFUN([FP_GEN_DOCBOOK_XML],
+[rm -f conftest.xml
+cat > conftest.xml << EOF
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<book id="test">
+  <title>A DocBook Test Document</title>
+  <chapter id="id-one">
+    <title>A Chapter Title</title>
+    <para>This is a paragraph, referencing <xref linkend="id-two"/>.</para>
+  </chapter>
+  <chapter id="id-two">
+    <title>Another Chapter Title</title>
+    <para>This is another paragraph, referencing <xref linkend="id-one"/>.</para>
+  </chapter>
+</book>
+EOF
+]) # FP_GEN_DOCBOOK_XML
+
+
+# FP_PROG_XSLTPROC
+# ----------------
+# Sets the output variable XsltprocCmd to the full path of the XSLT processor
+# xsltproc. XsltprocCmd is empty if xsltproc could not be found.
+AC_DEFUN([FP_PROG_XSLTPROC],
+[AC_PATH_PROG([XsltprocCmd], [xsltproc])
+if test -z "$XsltprocCmd"; then
+  AC_MSG_WARN([cannot find xsltproc in your PATH, you will not be able to build the documentation])
+fi
+])# FP_PROG_XSLTPROC
+
+
+# FP_DIR_DOCBOOK_XSL(XSL-DIRS)
+# ----------------------------
+# Check which of the directories XSL-DIRS contains DocBook XSL stylesheets. The
+# output variable DIR_DOCBOOK_XSL will contain the first usable directory or
+# will be empty if none could be found.
+AC_DEFUN([FP_DIR_DOCBOOK_XSL],
+[AC_REQUIRE([FP_PROG_XSLTPROC])dnl
+if test -n "$XsltprocCmd"; then
+  AC_CACHE_CHECK([for DocBook XSL stylesheet directory], fp_cv_dir_docbook_xsl,
+  [FP_GEN_DOCBOOK_XML
+  fp_cv_dir_docbook_xsl=no
+  for fp_var in $1; do
+     if $XsltprocCmd ${fp_var}/html/docbook.xsl conftest.xml > /dev/null 2>&1; then
+        fp_cv_dir_docbook_xsl=$fp_var
+        break
+     fi
+  done
+  rm -rf conftest*])
+fi
+if test x"$fp_cv_dir_docbook_xsl" = xno; then
+  AC_MSG_WARN([cannot find DocBook XSL stylesheets, you will not be able to build the documentation])
+  DIR_DOCBOOK_XSL=
+else
+  DIR_DOCBOOK_XSL=$fp_cv_dir_docbook_xsl
+fi
+AC_SUBST([DIR_DOCBOOK_XSL])
+])# FP_DIR_DOCBOOK_XSL
+
+
+# FP_PROG_XMLLINT
+# ----------------
+# Sets the output variable XmllintCmd to the full path of the XSLT processor
+# xmllint. XmllintCmd is empty if xmllint could not be found.
+AC_DEFUN([FP_PROG_XMLLINT],
+[AC_PATH_PROG([XmllintCmd], [xmllint])
+if test -z "$XmllintCmd"; then
+  AC_MSG_WARN([cannot find xmllint in your PATH, you will not be able to validate your documentation])
+fi
+])# FP_PROG_XMLLINT
+
+
+# FP_CHECK_DOCBOOK_DTD
+# --------------------
+AC_DEFUN([FP_CHECK_DOCBOOK_DTD],
+[AC_REQUIRE([FP_PROG_XMLLINT])dnl
+if test -n "$XmllintCmd"; then
+  AC_MSG_CHECKING([for DocBook DTD])
+  FP_GEN_DOCBOOK_XML
+  if $XmllintCmd --valid --noout conftest.xml > /dev/null 2>&1; then
+    AC_MSG_RESULT([ok])
+  else
+    AC_MSG_RESULT([failed])
+    AC_MSG_WARN([cannot find a DTD for DocBook XML V4.2, you will not be able to validate your documentation])
+    AC_MSG_WARN([check your XML_CATALOG_FILES environment variable and/or /etc/xml/catalog])
+  fi
+  rm -rf conftest*
+fi
+])# FP_CHECK_DOCBOOK_DTD
+
+
+# FP_PROG_FO_PROCESSOR
+# --------------------
+# Try to find an FO processor. PassiveTeX output is sometimes a bit strange, so
+# try FOP first.  Furthermore, /usr/bin/fop is broken in SuSE 9.1, so try the
+# "real" fop.sh first. Sets the output variables FopCmd, XmltexCmd, DvipsCmd,
+# and PdfxmltexCmd.
+AC_DEFUN([FP_PROG_FO_PROCESSOR],
+[AC_PATH_PROGS([FopCmd], [fop.sh fop], [], [$PATH:/usr/share/fop])
+AC_PATH_PROG([XmltexCmd], [xmltex])
+AC_PATH_PROG([DvipsCmd], [dvips])
+if test -z "$FopCmd"; then
+  if test -z "$XmltexCmd"; then
+    AC_MSG_WARN([cannot find an FO => DVI converter, you will not be able to build DVI or PostScript documentation])
+  else
+    if test -z "$DvipsCmd"; then
+      AC_MSG_WARN([cannot find a DVI  => PS converter, you will not be able to build PostScript documentation])
+    fi
+  fi
+  AC_PATH_PROG([PdfxmltexCmd], [pdfxmltex])
+  if test -z "$PdfxmltexCmd"; then
+    AC_MSG_WARN([cannot find an FO => PDF converter, you will not be able to build PDF documentation])
+  fi
+elif test -z "$XmltexCmd"; then
+  AC_MSG_WARN([cannot find an FO => DVI converter, you will not be able to build DVI documentation])
+fi
+])# FP_PROG_FO_PROCESSOR
+
+
 dnl ** Check which CATALOG file we have to use with DocBook SGML.
 dnl
 dnl FPTOOLS_DOCBOOK_CATALOG(VARIABLE, JADE, STYLESHEET, CATALOGS-TO-CHECK-FOR)
index df1ef00..f7841b8 100644 (file)
@@ -854,6 +854,11 @@ dnl ** check for tar
 dnl   if GNU tar is named gtar, look for it first.
 AC_PATH_PROGS(TarCmd,gtar tar,tar)
 
+dnl ** check for DocBook toolchain
+FP_CHECK_DOCBOOK_DTD
+FP_DIR_DOCBOOK_XSL([/usr/share/xml/docbook/stylesheet/nwalsh/current /usr/share/sgml/docbook/docbook-xsl-stylesheets* /opt/kde?/share/apps/ksgmltools2/docbook/xsl /usr/share/docbook-xsl /usr/share/sgml/docbkxsl])
+FP_PROG_FO_PROCESSOR
+
 dnl ** check for jade/openjade & determine a working catalog
 AC_PATH_PROGS(JadeCmd,openjade jade,jade)
 FPTOOLS_DOCBOOK_CATALOG(Catalog, $JadeCmd, docs/fptools-both.dsl, 
index 37a7f41..6d61470 100644 (file)
@@ -185,6 +185,12 @@ IncludeExampleDirsInBuild=NO
 #
 SGMLDocWays=
 
+#
+# Which ways should DocBook XML documents be built?
+# options are: dvi ps pdf html
+#
+XMLDocWays=
+
 ################################################################################
 #
 #              GHC project
@@ -902,6 +908,18 @@ SRC_SGML2PDF_OPTS       = -d $(SGMLSTYLESHEET)
 DOCBOOK_CATALOG                = @Catalog@
 
 #-----------------------------------------------------------------------------
+# DocBook XML stuff
+
+XSLTPROC               = @XsltprocCmd@
+XMLLINT                        = @XmllintCmd@
+FOP                    = @FopCmd@
+XMLTEX                 = @XmltexCmd@
+PDFXMLTEX              = @PdfxmltexCmd@
+DVIPS                  = @DvipsCmd@
+
+DIR_DOCBOOK_XSL                = @DIR_DOCBOOK_XSL@
+
+#-----------------------------------------------------------------------------
 #              FPtools support software
 
 # Stuff from fptools/glafp-utils
diff --git a/mk/fptools.css b/mk/fptools.css
new file mode 100644 (file)
index 0000000..8e7ad6f
--- /dev/null
@@ -0,0 +1,29 @@
+div.article div.book {
+  font-family: sans-serif;
+  color: black;
+  background: white
+}
+
+h1, h2, h3 { color: #005A9C }
+
+h1 { font:            170% sans-serif }
+h2 { font:            140% sans-serif }
+h3 { font:            120% sans-serif }
+h4 { font: bold       100% sans-serif }
+h5 { font: italic     100% sans-serif }
+h6 { font: small-caps 100% sans-serif }
+
+pre {
+  font-family: monospace;
+  border-width: 1px;
+  border-style: solid;
+  padding: 0.3em
+}
+
+pre.screen         { color: green  }
+pre.programlisting { color: maroon }
+
+a:link    { color:      #0000C8 }
+a:hover   { background: #FFFFA8 }
+a:active  { color:      #D00000 }
+a:visited { color:      #680098 }
index 1c8e189..778bb42 100644 (file)
@@ -5,7 +5,7 @@
 #      This file defines Make variables for the
 #      option flags for each utility program
 #
-#      $Id: opts.mk,v 1.34 2003/08/18 15:45:09 panne Exp $
+#      $Id: opts.mk,v 1.35 2004/08/15 20:28:06 panne Exp $
 #
 #################################################################################
 
@@ -104,6 +104,8 @@ SGML2PS_OPTS       = $(SRC_SGML2PS_OPTS) $(WAY$(_way)_SGML2PS_OPTS) $(EXTRA_SGML
 SGML2PDF_OPTS      = $(SRC_SGML2PDF_OPTS) $(WAY$(_way)_SGML2PDF_OPTS) $(EXTRA_SGML2PDF_OPTS)
 SGML2RTF_OPTS      = $(SRC_SGML2RTF_OPTS) $(WAY$(_way)_SGML2RTF_OPTS) $(EXTRA_SGML2RTF_OPTS)
 SGML2HTML_OPTS     = $(SRC_SGML2HTML_OPTS) $(WAY$(_way)_SGML2HTML_OPTS) $(EXTRA_SGML2HTML_OPTS)
+XSLTPROC_OPTS      = $(WAY$(_way)_XSLTPROC_OPTS) $(EXTRA_XSLTPROC_OPTS)
+FOP_OPTS           = $(WAY$(_way)_FOP_OPTS) $(EXTRA_FOP_OPTS)
 UNLIT_OPTS         = $(SRC_UNLIT_OPTS) $(WAY$(_way)_UNLIT_OPTS) $(EXTRA_UNLIT_OPTS)
 ZIP_OPTS           = $(SRC_ZIP_OPTS) $(EXTRA_ZIP_OPTS)
 
index 6951116..5c88a62 100644 (file)
@@ -351,3 +351,6 @@ SRC_DIST_NAME=$(ProjectNameShort)-$(ProjectVersion)
 
 DLL_PEN = $(FPTOOLS_TOP)/dll
 
+#------------------------------------------------------------------
+
+FPTOOLS_CSS = $(FPTOOLS_TOP)/mk/fptools.css
index a975c5d..c427a01 100644 (file)
@@ -240,13 +240,63 @@ endif
        $(TIME) $(RUNTEST) $(HC) $(RUNTEST_OPTS) $<
 
 #-----------------------------------------------------------------------------
+# DocBook XML suffix rules
+#
+
+%-no-chunks.html : %.xml
+       $(XSLTPROC) --output $@ \
+                   --stringparam html.stylesheet fptools.css \
+                   $(XSLTPROC_OPTS) $(DIR_DOCBOOK_XSL)/html/docbook.xsl $<
+       cp $(FPTOOLS_CSS) .
+
+%.html : %.xml
+       @$(RM) -rf $@ $(basename $@)
+       $(XSLTPROC) --stringparam base.dir $(basename $@)/ \
+                   --stringparam use.id.as.filename 1 \
+                   --stringparam root.filename '' \
+                   --stringparam html.stylesheet fptools.css \
+                   $(XSLTPROC_OPTS) $(DIR_DOCBOOK_XSL)/html/chunk.xsl $<
+       cp $(FPTOOLS_CSS) $(basename $@)
+       touch $@
+
+%.fo : %.xml
+       $(XSLTPROC) --output $@ \
+                   $(XSLTPROC_OPTS) $(DIR_DOCBOOK_XSL)/fo/docbook.xsl $<
+
+ifeq "$(FOP)" ""
+ifneq "$(PDFXMLTEX)" ""
+%.pdf : %.fo
+       $(PDFXMLTEX) $<
+       if grep "LaTeX Warning: Label(s) may have changed.Rerun to get cross-references right." $(basename $@).log > /dev/null ; then \
+         $(PDFXMLTEX) $< ; \
+         $(PDFXMLTEX) $< ; \
+       fi
+endif
+else
+%.ps : %.fo
+       $(FOP) $(FOP_OPTS) -fo $< -ps $@
+
+%.pdf : %.fo
+       $(FOP) $(FOP_OPTS) -fo $< -pdf $@
+endif
+
+ifneq "$(XMLTEX)" ""
+%.dvi : %.fo
+       $(XMLTEX) $<
+       if grep "LaTeX Warning: Label(s) may have changed.Rerun to get cross-references right." $(basename $@).log > /dev/null ; then \
+         $(XMLTEX) $< ; \
+         $(XMLTEX) $< ; \
+       fi
+endif
+
+#-----------------------------------------------------------------------------
 # Doc processing suffix rules
 #
 # ToDo: make these more robust
 #
 %.ps : %.dvi
        @$(RM) $@
-       dvips $< -o $@
+       $(DVIPS) $< -o $@
 
 %.tex : %.tib
        @$(RM) $*.tex $*.verb-t.tex
index 109dbfc..a823d57 100644 (file)
@@ -802,6 +802,35 @@ install-docs:: $(INSTALL_DOCS)
                $(INSTALL_DATA) $(INSTALL_OPTS) $$i $(datadir); \
        done
 endif
+ifneq "$(XMLDocWays)" ""
+install-docs:: $(INSTALL_DOCS)
+       @$(INSTALL_DIR) $(datadir)      
+       for i in $(INSTALL_DOCS); do \
+               $(INSTALL_DATA) $(INSTALL_OPTS) $$i $(datadir); \
+       done
+endif
+endif
+
+# The following could be an entry for an Obfuscated Makefile Contest...
+ifneq "$(INSTALL_XML_DOC)" ""
+ifneq "$(XMLDocWays)" ""
+install-docs:: $(foreach i,$(XMLDocWays),$(INSTALL_XML_DOC)$(subst .no-chunks-html,-no-chunks.html,.$(i)))
+       @$(INSTALL_DIR) $(datadir)      
+       @for i in $(XMLDocWays); do \
+               if [ $$i = "html" ]; then \
+                       $(INSTALL_DIR) $(datadir)/html; \
+                       echo $(CP) -r $(INSTALL_XML_DOC) $(datadir)/html; \
+                       $(CP) -r $(INSTALL_XML_DOC) $(datadir)/html; \
+               else \
+                       echo $(INSTALL_DATA) $(INSTALL_OPTS) $(INSTALL_XML_DOC)`echo .$$i | sed s/\.no-chunks-html/-no-chunks.html/` $(datadir); \
+                       $(INSTALL_DATA) $(INSTALL_OPTS) $(INSTALL_XML_DOC)`echo .$$i | sed s/\.no-chunks-html/-no-chunks.html/` $(datadir); \
+               fi; \
+               if [ $$i = "no-chunks-html" ]; then \
+                       echo $(CP) $(FPTOOLS_CSS) $(datadir); \
+                       $(CP) $(FPTOOLS_CSS) $(datadir); \
+               fi \
+       done
+endif
 endif
 
 ifneq "$(INSTALL_SGML_DOC)" ""
@@ -948,6 +977,50 @@ extraclean ::
        $(RM) -rf $(SGML_DOC)
 endif
 
+################################################################################
+#
+#                      DocBook XML Documentation
+#
+################################################################################
+
+.PHONY: html no-chunks-html fo dvi ps pdf
+
+ifneq "$(XML_DOC)" ""
+
+all :: $(XMLDocWays)
+
+# multi-file XML document: main document name is specified in $(XML_DOC),
+# sub-documents (.xml files) listed in $(XML_SRCS).
+
+ifeq "$(XML_SRCS)" ""
+XML_SRCS = $(wildcard *.xml)
+endif
+
+XML_HTML           = $(addsuffix .html,$(XML_DOC))
+XML_NO_CHUNKS_HTML = $(addsuffix -no-chunks.html,$(XML_DOC))
+XML_FO             = $(addsuffix .fo,$(XML_DOC))
+XML_DVI            = $(addsuffix .dvi,$(XML_DOC))
+XML_PS             = $(addsuffix .ps,$(XML_DOC))
+XML_PDF            = $(addsuffix .pdf,$(XML_DOC))
+
+$(XML_HTML) $(XML_NO_CHUNKS_HTML) $(XML_FO) $(XML_DVI) $(XML_PS) $(XML_PDF) :: $(XML_SRCS)
+
+html           :: $(XML_HTML)
+no-chunks-html :: $(XML_NO_CHUNKS_HTML)
+fo             :: $(XML_FO)
+dvi            :: $(XML_DVI)
+ps             :: $(XML_PS)
+pdf            :: $(XML_PDF)
+
+CLEAN_FILES += $(XML_HTML) $(XML_NO_CHUNKS_HTML) $(XML_FO) $(XML_DVI) $(XML_PS) $(XML_PDF)
+
+extraclean ::
+       $(RM) -rf $(XML_DOC).out $(XML_DOC)
+
+validate ::
+       $(XMLLINT) --valid --noout $(XMLLINT_OPTS) $(XML_DOC).xml
+endif
+
 ##############################################################################
 #
 #      Targets: clean