Browse Source

Implement color formatting of code examples during HTML export.

Carsten Dominik 17 years ago
parent
commit
7436274350
3 changed files with 131 additions and 5 deletions
  1. 34 3
      ORGWEBPAGE/Changes.org
  2. 81 0
      lisp/org-exp.el
  3. 16 2
      lisp/org.el

+ 34 - 3
ORGWEBPAGE/Changes.org

@@ -8,13 +8,16 @@
 #+LINK_UP: index.html
 #+LINK_UP: index.html
 #+LINK_HOME: http://orgmode.org
 #+LINK_HOME: http://orgmode.org
 
 
-* Version 6.02a
+* Version 6.03
+
 ** Details
 ** Details
-*** Clock task history
+
+*** Clock task history, and moving entries with the running clock
+
     Org now remembers the last 5 tasks that you clocked into, to
     Org now remembers the last 5 tasks that you clocked into, to
     make it easier to clock back into a task after interrupting
     make it easier to clock back into a task after interrupting
     it for another task.
     it for another task.
-    - `C-u C-u C-c C-x C-i' (or `C-u C-u I' from the agenda) wil
+    - `C-u C-u C-c C-x C-i' (or `C-u C-u I' from the agenda) will
       clock into that task and mark it as current default task.
       clock into that task and mark it as current default task.
     - `C-u C-c C-x C-i' (or `C-u I' from the agenda) will offer a
     - `C-u C-c C-x C-i' (or `C-u I' from the agenda) will offer a
       list of recently clocked tasks, including the default task,
       list of recently clocked tasks, including the default task,
@@ -23,6 +26,34 @@
       being clocked. `1',... selects a recent task.  When you
       being clocked. `1',... selects a recent task.  When you
       select a task, you will be clocked into it.
       select a task, you will be clocked into it.
 
 
