Is DSSSL Hard?

This is what I found in my test of DSSSL for a simple CSS-like
stylesheet. Stylesheets follow. It is a Internet Explorer cut and past
from http://itrc.uwaterloo.ca/~papresco/dsssl/hard.html . I find IE does
better cuts and pastes than does Netscape, but if you find funny things,
blame Tom et. al. =) I will refine my document according to criticisms
(or reports of typos) and also capture rebuttals (with permission) for


Is DSSSL Hard?

Many people, confronted with the large and intricate DSSSL standard come
to the conclusion that DSSSL is hard to learn. I fundamentally do not
believe that to be the case. Learning all of DSSSL is hard. Learning to
do hard things in DSSSL is hard. Using DSSSL for simple stylesheets is
as easy as using a declarative stylesheet language. To put this belief
to the test, I wrote a simple stylesheet that works for an HTML-like
language. This document sticks the subset of HTML handled by the
stylesheet. Todd Fahrner contributed a similar stylesheet in the
Cascading Style Sheet language, a representative declarative stylesheet
language, and a potential competitor to DSSSL for simple tasks. I
combined his stylesheet with a reference stylesheet from the CSS
specification to make something representative of standard CSS
stylesheets. Despite the fact that the DSSSL stylesheet is substantially
more complete, I do not believe it to be much more difficult to
understand or write than the CSS one. There are caveats, however, so
read on for the full story. 

The Truth About Flow Objects

Flow objects are the DSSSL term for the presentational objects that end
up in the output document. For instance paragraphs, characters,
sequences of characters and pages are all flow objects. CSS hides the
concept of flow objects, but they are implicit in the standard: the
display property controls the flow object. CSS has four flow objects,
"block", "inline", "list-item" and "none". Flow objects in DSSSL have
characteristics. In CSS these are called properties. My assertion is
that the only differences in ease of use between CSS and DSSSL are in
the lists of these flow objects and characteristics and not in the basic
stylesheet processing model or noation. 

In the vast majority of the rules, the difference between CSS and DSSSL
was quite trivial: 

