summaryrefslogtreecommitdiffstats
path: root/emacs.d/nxhtml/nxhtml/html-toc.el
diff options
context:
space:
mode:
Diffstat (limited to 'emacs.d/nxhtml/nxhtml/html-toc.el')
-rw-r--r--emacs.d/nxhtml/nxhtml/html-toc.el363
1 files changed, 363 insertions, 0 deletions
diff --git a/emacs.d/nxhtml/nxhtml/html-toc.el b/emacs.d/nxhtml/nxhtml/html-toc.el
new file mode 100644
index 0000000..866b43f
--- /dev/null
+++ b/emacs.d/nxhtml/nxhtml/html-toc.el
@@ -0,0 +1,363 @@
+;;; html-toc.el --- Building and updating TOC for a site
+;;
+;; Author: Lennart Borgman (lennart O borgman A gmail O com)
+;; Created: Wed Feb 01 14:40:13 2006
+(defconst html-toc:version "0.4");; Version:
+;; Last-Updated: Tue Apr 10 04:09:29 2007 (7200 +0200)
+;; Keywords:
+;; Compatibility:
+;;
+;; Features that might be required by this library:
+;;
+;; None
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;; Create table of contents for a static web site. See
+;; `html-toc-write-toc-file' and `html-toc-write-frames-file' for
+;; more info.
+;;
+;; To use this you can add (require 'html-toc) to your .emacs.
+;;
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Change log:
+;;
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Code:
+
+(eval-when-compile (require 'cl))
+(eval-when-compile (add-to-list 'load-path default-directory load-path))
+(eval-when-compile (require 'fupd nil t))
+;;(require 'html-move)
+(eval-when-compile (require 'html-site nil t))
+;;(require 'dom)
+(require 'xml)
+
+(defconst html-toc-mark-begin "<!-- html-toc START -->")
+(defconst html-toc-mark-middle "<!-- html-toc MIDDLE -->")
+(defconst html-toc-mark-end "<!-- html-toc END -->")
+
+(defun html-toc-create-pages-file ()
+ "Write a list of pages to be used for table of contents.
+Return the file name."
+ (interactive)
+ (html-site-current-ensure-site-defined)
+ (let* (
+ (site-dir (html-site-current-site-dir))
+ (page-file (html-site-current-page-list))
+ (page-file-dir (file-name-directory page-file))
+ (page-file-exists (file-exists-p page-file))
+ (sub-files (html-site-get-sub-files
+ site-dir
+ html-site-files-re))
+ (pages-text)
+ )
+ (setq sub-files
+ (sort (mapcar (lambda (full-file)
+ (assert (file-exists-p full-file))
+ (file-relative-name full-file page-file-dir))
+ sub-files)
+ 'string<))
+ ;;(setq sub-files (delete html-toc-file-default-name sub-files))
+ (with-temp-buffer
+ (let ((this-level)
+ (dir-title)
+ (title)
+ (full-file))
+ (dolist (file sub-files)
+ (setq full-file (expand-file-name file page-file-dir))
+ (setq dir-title (file-name-nondirectory
+ (substring (file-name-directory full-file) 0 -1)))
+ (setq title (html-toc-get-title full-file))
+ (setq this-level 0)
+ (mapc (lambda (c) (when (eq c ?/) (setq this-level (1+ this-level)))) file)
+ (insert (format "%s ### %s ### %s\n" this-level title file))))
+ (setq pages-text (buffer-string)))
+ (with-current-buffer (find-file page-file)
+ (if (string= pages-text (buffer-string))
+ (message "List of pages is already the default list")
+ (if (= 0 (length (buffer-string)))
+ (progn
+ (insert pages-text)
+ (save-buffer)
+ )
+ (if (y-or-n-p "Replace old list of pages? ")
+ (progn
+ (erase-buffer)
+ (insert pages-text)
+ (save-buffer)
+ )
+ (message "Keeping old list of pages.")))))
+ page-file))
+(defun html-toc-dir ()
+ (let* ((this-file (if load-file-name
+ load-file-name
+ buffer-file-name))
+ (this-dir (file-name-directory this-file))
+ )
+ (expand-file-name "html-toc" this-dir)))
+
+;;;###autoload
+(defgroup html-toc nil
+ "Customization group for html-toc."
+ :group 'nxhtml)
+
+(defcustom html-toc-template-file
+ (expand-file-name "html-toc-template.html" (html-toc-dir))
+ "Template file for table of contents file."
+ :type 'file
+ :group 'html-toc)
+
+
+(defun html-toc-write-toc-file ()
+ "Write a table of contents for a web site.
+Build the table of content from the information in
+`html-site-current-page-list'. Write it to the file
+`html-site-current-toc-file' and return that file name.
+
+When viewed in a browser the table of contents can be
+expanded/collapsed (if JavaScript is allowed)."
+ (interactive)
+ (html-site-current-ensure-site-defined)
+ (let* ((toc-file (html-site-current-toc-file))
+ (page-file (html-site-current-page-list))
+ page-lines
+ toc)
+ (unless (< 0 (length toc-file))
+ (error "There is no name for the table of content file in site \"%s\""
+ html-site-current))
+ (unless (< 0 (length page-file))
+ (error "There is no name for the pages file in site \"%s\""
+ html-site-current))
+ (with-temp-buffer
+ (insert-file-contents page-file)
+ (goto-char (point-min))
+ (while (not (eobp))
+ (let* ((line (buffer-substring (point) (line-end-position)))
+ (line-parts (split-string line "\\s-+###\\s-+")))
+ (setq page-lines (cons line-parts page-lines)))
+ (forward-line)))
+ (setq page-lines (reverse page-lines))
+ (with-temp-buffer
+ (html-toc-insert-toc page-lines toc-file)
+ (setq toc (buffer-substring-no-properties (point-min) (point-max))))
+ (with-current-buffer (find-file-noselect toc-file)
+ (erase-buffer)
+ (insert-file-contents-literally html-toc-template-file)
+ (let (toc-start)
+ (while (search-forward "%%TOC%%" nil t)
+ (unless toc-start
+ (setq toc-start (match-beginning 0)))
+ (replace-match toc t t))
+ (forward-line) ;; for indentation
+ (indent-region toc-start (point-marker)))
+ (goto-char (point-min))
+ (save-buffer))
+ toc-file))
+
+
+(defun html-toc-insert-toc (page-lines toc-file)
+ (let* ((curr-level)
+ (min-level 100)
+ div-levels
+ (site-directory (html-site-current-site-dir))
+ (toc-rel-file (file-relative-name toc-file site-directory)))
+ (dolist (line page-lines)
+ (let ((level (string-to-number (nth 0 line))))
+ (when (< level min-level)
+ (setq min-level level))))
+ (setq curr-level min-level)
+ (while page-lines
+ (let* ((line (car page-lines))
+ (file (nth 2 line))
+ (title (nth 1 line))
+ (this-level (string-to-number (nth 0 line)))
+ (next-level (progn
+ ;; Note:
+ (setq page-lines (cdr page-lines))
+ (let ((next-line (car page-lines)))
+ (when next-line
+ (string-to-number (nth 0 next-line))))))
+ (full-file (expand-file-name file site-directory))
+ (dir-title (file-name-nondirectory
+ (substring (file-name-directory full-file) 0 -1))))
+ ;;(insert "<!-- " (format "%s, %s, %s" curr-level this-level div-levels) " -->\n")
+ ;; Don't insert a link to the toc file
+ (unless (string= toc-rel-file file)
+ ;; If there are childs then insert a <div> before them. Save
+ ;; the level so we can close the div-tag later.
+ (when (< curr-level this-level)
+ ;; Save level so we can find the end of the <div>.
+ (setq div-levels (cons this-level div-levels))
+ (insert "<div class=\"html-toc-childs\">\n"))
+ ;; Close div-tags if this level is lower when the previous.
+ (when (> curr-level this-level)
+ (while (and div-levels
+ (> (car div-levels) this-level))
+ (insert "</div>\n")
+ (setq div-levels (cdr div-levels))))
+ (setq curr-level this-level)
+ (insert "<div class=\"html-toc-link\">"
+ "<span style=\"display:table-cell; width:15em; background-color:yellow;\">"
+ "<a style=\"padding-left:" (number-to-string (1+ (- curr-level min-level))) "em;\" "
+ (format "href=\"%s\">%s</a>" file title)
+ "</span>")
+ (when (and next-level (> next-level this-level))
+ (insert "<span onclick=\"html_toc_hs(this)\" class=\"html-toc-hs\""
+ " style=\"display:table-cell; background-color:white;\">HS</span>"))
+ (insert "</div>"
+ "\n")
+ )))
+ (while div-levels
+ (insert "</div>\n")
+ (setq div-levels (cdr div-levels)))))
+
+(defun html-toc-get-title (file)
+ (save-excursion
+ (with-temp-buffer
+ (insert-file-contents file nil 0 1000)
+ (goto-char (point-min))
+ (when (search-forward-regexp "<title>\\(.*\\)</title>" nil t)
+ (match-string 1)))))
+
+(defun html-toc-parse-toc (toc-str)
+ (let ((nodes))
+ (with-temp-buffer
+ (insert toc-str)
+ (setq nodes (xml-parse-region (point-min) (point-max))))
+ ))
+
+(defun html-toc-get-hrefs (nodes)
+ (let ((atags (html-toc-get-atags nodes)))
+ (mapcar (lambda (atag)
+ (xml-get-attribute atag 'href))
+ atags)))
+(defun html-toc-get-atags (nodes)
+ (let ((atags))
+ (dolist (node nodes)
+ (when (listp node)
+ (setq atags (append atags (xml-get-children node 'a)))
+ (setq atags (append atags (html-toc-get-atags (xml-node-children node))))))
+ atags))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Frames and viewing
+(defcustom html-toc-frames-default-name "html-toc-frames.html"
+ "Default file name sans directory for frames file."
+ :type 'string
+ :group 'html-toc)
+
+(defvar html-toc-frames-contents
+ "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>
+<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">
+<html xmlns=\"http://www.w3.org/1999/xhtml\">
+ <head>
+ <title>Frames for html-toc</title>
+ </head>
+ <frameset cols=\"20%, 80%\">
+ <frame name=\"html-toc-TOC\" src=\"%%TOCFILE%%\"/>
+ <frame name=\"html-toc-Document\" />
+ <noframes>
+ <body>
+ Html frame support required
+ </body>
+ </noframes>
+ </frameset>
+</html>
+")
+
+(defun html-toc-browse-frames-file ()
+ "View frames file written by `html-toc-write-frames-file'."
+ (interactive)
+ (html-site-current-ensure-site-defined)
+ (let ((frames-file (html-site-current-frames-file)))
+ (unless (< 0 (length frames-file))
+ (error "There is no frames file set for site \"%s\"" html-site-current))
+ ;;(message "frames-file=%s" frames-file)(sit-for 4)
+ (unless (file-exists-p frames-file)
+ (html-toc-write-frames-file))
+ (browse-url-of-file frames-file)))
+
+;; (defun html-toc-frames-file-name ()
+;; "Return name of file written by `html-toc-write-frames-file'."
+;; (html-toc-get-site)
+;; (expand-file-name html-toc-frames-default-name html-move-site-directory))
+
+(defun html-toc-write-frames-file ()
+ "Write a frames file.
+This frames file should load the table of contents build by
+`html-toc-write-toc-file' in one frame and shows the documents in
+another.
+
+The contents of the frames file is defined by
+`html-toc-frames-contents'.
+
+Returns the file name of the written or existing frames file.
+
+You may also want to look at `html-wtoc-write-pages-with-toc'."
+ (interactive)
+ ;;(html-toc-get-site)
+ (html-site-current-ensure-site-defined)
+ (let* ((frames-file (html-site-current-frames-file))
+ (frames-cont html-toc-frames-contents)
+ (toc-file (html-toc-write-toc-file))
+ toc-file-relative)
+ (when toc-file
+ (setq toc-file-relative (file-relative-name
+ toc-file
+ (file-name-directory frames-file)))
+ (save-match-data
+ (unless (string-match "%%TOCFILE%%" frames-cont)
+ (error "Can't find %%TOCFILE%% in html-toc-frames-contents"))
+ (setq frames-cont (replace-match toc-file-relative t t frames-cont)))
+ (with-current-buffer (find-file-noselect frames-file)
+ (erase-buffer)
+ (insert frames-cont)
+ (save-buffer))
+ frames-file)))
+
+;;;###autoload
+(defconst html-toc-menu-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map [html-toc-browse-frames-file]
+ (list 'menu-item "Browse Frames File" 'html-toc-browse-frames-file))
+ (define-key map [html-toc-write-frames-file]
+ (list 'menu-item "Write Frames File" 'html-toc-write-frames-file))
+ (define-key map [html-toc-write-toc-file]
+ (list 'menu-item "Write TOC File for Frames" 'html-toc-write-toc-file))
+ (define-key map [html-toc-sep1] (list 'menu-item "--"))
+ (define-key map [html-toc-edit-pages-file]
+ (list 'menu-item "Edit List of Pages for TOC" 'html-site-edit-pages-file))
+ (define-key map [html-toc-create-pages-file]
+ (list 'menu-item "Write List of Pages for TOC" 'html-toc-create-pages-file))
+ map))
+
+
+
+(provide 'html-toc)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; html-toc.el ends here