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