## 7 Document Type Declaration ¶

PSGML needs to know about the DTD you are using for many of its commands. If you do not have a ‘`DOCTYPE`’ declaration in your file, PSGML will try assume that there is one of the form

    <!DOCTYPE name SYSTEM>

where name is the value of `sgml-default-doctype-name`, if the value is non-`nil`, else the GI of the first tag will be used.

PSGML will try to parse the document type declaration the first time you do something that needs to parse the document or immediately if the variable `sgml-auto-activate-dtd` is `t`. You can also initiate the parsing of the document type declaration with the command `sgml-parse-prolog`. Big DTDs take some time to parse.

When the DTD has been parsed or loaded the name of the document element will be displayed in the mode line inside brackets. If there was an error parsing the DTD or there is no DTD, the mode line will display ‘`[ANY]`’ (*** this is not really correct! a DTD will be established even if there are missing entities, it may even be empty).

### 7.1 Precompiled DTD Subsets ¶

If parsing the DTD takes too long time you can arrange to have PSGML cache an internal complied version of the DTD. Caching can be done of DTD fragments in favourable situations. It is possible to have an external DTD subset cached but still have an internal DTD subset as long as the internal subset does not define parameter entities that affect the parsing of the external subset (*** what is the exact conditions?, probably you can’t use the cached external subset if the internal subset defines parameter entities that are also defined in the external subset with another value).

To enable caching you have to create special catalog files, hereafter called ECAT files due to (temporary) lack of imagination. These catalogs have similar syntax to the entity catalogs and there are two variables containing lists of catalogs to search: `sgml-ecat-files` and `sgml-local-ecat-files`. The ECAT files can contain the following types of entries:

‘`file dtdfile entitydef cfile`’

  The dtdfile is the name of a file containing a DTD subset that should be cached in cfile. The entitydef is optional and if given have the following syntax:

      [ name1 literal1 name2 literal2 ... ]

  Using entitydef will modify the DTD subset by defining the parameter entity with name name1 to be literal1, …. The cached version of the subset will be created with those entity definitions, and when PSGML search for a matching cached subset will check that the parameter entities in entitydef has been defined with those values before trying to use `cfile`.

‘`public pubid entitydef cfile`’

  Cache the DTD subset with public identifier pubid in file cfile.

User Option: sgml-recompile-out-of-date-cdtd ¶

  If non-`nil`, out of date compiled DTDs will be automatically recompiled. If the value is `ask`, PSGML will ask before recompiling. A `nil` value will cause PSGML to silently load an out of date compiled DTD. A DTD that refers to undefined external entities is always out of date, thus in such case it can be useful to set this variable to `nil`.

Previous versions of PSGML have had another way of speeding up DTD parsing. This code remains in this version of PSGML, but is not actively maintained and may disappear in the future.

You can save the parsed DTD in a file using the command `M-x sgml-save-dtd`. Next time PSGML can load that file instead of parsing the DTD. For PSGML to find the saved DTD you must either save the DTD using the default name or do a `M-x sgml-save-options` after saving the DTD. To directly use an already parsed and saved DTD, load the file containing the saved DTD with the command `M-x sgml-load-dtd`.

User Option: sgml-default-dtd-file ¶

  This is the default file name for saved DTD. This is set by `sgml-mode` to the buffer file name less extension plus the extension `.ced`, if that file exists. Can be changed in the Local variables section of the file.

### 7.2 Using a Split Document ¶

You can have the ‘`DOCTYPE`’ declaration in another file by setting `sgml-doctype` to the other file.

User Option: sgml-parent-document ¶

  Used when the current file is part of a bigger document.

  The variable describes how the current file’s content fit into the element hierarchy. The variable should have the form

      (parent-file context-element* top-element (has-seen-element*)?)

  parent-file

    is a string, the name of the file containing the document entity.

  context-element

    is a string, that is the name of an element type. It can occur 0 or more times and is used to set up exceptions and short reference map. Good candidates for these elements are the elements open when the entity pointing to the current file is used.

  top-element

    is a string that is the name of the element type of the top level element in the current file. The file should contain one instance of this element, unless the last (lisp) element of sgml-parent-document is a list. If it is a list, the top level of the file should follow the content model of top-element.

  has-seen-element

    is a string that is the name of an element type. This element is satisfied in the content model of top-element.

