440 likes | 560 Views
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.
E N D
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> </style-specification-body> </style-specification> <external-specification id="docbook" document=“parent-stylesheet"> </style-sheet> (define %generate-article-toc% #t) % 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 Further Customisation layer-3.dsl New functions And variables layer-2.dsl / custom.dsl nwalsh stylesheets html.dsl / print.dsl
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 % cd doc/en_US.ISO_8859-1/books/faq % make “FORMATS=html ps pdf”