Mercurial > hg > xemacs-beta
diff lisp/psgml/psgml.el @ 0:376386a54a3c r19-14
Import from CVS: tag r19-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:45:50 +0200 |
parents | |
children | ac2d302a0011 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lisp/psgml/psgml.el Mon Aug 13 08:45:50 2007 +0200 @@ -0,0 +1,1302 @@ +;;; psgml.el --- SGML-editing mode with parsing support +;; $Id: psgml.el,v 1.1.1.1 1996/12/18 03:35:23 steve Exp $ + +;; Copyright (C) 1993, 1994, 1995 Lennart Staflin +;; Copyright (C) 1992 Free Software Foundation, Inc. + +;; Author: Lennart Staflin <lenst@lysator.liu.se> +;; James Clark <jjc@clark.com> + +;; +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License +;; as published by the Free Software Foundation; either version 2 +;; of the License, or (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; if not, write to the Free Software +;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +;;; Commentary: + +;; Major mode for editing the SGML document-markup language. + +;; Send bugs to lenst@lysator.liu.se + +;; WHAT IT CAN DO + +;; - Identify structural errors (but it is not a validator) +;; - Menus for inserting tags with only the contextually valid tags +;; - Edit attribute values in separate window with information about types +;; and defaults +;; - Hide attributes +;; - Fold elements +;; - Indent according to element nesting depth +;; - Show context +;; - Structure editing: move and kill by element +;; - Find next data context + +;; LIMITATIONS + +;; - only accepts the referece concrete syntax, though it does allow +;; unlimited lengths on names + + +;;; Code: + +(defconst psgml-version "1.0a9" + "Version of psgml package.") + +(defconst psgml-maintainer-address "lenst@lysator.liu.se") + +(require 'cl) + +(defvar sgml-debug nil) + +(defmacro sgml-debug (&rest x) + (list 'if 'sgml-debug (cons 'sgml-log-message x))) + + +;;;; Variables + +(defvar sgml-mode-abbrev-table nil + "Abbrev table in use in sgml-mode.") +(define-abbrev-table 'sgml-mode-abbrev-table ()) + +(defvar sgml-mode-syntax-table nil + "Syntax table used in sgml mode.") + +(if sgml-mode-syntax-table + () + (setq sgml-mode-syntax-table (make-syntax-table)) + (modify-syntax-entry ?< "(>" sgml-mode-syntax-table) + (modify-syntax-entry ?> ")<" sgml-mode-syntax-table) + (modify-syntax-entry ?\" ". " sgml-mode-syntax-table) + (modify-syntax-entry ?\\ ". " sgml-mode-syntax-table) + (modify-syntax-entry ?' "w " sgml-mode-syntax-table)) + +(defvar sgml-running-xemacs + (not (not (string-match "Lucid\\|XEmacs" emacs-version)))) + +;;; User settable options: + +(defvar sgml-insert-missing-element-comment t + "*If true, and sgml-auto-insert-required-elements also true, +`sgml-insert-element' will insert a comment if there is an element required +but there is more than one to choose from." ) + +(defvar sgml-insert-end-tag-on-new-line nil + "*If true, `sgml-insert-element' will put the end-tag on a new line +after the start-tag. Useful on slow terminals if you find the end-tag after +the cursor irritating." ) + +(defvar sgml-doctype nil + "*If set, this should be the name of a file that contains the doctype +declaration to use. +Setting this variable automatically makes it local to the current buffer.") +(put 'sgml-doctype 'sgml-type 'string) +(make-variable-buffer-local 'sgml-doctype) + +(defvar sgml-system-identifiers-are-preferred nil + "*If nil, PSGML will look up external entities by searching the catalogs +in `sgml-local-catalogs' and `sgml-catalog-files' and only if the +entity is not found in the catalogs will a given system identifer be +used. If the variable is non-nil and a system identifer is given, the +system identifier will be used for the entity. If no system identifier +is given the catalogs will searched.") + +(defvar sgml-range-indicator-max-length 9 + "*Maximum number of characters used from the first and last entry +of a submenu to indicate the range of that menu.") + +(defvar sgml-default-doctype-name nil + "*Document type name to use if no document type declaration is present.") +(put 'sgml-default-doctype-name 'sgml-type 'string-or-nil) + +(defvar sgml-markup-faces '((start-tag . bold) + (end-tag . bold) + (comment . italic) + (pi . bold) + (sgml . bold) + (doctype . bold) + (entity . bold-italic) + (shortref . bold)) + "*List of markup to face mappings. +Element are of the form (MARKUP-TYPE . FACE). +Possible values for MARKUP-TYPE is: +comment - comment declaration +doctype - doctype declaration +end-tag +ignored - ignored marked section +ms-end - marked section start, if not ignored +ms-start- marked section end, if not ignored +pi - processing instruction +sgml - SGML declaration +start-tag +entity - general entity reference +shortref- short reference") + +(defvar sgml-buggy-subst-char-in-region + (or (not (boundp 'emacs-minor-version)) + (not (natnump emacs-minor-version)) + (< emacs-minor-version 23)) + "*If non-nil, work around a bug in subst-char-in-region. +The bug sets the buffer modified. If this is set, folding commands +will be slower.") + +(defvar sgml-set-face nil + "*If non-nil, psgml will set the face of parsed markup.") +(put 'sgml-set-face 'sgml-desc "Set face of parsed markup") + +(defvar sgml-live-element-indicator nil + "*If non-nil, indicate current element in mode line.") + +(defvar sgml-auto-activate-dtd nil + "*If non-nil, loading a sgml-file will automatically try to activate its DTD. +Activation means either to parse the document type declaration or to +load a previously saved parsed DTD. The name of the activated DTD +will be shown in the mode line.") +(put 'sgml-auto-activate-dtd 'sgml-desc "Auto Activate DTD") + +(defvar sgml-offer-save t + "*If non-nil, ask about saving modified buffers before \\[sgml-validate] is run.") + +(defvar sgml-parent-document nil + "* 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 contatining 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. + +Setting this variable automatically makes it local to the current buffer.") +(make-variable-buffer-local 'sgml-parent-document) +(put 'sgml-parent-document 'sgml-type 'list) + +(defvar sgml-tag-region-if-active t ;; wing change + "*If non-nil, the Tags menu will tag a region if the region is +considered active by Emacs. If nil, region must be active and +transient-mark-mode/zmacs-regions must be on for the region to be tagged.") + +(defvar sgml-normalize-trims t + "*If non-nil, sgml-normalize will trim off white space from end of element +when adding end tag.") + +(defvar sgml-omittag t + "*Set to non-nil, if you use OMITTAG YES. + +Setting this variable automatically makes it local to the current buffer.") + +(make-variable-buffer-local 'sgml-omittag) +(put 'sgml-omittag 'sgml-desc "OMITTAG") + +(defvar sgml-shorttag t + "*Set to non-nil, if you use SHORTTAG YES. + +Setting this variable automatically makes it local to the current buffer.") + +(make-variable-buffer-local 'sgml-shorttag) +(put 'sgml-shorttag 'sgml-desc "SHORTTAG") + +(defvar sgml-minimize-attributes nil + "*Determines minimization of attributes inserted by edit-attributes. +Actually two things are done +1. If non-nil, omit attribute name, if attribute value is from a token group. +2. If 'max, omit attributes with default value. + +Setting this variable automatically makes it local to the current buffer.") + +(make-variable-buffer-local 'sgml-minimize-attributes) +(put 'sgml-minimize-attributes 'sgml-type + '(("No" . nil) ("Yes" . t) ("Max" . max))) + +(defvar sgml-always-quote-attributes t + "*If non-nil, quote all attribute values inserted after finishing edit attributes. +Setting this variable automatically makes it local to the current buffer.") + +(make-variable-buffer-local 'sgml-always-quote-attributes) + +(defvar sgml-auto-insert-required-elements t + "*If non-nil, automatically insert required elements in the content +of an inserted element.") + +(defvar sgml-balanced-tag-edit t + "*If non-nil, always insert start-end tag pairs.") + +(defvar sgml-omittag-transparent (not sgml-balanced-tag-edit) + "*If non-nil, will show legal tags inside elements with omittable start tags +and legal tags beyond omittable end tags.") + +(defvar sgml-leave-point-after-insert nil + "*If non-nil, the point will remain after inserted tag(s). +If nil, the point will be placed before the inserted tag(s).") + +(defvar sgml-warn-about-undefined-elements t + "*If non-nil, print a warning when a tag for an undefined element is found.") + +(defvar sgml-warn-about-undefined-entities t + "*If non-nil, print a warning when an undefined entity is found.") + +(defvar sgml-ignore-undefined-elements nil + "*If non-nil, recover from an undefined element by ignoring the tag. +If nil, recover from an undefined element by assuming it can occur any +where and has content model ANY.") + +(defvar sgml-recompile-out-of-date-cdtd 'ask + "*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 referes to undefined external entities is always out of +date, thus in such case it can be useful to set this variable to +`nil'.") +(put 'sgml-recompile-out-of-date-cdtd 'sgml-type '(("No" . nil) + ("Yes" . t) + ("Ask" . ask))) + +(defvar sgml-indent-step 2 + "*How much to increment indent for every element level. +If nil, no indentation. +Setting this variable automatically makes it local to the current buffer.") +(make-variable-buffer-local 'sgml-indent-step) +(put 'sgml-indent-step 'sgml-type '(("None" . nil) 0 1 2 3 4 5 6 7 8)) + +(defvar sgml-indent-data nil + "*If non-nil, indent in data/mixed context also. +Setting this variable automatically makes it local to the current buffer.") +(make-variable-buffer-local 'sgml-indent-data) + +(defvar sgml-inhibit-indent-tags nil + "*List of tags within which indentation is inhibited. +The tags should be given as strings.") + +(defvar sgml-data-directory (expand-file-name "sgml" data-directory) + "*Directory for pre-supplied data files (DTD's and such). +Set this before loading psgml.") + +(defvar sgml-system-path nil + "*List of directories used to look for system identifiers. +The directory listed in `sgml-data-directory' is always searched in +addition to the directories listed here.") +(put 'sgml-system-path 'sgml-type 'list) + +(defun sgml-parse-colon-path (cd-path) + "Explode a colon-separated list of paths into a string list." + (let (cd-prefix cd-list (cd-start 0) cd-colon) + (setq cd-path (concat cd-path ":")) + (while (setq cd-colon (string-match ":" cd-path cd-start)) + (setq cd-list + (nconc cd-list + (list (if (= cd-start cd-colon) + nil + (substitute-in-file-name + (substring cd-path cd-start cd-colon)))))) + (setq cd-start (+ cd-colon 1))) + cd-list)) + +(defvar sgml-public-map (sgml-parse-colon-path + (or (getenv "SGML_PATH") + (concat "%S:" (directory-file-name + sgml-data-directory) + "%o/%c/%d"))) + + "*Mapping from public identifiers to file names. +This is a list of possible file names. To find the file for a public +identifier the elements of the list are used one at the time from the +beginning. If the element is a string a file name is constructed from +the string by substitution of the whole public identifier for %P, +owner for %O, public text class for %C, and public text description +for %D. The text class will be converted to lower case and the owner +and description will be transliterated according to the variable +sgml-public-transliterations. If the file exists it will be the file +used for the public identifier. An element can also be a dotted pair +(regexp . filename), the filename is a string treated as above, but +only if the regular expression, regexp, matches the public +identifier.") +(put 'sgml-public-map 'sgml-type 'list) + +(defvar sgml-local-catalogs nil +"*A list of SGML entity catalogs to be searched first when parsing the buffer. +This is used in addtion to `sgml-catalog-files', and `sgml-public-map'. +This variable is automatically local to the buffer.") +(make-variable-buffer-local 'sgml-local-catalogs) +(put 'sgml-local-catalogs 'sgml-type 'list) + +(defvar sgml-catalog-files (sgml-parse-colon-path + (or (getenv "SGML_CATALOG_FILES") + (concat "CATALOG:" + (expand-file-name + "CATALOG" + sgml-data-directory)))) + "*List of catalog entry files. +The files are in the format defined in the SGML Open Draft Technical +Resolution on Entity Management.") +(put 'sgml-catalog-files 'sgml-type 'list) + +(defvar sgml-ecat-files (list + "ECAT" + "~/sgml/ECAT" + (expand-file-name "ECAT" sgml-data-directory)) + "*List of catalog files for PSGML.") +(put 'sgml-ecat-files 'sgml-type 'list) + +(defvar sgml-local-ecat-files nil + "*List of local catalog files for PSGML. +Automatically becomes buffer local if set.") + +(make-variable-buffer-local 'sgml-local-ecat-files) +(put 'sgml-local-ecat-files 'sgml-type 'list) + +(defvar sgml-public-transliterations '((? . ?_) (?/ . ?%)) + "*Transliteration for characters that should be avoided in file names. +This is a list of dotted pairs (FROM . TO); where FROM is the the +character to be translated to TO. This is used when parts of a public +identifier are used to construct a file name.") + +(defvar sgml-default-dtd-file nil + "*This is the default file name for saved DTD. +This is set by sgml-mode from the buffer file name. +Can be changed in the Local variables section of the file.") +(put 'sgml-default-dtd-file 'sgml-type 'string) +(put 'sgml-default-dtd-file 'sgml-desc "Default (saved) DTD File") + +(defvar sgml-exposed-tags '() + "*The list of tag names that remain visible, despite \\[sgml-hide-tags]. +Each name is a lowercase string, and start-tags and end-tags must be +listed individually. + +`sgml-exposed-tags' is local to each buffer in which it has been set; +use `setq-default' to set it to a value that is shared among buffers.") +(make-variable-buffer-local 'sgml-exposed-tags) +(put 'sgml-exposed-tags 'sgml-type 'list) + + +(defvar sgml-custom-markup nil + "*Menu entries to be added to the Markup menu. +The value should be a list of lists of two strings. The first is a +string is the menu line and the second string is the text inserted +when the menu item is chosen. The second string can contain a \\r +where the cursor should be left. Also if a selection is made +according the same rules as for the Tags menu, the selection is +replaced with the second string and \\r is replaced with the +selection. + +Example: + + ((\"Version1\" \"<![%Version1[\\r]]>\") + (\"New page\" \"<?NewPage>\")) +") + +(defvar sgml-custom-dtd nil + "Menu entries to be added to the DTD menu. +The value should be a list of entrys 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 singel 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. + +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))) +") + + +;;; Faces used in edit attribute buffer: +(put 'sgml-default 'face 'underline) ; Face for #DEFAULT +(put 'sgml-fixed 'face 'underline) ; Face of #FIXED "..." + + +;;; sgmls is a free SGML parser available from +;;; ftp.uu.net:pub/text-processing/sgml +;;; Its error messages can be parsed by next-error. +;;; The -s option suppresses output. + +(defvar sgml-validate-command "sgmls -s %s %s" + "*The shell command to validate an SGML document. + +This is a `format' control string that by default should contain two +`%s' conversion specifications: the first will be replaced by the +value of `sgml-declaration' \(or the empty string, if nil\); the +second will be replaced by the current buffer's file name \(or the +empty string, if nil\). + +If `sgml-validate-files' is non-nil, the format string should contain +one `%s' conversion specification for each element of its result. + +If sgml-validate-command is a list, then every element should be a +string. The strings will be tried in order and %-sequences in the +string will be replaced according to the list below, if the string contains +%-sequences with no replacement value the next string will be tried. + +%b means the visited file of the current buffer +%s means the SGML declaration specified in the sgml-declaration variable +%d means the file containing the DOCTYPE declaration, if not in the buffer +") + +(defvar sgml-validate-files nil + "If non-nil, a function of no arguments that returns a list of file names. +These file names will serve as the arguments to the `sgml-validate-command' +format control string instead of the defaults.") + +(defvar sgml-validate-error-regexps + '(("\\(error\\|warning\\) at \\([^,]+\\), line \\([0-9]+\\)" 2 3) + ("^\\(.+\\):\\([0-9]+\\):\\([0-9]+\\):E: " 1 2 3)) + "Alist of regexps to recognize error messages from `sgml-validate'. +See `compilation-error-regexp-alist'.") + +(defvar sgml-declaration nil + "*If non-nil, this is the name of the SGML declaration file.") +(put 'sgml-declaration 'sgml-type 'string) + +(defvar sgml-mode-hook nil + "A hook or list of hooks to be run when entering sgml-mode") + +(defconst sgml-file-options + '( + sgml-omittag + sgml-shorttag + sgml-minimize-attributes + sgml-always-quote-attributes + sgml-indent-step + sgml-indent-data + sgml-doctype + sgml-parent-document + sgml-default-dtd-file + sgml-exposed-tags + sgml-local-catalogs + sgml-local-ecat-files + ) + "Options for the current file, can be saved or set from menu." + ) + +(defconst sgml-user-options + '( + sgml-set-face + sgml-live-element-indicator + sgml-auto-activate-dtd + sgml-offer-save + sgml-tag-region-if-active + sgml-normalize-trims + sgml-auto-insert-required-elements + sgml-balanced-tag-edit + sgml-omittag-transparent + sgml-leave-point-after-insert + sgml-warn-about-undefined-elements + sgml-warn-about-undefined-entities + sgml-ignore-undefined-elements + sgml-recompile-out-of-date-cdtd + sgml-default-doctype-name + sgml-declaration + sgml-validate-command + sgml-markup-faces + sgml-system-identifiers-are-preferred + sgml-system-path + sgml-public-map + sgml-catalog-files + sgml-ecat-files + ) + "User options that can be saved or set from menu." + ) + +;;; Internal variables + +(defvar sgml-validate-command-history nil + "The minibuffer history list for `sgml-validate''s COMMAND argument.") + +(defvar sgml-mode-map nil "Keymap for SGML mode") + +(defvar sgml-active-dtd-indicator nil + "Displayed in the mode line") + + +;;;; User options handling + +(defun sgml-variable-description (var) + (or (get var 'sgml-desc) + (let ((desc (symbol-name var))) + (if (string= "sgml-" (substring desc 0 5)) + (setq desc (substring desc 5))) + (loop for c across-ref desc + do (if (eq c ?-) (setf c ? ))) + (capitalize desc)))) + +(defun sgml-variable-type (var) + (or (get var 'sgml-type) + (if (memq (symbol-value var) '(t nil)) + 'toggle))) + +(defun sgml-set-local-variable (var val) + "Set the value of variable VAR to VAL in buffer and local variables list." + (set (make-local-variable var) val) + (save-excursion + (let ((prefix "") + (suffix "") + (case-fold-search t)) + (goto-char (max (point-min) (- (point-max) 3000))) + (cond ((search-forward "Local Variables:" nil t) + (setq suffix (buffer-substring (point) + (save-excursion (end-of-line 1) + (point)))) + (setq prefix + (buffer-substring (save-excursion (beginning-of-line 1) + (point)) + (match-beginning 0)))) + (t + (goto-char (point-max)) + (unless (bolp) + (insert ?\n)) + (insert + "<!-- Keep this comment at the end of the file\n" + "Local variables:\n" + "mode: sgml\n" + "End:\n" + "-->\n") + (forward-line -3))) + (let* ((endpos (save-excursion + (search-forward (format "\n%send:" prefix)))) + (varpos (search-forward (format "\n%s%s:" prefix var) endpos t))) + (cond (varpos + (delete-region (point) + (save-excursion (end-of-line 1) + (point))) + (insert (format "%S" val) suffix)) + (t + (goto-char endpos) + (beginning-of-line 1) + (insert prefix (format "%s:%S" var val) suffix ?\n))))))) + +(defun sgml-valid-option (var) + (let ((type (sgml-variable-type var)) + (val (symbol-value var))) + (cond ((eq 'string type) + (stringp val)) + ((eq 'list-or-string type) + (or (stringp val) + (consp val))) + (t + t)))) + +(defun sgml-save-options () + "Save user options for sgml-mode that have buffer local values." + (interactive) + (let ((l sgml-file-options)) + (loop for var in sgml-file-options do + (when (sgml-valid-option var) + (sgml-set-local-variable var (symbol-value var)))))) + + +;;;; Run hook with args + +(unless (fboundp 'run-hook-with-args) + (defun run-hook-with-args (hook &rest args) + "Run HOOK with the specified arguments ARGS. +HOOK should be a symbol, a hook variable. If HOOK has a non-nil +value, that value may be a function or a list of functions to be +called to run the hook. If the value is a function, it is called with +the given arguments and its return value is returned. If it is a list +of functions, those functions are called, in order, +with the given arguments ARGS. +It is best not to depend on the value return by `run-hook-with-args', +as that may change." + (and (boundp hook) + (symbol-value hook) + (let ((value (symbol-value hook))) + (if (and (listp value) (not (eq (car value) 'lambda))) + (mapcar '(lambda (foo) (apply foo args)) + value) + (apply value args)))))) + + + + +;;;; SGML mode: template functions + +(defun sgml-markup (entry text) + (cons entry + (` (lambda () + (interactive) + (sgml-insert-markup (, text)))))) + +(defun sgml-insert-markup (text) + (let ((end (sgml-mouse-region)) + before after + old-text) + (when end + (setq old-text (buffer-substring (point) end)) + (delete-region (point) end)) + (setq before (point)) + (if (stringp text) + (insert text) + (eval text)) + (setq after (point)) + (goto-char before) + (when (search-forward "\r" after t) + (delete-char -1)) + (when old-text (insert old-text)))) + +(defun sgml-mouse-region () + (let (start end) + (cond + (sgml-running-xemacs + (cond + ((null (mark-marker)) nil) + (t (setq start (region-beginning) + end (region-end))))) + ((and transient-mark-mode + mark-active) + (setq start (region-beginning) + end (region-end))) + ((and mouse-secondary-overlay + (eq (current-buffer) + (overlay-buffer mouse-secondary-overlay))) + (setq start (overlay-start mouse-secondary-overlay) + end (overlay-end mouse-secondary-overlay)) + (delete-overlay mouse-secondary-overlay))) + (when start + (goto-char start)) + end)) + + +;;;; SGML mode: indentation + +(defun sgml-indent-or-tab () + "Indent line in proper way for current major mode." + (interactive) + (if (null sgml-indent-step) + (insert-tab) + (funcall indent-line-function))) + +;;;; Bug reporting + +(eval-and-compile + (autoload 'reporter-submit-bug-report "reporter")) + +(defun sgml-submit-bug-report () + "Submit via mail a bug report on PSGML." + (interactive) + (and (y-or-n-p "Do you really want to submit a report on PSGML? ") + (reporter-submit-bug-report + psgml-maintainer-address + (concat "psgml.el " psgml-version) + (list + 'sgml-always-quote-attributes + 'sgml-auto-activate-dtd + 'sgml-auto-insert-required-elements + 'sgml-balanced-tag-edit + 'sgml-catalog-files + 'sgml-declaration + 'sgml-doctype + 'sgml-ecat-files + 'sgml-indent-data + 'sgml-indent-step + 'sgml-leave-point-after-insert + 'sgml-live-element-indicator + 'sgml-local-catalogs + 'sgml-local-ecat-files + 'sgml-markup-faces + 'sgml-minimize-attributes + 'sgml-normalize-trims + 'sgml-omittag + 'sgml-omittag-transparent + 'sgml-parent-document + 'sgml-public-map + 'sgml-set-face + 'sgml-shorttag + 'sgml-tag-region-if-active + )))) + + +;;;; SGML mode: keys and menus + +(if sgml-mode-map + () + (setq sgml-mode-map (make-sparse-keymap))) + +;;; Key commands + +(define-key sgml-mode-map "\t" 'sgml-indent-or-tab) +;(define-key sgml-mode-map "<" 'sgml-insert-tag) +(define-key sgml-mode-map ">" 'sgml-close-angle) +(define-key sgml-mode-map "/" 'sgml-slash) +(define-key sgml-mode-map "\C-c#" 'sgml-make-character-reference) +(define-key sgml-mode-map "\C-c-" 'sgml-untag-element) +(define-key sgml-mode-map "\C-c+" 'sgml-insert-attribute) +(define-key sgml-mode-map "\C-c/" 'sgml-insert-end-tag) +(define-key sgml-mode-map "\C-c<" 'sgml-insert-tag) +(define-key sgml-mode-map "\C-c=" 'sgml-change-element-name) +(define-key sgml-mode-map "\C-c\C-a" 'sgml-edit-attributes) +(define-key sgml-mode-map "\C-c\C-c" 'sgml-show-context) +(define-key sgml-mode-map "\C-c\C-d" 'sgml-next-data-field) +(define-key sgml-mode-map "\C-c\C-e" 'sgml-insert-element) +(define-key sgml-mode-map "\C-c\C-k" 'sgml-kill-markup) +(define-key sgml-mode-map "\C-c\C-l" 'sgml-show-or-clear-log) +(define-key sgml-mode-map "\C-c\C-n" 'sgml-up-element) +(define-key sgml-mode-map "\C-c\C-o" 'sgml-next-trouble-spot) +(define-key sgml-mode-map "\C-c\C-p" 'sgml-parse-prolog) +(define-key sgml-mode-map "\C-c\C-q" 'sgml-fill-element) +(define-key sgml-mode-map "\C-c\C-r" 'sgml-tag-region) +(define-key sgml-mode-map "\C-c\C-s" 'sgml-unfold-line) +(define-key sgml-mode-map "\C-c\C-t" 'sgml-list-valid-tags) +(define-key sgml-mode-map "\C-c\C-v" 'sgml-validate) +(define-key sgml-mode-map "\C-c\C-w" 'sgml-what-element) +(define-key sgml-mode-map "\C-c\C-z" 'sgml-trim-and-leave-element) +(define-key sgml-mode-map "\C-c\C-f\C-e" 'sgml-fold-element) +(define-key sgml-mode-map "\C-c\C-f\C-r" 'sgml-fold-region) +(define-key sgml-mode-map "\C-c\C-f\C-s" 'sgml-fold-subelement) +(define-key sgml-mode-map "\C-c\C-f\C-x" 'sgml-expand-element) +(define-key sgml-mode-map "\C-c\r" 'sgml-split-element) +(define-key sgml-mode-map "\C-c\C-u\C-e" 'sgml-unfold-element) +(define-key sgml-mode-map "\C-c\C-u\C-a" 'sgml-unfold-all) +(define-key sgml-mode-map "\C-c\C-u\C-l" 'sgml-unfold-line) +(define-key sgml-mode-map "\C-c\C-u\C-d" 'sgml-custom-dtd) +(define-key sgml-mode-map "\C-c\C-u\C-m" 'sgml-custom-markup) + +(define-key sgml-mode-map "\e\C-a" 'sgml-beginning-of-element) +(define-key sgml-mode-map "\e\C-e" 'sgml-end-of-element) +(define-key sgml-mode-map "\e\C-f" 'sgml-forward-element) +(define-key sgml-mode-map "\e\C-b" 'sgml-backward-element) +(define-key sgml-mode-map "\e\C-d" 'sgml-down-element) +(define-key sgml-mode-map "\e\C-u" 'sgml-backward-up-element) +(define-key sgml-mode-map "\e\C-k" 'sgml-kill-element) +(define-key sgml-mode-map "\e\C-@" 'sgml-mark-element) +;;(define-key sgml-mode-map [?\M-\C-\ ] 'sgml-mark-element) +(define-key sgml-mode-map "\e\C-h" 'sgml-mark-current-element) +(define-key sgml-mode-map "\e\C-t" 'sgml-transpose-element) +(define-key sgml-mode-map "\M-\t" 'sgml-complete) + +;;; Menu bar + +(eval-when-compile + (autoload 'sgml-build-custom-menus "psgml-other")) ; Avoid compiler warnings + +;; load menu file at the end + +;;;; Post command hook + +(defvar sgml-auto-activate-dtd-tried nil) +(make-variable-buffer-local 'sgml-auto-activate-dtd-tried) + +(defvar sgml-buffer-parse-state nil + "If the buffers DTD has been activated this contains the parser state. +The parser state has been created with `sgml-make-pstate' and contains +the information about the DTD and the parse tree. This parse state is +actually only the state that persists between commands.") +(make-variable-buffer-local 'sgml-buffer-parse-state) + +(eval-and-compile ; Interface to psgml-parse + (loop for fun in '(sgml-need-dtd sgml-update-display sgml-subst-expand + sgml-declaration) + do (autoload fun "psgml-parse"))) + + +(defun sgml-command-post () + (when (eq major-mode 'sgml-mode) + (when (and (null sgml-buffer-parse-state) + sgml-auto-activate-dtd + (null sgml-auto-activate-dtd-tried) + (not (zerop (buffer-size))) + (looking-at ".*<")) + (setq sgml-auto-activate-dtd-tried t) + (sgml-need-dtd)) + (when sgml-buffer-parse-state + (sgml-update-display)))) + + +;;;; SGML mode: major mode definition + +;;; This section is mostly from sgml-mode by James Clark. + +;;;###autoload +(defun sgml-mode () + "Major mode for editing SGML.\\<sgml-mode-map> +Makes > display the matching <. Makes / display matching /. +Use \\[sgml-validate] to validate your document with an SGML parser. + +You can find information with: +\\[sgml-show-context] Show the nesting of elements at cursor position. +\\[sgml-list-valid-tags] Show the tags valid at cursor position. + +Insert tags with completion of contextually valid tags with \\[sgml-insert-tag]. +End the current element with \\[sgml-insert-end-tag]. Insert an element (i.e. +both start and end tag) with \\[sgml-insert-element]. Or tag a region with +\\[sgml-tag-region]. + +To tag a region with the mouse, use transient mark mode or secondary selection. + +Structure editing: +\\[sgml-backward-element] Moves backwards over the previous element. +\\[sgml-forward-element] Moves forward over the nex element. +\\[sgml-down-element] Move forward and down one level in the element structure. +\\[sgml-backward-up-element] Move backward out of this element level. +\\[sgml-beginning-of-element] Move to after the start tag of the current element. +\\[sgml-end-of-element] Move to before the end tag of the current element. +\\[sgml-kill-element] Kill the element following the cursor. + +Finding interesting positions +\\[sgml-next-data-field] Move forward to next point where data is allowed. +\\[sgml-next-trouble-spot] Move forward to next point where something is + amiss with the structure. + +Folding and unfolding +\\[sgml-fold-element] Fold the lines comprising the current element, leaving + the first line visible. +\\[sgml-fold-subelement] Fold the elements in the content of the current element. + Leaving the first line of every element visible. +\\[sgml-unfold-line] Show hidden lines in current line. + +User options: + +sgml-omittag Set this to reflect OMITTAG in the SGML declaration. +sgml-shortag Set this to reflect SHORTTAG in the SGML declaration. +sgml-auto-insert-required-elements If non-nil, automatically insert required + elements in the content of an inserted element. +sgml-balanced-tag-edit If non-nil, always insert start-end tag pairs. +sgml-omittag-transparent If non-nil, will show legal tags inside elements + with omitable start tags and legal tags beyond omitable end tags. +sgml-leave-point-after-insert If non-nil, the point will remain after + inserted tag(s). +sgml-warn-about-undefined-elements If non-nil, print a warning when a tag + for a undefined element is found. +sgml-max-menu-size Max number of entries in Tags and Entities menus before + they are split into several panes. +sgml-always-quote-attributes If non-nil, quote all attribute values + inserted after finishing edit attributes. +sgml-minimize-attributes Determines minimization of attributes inserted by + edit-attributes. +sgml-normalize-trims If non-nil, sgml-normalize will trim off white space + from end of element when adding end tag. +sgml-indent-step How much to increament indent for every element level. +sgml-indent-data If non-nil, indent in data/mixed context also. +sgml-set-face If non-nil, psgml will set the face of parsed markup. +sgml-markup-faces The faces used when the above variable is non-nil. +sgml-system-path List of directorys used to look for system identifiers. +sgml-public-map Mapping from public identifiers to file names. +sgml-offer-save If non-nil, ask about saving modified buffers before + \\[sgml-validate] is run. + +All bindings: +\\{sgml-mode-map} +" + (interactive) + (kill-all-local-variables) + (setq local-abbrev-table sgml-mode-abbrev-table) + (use-local-map sgml-mode-map) + (setq mode-name "SGML") + (setq major-mode 'sgml-mode) + + ;; A start or end tag by itself on a line separates a paragraph. + ;; This is desirable because SGML discards a newline that appears + ;; immediately after a start tag or immediately before an end tag. + + (set (make-local-variable 'paragraph-separate) + "^[ \t\n]*$\\|\ +^[ \t]*</?\\([A-Za-z]\\([-.A-Za-z0-9= \t\n]\\|\ +\"[^\"]*\"\\|'[^']*'\\)*\\)?>$") + (set (make-local-variable 'paragraph-start) + paragraph-separate) + + (set-syntax-table text-mode-syntax-table) + (make-local-variable 'comment-start) + (setq comment-start "<!-- ") + (make-local-variable 'comment-end) + (setq comment-end " -->") + (make-local-variable 'comment-indent-function) + (setq comment-indent-function 'sgml-comment-indent) + (make-local-variable 'comment-start-skip) + ;; This will allow existing comments within declarations to be + ;; recognized. [Does not work well with auto-fill, Lst/940205] + ;;(setq comment-start-skip "--[ \t]*") + (setq comment-start-skip "<!--[ \t]*") + ;; Added for psgml: + (make-local-variable 'indent-line-function) + (setq indent-line-function 'sgml-indent-line) + (make-local-variable 'mode-line-format) + ;; wing change: use `subst' rather than duplicating the whole + ;; mode-line-format. XEmacs 19.14 changes the default mode-line-format. + (setq mode-line-format + (subst '("" mode-name sgml-active-dtd-indicator) 'mode-name + mode-line-format)) + (make-local-variable 'sgml-default-dtd-file) + (when (setq sgml-default-dtd-file (sgml-default-dtd-file)) + (unless (file-exists-p sgml-default-dtd-file) + (setq sgml-default-dtd-file nil))) + (add-hook 'post-command-hook 'sgml-command-post 'append) + (run-hooks 'text-mode-hook 'sgml-mode-hook) + (sgml-build-custom-menus)) + +(defun sgml-default-dtd-file () + (and (buffer-file-name) + (let ((base (file-name-nondirectory (buffer-file-name)))) + (concat + (cond ((string-match "\\.[^.]+$" base) + (substring base 0 (match-beginning 0))) + (t + base)) + ".ced")))) + +(defun sgml-comment-indent () + (if (and (looking-at "--") + (not (and (eq (char-after (1- (point))) ?!) + (eq (char-after (- (point) 2)) ?<)))) + (progn + (skip-chars-backward " \t") + (max comment-column (1+ (current-column)))) + 0)) + +(defconst sgml-start-tag-regex + "<[A-Za-z]\\([-.A-Za-z0-9= \n\t]\\|\"[^\"]*\"\\|'[^']*'\\)*" + "Regular expression that matches a non-empty start tag. +Any terminating > or / is not matched.") + +(defvar sgml-mode-markup-syntax-table nil + "Syntax table used for scanning SGML markup.") + +(if sgml-mode-markup-syntax-table + () + (setq sgml-mode-markup-syntax-table (make-syntax-table)) + (modify-syntax-entry ?< "(>" sgml-mode-markup-syntax-table) + (modify-syntax-entry ?> ")<" sgml-mode-markup-syntax-table) + (modify-syntax-entry ?- "_ 1234" sgml-mode-markup-syntax-table) + (modify-syntax-entry ?\' "\"" sgml-mode-markup-syntax-table)) + +(defconst sgml-angle-distance 4000 + "*If non-nil, is the maximum distance to search for matching <.") + +(defun sgml-close-angle (arg) + "Insert > and display matching <." + (interactive "p") + (insert-char ?> arg) + (if (> arg 0) + (let ((oldpos (point)) + (blinkpos)) + (save-excursion + (save-restriction + (if sgml-angle-distance + (narrow-to-region (max (point-min) + (- (point) sgml-angle-distance)) + oldpos)) + ;; See if it's the end of a marked section. + (and (> (- (point) (point-min)) 3) + (eq (char-after (- (point) 2)) ?\]) + (eq (char-after (- (point) 3)) ?\]) + (re-search-backward "<!\\[\\(-?[A-Za-z0-9. \t\n&;]\\|\ +--\\([^-]\\|-[^-]\\)*--\\)*\\[" + (point-min) + t) + (let ((msspos (point))) + (if (and (search-forward "]]>" oldpos t) + (eq (point) oldpos)) + (setq blinkpos msspos)))) + ;; This handles cases where the > ends one of the following: + ;; markup declaration starting with <! (possibly including a + ;; declaration subset); start tag; end tag; SGML declaration. + (if blinkpos + () + (goto-char oldpos) + (condition-case () + (let ((oldtable (syntax-table)) + (parse-sexp-ignore-comments t)) + (unwind-protect + (progn + (set-syntax-table sgml-mode-markup-syntax-table) + (setq blinkpos (scan-sexps oldpos -1))) + (set-syntax-table oldtable))) + (error nil)) + (and blinkpos + (goto-char blinkpos) + (or + ;; Check that it's a valid delimiter in context. + (not (looking-at + "<\\(\\?\\|/?[A-Za-z>]\\|!\\([[A-Za-z]\\|--\\)\\)")) + ;; Check that it's not a net-enabling start tag + ;; nor an unclosed start-tag. + (looking-at (concat sgml-start-tag-regex "[/<]")) + ;; Nor an unclosed end-tag. + (looking-at "</[A-Za-z][-.A-Za-z0-9]*[ \t]*<")) + (setq blinkpos nil))) + (if blinkpos + () + ;; See if it's the end of a processing instruction. + (goto-char oldpos) + (if (search-backward "<?" (point-min) t) + (let ((pipos (point))) + (if (and (search-forward ">" oldpos t) + (eq (point) oldpos)) + (setq blinkpos pipos)))))) + (if blinkpos + (progn + (goto-char blinkpos) + (if (pos-visible-in-window-p) + (sit-for 1) + (message "Matches %s" + (buffer-substring blinkpos + (progn (end-of-line) + (point))))))))))) + +;;; I doubt that null end tags are used much for large elements, +;;; so use a small distance here. +(defconst sgml-slash-distance 1000 + "*If non-nil, is the maximum distance to search for matching /.") + +(defun sgml-slash (arg) + "Insert / and display any previous matching /. +Two /s are treated as matching if the first / ends a net-enabling +start tag, and the second / is the corresponding null end tag." + (interactive "p") + (insert-char ?/ arg) + (if (> arg 0) + (let ((oldpos (point)) + (blinkpos) + (level 0)) + (save-excursion + (save-restriction + (if sgml-slash-distance + (narrow-to-region (max (point-min) + (- (point) sgml-slash-distance)) + oldpos)) + (if (and (re-search-backward sgml-start-tag-regex (point-min) t) + (eq (match-end 0) (1- oldpos))) + () + (goto-char (1- oldpos)) + (while (and (not blinkpos) + (search-backward "/" (point-min) t)) + (let ((tagend (save-excursion + (if (re-search-backward sgml-start-tag-regex + (point-min) t) + (match-end 0) + nil)))) + (if (eq tagend (point)) + (if (eq level 0) + (setq blinkpos (point)) + (setq level (1- level))) + (setq level (1+ level))))))) + (if blinkpos + (progn + (goto-char blinkpos) + (if (pos-visible-in-window-p) + (sit-for 1) + (message "Matches %s" + (buffer-substring (progn + (beginning-of-line) + (point)) + (1+ blinkpos)))))))))) + +(eval-and-compile + (autoload 'compile-internal "compile" "")) + +(defun sgml-default-validate-command () + (cond + ((consp sgml-validate-command) + (let ((validate-subst + (list + (cons ?b (and (buffer-file-name) + (file-name-nondirectory (buffer-file-name)))) + (cons ?s (sgml-declaration)) + (cons ?v sgml-declaration) + (cons ?d sgml-doctype)))) + (loop for template in sgml-validate-command + thereis + (sgml-subst-expand template validate-subst)))) + (t + (apply 'format sgml-validate-command + (if sgml-validate-files + (funcall sgml-validate-files) + (list (or sgml-declaration "") + (let ((name (buffer-file-name))) + (if name + (file-name-nondirectory name) + "")))))))) + +(defun sgml-validate (command) + "Validate an SGML document. +Runs COMMAND, a shell command, in a separate process asynchronously +with output going to the buffer *compilation*. +You can then use the command \\[next-error] to find the next error message +and move to the line in the SGML document that caused it." + (interactive + (list (read-from-minibuffer "Validate command: " + (sgml-default-validate-command) + nil nil 'sgml-validate-command-history))) + (if sgml-offer-save + (save-some-buffers nil nil)) + (compile-internal command "No more errors" "SGML validation" + nil + sgml-validate-error-regexps)) + + + +;;;; Autoloads and hooks + +(autoload 'sgml-doctype-insert "psgml-edit" + nil + nil nil) +(autoload 'sgml-indent-line "psgml-edit" nil) + +;;; Generated by sgml-build-autoloads + +(autoload 'sgml-load-dtd "psgml-parse" "Load a saved DTD from FILE." t) +(autoload 'sgml-show-or-clear-log "psgml-parse" "Show the *SGML LOG* buffer if it is not showing, or clear and +remove it if it is showing." t) +(autoload 'sgml-parse-prolog "psgml-parse" "Parse the document prolog to learn the DTD." t) +(autoload 'sgml-beginning-of-element "psgml-edit" "Move to after the start-tag of the current element. +If the start-tag is implied, move to the start of the element." t) +(autoload 'sgml-end-of-element "psgml-edit" "Move to before the end-tag of the current element." t) +(autoload 'sgml-backward-up-element "psgml-edit" "Move backward out of this element level. +That is move to before the start-tag or where a start-tag is implied." t) +(autoload 'sgml-up-element "psgml-edit" "Move forward out of this element level. +That is move to after the end-tag or where an end-tag is implied." t) +(autoload 'sgml-forward-element "psgml-edit" "Move forward over next element." t) +(autoload 'sgml-backward-element "psgml-edit" "Move backward over previous element at this level. +With implied tags this is ambigous." t) +(autoload 'sgml-down-element "psgml-edit" "Move forward and down one level in the element structure." t) +(autoload 'sgml-kill-element "psgml-edit" "Kill the element following the cursor." t) +(autoload 'sgml-transpose-element "psgml-edit" "Interchange element before point with element after point, leave point after." t) +(autoload 'sgml-mark-element "psgml-edit" "Set mark after next element." t) +(autoload 'sgml-mark-current-element "psgml-edit" "Set mark at end of current element, and leave point before current element." t) +(autoload 'sgml-change-element-name "psgml-edit" "Replace the name of the current element with a new name. +Eventual attributes of the current element will be translated if +possible." t) +(autoload 'sgml-untag-element "psgml-edit" "Remove tags from current element." t) +(autoload 'sgml-kill-markup "psgml-edit" "Kill next tag, markup declaration or process instruction." t) +(autoload 'sgml-fold-region "psgml-edit" "Hide (or if prefixarg unhide) region. +If called from a program first two arguments are start and end of +region. And optional third argument true unhides." t) +(autoload 'sgml-fold-element "psgml-edit" "Fold the lines comprising the current element, leaving the first line visible. +This uses the selective display feature." t) +(autoload 'sgml-fold-subelement "psgml-edit" "Fold all elements current elements content, leaving the first lines visible. +This uses the selective display feature." t) +(autoload 'sgml-unfold-line "psgml-edit" "Show hidden lines in current line." t) +(autoload 'sgml-unfold-element "psgml-edit" "Show all hidden lines in current element." t) +(autoload 'sgml-expand-element "psgml-edit" "As sgml-fold-subelement, but unfold first." t) +(autoload 'sgml-unfold-all "psgml-edit" "Show all hidden lines in buffer." t) +(autoload 'sgml-next-data-field "psgml-edit" "Move forward to next point where data is allowed." t) +(autoload 'sgml-next-trouble-spot "psgml-edit" "Move forward to next point where something is amiss with the structure." t) +(autoload 'sgml-list-valid-tags "psgml-edit" "Display a list of the contextually valid tags." t) +(autoload 'sgml-show-context "psgml-edit" "Display where the cursor is in the element hierarchy." t) +(autoload 'sgml-what-element "psgml-edit" "Display what element is under the cursor." t) +(autoload 'sgml-insert-tag "psgml-edit" "Insert a tag, reading tag name in minibuffer with completion. +If the variable sgml-balanced-tag-edit is t, also inserts the +corresponding end tag. If sgml-leave-point-after-insert is t, the point +is left after the inserted tag(s), unless the element has som required +content. If sgml-leave-point-after-insert is nil the point is left +after the first tag inserted." t) +(autoload 'sgml-insert-element "psgml-edit" "Reads element name from minibuffer and inserts start and end tags." t) +(autoload 'sgml-tag-region "psgml-edit" "Reads element name from minibuffer and inserts start and end tags." t) +(autoload 'sgml-insert-end-tag "psgml-edit" "Insert end-tag for the current open element." t) +(autoload 'sgml-insert-attribute "psgml-edit" "Read attribute name and value from minibuffer and insert attribute spec." t) +(autoload 'sgml-split-element "psgml-edit" "Split the current element at point. +If repeated, the containing element will be split before the beginning +of then current element." t) +(autoload 'sgml-custom-dtd "psgml-edit" "Insert a DTD declaration from the sgml-custom-dtd alist." t) +(autoload 'sgml-custom-markup "psgml-edit" "Insert markup from the sgml-custom-markup alist." t) +(autoload 'sgml-tags-menu "psgml-edit" "Pop up a menu with valid tags and insert the choosen tag. +If the variable sgml-balanced-tag-edit is t, also inserts the +corresponding end tag. If sgml-leave-point-after-insert is t, the point +is left after the inserted tag(s), unless the element has som required +content. If sgml-leave-point-after-insert is nil the point is left +after the first tag inserted." t) +(autoload 'sgml-element-menu "psgml-edit" "Pop up a menu with valid elements and insert choice. +If sgml-leave-point-after-insert is nil the point is left after the first +tag inserted." t) +(autoload 'sgml-start-tag-menu "psgml-edit" "Pop up a menu with valid start-tags and insert choice." t) +(autoload 'sgml-end-tag-menu "psgml-edit" "Pop up a menu with valid end-tags and insert choice." t) +(autoload 'sgml-tag-region-menu "psgml-edit" "Pop up a menu with valid elements and tag current region with the choice." t) +(autoload 'sgml-entities-menu "psgml-edit" nil t) +(autoload 'sgml-attrib-menu "psgml-edit" "Pop up a menu of the attributes of the current element +\(or the element whith start-tag before point)." t) +(autoload 'sgml-fill-element "psgml-edit" "Fill bigest enclosing element with mixed content. +If current element has pure element content, recursively fill the +subelements." t) +(autoload 'sgml-edit-attributes "psgml-edit" "Edit attributes of current element. +Editing is done in a separate window." t) +(autoload 'sgml-edit-attrib-finish "psgml-edit" "Finish editing and insert attribute values in original buffer." t) +(autoload 'sgml-edit-attrib-default "psgml-edit" "Set current attribute value to default." t) +(autoload 'sgml-edit-attrib-clear "psgml-edit" "Kill the value of current attribute." t) +(autoload 'sgml-edit-attrib-field-start "psgml-edit" "Go to the start of the attribute value field." t) +(autoload 'sgml-edit-attrib-field-end "psgml-edit" "Go to the end of the attribute value field." t) +(autoload 'sgml-edit-attrib-next "psgml-edit" "Move to next attribute value." t) +(autoload 'sgml-hide-tags "psgml-edit" "Hide all tags in buffer." t) +(autoload 'sgml-show-tags "psgml-edit" "Show hidden tags in buffer." t) +(autoload 'sgml-hide-attributes "psgml-edit" "Hide all attribute specifications in the buffer." t) +(autoload 'sgml-show-attributes "psgml-edit" "Show all attribute specifications in the buffer." t) +(autoload 'sgml-expand-all-shortrefs "psgml-edit" "Expand all short references in the buffer. +Short references to text entities are expanded to the replacement text +of the entity other short references are expanded into general entity +references. If argument, TO-ENTITY, is non-nil, or if called +interactive with numeric prefix argument, all short references are +replaced by generaly entity references." t) +(autoload 'sgml-normalize "psgml-edit" "Normalize buffer by filling in omitted tags and expanding empty tags. +Argument TO-ENTITY controls how short references are expanded as with +`sgml-expand-all-shortrefs'. An optional argument ELEMENT can be the +element to normalize insted of the whole buffer, if used no short +references will be expanded." t) +(autoload 'sgml-normalize-element "psgml-edit" nil t) +(autoload 'sgml-make-character-reference "psgml-edit" "Convert character after point into a character reference. +If called with a numeric argument, convert a character reference back +to a normal character. If called from a program, set optional +argument INVERT to non-nil." t) +(autoload 'sgml-expand-entity-reference "psgml-edit" "Insert the text of the entity referenced at point." t) +(autoload 'sgml-complete "psgml-edit" "Complete the word/tag/entity before point. +If it is a tag (starts with < or </) complete with valid tags. +If it is an entity (starts with &) complete with declared entities. +If it is a markup declaration (starts with <!) complete with markup +declaration names. +If it is something else complete with ispell-complete-word." t) +(autoload 'sgml-file-options-menu "psgml-edit" nil t) +(autoload 'sgml-user-options-menu "psgml-edit" nil t) +(autoload 'sgml-save-dtd "psgml-dtd" "Save the parsed dtd on FILE." t) +(autoload 'sgml-list-elements "psgml-info" "List the elements and their attributes in the current DTD." t) +(autoload 'sgml-list-attributes "psgml-info" "List the attributes and in which elements they occur." t) +(autoload 'sgml-list-terminals "psgml-info" "List the elements that can have data in their content." t) +(autoload 'sgml-list-content-elements "psgml-info" "List all element types and the element types that can occur in its content." t) +(autoload 'sgml-list-occur-in-elements "psgml-info" "List all element types and where it can occur." t) +(autoload 'sgml-describe-entity "psgml-info" "Describe the properties of an entity as declared in the current DTD." t) +(autoload 'sgml-describe-element-type "psgml-info" "Describe the properties of an element type as declared in the current DTD." t) +(autoload 'sgml-general-dtd-info "psgml-info" "Display information about the current DTD." t) +(autoload 'sgml-charent-to-display-char "psgml-charent" "Replace character entities with their display character equivalents" t) +(autoload 'sgml-display-char-to-charent "psgml-charent" "Replace displayable characters with their character entity equivalents" t) + + +;;;; Last provisions +(provide 'psgml) +(provide 'sgml-mode) + +(cond + (sgml-running-xemacs + (require 'psgml-xemacs) + (add-hook 'sgml-mode-hook 'sgml-install-xemacs-menus)) + (t + (require 'psgml-other))) + +;;; psgml.el ends HERE