+    When moving an entry using structure editing commands,
+    archiving commands, or the special subtree cut-and-paste
+    commands =C-c C-x C-w= and =C-c C-x C-y=, the running clock
+    marker and all clock history markers will be moved with the
+    subtree.  Now you can start a clock in a remember buffer and
+    keep the clock running while filing the note away.  See also
+    the variable `org-remember-clock-out-on-exit'.
+
+*** Fontified code examples in HTML export
+
+    You can now get code examples fontified like they would be
+    fontified in an emacs buffer, and export the result to HTML.
+    To do so, wrap the code examples into the following
+    structure:
+
+    : #+BEGIN_SRC emacs-lisp
+    : (defun org-xor (a b)
+    :   "Exclusive or."
+    :   (if a (not b) b))
+    : #+END_SRC
+
+    The string after the BEGIN_SRC is the name of the major emacs
+    mode that should be used to fontify the code example.
+
+    Currently this works only for HTML export, and requires the
+    /htmlize.el/ package.  For other backends, such structures are
+    exported as EXAMPLE.
+
 * Version 6.02
 * Version 6.02
 
 
 ** Overview
 ** Overview

+ 81 - 0
lisp/org-exp.el

@@ -1198,6 +1198,9 @@ on this string to produce the exported version."
       (let ((org-inhibit-startup t)) (org-mode))
       (let ((org-inhibit-startup t)) (org-mode))
       (untabify (point-min) (point-max))
       (untabify (point-min) (point-max))
 
 
+      ;; Handle source code snippets
+      (org-export-replace-src-segments)
+
       ;; Get rid of drawers
       ;; Get rid of drawers
       (unless (eq t exp-drawers)
       (unless (eq t exp-drawers)
 	(goto-char (point-min))
 	(goto-char (point-min))
@@ -1317,6 +1320,13 @@ on this string to produce the exported version."
 			     '(org-protected t))
 			     '(org-protected t))
 	(goto-char (1+ (match-end 4))))
 	(goto-char (1+ (match-end 4))))
 
 
+      ;; Blockquotes
+      (goto-char (point-min))
+      (while (re-search-forward "^#\\+\\(begin\\|end\\)_\\(block\\)quote\\>.*" nil t)
+	(replace-match (if (equal (downcase (match-string 1)) "end")
+			   "ORG-BLOCKUQUOTE-END" "ORG-BLOCKUQUOTE-START")
+			 t t))
+
       ;; Remove subtrees that are commented
       ;; Remove subtrees that are commented
       (goto-char (point-min))
       (goto-char (point-min))
       (while (re-search-forward re-commented nil t)
       (while (re-search-forward re-commented nil t)
@@ -1557,6 +1567,68 @@ When LEVEL is non-nil, increase section numbers on that level."
 	  (setq string (replace-match "" t nil string))))
 	  (setq string (replace-match "" t nil string))))
     string))
     string))
 
 
+;;; Fontification of code
+;; Currently only for th HTML backend, but who knows....
+(defun org-export-replace-src-segments ()
+  "Replace source code segments with special code for export."
+  (let (lang code trans)
+    (goto-char (point-min))
+    (while (re-search-forward
+	    "^#\\+BEGIN_SRC[ \t]+\\([^ \t\n]+\\)[ \t]*\n\\([^\000]+?\n\\)#\\+END_SRC.*"
+	    nil t)
+      (setq lang (match-string 1) code (match-string 2)
+	    trans (org-export-format-source-code lang code))
+      (replace-match trans t t))))
+
+(defvar htmlp)  ;; dynamically scoped from org-exp.el
+
+(defun org-export-format-source-code (lang code)
+  "Format CODE from language LANG and return it formatted for export.
+Currently, this only does something for HTML export, for all other
+backends, it converts the segment into an EXAMPLE segment."
+  (cond
+   (htmlp
+    ;; We are exporting to HTML
+    (condition-case nil (require 'htmlize) (nil t))
+    (if (not (fboundp 'htmlize-region-for-paste))
+	(progn
+	  ;; we do not have htmlize.el, or an old version of it
+	  (message
+	   "htmlize.el 1.34 or later is needed for source code formatting")
+	  (concat "#+BEGIN_EXAMPLE\n" code
+		  (if (string-match "\n\\'" code) "" "\n")
+		  "#+END_EXAMPLE\n"))
+      ;; ok, we are good to go
+      (save-match-data
+	(let* ((mode (and lang (intern (concat lang "-mode"))))
+	       (org-startup-folded nil)
+	       (htmltext
+		(with-temp-buffer
+		  (insert code)
+		  (if (functionp mode)
+		      (funcall mode)
+		    (fundamental-mode))
+		  (when (eq major-mode 'org-mode)
+		    ;; Free up the protected stuff
+		    (goto-char (point-min))
+		    (while (re-search-forward "^@\\([*#]\\|[ \t]*:\\)" nil t)
+		      (replace-match "\\1"))
+		    (org-mode))
+		  (font-lock-fontify-buffer)
+		  ;; silence the byte-compiler
+		  (when (fboundp 'htmlize-region-for-paste)
+		    ;; transform the region to HTML
+		    (htmlize-region-for-paste (point-min) (point-max))))))
+	  (if (string-match "<pre\\([^>]*\\)>\n?" htmltext)
+	      (setq htmltext (replace-match "<pre class=\"src\">"
+					    t t htmltext)))
+	  (concat "#+BEGIN_HTML\n" htmltext "\n#+END_HTML\n")))))
+   (t
+    ;; This is not HTML, so just make it an example.
+    (concat "#+BEGIN_EXAMPLE\n" code
+	    (if (string-match "\n\\'" code) "" "\n")
+	    "#+END_EXAMPLE\n"))))
+
 ;;; ASCII export
 ;;; ASCII export
 
 
 (defvar org-last-level nil) ; dynamically scoped variable
 (defvar org-last-level nil) ; dynamically scoped variable
@@ -2466,6 +2538,7 @@ lang=\"%s\" xml:lang=\"%s\">
 		(replace-match "\\2\n"))
 		(replace-match "\\2\n"))
 	      (insert line "\n")
 	      (insert line "\n")
 	      (while (and lines
 	      (while (and lines
+			  (not (string-match "^[ \t]*:" (car lines)))
 			  (or (= (length (car lines)) 0)
 			  (or (= (length (car lines)) 0)
 			      (get-text-property 0 'org-protected (car lines))))
 			      (get-text-property 0 'org-protected (car lines))))
 		(insert (pop lines) "\n"))
 		(insert (pop lines) "\n"))
@@ -2477,6 +2550,14 @@ lang=\"%s\" xml:lang=\"%s\">
 	    (insert "\n<hr/>\n")
 	    (insert "\n<hr/>\n")
 	    (throw 'nextline nil))
 	    (throw 'nextline nil))
 
 
+	  ;; Blockquotes
+	  (when (equal "ORG-BLOCKUQUOTE-START" line)
+	    (insert "<blockquote>\n<p>\n")
+	    (throw 'nextline nil))
+	  (when (equal "ORG-BLOCKUQUOTE-END" line)
+	    (insert "</p>\n</blockquote>\n")
+	    (throw 'nextline nil))
+
 	  ;; make targets to anchors
 	  ;; make targets to anchors
 	  (while (string-match "<<<?\\([^<>]*\\)>>>?\\((INVISIBLE)\\)?[ \t]*\n?" line)
 	  (while (string-match "<<<?\\([^<>]*\\)>>>?\\((INVISIBLE)\\)?[ \t]*\n?" line)
 	    (cond
 	    (cond

+ 16 - 2
lisp/org.el

@@ -4036,8 +4036,6 @@ are at least `org-cycle-separator-lines' empty lines before the headeline."
 	    (outline-flag-region b (point-at-eol) flag)
 	    (outline-flag-region b (point-at-eol) flag)
 	  (error ":END: line missing"))))))
 	  (error ":END: line missing"))))))
 
 
-
-
 (defun org-subtree-end-visible-p ()
 (defun org-subtree-end-visible-p ()
   "Is the end of the current subtree visible?"
   "Is the end of the current subtree visible?"
   (pos-visible-in-window-p
   (pos-visible-in-window-p
@@ -12732,6 +12730,22 @@ With optional NODE, go directly to that node."
 
 
 ;;; Generally useful functions
 ;;; Generally useful functions
 
 
+(defun org-display-warning (message) ;; Copied from Emacs-Muse
+  "Display the given MESSAGE as a warning."
+  (if (fboundp 'display-warning)
+      (display-warning 'org message
+                       (if (featurep 'xemacs)
+                           'warning
+                         :warning))
+    (let ((buf (get-buffer-create "*Org warnings*")))
+      (with-current-buffer buf
+        (goto-char (point-max))
+        (insert "Warning (Org): " message)
+        (unless (bolp)
+          (newline)))
+      (display-buffer buf)
+      (sit-for 0))))
+
 (defun org-plist-delete (plist property)
 (defun org-plist-delete (plist property)
   "Delete PROPERTY from PLIST.
   "Delete PROPERTY from PLIST.
 This is in contrast to merely setting it to 0."
 This is in contrast to merely setting it to 0."