+ (if (or (not compilation-ask-about-save)
+ (y-or-n-p (message "Save buffer %s? " (buffer-name))))
+ (save-buffer))
+ (compile-internal command "No more errors"))
+
+
+(defun sgml-beginning-of-tag (&optional top-level)
+ "Skip to beginning of tag and return its name.
+Else `t'."
+ (or (if top-level
+ (condition-case nil
+ (up-list -1)
+ (error t))
+ (>= (point)
+ (if (search-backward "<" nil t)
+ (save-excursion
+ (forward-list)
+ (point))
+ 0)))
+ (if (looking-at "<[!?/]?[[A-Za-z][A-Za-z0-9]*")
+ (buffer-substring-no-properties
+ (1+ (point))
+ (match-end 0))
+ t)))
+
+(defun sgml-value (alist)
+ (setq alist (cdr alist))
+ (if (stringp (car alist))
+ (insert "=\"" (car alist) ?\")
+ (if (eq (car alist) t)
+ (if (cdr alist)
+ (progn
+ (insert "=\"")
+ (setq alist (skeleton-read '(completing-read
+ "[Value]: " (cdr alist))))
+ (if (string< "" alist)
+ (insert (funcall skeleton-transformation alist) ?\")
+ (delete-backward-char 2))))
+ (insert "=\"")
+ (if alist
+ (insert (funcall skeleton-transformation
+ (skeleton-read '(completing-read "Value: " alist)))))
+ (insert ?\"))))
+
+(provide 'sgml-mode)
+\f
+(defvar html-quick-keys sgml-quick-keys
+ "Use C-c X combinations for quick insertion of frequent tags when non-nil.
+This defaults to `sgml-quick-keys'.
+This takes effect when first loading the library.")
+
+(defvar html-mode-map
+ (let ((map (nconc (make-sparse-keymap) sgml-mode-map))
+ (menu-map (make-sparse-keymap "HTML")))
+ (define-key map "\C-c6" 'html-headline-6)
+ (define-key map "\C-c5" 'html-headline-5)
+ (define-key map "\C-c4" 'html-headline-4)
+ (define-key map "\C-c3" 'html-headline-3)
+ (define-key map "\C-c2" 'html-headline-2)
+ (define-key map "\C-c1" 'html-headline-1)
+ (define-key map "\C-c\r" 'html-paragraph)
+ (define-key map "\C-c\n" 'html-line)
+ (define-key map "\C-c\C-c-" 'html-horizontal-rule)
+ (define-key map "\C-c\C-co" 'html-ordered-list)
+ (define-key map "\C-c\C-cu" 'html-unordered-list)
+ (define-key map "\C-c\C-cr" 'html-radio-buttons)
+ (define-key map "\C-c\C-cc" 'html-checkboxes)
+ (define-key map "\C-c\C-cl" 'html-list-item)
+ (define-key map "\C-c\C-ch" 'html-href-anchor)
+ (define-key map "\C-c\C-cn" 'html-name-anchor)
+ (define-key map "\C-c\C-ci" 'html-image)
+ (if html-quick-keys
+ (progn
+ (define-key map "\C-c-" 'html-horizontal-rule)
+ (define-key map "\C-co" 'html-ordered-list)
+ (define-key map "\C-cu" 'html-unordered-list)
+ (define-key map "\C-cr" 'html-radio-buttons)
+ (define-key map "\C-cc" 'html-checkboxes)
+ (define-key map "\C-cl" 'html-list-item)
+ (define-key map "\C-ch" 'html-href-anchor)
+ (define-key map "\C-cn" 'html-name-anchor)
+ (define-key map "\C-ci" 'html-image)))
+ (define-key map "\C-c\C-s" 'html-autoview-mode)
+ (define-key map "\C-c\C-v" 'browse-url-of-buffer)
+ (define-key map [menu-bar html] (cons "HTML" menu-map))
+ (define-key menu-map [html-autoview-mode]
+ '("Toggle Autoviewing" . html-autoview-mode))
+ (define-key menu-map [browse-url-of-buffer]
+ '("View Buffer Contents" . browse-url-of-buffer))
+ (define-key menu-map [nil] '("--"))
+ ;;(define-key menu-map "6" '("Heading 6" . html-headline-6))
+ ;;(define-key menu-map "5" '("Heading 5" . html-headline-5))
+ ;;(define-key menu-map "4" '("Heading 4" . html-headline-4))
+ (define-key menu-map "3" '("Heading 3" . html-headline-3))
+ (define-key menu-map "2" '("Heading 2" . html-headline-2))
+ (define-key menu-map "1" '("Heading 1" . html-headline-1))
+ (define-key menu-map "l" '("Radio Buttons" . html-radio-buttons))
+ (define-key menu-map "c" '("Checkboxes" . html-checkboxes))
+ (define-key menu-map "l" '("List Item" . html-list-item))
+ (define-key menu-map "u" '("Unordered List" . html-unordered-list))
+ (define-key menu-map "o" '("Ordered List" . html-ordered-list))
+ (define-key menu-map "-" '("Horizontal Rule" . html-horizontal-rule))
+ (define-key menu-map "\n" '("Line Break" . html-line))
+ (define-key menu-map "\r" '("Paragraph" . html-paragraph))
+ (define-key menu-map "i" '("Image" . html-image))
+ (define-key menu-map "h" '("Href Anchor" . html-href-anchor))
+ (define-key menu-map "n" '("Name Anchor" . html-name-anchor))
+ map)
+ "Keymap for commands for use in HTML mode.")
+
+
+(defvar html-face-tag-alist
+ '((bold . "b")
+ (italic . "i")
+ (underline . "u")
+ (modeline . "rev"))
+ "Value of `sgml-face-tag-alist' for HTML mode.")
+
+(defvar html-tag-face-alist
+ '(("b" . bold)
+ ("big" . bold)
+ ("blink" . highlight)
+ ("cite" . italic)
+ ("em" . italic)
+ ("h1" bold underline)
+ ("h2" bold-italic underline)
+ ("h3" italic underline)
+ ("h4" . underline)
+ ("h5" . underline)
+ ("h6" . underline)
+ ("i" . italic)
+ ("rev" . modeline)
+ ("s" . underline)
+ ("small" . default)
+ ("strong" . bold)
+ ("title" bold underline)
+ ("tt" . default)
+ ("u" . underline)
+ ("var" . italic))
+ "Value of `sgml-tag-face-alist' for HTML mode.")
+
+
+(defvar html-display-text
+ '((img . "[/]")
+ (hr . "----------")
+ (li . "o "))
+ "Value of `sgml-display-text' for HTML mode.")
+
+
+; should code exactly HTML 3 here when that is finished
+(defvar html-tag-alist
+ (let* ((1-9 '(("8") ("9")
+ ("1") ("2") ("3") ("4") ("5") ("6") ("7")))
+ (align '(("align" ("left") ("center") ("right"))))
+ (valign '(("top") ("middle") ("bottom") ("baseline")))
+ (rel '(("next") ("previous") ("parent") ("subdocument") ("made")))
+ (href '("href" ("ftp:") ("file:") ("finger:") ("gopher:") ("http:")
+ ("mailto:") ("news:") ("rlogin:") ("telnet:") ("tn3270:")
+ ("wais:") ("/cgi-bin/")))
+ (name '("name"))
+ (link `(,href
+ ("rel" ,@rel)
+ ("rev" ,@rel)
+ ("title")))
+ (list '((nil \n
+ ( "List item: "
+ "<li>" str \n))
+ ("type" ("A") ("a") ("I") ("i") ("1"))))
+ (cell `(t
+ ,align
+ ("valign" ,@valign)
+ ("colspan" ,@1-9)
+ ("rowspan" ,@1-9)
+ ("nowrap" t))))
+ ;; put ,-expressions first, else byte-compile chokes (as of V19.29)
+ ;; and like this it's more efficient anyway
+ `(("a" ,name ,@link)
+ ("base" t ,@href)
+ ("dir" ,@list)
+ ("font" ("size" ("-1") ("+1") ("-2") ("+2") ,@(cdr (cdr 1-9))))
+ ("form" (\n _ \n "<input type=\"submit\" value=\"\">")
+ ("action" ,@(cdr href)) ("method" ("get") ("post")))
+ ("h1" ,@align)
+ ("h2" ,@align)
+ ("h3" ,@align)
+ ("h4" ,@align)
+ ("h5" ,@align)
+ ("h6" ,@align)
+ ("hr" t ("size" ,@1-9) ("width") ("noshade" t) ,@align)
+ ("img" t ("align" ,@valign ("texttop") ("absmiddle") ("absbottom"))
+ ("src") ("alt") ("width" "1") ("height" "1")
+ ("border" "1") ("vspace" "1") ("hspace" "1") ("ismap" t))
+ ("input" t ("size" ,@1-9) ("maxlength" ,@1-9) ("checked" t) ,name
+ ("type" ("text") ("password") ("checkbox") ("radio")
+ ("submit") ("reset"))
+ ("value"))
+ ("link" t ,@link)
+ ("menu" ,@list)
+ ("ol" ,@list)
+ ("p" t ,@align)
+ ("select" (nil \n
+ ("Text: "
+ "<option>" str \n))
+ ,name ("size" ,@1-9) ("multiple" t))
+ ("table" (nil \n
+ ((completing-read "Cell kind: " '(("td") ("th"))
+ nil t "t")
+ "<tr><" str ?> _ \n))
+ ("border" t ,@1-9) ("width" "10") ("cellpadding"))
+ ("td" ,@cell)
+ ("textarea" ,name ("rows" ,@1-9) ("cols" ,@1-9))
+ ("th" ,@cell)
+ ("ul" ,@list)
+
+ ,@sgml-tag-alist
+
+ ("abbrev")
+ ("acronym")
+ ("address")
+ ("array" (nil \n
+ ("Item: " "<item>" str \n))
+ "align")
+ ("au")
+ ("b")
+ ("big")
+ ("blink")
+ ("blockquote" \n)
+ ("body" \n ("background" ".gif") ("bgcolor" "#") ("text" "#")
+ ("link" "#") ("alink" "#") ("vlink" "#"))
+ ("box" (nil _ "<over>" _))
+ ("br" t ("clear" ("left") ("right")))
+ ("caption" ("valign" ("top") ("bottom")))
+ ("center" \n)
+ ("cite")
+ ("code" \n)
+ ("dd" t)
+ ("del")
+ ("dfn")
+ ("dl" (nil \n
+ ( "Term: "
+ "<dt>" str "<dd>" _ \n)))
+ ("dt" (t _ "<dd>"))
+ ("em")
+ ("fn" "id" "fn")
+ ("head" \n)
+ ("html" (\n
+ "<head>\n"
+ "<title>" (setq str (read-input "Title: ")) "</title>\n"
+ "<body>\n<h1>" str "</h1>\n" _
+ "\n<address>\n<a href=\"mailto:"
+ user-mail-address
+ "\">" (user-full-name) "</a>\n</address>"))
+ ("i")
+ ("ins")
+ ("isindex" t ("action") ("prompt"))
+ ("kbd")
+ ("lang")
+ ("li" t)
+ ("math" \n)
+ ("nobr")
+ ("option" t ("value") ("label") ("selected" t))
+ ("over" t)
+ ("person")
+ ("pre" \n)
+ ("q")
+ ("rev")
+ ("s")
+ ("samp")
+ ("small")
+ ("strong")
+ ("sub")
+ ("sup")
+ ("title")
+ ("tr" t)
+ ("tt")
+ ("u")
+ ("var")
+ ("wbr" t)))
+ "*Value of `sgml-tag-alist' for HTML mode.")
+
+(defvar html-tag-help
+ `(,@sgml-tag-help
+ ("a" . "Anchor of point or link elsewhere")
+ ("abbrev" . "?")
+ ("acronym" . "?")
+ ("address" . "Formatted mail address")
+ ("array" . "Math array")
+ ("au" . "?")
+ ("b" . "Bold face")
+ ("base" . "Base address for URLs")
+ ("big" . "Font size")
+ ("blink" . "Blinking text")
+ ("blockquote" . "Indented quotation")
+ ("body" . "Document body")
+ ("box" . "Math fraction")
+ ("br" . "Line break")
+ ("caption" . "Table caption")
+ ("center" . "Centered text")
+ ("changed" . "Change bars")
+ ("cite" . "Citation of a document")
+ ("code" . "Formatted source code")
+ ("dd" . "Definition of term")
+ ("del" . "?")
+ ("dfn" . "?")
+ ("dir" . "Directory list (obsolete)")
+ ("dl" . "Definition list")
+ ("dt" . "Term to be definined")
+ ("em" . "Emphasised")
+ ("embed" . "Embedded data in foreign format")
+ ("fig" . "Figure")
+ ("figa" . "Figure anchor")
+ ("figd" . "Figure description")
+ ("figt" . "Figure text")
+ ("fn" . "?")
+ ("font" . "Font size")
+ ("form" . "Form with input fields")
+ ("group" . "Document grouping")
+ ("h1" . "Most important section headline")
+ ("h2" . "Important section headline")
+ ("h3" . "Section headline")
+ ("h4" . "Minor section headline")
+ ("h5" . "Unimportant section headline")
+ ("h6" . "Least important section headline")
+ ("head" . "Document header")
+ ("hr" . "Horizontal rule")
+ ("html" . "HTML Document")
+ ("i" . "Italic face")
+ ("img" . "Graphic image")
+ ("input" . "Form input field")
+ ("ins" . "?")
+ ("isindex" . "Input field for index search")
+ ("kbd" . "Keybard example face")
+ ("lang" . "Natural language")
+ ("li" . "List item")
+ ("link" . "Link relationship")
+ ("math" . "Math formula")
+ ("menu" . "Menu list (obsolete)")
+ ("mh" . "Form mail header")
+ ("nextid" . "Allocate new id")
+ ("nobr" . "Text without line break")
+ ("ol" . "Ordered list")
+ ("option" . "Selection list item")
+ ("over" . "Math fraction rule")
+ ("p" . "Paragraph start")
+ ("panel" . "Floating panel")
+ ("person" . "?")
+ ("pre" . "Preformatted fixed width text")
+ ("q" . "?")
+ ("rev" . "Reverse video")
+ ("s" . "?")
+ ("samp" . "Sample text")
+ ("select" . "Selection list")
+ ("small" . "Font size")
+ ("sp" . "Nobreak space")
+ ("strong" . "Standout text")
+ ("sub" . "Subscript")
+ ("sup" . "Superscript")
+ ("table" . "Table with rows and columns")
+ ("tb" . "Table vertical break")
+ ("td" . "Table data cell")
+ ("textarea" . "Form multiline edit area")
+ ("th" . "Table header cell")
+ ("title" . "Document title")
+ ("tr" . "Table row separator")
+ ("tt" . "Typewriter face")
+ ("u" . "Underlined text")
+ ("ul" . "Unordered list")
+ ("var" . "Math variable face")
+ ("wbr" . "Enable <br> within <nobr>"))
+"*Value of `sgml-tag-help' for HTML mode.")
+
+
+
+;;;###autoload
+(defun html-mode ()
+ "Major mode based on SGML mode for editing HTML documents.
+This allows inserting skeleton costructs used in hypertext documents with
+completion. See below for an introduction to HTML. Use
+\\[browse-url-of-buffer] to see how this comes out. See also `sgml-mode' on
+which this is based.
+
+Do \\[describe-variable] html- SPC and \\[describe-variable] sgml- SPC to see available variables.
+
+To write fairly well formatted pages you only need to know few things. Most
+browsers have a function to read the source code of the page being seen, so
+you can imitate various tricks. Here's a very short HTML primer which you
+can also view with a browser to see what happens:
+
+<title>A Title Describing Contents</title> should be on every page. Pages can
+have <h1>Very Major Headlines</h1> through <h6>Very Minor Headlines</h6>
+<hr> Parts can be separated with horizontal rules.
+
+<p>Paragraphs only need an opening tag. Line breaks and multiple spaces are
+ignored unless the text is <pre>preformatted.</pre> Text can be marked as
+<b>bold</b>, <i>italic</i> or <u>underlined</u> using the normal M-g or
+Edit/Text Properties/Face commands.
+
+Pages can have <a name=\"SOMENAME\">named points</a> and can link other points
+to them with <a href=\"#SOMENAME\">see also somename</a>. In the same way <a
+href=\"URL\">see also URL</a> where URL is a filename relative to current
+directory or something like http://www.cs.indiana.edu/elisp/w3/docs.html.
+
+Images in many formats can be inlined with <img src=\"URL\">.
+
+If you mainly create your own documents, `sgml-specials' might be interesting.
+But note that some HTML 2 browsers can't handle '. To work around that
+do:
+
+\(eval-after-load \"sgml-mode\" '(aset sgml-char-names ?' nil))
+\\{html-mode-map}"
+ (interactive)
+ (sgml-mode-common html-tag-face-alist html-display-text)
+ (use-local-map html-mode-map)
+ (make-local-variable 'sgml-tag-alist)
+ (make-local-variable 'sgml-face-tag-alist)
+ (make-local-variable 'sgml-tag-help)
+ (make-local-variable 'outline-regexp)
+ (make-local-variable 'outline-heading-end-regexp)
+ (make-local-variable 'outline-level)
+ (make-local-variable 'sentence-end)
+ (setq sentence-end
+ "[.?!][]\"')}]*\\(<[^>]*>\\)*\\($\\| $\\|\t\\| \\)[ \t\n]*")
+ (setq mode-name "HTML"
+ major-mode 'html-mode
+ sgml-tag-alist html-tag-alist
+ sgml-face-tag-alist html-face-tag-alist
+ sgml-tag-help html-tag-help
+ outline-regexp "^.*<[Hh][1-6]\\>"
+ outline-heading-end-regexp "</[Hh][1-6]>"
+ outline-level (lambda ()
+ (char-after (1- (match-end 0)))))
+ (run-hooks 'html-mode-hook))
+
+
+(define-skeleton html-href-anchor
+ "HTML anchor tag with href attribute."
+ nil
+ "<a href=\"http:" _ "\"></a>")
+
+(define-skeleton html-name-anchor
+ "HTML anchor tag with name attribute."
+ nil
+ "<a name=\"" _ "\"></a>")
+
+(define-skeleton html-headline-1
+ "HTML level 1 headline tags."
+ nil
+ "<h1>" _ "</h1>")
+
+(define-skeleton html-headline-2
+ "HTML level 2 headline tags."
+ nil
+ "<h2>" _ "</h2>")
+
+(define-skeleton html-headline-3
+ "HTML level 3 headline tags."
+ nil
+ "<h3>" _ "</h3>")
+
+(define-skeleton html-headline-4
+ "HTML level 4 headline tags."
+ nil
+ "<h4>" _ "</h4>")
+
+(define-skeleton html-headline-5
+ "HTML level 5 headline tags."
+ nil
+ "<h5>" _ "</h5>")
+
+(define-skeleton html-headline-6
+ "HTML level 6 headline tags."
+ nil
+ "<h6>" _ "</h6>")
+
+(define-skeleton html-horizontal-rule
+ "HTML horizontal rule tag."
+ nil
+ "<hr>" \n)
+
+(define-skeleton html-image
+ "HTML image tag."
+ nil
+ "<img src=\"http:" _ "\">")
+
+(define-skeleton html-line
+ "HTML line break tag."
+ nil
+ "<br>" \n)
+
+(define-skeleton html-ordered-list
+ "HTML ordered list tags."
+ nil
+ ?< "ol>" \n
+ "<li>" _ \n
+ "</ol>")
+
+(define-skeleton html-unordered-list
+ "HTML unordered list tags."
+ nil
+ ?< "ul>" \n
+ "<li>" _ \n
+ "</ul>")
+
+(define-skeleton html-list-item
+ "HTML list item tag."
+ nil
+ (if (bolp) nil '\n)
+ "<li>")
+
+(define-skeleton html-paragraph
+ "HTML paragraph tag."
+ nil
+ (if (bolp) nil ?\n)
+ \n "<p>")
+
+(define-skeleton html-checkboxes
+ "Group of connected checkbox inputs."
+ nil
+ '(setq v1 (eval str)) ; allow passing name as argument
+ ("Value & Text: "
+ "<input type=\"checkbox\" name=\""
+ (or v1 (setq v1 (skeleton-read "Name: ")))
+ "\" value=\"" str ?\"
+ (if v2 "" " checked") ?> str
+ (or v2 (setq v2 (if (y-or-n-p "Newline? ") "<br>" ""))) \n))
+
+(define-skeleton html-radio-buttons
+ "Group of connected radio button inputs."
+ nil
+ '(setq v1 (eval str)) ; allow passing name as argument
+ ("Value & Text: "
+ "<input type=\"radio\" name=\""
+ (or v1 (setq v1 (skeleton-read "Name: ")))
+ "\" value=\"" str ?\"
+ (if v2 "" " checked") ?> str
+ (or v2 (setq v2 (if (y-or-n-p "Newline? ") "<br>" ""))) \n))
+
+
+(defun html-autoview-mode (&optional arg)
+ "Toggle automatic viewing via `html-viewer' upon saving buffer.
+With positive prefix ARG always turns viewing on, with negative ARG always off.
+Can be used as a value for `html-mode-hook'."
+ (interactive "P")
+ (if (setq arg (if arg
+ (< (prefix-numeric-value arg) 0)
+ (and (boundp 'after-save-hook)
+ (memq 'browse-url-of-buffer after-save-hook))))
+ (setq after-save-hook (delq 'browse-url-of-buffer after-save-hook))
+ (make-local-hook 'after-save-hook)
+ (add-hook 'after-save-hook 'browse-url-of-buffer nil t))
+ (message "Autoviewing turned %s."
+ (if arg "off" "on")))