### 7.3 Inserting a DOCTYPE ¶

*** Describe the DTD menu in general. Describe customized entries for special DTDs. Mention `C-c C-u C-d` for inserting a DOCTYPE from keyboard.

If you change the doctype you must execute `sgml-parse-prolog`, changes in the doctype are not automatically recognized.

User Option: sgml-custom-dtd ¶

  Menu entries to be added to the DTD menu. The value should be a list of entries to be added to the DTD menu.

  Every entry should be a list. The first element of the entry is a string used as the menu entry. The second element is a string containing a doctype declaration (this can be nil if no doctype). The rest of the list should be a list of variables and values. For backward compatibility a single string instead of a variable is assigned to `sgml-default-dtd-file`. All variables are made buffer local and are also added to the buffers local variables list.

  When an entry is selected from the DTD menu, the doctype declaration will be inserted, the variables will be set to the values in the entry and a local variables list will be created in the buffer.

  Example:

         (("HTML" nil
           sgml-default-dtd-file "~/sgml/html.ced"
           sgml-omittag nil sgml-shorttag nil)
          ("HTML+" "<!doctype htmlplus system 'htmlplus.dtd'>"
           "~/sgml/htmlplus.ced"
           sgml-omittag t sgml-shorttag nil)
          ("DOCBOOK" "<!doctype docbook system 'docbook.dtd'>"
           "~/sgml/docbook.ced"
           sgml-omittag nil sgml-shorttag t)))

### 7.4 Information from the DTD ¶

PSGML can list various information about the current DTD. The following commands can be used via `M-x` and can also be found in the DTD menu.

`sgml-describe-dtd` ¶

  Display information about the current DTD.

`sgml-describe-element-type` ¶

  Describe the properties of an element type as declared in the current DTD.

`sgml-describe-entity` ¶

  Describe the properties of an entity as declared in the current DTD.

`sgml-list-elements` ¶

  Will list all elements and the attributes declared for the element.

`sgml-list-attributes` ¶

  Will list all attributes declared and the elements that use them.

`sgml-list-terminals` ¶

  Will list all elements that can contain data.

`sgml-list-occur-in-elements` ¶

  Will list all element types and where it can occur.

`sgml-list-content-elements` ¶

  Will list all element types and the element types that can occur in its content.

### 7.5 Customizing DTD ¶

PSGML can be customized by process instructions starting with “PSGML” in the DTD. Generally this associates some information with element types. E.g., if `sgml-fill-element` should skip the element type or if the content should be displayed with a special font.

The general syntax is

    ‘<?PSGML ELEMENT’ gi (prop = value)* ‘>’

Note: in XML the ending delimiter is ‘`?>`’, in SGML mode a trailing ‘`?`’ will be ignored if preceded by a space.

Where gi is the element type, prop is a propery described below, and value is the value for the property. The first part from ‘`PSGML`’ to gi is read with current setting for ‘`NAMECASE GENERAL`’, i.e., case insensitive for normal SGML but case sensitive in XML mode. The prop and value is read using Emacs Lisp conventions, i.e. case sensitive and value is a lisp expression (not evaluated).

Example

    <?PSGML ELEMENT PRE nofill=t face=fixed-pitch>

Properties

`nofill`

  Set to either `t` or `nil`. If `t` the elements of this type will be ignored when filling with `sgml-fill-element`. Note that Emacs normal filling functions will not honor this.

`font`

  Set to the name of an Emacs face. Should be a face that exists in Emacs. E.g. `bold`, `italic`, `fixed-pitch`. The content of elements of this type will be displayed in that face.

`attnames`

  Set to a list of attribute names. E.g., `attnames=("ID" "CLASS" "ONCLICK")`. This controls the attributes included when using the `sgml-edit-attributes` (`C-c C-a`) command. Only the attributes in the list will be included and in that order. You can also end the list with a `*` to include all attributes, but the listed attributes will be on the top. E.g., `attnames=("ID" "CLASS" "ONCLICK" *)`. Note: that the attribute names need to be written with the correct case and in string quotes.

`structure`

  Control if element is included in `sgml-show-structure` (`C-c C-s`). If set to `t`, the element is included and if set to `ignore` it will not be included. See Showing information.

`help-text`

  Should be a string. The string will be displayed by `sgml-show-current-element-type` (`C-c C-t`).