Notes
Outline
Customising the nwalsh DSSSL stylesheets
nik@FreeBSD.org
Why customise?
Fit in with corporate look and feel
Support an additional language
Support custom DocBook DTD extensions
Fix bugs
Adjust the documented parameters
Creating a customisation layer
DSSSL processor is directed to one stylesheet
Stylesheets can reference other stylesheets
First definition of variable or code takes precedence over later definitions
Your customisation references nwalsh’s stylesheets, and just contains overrides
Simplest possible customisation
The empty stylesheet
<!DOCTYPE style-sheet PUBLIC "-//James Clark//DTD DSSSL Style Sheet//EN" [
<!ENTITY parent-stylesheet SYSTEM “/path/to/docbook.dsl" CDATA DSSSL>
]>
<style-sheet>
  <style-specification use="docbook">
    <style-specification-body>
    </style-specification-body>
  </style-specification>
  <external-specification id="docbook" document=“parent-stylesheet">
</style-sheet>
% jade –c /path/to/catalog –d custom.dsl –t sgml file.sgml
Customising using documented variables
nwalsh stylesheets have wide range of tweakable knobs
All take the form
(define variable-name value)
Some historical conventions for variable names
%var-name%    Simple variable
$var-name$    Code that returns a value
Newer variables are not decorated in this way
See the documentation at http://www.nwalsh.com/docbook/dsssl/doc/
A trivial customisation
<!DOCTYPE style-sheet PUBLIC "-//James Clark//DTD DSSSL Style Sheet//EN" [
<!ENTITY parent-stylesheet SYSTEM “/path/to/docbook.dsl" CDATA DSSSL>
]>
<style-sheet>
  <style-specification use="docbook">
    <style-specification-body>
      (define %generate-article-toc% #t)
    </style-specification-body>
  </style-specification>
  <external-specification id="docbook" document=“parent-stylesheet">
</style-sheet>
% jade –c /path/to/catalog –d custom.dsl –t sgml file.sgml
Taking things further
Sharing customisation options between print and HTML stylesheets
A tour of the stylesheet structure
Extending DocBook, with stylesheet support
Writing your own DSSSL, rewriting the stylesheets
Customising your customisations
Sharing options between print and HTML stylesheets
Many configuration options are identical
Useful to have one stylesheet for print and HTML output
Avoids duplicate code
Requires use of parameter entities
In the Document Type Declaration
<!DOCTYPE style-sheet PUBLIC "-//James Clark//DTD DSSSL Style Sheet//EN" [
<!ENTITY % output.html    “IGNORE”>
<!ENTITY % output.print   “IGNORE”>
<![ %output.html; [
<!ENTITY parent-stylesheet SYSTEM “/path/to/html/docbook.dsl" CDATA DSSSL>
]]>
<![ %output.print; [
<!ENTITY parent-stylesheet SYSTEM “/path/to/print/docbook.dsl” CDATA DSSSL>
]]>
]>
<style-sheet>
  <style-specification use="docbook">
. . .
In the stylesheet body
<style-sheet>
  <style-specification use="docbook">
    <style-specification-body>
<![ %output.html; [                       <!-- HTML specific customisations -->
      (define %generate-article-toc% #t)
]]>
<![ %output.print; [                      <!-- Print specific customisations -->
]]>
      <!-- Non-specific customisations -->
    </style-specification-body>
  </style-specification>
  <external-specification id="docbook" document=“parent-stylesheet">
</style-sheet>
On the command line
For HTML

% jade –i output.html –c /path/to/catalog –d custom.dsl –t sgml file.sgml
For Postscript

% jade –i output.print –c /path/to/catalog –d custom.dsl –t tex file.sgml
Can be further extended
%output.html;
%output.print.ps;
%output.print.pdf;
%output.print.rtf;
…
A tour of the stylesheets
Three main directories of interest
html/     HTML stylesheet files
print/     Print stylesheet files
common/     Common code shared between them
Stylesheet “root” is html/docbook.dsl or print/docbook.dsl respectively
Other files handle chunks of work
The other files
Naming scheme is obvious when you know
dbadmon.dsl      Admonitions (<tip>, <note>, etc)
dbacallou.dsl  Callouts
dbfootn.dsl    Footnotes
dblink.dsl    <xref>, <ulink>, etc
dbrfntry.dsl    <refentry>, etc
dbverb.dsl    Verbatim displays (<screen>,               <literallayout>, etc)
And so on
Two types of DSSSL code
Code that describes how an element should be processed
(element element-name ... )
Code that defines functions used in processing elements
(define function-name ... )
Element processing may be self-contained, or it may rely on multiple functions
Tracing an element’s definition
% cd html
% grep ‘element emphasis’ *.dsl
dbinline.dsl:(element emphasis ($italic-seq$))
% grep ‘italic-seq’ *.dsl
dbgloss.dsl:          ($italic-seq$))
dbgloss.dsl:    ($italic-seq$))))
dbgloss.dsl:                        ($italic-seq$))
dbgloss.dsl:                  ($italic-seq$))))
dbhtml.dsl:(define ($italic-seq$ #!optional (sosofo (process-children)))
dbhtml.dsl:(define ($bold-italic-seq$ #!optional (sosofo (process-children)))
dbinline.dsl:(element medialabel ($italic-seq$))
dbinline.dsl:      ($italic-seq$)
dbinline.dsl:(element citetitle ($italic-seq$))
dbinline.dsl:(element emphasis ($italic-seq$))
dbinline.dsl:(element foreignphrase ($italic-seq$))
dbinline.dsl:(element wordasword ($italic-seq$))
dblink.dsl:    ($italic-seq$)))
Tracing an element’s definition
% cd html
% grep ‘element emphasis’ *.dsl
dbinline.dsl:(element emphasis ($italic-seq$))
% grep ‘italic-seq’ *.dsl
dbgloss.dsl:          ($italic-seq$))
dbgloss.dsl:    ($italic-seq$))))
dbgloss.dsl:                        ($italic-seq$))
dbgloss.dsl:                  ($italic-seq$))))
dbhtml.dsl:(define ($italic-seq$ #!optional (sosofo (process-children)))
dbhtml.dsl:(define ($bold-italic-seq$ #!optional (sosofo (process-children)))
dbinline.dsl:(element medialabel ($italic-seq$))
dbinline.dsl:      ($italic-seq$)
dbinline.dsl:(element citetitle ($italic-seq$))
dbinline.dsl:(element emphasis ($italic-seq$))
dbinline.dsl:(element foreignphrase ($italic-seq$))
dbinline.dsl:(element wordasword ($italic-seq$))
dblink.dsl:    ($italic-seq$)))
Tracing an element’s definition
dbhtml.dsl
. . .
(define ($bold-seq$ #!optional (sosofo (process-children)))
  (make element gi: "B"
        attributes: (list
                     (list "CLASS" (gi)))
        sosofo))
(define ($italic-seq$ #!optional (sosofo (process-children)))
  (make element gi: "I"
        attributes: (list
                     (list "CLASS" (gi)))
        sosofo))
(define ($bold-italic-seq$ #!optional (sosofo (process-children)))
  (make element gi: "B"
        attributes: (list
                     (list "CLASS" (gi)))
        (make element gi: "I"
              sosofo)))
Tracing an element’s definition
% cd ../print
% grep ‘element emphasis’ *.dsl
dbinline.dsl:(element emphasis ($italic-seq$))
% grep 'italic-seq' *.dsl
dbgloss.dsl:(element glosssee ($italic-seq$))
dbgloss.dsl:      ($italic-seq$ (literal (gentext-element-name (current-node))
dbgloss.dsl:    ($italic-seq$ (literal (gentext-element-name (current-node))
dbgloss.dsl:        ($italic-seq$ (literal ", ")))
dbgloss.dsl:      ($italic-seq$))
dbgloss.dsl:    ($italic-seq$))))
dbgloss.dsl:                    ($italic-seq$))
dbinline.dsl:(element medialabel ($italic-seq$))
dbinline.dsl:      ($italic-seq$)
dbinline.dsl:(element citetitle ($italic-seq$))
dbinline.dsl:(element emphasis ($italic-seq$))
dbinline.dsl:(element foreignphrase ($italic-seq$))
dbinline.dsl:(element wordasword ($italic-seq$))
dblink.dsl:    ($italic-seq$)))
dbprint.dsl:(define ($italic-seq$ #!optional (sosofo (process-children)))
dbprint.dsl:(define ($bold-italic-seq$ #!optional (sosofo (process-children)))
Tracing an element’s definition
% cd ../print
% grep ‘element emphasis’ *.dsl
dbinline.dsl:(element emphasis ($italic-seq$))
% grep 'italic-seq' *.dsl
dbgloss.dsl:(element glosssee ($italic-seq$))
dbgloss.dsl:      ($italic-seq$ (literal (gentext-element-name (current-node))
dbgloss.dsl:    ($italic-seq$ (literal (gentext-element-name (current-node))
dbgloss.dsl:        ($italic-seq$ (literal ", ")))
dbgloss.dsl:      ($italic-seq$))
dbgloss.dsl:    ($italic-seq$))))
dbgloss.dsl:                    ($italic-seq$))
dbinline.dsl:(element medialabel ($italic-seq$))
dbinline.dsl:      ($italic-seq$)
dbinline.dsl:(element citetitle ($italic-seq$))
dbinline.dsl:(element emphasis ($italic-seq$))
dbinline.dsl:(element foreignphrase ($italic-seq$))
dbinline.dsl:(element wordasword ($italic-seq$))
dblink.dsl:    ($italic-seq$)))
dbprint.dsl:(define ($italic-seq$ #!optional (sosofo (process-children)))
dbprint.dsl:(define ($bold-italic-seq$ #!optional (sosofo (process-children)))
Tracing an element’s definition
dbprint.dsl
. . .
(define ($bold-seq$ #!optional (sosofo (process-children)))
  (make sequence
    font-weight: 'bold
    sosofo))
(define ($italic-seq$ #!optional (sosofo (process-children)))
  (make sequence
    font-posture: 'italic
    sosofo))
(define ($bold-italic-seq$ #!optional (sosofo (process-children)))
  (make sequence
    font-weight: 'bold
    font-posture: 'italic
    sosofo))
Other …-seq functions
% grep -- -seq *.dsl | grep ‘(define’
dbhtml.dsl:(define ($bold-seq$ #!optional (sosofo (process-children)))
dbhtml.dsl:(define ($italic-seq$ #!optional (sosofo (process-children)))
dbhtml.dsl:(define ($bold-italic-seq$ #!optional (sosofo (process-children)))
dbhtml.dsl:(define ($mono-seq$ #!optional (sosofo (process-children)))
dbhtml.dsl:(define ($italic-mono-seq$ #!optional (sosofo (process-children)))
dbhtml.dsl:(define ($bold-mono-seq$ #!optional (sosofo (process-children)))
Rendering <emphasis> in bold
<style-sheet>
  <style-specification use="docbook">
    <style-specification-body>
<![ %output.html; [                       <!-- HTML specific customisations -->
]]>
<![ %output.print; [                      <!-- Print specific customisations -->
]]>
      <!-- Non-specific customisations -->
      (element emphasis ($bold-seq$))
    </style-specification-body>
  </style-specification>
  <external-specification id="docbook" document=“parent-stylesheet">
</style-sheet>
Rendering <emphasis> in bold
<style-sheet>
  <style-specification use="docbook">
    <style-specification-body>
<![ %output.html; [                       <!-- HTML specific customisations -->
      (element emphasis ($bold-seq$))
]]>
<![ %output.print; [                      <!-- Print specific customisations -->
]]>
      <!-- Non-specific customisations -->
    </style-specification-body>
  </style-specification>
  <external-specification id="docbook" document=“parent-stylesheet">
</style-sheet>
Rendering based on attribute
Q: How to make <emphasis> appear in italic, and <emphasis role=“bold”> appear in bold?
Rendering based on attribute
Find another element with similar behaviour written in the stylesheets
<literallayout>
and
<literallayout class=“monospaced”>
Rendering based on attribute
Look at the code for that element
% grep ‘element literallayout’ *.dsl
dbverb.dsl:(element literallayout
dbverb.dsl
(element literallayout
  (if (equal? (attribute-string "class") (normalize "monospaced"))
      ($verbatim-display$
       %indent-literallayout-lines%
       %number-literallayout-lines%)
      ($linespecific-display$
       %indent-literallayout-lines%
       %number-literallayout-lines%)))
Rendering based on attribute
Shamelessly ‘borrow’ the ideas
<style-sheet>
  <style-specification use="docbook">
    <style-specification-body>
<![ %output.html; [ ]]>                    <!-- HTML specific customisations -->
<![ %output.print; [ ]]>                   <!-- Print specific customisations -->
      <!-- Non-specific customisations -->
 (element emphasis
   (if (equal? (attribute-string “role") (normalize “bold"))
       ($bold-seq$)
       ($italic-seq$))
    </style-specification-body>
  </style-specification>
  <external-specification id="docbook" document=“parent-stylesheet">
</style-sheet>
A look in common/
common/ contains shared files
dbcommon.dsl
Shared variables
Shared functions
dbl1*.dsl
Language specific code
(e.g., ordering of author names)
dbl1*.ent
Entity definitions for language specific text
(“Chapter”, “Kapitel”, “Chapitre”, etc)
Supporting an extended DTD
Reasons to extend DocBook
Add environment specific elements
Tighten up content models
Add new common attributes
Stylesheets do not automatically understand new elements
Content will appear in red
See “(default …” in print/docbook.dsl and html/docbook.dsl
An extended DTD
<!ENTITY % docbook.org PUBLIC “-//OASIS//DTD DocBook V4.1//EN”>
%docbook.org;
<!ELEMENT HostID - - ((%cptr.char.mix;)+)>
<!ATTLIST HostID
                --
                Role: More specific information about this host ID.
                If not specified then the default is 'hostname'.
                --
                Role    (Hostname
                        |Domainname
                        |FQDN
                        |IPAddr
                        |IP6Addr
                        |Netmask
                        |MAC)      #IMPLIED
                %common.attrib;
>
Supporting the extension
<style-sheet>
  <style-specification use="docbook">
    <style-specification-body>
<![ %output.html; [                       <!-- HTML specific customisations -->
]]>
<![ %output.print; [                      <!-- Print specific customisations -->
]]>
      <!-- Non-specific customisations -->
      (element hostid ($mono-seq$))
    </style-specification-body>
  </style-specification>
  <external-specification id="docbook" document=“parent-stylesheet">
</style-sheet>
Supporting the extension
<style-sheet>
  <style-specification use="docbook">
    <style-specification-body>
<![ %output.html; [                       <!-- HTML specific customisations -->
      (element hostid ($mono-seq$)
]]>
<![ %output.print; [                      <!-- Print specific customisations -->
      (element hostid ($italic-seq$)
]]>
      <!-- Non-specific customisations -->
    </style-specification-body>
  </style-specification>
  <external-specification id="docbook" document=“parent-stylesheet">
</style-sheet>
Customising a customisation
A chain of stylesheets can be built up
Multi-lingual CiteRefEntry links
Q: Using <citerefentry> you can generate man page references of the form “ls(1)”, with markup like
<citerefentry>
  <refentrytitle>ls</refentrytitle>
  <manvolnum>1</manvolnum>
</citerefentry>
Man to HTML gateways exist.  How do you
Generate the HTML link?
Make sure that the link is for the correct language?
Allow this functionality to be turned on or off?
Step 1: Find citerefentry
dbverb.dsl
(element citerefentry
  (if %refentry-xref-italic%
    ($italic-seq$)
    ($char-seq$)))
dbrfntry.dsl
(element refentrytitle ($charseq$)
…
(element manvolnum
  (if %refentry-xref-manvolnum%
    (sosofo-append
      (literal “(“)
      (process-children)
      (literal “)”)
    (empty-sosofo)))
Step 2: Rewrite citerefentry in layer-2.dsl
<![ %output.html; [                       <!-- HTML specific customisations -->
      (define %refentry-xref-link% #f)
      (define $create-refentry-xref-link$)
        (literal “”)
      (element citerefentry
        (let ((href ($create-refentry-xref-link%)))
          (if %refentry-xref-link%
            (make element gi: “A”
                  attributes: (list (list “HREF” href))
              (if %refentry-xref-italic%
                ($italic-seq$)
                ($charseq$)))
            (if %refentry-xref-italic%
              ($italic-seq$)
              ($charseq$)))))
]]>
Step 3: Create layer-3.dsl
<!DOCTYPE style-sheet PUBLIC "-//James Clark//DTD DSSSL Style Sheet//EN" [
<!ENTITY % output.html    “IGNORE”>
<!ENTITY % output.print   “IGNORE”>
<!ENTITY parent-stylesheet SYSTEM “layer-2.dsl" CDATA DSSSL>
<style-sheet>
  <style-specification use="docbook">
    <style-specification-body>
    </style-specification-body>
  </style-specification>
  <external-specification id="docbook" document=“parent-stylesheet">
</style-sheet>
% jade –i output.html –c /path/to/catalog –d layer-3.dsl –t sgml file.sgml
Step 4: Turn on the linking
<!-- layer-3.dsl -->
<style-sheet>
  <style-specification use="docbook">
    <style-specification-body>
<![ %output.html; [                       <!-- HTML specific customisations -->
      (define %refentry-xref-link% #t)
]]>
<![ %output.print; [                      <!-- Print specific customisations -->
]]>
      <!-- Non-specific customisations -->
    </style-specification-body>
  </style-specification>
  <external-specification id="docbook" document=“parent-stylesheet">
</style-sheet>
Step 5: Create the link function
URL’s take the form
http://www.FreeBSD.org/cgi/man.cgi?query=refentrytitle&sektion=manvolnum
Code to implement this
<![ %output.html; [                       <!-- HTML specific customisations -->
      (define %refentry-xref-link% #t)
      (define ($create-refentry-xref-link$ #!optional (n (current-node)))
     (let ((r (select-elements (children n) (normalize “refentrytitle”)))
               (m (select-elements (children n) (normalize “manvolnum”))))
           (string-append http://www.FreeBSD.org/cgi/man.cgi?query=
             (data r) “&” “sektion=“ (data m))))
]]>
Step 6: Use the new layer-3.dsl
Now all you have to do is use the new
layer-3.dsl in your commands
% jade –i output.html –c /path/to/catalog –d layer-3.dsl –t sgml file.sgml
A German link function
URL’s take the form
http://www.de.FreeBSD.org/cgi/man.cgi?query=refentrytitle(manvolnum)
Code to implement this (german-layer-3.dsl)
<![ %output.html; [                       <!-- HTML specific customisations -->
      (define %refentry-xref-link% #t)
      (define ($create-refentry-xref-link$ #!optional (n (current-node)))
     (let ((r (select-elements (children n) (normalize “refentrytitle”)))
               (m (select-elements (children n) (normalize “manvolnum”))))
           (string-append http://www.de.FreeBSD.org/cgi/man.cgi?query=
             (data r) “(” (data m) “)”)))
]]>
% jade –i output.html –c /path/to/catalog –d german-layer-3.dsl –t sgml file.sgml
An extended link function
<citerefentry vendor=“xfree86”>
  <refentrytitle>xdm</refentrytitle>
  <manvolnum>1</manvolnum>
</citerefentry>
<![ %output.html; [                       <!-- HTML specific customisations -->
      (define %refentry-xref-link% #t)
      (define ($create-refentry-xref-link$ #!optional (n (current-node)))
         (let* ((r (select-elements (children n) (normalize "refentrytitle")))
                (m (select-elements (children n) (normalize "manvolnum")))
                (v (attribute-string (normalize "vendor") n))
                (u (string-append "http://www.FreeBSD.org/cgi/man.cgi?query="
                        (data r) "&" "sektion=" (data m))))
           (case v
             (("xfree86") (string-append u "&" "manpath=XFree86+4.0.2"))
             (("netbsd")  (string-append u "&" "manpath=NetBSD+1.5"))
             (else u))))
]]>
A sample infrastructure