Browse Source

Much better integration of org-info.js.

Carsten Dominik 17 years ago
parent
commit
bd80cd71d2
6 changed files with 246 additions and 71 deletions
  1. 12 0
      ChangeLog
  2. 1 0
      Makefile
  3. 26 0
      ORGWEBPAGE/Changes.org
  4. 53 70
      lisp/org-exp.el
  5. 152 0
      lisp/org-infojs.el
  6. 2 1
      lisp/org.el

+ 12 - 0
ChangeLog

@@ -1,5 +1,17 @@
+2008-04-07  Carsten Dominik  <dominik@science.uva.nl>
+
+	* lisp/org-exp.el (org-export-inbuffer-options-extra): New variable.
+	(org-export-options-filters): New hook.
+	(org-infile-export-plist): Find also the settings keywords in
+	`org-export-inbuffer-options-extra'.
+
+	* lisp/org-infojs.el: New file.
+
 2008-04-06  Carsten Dominik  <dominik@science.uva.nl>
 
+	* lisp/org-exp.el (org-infile-export-plist): Allow multiple
+	#+OPTIONS lines and multiple #+INFOJS_OPT lines.
+
 	* lisp/org-agenda.el (org-agenda-start-with-clockreport-mode): New
 	option.
 	(org-agenda-clockreport-parameter-plist): New option.

+ 1 - 0
Makefile

@@ -75,6 +75,7 @@ LISPF      = 	org.el			\
 		org-bibtex.el		\
 		org-gnus.el		\
 		org-info.el		\
+		org-infojs.el		\
 		org-irc.el		\
 		org-mac-message.el	\
 		org-mhe.el		\

+ 26 - 0
ORGWEBPAGE/Changes.org

@@ -9,6 +9,32 @@
 
 ** Details
 
+*** Support for Sebastian Rose's Javasript org-info.js.
+    This fascinating program allows and Org file (exported to
+    HTML) to be viewed different ways.  There is an Info-like
+    interface where you can jump through the sections of the
+    document with the `n' and `p' keys (and others).  And there
+    is a folding interface where you can fold the document much
+    like you can fold it in org-mode in Emacs.
+
+    To set this up, make sure the script is available in the same
+    location as your HTML file.  Make sure that `org-infojs' is
+    loaded in `org-modules'. Then add a line
+
+    : #+INFOJS_OPT: view:info
+
+    to the buffer, that is all.  The available views are:
+
+    - =info=: like the Info program
+    - =overview=: Folding interface, only top-level headings seen
+      at startup.
+    - =content=: Folding interface, all headlines but no text
+      visible at startup.
+    - =showall=: Entire file visible at startup.
+
+    For details see the documentation provided by Sebastian Rose
+    together with org-info.js.
+
 *** The Org distribution has a new structure
 
     In the distribution files, the lisp files are now located in

+ 53 - 70
lisp/org-exp.el

@@ -414,6 +414,16 @@ Org-mode file."
   :group 'org-export-html
   :type 'string)
 
