7 Editing SGML Documents

The PSGML package for emacs provides a very nice editing environment for SGML documents. You might put the following in your ~/.emacs file:

(setq load-path (cons "PSGML_DIR" load-path))
(autoload 'sgml-mode "psgml" "Major mode to edit SGML files." t)

where PSGML_DIR is the directory in which PSGML is installed. At our lab, this directory is: /project/ps/emacs/lisp/psgml

To turn on fontification of SGML document, also add the following:

(setq sgml-set-face 't)

You may also specify what font faces to use for highlighting. Here is what I (Denys) am using today:

(setq sgml-markup-faces 
  '((start-tag . font-lock-reference-face)
    (end-tag   . font-lock-reference-face)
    (comment   . font-lock-comment-face  )
    (pi        . font-lock-keyword-face  )
    (sgml      . font-lock-type-face     )
    (doctype   . font-lock-type-face     )
    (entity    . font-lock-keyword-face  )
    (shortref  . font-lock-reference-face)))

Strangely enough, when you open an SGML file for editing, the fontification process always waits for 6 seconds of idleness before it actually gets going. This is annoying, but hard coded.

For each document, psgml-mode parses the DTD and uses this information to help editing (it knows what is legal, where). Normally it uses the <!DOCTYPE ...> declaration at the top of the document to find theDTD. There are 2 common cases where that doesn't work well: when the DTD is in a location that PSGML cannot find and when editing part of a document in a separate file that doesn't have the DOCTYPE declaration.

In such cases it is easier to load a ``parsed DTD''; it is also much faster. The easiest way to save a parsed DTD is to create, in the directory where the DTD is located, a file containing the following line:

<!DOCTYPE ELEM SYSTEM "DTD">

and to invoke ``Parse DTD'' and then ``Save Parsed DTD'' from the DTD menu. Then, when editing a partial document, you can manually invoke ``Load Parsed DTD'' from that same menu.

fill-mode is also nice to get automatic line breaking, but, in my experience, it is better to turn adaptive-fill-mode off, otherwise, due to the indentation of nested element, you'll soon be writing in a very narrow column at the right of the page. For example, you might add the following code at the end of and SGML document:

<!--
Local Variables:
mode: sgml
mode: auto-fill
adaptive-fill-mode: nil
End:
-->

as far as SGML is concerned, this is a comment, but is meaningful to emacs.


Denys Duchier
Version 1.4.0 (20080702)