home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / h / htmlmode.zip / HTMLMODE.EL next >
Text File  |  1993-03-25  |  25KB  |  653 lines

  1. ;;; --------------------------------------------------------------------------
  2. ;;; HTML mode, based on text mode.
  3. ;;; Copyright (C) 1985 Free Software Foundation, Inc.
  4. ;;; Copyright (C) 1992 National Center for Supercomputing Applications.
  5. ;;; NCSA modifications by Marc Andreessen (marca@ncsa.uiuc.edu).
  6. ;;;
  7. ;;; This program is free software; you can redistribute it and/or
  8. ;;; modify it under the terms of the GNU General Public License as
  9. ;;; published by the Free Software Foundation; either version 1, or
  10. ;;; (at your option) any later version.
  11. ;;;
  12. ;;; This program is distributed in the hope that it will be useful,
  13. ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15. ;;; General Public License for more details.
  16. ;;;
  17. ;;; You should have received a copy of the GNU General Public License
  18. ;;; along with GNU Emacs; see the file COPYING.  If not, write to the
  19. ;;; Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  20. ;;;
  21. ;;; -------------------------------- CONTENTS --------------------------------
  22. ;;;
  23. ;;; html-mode: Major mode for editing HTML hypertext documents.
  24. ;;; $Revision: 1.22 $
  25. ;;; $Date: 1992/11/23 01:29:10 $
  26. ;;;
  27. ;;; Canonical list of features:
  28. ;;;   See below.
  29. ;;;
  30. ;;; ------------------------------ INSTRUCTIONS ------------------------------
  31. ;;;
  32. ;;; Load html-mode.el before editing HTML documents.  html-mode will
  33. ;;; detect the ``.html'' suffix and activate itself appropriately.
  34. ;;;
  35. ;;; You are assumed to be at least somewhat familiar with HTML format.
  36. ;;; If you aren't, read about it first (see below).
  37. ;;;
  38. ;;; Here are key sequences and corresponding commands:
  39. ;;;
  40. ;;; NORMAL COMMANDS:
  41. ;;;
  42. ;;; C-c a         html-add-address
  43. ;;;   Open an address element.
  44. ;;;
  45. ;;; C-c d         html-add-definition-list
  46. ;;;   Open a definition list.  The initial entry is created for you.
  47. ;;;   To create subsequent entries, use 'C-c e'.
  48. ;;;
  49. ;;; C-c e         html-add-definition-entry
  50. ;;;   Add a new definition entry in a definition list.  You are
  51. ;;;   assumed to be inside a definition list (specifically, at the end
  52. ;;;   of another definition entry).
  53. ;;;
  54. ;;; C-c h         html-add-header
  55. ;;;   Add a header.  You are prompted for size (1 is biggest, 2 is
  56. ;;;   next biggest) and header contents.
  57. ;;;
  58. ;;; C-c i         html-add-list-or-menu-item
  59. ;;;   Add a new list or menu item in a list or menu.  You are assumed
  60. ;;;   to be inside a list or menu (specifically, at the end of another
  61. ;;;   item).
  62. ;;;
  63. ;;; C-c l         html-add-normal-link
  64. ;;;   Add a link.  You will be prompted for the link (any string;
  65. ;;;   e.g., http://foo.bar/argh/blagh).  The cursor will be left where
  66. ;;;   you can type the text that will represent the link in the
  67. ;;;   document.
  68. ;;;
  69. ;;; C-c m         html-add-menu
  70. ;;;   Open a menu.  The initial item is created for you.  To create
  71. ;;;   additional items, use 'C-c i'.
  72. ;;;
  73. ;;; C-c p         html-add-paragraph-separator
  74. ;;;   Use this command at the end of each paragraph.
  75. ;;;
  76. ;;; C-c s         html-add-list
  77. ;;;   Open a list.  The initial item is created for you.  To create
  78. ;;;   additional items, use 'C-c i'.
  79. ;;;
  80. ;;; C-c t         html-add-title
  81. ;;;   Add a title to the document.  You will be prompted for the
  82. ;;;   contents of the title.  If a title already exists at the very
  83. ;;;   top of the document, the existing contents will be replaced.
  84. ;;;
  85. ;;; C-c x         html-add-plaintext
  86. ;;;   Add plaintext.  The cursor will be positioned where you can type
  87. ;;;   plaintext (or insert another file, or whatever).
  88. ;;;
  89. ;;; COMMANDS THAT OPERATE ON THE CURRENT REGION:
  90. ;;;
  91. ;;; C-c C-r l     html-add-normal-link-to-region
  92. ;;;   Add a link that will be represented by the current region.  You
  93. ;;;   will be prompted for the link (any string, as with
  94. ;;;   html-add-normal-link).
  95. ;;;
  96. ;;; C-c C-r r     html-add-reference-to-region
  97. ;;;   Add a reference (a link that does not reference anything) that
  98. ;;;   will be represented by the current region.  You will be prompted
  99. ;;;   for the name of the link; if you just press RET, a numeric name
  100. ;;;   will be created for you.
  101. ;;;
  102. ;;; SPECIAL COMMANDS:
  103. ;;;
  104. ;;; <, >, &
  105. ;;;   These are overridden to output <, >, and &
  106. ;;;   respectively.  The real characters <, >, and & can be entered
  107. ;;;   into the text either by prepending 'C-c' to the character or by
  108. ;;;   using the Emacs quoted-insert (C-q) command.
  109. ;;;
  110. ;;; C-c <, C-c >, C-c &
  111. ;;;   See '<, >, &' above.
  112. ;;;
  113. ;;; NOTE: The key bindings above are what I find to be useful and easy
  114. ;;; to remember.  If you have ideas on how to make them easier to
  115. ;;; handle for yourself or other people, please let me know.
  116. ;;; (Ideally, these commands all go in menus; to that end, someday
  117. ;;; soon I'll add a Lucid Emacs menu to html-mode.)
  118. ;;;
  119. ;;; ---------------------------- ADDITIONAL NOTES ----------------------------
  120. ;;;
  121. ;;; If you are running Epoch or Lucid Emacs, highlighting will be used
  122. ;;; to deemphasize HTML message elements as they are created.  You can
  123. ;;; turn this off; see the variable 'html-use-highlighting'.
  124. ;;;
  125. ;;; To reorder all of the link NAME fields in your message (in order
  126. ;;; of their occurrence in the text), use:
  127. ;;;
  128. ;;; html-reorder-numeric-names
  129. ;;;   Reorder the NAME fields for links in the current buffer.  The
  130. ;;;   new ordering starts at 1 and increases monotonically through the
  131. ;;;   buffer.  If optional arg REORDER-NON-NUMERIC is non-nil, then
  132. ;;;   non-numeric NAME's will also be numbered, else they won't.
  133. ;;;
  134. ;;; In most current HTML documents, HREF arguments are not quoted.
  135. ;;; They really should be, so HTML can be fully SGML-compliant.
  136. ;;; However, some HTML browsers don't deal with quoted HREF arguments
  137. ;;; very well yet, but they should soon.
  138. ;;;
  139. ;;; To deal with this situation, there are two variables and a command
  140. ;;; that you should know about:
  141. ;;;
  142. ;;; html-quote-hrefs                 (variable, default nil)
  143. ;;;   If this is non-nil, new HREF arguments will be quoted.
  144. ;;;
  145. ;;; html-quotify-hrefs-on-find       (variable, default nil)
  146. ;;;   If this is non-nil, all HREF arguments will be quotified
  147. ;;;   automatically when a HTML document is loaded into Emacs
  148. ;;;   (actually when html-mode is entered).
  149. ;;;
  150. ;;; html-quotify-hrefs
  151. ;;;   This command will quotify all HREF arguments in the current
  152. ;;;   document.
  153. ;;;
  154. ;;; The default values for 'html-quote-hrefs' and
  155. ;;; 'html-quotify-hrefs-on-find' will change as soon as the rest of
  156. ;;; the world has caught up to quoted HREF arguments.
  157. ;;;
  158. ;;; -------------------------------- GOTCHAS ---------------------------------
  159. ;;;
  160. ;;; HTML documents can be tricky.  html-mode is not smart enough to
  161. ;;; enforce correctness or sanity, so you have to do that yourself.
  162. ;;;
  163. ;;; In particular, html-mode is smart enough to generate unique
  164. ;;; numeric NAME id's for all links that were (1) created via an
  165. ;;; html-mode command or (2) present in the file when it was loaded.
  166. ;;; Any other links (e.g. links added via Emacs cut and paste) may
  167. ;;; have ID's that conflict with ID's html-mode generates.  You must
  168. ;;; watch for this and fix it when appropriate; otherwise, your
  169. ;;; hypertext document will not work correctly.
  170. ;;;
  171. ;;; html-reorder-numeric-names can be used to reset all of the NAME
  172. ;;; id's in a document to an ordered sequence; this will also give
  173. ;;; html-mode a chance to look over the document and figure out what
  174. ;;; new links should be named to be unique.
  175. ;;;
  176. ;;; ------------------------- WHAT HTML-MODE IS NOT --------------------------
  177. ;;;
  178. ;;; html-mode is not a mode for *browsing* HTML documents.  In
  179. ;;; particular, html-mode provides no hypertext capabilities.  There
  180. ;;; is a clear need for an HTML browser; if you write one, let me
  181. ;;; know.
  182. ;;;
  183. ;;; ------------------------------ WHAT HTML IS ------------------------------
  184. ;;;
  185. ;;; HTML (HyperText Markup Language) is a format for hypertext
  186. ;;; documents.  For more information on HTML, telnet to info.cern.ch.
  187. ;;;
  188. ;;; ---------------------------- ACKNOWLEDGEMENTS ----------------------------
  189. ;;;
  190. ;;; Some code herein provided by:
  191. ;;;   Dan Connolly <connolly@pixel.convex.com>
  192. ;;;
  193. ;;; --------------------------------------------------------------------------
  194. ;;; LCD Archive Entry:
  195. ;;; html-mode|Marc Andreessen|marca@ncsa.uiuc.edu|
  196. ;;; Major mode for editing HTML hypertext files.|
  197. ;;; 1992-11-23|1.22|~/modes/html-mode.el.Z|
  198. ;;; --------------------------------------------------------------------------
  199.  
  200. ;; TODO:
  201. ;; sgml-mode stuff.
  202.  
  203. (provide 'html-mode)
  204.  
  205. ;;; ------------------------------- variables --------------------------------
  206.  
  207. (defvar html-quote-hrefs nil
  208.   "*New HREF fields will be quoted if this is non-nil; else they won't be.
  209. Technically, they should be, but that currently conflicts with common usage.")
  210.  
  211. (defvar html-quotify-hrefs-on-find nil
  212.   "*If non-nil, all HREF's in a file will be automatically quotified when
  213. the file is loaded.  This will be useful when converting old HTML documents
  214. to the new SGML-compatible syntax (currently, some HTML browsers can't handle
  215. quotes around HREF's, but this should change in the near future).")
  216.  
  217. (defvar html-use-highlighting t
  218.   "*Flag to use highlighting for HTML directives in Epoch or Lucid Emacs; 
  219. if non-NIL, highlighting will be used.")
  220.  
  221. (defvar html-deemphasize-color "grey80"
  222.   "*Color for de-highlighting HTML directives in Epoch or Lucid Emacs.")
  223.  
  224. (defvar html-emphasize-color "yellow"
  225.   "*Color for highlighting HTML something-or-others in Epoch or Lucid Emacs.")
  226.  
  227. ;;; --------------------------------- setup ----------------------------------
  228.  
  229. (defvar html-mode-syntax-table nil
  230.   "Syntax table used while in html mode.")
  231.  
  232. (defvar html-mode-abbrev-table nil
  233.   "Abbrev table used while in html mode.")
  234. (define-abbrev-table 'html-mode-abbrev-table ())
  235.  
  236. (if html-mode-syntax-table
  237.     ()
  238.   (setq html-mode-syntax-table (make-syntax-table))
  239.   (modify-syntax-entry ?\" ".   " html-mode-syntax-table)
  240.   (modify-syntax-entry ?\\ ".   " html-mode-syntax-table)
  241.   (modify-syntax-entry ?' "w   " html-mode-syntax-table))
  242.  
  243. (defvar html-mode-map nil "")
  244. (if html-mode-map
  245.     ()
  246.   (setq html-mode-map (make-sparse-keymap))
  247.   (define-key html-mode-map "\t" 'tab-to-tab-stop)
  248.   (define-key html-mode-map "\C-ca" 'html-add-address)
  249.   (define-key html-mode-map "\C-cd" 'html-add-definition-list)
  250.   (define-key html-mode-map "\C-ce" 'html-add-definition-entry)
  251.   (define-key html-mode-map "\C-ch" 'html-add-header)
  252.   (define-key html-mode-map "\C-ci" 'html-add-list-or-menu-item)
  253.   (define-key html-mode-map "\C-cl" 'html-add-normal-link)
  254.   (define-key html-mode-map "\C-cm" 'html-add-menu)
  255.   (define-key html-mode-map "\C-cp" 'html-add-paragraph-separator)
  256.   (define-key html-mode-map "\C-cs" 'html-add-list)
  257.   (define-key html-mode-map "\C-ct" 'html-add-title)
  258.   (define-key html-mode-map "\C-cx" 'html-add-plaintext)
  259.   (define-key html-mode-map "<" 'html-less-than)
  260.   (define-key html-mode-map ">" 'html-greater-than)
  261.   (define-key html-mode-map "&" 'html-ampersand)
  262.   (define-key html-mode-map "\C-c<" 'html-real-less-than)
  263.   (define-key html-mode-map "\C-c>" 'html-real-greater-than)
  264.   (define-key html-mode-map "\C-c&" 'html-real-ampersand)
  265.   (define-key html-mode-map "\C-c\C-rl" 'html-add-normal-link-to-region)
  266.   (define-key html-mode-map "\C-c\C-rr" 'html-add-reference-to-region)
  267. )
  268.  
  269. ;;; --------------------------- buffer-local vars ----------------------------
  270.  
  271. (defvar html-link-counter-default 0)
  272. (defvar html-link-counter nil)
  273. (make-variable-buffer-local 'html-link-counter)
  274. (setq-default html-link-counter html-link-counter-default)
  275.  
  276. ;;; ------------------------------ highlighting ------------------------------
  277.  
  278. (defvar html-running-lemacs (string-match "Lucid" emacs-version)
  279.   "Non-nil if running Lucid Emacs.")
  280.  
  281. (defvar html-running-epoch (boundp 'epoch::version)
  282.   "Non-nil if running Epoch.")
  283.  
  284. (if (and html-running-epoch html-use-highlighting)
  285.     (progn
  286.       (defvar html-deemphasize-style (make-style))
  287.       (set-style-foreground html-deemphasize-style html-deemphasize-color)
  288.       (defvar html-emphasize-style (make-style))
  289.       (set-style-foreground html-emphasize-style html-emphasize-color)))
  290.  
  291. (if (and html-running-lemacs html-use-highlighting)
  292.     (progn
  293.       (defvar html-deemphasize-style (make-face 'html-deemphasize-face))
  294.       (set-face-foreground html-deemphasize-style html-deemphasize-color)
  295.       (defvar html-emphasize-style (make-face 'html-emphasize-face))
  296.       (set-face-foreground html-emphasize-style html-emphasize-color)))
  297.  
  298. (if html-use-highlighting
  299.     (progn
  300.       (if html-running-lemacs
  301.           (defun html-add-zone (start end style)
  302.             "Add a Lucid Emacs extent from START to END with STYLE."
  303.             (let ((extent (make-extent start end)))
  304.               (set-extent-face extent style)
  305.               (set-extent-data extent 'html-mode))))
  306.       (if html-running-epoch
  307.           (defun html-add-zone (start end style)
  308.             "Add an Epoch zone from START to END with STYLE."
  309.             (let ((zone (add-zone start end style)))
  310.               (epoch::set-zone-data zone 'html-mode))))))
  311.  
  312. (defun html-maybe-deemphasize-region (start end)
  313.   "Maybe deemphasize a region of text.  Region is from START to END."
  314.   (and (or html-running-epoch html-running-lemacs)
  315.        html-use-highlighting
  316.        (html-add-zone start end html-deemphasize-style)))
  317.  
  318. ;;; ----------------------------- link commands ------------------------------
  319.  
  320. (defun html-add-link (link-object)
  321.   "Add a link."
  322.   (let ((start (point)))
  323.     (setq html-link-counter (1+ html-link-counter))
  324.     (if html-quote-hrefs
  325.         (insert "<A NAME=" (format "%d" html-link-counter) 
  326.                 " HREF=\"" link-object "\">")
  327.       (insert "<A NAME=" (format "%d" html-link-counter) 
  328.               " HREF=" link-object ">"))
  329.     (html-maybe-deemphasize-region start (1- (point)))
  330.     (insert "</A>")
  331.     (push-mark)
  332.     (forward-char -4)
  333.     (html-maybe-deemphasize-region (1+ (point)) (+ (point) 4))))
  334.  
  335. (defun html-add-normal-link (link)
  336.   "Make a link.  There is no completion of any kind yet."
  337.   (interactive "sLink to: ")
  338.   (html-add-link link))
  339.  
  340. (defun html-add-normal-link-to-region (link start end)
  341.   "Make a link that applies to the current region.  Again,
  342. no completion."
  343.   (interactive "sLink to: \nr")
  344.   (save-excursion
  345.     (goto-char end)
  346.     (save-excursion
  347.       (goto-char start)
  348.       (setq html-link-counter (1+ html-link-counter))
  349.       (if html-quote-hrefs
  350.           (insert "<A NAME=" (format "%d" html-link-counter)
  351.                   " HREF=\"" link "\">")
  352.         (insert "<A NAME=" (format "%d" html-link-counter)
  353.                 " HREF=" link ">"))
  354.       (html-maybe-deemphasize-region start (1- (point))))
  355.     (insert "</A>")
  356.     (html-maybe-deemphasize-region (- (point) 3) (point))))
  357.  
  358. (defun html-add-reference-to-region (name start end)
  359.   "Add a reference point (a link with no reference of its own) to
  360. the current region."
  361.   (interactive "sName (or RET for numeric): \nr")
  362.   (and (string= name "")
  363.        (progn
  364.          (setq html-link-counter (1+ html-link-counter))
  365.          (setq name (format "%d" html-link-counter))))
  366.   (save-excursion
  367.     (goto-char end)
  368.     (save-excursion
  369.       (goto-char start)
  370.       (insert "<A NAME=" name ">")
  371.       (html-maybe-deemphasize-region start (1- (point))))
  372.     (insert "</A>")
  373.     (html-maybe-deemphasize-region (- (point) 3) (point))))
  374.  
  375. ;;; --------------------------- document elements ----------------------------
  376.  
  377. (defun html-add-title (title)
  378.   "Add or modify a title."
  379.   (interactive "sTitle: ")
  380.   (save-excursion
  381.     (goto-char (point-min))
  382.     (if (and (looking-at "<TITLE>")
  383.              (save-excursion
  384.                (forward-char 7)
  385.                (re-search-forward "[^<]*" 
  386.                                   (save-excursion (end-of-line) (point)) 
  387.                                   t)))
  388.         ;; Plop the new title in its place.
  389.         (replace-match title t)
  390.       (insert "<TITLE>")
  391.       (html-maybe-deemphasize-region (point-min) (1- (point)))
  392.       (insert title)
  393.       (insert "</TITLE>")
  394.       (html-maybe-deemphasize-region (- (point) 7) (point))
  395.       (insert "\n"))))
  396.  
  397. (defun html-add-header (size header)
  398.   "Add a header."
  399.   (interactive "sSize (1 or 2): \nsHeader: ")
  400.   (let ((start (point)))
  401.     (insert "<H" size ">")
  402.     (html-maybe-deemphasize-region start (1- (point)))
  403.     (insert header)
  404.     (setq start (point))
  405.     (insert "</H" size ">\n")
  406.     (html-maybe-deemphasize-region (1+ start) (1- (point)))))
  407.  
  408. (defun html-add-paragraph-separator ()
  409.   "Add a paragraph separator."
  410.   (interactive)
  411.   (let ((start (point)))
  412.     (insert "  <P>\n\n")
  413.     (html-maybe-deemphasize-region (+ start 2) (- (point) 2))))
  414.  
  415. (defun html-add-definition-list ()
  416.   "Add a definition list."
  417.   (interactive)
  418.   (let ((start (point)))
  419.     (insert "<DL>\n")
  420.     (html-maybe-deemphasize-region start (1- (point)))
  421.     (insert "<DT> ")
  422.     ;; Point goes right there.
  423.     (save-excursion
  424.       (insert "\n<DD> \n")
  425.       (setq start (point))
  426.       (insert "</DL>\n")
  427.       (html-maybe-deemphasize-region start (1- (point)))
  428.       ;; Mark goes after list -- this doesn't work.
  429.       (push-mark))))
  430.  
  431. (defun html-add-definition-entry ()
  432.   "Add a definition entry.  Assume we're at the end of a previous
  433. entry."
  434.   (interactive)
  435.   (let ((start (point)))
  436.     (insert "\n<DT> ")
  437.     (save-excursion
  438.       (insert "\n<DD> "))))
  439.  
  440. (defun html-add-plaintext ()
  441.   "Add plaintext."
  442.   (interactive)
  443.   (let ((start (point)))
  444.     (insert "<XMP>\n")
  445.     (html-maybe-deemphasize-region start (1- (point)))
  446.     (save-excursion
  447.       (insert "\n")
  448.       (setq start (point))
  449.       (insert "</XMP>\n")
  450.       (html-maybe-deemphasize-region start (1- (point)))
  451.       ;; This doesn't work.
  452.       (push-mark))))
  453.  
  454. (defun html-add-list-internal (type)
  455.   (let ((start (point)))
  456.     (insert "<" type ">\n")
  457.     (html-maybe-deemphasize-region start (1- (point)))
  458.     (insert "<LI> ")
  459.     ;; Point goes right there.
  460.     (save-excursion
  461.       (insert "\n")
  462.       (setq start (point))
  463.       (insert "</" type ">\n")
  464.       (html-maybe-deemphasize-region start (1- (point)))
  465.       ;; Mark goes after list -- this doesn't work.
  466.       (push-mark))))
  467.  
  468. (defun html-add-list ()
  469.   "Add a list."
  470.   (interactive)
  471.   (html-add-list-internal "UL"))
  472.  
  473. ;; Is this correct?  Viola doesn't seem to do anything with it.
  474. (defun html-add-menu ()
  475.   "Add a menu."
  476.   (interactive)
  477.   (html-add-list-internal "MENU"))
  478.  
  479. (defun html-add-list-or-menu-item ()
  480.   "Add a list or menu item.  Assume we're at the end of the
  481. last item."
  482.   (interactive)
  483.   (let ((start (point)))
  484.     (insert "\n<LI> ")))
  485.  
  486. (defun html-add-address ()
  487.   "Add an address."
  488.   (interactive)
  489.   (let ((start (point)))
  490.     (insert "<ADDRESS> ")
  491.     (html-maybe-deemphasize-region start (1- (point)))
  492.     (save-excursion
  493.       (setq start (point))
  494.       (insert "  </ADDRESS>\n")
  495.       (html-maybe-deemphasize-region (+ start 2) (1- (point)))
  496.       ;; Obviously this doesn't work here, so I don't
  497.       ;; see why you're being an idiot and still doing it
  498.       ;; like this....
  499.       (push-mark))))
  500.  
  501. (defun html-less-than ()
  502.   (interactive)
  503.   (insert "<"))
  504.  
  505. (defun html-greater-than ()
  506.   (interactive)
  507.   (insert ">"))
  508.  
  509. (defun html-ampersand ()
  510.   (interactive)
  511.   (insert "&"))
  512.  
  513. (defun html-real-less-than ()
  514.   (interactive)
  515.   (insert "<"))
  516.  
  517. (defun html-real-greater-than ()
  518.   (interactive)
  519.   (insert ">"))
  520.  
  521. (defun html-real-ampersand ()
  522.   (interactive)
  523.   (insert "&"))
  524.  
  525. ;;; ----------------------- html-reorder-numeric-names -----------------------
  526.  
  527. (defun replace-string-in-buffer (start end newstring)
  528.   (save-excursion
  529.     (goto-char start)
  530.     (delete-char (1+ (- end start)))
  531.     (insert newstring)))
  532.  
  533. (defun html-reorder-numeric-names (&optional reorder-non-numeric)
  534.   "Reorder the NAME fields for links in the current buffer.  The
  535. new ordering starts at 1 and increases monotonically through the buffer.
  536. If optional arg REORDER-NON-NUMERIC is non-nil, then non-numeric NAME's
  537. will also be numbered, else they won't.
  538.  
  539. Beware that doing this will possibly mess up references to specific
  540. links within this document (e.g., HREF=\"#12\") or by other documents.
  541. This command is mainly intended for use during the initial creation
  542. stage of a document, especially when this creation involves cutting
  543. and pasting from other documents (which it shouldn't, since this is
  544. hypertext :-)."
  545.   (interactive)
  546.   (save-excursion
  547.     (goto-char (point-min))
  548.     (setq html-link-counter 0)
  549.     (while (re-search-forward "<A[ \t\n]+NAME=" (point-max) t)
  550.       (let* ((start (match-end 0))
  551.              (end (save-excursion
  552.                     (re-search-forward "[ \t\n>]" 
  553.                                        (point-max) 
  554.                                        t)
  555.                     (match-beginning 0)))
  556.              (subst (buffer-substring start end)))
  557.         (and subst
  558.              ;; Proceed only if we reorder non-numeric links or
  559.              ;; this is in fact numeric (i.e. > 0).
  560.              (or reorder-non-numeric (> (string-to-int subst) 0))
  561.              (progn
  562.                (setq html-link-counter (1+ html-link-counter))
  563.                (replace-string-in-buffer start (1- end)
  564.                 (format "%d" html-link-counter))))))))
  565.  
  566. ;;; --------------------------- html-quotify-hrefs ---------------------------
  567.  
  568. (defun html-quotify-hrefs ()
  569.   "Insert quotes around all HREF attribute value literals.
  570.  
  571. This remedies the problem with old HTML files that can't be processed
  572. by SGML parsers. That is, changes <A HREF=foo> to <A HREF=\"foo\">."
  573.   (interactive)
  574.   (save-excursion
  575.     (goto-char (point-min))
  576.     (while 
  577.         (re-search-forward
  578.          "<[aA][ \t\n]+\\([nN][aA][mM][eE]=[a-zA-Z0-9]+[ \t\n]+\\)?[hH][rR][eE][fF]="
  579.          (point-max)
  580.          t)
  581.       (cond
  582.        ((null (looking-at "\""))
  583.         (insert "\"")
  584.         (re-search-forward "[ \t\n>]" (point-max) t)
  585.         (forward-char -1)
  586.         (insert "\""))))))
  587.  
  588. ;;; ------------------------------- html-mode --------------------------------
  589.  
  590. (defun html-mode ()
  591.   "Major mode for editing HTML hypertext documents.  Special commands:\\{html-mode-map}
  592. Turning on html-mode calls the value of the variable html-mode-hook,
  593. if that value is non-nil.
  594.  
  595. More extensive documentation is available in the file 'html-mode.el'.
  596. The latest (possibly unstable) version of this file will always be available
  597. on anonymous FTP server ftp.ncsa.uiuc.edu in /outgoing/marca."
  598.   (interactive)
  599.   (kill-all-local-variables)
  600.   (use-local-map html-mode-map)
  601.   (setq mode-name "HTML")
  602.   (setq major-mode 'html-mode)
  603.   (setq local-abbrev-table html-mode-abbrev-table)
  604.   (set-syntax-table html-mode-syntax-table)
  605.   (run-hooks 'html-mode-hook))
  606.  
  607. ;;; ------------------------------- our hooks --------------------------------
  608.  
  609. (defun html-html-mode-hook ()
  610.   "Hook called from html-mode-hooks.  Set html-link-counter to 
  611. the highest link value in the document (the next link created will
  612. be one greater than that) to insure unique (numeric) link ID's.
  613. Also run htlm-quotify-hrefs if html-quotify-hrefs-on-find is non-nil."
  614.   (save-excursion
  615.     (goto-char (point-min))
  616.     (while (re-search-forward "<A[ \t\n]+NAME=" (point-max) t)
  617.       (let* ((start (match-end 0))
  618.              (end (save-excursion
  619.                     (re-search-forward "[ \t\n>]"
  620.                                        (point-max)
  621.                                        t)
  622.                     (match-beginning 0)))
  623.              (subst (buffer-substring start end)))
  624.         (and subst
  625.              ;; Safe to do compare, since string-to-int passed a non-number
  626.              ;; returns 0.
  627.              (> (string-to-int subst) html-link-counter)
  628.              (setq html-link-counter (string-to-int subst))))))
  629.   ;; Quotify existing HREF's if html-quotify-hrefs-on-find is non-nil.
  630.   (and html-quotify-hrefs-on-find (html-quotify-hrefs)))
  631.  
  632. ;;; ------------------------------- hook setup -------------------------------
  633.  
  634. ;; Author: Daniel LaLiberte (liberte@cs.uiuc.edu).
  635. (defun html-postpend-unique-hook (hook-var hook-function)
  636.   "Postpend HOOK-VAR with HOOK-FUNCTION, if it is not already an element.
  637. hook-var's value may be a single function or a list of functions."
  638.   (if (boundp hook-var)
  639.       (let ((value (symbol-value hook-var)))
  640.         (if (and (listp value) (not (eq (car value) 'lambda)))
  641.             (and (not (memq hook-function value))
  642.                  (set hook-var (append value (list hook-function))))
  643.           (and (not (eq hook-function value))
  644.                (set hook-var (append value (list hook-function))))))
  645.     (set hook-var (list hook-function))))
  646.  
  647. (html-postpend-unique-hook 'html-mode-hook 'html-html-mode-hook)
  648.  
  649. ;;; ------------------------------ final setup -------------------------------
  650.  
  651. (or (assoc "\\.html$" auto-mode-alist)
  652.     (setq auto-mode-alist (cons '("\\.html$" . html-mode) auto-mode-alist)))
  653.