File psgml-dsssl.el of Package psgml
;; psgml-dsssl.el --- create a skeleton DSSSL spec for an SGML document.
;; $Id: psgml-dsssl.el,v 1.2 1996/10/19 17:24:24 david Exp david $
;; Copyright (C) 1996 David Megginson. Free redistribution permitted.
;; USE AT YOUR OWN RISK!
;;
;; Author: David Megginson (dmeggins@microstar.com)
;;; Commentary:
;; Installation:
;;
;; This file requires Gnu Emacs 19.* or XEmacs, together with Lennart
;; Staflin's PSGML mode (tested with version 1a12).
;;
;; Install this file somewhere on your load path, byte-compile it, and
;; include the following in your .emacs or site-start.el file:
;;
;; (autoload 'sgml-dsssl-make-spec "psgml-dsssl" nil t)
;;
;; Now, whenever you are editing an SGML document with PSGML, you can
;; type
;;
;; M-x sgml-dsssl-make-spec
;;
;; to create a skeleton DSSSL style spec in a temporary buffer
;; "**DSSSL**" (overwriting any existing spec). You may save the
;; buffer to a file and edit it as you wish.
;;
;;
;; Operation:
;;
;; This package will generate an element construction rule for every
;; element type which could appear in the SGML document, whether it
;; actually appears or not -- it does so by starting with the element
;; type of the document's root element, then performing a depth-first
;; traversal of the DTD tree. Any element types which are not
;; reachable from the root will be excluded.
;;
;; The first instance of each element class in the DTD tree will
;; determine its context, and thus, its default flow-object class.
;; The contexts are as follow:
;;
;; 1) The root element of the document (default: simple-page-sequence).
;; 2) The element appears in mixed content or contains PCDATA content
;; (default: sequence).
;; 3) The element contains mixed content and appears in element content
;; (default: paragraph).
;; 4) The element contains only element content
;; (default: display-group).
;; 5) The element is EMPTY (default: sequence).
;;
;; These will work well with some DTDs, but the assumptions will fall
;; apart quickly for others, especially HTML (which allows mixed
;; content almost everywhere). You can change the default flow-object
;; classes for each of these using configuration variables, as you can
;; change the default document-type declaration at the top of the
;; specification.
;;
;;; Code:
(require 'psgml-parse)
(autoload 'sgml-map-element-types "psgml-info" nil t)
(autoload 'sgml-eltype-refrenced-elements "psgml-info" nil t)
;;
;; Global configuration variables -- change as appropriate.
;;
; Default to the style-sheet
; DTD from the jade distribution.
(defvar sgml-dsssl-prolog
"<!DOCTYPE style-sheet PUBLIC \"-//James Clark//DTD DSSSL Style Sheet//EN\">\n\n"
"Prolog for generated DSSSL scripts.")
(defvar sgml-dsssl-root-foc "simple-page-sequence"
"The default flow-object class for the root element type.")
(defvar sgml-dsssl-mixed-foc "paragraph"
"The default flow-object class for an element type with mixed content.")
(defvar sgml-dsssl-element-foc "display-group"
"The default flow-object class for an element type with element content.")
(defvar sgml-dsssl-data-foc "sequence"
"The default flow-object class for an element type with data content.")
(defvar sgml-dsssl-empty-foc "sequence"
"The default flow-object class for an element type with EMPTY content.")
;;;
;;; Generate a skeleton DSSSL spec.
;;;
(defun sgml-dsssl-make-spec ()
"Generate a skeleton DSSSL style spec for the SGML document in a buffer.
The output will always go into a buffer named \"**DSSSL**\"."
(interactive)
(sgml-need-dtd)
(let ((root (symbol-name (sgml-element-name (sgml-top-element))))
(max-lisp-eval-depth 10000)
(elements-seen ()))
(with-output-to-temp-buffer "**DSSSL**"
(princ sgml-dsssl-prolog)
(sgml-dsssl-make-rule (sgml-lookup-eltype root)))))
(defun sgml-dsssl-make-rule (eltype &optional parent-mixed)
"Generate an element-construction rule, then recurse to any children."
(let ((name (sgml-eltype-name eltype))
(foc
(cond ((equal elements-seen ())
sgml-dsssl-root-foc)
((or (equal (sgml-eltype-refrenced-elements eltype)
(list (intern "#PCDATA")))
parent-mixed)
sgml-dsssl-data-foc)
; ((sgml-eltype-mixed eltype)
; sgml-dsssl-mixed-foc)
((equal (sgml-eltype-refrenced-elements eltype) ())
sgml-dsssl-empty-foc)
(t sgml-dsssl-element-foc))))
(push name elements-seen)
; (princ ";; Contents: ")
; (mapc (function (lambda (child) (princ child) (princ " ")))
; (sgml-eltype-refrenced-elements eltype))
; (princ "\n")
(princ (format "(element %s\n (make %s\n (process-children)))\n\n"
(upcase name) foc)))
(mapcar (function
(lambda (el)
(if (and (not (memq (sgml-eltype-name el) elements-seen))
(not (string= (sgml-eltype-name el) "#PCDATA")))
(sgml-dsssl-make-rule el (sgml-eltype-mixed eltype)))))
(sgml-eltype-refrenced-elements eltype)))