home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #27 / NN_1992_27.iso / spool / gnu / emacs / sources / 818 < prev    next >
Encoding:
Text File  |  1992-11-22  |  24.9 KB  |  679 lines

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