Jade: making entities, preserving sdata, structure and examples of transformations -- an extended ramble

Subject: Jade: making entities, preserving sdata, structure and examples of transformations -- an extended ramble
From: Robin Stephenson <robin.stephenson@xxxxxxxxxxxxxxx>
Date: 29 Jun 1998 17:59:44 +0100
Keywords: Jade, DSSSL, transformation, entities, examples, sdata
First off, some problems with creating a new entity declaration.  At
the head of each SGML source file I have a couple of lines thus:

<!DOCTYPE article PUBLIC "-//BPG//DTD Blackwell Publishing Group 2.2//EN"
<!ENTITY fulltext SYSTEM "ijd00335.pdf" NDATA PDF>

I've got a transformation working (sort of), but I'm having trouble
copying the value of the entity across unmangled.  The source file
doesn't use the entity (not guilty), so I think Jade (understandably)
just drops it.  I do need to use it, however, so I try to reconstruct
it as follows:

(element article (sosofo-append
       (make document-type
	 name: "bhbheadr"
	 public-id: "-//BH Blackwell//DTD Header 1.01//EN")

       ;; literal entity broken into chunks so that the strings don't
       ;; get (mis)interpreted by Jade
       (literal "<")
       (literal "!ENTITY fulltext SYSTEM \"")
       ;; grab the value from the old entity
       (literal (entity-generated-system-id "fulltext"))
       (literal "\" NDATA PDF>")

       (make element
         gi: "bhbheadr"
         preserve-sdata?: #t
         attributes: (list
                      (list "dtdname" "bhbheadr.dtd")
                      (list "version" "1.01"))

This produces this output:

<!DOCTYPE bhbheadr PUBLIC "-//BH Blackwell//DTD Header 1.01//EN">
&#60;!ENTITY fulltext SYSTEM "&#60;OSFILE&#62;../sgml/ijd00259.pdf" NDATA PDF&#6

How can I stop Jade from expanding the angle brackets, etc?  I tried
using (make-formatting-instruction "<"), but Jade came up with
`content expression cannot be specified in make expression for atomic
flow object class "formatting-instruction"', so I stopped.

    ------------------------------  ------------------------------
On another, larger scale topic, I'm driving this translation from the
output, rather than the input, and would appreciate comments.  To
explain briefly: it seemed logical to start with the DTD of the end
point of the translation and work through it in order, seeing where I
could `flesh it out' from the input.  This means that I don't handle
tags individually: I start from the root and then delve about in the
parsed document and explicitly build the things I want:

;; NB this code has been annotated, and might not work with the
;; comments in it.


;; see above for (element article [...].  The <article> element is the
;; only one to be handled `automatically': everything else is done by
;; the bhb-body function below, and the functions it calls:

(define (bhb-body)
  (make element
    gi: "body"
    (make sequence
      ;; These functions call functions, which call functions... and
      ;; ultimately result in a sequence of sosofos: the output document.

;; Here's an example function that actually produces a sosofo:
(define (bhb-jalt)
  (let ((nl (select-named-elements "jalt")))
    (if (node-list-empty? nl)
        (make element
          gi: "jalt"
          (literal (data nl))))))

;; and here's the definition of select-named-element (£1 to 1p says
;; there's an easier way)
(define (select-named-elements name #!optional (nd (sgml-root-element)))
  (or (select-elements (descendants nd) name)

(define (sgml-root-element)
  (let loop ((root (current-node)))
    (if (node-list-empty? (parent root))
        (loop (parent root)))))

  This seems to produce some peculiar behaviour WRT handling of
entities (I want to set (preserve-sdata?: #t), but it doesn't have any 
effect currently), and I haven't seen anyone else doing this.  Am I
barking up completely the wrong tree?  Is this a nutcase's way of
doing SGML -> SGML translation?  I've thought about using modes, but I 
don't see that it's going to make my particular case any easier.
  Daniel Speck said (offline -- thanks, Daniel) that my sdata problems
are a result of not using the (process-children) mechanism for walking
the source tree: is this the only way to get what I want?  In other
words, do I have to rewrite my transformation to be driven by the
input, rather than the output?
  How about an alternative to the (literal (data nodelist)) thing --
something that doesn't do entity expansion?

    ------------------------------  ------------------------------
What would be really great would be an example SGML -> SGML
translation somewhere mid-way in complexity between
<http://www.groveware.com/~graydon/idiots.html> and the full-blown
`docbook' translation that makes my eyes roll back inside my head.
Does anyone know of such a beast?
  The case I'm working on at the moment is a translation between two
slightly differing DTDs -- move a few things about, collate some
information, provide some default values, etc.  It sounds like the
sort of thing that's been done before, but I can't find any examples.
It's nearly working, but I'd like to see how others have coped.  And,
as I said, there are still a couple of rough edges, notably the fact
I can't persuade Jade to leave my sdata alone.

 Robin Stephenson
 Serve Over Fish

 DSSSList info and archive:  http://www.mulberrytech.com/dsssl/dssslist

Current Thread