H2 {
display: block
font-size: 133%;
margin-top: 1.5em;
margin-bottom: 1em;
font-weight: bold;


(element H2
    (make paragraph
	font-size: (* 1.3 (inherited-font-size))
	space-before: 1.5em
	space-after: 1em
	font-weight: 'bold))

The major differences were prefix notation vs. C-style notation and the
fact that the current version of DSSSL does not really support page
percentages as a built-in quantity unit. I could have defined one in 1
line of code, but I chose instead to stick to idiomatic DSSSL code so as
not to distract from the important issues of their processing and
stylesheet models. 

I think that there were a few cases in the code where CSS was simpler
because it had predefined flow objects or properties for things that had
to be "constructed" in DSSSL. 

The first example involves lists: 

  OL { list-style: decimal }
  LI { display: list-item
	margin-top: 1.5em
	margin-left: 3em }


(element (OL LI) 
    (make sequence
	start-indent: 3em
	space-before: 1.5em
            (literal (format-number (child-number) "1")) 

The CSS version is simpler, because it has a built-in list item flow
object. There is no good reason, however, that DSSSL-for-the-web (the
final product of the XML exercise) cannot have a list item flow object
that is exactly as easy to use as the CSS version. To show that this is
a trivial difference, it would be nice if I could show something that is
easy in DSSSL, using a built-in flow object, (like tables or images),
but difficult in CSS. It goes both ways. A missing flow object is a
hassle, but the set of flow objects available are mostly an arbitrary
set that can be expanded as needed in future versions of the standard. 

unfortunately CSS does not even allow anything outside of its hard-coded
options, so demonstrating something that is easy in DSSSL but hard in
CSS is impossible. CSS is "easy" precisely because anything the
slightest bit outside of what is provided is not possible. As an
example, in the DSSSL code above, I could change the numbering style
from "1" "2" "3" "4" to "1.", "2.", "3.", "4." with three extra
characters. This simple change is absolutely impossible in CSS. No
matter how much work I am willing to put in, I cannot get this simple

There were four other cases where CSS seemed slightly easier: 

1.There is no standard function in DSSSL for translating strings to
upper case and lower case. I think that uppercasing is stylistically
suspect, but the stylesheet I was working from did use this convention.
It only takes one line of code, but it is an intimidating line. Once the
line is written, you may copy it from stylesheet to stylesheet without
understanding it. Of course if this was one of the basic features that
CSS left out, rather than DSSSL, it would simply be impossible to do,
rather than difficult. Uppercasing can be provided in DSSSL-on-the-Web
through a function or (as in CSS) characteristic. 2.In DSSSL you must
declare what "color-space" you are using, as RGB has many known
limitations. This is also one line of code. The easy solution to this is
to have DSSSL-on-the-web predefine the RGB color space. 3.You may also
define units in DSSSL and I added "em" to the list of defined units for
ease of translation. This could also be predefined in DSSSL-on-the-web.
4.In DSSSL bullets are provided using Unicode characters. A list item
flow object as described above would have standard bullets built-in
which would save you from looking them up in Unicode. 

Even in current day ISO DSSSL, the difference between CSS and DSSSL in
all of these cases is that in DSSSL you would have to cut and paste
these declarations into the beginning of your stylesheet from one of the
many publically available stylesheets. 


I do not believe DSSSL is difficult, and a comparison with a simple
stylesheet language like CSS shows that things only become difficult in
DSSSL when you want to move beyond the predefined flow objects and
characteristics. Since this form of extension is impossible in CSS, this
cannot be fairly used as an argument that DSSSL is difficult. If you
restrict yourself to the hard-coded subset, you will find it exactly as
easy to use as CSS, but you will have a slightly different mix of
features (e.g. tables, and images but no automatic upper casing). I can
find nothing in the basic DSSSL stylesheet model or syntax to make it
harder than a purely declarative language like CSS. It can be used as a
declarative language until you need to step "outside the box." Of course
finding that declarative language inside of the DSSSL standard is a
challenge, so there is a large role for easy tutorials and summaries. 

Postscript on CSS

I believe that CSS and DSSSL are at the point of about equivalent
difficulty for doing simple things now, but will not be so in the
future. As CSS grows to incorporate these sorts of things, its
complexity will surpass that of DSSSL. Not catch up to, but surpass: the
basic decision to hide flow objects will make the organization of
properties extremely difficult. The interaction of properties seems to
me to be already a problem. What does it mean for a display: inline
element to have a margin-left property? What does it mean for an inline
element to have a list-style: property? In my opinion, these nonsensical
or questionable combinations will become unmanagable in the future. 

The interactions of various rules that affect a particular element also
seems problematic, even without introducing the author/reader problem.
CSS rules can be split into multiple sections, but the rules of which
sections will be called for which elements are complex: much more
difficult than those for DSSSL. I also think that conflicting
cumulatively applied rules will cause a maintenance headache in large
stylesheets: "Why is that blue? Oh! I didn't know I had another rule for
that down here." The sample stylesheet I was using had one such mistake. 

Extensions to CSS beyond its current level will only appeal to
professional Web publishers, the natural constituency for
DSSSL-for-the-Web. In my opinion, the effort of the W3C, vendor and user
community would be better spent improving the declarative subset of
DSSSL. Otherwise these professional publishers will face a stark
dichtomy: the "interactive", "java-script-enabled", "kewl" CSS or the
powerful, scalable, robust DSSSL. There is no good reason for this
dichtomy. CSS serves its purpose and did so before the DSSSL standard
was ready. It should be left a simple language that can appeal to
amateurs and occasional users. 

The Two Stylesheets

Note that the DSSSL stylesheet covers tables, images and paragraph
breaks. The CSS one cannot because CSS does not support these features.
The browser must recognize those elements and "do the right thing",
without help from the stylesheet. For a full stylesheet that covers all
of HTML, including the many advanced attributes, see Jon Bosak's
complete HTML Stylesheet. The DSSSL stylesheet is fairly idiomatic
print-DSSSL code. 


<!doctype style-sheet PUBLIC "-//James Clark//DTD DSSSL Style

;*** Some initial declarations ***

(define rgb (color-space "ISO/IEC 10179:1996//Color-Space Family::Device
RGB" ))

(define page-width 8.5in)	; these are just useful, not necessary
(define page-height 11in)
(define font-size 11pt ) 

(define-unit em font-size)      ; this is convenient

(define *disk-bullet* #\l)	; replace this with a Unicode character

; *** The actual rules *** 

(element BR (make paragraph-break))  

(element B (make sequence font-weight: 'bold))

(element STRONG (make sequence font-weight: 'extra-bold ))

(element I (make sequence font-posture: 'italic))
(element EM (make sequence font-posture: 'italic))
(element CITE (make sequence font-posture: 'italic))

(element VAR (make sequence use: mono-para))
(element TT (make sequence use: mono-para))
(element CODE (make sequence use: mono-para))
(element KBD (make sequence use: mono-para ))
(element SAMP (make sequence use: mono-para))

(element IMG
  (make external-graphic
	entity-system-id: (attribute-string "src")
	display?: #t
	space-before: 1em
	space-after: 1em ))

(element table
    (make table))

(element tr
    (make table-row))

(element td
    (make table-cell))

(element title

(element body
    (make simple-page-sequence
        page-width: page-width
        page-height: page-height
        left-margin: 1in
        right-margin: 1in
	top-margin: 1in
        font-family-name: "Times New Roman"
        font-size: font-size;
        line-spacing: 1.3em
	background-color: (color rgb 1 1 0.95)
	color: (color rgb 0 0 0)
        quadding: 'start))

(define (uppercase)
    (literal (list->string (map char-upcase (string->list (data

(define (lowercase)
    (literal (list->string (map char-downcase (string->list (data

(element H1 
    (make paragraph 
	font-size: (* 1.5 (inherited-font-size))
	space-before: 2.5em
	space-after: 1.5em
	escapement-space-after: 0.1em
	font-weight: 'bold
	(uppercase) ))

(element H2
    (make paragraph
	font-size: (* 1.3 (inherited-font-size))
	space-before: 1.5em
	space-after: 1em
	font-weight: 'bold))

(element H3 
    (make paragraph 
	font-size: (* 1.3 (inherited-font-size))
	space-before: 1em
	space-after: 0.25em
	font-weight: 'bold))

(element H4 
    (make paragraph
	font-size: (* 1.2 (inherited-font-size))
	space-before: 1em
	space-after: 0em
	font-weight: 'bold))

(element H5 
    (make paragraph
	space-before: 1em
	space-after: 0em
	font-weight: 'bold
	start-indent: (/ page-width 20)))

(element H6 
    (make paragraph
	space-before: 1em
	space-after: 0em
	font-weight: 'normal
	start-indent: (/ page-width 20)

(define mono-para 
    (style font-family-name: "Monospace"
	font-size: (* 1.2 (inherited-font-size))))

(element P
    (make paragraph))

(element (UL LI) 
    (make display-group
	first-line-start-indent: -1em
    	(make character char: *disk-bullet*)

(element (OL LI) 
    (make display-group
	start-indent: 0pt
            (literal (format-number (child-number) "1") ". ") 

(element (DIR LI)
    (make display-group
	start-indent: 0pt

(element MENU 
    (make paragraph))

(element DIV 
    (make paragraph))

(element DT 
    (make paragraph 
	font-weight: 'bold))

(element DD 
	(make paragraph start-indent: (/ page-width 20)))

(element ADDRESS (make paragraph))

(element BLOCKQUOTE 
    (make paragraph
	start-indent: (/ page-width 20)
	font-size: 0.7em
	line-spacing: 1.2em))

(element HR
    (make rule
	start-indent: 1em
	orientation: 'horizontal))

(element PRE 
    (make paragraph
	font-family-name: "Monospace"
	input-whitespace-treatment: 'preserve
	lines: 'asis))


margin: 1em;
font-family: serif;
line-height: 1.1;
margin-left: 16%;
margin-right: 4%;
margin-top: 8%;
line-height: 1.3em;
background: #FFFDF3;
color: black;
text-align: left;

H1, H2, H3, H4, H5, H6, P, UL, OL, DIR, MENU, DIV,
display: block;

display: inline;

LI { display: list-item; }

P {
text-indent: 4%;
margin-top: 0;
margin-bottom: 0;

/* this is for some measure of compatibility with table-based layouts */
margin-top: 0;
margin-bottom: 0;
margin-right: -4%;
margin-left: -16%;

H1 {
font-size: 167%;
margin-top: 2.5em;
margin-bottom: 1.5em;
letter-spacing: 0.1em;
font-weight: bold;
text-transform: uppercase;

H2 {
font-size: 133%;
margin-top: 1.5em;
margin-bottom: 1em;
font-weight: bold;

H3 {
font-size: 133%;
margin-top: 1em;
margin-bottom: 0.25em;
font-weight: bold;

H4 {
font-size: 125%;
margin-top: 1em;
margin-bottom: 0;
font-weight: bold;

H5 {
font-size: 100%;
margin-top: 1em;
margin-bottom: 0;
font-weight: bold;
text-indent: 4%;

H6 {
font-size: 100%;
margin-top: 1em;
margin-bottom: 0;
text-indent: 4%;
font-weight: normal;
text-transform: lowercase;

STRONG { font-weight: bolder; }

CITE, EM  { font-style: italic; }

margin-left: 4%;
font-size: 0.7em;
line-height: 1.2em;

font-family: monospace;
font-size: 120%;

margin-left: -16%;
font-family: monospace;
font-size: 120%;
white-space: pre;

margin-left: 24%;
margin-right: 16%;

list-style: disc
margin: 0;

OL {
list-style: decimal;
margin: 0;

MENU { margin: 0 }

LI { 
margin-top: 1.5em
margin: 0 

DT { 
margin: 0;
font-weight: bold;

DD { margin: 0 }

HR { border-top: solid } 

A { text-decoration: none }

A:link { color: red }

A:visited { color: #336666 }

A:active {
color: red;
background: #FFFF00;

A:link IMG { border: 1px solid red  }

A:visited IMG { border: 1px solid #336666 }

A:active IMG { border: 2px solid #FFFF00 }