+(defcustom org-export-html-link-up ""
+  "Where should the \"UP\" link of exported HTML pages lead?" 
+  :group 'org-export-html
+  :type '(string :tag "File or URL"))
+
+(defcustom org-export-html-link-home ""
+  "Where should the \"HOME\" link of exported HTML pages lead?" 
+  :group 'org-export-html
+  :type '(string :tag "File or URL"))
+
 (defcustom org-export-html-style
 "<style type=\"text/css\">
   html {
@@ -463,18 +473,6 @@ you can \"misuse\" it to add arbitrary text to the header."
   :group 'org-export-html
   :type 'string)
 
-(defcustom org-export-html-infojs-setup
-  "<script type=\"text/javascript\" language=\"JavaScript\" src=\"org-info.js\"></script>
-<script type=\"text/javascript\" language=\"JavaScript\">
-/* <![CDATA[ */
-%MANAGER-OPTIONS
-org_html_manager.setup();  // activate after the parameterd are set
-/* ]]> */
-</script>"
-  "The template for the export style additions when org-info.js is used.
-Option settings will replace the %MANAGER-OPTIONS cookie."
-  :group 'org-export-html
-  :type 'string)
 
 (defcustom org-export-html-title-format "<h1 class=\"title\">%s</h1>\n"
   "Format for typesetting the document title in HTML export."
@@ -612,7 +610,9 @@ The text will be inserted into the DESCRIPTION field."
 (defvar org-current-export-dir nil) ; dynamically scoped parameter
 
 (defconst org-export-plist-vars
-  '((:language             . org-export-default-language)
+  '((:link-up              . org-export-html-link-up)
+    (:link-home            . org-export-html-link-home)
+    (:language             . org-export-default-language)
     (:customtime           . org-display-custom-times)
     (:headline-levels      . org-export-headline-levels)
     (:section-numbers      . org-export-with-section-numbers)
@@ -657,6 +657,24 @@ The text will be inserted into the DESCRIPTION field."
       (setq rtn (cons (car e) (cons (symbol-value (cdr e)) rtn))))
     rtn))
 
+(defvar org-export-inbuffer-options-extra nil
+  "List of additional in-buffer options that should be detected.
+Just before export, the buffer is scanned for options like #+TITLE, #+EMAIL,
+etc.  Extensions can add to this list to get their options detected, and they
+can then add a function to `org-export-options-filters' to process these
+options.
+Each element in this list must be a list, with the in-buffer keyword as car,
+and a property (a symbol) as the next element.  All occurences of the
+keyword will be found, the values concatenated with a space character
+in between, and the result stored in the export options property list.")
+
+(defvar org-export-options-filters nil
+  "Functions to be called to finalize the export/publishing options.
+All these options are stored in a property list, and each of the functions
+in this hook gets a chance to modify this property list.  Each function
+must accept the property list as an argument, and must return the (possibly
+modified) list.")
+
 (defun org-infile-export-plist ()
   "Return the property list with file-local settings for export."
   (save-excursion
@@ -664,13 +682,18 @@ The text will be inserted into the DESCRIPTION field."
       (widen)
       (goto-char 0)
       (let ((re (org-make-options-regexp
-		 '("TITLE" "AUTHOR" "DATE" "EMAIL" "TEXT" "OPTIONS" "LANGUAGE"
-		   "INFOJS_UP" "INFOJS_HOME" "INFOJS_OPT")))
-	    p key val text options js-up js-main js-css js-opt)
+		 (append
+		  '("TITLE" "AUTHOR" "DATE" "EMAIL" "TEXT" "OPTIONS" "LANGUAGE"
+		    "LINK_UP" "LINK_HOME")
+		  (mapcar 'car org-export-inbuffer-options-extra))))
+	    p key val text options js-up js-main js-css js-opt a pr)
 	(while (re-search-forward re nil t)
 	  (setq key (org-match-string-no-properties 1)
 		val (org-match-string-no-properties 2))
 	  (cond
+	   ((setq a (assoc key org-export-inbuffer-options-extra))
+	    (setq pr (nth 1 a))
+	    (setq p (plist-put p pr (concat (plist-get p pr) " " val))))
 	   ((string-equal key "TITLE") (setq p (plist-put p :title val)))
 	   ((string-equal key "AUTHOR")(setq p (plist-put p :author val)))
 	   ((string-equal key "EMAIL") (setq p (plist-put p :email val)))
@@ -678,13 +701,12 @@ The text will be inserted into the DESCRIPTION field."
 	   ((string-equal key "LANGUAGE") (setq p (plist-put p :language val)))
 	   ((string-equal key "TEXT")
 	    (setq text (if text (concat text "\n" val) val)))
-	   ((string-equal key "OPTIONS") (setq options val))
-	   ((string-equal key "INFOJS_UP")
-	    (setq p (plist-put p :infojs-up val)))
-	   ((string-equal key "INFOJS_HOME")
-	    (setq p (plist-put p :infojs-home val)))
-	   ((string-equal key "INFOJS_OPT")
-	    (setq p (plist-put p :infojs-opt val)))))
+	   ((string-equal key "OPTIONS")
+	    (setq options (concat options " " val)))
+	   ((string-equal key "LINK_UP")
+	    (setq p (plist-put p :link-up val)))
+	   ((string-equal key "LINK_HOME")
+	    (setq p (plist-put p :link-home val)))))
 	(setq p (plist-put p :text text))
 	(when options
 	  (let ((op '(("H"     . :headline-levels)
@@ -722,52 +744,6 @@ The text will be inserted into the DESCRIPTION field."
 		val)))
     dir))
 
-(defun org-export-html-handle-js-options (exp-plist)
-  "Analyze JavaScript options in INFO-PLIST and modify EXP-PLIST accordingly.
-Both P and PJ are property lists."
-  (let (p1 (s "") p v a1 tmp)
-    (setq p1 (plist-put p1 'TOC (if (not (plist-get exp-plist
-						    :table-of-contents))
-				    "0" "1")))
-    (when (setq v (plist-get exp-plist :infojs-opt))
-      (when (string-match "\\<view:\\(\\S-+\\)" v)
-	(setq tmp (match-string 1 v))
-	(unless (member tmp '("info" "overview" "content" "showall"))
-	  (error "Invalid value \"%s\" for `view' in #+INFOJS_OPT" tmp))
-	(setq p1 (plist-put p1 'VIEW tmp)))
-      (when (string-match "\\<mouse:\\(\\S-+\\)" v)
-	(setq tmp (match-string 1 v))
-	(unless (string-match "^underline$\\|^#[0-9a-fA-F]\\{6\\}" tmp)
-	  (error "Invalid value \"%s\" for `mouse' in #+INFOJS_OPT" tmp))
-	(setq p1 (plist-put p1 'MOUSE_HINT tmp)))
-      (when (string-match "\\<toc:\\(\\S-+\\)" v)
-	(setq p1 (plist-put p1 'TOC
-			    (if (equal (match-string 1 v) "nil") "0" "1"))))
-      (when (string-match "\\<runs:\\([0-9]+\\)" v)
-	(setq p1 (plist-put p1 'MAX_RUNS (match-string 1 v))))
-      (when (string-match "\\<buttons:\\(\\S-+\\)" v)
-	(setq p1 (plist-put p1 'VIEW_BUTTONS
-			    (if (equal (match-string 1 v) "nil") "0" "1")))))
-    (when (setq v (plist-get exp-plist :infojs-up))
-      (setq p1 (plist-put p1 'LINK_UP v)))
-    (when (setq v (plist-get exp-plist :infojs-home))
-      (setq p1 (plist-put p1 'LINK_HOME v)))
-    (while p1
-      (setq p (pop p1) v (pop p1))
-      (push (cons p v) a1))
-    (setq s (mapconcat
-	     (lambda (x) (format "org_html_manager.set(\"%s\", \"%s\");"
-				 (car x) (cdr x)))
-	     a1 "\n"))
-    (when (> (length s) 0)
-      (and (string-match "%MANAGER-OPTIONS" org-export-html-infojs-setup)
-	   (setq s (replace-match s t t org-export-html-infojs-setup))
-	   (setq exp-plist
-		 (plist-put
-		  exp-plist :style
-		  (concat (or (plist-get exp-plist :style) "") "\n" s)))))
-    exp-plist))
-
 ;;;###autoload
 (defun org-export (&optional arg)
   "Export dispatcher for Org-mode."
@@ -2065,7 +2041,7 @@ PUB-DIR is set, use this as the publishing directory."
   (setq-default org-done-keywords org-done-keywords)
   (setq-default org-maybe-keyword-time-regexp org-maybe-keyword-time-regexp)
   (let* ((opt-plist
-	  (org-export-html-handle-js-options
+	  (org-export-process-option-filters
 	   (org-combine-plists (org-default-export-plist)
 			       ext-plist
 			       (org-infile-export-plist))))
@@ -3652,3 +3628,10 @@ The XOXO buffer is named *xoxo-<source buffer name>*"
 (provide 'org-exp)
 
 ;;; org-exp.el ends here
+
+
+(defun org-export-process-option-filters (plist)
+  (let ((functions org-export-options-filters) f)
+    (while (setq f (pop functions))
+      (setq plist (funcall f plist))))
+  plist)

+ 152 - 0
lisp/org-infojs.el

@@ -0,0 +1,152 @@
+;;; org-infojs.el --- Support for org-info.js Javascript in Org HTML export
+
+;; Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+
+;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Keywords: outlines, hypermedia, calendar, wp
+;; Homepage: http://orgmode.org
+;; Version: 6.00pre-2
+;;
+;; This file is part of GNU Emacs.
+;;
+;; GNU Emacs 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 3, or (at your option)
+;; any later version.
+
+;; GNU Emacs 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 GNU Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+
+;; This file implements the support for Sebastian Rose's Javascript
+;; org-info.js to display an org-mode file exported to HTML in an
+;; Info-like way, or using folding similar to the outline structure
+;; org org-mode itself.
+
+;; Documentation for using this module is in the Org manual. The script
+;; itself is documented by Sebastian Rose in a file distributed with
+;; the script.  FIXME: Accurate pointers!
+
+;; Org-mode loads this module by default - if this is not what you want,
+;; configure the variable `org-modules'.
+
+;;; Code:
+
+(require 'org-exp)
+
+(add-to-list 'org-export-inbuffer-options-extra '("INFOJS_OPT" :infojs-opt))
+(add-hook 'org-export-options-filters 'org-infojs-handle-options)
+
+(defgroup org-infojs nil
+  "Options specific for using org-info.js in HTML export of Org-mode files."
+  :tag "Org Export HTML INFOJS"
+  :group 'org-export-html)
+
+(defcustom org-export-html-use-infojs 'when-configured
+  "Should Sebasian Rose's Java Script org-info.js be linked into HTML files?
+This option can be nil or t to never or always use the script.  It can
+also be the symbol `when-configured', meaning that the script will be
+linked into the export file if and only if there is a \"#+INFOJS_OPT:\"
+line in the buffer.  See also the variable `org-infojs-options'."
+  :group 'org-export-html
+  :group 'org-infojs
+  :type '(choice
+	  (const :tag "Never" nil)
+	  (const :tag "When configured in buffer" when-configured)
+	  (const :tag "Always" t)))
+  
+(defconst org-infojs-opts-table
+  '((path PATH "org-info.js")
+    (view VIEW "info")
+    (toc TOC :table-of-contents)
+    (mouse MOUSE_HINT "underline")
+    (runs MAX_RUNS "5")
+    (buttons VIEW_BUTTONS "0")
+    (up LINK_UP :link-up)
+    (home LINK_HOME :link-home))
+  "JavaScript options, long form for script, default values.")
+
+(defcustom org-infojs-options
+  (mapcar (lambda (x) (cons (car x) (nth 2 x)))
+	  org-infojs-opts-table)
+  "Options settings for the INFOJS Javascript.
+Each of the options must have an entry in `org-export-html/infojs-opts-table'.
+The value can either be a string that will be passed to the script, or
+a property.  This property is then assumed to be a property that is defined
+by the Export/Publishing setup of Org."
+  :group 'org-infojs
+  :type
+  '(repeat
+    (cons (symbol :tag "Option")
+	  (choice (symbol :tag "Publishing/Export property")
+		  (string :tag "Value")))))
+
+(defcustom org-infojs-template
+  "<script type=\"text/javascript\" language=\"JavaScript\" src=\"%SCRIPT_PATH\"></script>
+<script type=\"text/javascript\" language=\"JavaScript\">
+/* <![CDATA[ */
+%MANAGER_OPTIONS
+org_html_manager.setup();  // activate after the parameterd are set
+/* ]]> */
+</script>"
+  "The template for the export style additions when org-info.js is used.
+Option settings will replace the %MANAGER-OPTIONS cookie."
+  :group 'org-infojs
+  :type 'string)
+
+(defun org-infojs-handle-options (exp-plist)
+  "Analyze JavaScript options in INFO-PLIST and modify EXP-PLIST accordingly."
+  (if (or (not org-export-html-use-infojs)
+	  (and (eq org-export-html-use-infojs 'when-configured)
+	       (not (plist-get exp-plist :infojs-opt))))
+      ;; We do not want to use the script
+      exp-plist
+    ;; We do want to use the script, set it up
+  (let ((template org-infojs-template)
+	p1 s p v a1 tmp e opt var val table default)
+    (setq v (plist-get exp-plist :infojs-opt)
+	  table org-infojs-opts-table)
+    (while (setq e (pop table))
+      (setq opt (car e) var (nth 1 e)
+	    default (cdr (assoc opt org-infojs-options)))
+      (and (symbolp default) (not (memq default '(t nil)))
+	   (setq default (plist-get exp-plist default)))
+      (if (string-match (format " %s:\\(\\S-+\\)" opt) v)
+	  (setq val (match-string 1 v))
+	(setq val default))
+      (cond
+       ((eq opt 'path)
+	(and (string-match "%SCRIPT_PATH" template)
+	     (setq template (replace-match val t t template))))
+       (t
+	(setq val
+	      (cond
+	       ((or (eq val t) (equal val "t")) "1")
+	       ((or (eq val nil) (equal val "nil")) "0")
+	       ((stringp val) val)
+	       (t (format "%s" val))))
+	(push (cons var val) s))))
+
+    (setq s (mapconcat
+	     (lambda (x) (format "org_html_manager.set(\"%s\", \"%s\");"
+				 (car x) (cdr x)))
+	     s "\n"))
+    (when (and s (> (length s) 0))
+      (and (string-match "%MANAGER_OPTIONS" template)
+	   (setq s (replace-match s t t template))
+	   (setq exp-plist
+		 (plist-put
+		  exp-plist :style
+		  (concat (or (plist-get exp-plist :style) "") "\n" s)))))
+    exp-plist)))
+
+(provide 'org-infojs)

+ 2 - 1
lisp/org.el

@@ -139,7 +139,7 @@ With prefix arg HERE, insert it at point."
   (when (featurep 'org)
     (org-load-modules-maybe 'force)))
 
-(defcustom org-modules '(org-bbdb org-bibtex org-gnus org-info org-irc org-mhe org-rmail org-vm org-wl)
+(defcustom org-modules '(org-bbdb org-bibtex org-gnus org-info org-infojs org-irc org-mhe org-rmail org-vm org-wl)
   "Modules that should always be loaded together with org.el.
 If a description starts with <C>, the file is not part of emacs
 and loading it will require that you have downloaded and properly installed
@@ -159,6 +159,7 @@ to add the symbol `xyz', and the package must have a call to
 	(const :tag "   bibtex:            Links to BibTeX entries" org-bibtex)
 	(const :tag "   gnus:              Links to GNUS folders/messages" org-gnus)
 	(const :tag "   info:              Links to Info nodes" org-info)
+	(const :tag "   infojs:            Set up Sebastian Rose's JavaScript org-info.js" org-infojs)
 	(const :tag "   irc:               Links to IRC/ERC chat sessions" org-irc)
 	(const :tag "   mac-message:       Links to messages in Apple Mail" org-mac-message)
 	(const :tag "   mhe:               Links to MHE folders/messages" org-mhe)