Merge branch 'master' of git+ssh://repo.or.cz/srv/git/org-mode

This commit is contained in:
Carsten Dominik 2010-09-16 17:20:02 +02:00
commit a1dc916be6
88 changed files with 6271 additions and 4173 deletions

6
.gitignore vendored
View File

@ -8,23 +8,25 @@
*.bak
*.cp
*.cps
*.diff
*.dvi
*.elc
*.fn
*.fns
*.html
*.info
*.ky
*.kys
*.log
*.patch
*.pdf
*.pg
*.pgs
*.ps
*.toc
*.tp
*.vr
*.vrs
*.dvi
*.ps
orgcard_letter.tex
orgcard.txt
org

View File

@ -1,3 +0,0 @@
(defun org-find-links ()
(let* ((file (buffer-file-name))
(tname (file-truename file)))

View File

@ -147,7 +147,11 @@ LISPF = org.el \
ob-css.el \
ob-gnuplot.el \
ob-octave.el \
ob-screen.el
ob-screen.el \
ob-plantuml.el \
ob-org.el \
ob-js.el \
ob-scheme.el
LISPFILES0 = $(LISPF:%=lisp/%)
LISPFILES = $(LISPFILES0) lisp/org-install.el
@ -166,7 +170,6 @@ SHELL = /bin/sh
# Additional distribution files
DISTFILES_extra= Makefile request-assign-future.txt contrib
DISTFILES_xemacs= xemacs/noutline.el xemacs/ps-print-invisible.el xemacs/README
default: $(ELCFILES) $(ELCBFILES)
@ -205,10 +208,6 @@ install-info: $(INFOFILES)
install-info-debian: $(INFOFILES)
$(INSTALL_INFO) --infodir=$(infodir) $(INFOFILES)
install-noutline: xemacs/noutline.elc
if [ ! -d $(lispdir) ]; then $(MKDIR) $(lispdir); else true; fi ;
$(CP) xemacs/noutline.el xemacs/noutline.elc $(lispdir)
autoloads: lisp/org-install.el
lisp/org-install.el: $(LISPFILES0) Makefile
@ -220,8 +219,6 @@ lisp/org-install.el: $(LISPFILES0) Makefile
--eval '(save-buffer)'
mv org-install.el lisp
xemacs/noutline.elc: xemacs/noutline.el
doc/org: doc/org.texi
(cd doc; $(MAKEINFO) --no-split org.texi -o org)
@ -318,7 +315,6 @@ distfile:
${MAKE} lisp/org-install.el
rm -rf org-$(TAG) org-$(TAG).zip
$(MKDIR) org-$(TAG)
$(MKDIR) org-$(TAG)/xemacs
$(MKDIR) org-$(TAG)/doc
$(MKDIR) org-$(TAG)/lisp
cp -r $(LISPFILES) org-$(TAG)/lisp
@ -326,7 +322,6 @@ distfile:
cp -r $(DISTFILES_extra) org-$(TAG)/
cp -r README_DIST org-$(TAG)/README
cp -r ORGWEBPAGE/Changes.org org-$(TAG)/
cp -r $(DISTFILES_xemacs) org-$(TAG)/xemacs/
zip -r org-$(TAG).zip org-$(TAG)
gtar zcvf org-$(TAG).tar.gz org-$(TAG)
@ -453,4 +448,4 @@ lisp/org-timer.elc: lisp/org.el
lisp/org-vm.elc: lisp/org.el
lisp/org-w3m.elc: lisp/org.el
lisp/org-wl.elc: lisp/org.el
lisp/org-xoxo.elc: lisp/org-exp.el
lisp/org-xoxo.elc: lisp/org-exp.el

View File

@ -152,7 +152,7 @@ the command line....):
Some more information about this can be found in the [[http://orgmode.org/worg/org-faq.php][FAQ]], under [[http://orgmode.org/worg/org-faq.php#keeping-current-with-Org-mode-development][How do
I keep current with Org mode development?]]. For people who cannot use
git, we provide [[file:org-latest.zip][zip]] or [[file:org-latest.tar.gz][tar.gz]] snapshot release files updated each hour
git, we provide [[file:org-latest.zip][zip]] or [[file:org-latest.tar.gz][tar.gz]] snapshot release files updated each day
and corresponding to the latest git version.
** Alternative distributions

6
README
View File

@ -21,12 +21,6 @@ doc/
The documentation files. org.texi is the source of the
documentation, org.html and org.pdf are formatted versions of it.
xemacs/
The xemacs directory contains special code for XEmacs users, in
particular a port of the GNU Emacs outline.el to XEmacs. Org-mode
does not work under XEmacs without this file installed. It did
until version 4.37, but no longer.
contrib/
A directory with third-party additions for Org. Some really cool
stuff is in there.

View File

@ -17,12 +17,6 @@ doc/
The documentation files. org.texi is the source of the
documentation, org.html and org.pdf are formatted versions of it.
xemacs/
The xemacs directory contains special code for XEmacs users, in
particular a port of the GNU Emacs outline.el to XEmacs. Org-mode
does not work under XEmacs without this file installed. It did
until version 4.37, but no longer.
contrib/
A directory with third-party additions for Org. Some really cool
stuff is in there.

View File

@ -285,7 +285,8 @@ def action_apply(rpc, patch_id):
sys.exit(1)
def action_update_patch(rpc, patch_id, state = None, commit = None,
delegate_str = "", comment_str, archived = False):
delegate_str = "", comment_str = "None",
archived = False):
patch = rpc.patch_get(patch_id)
if patch == {}:
sys.stderr.write("Error getting information on patch ID %d\n" % \
@ -471,7 +472,8 @@ def merge_with(patch_id, rpc, delegate_str, comment_str):
# If it succeeded this far, mark the patch as "Accepted" by the invoking
# user.
action_update_patch(rpc, patch_id, state = 'Accepted', commit = sha,
delegate_str = delegate_str, archived = True)
delegate_str = delegate_str, comment_str = comment_str,
archived = True)
print sha

View File

@ -18,6 +18,8 @@ org-choose.el --- Use TODO keywords to mark decision states
org-collector.el --- Collect properties into tables
org-contribdir.el --- Dummy file to mark the org contrib Lisp directory
org-depend.el --- TODO dependencies for Org-mode
org-drill.el --- Self-testing with org-learn
org-depend.el --- TODO dependencies for Org-mode
org-elisp-symbol.el --- Org links to emacs-lisp symbols
org-eval.el --- The <lisp> tag, adapted from Muse
org-eval-light.el --- Evaluate in-buffer code on demand

775
contrib/lisp/org-drill.el Normal file
View File

@ -0,0 +1,775 @@
;;; org-drill.el - Self-testing with org-learn
;;;
;;; Author: Paul Sexton <eeeickythump@gmail.com>
;;; Version: 1.0
;;; Repository at http://bitbucket.org/eeeickythump/org-drill/
;;;
;;;
;;; Synopsis
;;; ========
;;;
;;; Uses the spaced repetition algorithm in `org-learn' to conduct interactive
;;; "drill sessions", where the material to be remembered is presented to the
;;; student in random order. The student rates his or her recall of each item,
;;; and this information is fed back to `org-learn' to schedule the item for
;;; later revision.
;;;
;;; Each drill session can be restricted to topics in the current buffer
;;; (default), one or several files, all agenda files, or a subtree. A single
;;; topic can also be drilled.
;;;
;;; Different "card types" can be defined, which present their information to
;;; the student in different ways.
;;;
;;; See the file README.org for more detailed documentation.
(eval-when-compile (require 'cl))
(eval-when-compile (require 'hi-lock))
(require 'org)
(require 'org-learn)
(defgroup org-drill nil
"Options concerning interactive drill sessions in Org mode (org-drill)."
:tag "Org-Drill"
:group 'org-link)
(defcustom org-drill-question-tag
"drill"
"Tag which topics must possess in order to be identified as review topics
by `org-drill'."
:group 'org-drill
:type 'string)
(defcustom org-drill-maximum-items-per-session
30
"Each drill session will present at most this many topics for review.
Nil means unlimited."
:group 'org-drill
:type '(choice integer (const nil)))
(defcustom org-drill-maximum-duration
20
"Maximum duration of a drill session, in minutes.
Nil means unlimited."
:group 'org-drill
:type '(choice integer (const nil)))
(defcustom org-drill-failure-quality
2
"If the quality of recall for an item is this number or lower,
it is regarded as an unambiguous failure, and the repetition
interval for the card is reset to 0 days. By default this is
2. For Mnemosyne-like behaviour, set it to 1. Other values are
not really sensible."
:group 'org-drill
:type '(choice (const 2) (const 1)))
(defcustom org-drill-leech-failure-threshold
15
"If an item is forgotten more than this many times, it is tagged
as a 'leech' item."
:group 'org-drill
:type '(choice integer (const nil)))
(defcustom org-drill-leech-method
'skip
"How should 'leech items' be handled during drill sessions?
Possible values:
- nil :: Leech items are treated the same as normal items.
- skip :: Leech items are not included in drill sessions.
- warn :: Leech items are still included in drill sessions,
but a warning message is printed when each leech item is
presented."
:group 'org-drill
:type '(choice (const 'warn) (const 'skip) (const nil)))
(defface org-drill-visible-cloze-face
'((t (:foreground "dark slate blue")))
"The face used to hide the contents of cloze phrases."
:group 'org-drill)
(defcustom org-drill-use-visible-cloze-face-p
nil
"Use a special face to highlight cloze-deleted text in org mode
buffers?"
:group 'org-drill
:type 'boolean)
(defface org-drill-hidden-cloze-face
'((t (:foreground "deep sky blue" :background "blue")))
"The face used to hide the contents of cloze phrases."
:group 'org-drill)
(setplist 'org-drill-cloze-overlay-defaults
'(display "[...]"
face org-drill-hidden-cloze-face
window t))
(defvar org-drill-cloze-regexp
;; ver 1 "[^][]\\(\\[[^][][^]]*\\]\\)"
;; ver 2 "\\(\\[.*?\\]\\|^[^[[:cntrl:]]*?\\]\\|\\[.*?$\\)"
"\\(\\[.*?\\]\\|\\[.*?[[:cntrl:]]+.*?\\]\\)")
(defcustom org-drill-card-type-alist
'((nil . org-drill-present-simple-card)
("simple" . org-drill-present-simple-card)
("twosided" . org-drill-present-two-sided-card)
("multisided" . org-drill-present-multi-sided-card)
("spanish_verb" . org-drill-present-spanish-verb))
"Alist associating card types with presentation functions. Each entry in the
alist takes the form (CARDTYPE . FUNCTION), where CARDTYPE is a string
or nil, and FUNCTION is a function which takes no arguments and returns a
boolean value."
:group 'org-drill
:type '(alist :key-type (choice string (const nil)) :value-type function))
(defcustom org-drill-spaced-repetition-algorithm
'sm5
"Which SuperMemo spaced repetition algorithm to use for scheduling items.
Available choices are SM2 and SM5."
:group 'org-drill
:type '(choice (const 'sm2) (const 'sm5)))
(defcustom org-drill-add-random-noise-to-intervals-p
nil
"If true, the number of days until an item's next repetition
will vary slightly from the interval calculated by the SM2
algorithm. The variation is very small when the interval is
small, and scales up with the interval. The code for calculating
random noise is adapted from Mnemosyne."
:group 'org-drill
:type 'boolean)
(defvar *org-drill-done-entry-count* 0)
(defvar *org-drill-pending-entry-count* 0)
(defvar *org-drill-session-qualities* nil)
(defvar *org-drill-start-time* 0)
(defun shuffle-list (list)
"Randomly permute the elements of LIST (all permutations equally likely)."
;; Adapted from 'shuffle-vector' in cookie1.el
(let ((i 0)
j
temp
(len (length list)))
(while (< i len)
(setq j (+ i (random (- len i))))
(setq temp (nth i list))
(setf (nth i list) (nth j list))
(setf (nth j list) temp)
(setq i (1+ i))))
list)
(defun org-drill-entry-p ()
"Is the current entry a 'drill item'?"
(or (assoc "LEARN_DATA" (org-entry-properties nil))
(member org-drill-question-tag (org-get-local-tags))))
(defun org-part-of-drill-entry-p ()
"Is the current entry either the main heading of a 'drill item',
or a subheading within a drill item?"
(or (org-drill-entry-p)
;; Does this heading INHERIT the drill tag
(member org-drill-question-tag (org-get-tags-at))))
(defun org-drill-entry-leech-p ()
"Is the current entry a 'leech item'?"
(and (org-drill-entry-p)
(member "leech" (org-get-local-tags))))
(defun org-drill-entry-due-p ()
(let ((item-time (org-get-scheduled-time (point))))
(and (org-drill-entry-p)
(or (not (eql 'skip org-drill-leech-method))
(not (org-drill-entry-leech-p)))
(or (null item-time)
(not (minusp ; scheduled for today/in future
(- (time-to-days (current-time))
(time-to-days item-time))))))))
(defun org-drill-entry-new-p ()
(let ((item-time (org-get-scheduled-time (point))))
(and (org-drill-entry-p)
(null item-time))))
(defun org-drill-entry-last-quality ()
(let ((quality (cdr (assoc "DRILL_LAST_QUALITY" (org-entry-properties nil)))))
(if quality
(string-to-number quality)
nil)))
;;; SM2 Algorithm =============================================================
(defun determine-next-interval-sm2 (last-interval n ef quality of-matrix)
"Arguments:
- LAST-INTERVAL -- the number of days since the item was last reviewed.
- N -- the number of times the item has been successfully reviewed
- EF -- the 'easiness factor'
- QUALITY -- 0 to 5
- OF-MATRIX -- a matrix of values, used by SM5 but not by SM2.
Returns a list: (INTERVAL N EF OFMATRIX), where:
- INTERVAL is the number of days until the item should next be reviewed
- N is incremented by 1.
- EF is modified based on the recall quality for the item.
- OF-MATRIX is not modified."
(assert (> n 0))
(assert (and (>= quality 0) (<= quality 5)))
(if (<= quality org-drill-failure-quality)
;; When an item is failed, its interval is reset to 0,
;; but its EF is unchanged
(list -1 1 ef of-matrix)
;; else:
(let* ((next-ef (modify-e-factor ef quality))
(interval
(cond
((<= n 1) 1)
((= n 2)
(cond
(org-drill-add-random-noise-to-intervals-p
(case quality
(5 6)
(4 4)
(3 3)
(2 1)
(t -1)))
(t 6)))
(t (ceiling (* last-interval next-ef))))))
(list (round
(if org-drill-add-random-noise-to-intervals-p
(+ last-interval (* (- interval last-interval)
(org-drill-random-dispersal-factor)))
interval))
(1+ n) next-ef of-matrix))))
;;; SM5 Algorithm =============================================================
;;; From http://www.supermemo.com/english/ol/sm5.htm
(defun org-drill-random-dispersal-factor ()
(let ((a 0.047)
(b 0.092)
(p (- (random* 1.0) 0.5)))
(flet ((sign (n)
(cond ((zerop n) 0)
((plusp n) 1)
(t -1))))
(/ (+ 100 (* (* (/ -1 b) (log (- 1 (* (/ b a ) (abs p)))))
(sign p)))
100))))
(defun inter-repetition-interval-sm5 (last-interval n ef &optional of-matrix)
(let ((of (get-optimal-factor n ef of-matrix)))
(if (= 1 n)
of
(* of last-interval))))
(defun determine-next-interval-sm5 (last-interval n ef quality of-matrix)
(assert (> n 0))
(assert (and (>= quality 0) (<= quality 5)))
(let ((next-ef (modify-e-factor ef quality))
(interval nil))
(setq of-matrix
(set-optimal-factor n next-ef of-matrix
(modify-of (get-optimal-factor n ef of-matrix)
quality org-learn-fraction))
ef next-ef)
(cond
;; "Failed" -- reset repetitions to 0,
((<= quality org-drill-failure-quality)
(list -1 1 ef of-matrix)) ; Not clear if OF matrix is supposed to be
; preserved
;; For a zero-based quality of 4 or 5, don't repeat
((and (>= quality 4)
(not org-learn-always-reschedule))
(list 0 (1+ n) ef of-matrix)) ; 0 interval = unschedule
(t
(setq interval (inter-repetition-interval-sm5
last-interval n ef of-matrix))
(if org-drill-add-random-noise-to-intervals-p
(setq interval (+ last-interval
(* (- interval last-interval)
(org-drill-random-dispersal-factor)))))
(list (round interval) (1+ n) ef of-matrix)))))
;;; Essentially copied from `org-learn.el', but modified to
;;; optionally call the SM2 function above.
(defun org-drill-smart-reschedule (quality)
(interactive "nHow well did you remember the information (on a scale of 0-5)? ")
(let* ((learn-str (org-entry-get (point) "LEARN_DATA"))
(learn-data (or (and learn-str
(read learn-str))
(copy-list initial-repetition-state)))
closed-dates)
(setq learn-data
(case org-drill-spaced-repetition-algorithm
(sm5 (determine-next-interval-sm5 (nth 0 learn-data)
(nth 1 learn-data)
(nth 2 learn-data)
quality
(nth 3 learn-data)))
(sm2 (determine-next-interval-sm2 (nth 0 learn-data)
(nth 1 learn-data)
(nth 2 learn-data)
quality
(nth 3 learn-data)))))
(org-entry-put (point) "LEARN_DATA" (prin1-to-string learn-data))
(cond
((= 0 (nth 0 learn-data))
(org-schedule t))
(t
(org-schedule nil (time-add (current-time)
(days-to-time (nth 0 learn-data))))))))
(defun org-drill-reschedule ()
"Returns quality rating (0-5), or nil if the user quit."
(let ((ch nil))
(while (not (memq ch '(?q ?0 ?1 ?2 ?3 ?4 ?5)))
(setq ch (read-char
(if (eq ch ??)
"0-2 Means you have forgotten the item.
3-5 Means you have remembered the item.
0 - Completely forgot.
1 - Even after seeing the answer, it still took a bit to sink in.
2 - After seeing the answer, you remembered it.
3 - It took you awhile, but you finally remembered.
4 - After a little bit of thought you remembered.
5 - You remembered the item really easily.
How well did you do? (0-5, ?=help, q=quit)"
"How well did you do? (0-5, ?=help, q=quit)"))))
(cond
((and (>= ch ?0) (<= ch ?5))
(let ((quality (- ch ?0))
(failures (cdr (assoc "DRILL_FAILURE_COUNT" (org-entry-properties nil)))))
(save-excursion
(org-drill-smart-reschedule quality))
(push quality *org-drill-session-qualities*)
(cond
((<= quality org-drill-failure-quality)
(when org-drill-leech-failure-threshold
(setq failures (if failures (string-to-number failures) 0))
(org-set-property "DRILL_FAILURE_COUNT"
(format "%d" (1+ failures)))
(if (> (1+ failures) org-drill-leech-failure-threshold)
(org-toggle-tag "leech" 'on)))))
(org-set-property "DRILL_LAST_QUALITY" (format "%d" quality))
quality))
(t
nil))))
(defun org-drill-hide-all-subheadings-except (heading-list)
"Returns a list containing the position of each immediate subheading of
the current topic."
(let ((drill-entry-level (org-current-level))
(drill-sections nil)
(drill-heading nil))
(org-show-subtree)
(save-excursion
(org-map-entries
(lambda ()
(when (= (org-current-level) (1+ drill-entry-level))
(setq drill-heading (org-get-heading t))
(unless (member drill-heading heading-list)
(hide-subtree))
(push (point) drill-sections)))
"" 'tree))
(reverse drill-sections)))
(defun org-drill-presentation-prompt (&rest fmt-and-args)
(let ((ch nil)
(prompt
(if fmt-and-args
(apply 'format
(first fmt-and-args)
(rest fmt-and-args))
"Press any key to see the answer, 'e' to edit, 'q' to quit.")))
(setq prompt
(format "(%d) %s" *org-drill-pending-entry-count* prompt))
(if (and (eql 'warn org-drill-leech-method)
(org-drill-entry-leech-p))
(setq prompt (concat "!!! LEECH ITEM !!!
You seem to be having a lot of trouble memorising this item.
Consider reformulating the item to make it easier to remember.\n" prompt)))
(setq ch (read-char prompt))
(case ch
(?q nil)
(?e 'edit)
(otherwise t))))
(defun org-drill-hide-clozed-text ()
(let ((ovl nil))
(save-excursion
(while (re-search-forward org-drill-cloze-regexp nil t)
(setf ovl (make-overlay (match-beginning 0) (match-end 0)))
(overlay-put ovl 'category
'org-drill-cloze-overlay-defaults)
(when (find ?| (match-string 0))
(overlay-put ovl
'display
(format "[...%s]"
(substring-no-properties
(match-string 0)
(1+ (position ?| (match-string 0)))
(1- (length (match-string 0)))))))))))
(defun org-drill-unhide-clozed-text ()
(save-excursion
(dolist (ovl (overlays-in (point-min) (point-max)))
(when (eql 'org-drill-cloze-overlay-defaults (overlay-get ovl 'category))
(delete-overlay ovl)))))
;;; Presentation functions ====================================================
;; Each of these is called with point on topic heading. Each needs to show the
;; topic in the form of a 'question' or with some information 'hidden', as
;; appropriate for the card type. The user should then be prompted to press a
;; key. The function should then reveal either the 'answer' or the entire
;; topic, and should return t if the user chose to see the answer and rate their
;; recall, nil if they chose to quit.
(defun org-drill-present-simple-card ()
(org-drill-hide-all-subheadings-except nil)
(prog1 (org-drill-presentation-prompt)
(org-show-subtree)))
(defun org-drill-present-two-sided-card ()
(let ((drill-sections (org-drill-hide-all-subheadings-except nil)))
(when drill-sections
(save-excursion
(goto-char (nth (random (min 2 (length drill-sections))) drill-sections))
(org-show-subtree)))
(prog1
(org-drill-presentation-prompt)
(org-show-subtree))))
(defun org-drill-present-multi-sided-card ()
(let ((drill-sections (org-drill-hide-all-subheadings-except nil)))
(when drill-sections
(save-excursion
(goto-char (nth (random (length drill-sections)) drill-sections))
(org-show-subtree)))
(prog1
(org-drill-presentation-prompt)
(org-show-subtree))))
(defun org-drill-present-spanish-verb ()
(case (random 6)
(0
(org-drill-hide-all-subheadings-except '("Infinitive"))
(prog1
(org-drill-presentation-prompt
"Translate this Spanish verb, and conjugate it for the *present* tense.")
(org-drill-hide-all-subheadings-except '("English" "Present Tense"
"Notes"))))
(1
(org-drill-hide-all-subheadings-except '("English"))
(prog1
(org-drill-presentation-prompt
"For the *present* tense, conjugate the Spanish translation of this English verb.")
(org-drill-hide-all-subheadings-except '("Infinitive" "Present Tense"
"Notes"))))
(2
(org-drill-hide-all-subheadings-except '("Infinitive"))
(prog1
(org-drill-presentation-prompt
"Translate this Spanish verb, and conjugate it for the *past* tense.")
(org-drill-hide-all-subheadings-except '("English" "Past Tense"
"Notes"))))
(3
(org-drill-hide-all-subheadings-except '("English"))
(prog1
(org-drill-presentation-prompt
"For the *past* tense, conjugate the Spanish translation of this English verb.")
(org-drill-hide-all-subheadings-except '("Infinitive" "Past Tense"
"Notes"))))
(4
(org-drill-hide-all-subheadings-except '("Infinitive"))
(prog1
(org-drill-presentation-prompt
"Translate this Spanish verb, and conjugate it for the *future perfect* tense.")
(org-drill-hide-all-subheadings-except '("English" "Future Perfect Tense"
"Notes"))))
(5
(org-drill-hide-all-subheadings-except '("English"))
(prog1
(org-drill-presentation-prompt
"For the *future perfect* tense, conjugate the Spanish translation of this English verb.")
(org-drill-hide-all-subheadings-except '("Infinitive" "Future Perfect Tense"
"Notes"))))))
(defun org-drill-entry ()
"Present the current topic for interactive review, as in `org-drill'.
Review will occur regardless of whether the topic is due for review or whether
it meets the definition of a 'review topic' used by `org-drill'.
Returns a quality rating from 0 to 5, or nil if the user quit, or the symbol
EDIT if the user chose to exit the drill and edit the current item.
See `org-drill' for more details."
(interactive)
(unless (org-at-heading-p)
(org-back-to-heading))
(let ((card-type (cdr (assoc "DRILL_CARD_TYPE" (org-entry-properties nil))))
(cont nil))
(save-restriction
(org-narrow-to-subtree)
(org-show-subtree)
(org-cycle-hide-drawers 'all)
(let ((presentation-fn (cdr (assoc card-type org-drill-card-type-alist))))
(cond
(presentation-fn
(org-drill-hide-clozed-text)
;;(highlight-regexp org-drill-cloze-regexp
;; 'org-drill-hidden-cloze-face)
(unwind-protect
(progn
(setq cont (funcall presentation-fn)))
(org-drill-unhide-clozed-text))
;;(unhighlight-regexp org-drill-cloze-regexp)
)
(t
(error "Unknown card type: '%s'" card-type))))
(cond
((not cont)
(message "Quit")
nil)
((eql cont 'edit)
'edit)
(t
(save-excursion
(org-drill-reschedule)))))))
(defun org-drill-entries (entries)
"Returns nil, t, or a list of markers representing entries that were
'failed' and need to be presented again before the session ends."
(let ((again-entries nil)
(*org-drill-done-entry-count* 0)
(*org-drill-pending-entry-count* (length entries)))
(if (and org-drill-maximum-items-per-session
(> (length entries)
org-drill-maximum-items-per-session))
(setq entries (subseq entries 0
org-drill-maximum-items-per-session)))
(block org-drill-entries
(dolist (m entries)
(save-restriction
(switch-to-buffer (marker-buffer m))
(goto-char (marker-position m))
(setq result (org-drill-entry))
(cond
((null result)
(message "Quit")
(return-from org-drill-entries nil))
((eql result 'edit)
(setq end-pos (point-marker))
(return-from org-drill-entries nil))
(t
(cond
((< result 3)
(push m again-entries))
(t
(decf *org-drill-pending-entry-count*)
(incf *org-drill-done-entry-count*)))
(when (and org-drill-maximum-duration
(> (- (float-time (current-time)) *org-drill-start-time*)
(* org-drill-maximum-duration 60)))
(message "This drill session has reached its maximum duration.")
(return-from org-drill-entries nil))))))
(or again-entries
t))))
(defun org-drill-final-report ()
(read-char
(format
"%d items reviewed, %d items awaiting review
Session duration %s
Recall of reviewed items:
Excellent (5): %3d%%
Good (4): %3d%%
Hard (3): %3d%%
Near miss (2): %3d%%
Failure (1): %3d%%
Total failure (0): %3d%%
Session finished. Press a key to continue..."
*org-drill-done-entry-count*
*org-drill-pending-entry-count*
(format-seconds "%h:%.2m:%.2s"
(- (float-time (current-time)) *org-drill-start-time*))
(round (* 100 (count 5 *org-drill-session-qualities*))
(max 1 (length *org-drill-session-qualities*)))
(round (* 100 (count 4 *org-drill-session-qualities*))
(max 1 (length *org-drill-session-qualities*)))
(round (* 100 (count 3 *org-drill-session-qualities*))
(max 1 (length *org-drill-session-qualities*)))
(round (* 100 (count 2 *org-drill-session-qualities*))
(max 1 (length *org-drill-session-qualities*)))
(round (* 100 (count 1 *org-drill-session-qualities*))
(max 1 (length *org-drill-session-qualities*)))
(round (* 100 (count 0 *org-drill-session-qualities*))
(max 1 (length *org-drill-session-qualities*)))
)))
(defun org-drill (&optional scope)
"Begin an interactive 'drill session'. The user is asked to
review a series of topics (headers). Each topic is initially
presented as a 'question', often with part of the topic content
hidden. The user attempts to recall the hidden information or
answer the question, then presses a key to reveal the answer. The
user then rates his or her recall or performance on that
topic. This rating information is used to reschedule the topic
for future review using the `org-learn' library.
Org-drill proceeds by:
- Finding all topics (headings) in SCOPE which have either been
used and rescheduled by org-learn before (i.e. the LEARN_DATA
property is set), or which have a tag that matches
`org-drill-question-tag'.
- All matching topics which are either unscheduled, or are
scheduled for the current date or a date in the past, are
considered to be candidates for the drill session.
- If `org-drill-maximum-items-per-session' is set, a random
subset of these topics is presented. Otherwise, all of the
eligible topics will be presented.
SCOPE determines the scope in which to search for
questions. It is passed to `org-map-entries', and can be any of:
nil The current buffer, respecting the restriction if any.
This is the default.
tree The subtree started with the entry at point
file The current buffer, without restriction
file-with-archives
The current buffer, and any archives associated with it
agenda All agenda files
agenda-with-archives
All agenda files with any archive files associated with them
(file1 file2 ...)
If this is a list, all files in the list will be scanned."
(interactive)
(let ((entries nil)
(failed-entries nil)
(new-entries nil)
(old-entries nil)
(result nil)
(results nil)
(end-pos nil))
(block org-drill
(setq *org-drill-session-qualities* nil)
(setq *org-drill-start-time* (float-time (current-time)))
(save-excursion
(org-map-entries
(lambda () (when (org-drill-entry-due-p)
(cond
((org-drill-entry-new-p)
(push (point-marker) new-entries))
((<= (org-drill-entry-last-quality)
org-drill-failure-quality)
(push (point-marker) failed-entries))
(t
(push (point-marker) old-entries)))))
"" scope)
;; Failed first, then random mix of old + new
(setq entries (append (shuffle-list failed-entries)
(shuffle-list (append old-entries
new-entries))))
(cond
((null entries)
(message "I did not find any pending drill items."))
(t
(let ((again t))
(while again
(when (listp again)
(setq entries (shuffle-list again)))
(setq again (org-drill-entries entries))
(cond
((null again)
(return-from org-drill nil))
((eql t again)
(setq again nil))))
(message "Drill session finished!")
)))))
(cond
(end-pos
(switch-to-buffer (marker-buffer end-pos))
(goto-char (marker-position end-pos))
(message "Edit topic."))
(t
(org-drill-final-report)))))
(add-hook 'org-mode-hook
(lambda ()
(if org-drill-use-visible-cloze-face-p
(font-lock-add-keywords
'org-mode
`((,org-drill-cloze-regexp
(0 'org-drill-visible-cloze-face nil)))
t))))
(provide 'org-drill)

View File

@ -1,4 +1,4 @@
;;; org-export-generic.el --- Export frameworg with custom backends
;; org-export-generic.el --- Export frameworg with custom backends
;; Copyright (C) 2009 Free Software Foundation, Inc.
@ -444,6 +444,40 @@ in this way, it will be wrapped."
export definitions."
(aput 'org-generic-alist type definition))
;;; helper functions for org-set-generic-type
(defvar org-export-generic-keywords nil)
(defmacro* def-org-export-generic-keyword (keyword
&key documentation
type)
"Define KEYWORD as a legitimate element for inclusion in
the body of an org-set-generic-type definition."
`(progn
(pushnew ,keyword org-export-generic-keywords)
;; TODO: push the documentation and type information
;; somewhere where it will do us some good.
))
(def-org-export-generic-keyword :body-newline-paragraph
:documentation "Bound either to NIL or to a pattern to be
inserted in the output for every blank line in the input.
The intention is to handle formats where text is flowed, and
newlines are interpreted as significant \(e.g., as indicating
preformatted text\). A common non-nil value for this keyword
is \"\\n\". Should typically be combined with a value for
:body-line-format that does NOT end with a newline."
:type string)
;;; fontification keywords
(def-org-export-generic-keyword :bold-format)
(def-org-export-generic-keyword :italic-format)
(def-org-export-generic-keyword :underline-format)
(def-org-export-generic-keyword :strikethrough-format)
(def-org-export-generic-keyword :code-format)
(def-org-export-generic-keyword :verbatim-format)
(defun org-export-generic-remember-section (type suffix &optional prefix)
(setq org-export-generic-section-type type)
(setq org-export-generic-section-suffix suffix)
@ -598,6 +632,7 @@ underlined headlines. The default is 3."
:verbatim-multiline t
:select-tags (plist-get export-plist :select-tags-export)
:exclude-tags (plist-get export-plist :exclude-tags-export)
:emph-multiline t
:archived-trees
(plist-get export-plist :archived-trees-export)
:add-text (plist-get opt-plist :text))
@ -646,6 +681,16 @@ underlined headlines. The default is 3."
(bodylineform (or (plist-get export-plist :body-line-format) "%s"))
(blockquotestart (or (plist-get export-plist :blockquote-start) "\n\n\t"))
(blockquoteend (or (plist-get export-plist :blockquote-end) "\n\n"))
;; dynamic variables used heinously in fontification
;; not referenced locally...
(format-boldify (plist-get export-plist :bold-format))
(format-italicize (plist-get export-plist :italic-format))
(format-underline (plist-get export-plist :underline-format))
(format-strikethrough (plist-get export-plist :strikethrough-format))
(format-code (plist-get export-plist :code-format))
(format-verbatim (plist-get export-plist :verbatim-format))
thetoc toctags have-headings first-heading-pos
@ -829,7 +874,7 @@ underlined headlines. The default is 3."
(if org-export-generic-links-to-notes
(push (cons desc0 link) link-buffer)
(setq rpl (concat rpl " (" link ")")
wrap (+ (length line) (- (length (match-string 0) line))
wrap (+ (length line) (- (length (match-string 0 line)))
(length desc)))))
(setq line (replace-match rpl t t line))))
(when custom-times
@ -887,9 +932,13 @@ underlined headlines. The default is 3."
(string-match "^\\([ \t]+\\)\\(\\*[ \t]*\\)" line))
;;
;; plain list item
;;
;; TODO: nested lists
;;
;; first add a line break between any previous paragraph or line item and this
;; one
(when bodynewline-paragraph
(insert bodynewline-paragraph))
;; I believe this gets rid of leading whitespace.
(setq line (replace-match "" nil nil line))
@ -911,7 +960,7 @@ underlined headlines. The default is 3."
listcheckhalfend)))
)
(insert (format listformat line)))
(insert (format listformat (org-export-generic-fontify line))))
((string-match "^\\([ \t]+\\)\\([0-9]+\\.[ \t]*\\)" line)
;;
;; numbered list item
@ -937,7 +986,7 @@ underlined headlines. The default is 3."
listcheckhalfend)))
)
(insert (format numlistformat line)))
(insert (format numlistformat (org-export-generic-fontify line))))
((equal line "ORG-BLOCKQUOTE-START")
(setq line blockquotestart))
@ -946,13 +995,16 @@ underlined headlines. The default is 3."
((string-match "^\\s-*$" line)
;; blank line
(if bodynewline-paragraph
(insert "\n")))
(insert bodynewline-paragraph)))
(t
;;
;; body
;;
(org-export-generic-check-section "body" bodytextpre bodytextsuf)
(setq line
(org-export-generic-fontify line))
;; XXX: properties? list?
(if (string-match "^\\([ \t]*\\)\\([-+*][ \t]+\\)\\(.*?\\)\\( ::\\)" line)
(setq line (replace-match "\\1\\3:" t nil line)))
@ -1259,6 +1311,74 @@ REVERSE means to reverse the list if the plist match is a list
(and vl (setcar vl nil))
vl))
;;; FIXME: this should probably turn into a defconstant later [2010/05/20:rpg]
(defvar org-export-generic-emphasis-alist
'(("*" format-boldify nil)
("/" format-italicize nil)
("_" format-underline nil)
("+" format-strikethrough nil)
("=" format-code t)
("~" format-verbatim t))
"Alist of org format -> formatting variables for fontification.
Each element of the list is a list of three elements.
The first element is the character used as a marker for fontification.
The second element is a variable name, set in org-export-generic. That
variable will be dereferenced to obtain a formatting string to wrap
fontified text with.
The third element decides whether to protect converted text from other
conversions.")
;;; Cargo-culted from the latex translation. I couldn't figure out how
;;; to keep the structure since the generic export operates on lines, rather
;;; than on a buffer as in the latex export, meaning that none of the
;;; search forward code could be kept. This led me to rewrite the
;;; whole thing recursively. A huge lose for efficiency (potentially),
;;; but I couldn't figure out how to make the looping work.
;;; Worse, it's /doubly/ recursive, because this function calls
;;; org-export-generic-emph-format, which can call it recursively...
;;; [2010/05/20:rpg]
(defun org-export-generic-fontify (string)
"Convert fontification according to generic rules."
(if (string-match org-emph-re string)
;; The match goes one char after the *string*, except at the end of a line
(let ((emph (assoc (match-string 3 string)
org-export-generic-emphasis-alist))
(beg (match-beginning 0))
(end (match-end 0)))
(unless emph
(message "`org-export-generic-emphasis-alist' has no entry for formatting triggered by \"%s\""
(match-string 3 string)))
;; now we need to determine whether we have strikethrough or
;; a list, which is a bit nasty
(if (and (equal (match-string 3 string) "+")
(save-match-data
(string-match "\\`-+\\'" (match-string 4 string))))
;; a list --- skip this match and recurse on the point after the
;; first emph char...
(concat (substring string 0 (1+ (match-beginning 3)))
(org-export-generic-fontify (substring string (match-beginning 3))))
(concat (substring string 0 beg) ;; part before the match
(match-string 1 string)
(org-export-generic-emph-format (second emph)
(match-string 4 string)
(third emph))
(or (match-string 5 string) "")
(org-export-generic-fontify (substring string end)))))
string))
(defun org-export-generic-emph-format (format-varname string protect)
"Return a string that results from applying the markup indicated by
FORMAT-VARNAME to STRING."
(let ((format (symbol-value format-varname)))
(let ((string-to-emphasize
(if protect
string
(org-export-generic-fontify string))))
(if format
(format format string-to-emphasize)
string-to-emphasize))))
(provide 'org-generic)
(provide 'org-export-generic)

View File

@ -0,0 +1,171 @@
;;; org-static-mathjax.el --- Muse-like tags in Org-mode
;;
;; Author: Jan Böker <jan dot boecker at jboecker dot de>
;; This elisp code integrates Static MathJax into the
;; HTML export process of Org-mode.
;;
;; The supporting files for this package are in contrib/scripts/staticmathjax
;; Please read the README.org file in that directory for more information.
;; To use it, evaluate it on startup, add the following to your .emacs:
;; (require 'org-static-mathjax)
;;
;; You will then have to customize the following two variables:
;; - org-static-mathjax-app-ini-path
;; - org-static-mathjax-local-mathjax-path
;;
;; If xulrunner is not in your $PATH, you will also need to customize
;; org-static-mathjax-xulrunner-path.
;;
;; If everything is setup correctly, you can trigger Static MathJax on
;; export to HTML by adding the following line to your Org file:
;; #+StaticMathJax: embed-fonts:nil output-file-name:"embedded-math.html"
;;
;; You can omit either argument.
;; embed-fonts defaults to nil. If you do not specify output-file-name,
;; the exported file is overwritten with the static version.
;;
;; If embed-fonts is non-nil, the fonts are embedded directly into the
;; output file using data: URIs.
;;
;; output-file-name specifies the file name of the static version. You
;; can use any arbitrary lisp form here, for example:
;; output-file-name:(concat (file-name-sans-extension buffer-file-name) "-static.html")
;;
;; The StaticMathJax XULRunner application expects a UTF-8 encoded
;; input file. If the static version displays random characters instead
;; of your math, add the following line at the top of your Org file:
;; -*- coding: utf-8; -*-
;;
;; License: GPL v2 or later
(defcustom org-static-mathjax-app-ini-path
(or (expand-file-name
"../scripts/staticmatchjax/application.ini"
(file-name-directory (or load-file-name buffer-file-name)))
"")
"Path to \"application.ini\" of the Static MathJax XULRunner application.
If you have extracted StaticMathJax to e.g. ~/.local/staticmathjax, set
this to ~/.local/staticmathjax/application.ini"
:type 'string)
(defcustom org-static-mathjax-xulrunner-path
"xulrunner"
"Path to your xulrunner binary"
:type 'string)
(defcustom org-static-mathjax-local-mathjax-path
""
"Extract the MathJax zip file somewhere on your local
hard drive and specify the path here.
The directory has to be writeable, as org-static-mathjax
creates a temporary file there during export."
:type 'string)
(defvar org-static-mathjax-debug
nil
"If non-nil, org-static-mathjax will print some debug messages")
(defun org-static-mathjax-hook-installer ()
"Installs org-static-mathjax-process in after-save-hook.
Sets the following buffer-local variables for org-static-mathjax-process to pick up:
org-static-mathjax-mathjax-path: The path to MathJax.js as used by Org HTML export
org-static-mathjax-options: The string given with #+STATICMATHJAX: in the file"
(let ((static-mathjax-option-string (plist-get opt-plist :static-mathjax)))
(if static-mathjax-option-string
(progn (set (make-local-variable 'org-static-mathjax-options) static-mathjax-option-string)
(set (make-local-variable 'org-static-mathjax-mathjax-path)
(nth 1 (assq 'path org-export-html-mathjax-options)))
(let ((mathjax-options (plist-get opt-plist :mathjax)))
(if mathjax-options
(if (string-match "\\<path:" mathjax-options)
(set 'org-static-mathjax-mathjax-path
(car (read-from-string
(substring mathjax-options (match-end 0))))))))
(add-hook 'after-save-hook
'org-static-mathjax-process
nil t)))))
(defun org-static-mathjax-process ()
(save-excursion
; some sanity checking
(if (or (string= org-static-mathjax-app-ini-path "")
(not (file-exists-p org-static-mathjax-app-ini-path)))
(error "Static MathJax: You must customize org-static-mathjax-app-ini-path!"))
(if (or (string= org-static-mathjax-local-mathjax-path "")
(not (file-exists-p org-static-mathjax-local-mathjax-path)))
(error "Static MathJax: You must customize org-static-mathjax-local-mathjax-path!"))
; define variables
(let* ((options org-static-mathjax-options)
(output-file-name buffer-file-name)
(input-file-name (let ((temporary-file-directory (file-name-directory org-static-mathjax-local-mathjax-path)))
(make-temp-file "org-static-mathjax-" nil ".html")))
(html-code (buffer-string))
(mathjax-oldpath (concat "src=\"" org-static-mathjax-mathjax-path))
(mathjax-newpath (concat "src=\"" org-static-mathjax-local-mathjax-path))
embed-fonts)
; read file-local options
(mapc
(lambda (symbol)
(if (string-match (concat "\\<" (symbol-name symbol) ":") options)
(set symbol (eval (car (read-from-string
(substring options (match-end 0))))))))
'(embed-fonts output-file-name))
; debug
(when org-static-mathjax-debug
(message "output file name, embed-fonts")
(print output-file-name)
(print embed-fonts))
; open (temporary) input file, copy contents there, replace MathJax path with local installation
(with-temp-buffer
(insert html-code)
(goto-char 1)
(replace-regexp mathjax-oldpath mathjax-newpath)
(write-file input-file-name))
; prepare argument list for call-process
(let ((call-process-args (list org-static-mathjax-xulrunner-path
nil nil nil
org-static-mathjax-app-ini-path
input-file-name
output-file-name)))
; if fonts are embedded, just append the --embed-fonts flag
(if embed-fonts
(add-to-list 'call-process-args "--embed-fonts" t))
; if fonts are not embedded, the XULRunner app must replace all references
; to the font files with the real location (Firefox inserts file:// URLs there,
; because we are using a local MathJax installation here)
(if (not embed-fonts)
(progn
(add-to-list 'call-process-args "--final-mathjax-url" t)
(add-to-list 'call-process-args
(file-name-directory org-static-mathjax-mathjax-path)
t)))
; debug
(when org-static-mathjax-debug
(print call-process-args))
; call it
(apply 'call-process call-process-args)
; delete our temporary input file
(kill-buffer)
(delete-file input-file-name)
(let ((backup-file (concat input-file-name "~")))
(if (file-exists-p backup-file)
(delete-file backup-file)))))))
(add-to-list 'org-export-inbuffer-options-extra
'("STATICMATHJAX" :static-mathjax))
(add-hook 'org-export-html-final-hook 'org-static-mathjax-hook-installer)
(provide 'org-static-mathjax)

View File

@ -119,10 +119,10 @@ setting of `org-wikinodes-create-targets'."
(let ((create org-wikinodes-create-targets)
visiting buffer m pos file rpl)
(setq pos
(or (org-find-exact-headling-in-buffer target (current-buffer))
(or (org-find-exact-headline-in-buffer target (current-buffer))
(and (eq org-wikinodes-scope 'directory)
(setq file (org-wikinodes-which-file target))
(org-find-exact-headling-in-buffer
(org-find-exact-headline-in-buffer
target (or (get-file-buffer file)
(find-file-noselect file))))))
(if pos
@ -288,7 +288,7 @@ with working links."
(delete-region (match-beginning 0) (match-end 0))
(save-match-data
(cond
((org-find-exact-headling-in-buffer link (current-buffer))
((org-find-exact-headline-in-buffer link (current-buffer))
;; Found in current buffer
(insert (format "[[#%s][%s]]" link link)))
((eq org-wikinodes-scope 'file)

View File

@ -0,0 +1,39 @@
(require 'org-export-generic)
(defun test-preproc ()
(interactive)
(let ((string
(let ((region
(buffer-substring
(if (org-region-active-p) (region-beginning) (point-min))
(if (org-region-active-p) (region-end) (point-max))))
(opt-plist (org-combine-plists (org-default-export-plist)
(org-infile-export-plist)))
(export-plist '("tikiwiki" :file-suffix ".txt" :key-binding 85 :header-prefix "" :header-suffix "" :title-format "-= %s =-\n" :date-export nil :toc-export nil :body-header-section-numbers nil :body-section-prefix "\n" :body-section-header-prefix
("! " "!! " "!!! " "!!!! " "!!!!! " "!!!!!! " "!!!!!!! ")
:body-section-header-suffix
(" \n" " \n" " \n" " \n" " \n" " \n")
:body-line-export-preformated t :body-line-format "%s " :body-line-wrap nil :body-line-fixed-format " %s\n" :body-list-format "* %s\n" :body-number-list-format "# %s\n" :blockquote-start "\n^\n" :blockquote-end "^\n\n" :body-newline-paragraph "\n" :bold-format "__%s__" :italic-format "''%s''" :underline-format "===%s===" :strikethrough-format "--%s--" :code-format "-+%s+-" :verbatim-format "~pp~%s~/pp~")))
(org-export-preprocess-string
region
:for-ascii t
:skip-before-1st-heading
(plist-get opt-plist :skip-before-1st-heading)
:drawers (plist-get export-plist :drawers-export)
:tags (plist-get export-plist :tags-export)
:priority (plist-get export-plist :priority-export)
:footnotes (plist-get export-plist :footnotes-export)
:timestamps (plist-get export-plist :timestamps-export)
:todo-keywords (plist-get export-plist :todo-keywords-export)
:verbatim-multiline t
:select-tags (plist-get export-plist :select-tags-export)
:exclude-tags (plist-get export-plist :exclude-tags-export)
:emph-multiline t
:archived-trees
(plist-get export-plist :archived-trees-export)
:add-text (plist-get opt-plist :text)))))
(save-excursion
(switch-to-buffer "*preproc-temp*")
(point-max)
(insert string))))

1
contrib/scripts/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
plantuml.jar

View File

@ -44,6 +44,11 @@ EMACS = emacs -batch -l ~/.emacs
LATEX = latex
DIARY = $($(EMACS) -eval "diary-file")
# Number of weeks to be printed. Should be a multiple of 4, because 4
# of them are merged on one page. Can be set when invoking the script
# as follows: make NUMBER_OF_WEEKS=8 -f org2hpda
NUMBER_OF_WEEKS = 4
hipsterFiles = weekCalendar.pdf yearCalendar.pdf monthCalendar3.pdf monthCalendar2.pdf monthCalendar1.pdf
pocketModFiles = weekCalendar.pdf yearCalendar-rotated.pdf \
monthCalendar3-rotated.pdf monthCalendar2-rotated.pdf monthCalendar1-rotated.pdf
@ -73,7 +78,7 @@ all: pocketMod.pdf hipsterPDA.pdf
done
weekCalendar.tex: $(DIARY)
$(EMACS) -eval "(progn (calendar) (cal-tex-cursor-week-iso 4) (with-current-buffer cal-tex-buffer (write-file \"$@\")))"
$(EMACS) -eval "(progn (calendar) (cal-tex-cursor-week-iso $(NUMBER_OF_WEEKS)) (with-current-buffer cal-tex-buffer (write-file \"$@\")))"
monthCalendar1.tex: $(DIARY)
$(EMACS) -eval "(progn (calendar) (cal-tex-cursor-month-landscape 1) (with-current-buffer cal-tex-buffer (write-file \"$@\")))"

View File

@ -0,0 +1 @@
*~

View File

@ -0,0 +1,79 @@
Static MathJax v0.1 README
#+AUTHOR: Jan Böcker <jan.boecker@jboecker.de>
Static MathJax is a XULRunner application which loads a HTML input
file that uses MathJax into a browser, waits until MathJax is done
processing, and then writes the formatted result to an output HTML
file.
I have only tested exports from Emacs Org-mode as input files. (As of
2010-08-14, MathJax is used by default with HTML exports in the
current Org development version.)
Optionally, references to the math fonts used will be converted to
"data:" URIs, thus embedding the font data into the HTML file itself.
(see [[http://en.wikipedia.org/wiki/Data_URI_scheme]])
The code is licensed under the GNU General Public License version
2, or, at your option, any later version.
* Usage
To run Static MathJax, an existing XULRunner installation is
required. From the directory to which you unpacked Static MathJax,
run:
xulrunner application.ini <--embed-fonts | --final-mathjax-url <URL>>
<input file> <output file>
If you prefer to call "staticmathjax" instead of "xulrunner
application.ini", link xulrunner-stub into the directory:
ln /usr/lib/xulrunner-1.9.2.8/xulrunner-stub ./staticmathjax
- input file ::
name of the input file (the result of a HTML export
from Org-mode). It is assumed that this file uses the
UTF-8 character encoding.
- output file ::
name of the output file.
- --embed-fonts ::
if specified, the math fonts will be embedded into
the output file using data: URIs
- --final-mathjax-url <URL> ::
if --embed-fonts is not specified, this
must be the URL to a MathJax installation folder (e.g. "MathJax"
if MathJax is installed in a subdirectory, or
"http://orgmode.org/mathjax" to use the version hosted on the Org
website.
All references to math fonts in the output file will point to
this directory.
* Caveats
The input file must not use a MathJax installation on the
web. Otherwise, due to a security feature of Firefox, MathJax will
fallback to image fonts. If you have unpacked MathJax to a
subdirectory "MathJax", specify the following in your Org file:
#+MathJax: path:"MathJax"
The math is rendered in Firefox, so MathJax applies its
Firefox-specific settings. When viewing the output files in other
browsers, it will look slightly different than the result that
running MathJax in that browser would produce.
Internet Explorer does not use the correct font, because it only
supports the EOT font format. For all other browsers (including
Firefox), MathJax uses the OTF font format.
Embedding fonts into the HTML file wastes some space due to the
base64 encoding used in data: URIs.
I have found no way to access stdout or set an exit code in an
XULRunner app, so any code which calls Static MathJax has no idea if
processing was successful and when an error occurs, graphical
message boxes are displayed.

View File

@ -0,0 +1,91 @@
Static MathJax v0.1 README
==========================
Author: Jan Böcker <jan.boecker@jboecker.de>
Date: 2010-08-15 13:53:39 CEST
Static MathJax is a XULRunner application which loads a HTML input
file that uses MathJax into a browser, waits until MathJax is done
processing, and then writes the formatted result to an output HTML
file.
I have only tested exports from Emacs Org-mode as input files. (As of
2010-08-14, MathJax is used by default with HTML exports in the
current Org development version.)
Optionally, references to the math fonts used will be converted to
"data:" URIs, thus embedding the font data into the HTML file itself.
(see [http://en.wikipedia.org/wiki/Data_URI_scheme])
The code is licensed under the GNU General Public License version
2, or, at your option, any later version.
Table of Contents
=================
1 Usage
2 Caveats
1 Usage
~~~~~~~~
To run Static MathJax, an existing XULRunner installation is
required. From the directory to which you unpacked Static MathJax,
run:
xulrunner application.ini <--embed-fonts | --final-mathjax-url <URL>>
<input file> <output file>
If you prefer to call "staticmathjax" instead of "xulrunner
application.ini", link xulrunner-stub into the directory:
ln /usr/lib/xulrunner-1.9.2.8/xulrunner-stub ./staticmathjax
input file:
name of the input file (the result of a HTML export
from Org-mode). It is assumed that this file uses the
UTF-8 character encoding.
output file:
name of the output file.
--embed-fonts:
if specified, the math fonts will be embedded into
the output file using data: URIs
--final-mathjax-url <URL>:
if --embed-fonts is not specified, this
must be the URL to a MathJax installation folder (e.g. "MathJax"
if MathJax is installed in a subdirectory, or
"[http://orgmode.org/mathjax]" to use the version hosted on the Org
website.
All references to math fonts in the output file will point to
this directory.
2 Caveats
~~~~~~~~~~
The input file must not use a MathJax installation on the
web. Otherwise, due to a security feature of Firefox, MathJax will
fallback to image fonts. If you have unpacked MathJax to a
subdirectory "MathJax", specify the following in your Org file:
#+MathJax: path:"MathJax"
The math is rendered in Firefox, so MathJax applies its
Firefox-specific settings. When viewing the output files in other
browsers, it will look slightly different than the result that
running MathJax in that browser would produce.
Internet Explorer does not use the correct font, because it only
supports the EOT font format. For all other browsers (including
Firefox), MathJax uses the OTF font format.
Embedding fonts into the HTML file wastes some space due to the
base64 encoding used in data: URIs.
I have found no way to access stdout or set an exit code in an
XULRunner app, so any code which calls Static MathJax has no idea if
processing was successful and when an error occurs, graphical
message boxes are displayed.

View File

@ -0,0 +1,11 @@
[App]
Vendor=Jan Boecker
Name=StaticMathJax
Version=0.2
BuildID=2
Copyright=Copyright (c) 2010 Jan Boecker
ID=xulapp@jboecker.de
[Gecko]
MinVersion=1.8

View File

@ -0,0 +1 @@
content staticmathjax file:content/

View File

@ -0,0 +1,198 @@
var docFrame;
var logtextbox;
var destFile;
var embedFonts = false;
var finalMathJaxURL = null;
function log(text)
{
logtextbox.setAttribute("value", logtextbox.getAttribute("value") + "\n" + text);
}
function init()
{
try {
docFrame = document.getElementById("docFrame");
logtextbox = document.getElementById("logtextbox");
// parse command line arguments
var cmdLine = window.arguments[0];
cmdLine = cmdLine.QueryInterface(Components.interfaces.nsICommandLine);
embedFonts = cmdLine.handleFlag("embed-fonts", false);
finalMathJaxURL = cmdLine.handleFlagWithParam("final-mathjax-url", false);
if (!embedFonts && !finalMathJaxURL) {
alert("You must eiher specify --embed-fonts or --final-mathjax-url");
window.close();
return;
}
sourceFilePath = cmdLine.getArgument(0);
destFilePath = cmdLine.getArgument(1);
if ( !sourceFilePath || !destFilePath ) {
alert("Not enough parameters, expecting two arguments:\nInput file, output file");
window.close();
return;
}
sourceFile = cmdLine.resolveFile(sourceFilePath);
if (! (sourceFile.exists() && sourceFile.isFile()) ) {
alert("Invalid source file path.");
window.close();
return;
}
sourceURI = cmdLine.resolveURI(sourceFilePath);
// create a nsIFile object for the output file
try{
destFile = cmdLine.resolveURI(destFilePath).QueryInterface(Components.interfaces.nsIFileURL).file;
}catch(e){
alert("Invalid destination file.\n\nException:\n" + e);
window.close();
return;
}
// add iframeLoaded() as an onload event handler, then navigate to the source file
docFrame.addEventListener("DOMContentLoaded", iframeLoaded, true);
docFrame.setAttribute("src", sourceURI.spec);
} catch (e) {
alert("Error in init():\n\n" + e);
window.close();
return;
}
}
function iframeLoaded()
{
/*
// print every MathJax signal to the log
docFrame.contentWindow.MathJax.Hub.Startup.signal.Interest(
function (message) {log("Startup: "+message)}
);
docFrame.contentWindow.MathJax.Hub.signal.Interest(
function (message) {log("Hub: "+message)}
);
*/
// tell MathJax to call serialize() when finished
docFrame.contentWindow.MathJax.Hub.Register.StartupHook("End", function() {serialize();});
}
function fileURLtoDataURI(url)
{
var ios = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
var url_object = ios.newURI(url, "", null);
var file = url_object.QueryInterface(Components.interfaces.nsIFileURL).file;
var data = "";
var fstream = Components.classes["@mozilla.org/network/file-input-stream;1"].
createInstance(Components.interfaces.nsIFileInputStream);
fstream.init(file, -1, -1, false);
var bstream = Components.classes["@mozilla.org/binaryinputstream;1"].
createInstance(Components.interfaces.nsIBinaryInputStream);
bstream.setInputStream(fstream);
var bytes = bstream.readBytes(bstream.available());
b64bytes = btoa(bytes);
return "data:;base64," + b64bytes;
}
function serialize()
{
var MathJaxURL = docFrame.contentWindow.MathJax.Hub.config.root;
var searchURIList = new Array();
var replacementURIList = new Array();
log("serialize: preprocessing");
// remove the MathJax status message window
msgdiv = docFrame.contentDocument.getElementById("MathJax_Message");
msgdiv.parentNode.removeChild(msgdiv);
/* Loop through all CSS rules to find all @font-face rules.
At this point, they refer to local absolute paths using file:// URLs.
Replace them either with appropriate URLs relative to finalMathJaxURL
or with data URIs. */
for (var i = 0; i<docFrame.contentDocument.styleSheets.length; i++) {
var stylesheet = docFrame.contentDocument.styleSheets[i];
for (var j=0; j< stylesheet.cssRules.length; j++) {
var rule = stylesheet.cssRules[j];
if (rule.cssText.match("font-face")) {
url = rule.style.getPropertyValue("src");
url = url.match(/url\(\"(.+)\"\)/)[1];
// Since the properties seem read-only here, we populate
// searchURIList and replacementURIList to do text substitution
// after serialization
searchURIList.push(url);
if (embedFonts) {
replacementURIList.push(fileURLtoDataURI(url));
} else {
replacementURIList.push(url.replace(MathJaxURL, finalMathJaxURL));
}
}
}
}
// find and remove the MathJax <script> tag
try{
var scriptTags = docFrame.contentDocument.getElementsByTagName("script");
for (var i=0; i<scriptTags.length; i++) {
if (scriptTags[i].getAttribute("src") && scriptTags[i].getAttribute("src").match(/MathJax.js/i))
scriptTags[i].parentNode.removeChild(scriptTags[i]);
}
}catch(e){alert(e);}
log("serialize: serializing");
var serializer = new XMLSerializer();
var xhtml = serializer.serializeToString(docFrame.contentDocument);
log("serialize: postprocessing");
// make the MathJax URL relative again
// xhtml = xhtml.replace(findMathJaxURL, "MathJax");
try{
r1 = RegExp("&lt;!--/\\*--&gt;&lt;!\\[CDATA\\[/\\*&gt;&lt;!--\\*/", "g");
xhtml = xhtml.replace(r1, "");
r2 = RegExp("/\\*\\]\\]&gt;\\*/--&gt;", "g");
xhtml = xhtml.replace(r2, "");
r3 = RegExp("/\\*\\]\\]&gt;\\*///--&gt;", "g");
xhtml = xhtml.replace(r3, "");
}catch(e){alert(e);}
for (var i=0; i<searchURIList.length; i++)
xhtml = xhtml.replace(searchURIList[i], replacementURIList[i]);
save(xhtml);
window.close();
}
function save(xhtml)
{
try {
var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"].
createInstance(Components.interfaces.nsIFileOutputStream);
foStream.init(destFile, 0x02 | 0x08 | 0x20, 0666, 0);
// write, create, truncate
// write in UTF-8 encoding
var converter = Components.classes["@mozilla.org/intl/converter-output-stream;1"].
createInstance(Components.interfaces.nsIConverterOutputStream);
converter.init(foStream, "UTF-8", 0, 0);
converter.writeString(xhtml);
converter.close(); // this closes foStream
} catch (e) {
alert("Error in save():\n\n" + e);
}
}

View File

@ -0,0 +1,11 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window onload="init();" id="main" title="Static MathJax" width="300" height="300"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script language="JavaScript" src="chrome://staticmathjax/content/main.js"/>
<browser flex="1" id="docFrame" src="" style="background-color:white;"/>
<textbox flex="1" id="logtextbox" multiline="true" style="display:none;"/>
</window>

View File

@ -0,0 +1 @@
pref("toolkit.defaultChromeURI", "chrome://staticmathjax/content/main.xul");

File diff suppressed because it is too large Load Diff

View File

@ -480,8 +480,10 @@ formula, \kbd{:=} a field formula.
\key{view expanded body of code block at point}{C-c C-v v}
\key{go to named code block}{C-c C-v g}
\key{go to named result}{C-c C-v r}
\key{go to the head of the current code block}{C-c C-v u}
\key{go to the next code block}{C-c C-v n}
\key{go to the previous code block}{C-c C-v p}
\key{execute the next key sequence in the code edit buffer}{C-c C-v x}
\key{execute all code blocks in current buffer}{C-c C-v b}
\key{execute all code blocks in current subtree}{C-c C-v s}
\key{tangle code blocks in current file}{C-c C-v t}

View File

@ -33,7 +33,6 @@
;;; Code:
(require 'ob)
(require 'ob-eval)
(require 'org)
(require 'cc-mode)
(declare-function org-entry-get "org"
@ -84,12 +83,13 @@ header arguments (calls `org-babel-C-expand')."
"This function should only be called by `org-babel-execute:C'
or `org-babel-execute:c++'."
(let* ((processed-params (org-babel-process-params params))
(tmp-src-file (make-temp-file "org-babel-C-src" nil
(cond
((equal org-babel-c-variant 'c) ".c")
((equal org-babel-c-variant 'cpp) ".cpp"))))
(tmp-bin-file (make-temp-file "org-babel-C-bin"))
(tmp-out-file (make-temp-file "org-babel-C-out"))
(tmp-src-file (org-babel-temp-file
"C-src-"
(cond
((equal org-babel-c-variant 'c) ".c")
((equal org-babel-c-variant 'cpp) ".cpp"))))
(tmp-bin-file (org-babel-temp-file "C-bin-"))
(tmp-out-file (org-babel-temp-file "C-out-"))
(cmdline (cdr (assoc :cmdline params)))
(flags (cdr (assoc :flags params)))
(full-body (org-babel-C-expand body params))
@ -108,7 +108,7 @@ or `org-babel-execute:c++'."
((lambda (results)
(org-babel-reassemble-table
(if (member "vector" (nth 2 processed-params))
(let ((tmp-file (make-temp-file "ob-c")))
(let ((tmp-file (org-babel-temp-file "c-")))
(with-temp-file tmp-file (insert results))
(org-babel-import-elisp-from-file tmp-file))
(org-babel-read results))

View File

@ -33,9 +33,11 @@
(require 'ob-eval)
(eval-when-compile (require 'cl))
(declare-function orgtbl-to-tsv "ob-table" (table params))
(declare-function orgtbl-to-tsv "org-table" (table params))
(declare-function R "ext:essd-r" (&optional start-args))
(declare-function inferior-ess-send-input "ext:ess-inf" ())
(declare-function ess-make-buffer-current "ext:ess-inf" ())
(declare-function ess-eval-buffer "ext:ess-inf" (vis))
(defconst org-babel-header-arg-names:R
'(width height bg units pointsize antialias quality compression
@ -139,7 +141,7 @@ This function is called by `org-babel-execute-src-block'."
(defun org-babel-R-assign-elisp (name value colnames-p rownames-p)
"Construct R code assigning the elisp VALUE to a variable named NAME."
(if (listp value)
(let ((transition-file (make-temp-file "org-babel-R-import")))
(let ((transition-file (org-babel-temp-file "R-import-")))
;; ensure VALUE has an orgtbl structure (depth of at least 2)
(unless (listp (car value)) (setq value (list value)))
(with-temp-file (org-babel-maybe-remote-file transition-file)
@ -151,11 +153,13 @@ This function is called by `org-babel-execute-src-block'."
(if rownames-p "1" "NULL")))
(format "%s <- %s" name (org-babel-R-quote-tsv-field value))))
(defvar ess-ask-for-ess-directory nil)
(defun org-babel-R-initiate-session (session params)
"If there is not a current R process then create one."
(unless (string= session "none")
(let ((session (or session "*R*"))
(ess-ask-for-ess-directory (not (cdr (assoc :dir params)))))
(ess-ask-for-ess-directory
(and ess-ask-for-ess-directory (not (cdr (assoc :dir params))))))
(if (org-babel-comint-buffer-livep session)
session
(save-window-excursion
@ -168,6 +172,15 @@ This function is called by `org-babel-execute-src-block'."
(buffer-name))))
(current-buffer))))))
(defvar ess-local-process-name nil)
(defun org-babel-R-associate-session (session)
"Associate R code buffer with an R session.
Make SESSION be the inferior ESS process associated with the
current code buffer."
(setq ess-local-process-name
(process-name (get-buffer-process session)))
(ess-make-buffer-current))
(defun org-babel-R-construct-graphics-device-call (out-file params)
"Construct the call to the graphics device."
(let ((devices
@ -205,69 +218,78 @@ This function is called by `org-babel-execute-src-block'."
(defvar org-babel-R-eoe-indicator "'org_babel_R_eoe'")
(defvar org-babel-R-eoe-output "[1] \"org_babel_R_eoe\"")
(defvar org-babel-R-wrapper-method "main <- function ()\n{\n%s\n}
write.table(main(), file=\"%s\", sep=\"\\t\", na=\"nil\",row.names=%s, col.names=%s, quote=FALSE)")
(defvar org-babel-R-wrapper-lastvar "write.table(.Last.value, file=\"%s\", sep=\"\\t\", na=\"nil\",row.names=%s, col.names=%s, quote=FALSE)")
(defvar org-babel-R-write-object-command "{function(object, transfer.file) {invisible(if(inherits(try(write.table(object, file=transfer.file, sep=\"\\t\", na=\"nil\",row.names=%s, col.names=%s, quote=FALSE), silent=TRUE),\"try-error\")) {if(!file.exists(transfer.file)) file.create(transfer.file)})}}(object=%s, transfer.file=\"%s\")")
(defun org-babel-R-evaluate
(session body result-type column-names-p row-names-p)
"Pass BODY to the R process in SESSION.
If RESULT-TYPE equals 'output then return a list of the outputs
of the statements in BODY, if RESULT-TYPE equals 'value then
return the value of the last statement in BODY, as elisp."
(if (not session)
;; external process evaluation
(case result-type
(output (org-babel-eval org-babel-R-command body))
(value
(let ((tmp-file (make-temp-file "org-babel-R-results-")))
(org-babel-eval org-babel-R-command
(format org-babel-R-wrapper-method
body tmp-file
(if row-names-p "TRUE" "FALSE")
(if column-names-p
(if row-names-p "NA" "TRUE")
"FALSE")))
(org-babel-R-process-value-result
(org-babel-import-elisp-from-file
(org-babel-maybe-remote-file tmp-file) '(16)) column-names-p))))
;; comint session evaluation
(case result-type
(value
(let ((tmp-file (make-temp-file "org-babel-R"))
broke)
(org-babel-comint-with-output (session org-babel-R-eoe-output)
(insert (mapconcat
#'org-babel-chomp
(list
body
(format org-babel-R-wrapper-lastvar
tmp-file
(if row-names-p "TRUE" "FALSE")
(if column-names-p
(if row-names-p "NA" "TRUE")
"FALSE"))
org-babel-R-eoe-indicator) "\n"))
(inferior-ess-send-input))
(org-babel-R-process-value-result
(org-babel-import-elisp-from-file
(org-babel-maybe-remote-file tmp-file) '(16)) column-names-p)))
(output
(mapconcat
#'org-babel-chomp
(butlast
(delq nil
(mapcar
(lambda (line) ;; cleanup extra prompts left in output
(if (string-match
"^\\([ ]*[>+][ ]?\\)+\\([[0-9]+\\|[ ]\\)" line)
(substring line (match-end 1))
line))
(org-babel-comint-with-output (session org-babel-R-eoe-output)
(insert (mapconcat #'org-babel-chomp
(list body org-babel-R-eoe-indicator)
"\n"))
(inferior-ess-send-input)))) 2) "\n")))))
"Evaluate R code in BODY."
(if session
(org-babel-R-evaluate-session
session body result-type column-names-p row-names-p)
(org-babel-R-evaluate-external-process
body result-type column-names-p row-names-p)))
(defun org-babel-R-evaluate-external-process
(body result-type column-names-p row-names-p)
"Evaluate BODY in external R process.
If RESULT-TYPE equals 'output then return standard output as a
string. If RESULT-TYPE equals 'value then return the value of the
last statement in BODY, as elisp."
(case result-type
(value
(let ((tmp-file (org-babel-temp-file "R-")))
(org-babel-eval org-babel-R-command
(format org-babel-R-write-object-command
(if row-names-p "TRUE" "FALSE")
(if column-names-p
(if row-names-p "NA" "TRUE")
"FALSE")
(format "{function ()\n{\n%s\n}}()" body)
(org-babel-tramp-localname tmp-file)))
(org-babel-R-process-value-result
(org-babel-import-elisp-from-file tmp-file '(16)) column-names-p)))
(output (org-babel-eval org-babel-R-command body))))
(defun org-babel-R-evaluate-session
(session body result-type column-names-p row-names-p)
"Evaluate BODY in SESSION.
If RESULT-TYPE equals 'output then return standard output as a
string. If RESULT-TYPE equals 'value then return the value of the
last statement in BODY, as elisp."
(case result-type
(value
(with-temp-buffer
(insert (org-babel-chomp body))
(let ((ess-local-process-name
(process-name (get-buffer-process session))))
(ess-eval-buffer nil)))
(let ((tmp-file (org-babel-temp-file "R-")))
(org-babel-comint-eval-invisibly-and-wait-for-file
session tmp-file
(format org-babel-R-write-object-command
(if row-names-p "TRUE" "FALSE")
(if column-names-p
(if row-names-p "NA" "TRUE")
"FALSE")
".Last.value" (org-babel-tramp-localname tmp-file)))
(org-babel-R-process-value-result
(org-babel-import-elisp-from-file tmp-file '(16)) column-names-p)))
(output
(mapconcat
#'org-babel-chomp
(butlast
(delq nil
(mapcar
(lambda (line) ;; cleanup extra prompts left in output
(if (string-match
"^\\([ ]*[>+][ ]?\\)+\\([[0-9]+\\|[ ]\\)" line)
(substring line (match-end 1))
line))
(org-babel-comint-with-output (session org-babel-R-eoe-output)
(insert (mapconcat #'org-babel-chomp
(list body org-babel-R-eoe-indicator)
"\n"))
(inferior-ess-send-input)))) 2) "\n"))))
(defun org-babel-R-process-value-result (result column-names-p)
"R-specific processing of return value.

View File

@ -73,7 +73,7 @@ This function is called by `org-babel-execute-src-block'."
(match-string 1 out-file))
"pdf"))
(cmdline (cdr (assoc :cmdline params)))
(in-file (make-temp-file "org-babel-asymptote"))
(in-file (org-babel-temp-file "asymptote-"))
(cmd (concat "asy "
(if out-file
(concat "-globalwrite -f " format " -o " out-file)

View File

@ -261,7 +261,7 @@ repl buffer."
" "))))
(case result-type
(output (org-babel-eval cmd body))
(value (let* ((tmp-file (make-temp-file "org-babel-clojure-results-")))
(value (let* ((tmp-file (org-babel-temp-file "clojure-results-")))
(org-babel-eval cmd (format org-babel-clojure-wrapper-method
body tmp-file tmp-file))
(org-babel-clojure-table-or-string

View File

@ -34,6 +34,8 @@
(require 'ob)
(require 'comint)
(eval-when-compile (require 'cl))
(declare-function with-parsed-tramp-file-name "tramp" (filename var &rest body))
(declare-function tramp-flush-directory-property "tramp" (vec directory))
(defun org-babel-comint-buffer-livep (buffer)
"Check if BUFFER is a comint buffer with a live process."
@ -136,6 +138,24 @@ statement (not large blocks of code)."
"comint-highlight-prompt"))))
(accept-process-output (get-buffer-process buffer)))))
(defun org-babel-comint-eval-invisibly-and-wait-for-file
(buffer file string &optional period)
"Evaluate STRING in BUFFER invisibly.
Don't return until FILE exists. Code in STRING must ensure that
FILE exists at end of evaluation."
(unless (org-babel-comint-buffer-livep buffer)
(error "buffer %s doesn't exist or has no process" buffer))
(if (file-exists-p file) (delete-file file))
(process-send-string
(get-buffer-process buffer)
(if (string-match "\n$" string) string (concat string "\n")))
;; From Tramp 2.1.19 the following cache flush is not necessary
(if (file-remote-p default-directory)
(let (v)
(with-parsed-tramp-file-name default-directory nil
(tramp-flush-directory-property v ""))))
(while (not (file-exists-p file)) (sit-for (or period 0.25))))
(provide 'ob-comint)
;; arch-tag: 9adddce6-0864-4be3-b0b5-6c5157dc7889

View File

@ -50,15 +50,18 @@
(defun org-babel-execute:ditaa (body params)
"Execute a block of Ditaa code with org-babel.
This function is called by `org-babel-execute-src-block'."
(let ((result-params (split-string (or (cdr (assoc :results params)) "")))
(out-file (cdr (assoc :file params)))
(cmdline (cdr (assoc :cmdline params)))
(in-file (make-temp-file "org-babel-ditaa")))
(let* ((result-params (split-string (or (cdr (assoc :results params)) "")))
(out-file (cdr (assoc :file params)))
(cmdline (cdr (assoc :cmdline params)))
(in-file (org-babel-temp-file "ditaa-"))
(cmd (concat "java -jar "
(shell-quote-argument
(expand-file-name org-ditaa-jar-path))
" " cmdline " " in-file " " out-file)))
(unless (file-exists-p org-ditaa-jar-path)
(error "Could not find ditaa.jar at %s" org-ditaa-jar-path))
(with-temp-file in-file (insert body))
(message (concat "java -jar " org-ditaa-jar-path " " cmdline " " in-file " " out-file))
(shell-command (concat "java -jar " (shell-quote-argument org-ditaa-jar-path) " " cmdline " " in-file " " out-file))
(message cmd) (shell-command cmd)
out-file))
(defun org-babel-prep-session:ditaa (session params)

View File

@ -70,7 +70,7 @@ This function is called by `org-babel-execute-src-block'."
(out-file (cdr (assoc :file params)))
(cmdline (cdr (assoc :cmdline params)))
(cmd (or (cdr (assoc :cmd params)) "dot"))
(in-file (make-temp-file "org-babel-dot")))
(in-file (org-babel-temp-file "dot-")))
(with-temp-file in-file
(insert (org-babel-expand-body:dot body params processed-params)))
(org-babel-eval (concat cmd " " in-file " " cmdline " -o " out-file) "")

View File

@ -28,15 +28,12 @@
;;; Code:
(require 'ob)
(eval-when-compile (require 'ob-comint))
(defvar org-babel-default-header-args:emacs-lisp
'((:hlines . "yes") (:colnames . "no"))
"Default arguments for evaluating an emacs-lisp source block.")
(declare-function org-babel-comint-with-output "ob-comint" (&rest body))
(declare-function org-babel-comint-buffer-livep "ob-comint" (buffer))
(declare-function org-babel-comint-wait-for-output "ob-comint" (buffer))
(declare-function org-babel-comint-in-buffer "ob-comint" (buffer &rest body))
(declare-function orgtbl-to-generic "org-table" (table params))
(defun org-babel-expand-body:emacs-lisp (body params &optional processed-params)

View File

@ -178,6 +178,8 @@ options are taken from `org-babel-default-header-args'."
(list "emacs-lisp" "results"
(org-babel-merge-params
org-babel-default-header-args
(org-babel-params-from-buffer)
(org-babel-params-from-properties)
(org-babel-parse-header-arguments
(org-babel-clean-text-properties
(concat ":var results="
@ -193,8 +195,7 @@ options are taken from `org-babel-default-header-args'."
The function respects the value of the :exports header argument."
(flet ((silently () (let ((session (cdr (assoc :session (nth 2 info)))))
(when (and session
(not (equal "none" session))
(not (assoc :noeval (nth 2 info))))
(not (equal "none" session)))
(org-babel-exp-results info type 'silent))))
(clean () (org-babel-remove-result info)))
(case (intern (or (cdr (assoc :exports (nth 2 info))) "code"))

View File

@ -68,7 +68,7 @@ code."
(car pair) ;; variable name
(if (listp (cdr pair)) ;; variable value
(org-babel-gnuplot-table-to-data
(cdr pair) (make-temp-file "org-babel-gnuplot") params)
(cdr pair) (org-babel-temp-file "gnuplot") params)
(cdr pair))))
(org-babel-ref-variables params)))
@ -141,7 +141,7 @@ This function is called by `org-babel-execute-src-block'."
(save-window-excursion
;; evaluate the code body with gnuplot
(if (string= session "none")
(let ((script-file (make-temp-file "org-babel-gnuplot-script")))
(let ((script-file (org-babel-temp-file "gnuplot-script")))
(with-temp-file script-file
(insert (concat body "\n")))
(message "gnuplot \"%s\"" script-file)

View File

@ -116,7 +116,7 @@ then create one. Return the initialized session."
(save-window-excursion
(let* ((buffer (org-babel-prep-session:haskell
session params processed-params))
(load-file (concat (make-temp-file "org-babel-haskell-load") ".hs")))
(load-file (concat (org-babel-temp-file "haskell-load-") ".hs")))
(with-temp-buffer
(insert body) (write-file load-file)
(haskell-mode) (inferior-haskell-load-file))
@ -177,7 +177,7 @@ constructs (header arguments, no-web syntax etc...) are ignored."
(concat "^\\([ \t]*\\)#\\+begin_src[ \t]haskell*\\(.*\\)?[\r\n]"
"\\([^\000]*?\\)[\r\n][ \t]*#\\+end_src.*"))
(base-name (file-name-sans-extension (buffer-file-name)))
(tmp-file (make-temp-file "ob-haskell"))
(tmp-file (org-babel-temp-file "haskell-"))
(tmp-org-file (concat tmp-file ".org"))
(tmp-tex-file (concat tmp-file ".tex"))
(lhs-file (concat base-name ".lhs"))

170
lisp/ob-js.el Normal file
View File

@ -0,0 +1,170 @@
;;; ob-js.el --- org-babel functions for Javascript
;; Copyright (C) 2010 Free Software Foundation
;; Author: Eric Schulte
;; Keywords: literate programming, reproducible research, js
;; Homepage: http://orgmode.org
;; Version: 0.01
;;; License:
;; 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 3, 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 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:
;; Now working with SBCL for both session and external evaluation.
;;
;; This certainly isn't optimally robust, but it seems to be working
;; for the basic use cases.
;;; Requirements:
;; - a non-browser javascript engine such as node.js http://nodejs.org/
;; or mozrepl http://wiki.github.com/bard/mozrepl/
;;
;; - for session based evaluation mozrepl and moz.el are required see
;; http://wiki.github.com/bard/mozrepl/emacs-integration for
;; configuration instructions
;;; Code:
(require 'ob)
(require 'ob-ref)
(require 'ob-comint)
(require 'ob-eval)
(eval-when-compile (require 'cl))
(declare-function run-mozilla "ext:moz" (arg))
(defvar org-babel-default-header-args:js '()
"Default header arguments for js code blocks.")
(defvar org-babel-js-eoe "org-babel-js-eoe"
"String to indicate that evaluation has completed.")
(defcustom org-babel-js-cmd "node"
"Name of command used to evaluate js blocks."
:group 'org-babel
:type 'string)
(defvar org-babel-js-function-wrapper
"require('sys').print(require('sys').inspect(function(){%s}()));"
"Javascript code to print value of body.")
(defun org-babel-expand-body:js (body params &optional processed-params)
"Expand BODY according to PARAMS, return the expanded body."
(let ((vars (nth 1 (or processed-params (org-babel-process-params params)))))
(concat
(mapconcat ;; define any variables
(lambda (pair) (format "var %s=%s;"
(car pair) (org-babel-js-var-to-js (cdr pair))))
vars "\n") "\n" body "\n")))
(defun org-babel-execute:js (body params)
"Execute a block of Javascript code with org-babel.
This function is called by `org-babel-execute-src-block'"
(let* ((processed-params (org-babel-process-params params))
(org-babel-js-cmd (or (cdr (assoc :cmd params)) org-babel-js-cmd))
(result-type (nth 3 processed-params))
(full-body (org-babel-expand-body:js body params processed-params)))
(org-babel-js-read
(if (not (string= (nth 0 processed-params) "none"))
;; session evaluation
(let ((session (org-babel-prep-session:js
(nth 0 processed-params) params)))
(nth 1
(org-babel-comint-with-output
(session (format "%S" org-babel-js-eoe) t body)
(mapc
(lambda (line)
(insert (org-babel-chomp line)) (comint-send-input nil t))
(list body (format "%S" org-babel-js-eoe))))))
;; external evaluation
(let ((script-file (org-babel-temp-file "js-script-")))
(with-temp-file script-file
(insert
;; return the value or the output
(if (string= result-type "value")
(format org-babel-js-function-wrapper full-body)
full-body)))
(org-babel-eval (format "%s %s" org-babel-js-cmd script-file) ""))))))
(defun org-babel-js-read (results)
"Convert RESULTS into an appropriate elisp value.
If RESULTS look like a table, then convert them into an
Emacs-lisp table, otherwise return the results as a string."
(org-babel-read
(if (and (stringp results) (string-match "^\\[.+\\]$" results))
(org-babel-read
(concat "'"
(replace-regexp-in-string
"\\[" "(" (replace-regexp-in-string
"\\]" ")" (replace-regexp-in-string
", " " " (replace-regexp-in-string
"'" "\"" results))))))
results)))
(defun org-babel-js-var-to-js (var)
"Convert VAR into a js variable.
Convert an elisp value into a string of js source code
specifying a variable of the same value."
(if (listp var)
(concat "[" (mapconcat #'org-babel-js-var-to-js var ", ") "]")
(format "%S" var)))
(defun org-babel-prep-session:js (session params)
"Prepare SESSION according to the header arguments specified in PARAMS."
(let* ((session (org-babel-js-initiate-session session))
(vars (org-babel-ref-variables params))
(var-lines
(mapcar
(lambda (pair) (format "var %s=%s;"
(car pair) (org-babel-js-var-to-js (cdr pair))))
vars)))
(when session
(org-babel-comint-in-buffer session
(sit-for .5) (goto-char (point-max))
(mapc (lambda (var)
(insert var) (comint-send-input nil t)
(org-babel-comint-wait-for-output session)
(sit-for .1) (goto-char (point-max))) var-lines)))
session))
(defun org-babel-js-initiate-session (&optional session)
"If there is not a current inferior-process-buffer in SESSION
then create. Return the initialized session."
(unless (string= session "none")
(cond
((string= "mozrepl" org-babel-js-cmd)
(require 'moz)
(let ((session-buffer (save-window-excursion
(run-mozilla nil)
(rename-buffer session)
(current-buffer))))
(if (org-babel-comint-buffer-livep session-buffer)
(progn (sit-for .25) session-buffer)
(sit-for .5)
(org-babel-js-initiate-session session))))
((string= "node" org-babel-js-cmd )
(error "session evaluation with node.js is not supported"))
(t
(error "sessions are only supported with mozrepl add \":cmd mozrepl\"")))))
(provide 'ob-js)
;; arch-tag: 84401fb3-b8d9-4bb6-9a90-cbe2d103d494
;;; ob-js.el ends here

View File

@ -58,6 +58,8 @@ functions which are assigned key bindings, and see
("\C-o" . org-babel-open-src-block-result)
("\C-v" . org-babel-expand-src-block)
("v" . org-babel-expand-src-block)
("u" . org-babel-goto-src-block-head)
("\C-u" . org-babel-goto-src-block-head)
("g" . org-babel-goto-named-src-block)
("r" . org-babel-goto-named-result)
("\C-r" . org-babel-goto-named-result)
@ -74,10 +76,12 @@ functions which are assigned key bindings, and see
("\C-i" . org-babel-lob-ingest)
("i" . org-babel-lob-ingest)
("\C-z" . org-babel-switch-to-session)
("z" . org-babel-switch-to-session)
("z" . org-babel-switch-to-session-with-code)
("\C-a" . org-babel-sha1-hash)
("a" . org-babel-sha1-hash)
("h" . org-babel-describe-bindings))
("h" . org-babel-describe-bindings)
("\C-x" . org-babel-do-key-sequence-in-edit-buffer)
("x" . org-babel-do-key-sequence-in-edit-buffer))
"Alist of key bindings and interactive Babel functions.
This list associates interactive Babel functions
with keys. Each element of this list will add an entry to the

View File

@ -37,9 +37,18 @@
(declare-function org-splice-latex-header "org"
(tpl def-pkg pkg snippets-p &optional extra))
(declare-function org-export-latex-fix-inputenc "org-latex" ())
(add-to-list 'org-babel-tangle-lang-exts '("latex" . "tex"))
(defvar org-format-latex-header)
(defvar org-format-latex-header-extra)
(defvar org-export-latex-packages-alist)
(defvar org-export-latex-default-packages-alist)
(defvar org-export-pdf-logfiles)
(defvar org-latex-to-pdf-process)
(defvar org-export-pdf-remove-logfiles)
(defvar org-format-latex-options)
(defvar org-export-latex-packages-alist)
(defvar org-babel-default-header-args:latex
'((:results . "latex") (:exports . "results"))
"Default arguments to use when evaluating a LaTeX source block.")
@ -53,29 +62,54 @@
(if (stringp (cdr pair))
(cdr pair) (format "%S" (cdr pair)))
body))) (nth 1 (org-babel-process-params params)))
body)
(org-babel-trim body))
(defvar org-format-latex-options)
(defvar org-export-latex-packages-alist)
(defun org-babel-execute:latex (body params)
"Execute a block of Latex code with Babel.
This function is called by `org-babel-execute-src-block'."
(setq body (org-babel-expand-body:latex body params))
(if (cdr (assoc :file params))
(let ((out-file (cdr (assoc :file params)))
(tex-file (make-temp-file "org-babel-latex" nil ".tex"))
(pdfheight (cdr (assoc :pdfheight params)))
(pdfwidth (cdr (assoc :pdfwidth params)))
(in-buffer (not (string= "no" (cdr (assoc :buffer params)))))
(org-export-latex-packages-alist
(append (cdr (assoc :packages params))
org-export-latex-packages-alist)))
(let* ((out-file (cdr (assoc :file params)))
(tex-file (org-babel-temp-file "latex-" ".tex"))
(border (cdr (assoc :border params)))
(fit (or (cdr (assoc :fit params)) border))
(height (and fit (cdr (assoc :pdfheight params))))
(width (and fit (cdr (assoc :pdfwidth params))))
(in-buffer (not (string= "no" (cdr (assoc :buffer params)))))
(org-export-latex-packages-alist
(append (cdr (assoc :packages params))
org-export-latex-packages-alist)))
(cond
((string-match "\\.png$" out-file)
(org-create-formula-image
body out-file org-format-latex-options in-buffer))
((string-match "\\.pdf$" out-file)
(org-babel-latex-body-to-tex-file tex-file body pdfheight pdfwidth)
(require 'org-latex)
(with-temp-file tex-file
(insert
(org-splice-latex-header
org-format-latex-header
(delq
nil
(mapcar
(lambda (el)
(unless (and (listp el) (string= "hyperref" (cadr el)))
el))
org-export-latex-default-packages-alist))
org-export-latex-packages-alist
org-format-latex-header-extra)
(if fit "\n\\usepackage[active, tightpage]{preview}\n" "")
(if border (format "\\setlength{\\PreviewBorder}{%s}" border) "")
(if height (concat "\n" (format "\\pdfpageheight %s" height)) "")
(if width (concat "\n" (format "\\pdfpagewidth %s" width)) "")
(if org-format-latex-header-extra
(concat "\n" org-format-latex-header-extra)
"")
(if fit
(concat "\n\\begin{document}\n\\begin{preview}\n" body
"\n\\end{preview}\n\\end{document}\n")
(concat "\n\\begin{document}\n" body "\n\\end{document}\n")))
(org-export-latex-fix-inputenc))
(when (file-exists-p out-file) (delete-file out-file))
(rename-file (org-babel-latex-tex-to-pdf tex-file) out-file))
((string-match "\\.\\([^\\.]+\\)$" out-file)
@ -84,67 +118,48 @@ This function is called by `org-babel-execute-src-block'."
out-file)
body))
(defvar org-format-latex-header)
(defvar org-format-latex-header-extra)
(defvar org-export-latex-packages-alist)
(defvar org-export-latex-default-packages-alist)
(defun org-babel-latex-body-to-tex-file (tex-file body &optional height width)
"Place the contents of BODY into TEX-FILE.
Extracted from `org-create-formula-image' in org.el."
(with-temp-file tex-file
(insert (org-splice-latex-header
org-format-latex-header
(delq
nil
(mapcar
(lambda (el) (unless (and (listp el) (string= "hyperref" (cadr el)))
el))
org-export-latex-default-packages-alist))
org-export-latex-packages-alist
org-format-latex-header-extra)
(if height (concat "\n" (format "\\pdfpageheight %s" height)) "")
(if width (concat "\n" (format "\\pdfpagewidth %s" width)) "")
(if org-format-latex-header-extra
(concat "\n" org-format-latex-header-extra)
"")
"\n\\begin{document}\n" body "\n\\end{document}\n")
(org-export-latex-fix-inputenc)))
(defvar org-export-pdf-logfiles)
(defvar org-latex-to-pdf-process)
(defvar org-export-pdf-remove-logfiles)
(defun org-babel-latex-tex-to-pdf (tex-file)
"Generate a pdf file according to the contents TEX-FILE.
(defun org-babel-latex-tex-to-pdf (file)
"Generate a pdf file according to the contents FILE.
Extracted from `org-export-as-pdf' in org-latex.el."
(let* ((wconfig (current-window-configuration))
(default-directory (file-name-directory tex-file))
(base (file-name-sans-extension tex-file))
(default-directory (file-name-directory file))
(base (file-name-sans-extension file))
(pdffile (concat base ".pdf"))
(cmds org-latex-to-pdf-process)
(outbuf (get-buffer-create "*Org PDF LaTeX Output*"))
cmd)
output-dir cmd)
(with-current-buffer outbuf (erase-buffer))
(message (concat "Processing LaTeX file " file "..."))
(setq output-dir (file-name-directory file))
(if (and cmds (symbolp cmds))
(funcall cmds tex-file)
(funcall cmds (shell-quote-argument file))
(while cmds
(setq cmd (pop cmds))
(while (string-match "%b" cmd)
(setq cmd (replace-match
(save-match-data
(shell-quote-argument base))
t t cmd)))
(while (string-match "%s" cmd)
(setq cmd (replace-match
(save-match-data
(shell-quote-argument tex-file))
t t cmd)))
(shell-command cmd outbuf outbuf)))
(setq cmd (pop cmds))
(while (string-match "%b" cmd)
(setq cmd (replace-match
(save-match-data
(shell-quote-argument base))
t t cmd)))
(while (string-match "%f" cmd)
(setq cmd (replace-match
(save-match-data
(shell-quote-argument file))
t t cmd)))
(while (string-match "%o" cmd)
(setq cmd (replace-match
(save-match-data
(shell-quote-argument output-dir))
t t cmd)))
(shell-command cmd outbuf outbuf)))
(message (concat "Processing LaTeX file " file "...done"))
(if (not (file-exists-p pdffile))
(error "PDF file was not produced from %s" tex-file)
(error (concat "PDF file " pdffile " was not produced"))
(set-window-configuration wconfig)
(when org-export-pdf-remove-logfiles
(dolist (ext org-export-pdf-logfiles)
(setq tex-file (concat base "." ext))
(and (file-exists-p tex-file) (delete-file tex-file))))
(dolist (ext org-export-pdf-logfiles)
(setq file (concat base "." ext))
(and (file-exists-p file) (delete-file file))))
(message "Exporting to PDF...done")
pdffile)))
(defun org-babel-prep-session:latex (session params)

View File

@ -38,7 +38,6 @@
;;; Code:
(require 'ob)
(require 'org)
(defvar org-babel-default-header-args:ledger
'((:results . "output") (:cmdline . "bal"))
@ -50,8 +49,8 @@ called by `org-babel-execute-src-block'."
(message "executing Ledger source code block")
(let ((result-params (split-string (or (cdr (assoc :results params)) "")))
(cmdline (cdr (assoc :cmdline params)))
(in-file (make-temp-file "org-babel-ledger"))
(out-file (make-temp-file "org-babel-ledger-output"))
(in-file (org-babel-temp-file "ledger-"))
(out-file (org-babel-temp-file "ledger-output-"))
)
(with-temp-file in-file (insert body))
(message (concat "ledger -f " in-file " " cmdline))

View File

@ -74,7 +74,7 @@ This function is called by `org-babel-execute-src-block'"
(save-window-excursion
(cadr (slime-eval `(swank:eval-and-grab-output ,full-body))))
;; external evaluation
(let ((script-file (make-temp-file "ob-lisp-script")))
(let ((script-file (org-babel-temp-file "lisp-script-")))
(with-temp-file script-file
(insert
;; return the value or the output

View File

@ -79,14 +79,7 @@ if so then run the appropriate source block from the Library."
;;;###autoload
(defun org-babel-lob-get-info ()
"Return a Library of Babel function call as a string.
This function is analogous to org-babel-get-src-block-name. For
both functions, after they are called, (match-string 1) matches
the function name, and (match-string 2) matches the function
arguments inside the parentheses. I think perhaps these functions
should be renamed to bring out this similarity, perhaps involving
the word 'call'."
"Return a Library of Babel function call as a string."
(let ((case-fold-search t))
(save-excursion
(beginning-of-line 1)

View File

@ -178,7 +178,7 @@ value of the last statement in BODY, as elisp."
org-babel-octave-shell-command)))
(case result-type
(output (org-babel-eval cmd body))
(value (let ((tmp-file (make-temp-file "org-babel-results-")))
(value (let ((tmp-file (org-babel-temp-file "results-")))
(org-babel-eval
cmd
(format org-babel-octave-wrapper-method body tmp-file tmp-file))
@ -188,8 +188,8 @@ value of the last statement in BODY, as elisp."
(defun org-babel-octave-evaluate-session
(session body result-type &optional matlabp)
"Evaluate BODY in SESSION."
(let* ((tmp-file (make-temp-file "org-babel-results-"))
(wait-file (make-temp-file "org-babel-matlab-emacs-link-wait-signal-"))
(let* ((tmp-file (org-babel-temp-file "results-"))
(wait-file (org-babel-temp-file "matlab-emacs-link-wait-signal-"))
(full-body
(case result-type
(output
@ -246,7 +246,7 @@ value of the last statement in BODY, as elisp."
"Import data from FILE-NAME.
This removes initial blank and comment lines and then calls
`org-babel-import-elisp-from-file'."
(let ((temp-file (make-temp-file "org-babel-results-")) beg end)
(let ((temp-file (org-babel-temp-file "results-")) beg end)
(with-temp-file temp-file
(insert-file-contents file-name)
(re-search-forward "^[ \t]*[^# \t]" nil t)

81
lisp/ob-org.el Normal file
View File

@ -0,0 +1,81 @@
;;; ob-org.el --- org-babel functions for org code block evaluation
;; Copyright (C) 2010 Free Software Foundation, Inc.
;; Author: Eric Schulte
;; Keywords: literate programming, reproducible research
;; Homepage: http://orgmode.org
;; Version: 7.01trans
;; 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 of the License, 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. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; This is the simplest of code blocks, where upon evaluation the
;; contents of the code block are returned in a raw result.
;;; Code:
(require 'ob)
(declare-function org-load-modules-maybe "org" (&optional force))
(declare-function org-get-local-variables "org" ())
(defvar org-babel-default-header-args:org
'((:results . "raw silent") (:exports . "results"))
"Default arguments for evaluating a org source block.")
(defvar org-babel-org-default-header
"#+TITLE: default empty header\n"
"Default header inserted during export of org blocks.")
(defun org-babel-expand-body:org (body params &optional processed-params)
"Expand BODY according to PARAMS, return the expanded body." body)
(defun org-babel-execute:org (body params)
"Execute a block of Org code with.
This function is called by `org-babel-execute-src-block'."
(let ((result-params (split-string (or (cdr (assoc :results params)) ""))))
(cond
((member "latex" result-params) (org-babel-org-export body "latex"))
((member "html" result-params) (org-babel-org-export body "html"))
((member "ascii" result-params) (org-babel-org-export body "ascii"))
(t body))))
(defvar org-local-vars)
(defun org-babel-org-export (body fmt)
"Export BODY to FMT using Org-mode's export facilities. "
(let ((tmp-file (org-babel-temp-file "org-")))
(with-temp-buffer
(insert org-babel-org-default-header)
(insert body)
(write-file tmp-file)
(org-load-modules-maybe)
(unless org-local-vars
(setq org-local-vars (org-get-local-variables)))
(eval ;; convert to fmt -- mimicing `org-run-like-in-org-mode'
(list 'let org-local-vars
(list (intern (concat "org-export-as-" fmt))
nil nil nil ''string t))))))
(defun org-babel-prep-session:org (session params)
"Return an error because org does not support sessions."
(error "Org does not support sessions"))
(provide 'ob-org)
;; arch-tag: 130af5fe-cc56-46bd-9508-fa0ebd94cb1f
;;; ob-org.el ends here

View File

@ -107,7 +107,7 @@ return the value of the last statement in BODY, as elisp."
(when session (error "Sessions are not supported for Perl."))
(case result-type
(output (org-babel-eval org-babel-perl-command body))
(value (let ((tmp-file (make-temp-file "org-babel-perl-results-")))
(value (let ((tmp-file (org-babel-temp-file "perl-results-")))
(org-babel-eval
org-babel-perl-command
(format org-babel-perl-wrapper-method body tmp-file))

86
lisp/ob-plantuml.el Normal file
View File

@ -0,0 +1,86 @@
;;; ob-plantuml.el --- org-babel functions for plantuml evaluation
;; Copyright (C) 2010 Free Software Foundation, Inc.
;; Author: Zhang Weize
;; Keywords: literate programming, reproducible research
;; Homepage: http://orgmode.org
;; Version: 7.01trans
;; 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 of the License, 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. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; Org-Babel support for evaluating plantuml script.
;;
;; Inspired by Ian Yang's org-export-blocks-format-plantuml
;; http://www.emacswiki.org/emacs/org-export-blocks-format-plantuml.el
;;; Requirements:
;; plantuml | http://plantuml.sourceforge.net/
;; plantuml.jar | `org-plantuml-jar-path' should point to the jar file
;;; Code:
(require 'ob)
(require 'ob-eval)
(defvar org-babel-default-header-args:plantuml
'((:results . "file") (:exports . "results"))
"Default arguments for evaluating a plantuml source block.")
(defun org-babel-expand-body:plantuml (body params &optional processed-params)
"Expand BODY according to PARAMS, return the expanded body." body)
(defcustom org-plantuml-jar-path nil
"Path to the plantuml.jar file."
:group 'org-babel
:type 'string)
(defun org-babel-execute:plantuml (body params)
"Execute a block of plantuml code with org-babel.
This function is called by `org-babel-execute-src-block'."
(let* ((result-params (split-string (or (cdr (assoc :results params)) "")))
(out-file (or (cdr (assoc :file params))
(error "plantuml requires a \":file\" header argument")))
(cmdline (cdr (assoc :cmdline params)))
(in-file (org-babel-temp-file "plantuml-"))
(cmd (if (not org-plantuml-jar-path)
(error "`org-plantuml-jar-path' is not set")
(concat "java -jar "
(shell-quote-argument
(expand-file-name org-plantuml-jar-path))
" -p " cmdline " < "
(shell-quote-argument
(expand-file-name in-file))
" > "
(shell-quote-argument
(expand-file-name out-file))))))
(unless (file-exists-p org-plantuml-jar-path)
(error "Could not find plantuml.jar at %s" org-plantuml-jar-path))
(with-temp-file in-file (insert (concat "@startuml\n" body "\n@enduml")))
(message "%s" cmd) (org-babel-eval cmd "")
out-file))
(defun org-babel-prep-session:plantuml (session params)
"Return an error because plantuml does not support sessions."
(error "Plantuml does not support sessions"))
(provide 'ob-plantuml)
;; arch-tag: 451f50c5-e779-407e-ad64-70e0e8f161d1
;;; ob-plantuml.el ends here

View File

@ -150,10 +150,10 @@ then create. Return the initialized session."
(let* ((session (if session (intern session) :default))
(python-buffer (org-babel-python-session-buffer session)))
(cond
((and (equal 'python org-babel-python-mode)
((and (eq 'python org-babel-python-mode)
(fboundp 'run-python)) ; python.el
(run-python))
((and (equal 'python-mode org-babel-python-mode)
((and (eq 'python-mode org-babel-python-mode)
(fboundp 'py-shell)) ; python-mode.el
;; `py-shell' creates a buffer whose name is the value of
;; `py-which-bufname' with '*'s at the beginning and end
@ -194,73 +194,87 @@ def main():
open('%s', 'w').write( pprint.pformat(main()) )")
(defun org-babel-python-evaluate
(buffer body &optional result-type result-params)
"Pass BODY to the Python process in BUFFER.
If RESULT-TYPE equals 'output then return a list of the outputs
of the statements in BODY, if RESULT-TYPE equals 'value then
return the value of the last statement in BODY, as elisp."
(if (not buffer)
;; external process evaluation
(case result-type
(output (org-babel-eval org-babel-python-command body))
(value (let ((tmp-file (make-temp-file "org-babel-python-results-")))
(org-babel-eval org-babel-python-command
(format
(if (member "pp" result-params)
org-babel-python-pp-wrapper-method
org-babel-python-wrapper-method)
(mapconcat
(lambda (line) (format "\t%s" line))
(split-string
(org-remove-indentation
(org-babel-trim body))
"[\r\n]") "\n")
tmp-file))
((lambda (raw)
(if (or (member "code" result-params)
(member "pp" result-params))
raw
(org-babel-python-table-or-string raw)))
(org-babel-eval-read-file tmp-file)))))
;; comint session evaluation
(flet ((dump-last-value (tmp-file pp)
(mapc
(lambda (statement) (insert statement) (comint-send-input))
(if pp
(list
"import pp"
(format "open('%s', 'w').write(pprint.pformat(_))" tmp-file))
(list (format "open('%s', 'w').write(str(_))" tmp-file)))))
(input-body (body)
(mapc (lambda (statement) (insert statement) (comint-send-input))
(split-string (org-babel-trim body) "[\r\n]+"))
(comint-send-input) (comint-send-input)))
(case result-type
(output
(mapconcat
#'org-babel-trim
(butlast
(org-babel-comint-with-output
(buffer org-babel-python-eoe-indicator t body)
(let ((comint-process-echoes nil))
(input-body body)
(insert org-babel-python-eoe-indicator)
(comint-send-input))) 2) "\n"))
(value
((lambda (results)
(if (or (member "code" result-params) (member "pp" result-params))
results
(org-babel-python-table-or-string results)))
(let ((tmp-file (make-temp-file "org-babel-python-results-")))
(org-babel-comint-with-output
(buffer org-babel-python-eoe-indicator t body)
(let ((comint-process-echoes nil))
(input-body body)
(dump-last-value tmp-file (member "pp" result-params))
(comint-send-input) (comint-send-input)
(insert org-babel-python-eoe-indicator)
(comint-send-input)))
(org-babel-eval-read-file tmp-file))))))))
(session body &optional result-type result-params)
"Evaluate BODY as python code."
(if session
(org-babel-python-evaluate-session
session body result-type result-params)
(org-babel-python-evaluate-external-process
body result-type result-params)))
(defun org-babel-python-evaluate-external-process
(body &optional result-type result-params)
"Evaluate BODY in external python process.
If RESULT-TYPE equals 'output then return standard output as a
string. If RESULT-TYPE equals 'value then return the value of the
last statement in BODY, as elisp."
(case result-type
(output (org-babel-eval org-babel-python-command body))
(value (let ((tmp-file (org-babel-temp-file "python-results-")))
(org-babel-eval org-babel-python-command
(format
(if (member "pp" result-params)
org-babel-python-pp-wrapper-method
org-babel-python-wrapper-method)
(mapconcat
(lambda (line) (format "\t%s" line))
(split-string
(org-remove-indentation
(org-babel-trim body))
"[\r\n]") "\n")
tmp-file))
((lambda (raw)
(if (or (member "code" result-params)
(member "pp" result-params))
raw
(org-babel-python-table-or-string raw)))
(org-babel-eval-read-file tmp-file))))))
(defun org-babel-python-evaluate-session
(session body &optional result-type result-params)
"Pass BODY to the Python process in SESSION.
If RESULT-TYPE equals 'output then return standard output as a
string. If RESULT-TYPE equals 'value then return the value of the
last statement in BODY, as elisp."
(flet ((dump-last-value
(tmp-file pp)
(mapc
(lambda (statement) (insert statement) (comint-send-input))
(if pp
(list
"import pp"
(format "open('%s', 'w').write(pprint.pformat(_))" tmp-file))
(list (format "open('%s', 'w').write(str(_))" tmp-file)))))
(input-body (body)
(mapc (lambda (statement) (insert statement) (comint-send-input))
(split-string (org-babel-trim body) "[\r\n]+"))
(comint-send-input) (comint-send-input)))
(case result-type
(output
(mapconcat
#'org-babel-trim
(butlast
(org-babel-comint-with-output
(session org-babel-python-eoe-indicator t body)
(let ((comint-process-echoes nil))
(input-body body)
(insert org-babel-python-eoe-indicator)
(comint-send-input))) 2) "\n"))
(value
((lambda (results)
(if (or (member "code" result-params) (member "pp" result-params))
results
(org-babel-python-table-or-string results)))
(let ((tmp-file (org-babel-temp-file "python-results-")))
(org-babel-comint-with-output
(session org-babel-python-eoe-indicator t body)
(let ((comint-process-echoes nil))
(input-body body)
(dump-last-value tmp-file (member "pp" result-params))
(comint-send-input) (comint-send-input)
(insert org-babel-python-eoe-indicator)
(comint-send-input)))
(org-babel-eval-read-file tmp-file)))))))
(defun org-babel-python-read-string (string)
"Strip 's from around python string"

View File

@ -54,7 +54,6 @@
(defun org-babel-expand-body:ruby (body params &optional processed-params)
"Expand BODY according to PARAMS, return the expanded body."
(require 'inf-ruby)
(let ((vars (nth 1 (or processed-params (org-babel-process-params params)))))
(concat
(mapconcat ;; define any variables
@ -186,7 +185,7 @@ return the value of the last statement in BODY, as elisp."
;; external process evaluation
(case result-type
(output (org-babel-eval org-babel-ruby-command body))
(value (let ((tmp-file (make-temp-file "org-babel-ruby-results-")))
(value (let ((tmp-file (org-babel-temp-file "ruby-results-")))
(org-babel-eval org-babel-ruby-command
(format (if (member "pp" result-params)
org-babel-ruby-pp-wrapper-method
@ -221,7 +220,7 @@ return the value of the last statement in BODY, as elisp."
(if (or (member "code" result-params) (member "pp" result-params))
results
(org-babel-ruby-table-or-string results)))
(let* ((tmp-file (make-temp-file "org-babel-ruby-results-"))
(let* ((tmp-file (org-babel-temp-file "ruby-results-"))
(ppp (or (member "code" result-params)
(member "pp" result-params))))
(org-babel-comint-with-output

View File

@ -51,9 +51,9 @@
This function is called by `org-babel-execute-src-block'."
(let* ((result-params (split-string (or (cdr (assoc :results params)) "")))
(file (cdr (assoc :file params)))
(out-file (or file (make-temp-file "org-babel-sass-out")))
(out-file (or file (org-babel-temp-file "sass-out-")))
(cmdline (cdr (assoc :cmdline params)))
(in-file (make-temp-file "org-babel-sass-in"))
(in-file (org-babel-temp-file "sass-in-"))
(cmd (concat "sass " (or cmdline "") in-file " " out-file)))
(with-temp-file in-file
(insert (org-babel-expand-body:sass body params))) (shell-command cmd)

138
lisp/ob-scheme.el Normal file
View File

@ -0,0 +1,138 @@
;;; ob-scheme.el --- org-babel functions for Scheme
;; Copyright (C) 2010 Free Software Foundation
;; Author: Eric Schulte
;; Keywords: literate programming, reproducible research, scheme
;; Homepage: http://orgmode.org
;; Version: 0.01
;;; License:
;; 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 3, 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 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:
;; Now working with SBCL for both session and external evaluation.
;;
;; This certainly isn't optimally robust, but it seems to be working
;; for the basic use cases.
;;; Requirements:
;; - a working scheme implementation
;; (e.g. guile http://www.gnu.org/software/guile/guile.html)
;;
;; - for session based evaluation cmuscheme.el is required which is
;; included in Emacs
;;; Code:
(require 'ob)
(require 'ob-ref)
(require 'ob-comint)
(require 'ob-eval)
(eval-when-compile (require 'cl))
(declare-function run-scheme "ext:cmuscheme" (cmd))
(defvar org-babel-default-header-args:scheme '()
"Default header arguments for scheme code blocks.")
(defvar org-babel-scheme-eoe "org-babel-scheme-eoe"
"String to indicate that evaluation has completed.")
(defcustom org-babel-scheme-cmd "guile"
"Name of command used to evaluate scheme blocks."
:group 'org-babel
:type 'string)
(defun org-babel-expand-body:scheme (body params &optional processed-params)
"Expand BODY according to PARAMS, return the expanded body."
(let ((vars (nth 1 (or processed-params (org-babel-process-params params)))))
(if (> (length vars) 0)
(concat "(let ("
(mapconcat
(lambda (var) (format "%S" (print `(,(car var) ',(cdr var)))))
vars "\n ")
")\n" body ")")
body)))
(defvar scheme-program-name)
(defun org-babel-execute:scheme (body params)
"Execute a block of Scheme code with org-babel.
This function is called by `org-babel-execute-src-block'"
(let* ((processed-params (org-babel-process-params params))
(result-type (nth 3 processed-params))
(org-babel-scheme-cmd (or (cdr (assoc :scheme params)) org-babel-scheme-cmd))
(full-body (org-babel-expand-body:scheme body params processed-params)))
(read
(if (not (string= (nth 0 processed-params) "none"))
;; session evaluation
(let ((session (org-babel-prep-session:scheme
(nth 0 processed-params) params)))
(org-babel-comint-with-output
(session (format "%S" org-babel-scheme-eoe) t body)
(mapc
(lambda (line)
(insert (org-babel-chomp line)) (comint-send-input nil t))
(list body (format "%S" org-babel-scheme-eoe)))))
;; external evaluation
(let ((script-file (org-babel-temp-file "lisp-script-")))
(with-temp-file script-file
(insert
;; return the value or the output
(if (string= result-type "value")
(format "(display %s)" full-body)
full-body)))
(org-babel-eval
(format "%s %s" org-babel-scheme-cmd script-file) ""))))))
(defun org-babel-prep-session:scheme (session params)
"Prepare SESSION according to the header arguments specified in PARAMS."
(let* ((session (org-babel-scheme-initiate-session session))
(vars (org-babel-ref-variables params))
(var-lines
(mapcar
(lambda (var) (format "%S" (print `(define ,(car var) ',(cdr var)))))
vars)))
(when session
(org-babel-comint-in-buffer session
(sit-for .5) (goto-char (point-max))
(mapc (lambda (var)
(insert var) (comint-send-input nil t)
(org-babel-comint-wait-for-output session)
(sit-for .1) (goto-char (point-max))) var-lines)))
session))
(defun org-babel-scheme-initiate-session (&optional session)
"If there is not a current inferior-process-buffer in SESSION
then create. Return the initialized session."
(require 'cmuscheme)
(unless (string= session "none")
(let ((session-buffer (save-window-excursion
(run-scheme org-babel-scheme-cmd)
(rename-buffer session)
(current-buffer))))
(if (org-babel-comint-buffer-livep session-buffer)
(progn (sit-for .25) session-buffer)
(sit-for .5)
(org-babel-scheme-initiate-session session)))))
(provide 'ob-scheme)
;; arch-tag: 6b2fe76f-4b25-4e87-ad1c-225b2f282a71
;;; ob-scheme.el ends here

View File

@ -155,12 +155,12 @@ return the value of the last statement in BODY."
(if (or (member "scalar" result-params)
(member "output" result-params))
results
(let ((tmp-file (make-temp-file "org-babel-sh")))
(let ((tmp-file (org-babel-temp-file "sh-")))
(with-temp-file tmp-file (insert results))
(org-babel-import-elisp-from-file tmp-file))))
(if (not session)
(org-babel-eval org-babel-sh-command (org-babel-trim body))
(let ((tmp-file (make-temp-file "org-babel-sh")))
(let ((tmp-file (org-babel-temp-file "sh-")))
(mapconcat
#'org-babel-sh-strip-weird-long-prompt
(mapcar

View File

@ -60,9 +60,9 @@ This function is called by `org-babel-execute-src-block'."
(processed-params (org-babel-process-params params))
(cmdline (cdr (assoc :cmdline params)))
(engine (cdr (assoc :engine params)))
(in-file (make-temp-file "org-babel-sql-in"))
(in-file (org-babel-temp-file "sql-in-"))
(out-file (or (cdr (assoc :out-file params))
(make-temp-file "org-babel-sql-out")))
(org-babel-temp-file "sql-out-")))
(command (case (intern engine)
('mysql (format "mysql %s -e \"source %s\" > %s"
(or cmdline "") in-file out-file))

View File

@ -73,7 +73,7 @@ This function is called by `org-babel-execute-src-block'."
(insert (org-babel-expand-body:sqlite
body nil (list nil vars))))
sql-file)
(make-temp-file "ob-sqlite-sql")))
(org-babel-temp-file "sqlite-sql-")))
(cons "cmd" org-babel-sqlite3-command)
(cons "header" (if headers-p "-header" "-noheader"))
(cons "separator"
@ -117,7 +117,7 @@ This function is called by `org-babel-execute-src-block'."
el
(format "%S" el)))))))
data-file)
(make-temp-file "ob-sqlite-data"))
(org-babel-temp-file "sqlite-data-"))
(if (stringp val) val (format "%S" val))))
(cdr pair))
body)))

View File

@ -34,7 +34,10 @@
(declare-function org-link-escape "org" (text &optional table))
(declare-function org-heading-components "org" ())
(declare-function org-back-to-heading "org" (invisible-ok))
(declare-function org-fill-template "org" (template alist))
;;;###autoload
(defcustom org-babel-tangle-lang-exts
'(("emacs-lisp" . "el"))
"Alist mapping languages to their file extensions.
@ -53,6 +56,38 @@ then the name of the language is used."
:group 'org-babel
:type 'hook)
(defcustom org-babel-pre-tangle-hook '(save-buffer)
"Hook run at the beginning of `org-babel-tangle'."
:group 'org-babel
:type 'hook)
(defcustom org-babel-tangle-pad-newline t
"Switch indicating whether to pad tangled code with newlines."
:group 'org-babel
:type 'boolean)
(defcustom org-babel-tangle-comment-format-beg "[[%link][%sourcename]]"
"Format of inserted comments in tangled code files.
The following format strings can be used to insert special
information into the output using `org-fill-template'.
%start-line --- the line number at the start of the code block
%file --------- the file from which the code block was tangled
%link --------- Org-mode style link to the code block
%source-name -- name of the code block"
:group 'org-babel
:type 'string)
(defcustom org-babel-tangle-comment-format-end "%sourcename ends here"
"Format of inserted comments in tangled code files.
The following format strings can be used to insert special
information into the output using `org-fill-template'.
%start-line --- the line number at the start of the code block
%file --------- the file from which the code block was tangled
%link --------- Org-mode style link to the code block
%source-name -- name of the code block"
:group 'org-babel
:type 'string)
(defun org-babel-find-file-noselect-refresh (file)
"Find file ensuring that the latest changes on disk are
represented in the file."
@ -127,7 +162,7 @@ TARGET-FILE can be used to specify a default export file for all
source blocks. Optional argument LANG can be used to limit the
exported source code blocks by language."
(interactive)
(save-buffer)
(run-hooks 'org-babel-pre-tangle-hook)
(save-excursion
(let ((block-counter 0)
(org-babel-default-header-args
@ -152,7 +187,7 @@ exported source code blocks by language."
(mapc
(lambda (spec)
(flet ((get-spec (name)
(cdr (assoc name (nth 2 spec)))))
(cdr (assoc name (nth 4 spec)))))
(let* ((tangle (get-spec :tangle))
(she-bang ((lambda (sheb) (when (> (length sheb) 0) sheb))
(get-spec :shebang)))
@ -187,7 +222,7 @@ exported source code blocks by language."
(insert content)
(write-region nil nil file-name))))
;; if files contain she-bangs, then make the executable
(when she-bang (set-file-modes file-name ?\755))
(when she-bang (set-file-modes file-name #o755))
;; update counter
(setq block-counter (+ 1 block-counter))
(add-to-list 'path-collector file-name)))))
@ -219,7 +254,7 @@ references."
(save-excursion (end-of-line 1) (forward-char 1) (point)))))
(defvar org-stored-links)
(defun org-babel-tangle-collect-blocks (&optional lang)
(defun org-babel-tangle-collect-blocks (&optional language)
"Collect source blocks in the current Org-mode file.
Return an association list of source-code block specifications of
the form used by `org-babel-spec-to-string' grouped by language.
@ -237,43 +272,53 @@ code blocks by language."
(condition-case nil
(nth 4 (org-heading-components))
(error (buffer-file-name)))))
(let* ((link (progn (call-interactively 'org-store-link)
(let* ((start-line (save-restriction (widen)
(+ 1 (line-number-at-pos (point)))))
(file (buffer-file-name))
(link (progn (call-interactively 'org-store-link)
(org-babel-clean-text-properties
(car (pop org-stored-links)))))
(info (org-babel-get-src-block-info))
(params (nth 2 info))
(source-name (intern (or (nth 4 info)
(format "%s:%d"
current-heading block-counter))))
(src-lang (nth 0 info))
(src-lang (nth 0 info))
(expand-cmd (intern (concat "org-babel-expand-body:" src-lang)))
(params (nth 2 info))
(body ((lambda (body)
(if (assoc :no-expand params)
body
(funcall (if (fboundp expand-cmd)
expand-cmd
'org-babel-expand-body:generic)
body params)))
(if (and (cdr (assoc :noweb params))
(string= "yes" (cdr (assoc :noweb params))))
(org-babel-expand-noweb-references info)
(nth 1 info))))
(comment (when (or (string= "both" (cdr (assoc :comments params)))
(string= "org" (cdr (assoc :comments params))))
;; from the previous heading or code-block end
(buffer-substring
(max (condition-case nil
(save-excursion
(org-back-to-heading t) (point))
(error 0))
(save-excursion (re-search-backward
org-babel-src-block-regexp nil t)
(match-end 0)))
(point))))
by-lang)
(unless (string= (cdr (assoc :tangle params)) "no") ;; skip
(unless (and lang (not (string= lang src-lang))) ;; limit by language
(unless (string= (cdr (assoc :tangle params)) "no")
(unless (and language (not (string= language src-lang)))
;; add the spec for this block to blocks under it's language
(setq by-lang (cdr (assoc src-lang blocks)))
(setq blocks (delq (assoc src-lang blocks) blocks))
(setq blocks
(cons
(cons src-lang
(cons (list link source-name params
((lambda (body)
(if (assoc :no-expand params)
body
(funcall
(if (fboundp expand-cmd)
expand-cmd
'org-babel-expand-body:generic)
body
params)))
(if (and (cdr (assoc :noweb params))
(string=
"yes"
(cdr (assoc :noweb params))))
(org-babel-expand-noweb-references
info)
(nth 1 info))))
by-lang)) blocks))))))
(setq blocks (cons
(cons src-lang
(cons (list start-line file link
source-name params body comment)
by-lang)) blocks))))))
;; ensure blocks in the correct order
(setq blocks
(mapcar
@ -288,22 +333,39 @@ source code file. This function uses `comment-region' which
assumes that the appropriate major-mode is set. SPEC has the
form
(link source-name params body)"
(let ((link (nth 0 spec))
(source-name (nth 1 spec))
(body (nth 3 spec))
(commentable (string= (cdr (assoc :comments (nth 2 spec))) "yes")))
(start-line file link source-name params body comment)"
(let* ((start-line (nth 0 spec))
(file (nth 1 spec))
(link (org-link-escape (nth 2 spec)))
(source-name (nth 3 spec))
(body (nth 5 spec))
(comment (nth 6 spec))
(comments (cdr (assoc :comments (nth 4 spec))))
(link-p (or (string= comments "both") (string= comments "link")
(string= comments "yes")))
(link-data (mapcar (lambda (el)
(cons (symbol-name el)
((lambda (le)
(if (stringp le) le (format "%S" le)))
(eval el))))
'(start-line file link source-name))))
(flet ((insert-comment (text)
(when commentable
(insert "\n")
(comment-region (point)
(progn (insert text) (point)))
(end-of-line nil)
(insert "\n"))))
(insert-comment (format "[[%s][%s]]" (org-link-escape link) source-name))
(insert (format "\n%s\n" (replace-regexp-in-string
"^," "" (org-babel-chomp body))))
(insert-comment (format "%s ends here" source-name)))))
(let ((text (org-babel-trim text)))
(when (and comments (not (string= comments "no"))
(> (length text) 0))
(when org-babel-tangle-pad-newline (insert "\n"))
(comment-region (point) (progn (insert text) (point)))
(end-of-line nil) (insert "\n")))))
(when comment (insert-comment comment))
(when link-p
(insert-comment
(org-fill-template org-babel-tangle-comment-format-beg link-data)))
(when org-babel-tangle-pad-newline (insert "\n"))
(insert (format "%s\n" (replace-regexp-in-string
"^," "" (org-babel-trim body))))
(when link-p
(insert-comment
(org-fill-template org-babel-tangle-comment-format-end link-data))))))
(provide 'ob-tangle)

View File

@ -25,33 +25,39 @@
;;; Commentary:
;; See the online documentation for more information
;;
;;
;; http://orgmode.org/worg/org-contrib/babel/
;;; Code:
(eval-when-compile (require 'cl))
(eval-when-compile
(require 'cl))
(require 'org-macs)
(defvar org-babel-call-process-region-original)
(declare-function show-all "outline" ())
(declare-function tramp-compat-make-temp-file "tramp" (filename &optional dir-flag))
(declare-function tramp-compat-make-temp-file "tramp-compat"
(filename &optional dir-flag))
(declare-function tramp-dissect-file-name "tramp" (name &optional nodefault))
(declare-function tramp-file-name-user "tramp" (vec))
(declare-function tramp-file-name-host "tramp" (vec))
(declare-function with-parsed-tramp-file-name "tramp" (filename var &rest body))
(declare-function org-icompleting-read "org" (&rest args))
(declare-function org-edit-src-code "org" (context code edit-buffer-name))
(declare-function org-edit-src-code "org-src"
(&optional context code edit-buffer-name quietp))
(declare-function org-edit-src-exit "org-src" (&optional context))
(declare-function org-open-at-point "org" (&optional in-emacs reference-buffer))
(declare-function org-save-outline-visibility "org" (use-markers &rest body))
(declare-function org-outline-overlay-data "org" (&optional use-markers))
(declare-function org-set-outline-overlay-data "org" (data))
(declare-function org-narrow-to-subtree "org" ())
(declare-function org-entry-get "org" (pom property &optional inherit))
(declare-function org-entry-get "org" (pom property &optional inherit literal-nil))
(declare-function org-make-options-regexp "org" (kwds &optional extra))
(declare-function org-match-string-no-properties "org" (num &optional string))
(declare-function org-do-remove-indentation "org" (&optional n))
(declare-function org-show-context "org" (&optional key))
(declare-function org-at-table-p "org" (&optional table-type))
(declare-function org-cycle "org" (&optional arg))
(declare-function org-uniquify "org" (list))
(declare-function org-table-import "org" (file arg))
(declare-function org-table-import "org-table" (file arg))
(declare-function org-add-hook "org-compat" (hook function &optional append local))
(declare-function org-table-align "org-table" ())
(declare-function org-table-end "org-table" (&optional table-type))
@ -182,18 +188,20 @@ confirmation from the user.
Note disabling confirmation may result in accidental evaluation
of potentially harmful code."
(let* ((eval (cdr (assoc :eval (nth 2 info))))
(let* ((eval (or (cdr (assoc :eval (nth 2 info)))
(when (assoc :noeval (nth 2 info)) "no")))
(query (or (equal eval "query")
(and (functionp org-confirm-babel-evaluate)
(funcall org-confirm-babel-evaluate
(nth 0 info) (nth 1 info)))
org-confirm-babel-evaluate)))
(when (or (equal eval "never")
(and query
(not (yes-or-no-p
(format "Evaluate this%scode on your system? "
(if info (format " %s " (nth 0 info)) " "))))))
(error "evaluation aborted"))))
(if (or (equal eval "never") (equal eval "no")
(and query
(not (yes-or-no-p
(format "Evaluate this%scode on your system? "
(if info (format " %s " (nth 0 info)) " "))))))
(prog1 nil (message "evaluation aborted"))
t)))
;;;###autoload
(defun org-babel-execute-safely-maybe ()
@ -254,7 +262,7 @@ then run `org-babel-pop-to-session'."
(defconst org-babel-header-arg-names
'(cache cmdline colnames dir exports file noweb results
session tangle var noeval comments)
session tangle var eval noeval comments)
"Common header arguments used by org-babel.
Note that individual languages may define their own language
specific header arguments as well.")
@ -315,6 +323,10 @@ Insert the results of execution into the buffer. Source code
execution and the collection and formatting of results can be
controlled through a variety of header arguments.
With prefix argument ARG, force re-execution even if a an
existing result cached in the buffer would otherwise have been
returned.
Optionally supply a value for INFO in the form returned by
`org-babel-get-src-block-info'.
@ -322,66 +334,65 @@ Optionally supply a value for PARAMS which will be merged with
the header arguments specified at the front of the source code
block."
(interactive)
(let* ((info (or info (org-babel-get-src-block-info)))
;; note the `evaluation-confirmed' variable is currently not
;; used, but could be used later to avoid the need for
;; chaining confirmations
(evaluation-confirmed (org-babel-confirm-evaluate info))
(lang (nth 0 info))
(params (setf (nth 2 info)
(sort (org-babel-merge-params (nth 2 info) params)
(lambda (el1 el2) (string< (symbol-name (car el1))
(symbol-name (car el2)))))))
(new-hash
(if (and (cdr (assoc :cache params))
(string= "yes" (cdr (assoc :cache params))))
(org-babel-sha1-hash info)))
(old-hash (org-babel-result-hash info))
(body (setf (nth 1 info)
(if (and (cdr (assoc :noweb params))
(string= "yes" (cdr (assoc :noweb params))))
(org-babel-expand-noweb-references info)
(nth 1 info))))
(result-params (split-string (or (cdr (assoc :results params)) "")))
(result-type (cond ((member "output" result-params) 'output)
((member "value" result-params) 'value)
(t 'value)))
(cmd (intern (concat "org-babel-execute:" lang)))
(dir (cdr (assoc :dir params)))
(default-directory
(or (and dir (file-name-as-directory dir)) default-directory))
(org-babel-call-process-region-original
(if (boundp 'org-babel-call-process-region-original) org-babel-call-process-region-original
(symbol-function 'call-process-region)))
(indent (car (last info)))
result)
(unwind-protect
(flet ((call-process-region (&rest args)
(apply 'org-babel-tramp-handle-call-process-region args)))
(unless (fboundp cmd)
(error "No org-babel-execute function for %s!" lang))
(if (and (not arg) new-hash (equal new-hash old-hash))
(save-excursion ;; return cached result
(goto-char (org-babel-where-is-src-block-result nil info))
(end-of-line 1) (forward-char 1)
(setq result (org-babel-read-result))
(message (replace-regexp-in-string "%" "%%"
(format "%S" result))) result)
(message "executing %s code block%s..."
(capitalize lang)
(if (nth 4 info) (format " (%s)" (nth 4 info)) ""))
(setq result (funcall cmd body params))
(if (eq result-type 'value)
(setq result (if (and (or (member "vector" result-params)
(member "table" result-params))
(not (listp result)))
(list (list result))
result)))
(org-babel-insert-result
result result-params info new-hash indent lang)
(run-hooks 'org-babel-after-execute-hook)
result))
(setq call-process-region 'org-babel-call-process-region-original))))
(let ((info (or info (org-babel-get-src-block-info))))
(when (org-babel-confirm-evaluate info)
(let* ((lang (nth 0 info))
(params (setf
(nth 2 info)
(sort (org-babel-merge-params (nth 2 info) params)
(lambda (el1 el2) (string< (symbol-name (car el1))
(symbol-name (car el2)))))))
(new-hash
(if (and (cdr (assoc :cache params))
(string= "yes" (cdr (assoc :cache params))))
(org-babel-sha1-hash info)))
(old-hash (org-babel-result-hash info))
(body (setf (nth 1 info)
(if (and (cdr (assoc :noweb params))
(string= "yes" (cdr (assoc :noweb params))))
(org-babel-expand-noweb-references info)
(nth 1 info))))
(result-params (split-string (or (cdr (assoc :results params)) "")))
(result-type (cond ((member "output" result-params) 'output)
((member "value" result-params) 'value)
(t 'value)))
(cmd (intern (concat "org-babel-execute:" lang)))
(dir (cdr (assoc :dir params)))
(default-directory
(or (and dir (file-name-as-directory dir)) default-directory))
(org-babel-call-process-region-original
(if (boundp 'org-babel-call-process-region-original)
org-babel-call-process-region-original
(symbol-function 'call-process-region)))
(indent (car (last info)))
result)
(unwind-protect
(flet ((call-process-region (&rest args)
(apply 'org-babel-tramp-handle-call-process-region args)))
(unless (fboundp cmd)
(error "No org-babel-execute function for %s!" lang))
(if (and (not arg) new-hash (equal new-hash old-hash))
(save-excursion ;; return cached result
(goto-char (org-babel-where-is-src-block-result nil info))
(end-of-line 1) (forward-char 1)
(setq result (org-babel-read-result))
(message (replace-regexp-in-string
"%" "%%" (format "%S" result))) result)
(message "executing %s code block%s..."
(capitalize lang)
(if (nth 4 info) (format " (%s)" (nth 4 info)) ""))
(setq result (funcall cmd body params))
(if (eq result-type 'value)
(setq result (if (and (or (member "vector" result-params)
(member "table" result-params))
(not (listp result)))
(list (list result))
result)))
(org-babel-insert-result
result result-params info new-hash indent lang)
(run-hooks 'org-babel-after-execute-hook)
result))
(setq call-process-region 'org-babel-call-process-region-original))))))
(defun org-babel-expand-body:generic (body params &optional processed-params)
"Expand BODY with PARAMS.
@ -421,8 +432,12 @@ session."
(interactive)
(let* ((info (or info (org-babel-get-src-block-info)))
(lang (nth 0 info))
(body (nth 1 info))
(params (nth 2 info))
(body (setf (nth 1 info)
(if (and (cdr (assoc :noweb params))
(string= "yes" (cdr (assoc :noweb params))))
(org-babel-expand-noweb-references info)
(nth 1 info))))
(session (cdr (assoc :session params)))
(dir (cdr (assoc :dir params)))
(default-directory
@ -434,12 +449,12 @@ session."
(end-of-line 1)))
;;;###autoload
(defun org-babel-switch-to-session (&optional arg info)
"Switch to the session of the current source-code block.
(defun org-babel-initiate-session (&optional arg info)
"Initiate session for current code block.
If called with a prefix argument then evaluate the header arguments
for the source block before entering the session. Copy the body
of the source block to the kill ring."
(interactive)
for the code block before entering the session. Copy the body
of the code block to the kill ring."
(interactive "P")
(let* ((info (or info (org-babel-get-src-block-info)))
(lang (nth 0 info))
(body (nth 1 info))
@ -450,21 +465,72 @@ of the source block to the kill ring."
(or (and dir (file-name-as-directory dir)) default-directory))
(cmd (intern (format "org-babel-%s-initiate-session" lang)))
(cmd2 (intern (concat "org-babel-prep-session:" lang))))
(if (and (stringp session) (string= session "none"))
(error "This block is not using a session!"))
(unless (fboundp cmd)
(error "No org-babel-initiate-session function for %s!" lang))
;; copy body to the kill ring
(with-temp-buffer (insert (org-babel-trim body))
(copy-region-as-kill (point-min) (point-max)))
;; if called with a prefix argument, then process header arguments
(unless (fboundp cmd2)
(error "No org-babel-prep-session function for %s!" lang))
(when arg (funcall cmd2 session params))
;; just to the session using pop-to-buffer
(pop-to-buffer (funcall cmd session params))
(end-of-line 1)))
(when arg
(unless (fboundp cmd2)
(error "No org-babel-prep-session function for %s!" lang))
(funcall cmd2 session params))
(funcall cmd session params)))
;;;###autoload
(defun org-babel-switch-to-session (&optional arg info)
"Switch to the session of the current code block.
Uses `org-babel-initiate-session' to start the session. If called
with a prefix argument then this is passed on to
`org-babel-initiate-session'."
(interactive "P")
(pop-to-buffer (org-babel-initiate-session arg info))
(end-of-line 1))
(defalias 'org-babel-pop-to-session 'org-babel-switch-to-session)
;;;###autoload
(defun org-babel-switch-to-session-with-code (&optional arg info)
"Switch to code buffer and display session."
(interactive "P")
(flet ((swap-windows
()
(let ((other-window-buffer (window-buffer (next-window))))
(set-window-buffer (next-window) (current-buffer))
(set-window-buffer (selected-window) other-window-buffer))
(other-window 1)))
(let ((info (org-babel-get-src-block-info))
(org-src-window-setup 'reorganize-frame))
(save-excursion
(org-babel-switch-to-session arg info))
(org-edit-src-code))
(swap-windows)))
(defmacro org-babel-do-in-edit-buffer (&rest body)
"Evaluate BODY in edit buffer if there is a code block at point.
Return t if a code block was found at point, nil otherwise."
`(let ((org-src-window-setup 'switch-invisibly))
(when (and (org-babel-where-is-src-block-head)
(org-edit-src-code nil nil nil 'quietly))
(unwind-protect (progn ,@body)
(if (org-bound-and-true-p org-edit-src-from-org-mode)
(org-edit-src-exit)))
t)))
(defun org-babel-do-key-sequence-in-edit-buffer (key)
"Read key sequence and execute the command in edit buffer.
Enter a key sequence to be executed in the language major-mode
edit buffer. For example, TAB will alter the contents of the
Org-mode code block according to the effect of TAB in the
language major-mode buffer. For languages that support
interactive sessions, this can be used to send code from the Org
buffer to the session for evaluation using the native major-mode
evaluation mechanisms."
(interactive "kEnter key-sequence to execute in edit buffer: ")
(org-babel-do-in-edit-buffer
(call-interactively
(key-binding (or key (read-key-sequence nil))))))
(defvar org-bracket-link-regexp)
;;;###autoload
(defun org-babel-open-src-block-result (&optional re-run)
@ -522,7 +588,7 @@ the current subtree."
(save-restriction
(save-excursion
(org-narrow-to-subtree)
(org-babel-execute-buffer)
(org-babel-execute-buffer arg)
(widen))))
;;;###autoload
@ -663,20 +729,56 @@ portions of results lines."
'org-babel-show-result-all 'append 'local)))
(defmacro org-babel-map-src-blocks (file &rest body)
"Evaluate BODY forms on each source-block in FILE."
"Evaluate BODY forms on each source-block in FILE.
If FILE is nil evaluate BODY forms on source blocks in current
buffer. During evaluation of BODY the following local variables
are set relative to the currently matched code block.
full-block ------- string holding the entirety of the code block
beg-block -------- point at the beginning of the code block
end-block -------- point at the end of the matched code block
lang ------------- string holding the language of the code block
beg-lang --------- point at the beginning of the lang
end-lang --------- point at the end of the lang
switches --------- string holding the switches
beg-switches ----- point at the beginning of the switches
end-switches ----- point at the end of the switches
header-args ------ string holding the header-args
beg-header-args -- point at the beginning of the header-args
end-header-args -- point at the end of the header-args
body ------------- string holding the body of the code block
beg-body --------- point at the beginning of the body
end-body --------- point at the end of the body"
(declare (indent 1))
`(let ((visited-p (get-file-buffer (expand-file-name ,file)))
to-be-removed)
`(let ((visited-p (or (null ,file)
(get-file-buffer (expand-file-name ,file))))
(point (point)) to-be-removed)
(save-window-excursion
(find-file ,file)
(when ,file (find-file ,file))
(setq to-be-removed (current-buffer))
(goto-char (point-min))
(while (re-search-forward org-babel-src-block-regexp nil t)
(goto-char (match-beginning 0))
(save-match-data ,@body)
(let ((full-block (match-string 0))
(beg-block (match-beginning 0))
(end-block (match-beginning 0))
(lang (match-string 2))
(beg-lang (match-beginning 2))
(end-lang (match-end 2))
(switches (match-string 3))
(beg-switches (match-beginning 3))
(end-switches (match-end 3))
(header-args (match-string 4))
(beg-header-args (match-beginning 4))
(end-header-args (match-end 4))
(body (match-string 5))
(beg-body (match-beginning 5))
(end-body (match-end 5)))
(save-match-data ,@body))
(goto-char (match-end 0))))
(unless visited-p
(kill-buffer to-be-removed))))
(kill-buffer to-be-removed))
(goto-char point)))
(defvar org-file-properties)
(defun org-babel-params-from-properties (&optional lang)
@ -920,6 +1022,14 @@ If the point is not on a source block then return nil."
(looking-at org-babel-src-block-regexp))
(point))))))
;;;###autoload
(defun org-babel-goto-src-block-head ()
"Go to the beginning of the current code block."
(interactive)
((lambda (head)
(if head (goto-char head) (error "not currently in a code block")))
(org-babel-where-is-src-block-head)))
;;;###autoload
(defun org-babel-goto-named-src-block (name)
"Go to a named source-code block."
@ -996,7 +1106,9 @@ buffer or nil if no such result exists."
With optional prefix argument ARG, jump forward ARG many source blocks."
(interactive "P")
(when (looking-at org-babel-src-block-regexp) (forward-char 1))
(re-search-forward org-babel-src-block-regexp nil nil (or arg 1))
(condition-case nil
(re-search-forward org-babel-src-block-regexp nil nil (or arg 1))
(error (error "No further code blocks")))
(goto-char (match-beginning 0)) (org-show-context))
;;;###autoload
@ -1004,7 +1116,9 @@ With optional prefix argument ARG, jump forward ARG many source blocks."
"Jump to the previous source block.
With optional prefix argument ARG, jump backward ARG many source blocks."
(interactive "P")
(re-search-backward org-babel-src-block-regexp nil nil (or arg 1))
(condition-case nil
(re-search-backward org-babel-src-block-regexp nil nil (or arg 1))
(error (error "No previous code blocks")))
(goto-char (match-beginning 0)) (org-show-context))
(defvar org-babel-lob-one-liner-regexp)
@ -1148,7 +1262,12 @@ raw ----- results are added directly to the org-mode file. This
is a good option if you code block will output org-mode
formatted text.
org ----- this is the same as the 'raw' option
org ----- similar in effect to raw, only the results are wrapped
in an org code block. Similar to the raw option, on
export the results will be interpreted as org-formatted
text, however by wrapping the results in an org code
block they can be replaced upon re-execution of the
code block.
html ---- results are added inside of a #+BEGIN_HTML block. This
is a good option if you code block will output html
@ -1169,74 +1288,79 @@ code ---- the results are extracted in the syntax of the source
(when (member "file" result-params)
(setq result (org-babel-result-to-file result))))
(unless (listp result) (setq result (format "%S" result))))
(if (= (length result) 0)
(if (member "value" result-params)
(message "No result returned by source block")
(message "Source block produced no output"))
(if (and result-params (member "silent" result-params))
(progn
(message (replace-regexp-in-string "%" "%%" (format "%S" result)))
result)
(when (and (stringp result) ;; ensure results end in a newline
(not (or (string-equal (substring result -1) "\n")
(string-equal (substring result -1) "\r"))))
(setq result (concat result "\n")))
(save-excursion
(let ((existing-result (org-babel-where-is-src-block-result
t info hash indent))
(results-switches
(cdr (assoc :results_switches (nth 2 info))))
beg end)
(if (not existing-result)
(setq beg (point))
(goto-char existing-result)
(save-excursion
(re-search-forward "#" nil t)
(setq indent (- (current-column) 1)))
(forward-line 1)
(if (and result-params (member "silent" result-params))
(progn
(message (replace-regexp-in-string "%" "%%" (format "%S" result)))
result)
(when (and (stringp result) ;; ensure results end in a newline
(> (length result) 0)
(not (or (string-equal (substring result -1) "\n")
(string-equal (substring result -1) "\r"))))
(setq result (concat result "\n")))
(save-excursion
(let ((existing-result (org-babel-where-is-src-block-result
t info hash indent))
(results-switches
(cdr (assoc :results_switches (nth 2 info))))
beg end)
(if (not existing-result)
(setq beg (point))
(cond
((member "replace" result-params)
(delete-region (point) (org-babel-result-end)))
((member "append" result-params)
(goto-char (org-babel-result-end)) (setq beg (point)))
((member "prepend" result-params) ;; already there
)))
(setq results-switches
(if results-switches (concat " " results-switches) ""))
(goto-char existing-result)
(save-excursion
(re-search-forward "#" nil t)
(setq indent (- (current-column) 1)))
(forward-line 1)
(setq beg (point))
(cond
;; assume the result is a table if it's not a string
((not (stringp result))
(insert (concat (orgtbl-to-orgtbl
(if (or (eq 'hline (car result))
(and (listp (car result))
(listp (cdr (car result)))))
result (list result))
'(:fmt (lambda (cell) (format "%s" cell)))) "\n"))
(goto-char beg) (when (org-at-table-p) (org-table-align)))
((member "file" result-params)
(insert result))
((member "html" result-params)
(insert (format "#+BEGIN_HTML%s\n%s#+END_HTML\n"
results-switches result)))
((member "latex" result-params)
(insert (format "#+BEGIN_LaTeX%s\n%s#+END_LaTeX\n"
results-switches result)))
((member "code" result-params)
(insert (format "#+BEGIN_SRC %s%s\n%s#+END_SRC\n"
(or lang "none") results-switches result)))
((or (member "raw" result-params) (member "org" result-params))
(save-excursion (insert result)) (if (org-at-table-p) (org-cycle)))
(t
(org-babel-examplize-region
(point) (progn (insert result) (point)) results-switches)))
;; possibly indent the results to match the #+results line
(setq end (if (listp result) (org-table-end) (point)))
(when (and indent (> indent 0)
;; in this case `table-align' does the work for us
(not (and (listp result)
(member "append" result-params))))
(indent-rigidly beg end indent))))
((member "replace" result-params)
(delete-region (point) (org-babel-result-end)))
((member "append" result-params)
(goto-char (org-babel-result-end)) (setq beg (point)))
((member "prepend" result-params) ;; already there
)))
(setq results-switches
(if results-switches (concat " " results-switches) ""))
(cond
;; do nothing for an empty result
((= (length result) 0))
;; assume the result is a table if it's not a string
((not (stringp result))
(insert (concat (orgtbl-to-orgtbl
(if (or (eq 'hline (car result))
(and (listp (car result))
(listp (cdr (car result)))))
result (list result))
'(:fmt (lambda (cell) (format "%s" cell)))) "\n"))
(goto-char beg) (when (org-at-table-p) (org-table-align)))
((member "file" result-params)
(insert result))
((member "html" result-params)
(insert (format "#+BEGIN_HTML%s\n%s#+END_HTML\n"
results-switches result)))
((member "latex" result-params)
(insert (format "#+BEGIN_LaTeX%s\n%s#+END_LaTeX\n"
results-switches result)))
((member "code" result-params)
(insert (format "#+BEGIN_SRC %s%s\n%s#+END_SRC\n"
(or lang "none") results-switches result)))
((member "org" result-params)
(insert (format "#+BEGIN_SRC org\n%s#+END_SRC\n" result)))
((member "raw" result-params)
(save-excursion (insert result)) (if (org-at-table-p) (org-cycle)))
(t
(org-babel-examplize-region
(point) (progn (insert result) (point)) results-switches)))
;; possibly indent the results to match the #+results line
(setq end (if (listp result) (org-table-end) (point)))
(when (and indent (> indent 0)
;; in this case `table-align' does the work for us
(not (and (listp result)
(member "append" result-params))))
(indent-rigidly beg end indent))))
(if (= (length result) 0)
(if (member "value" result-params)
(message "No result returned by source block")
(message "Source block produced no output"))
(message "finished"))))
(defun org-babel-remove-result (&optional info)
@ -1291,7 +1415,7 @@ file's directory then expand relative links."
(let ((size (count-lines beg end)))
(save-excursion
(cond ((= size 0)
(error (concat "This should be impossible:"
(error (concat "This should not be impossible:"
"a newline was appended to result if missing")))
((< size org-babel-min-lines-for-block-output)
(goto-char beg)
@ -1604,6 +1728,57 @@ the remote connection."
(concat "/" user (when user "@") host ":" file))
file))
(defun org-babel-tramp-localname (file)
"Return the local name component of FILE."
(if (file-remote-p file)
(let (localname)
(with-parsed-tramp-file-name file nil
localname))
file))
;; (defvar org-babel-temporary-directory
;; (or (and (boundp 'org-babel-temporary-directory)
;; org-babel-temporary-directory)
;; (make-temp-file "babel-" t))
;; "Directory to hold temporary files created to execute code blocks.
;; Used by `org-babel-temp-file'. This directory will be removed on
;; Emacs shutdown.")
(defun org-babel-temp-file (prefix &optional suffix)
"Create a temporary file in the `org-babel-temporary-directory'.
Passes PREFIX and SUFFIX directly to `make-temp-file' with the
value of `temporary-file-directory' temporarily set to the value
of `org-babel-temporary-directory'."
(if (file-remote-p default-directory)
(make-temp-file
(concat (file-remote-p default-directory)
(expand-file-name
prefix temporary-file-directory)
nil suffix))
;; (let ((temporary-file-directory (expand-file-name
;; org-babel-temporary-directory
;; temporary-file-directory)))
;; (make-temp-file prefix nil suffix))
(make-temp-file prefix nil suffix)))
;; (defun org-babel-remove-temporary-directory ()
;; "Remove `org-babel-temporary-directory' on Emacs shutdown."
;; (when (boundp 'org-babel-temporary-directory)
;; ;; taken from `delete-directory' in files.el
;; (mapc (lambda (file)
;; ;; This test is equivalent to
;; ;; (and (file-directory-p fn) (not (file-symlink-p fn)))
;; ;; but more efficient
;; (if (eq t (car (file-attributes file)))
;; (delete-directory file)
;; (delete-file file)))
;; ;; We do not want to delete "." and "..".
;; (directory-files org-babel-temporary-directory 'full
;; "^\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*"))
;; (delete-directory org-babel-temporary-directory)))
;; (add-hook 'kill-emacs-hook 'org-babel-remove-temporary-directory)
(provide 'ob)
;; arch-tag: 01a7ebee-06c5-4ee4-a709-e660d28c0af1

View File

@ -1488,6 +1488,18 @@ the lower-case version of all tags."
(require 'cl))
(require 'org)
(defmacro org-agenda-with-point-at-orig-entry (string &rest body)
"Execute BODY with point at location given by `org-hd-marker' property.
If STRING is non-nil, the text property will be fetched from position 0
in that string. If STRING is nil, it will be fetched from the beginning
of the current line."
`(let ((marker (get-text-property (if string 0 (point-at-bol))
'org-hd-marker string)))
(with-current-buffer (marker-buffer marker)
(save-excursion
(goto-char marker)
,@body))))
(defun org-add-agenda-custom-command (entry)
"Replace or add a command in `org-agenda-custom-commands'.
This is mostly for hacking and trying a new command - once the command
@ -2503,16 +2515,15 @@ higher priority settings."
(interactive "FWrite agenda to file: \nP")
(if (not (file-writable-p file))
(error "Cannot write agenda to file %s" file))
(cond
((string-match "\\.html?\\'" file) (require 'htmlize))
((string-match "\\.ps\\'" file) (require 'ps-print)))
(org-let (if nosettings nil org-agenda-exporter-settings)
`(save-excursion
'(save-excursion
(save-window-excursion
(org-agenda-mark-filtered-text)
(let ((bs (copy-sequence (buffer-string))) beg)
(org-agenda-unmark-filtered-text)
(with-temp-buffer
(rename-buffer "Agenda View" t)
(set-buffer-modified-p nil)
(insert bs)
(org-agenda-remove-marked-text 'org-filtered)
(while (setq beg (text-property-any (point-min) (point-max)
@ -2525,6 +2536,7 @@ higher priority settings."
((org-bound-and-true-p org-mobile-creating-agendas)
(org-mobile-write-agenda-for-mobile file))
((string-match "\\.html?\\'" file)
(require 'htmlize)
(set-buffer (htmlize-buffer (current-buffer)))
(when (and org-agenda-export-html-style
@ -2539,18 +2551,17 @@ higher priority settings."
(message "HTML written to %s" file))
((string-match "\\.ps\\'" file)
(require 'ps-print)
,(flet ((ps-get-buffer-name () "Agenda View"))
(ps-print-buffer-with-faces file))
(ps-print-buffer-with-faces file)
(message "Postscript written to %s" file))
((string-match "\\.pdf\\'" file)
(require 'ps-print)
,(flet ((ps-get-buffer-name () "Agenda View"))
(ps-print-buffer-with-faces
(concat (file-name-sans-extension file) ".ps")))
(ps-print-buffer-with-faces
(concat (file-name-sans-extension file) ".ps"))
(call-process "ps2pdf" nil nil nil
(expand-file-name
(concat (file-name-sans-extension file) ".ps"))
(expand-file-name file))
(delete-file (concat (file-name-sans-extension file) ".ps"))
(message "PDF written to %s" file))
((string-match "\\.ics\\'" file)
(require 'org-icalendar)
@ -2616,7 +2627,9 @@ Drawers will be excluded, also the line with scheduling/deadline info."
(setq txt (org-agenda-get-some-entry-text
m org-agenda-add-entry-text-maxlines " > "))
(end-of-line 1)
(if (string-match "\\S-" txt) (insert "\n" txt)))))))
(if (string-match "\\S-" txt)
(insert "\n" txt)
(or (eobp) (forward-char 1))))))))
(defun org-agenda-get-some-entry-text (marker n-lines &optional indent
&rest keep)
@ -3993,8 +4006,7 @@ The remainder is either a list of TODO keywords, or a state symbol
"Create agenda view for projects that are stuck.
Stuck projects are project that have no next actions. For the definitions
of what a project is and how to check if it stuck, customize the variable
`org-stuck-projects'.
MATCH is being ignored."
`org-stuck-projects'."
(interactive)
(let* ((org-agenda-skip-function
'org-agenda-skip-entry-when-regexp-matches-in-subtree)
@ -4016,11 +4028,11 @@ MATCH is being ignored."
"\\)\\>"))
(tags (nth 2 org-stuck-projects))
(tags-re (if (member "*" tags)
(org-re "^\\*+ .*:[[:alnum:]_@]+:[ \t]*$")
(org-re "^\\*+ .*:[[:alnum:]_@#%]+:[ \t]*$")
(if tags
(concat "^\\*+ .*:\\("
(mapconcat 'identity tags "\\|")
(org-re "\\):[[:alnum:]_@:]*[ \t]*$")))))
(org-re "\\):[[:alnum:]_@#%:]*[ \t]*$")))))
(gen-re (nth 3 org-stuck-projects))
(re-list
(delq nil
@ -4979,7 +4991,7 @@ Any match of REMOVE-RE will be removed from TXT."
(setq h (/ m 60) m (- m (* h 60)))
(setq s2 (format "%02d:%02d" h m))))
(when (string-match (org-re "\\([ \t]+\\)\\(:[[:alnum:]_@:]+:\\)[ \t]*$")
(when (string-match (org-re "\\([ \t]+\\)\\(:[[:alnum:]_@#%:]+:\\)[ \t]*$")
txt)
;; Tags are in the string
(if (or (eq org-agenda-remove-tags t)
@ -5053,7 +5065,7 @@ Any match of REMOVE-RE will be removed from TXT."
The modified list may contain inherited tags, and tags matched by
`org-agenda-hide-tags-regexp' will be removed."
(when (or add-inherited hide-re)
(if (string-match (org-re "\\([ \t]+\\)\\(:[[:alnum:]_@:]+:\\)[ \t]*$") txt)
(if (string-match (org-re "\\([ \t]+\\)\\(:[[:alnum:]_@#%:]+:\\)[ \t]*$") txt)
(setq txt (substring txt 0 (match-beginning 0))))
(setq tags
(delq nil
@ -5109,7 +5121,7 @@ The modified list may contain inherited tags, and tags matched by
(throw 'exit list))
(while (setq time (pop gridtimes))
(unless (and remove (member time have))
(setq time (int-to-string time))
(setq time (replace-regexp-in-string " " "0" (format "%4s" time)))
(push (org-format-agenda-item
nil string "" nil
(concat (substring time 0 -2) ":" (substring time -2)))
@ -5228,8 +5240,8 @@ could bind the variable in the options section of a custom command.")
(if nosort
list
(when org-agenda-before-sorting-filter-function
(setq list (mapcar org-agenda-before-sorting-filter-function list)))
(delq nil (mapconcat 'identity (sort list 'org-entries-lessp) "\n"))))
(setq list (delq nil (mapcar org-agenda-before-sorting-filter-function list))))
(mapconcat 'identity (sort list 'org-entries-lessp) "\n")))
(defun org-agenda-highlight-todo (x)
(let ((org-done-keywords org-done-keywords-for-agenda)
@ -6719,7 +6731,7 @@ If FORCE-TAGS is non nil, the car of it returns the new tags."
(let ((inhibit-read-only t) l c)
(save-excursion
(goto-char (if line (point-at-bol) (point-min)))
(while (re-search-forward (org-re "\\([ \t]+\\)\\(:[[:alnum:]_@:]+:\\)[ \t]*$")
(while (re-search-forward (org-re "\\([ \t]+\\)\\(:[[:alnum:]_@#%:]+:\\)[ \t]*$")
(if line (point-at-eol) nil) t)
(add-text-properties
(match-beginning 2) (match-end 2)
@ -7142,9 +7154,9 @@ The cursor may be at a date in the calendar, or in the Org agenda."
(setq newhead (org-get-heading)))
(org-agenda-change-all-lines newhead hdmarker)))))
(defun org-agenda-clock-out (&optional arg)
(defun org-agenda-clock-out ()
"Stop the currently running clock."
(interactive "P")
(interactive)
(unless (marker-buffer org-clock-marker)
(error "No running clock"))
(let ((marker (make-marker)) newhead)
@ -7271,7 +7283,8 @@ the resulting entry will not be shown. When TEXT is empty, switch to
(let ((calendar-date-display-form
(if (if (boundp 'calendar-date-style)
(eq calendar-date-style 'european)
(org-bound-and-true-p european-calendar-style)) ; Emacs 22
(with-no-warnings ;; european-calendar-style is obsolete as of version 23.1
(org-bound-and-true-p european-calendar-style))) ; Emacs 22
'(day " " month " " year)
'(month " " day " " year))))

View File

@ -115,7 +115,7 @@ information."
((or (re-search-backward re nil t)
(re-search-forward re nil t))
(match-string 1))
(t org-archive-location (match-string 1)))))))
(t org-archive-location))))))
(defun org-add-archive-files (files)
"Splice the archive files into the list of files.
@ -268,7 +268,7 @@ this heading."
(progn
(if (re-search-forward
(concat "^" (regexp-quote heading)
(org-re "[ \t]*\\(:[[:alnum:]_@:]+:\\)?[ \t]*\\($\\|\r\\)"))
(org-re "[ \t]*\\(:[[:alnum:]_@#%:]+:\\)?[ \t]*\\($\\|\r\\)"))
nil t)
(goto-char (match-end 0))
;; Heading not found, just insert it at the end

View File

@ -311,7 +311,7 @@ publishing directory."
:add-text (plist-get opt-plist :text))
"\n"))
thetoc have-headings first-heading-pos
table-open table-buffer link-buffer link desc desc0 rpl wrap)
table-open table-buffer link-buffer link type path desc desc0 rpl wrap fnc)
(let ((inhibit-read-only t))
(org-unmodified
(remove-text-properties (point-min) (point-max)
@ -347,7 +347,7 @@ publishing directory."
(if (and (or author email)
org-export-author-info)
(insert(concat (nth 1 lang-words) ": " (or author "")
(insert (concat (nth 1 lang-words) ": " (or author "")
(if (and org-export-email-info
email (string-match "\\S-" email))
(concat " <" email ">") "")
@ -400,7 +400,7 @@ publishing directory."
(if (and (memq org-export-with-tags '(not-in-toc nil))
(string-match
(org-re "[ \t]+:[[:alnum:]_@:]+:[ \t]*$")
(org-re "[ \t]+:[[:alnum:]_@#%:]+:[ \t]*$")
txt))
(setq txt (replace-match "" t t txt)))
(if (string-match quote-re0 txt)
@ -431,10 +431,12 @@ publishing directory."
;; Remove the quoted HTML tags.
(setq line (org-html-expand-for-ascii line))
;; Replace links with the description when possible
(while (string-match org-bracket-link-regexp line)
(setq link (match-string 1 line)
desc0 (match-string 3 line)
desc (or desc0 (match-string 1 line)))
(while (string-match org-bracket-link-analytic-regexp++ line)
(setq path (match-string 3 line)
link (concat (match-string 1 line) path)
type (match-string 1 line)
desc0 (match-string 5 line)
desc (or desc0 link))
(if (and (> (length link) 8)
(equal (substring link 0 8) "coderef:"))
(setq line (replace-match
@ -443,15 +445,18 @@ publishing directory."
(substring link 8)
org-export-code-refs)))
t t line))
(setq rpl (concat "["
(or (match-string 3 line) (match-string 1 line))
"]"))
(when (and desc0 (not (equal desc0 link)))
(if org-export-ascii-links-to-notes
(push (cons desc0 link) link-buffer)
(setq rpl (concat rpl " (" link ")")
wrap (+ (length line) (- (length (match-string 0 line)))
(length desc)))))
(setq rpl (concat "[" desc "]"))
(if (functionp (setq fnc (nth 2 (assoc type org-link-protocols))))
(setq rpl (or (save-match-data
(funcall fnc (org-link-unescape path)
desc0 'ascii))
rpl))
(when (and desc0 (not (equal desc0 link)))
(if org-export-ascii-links-to-notes
(push (cons desc0 link) link-buffer)
(setq rpl (concat rpl " (" link ")")
wrap (+ (length line) (- (length (match-string 0 line)))
(length desc))))))
(setq line (replace-match rpl t t line))))
(when custom-times
(setq line (org-translate-time line)))
@ -482,7 +487,8 @@ publishing directory."
(org-format-table-ascii table-buffer)
"\n") "\n")))
(t
(if (string-match "^\\([ \t]*\\)\\([-+*][ \t]+\\)\\(.*?\\)\\( ::\\)" line)
(if (string-match "^\\([ \t]*\\)\\([-+*][ \t]+\\)\\(.*?\\)\\( ::\\)"
line)
(setq line (replace-match "\\1\\3:" t nil line)))
(setq line (org-fix-indentation line org-ascii-current-indentation))
;; Remove forced line breaks
@ -571,9 +577,12 @@ publishing directory."
(replace-match "\\1\\2")))
;; Remove list start counters
(goto-char (point-min))
(while (re-search-forward "\\[@start:[0-9]+\\] ?" nil t)
(org-if-unprotected
(replace-match ""))))
(while (org-search-forward-unenclosed
"\\[@\\(?:start:\\)?[0-9]+\\][ \t]*" nil t)
(replace-match ""))
(remove-text-properties
(point-min) (point-max)
'(face nil font-lock-fontified nil font-lock-multiline nil line-prefix nil wrap-prefix nil)))
(defun org-html-expand-for-ascii (line)
"Handle quoted HTML for ASCII export."
@ -645,7 +654,7 @@ publishing directory."
(insert "\n"))
(setq char (nth (- umax level) (reverse org-export-ascii-underline)))
(unless org-export-with-tags
(if (string-match (org-re "[ \t]+\\(:[[:alnum:]_@:]+:\\)[ \t]*$") title)
(if (string-match (org-re "[ \t]+\\(:[[:alnum:]_@#%:]+:\\)[ \t]*$") title)
(setq title (replace-match "" t t title))))
(if org-export-with-section-numbers
(setq title (concat (org-section-number level) " " title)))

View File

@ -76,6 +76,7 @@
:tag "Org Capture"
:group 'org)
;;;###autoload
(defcustom org-capture-templates nil
"Templates for the creation of new entries.
@ -220,7 +221,7 @@ Furthermore, the following %-escapes will be replaced with content:
Apart from these general escapes, you can access information specific to the
link type that is created. For example, calling `org-capture' in emails
or gnus will record the author and the subject of the message, which you
can access with \"%:author\" and \"%:subject\", respectively. Here is a
can access with \"%:from\" and \"%:subject\", respectively. Here is a
complete list of what is recorded for each link type.
Link type | Available information
@ -382,6 +383,11 @@ bypassed."
(initial (and (org-region-active-p)
(buffer-substring (point) (mark))))
(entry (org-capture-select-template keys)))
(when (stringp initial)
(remove-text-properties 0 (length initial) '(read-only t) initial))
(when (stringp annotation)
(remove-text-properties 0 (length annotation)
'(read-only t) annotation))
(cond
((equal entry "C")
(customize-variable 'org-capture-templates))
@ -589,6 +595,8 @@ already gone."
(set-buffer (org-capture-target-buffer (nth 1 target)))
(let ((hd (nth 2 target)))
(goto-char (point-min))
(unless (org-mode-p)
(error "Target buffer for file+headline should be in Org mode"))
(if (re-search-forward
(format org-complex-heading-regexp-format (regexp-quote hd))
nil t)
@ -743,14 +751,14 @@ already gone."
(if (org-capture-get :prepend)
(progn
(goto-char beg)
(if (re-search-forward (concat "^" (org-item-re)) end t)
(if (org-search-forward-unenclosed org-item-beginning-re end t)
(progn
(goto-char (match-beginning 0))
(setq ind (org-get-indentation)))
(goto-char end)
(setq ind 0)))
(goto-char end)
(if (re-search-backward (concat "^" (org-item-re)) beg t)
(if (org-search-backward-unenclosed org-item-beginning-re beg t)
(progn
(setq ind (org-get-indentation))
(org-end-of-item))
@ -972,7 +980,7 @@ Point will remain at the first line after the inserted text."
(insert template)
(org-capture-empty-lines-after)
(goto-char beg)
(org-maybe-renumber-ordered-list)
(org-list-repair)
(org-end-of-item)
(setq end (point)))
(t (insert template)))
@ -1204,12 +1212,13 @@ The template may still contain \"%?\" for cursor positioning."
'org-tags-history)))
(setq ins (mapconcat 'identity
(org-split-string
ins (org-re "[^[:alnum:]_@]+"))
ins (org-re "[^[:alnum:]_@#%]+"))
":"))
(when (string-match "\\S-" ins)
(or (equal (char-before) ?:) (insert ":"))
(insert ins)
(or (equal (char-after) ?:) (insert ":")))))
(or (equal (char-after) ?:) (insert ":"))
(and (org-on-heading-p) (org-set-tags nil 'align)))))
((equal char "C")
(cond ((= (length clipboards) 1) (insert (car clipboards)))
((> (length clipboards) 1)

View File

@ -35,6 +35,7 @@
(require 'cl))
(declare-function calendar-absolute-from-iso "cal-iso" (&optional date))
(declare-function notifications-notify "notifications" (&rest params))
(defvar org-time-stamp-formats)
(defgroup org-clock nil
@ -557,6 +558,14 @@ use libnotify if available, or fall back on a message."
((stringp org-show-notification-handler)
(start-process "emacs-timer-notification" nil
org-show-notification-handler notification))
((featurep 'notifications)
(require 'notifications)
(notifications-notify
:title "Org-mode message"
:body notification
;; FIXME how to link to the Org icon?
;; :app-icon "~/.emacs.d/icons/mail.png"
:urgency 'low))
((org-program-exists "notify-send")
(start-process "emacs-timer-notification" nil
"notify-send" notification))
@ -1863,7 +1872,7 @@ the currently selected interval size."
(when (setq time (get-text-property p :org-clock-minutes))
(save-excursion
(beginning-of-line 1)
(when (and (looking-at (org-re "\\(\\*+\\)[ \t]+\\(.*?\\)\\([ \t]+:[[:alnum:]_@:]+:\\)?[ \t]*$"))
(when (and (looking-at (org-re "\\(\\*+\\)[ \t]+\\(.*?\\)\\([ \t]+:[[:alnum:]_@#%:]+:\\)?[ \t]*$"))
(setq level (org-reduced-level
(- (match-end 1) (match-beginning 1))))
(<= level maxlevel))
@ -1971,10 +1980,22 @@ the currently selected interval size."
(when block
(setq cc (org-clock-special-range block nil t)
ts (car cc) te (nth 1 cc) range-text (nth 2 cc)))
(if ts (setq ts (org-float-time
(apply 'encode-time (org-parse-time-string ts)))))
(if te (setq te (org-float-time
(apply 'encode-time (org-parse-time-string te)))))
(cond
((numberp ts)
;; If ts is a number, it's an absolute day number from org-agenda.
(destructuring-bind (month day year) (calendar-gregorian-from-absolute ts)
(setq ts (org-float-time (encode-time 0 0 0 day month year)))))
(ts
(setq ts (org-float-time
(apply 'encode-time (org-parse-time-string ts))))))
(cond
((numberp te)
;; Likewise for te.
(destructuring-bind (month day year) (calendar-gregorian-from-absolute te)
(setq te (org-float-time (encode-time 0 0 0 day month year)))))
(te
(setq te (org-float-time
(apply 'encode-time (org-parse-time-string te))))))
(setq p1 (plist-put p1 :header ""))
(setq p1 (plist-put p1 :step nil))
(setq p1 (plist-put p1 :block nil))

View File

@ -685,7 +685,7 @@ Where possible, use the standard interface for changing this line."
(txt (match-string 3))
(post "")
txt2)
(if (string-match (org-re "[ \t]+:[[:alnum:]:_@]+:[ \t]*$") txt)
(if (string-match (org-re "[ \t]+:[[:alnum:]:_@#%]+:[ \t]*$") txt)
(setq post (match-string 0 txt)
txt (substring txt 0 (match-beginning 0))))
(setq txt2 (read-string "Edit: " txt))

View File

@ -519,7 +519,7 @@ Where possible, use the standard interface for changing this line."
(txt (match-string 3))
(post "")
txt2)
(if (string-match (org-re "[ \t]+:[[:alnum:]:_@]+:[ \t]*$") txt)
(if (string-match (org-re "[ \t]+:[[:alnum:]:_@#%]+:[ \t]*$") txt)
(setq post (match-string 0 txt)
txt (substring txt 0 (match-beginning 0))))
(setq txt2 (read-string "Edit: " txt))

View File

@ -353,7 +353,7 @@ TIME defaults to the current time."
(if (fboundp 'looking-at-p)
(apply 'looking-at-p args)
(save-match-data
(apply 'looking-at-p args))))
(apply 'looking-at args))))
; XEmacs does not have `looking-back'.
(if (fboundp 'looking-back)

View File

@ -552,9 +552,9 @@ publishing directory."
(nth 2 (assoc "=" org-export-docbook-emphasis-alist)))
table-open type
table-buffer table-orig-buffer
ind item-type starter didclose
ind item-type starter
rpl path attr caption label desc descp desc1 desc2 link
fnc item-tag initial-number
fnc item-tag item-number
footref-seen footnote-list
id-file
)
@ -671,7 +671,21 @@ publishing directory."
(org-export-docbook-open-para))
(throw 'nextline nil))
(org-export-docbook-close-lists-maybe line)
;; List ender: close every open list.
(when (equal "ORG-LIST-END" line)
(while local-list-type
(let ((listtype (car local-list-type)))
(org-export-docbook-close-li listtype)
(insert (cond
((equal listtype "o") "</orderedlist>\n")
((equal listtype "u") "</itemizedlist>\n")
((equal listtype "d") "</variablelist>\n"))))
(pop local-list-type))
;; We did close a list, normal text follows: need <para>
(org-export-docbook-open-para)
(setq local-list-indent nil
in-local-list nil)
(throw 'nextline nil))
;; Protected HTML
(when (get-text-property 0 'org-protected line)
@ -963,18 +977,6 @@ publishing directory."
txt (match-string 2 line))
(if (string-match quote-re0 txt)
(setq txt (replace-match "" t t txt)))
(when in-local-list
;; Close any local lists before inserting a new header line
(while local-list-type
(let ((listtype (car local-list-type)))
(org-export-docbook-close-li listtype)
(insert (cond
((equal listtype "o") "</orderedlist>\n")
((equal listtype "u") "</itemizedlist>\n")
((equal listtype "d") "</variablelist>\n"))))
(pop local-list-type))
(setq local-list-indent nil
in-local-list nil))
(org-export-docbook-level-start level txt)
;; QUOTES
(when (string-match quote-re line)
@ -1004,6 +1006,7 @@ publishing directory."
(org-export-docbook-close-para-maybe)
(insert (org-export-docbook-finalize-table
(org-format-table-html table-buffer table-orig-buffer)))))
(t
;; Normal lines
(when (string-match
@ -1020,34 +1023,14 @@ publishing directory."
(substring (match-string 2 line) 0 -1))
line (substring line (match-beginning 5))
item-tag nil
initial-number nil)
(if (string-match "\\`\\[@start:\\([0-9]+\\)\\][ \t]?" line)
(setq initial-number (match-string 1 line)
item-number nil)
(if (string-match "\\[@\\(?:start:\\)?\\([0-9]+\\)\\][ \t]?" line)
(setq item-number (match-string 1 line)
line (replace-match "" t t line)))
(if (and starter (string-match "\\(.*?\\) ::[ \t]*" line))
(setq item-type "d"
item-tag (match-string 1 line)
line (substring line (match-end 0))))
(when (and (not (equal item-type "d"))
(not (string-match "[^ \t]" line)))
;; Empty line. Pretend indentation is large.
(setq ind (if org-empty-line-terminates-plain-lists
0
(1+ (or (car local-list-indent) 1)))))
(setq didclose nil)
(while (and in-local-list
(or (and (= ind (car local-list-indent))
(not starter))
(< ind (car local-list-indent))))
(setq didclose t)
(let ((listtype (car local-list-type)))
(org-export-docbook-close-li listtype)
(insert (cond
((equal listtype "o") "</orderedlist>\n")
((equal listtype "u") "</itemizedlist>\n")
((equal listtype "d") "</variablelist>\n"))))
(pop local-list-type) (pop local-list-indent)
(setq in-local-list local-list-indent))
(cond
((and starter
(or (not in-local-list)
@ -1056,7 +1039,7 @@ publishing directory."
(org-export-docbook-close-para-maybe)
(insert (cond
((equal item-type "u") "<itemizedlist>\n<listitem>\n")
((equal item-type "o")
((and (equal item-type "o") item-number)
;; Check for a specific start number. If it
;; is specified, we use the ``override''
;; attribute of element <listitem> to pass the
@ -1064,10 +1047,8 @@ publishing directory."
;; ``startingnumber'' attribute of element
;; <orderedlist>, but the former works on both
;; DocBook 5.0 and prior versions.
(if initial-number
(format "<orderedlist>\n<listitem override=\"%s\">\n"
initial-number)
"<orderedlist>\n<listitem>\n"))
(format "<orderedlist>\n<listitem override=\"%s\">\n" item-number))
((equal item-type "o") "<orderedlist>\n<listitem>\n")
((equal item-type "d")
(format "<variablelist>\n<varlistentry><term>%s</term><listitem>\n" item-tag))))
;; For DocBook, we need to open a para right after tag
@ -1076,11 +1057,27 @@ publishing directory."
(push item-type local-list-type)
(push ind local-list-indent)
(setq in-local-list t))
(starter
;; Continue current list
(starter
;; terminate any previous sublist but first ensure
;; list is not ill-formed
(let ((min-ind (apply 'min local-list-indent)))
(when (< ind min-ind) (setq ind min-ind)))
(while (< ind (car local-list-indent))
(let ((listtype (car local-list-type)))
(org-export-docbook-close-li listtype)
(insert (cond
((equal listtype "o") "</orderedlist>\n")
((equal listtype "u") "</itemizedlist>\n")
((equal listtype "d") "</variablelist>\n"))))
(pop local-list-type) (pop local-list-indent)
(setq in-local-list local-list-indent))
;; insert new item
(let ((listtype (car local-list-type)))
(org-export-docbook-close-li listtype)
(insert (cond
((and (equal listtype "o") item-number)
(format "<listitem override=\"%s\">" item-number))
((equal listtype "o") "<listitem>")
((equal listtype "u") "<listitem>")
((equal listtype "d") (format
@ -1089,9 +1086,6 @@ publishing directory."
"???"))))))
;; For DocBook, we need to open a para right after tag
;; <listitem>.
(org-export-docbook-open-para))
(didclose
;; We did close a list, normal text follows: need <para>
(org-export-docbook-open-para)))
;; Checkboxes.
(if (string-match "^[ \t]*\\(\\[[X -]\\]\\)" line)
@ -1134,18 +1128,7 @@ publishing directory."
(when inquote
(insert "]]></programlisting>\n")
(org-export-docbook-open-para))
(when in-local-list
;; Close any local lists before inserting a new header line
(while local-list-type
(let ((listtype (car local-list-type)))
(org-export-docbook-close-li listtype)
(insert (cond
((equal listtype "o") "</orderedlist>\n")
((equal listtype "u") "</itemizedlist>\n")
((equal listtype "d") "</variablelist>\n"))))
(pop local-list-type))
(setq local-list-indent nil
in-local-list nil))
;; Close all open sections.
(org-export-docbook-level-start 1 nil)
@ -1212,24 +1195,6 @@ publishing directory."
(defvar in-local-list)
(defvar local-list-indent)
(defvar local-list-type)
(defun org-export-docbook-close-lists-maybe (line)
(let ((ind (or (get-text-property 0 'original-indentation line)))
; (and (string-match "\\S-" line)
; (org-get-indentation line))))
didclose)
(when ind
(while (and in-local-list
(<= ind (car local-list-indent)))
(setq didclose t)
(let ((listtype (car local-list-type)))
(org-export-docbook-close-li listtype)
(insert (cond
((equal listtype "o") "</orderedlist>\n")
((equal listtype "u") "</itemizedlist>\n")
((equal listtype "d") "</variablelist>\n"))))
(pop local-list-type) (pop local-list-indent)
(setq in-local-list local-list-indent))
(and didclose (org-export-docbook-open-para)))))
(defun org-export-docbook-level-start (level title)
"Insert a new level in DocBook export.
@ -1249,7 +1214,7 @@ When TITLE is nil, just close all open levels."
;; all levels, so the rest is done only if title is given.
;;
;; Format tags: put them into a superscript like format.
(when (string-match (org-re "\\(:[[:alnum:]_@:]+:\\)[ \t]*$") title)
(when (string-match (org-re "\\(:[[:alnum:]_@#%:]+:\\)[ \t]*$") title)
(setq title
(replace-match
(if org-export-with-tags
@ -1273,7 +1238,7 @@ When TITLE is nil, just close all open levels."
Applies all active conversions. If there are links in the
string, don't modify these."
(let* ((re (concat org-bracket-link-regexp "\\|"
(org-re "[ \t]+\\(:[[:alnum:]_@:]+:\\)[ \t]*$")))
(org-re "[ \t]+\\(:[[:alnum:]_@#%:]+:\\)[ \t]*$")))
m s l res)
(while (setq m (string-match re string))
(setq s (substring string 0 m)

View File

@ -46,8 +46,11 @@
(require 'org)
(declare-function doc-view-goto-page "doc-view" (page))
(declare-function doc-view-current-page "doc-view" (&optional win))
(declare-function doc-view-goto-page "ext:doc-view" (page))
(declare-function image-mode-window-get "ext:image-mode"
(prop &optional winprops))
(autoload 'doc-view-goto-page "doc-view")
(org-add-link-type "docview" 'org-docview-open)
(add-hook 'org-store-link-functions 'org-docview-store-link)
@ -66,7 +69,7 @@
(when (eq major-mode 'doc-view-mode)
;; This buffer is in doc-view-mode
(let* ((path buffer-file-name)
(page (doc-view-current-page))
(page (image-mode-window-get 'page))
(link (concat "docview:" path "::" (number-to-string page)))
(description ""))
(org-store-link-props

View File

@ -201,7 +201,8 @@ which defaults to the value of `org-export-blocks-witheld'."
(interblock start (point-max))
(run-hooks 'org-export-blocks-postblock-hook)))))
(add-hook 'org-export-preprocess-hook 'org-export-blocks-preprocess)
(add-hook 'org-export-preprocess-after-include-files-hook
'org-export-blocks-preprocess)
;;================================================================================
;; type specific functions

View File

@ -695,6 +695,7 @@ modified) list.")
"EXPORT_SELECT_TAGS" "EXPORT_EXCLUDE_TAGS"
"KEYWORDS" "DESCRIPTION" "MACRO" "BIND" "XSLT")
(mapcar 'car org-export-inbuffer-options-extra))))
(case-fold-search t)
p key val text options mathjax a pr style
latex-header latex-class macros letbind
ext-setup-or-nil setup-contents (start 0))
@ -1076,6 +1077,9 @@ on this string to produce the exported version."
(plist-get parameters :exclude-tags))
(run-hooks 'org-export-preprocess-after-tree-selection-hook)
;; Mark end of lists
(org-export-mark-list-ending backend)
;; Handle source code snippets
(org-export-replace-src-segments-and-examples backend)
@ -1626,6 +1630,31 @@ These special cookies will later be interpreted by the backend."
(delete-region beg end)
(insert (org-add-props content nil 'original-indentation ind))))))
(defun org-export-mark-list-ending (backend)
"Mark list endings with special cookies.
These special cookies will later be interpreted by the backend.
`org-list-end-re' is replaced by a blank line in the process."
(let ((process-buffer
(lambda (end-list-marker)
(goto-char (point-min))
(while (org-search-forward-unenclosed org-item-beginning-re nil t)
(goto-char (org-list-bottom-point))
(when (and (not (eq org-list-ending-method 'indent))
(looking-at (org-list-end-re)))
(replace-match "\n"))
(insert end-list-marker)))))
;; We need to divide backends into 3 categories.
(cond
;; 1. Backends using `org-list-parse-list' do not need markers.
((memq backend '(latex))
nil)
;; 2. Line-processing backends need to be told where lists end.
((memq backend '(html docbook))
(funcall process-buffer "ORG-LIST-END\n"))
;; 3. Others backends do not need to know this: clean list enders.
(t
(funcall process-buffer "")))))
(defun org-export-attach-captions-and-attributes (backend target-alist)
"Move #+CAPTION, #+ATTR_BACKEND, and #+LABEL text into text properties.
If the next thing following is a table, add the text properties to the first
@ -1838,7 +1867,9 @@ can work correctly."
(if (and (not (= (char-after (match-beginning 3))
(char-after (match-beginning 4))))
(save-excursion (goto-char (match-beginning 0))
(save-match-data (not (org-at-table-p)))))
(save-match-data
(and (not (org-at-table-p))
(not (org-at-heading-p))))))
(org-if-unprotected
(subst-char-in-region (match-beginning 0) (match-end 0)
?\n ?\ t)
@ -2794,7 +2825,7 @@ If yes remove the column and the special lines."
(defun org-export-cleanup-toc-line (s)
"Remove tags and timestamps from lines going into the toc."
(when (memq org-export-with-tags '(not-in-toc nil))
(if (string-match (org-re " +:[[:alnum:]_@:]+: *$") s)
(if (string-match (org-re " +:[[:alnum:]_@#%:]+: *$") s)
(setq s (replace-match "" t t s))))
(when org-export-remove-timestamps-from-toc
(while (string-match org-maybe-keyword-time-regexp s)

View File

@ -99,11 +99,11 @@
(declare-function xml-get-children "xml" (node child-name))
(declare-function xml-get-attribute "xml" (node attribute))
(declare-function xml-get-attribute-or-nil "xml" (node attribute))
(defvar xml-entity-alist)
(declare-function xml-substitute-special "xml" (string))
(defgroup org-feed nil
"Options concerning RSS feeds as inputs for Org files."
:tag "Org ID"
:tag "Org Feed"
:group 'org)
(defcustom org-feed-alist nil
@ -269,17 +269,6 @@ have been saved."
(defvar org-feed-buffer "*Org feed*"
"The buffer used to retrieve a feed.")
(defun org-feed-unescape (s)
"Unescape protected entities in S."
(require 'xml)
(let ((re (concat "&\\("
(mapconcat 'car xml-entity-alist "\\|")
"\\);")))
(while (string-match re s)
(setq s (replace-match
(cdr (assoc (match-string 1 s) xml-entity-alist)) nil nil s)))
s))
;;;###autoload
(defun org-feed-update-all ()
"Get inbox items from all feeds in `org-feed-alist'."
@ -553,7 +542,8 @@ If that property is already present, nothing changes."
(setq tmp (org-feed-make-indented-block
tmp (org-get-indentation))))))
(replace-match tmp t t))))
(buffer-string)))))
(decode-coding-string
(buffer-string) (detect-coding-region (point-min) (point-max) t))))))
(defun org-feed-make-indented-block (s n)
"Add indentation of N spaces to a multiline string S."
@ -613,6 +603,7 @@ containing the properties `:guid' and `:item-full-text'."
(defun org-feed-parse-rss-entry (entry)
"Parse the `:item-full-text' field for xml tags and create new properties."
(require 'xml)
(with-temp-buffer
(insert (plist-get entry :item-full-text))
(goto-char (point-min))
@ -620,7 +611,7 @@ containing the properties `:guid' and `:item-full-text'."
nil t)
(setq entry (plist-put entry
(intern (concat ":" (match-string 1)))
(org-feed-unescape (match-string 2)))))
(xml-substitute-special (match-string 2)))))
(goto-char (point-min))
(unless (re-search-forward "isPermaLink[ \t]*=[ \t]*\"false\"" nil t)
(setq entry (plist-put entry :guid-permalink t))))
@ -654,7 +645,7 @@ formatted as a string, not the original XML data."
'href)))
;; Add <title/> as :title.
(setq entry (plist-put entry :title
(org-feed-unescape
(xml-substitute-special
(car (xml-node-children
(car (xml-get-children xml 'title)))))))
(let* ((content (car (xml-get-children xml 'content)))
@ -664,12 +655,12 @@ formatted as a string, not the original XML data."
((string= type "text")
;; We like plain text.
(setq entry (plist-put entry :description
(org-feed-unescape
(xml-substitute-special
(car (xml-node-children content))))))
((string= type "html")
;; TODO: convert HTML to Org markup.
(setq entry (plist-put entry :description
(org-feed-unescape
(xml-substitute-special
(car (xml-node-children content))))))
((string= type "xhtml")
;; TODO: convert XHTML to Org markup.

View File

@ -39,6 +39,7 @@
;; Declare external functions and variables
(declare-function message-fetch-field "message" (header &optional not-all))
(declare-function message-narrow-to-head-1 "message" nil)
(declare-function nnimap-group-overview-filename "nnimap" (group server))
;; The following line suppresses a compiler warning stemming from gnus-sum.el
(declare-function gnus-summary-last-subject "gnus-sum" nil)
;; Customization variables
@ -54,12 +55,40 @@ negates this setting for the duration of the command."
:group 'org-link-store
:type 'boolean)
(defcustom org-gnus-nnimap-query-article-no-from-file t
"If non-nil, `org-gnus-follow-link' will try to translate
Message-Ids to article numbers by querying the .overview file.
Normally, this translation is done by querying the IMAP server,
which is usually very fast. Unfortunately, some (maybe badly
configured) IMAP servers don't support this operation quickly.
So if following a link to a Gnus article takes ages, try setting
this variable to `t'."
:group 'org-link-store
:type 'boolean)
;; Install the link type
(org-add-link-type "gnus" 'org-gnus-open)
(add-hook 'org-store-link-functions 'org-gnus-store-link)
;; Implementation
(defun org-gnus-nnimap-cached-article-number (group server message-id)
"Return cached article number (uid) of message in GROUP on SERVER.
MESSAGE-ID is the message-id header field that identifies the
message. If the uid is not cached, return nil."
(with-temp-buffer
(let ((nov (nnimap-group-overview-filename group server)))
(when (file-exists-p nov)
(mm-insert-file-contents nov)
(set-buffer-modified-p nil)
(goto-char (point-min))
(catch 'found
(while (search-forward message-id nil t)
(let ((hdr (split-string (thing-at-point 'line) "\t")))
(if (string= (nth 4 hdr) message-id)
(throw 'found (nth 0 hdr))))))))))
(defun org-gnus-group-link (group)
"Create a link to the Gnus group GROUP.
If GROUP is a newsgroup and `org-gnus-prefer-web-links' is
@ -171,7 +200,9 @@ If `org-store-link' was called with a prefix arg the meaning of
(cond ((and group article)
(gnus-activate-group group t)
(condition-case nil
(let ((backend (car (gnus-find-method-for-group group))))
(let* ((method (gnus-find-method-for-group group))
(backend (car method))
(server (cadr method)))
(cond
((eq backend 'nndoc)
(if (gnus-group-read-group t nil group)
@ -181,6 +212,12 @@ If `org-store-link' was called with a prefix arg the meaning of
(t
(let ((articles 1)
group-opened)
(when (and (eq backend 'nnimap)
org-gnus-nnimap-query-article-no-from-file)
(setq article
(or (org-gnus-nnimap-cached-article-number
(nth 1 (split-string group ":"))
server (concat "<" article ">")) article)))
(while (and (not group-opened)
;; stop on integer overflows
(> articles 0))

View File

@ -149,15 +149,17 @@ This list represents a \"habit\" for the rest of this module."
(assert (org-is-habit-p (point)))
(let* ((scheduled (org-get-scheduled-time (point)))
(scheduled-repeat (org-get-repeat org-scheduled-string))
(sr-days (org-habit-duration-to-days scheduled-repeat))
(end (org-entry-end-position))
(habit-entry (org-no-properties (nth 5 (org-heading-components))))
closed-dates deadline dr-days)
(habit-entry (org-no-properties (nth 4 (org-heading-components))))
closed-dates deadline dr-days sr-days)
(if scheduled
(setq scheduled (time-to-days scheduled))
(error "Habit %s has no scheduled date" habit-entry))
(unless scheduled-repeat
(error "Habit %s has no scheduled repeat period" habit-entry))
(error
"Habit '%s' has no scheduled repeat period or has an incorrect one"
habit-entry))
(setq sr-days (org-habit-duration-to-days scheduled-repeat))
(unless (> sr-days 0)
(error "Habit %s scheduled repeat period is less than 1d" habit-entry))
(when (string-match "/\\([0-9]+[dwmy]\\)" scheduled-repeat)

View File

@ -674,7 +674,7 @@ See variable `org-export-html-link-org-files-as-html'"
(string-match "\\.org$" path)
(progn
(list
"http"
"file"
(concat
(substring path 0 (match-beginning 0))
"."
@ -720,7 +720,7 @@ MAY-INLINE-P allows inlining it as an image."
;;Substitute just if original path was absolute.
;;(Otherwise path must remain relative)
(if (file-name-absolute-p path)
(expand-file-name path)
(concat "file://" (expand-file-name path))
path)))
((string= type "")
(list nil path))
@ -756,8 +756,7 @@ MAY-INLINE-P allows inlining it as an image."
(setq thefile
(let
((str (org-export-html-format-href thefile)))
(if (and type (not (string= "file" type))
(org-string-match-p "^//" str))
(if (and type (not (string= "file" type)))
(concat type ":" str)
str)))
@ -890,8 +889,8 @@ PUB-DIR is set, use this as the publishing directory."
(string-match "\\S-" (plist-get opt-plist :link-up))
(plist-get opt-plist :link-up)))
(link-home (and (plist-get opt-plist :link-home)
(string-match "\\S-" (plist-get opt-plist :link-home))
(plist-get opt-plist :link-home)))
(string-match "\\S-" (plist-get opt-plist :link-home))
(plist-get opt-plist :link-home)))
(dummy (setq opt-plist (plist-put opt-plist :title title)))
(html-table-tag (plist-get opt-plist :html-table-tag))
(quote-re0 (concat "^[ \t]*" org-quote-string "\\>"))
@ -960,9 +959,9 @@ PUB-DIR is set, use this as the publishing directory."
""))
table-open type
table-buffer table-orig-buffer
ind item-type starter didclose
ind item-type starter
rpl path attr desc descp desc1 desc2 link
snumber fnc item-tag initial-number
snumber fnc item-tag item-number
footnotes footref-seen
id-file href
)
@ -1072,73 +1071,73 @@ lang=\"%s\" xml:lang=\"%s\">
(push "<ul>\n<li>" thetoc)
(setq lines
(mapcar '(lambda (line)
(if (and (string-match org-todo-line-regexp line)
(not (get-text-property 0 'org-protected line)))
;; This is a headline
(progn
(setq have-headings t)
(setq level (- (match-end 1) (match-beginning 1)
level-offset)
level (org-tr-level level)
txt (save-match-data
(org-html-expand
(org-export-cleanup-toc-line
(match-string 3 line))))
todo
(or (and org-export-mark-todo-in-toc
(match-beginning 2)
(not (member (match-string 2 line)
org-done-keywords)))
(if (and (string-match org-todo-line-regexp line)
(not (get-text-property 0 'org-protected line)))
;; This is a headline
(progn
(setq have-headings t)
(setq level (- (match-end 1) (match-beginning 1)
level-offset)
level (org-tr-level level)
txt (save-match-data
(org-html-expand
(org-export-cleanup-toc-line
(match-string 3 line))))
todo
(or (and org-export-mark-todo-in-toc
(match-beginning 2)
(not (member (match-string 2 line)
org-done-keywords)))
; TODO, not DONE
(and org-export-mark-todo-in-toc
(= level umax-toc)
(org-search-todo-below
line lines level))))
(if (string-match
(org-re "[ \t]+:\\([[:alnum:]_@:]+\\):[ \t]*$") txt)
(setq txt (replace-match "&nbsp;&nbsp;&nbsp;<span class=\"tag\"> \\1</span>" t nil txt)))
(if (string-match quote-re0 txt)
(setq txt (replace-match "" t t txt)))
(setq snumber (org-section-number level))
(if org-export-with-section-numbers
(setq txt (concat snumber " " txt)))
(if (<= level (max umax umax-toc))
(setq head-count (+ head-count 1)))
(if (<= level umax-toc)
(progn
(if (> level org-last-level)
(progn
(setq cnt (- level org-last-level))
(while (>= (setq cnt (1- cnt)) 0)
(push "\n<ul>\n<li>" thetoc))
(push "\n" thetoc)))
(if (< level org-last-level)
(progn
(setq cnt (- org-last-level level))
(while (>= (setq cnt (1- cnt)) 0)
(push "</li>\n</ul>" thetoc))
(push "\n" thetoc)))
;; Check for targets
(while (string-match org-any-target-regexp line)
(setq line (replace-match
(concat "@<span class=\"target\">" (match-string 1 line) "@</span> ")
t t line)))
(while (string-match "&lt;\\(&lt;\\)+\\|&gt;\\(&gt;\\)+" txt)
(setq txt (replace-match "" t t txt)))
(setq href
(replace-regexp-in-string
"\\." "_" (format "sec-%s" snumber)))
(setq href (or (cdr (assoc href org-export-preferred-target-alist)) href))
(push
(format
(if todo
"</li>\n<li><a href=\"#%s\"><span class=\"todo\">%s</span></a>"
"</li>\n<li><a href=\"#%s\">%s</a>")
href txt) thetoc)
(and org-export-mark-todo-in-toc
(= level umax-toc)
(org-search-todo-below
line lines level))))
(if (string-match
(org-re "[ \t]+:\\([[:alnum:]_@:]+\\):[ \t]*$") txt)
(setq txt (replace-match "&nbsp;&nbsp;&nbsp;<span class=\"tag\"> \\1</span>" t nil txt)))
(if (string-match quote-re0 txt)
(setq txt (replace-match "" t t txt)))
(setq snumber (org-section-number level))
(if org-export-with-section-numbers
(setq txt (concat snumber " " txt)))
(if (<= level (max umax umax-toc))
(setq head-count (+ head-count 1)))
(if (<= level umax-toc)
(progn
(if (> level org-last-level)
(progn
(setq cnt (- level org-last-level))
(while (>= (setq cnt (1- cnt)) 0)
(push "\n<ul>\n<li>" thetoc))
(push "\n" thetoc)))
(if (< level org-last-level)
(progn
(setq cnt (- org-last-level level))
(while (>= (setq cnt (1- cnt)) 0)
(push "</li>\n</ul>" thetoc))
(push "\n" thetoc)))
;; Check for targets
(while (string-match org-any-target-regexp line)
(setq line (replace-match
(concat "@<span class=\"target\">" (match-string 1 line) "@</span> ")
t t line)))
(while (string-match "&lt;\\(&lt;\\)+\\|&gt;\\(&gt;\\)+" txt)
(setq txt (replace-match "" t t txt)))
(setq href
(replace-regexp-in-string
"\\." "_" (format "sec-%s" snumber)))
(setq href (or (cdr (assoc href org-export-preferred-target-alist)) href))
(push
(format
(if todo
"</li>\n<li><a href=\"#%s\"><span class=\"todo\">%s</span></a>"
"</li>\n<li><a href=\"#%s\">%s</a>")
href txt) thetoc)
(setq org-last-level level))
)))
line)
(setq org-last-level level))
)))
line)
lines))
(while (> org-last-level (1- org-min-level))
(setq org-last-level (1- org-last-level))
@ -1181,7 +1180,16 @@ lang=\"%s\" xml:lang=\"%s\">
(org-open-par))
(throw 'nextline nil))
(org-export-html-close-lists-maybe line)
;; Explicit list closure
(when (equal "ORG-LIST-END" line)
(while local-list-indent
(org-close-li (car local-list-type))
(insert (format "</%sl>\n" (car local-list-type)))
(pop local-list-type)
(pop local-list-indent))
(setq in-local-list nil)
(org-open-par)
(throw 'nextline nil))
;; Protected HTML
(when (get-text-property 0 'org-protected line)
@ -1300,79 +1308,79 @@ lang=\"%s\" xml:lang=\"%s\">
desc2 (if (match-end 2) (concat type ":" path) path)
descp (and desc1 (not (equal desc1 desc2)))
desc (or desc1 desc2))
;; Make an image out of the description if that is so wanted
;; Make an image out of the description if that is so wanted
(when (and descp (org-file-image-p
desc org-export-html-inline-image-extensions))
(save-match-data
(if (string-match "^file:" desc)
(setq desc (substring desc (match-end 0)))))
(setq desc (org-add-props
desc org-export-html-inline-image-extensions))
(save-match-data
(if (string-match "^file:" desc)
(setq desc (substring desc (match-end 0)))))
(setq desc (org-add-props
(concat "<img src=\"" desc "\"/>")
'(org-protected t))))
(cond
((equal type "internal")
(let
((frag-0
(if (= (string-to-char path) ?#)
(substring path 1)
path)))
(setq rpl
(let
((frag-0
(if (= (string-to-char path) ?#)
(substring path 1)
path)))
(setq rpl
(org-html-make-link
opt-plist
""
""
(org-solidify-link-text
(save-match-data (org-link-unescape frag-0))
nil)
desc attr nil))))
opt-plist
""
""
(org-solidify-link-text
(save-match-data (org-link-unescape frag-0))
nil)
desc attr nil))))
((and (equal type "id")
(setq id-file (org-id-find-id-file path)))
;; This is an id: link to another file (if it was the same file,
;; it would have become an internal link...)
(save-match-data
(setq id-file (file-relative-name
id-file
(file-name-directory org-current-export-file)))
id-file
(file-name-directory org-current-export-file)))
(setq rpl
(org-html-make-link opt-plist
"file" id-file
(concat (if (org-uuidgen-p path) "ID-") path)
desc
attr
nil))))
(org-html-make-link opt-plist
"file" id-file
(concat (if (org-uuidgen-p path) "ID-") path)
desc
attr
nil))))
((member type '("http" "https"))
;; standard URL, can inline as image
(setq rpl
(org-html-make-link opt-plist
type path nil
desc
attr
(org-html-should-inline-p path descp))))
;; standard URL, can inline as image
(setq rpl
(org-html-make-link opt-plist
type path nil
desc
attr
(org-html-should-inline-p path descp))))
((member type '("ftp" "mailto" "news"))
;; standard URL, can't inline as image
(setq rpl
(org-html-make-link opt-plist
type path nil
desc
attr
nil)))
;; standard URL, can't inline as image
(setq rpl
(org-html-make-link opt-plist
type path nil
desc
attr
nil)))
((string= type "coderef")
(let*
((coderef-str (format "coderef-%s" path))
(attr-1
(format "class=\"coderef\" onmouseover=\"CodeHighlightOn(this, '%s');\" onmouseout=\"CodeHighlightOff(this, '%s');\""
(let*
((coderef-str (format "coderef-%s" path))
(attr-1
(format "class=\"coderef\" onmouseover=\"CodeHighlightOn(this, '%s');\" onmouseout=\"CodeHighlightOff(this, '%s');\""
coderef-str coderef-str)))
(setq rpl
(setq rpl
(org-html-make-link opt-plist
type "" coderef-str
(format
(org-export-get-coderef-format
path
(and descp desc))
(cdr (assoc path org-export-code-refs)))
attr-1
nil))))
type "" coderef-str
(format
(org-export-get-coderef-format
path
(and descp desc))
(cdr (assoc path org-export-code-refs)))
attr-1
nil))))
((functionp (setq fnc (nth 2 (assoc type org-link-protocols))))
;; The link protocol has a function for format the link
@ -1381,55 +1389,55 @@ lang=\"%s\" xml:lang=\"%s\">
(funcall fnc (org-link-unescape path) desc1 'html))))
((string= type "file")
;; FILE link
(save-match-data
(let*
((components
(if
(string-match "::\\(.*\\)" path)
(list
(replace-match "" t nil path)
(match-string 1 path))
(list path nil)))
;; FILE link
(save-match-data
(let*
((components
(if
(string-match "::\\(.*\\)" path)
(list
(replace-match "" t nil path)
(match-string 1 path))
(list path nil)))
;;The proper path, without a fragment
(path-1
(first components))
;;The proper path, without a fragment
(path-1
(first components))
;;The raw fragment
(fragment-0
(second components))
;;The raw fragment
(fragment-0
(second components))
;;Check the fragment. If it can't be used as
;;target fragment we'll pass nil instead.
(fragment-1
(if
(and fragment-0
(not (string-match "^[0-9]*$" fragment-0))
(not (string-match "^\\*" fragment-0))
(not (string-match "^/.*/$" fragment-0)))
(org-solidify-link-text
(org-link-unescape fragment-0))
nil))
(desc-2
;;Description minus "file:" and ".org"
(if (string-match "^file:" desc)
(let
((desc-1 (replace-match "" t t desc)))
(if (string-match "\\.org$" desc-1)
(replace-match "" t t desc-1)
desc-1))
desc)))
;;Check the fragment. If it can't be used as
;;target fragment we'll pass nil instead.
(fragment-1
(if
(and fragment-0
(not (string-match "^[0-9]*$" fragment-0))
(not (string-match "^\\*" fragment-0))
(not (string-match "^/.*/$" fragment-0)))
(org-solidify-link-text
(org-link-unescape fragment-0))
nil))
(desc-2
;;Description minus "file:" and ".org"
(if (string-match "^file:" desc)
(let
((desc-1 (replace-match "" t t desc)))
(if (string-match "\\.org$" desc-1)
(replace-match "" t t desc-1)
desc-1))
desc)))
(setq rpl
(if
(setq rpl
(if
(and
(functionp link-validate)
(not (funcall link-validate path-1 current-dir)))
(functionp link-validate)
(not (funcall link-validate path-1 current-dir)))
desc
(org-html-make-link opt-plist
"file" path-1 fragment-1 desc-2 attr
(org-html-should-inline-p path-1 descp)))))))
(org-html-make-link opt-plist
"file" path-1 fragment-1 desc-2 attr
(org-html-should-inline-p path-1 descp)))))))
(t
;; just publish the path, as default
@ -1486,14 +1494,6 @@ lang=\"%s\" xml:lang=\"%s\">
(setq txt (replace-match "" t t txt)))
(if (<= level (max umax umax-toc))
(setq head-count (+ head-count 1)))
(when in-local-list
;; Close any local lists before inserting a new header line
(while local-list-type
(org-close-li (car local-list-type))
(insert (format "</%sl>\n" (car local-list-type)))
(pop local-list-type))
(setq local-list-indent nil
in-local-list nil))
(setq first-heading-pos (or first-heading-pos (point)))
(org-html-level-start level txt umax
(and org-export-with-toc (<= level umax))
@ -1505,19 +1505,6 @@ lang=\"%s\" xml:lang=\"%s\">
(insert "<pre>")
(setq inquote t)))
((string-match "^[ \t]*- __+[ \t]*$" line)
;; Explicit list closure
(when local-list-type
(let ((ind (org-get-indentation line)))
(while (and local-list-indent
(<= ind (car local-list-indent)))
(org-close-li (car local-list-type))
(insert (format "</%sl>\n" (car local-list-type)))
(pop local-list-type)
(pop local-list-indent))
(or local-list-indent (setq in-local-list nil))))
(throw 'nextline nil))
((and org-export-with-tables
(string-match "^\\([ \t]*\\)\\(|\\|\\+-+\\+\\)" line))
(when (not table-open)
@ -1550,66 +1537,57 @@ lang=\"%s\" xml:lang=\"%s\">
starter (if (match-beginning 2)
(substring (match-string 2 line) 0 -1))
line (substring line (match-beginning 5))
initial-number nil
item-number nil
item-tag nil)
(if (string-match "\\`\\[@start:\\([0-9]+\\)\\][ \t]?" line)
(setq initial-number (match-string 1 line)
(if (string-match "\\[@\\(?:start:\\)?\\([0-9]+\\)\\][ \t]?" line)
(setq item-number (match-string 1 line)
line (replace-match "" t t line)))
(if (and starter (string-match "\\(.*?\\) ::[ \t]*" line))
(setq item-type "d"
item-tag (match-string 1 line)
line (substring line (match-end 0))))
(when (and (not (equal item-type "d"))
(not (string-match "[^ \t]" line)))
;; empty line. Pretend indentation is large.
(setq ind (if org-empty-line-terminates-plain-lists
0
(1+ (or (car local-list-indent) 1)))))
(setq didclose nil)
(while (and in-local-list
(or (and (= ind (car local-list-indent))
(not starter))
(< ind (car local-list-indent))))
(setq didclose t)
(org-close-li (car local-list-type))
(insert (format "</%sl>\n" (car local-list-type)))
(pop local-list-type) (pop local-list-indent)
(setq in-local-list local-list-indent))
(cond
((and starter
(or (not in-local-list)
(> ind (car local-list-indent))))
;; check for a specified start number
;; Start new (level of) list
(org-close-par-maybe)
(insert (cond
((equal item-type "u") "<ul>\n<li>\n")
((equal item-type "o")
(if initial-number
(format "<ol start=%s>\n<li>\n" initial-number)
"<ol>\n<li>\n"))
((and (equal item-type "o") item-number)
(format "<ol>\n<li value=\"%s\">\n" item-number))
((equal item-type "o") "<ol>\n<li>\n")
((equal item-type "d")
(format "<dl>\n<dt>%s</dt><dd>\n" item-tag))))
(push item-type local-list-type)
(push ind local-list-indent)
(setq in-local-list t))
;; Continue list
(starter
;; continue current list
;; terminate any previous sublist but first ensure
;; list is not ill-formed.
(let ((min-ind (apply 'min local-list-indent)))
(when (< ind min-ind) (setq ind min-ind)))
(while (< ind (car local-list-indent))
(org-close-li (car local-list-type))
(insert (format "</%sl>\n" (car local-list-type)))
(pop local-list-type) (pop local-list-indent)
(setq in-local-list local-list-indent))
;; insert new item
(org-close-li (car local-list-type))
(insert (cond
((equal (car local-list-type) "d")
(format "<dt>%s</dt><dd>\n" (or item-tag "???")))
(t "<li>\n"))))
(didclose
;; we did close a list, normal text follows: need <p>
(org-open-par)))
((and (equal item-type "o") item-number)
(format "<li value=\"%s\">\n" item-number))
(t "<li>\n")))))
(if (string-match "^[ \t]*\\[\\([X ]\\)\\]" line)
(setq line
(replace-match
(if (equal (match-string 1 line) "X")
"<b>[X]</b>"
"<b>[<span style=\"visibility:hidden;\">X</span>]</b>")
t t line))))
t t line))))
;; Horizontal line
(when (string-match "^[ \t]*-\\{5,\\}[ \t]*$" line)
@ -1664,14 +1642,7 @@ lang=\"%s\" xml:lang=\"%s\">
(when inquote
(insert "</pre>\n")
(org-open-par))
(when in-local-list
;; Close any local lists before inserting a new header line
(while local-list-type
(org-close-li (car local-list-type))
(insert (format "</%sl>\n" (car local-list-type)))
(pop local-list-type))
(setq local-list-indent nil
in-local-list nil))
(org-html-level-start 1 nil umax
(and org-export-with-toc (<= level umax))
head-count)
@ -1752,8 +1723,6 @@ lang=\"%s\" xml:lang=\"%s\">
(while (re-search-forward "<li>[ \r\n\t]*</li>\n?" nil t)
(replace-match ""))
(goto-char (point-min))
(while (re-search-forward "</ul>\\s-*<ul>\n?" nil t)
(replace-match ""))
;; Convert whitespace place holders
(goto-char (point-min))
(let (beg end n)
@ -2164,7 +2133,7 @@ that uses these same face definitions."
"Prepare STRING for HTML export. Apply all active conversions.
If there are links in the string, don't modify these."
(let* ((re (concat org-bracket-link-regexp "\\|"
(org-re "[ \t]+\\(:[[:alnum:]_@:]+:\\)[ \t]*$")))
(org-re "[ \t]+\\(:[[:alnum:]_@#%:]+:\\)[ \t]*$")))
m s l res)
(if (string-match "^[ \t]*\\+-[-+]*\\+[ \t]*$" string)
string
@ -2274,28 +2243,6 @@ If there are links in the string, don't modify these."
(defvar in-local-list)
(defvar local-list-indent)
(defvar local-list-type)
(defun org-export-html-close-lists-maybe (line)
"Close local lists based on the original indentation of the line."
(let* ((rawhtml (and in-local-list
(get-text-property 0 'org-protected line)
(not (get-text-property 0 'org-example line))))
;; rawhtml means: This was between #+begin_html..#+end_html
;; originally, thus it excludes stuff that was a source code example
;; Actually, this code seems wrong, I don't know why it works, but
;; it seems to work.... So keep it like this for now.
(ind (if rawhtml
(org-get-indentation line)
(get-text-property 0 'original-indentation line)))
didclose)
(when ind
(while (and in-local-list
(<= ind (car local-list-indent)))
(setq didclose t)
(org-close-li (car local-list-type))
(insert (format "</%sl>\n" (car local-list-type)))
(pop local-list-type) (pop local-list-indent)
(setq in-local-list local-list-indent))
(and didclose (org-open-par)))))
(defvar body-only) ; dynamically scoped into this.
(defun org-html-level-start (level title umax with-toc head-count)
@ -2328,7 +2275,7 @@ When TITLE is nil, just close all open levels."
(when title
;; If title is nil, this means this function is called to close
;; all levels, so the rest is done only if title is given
(when (string-match (org-re "\\(:[[:alnum:]_@:]+:\\)[ \t]*$") title)
(when (string-match (org-re "\\(:[[:alnum:]_@#%:]+:\\)[ \t]*$") title)
(setq title (replace-match
(if org-export-with-tags
(save-match-data

View File

@ -194,6 +194,13 @@ When nil of the empty string, use the abbreviation retrieved from Emacs."
(const :tag "Unspecified" nil)
(string :tag "Time zone")))
(defcustom org-icalendar-use-UTC-date-time ()
"Non-nil force the use of the universal time for iCalendar DATE-TIME.
The iCalendar DATE-TIME can be expressed with local time or universal Time,
universal time could be more compatible with some external tools."
:group 'org-export-icalendar
:type 'boolean)
;;; iCalendar export
;;;###autoload
@ -311,7 +318,7 @@ When COMBINE is non nil, add the category to each line."
inc t
hd (condition-case nil
(org-icalendar-cleanup-string
(org-get-heading))
(org-get-heading t))
(error (throw :skip nil)))
summary (org-icalendar-cleanup-string
(org-entry-get nil "SUMMARY"))
@ -439,7 +446,7 @@ END:VEVENT\n"
(when org-icalendar-include-todo
(setq prefix "TODO-")
(goto-char (point-min))
(while (re-search-forward org-todo-line-regexp nil t)
(while (re-search-forward org-complex-heading-regexp nil t)
(catch :skip
(org-agenda-skip)
(when org-icalendar-verify-function
@ -471,7 +478,7 @@ END:VEVENT\n"
((eq org-icalendar-include-todo t)
;; include everything that is not done
(member state org-not-done-keywords))))
(setq hd (match-string 3)
(setq hd (match-string 4)
summary (org-icalendar-cleanup-string
(org-entry-get nil "SUMMARY"))
desc (org-icalendar-cleanup-string
@ -634,8 +641,13 @@ a time), or the day by one (if it does not contain a time)."
(setq h (+ 2 h)))
(setq d (1+ d))))
(setq time (encode-time s mi h d m y)))
(setq fmt (if have-time ":%Y%m%dT%H%M%S" ";VALUE=DATE:%Y%m%d"))
(concat keyword (format-time-string fmt time)))))
(setq fmt (if have-time (if org-icalendar-use-UTC-date-time
":%Y%m%dT%H%M%SZ"
":%Y%m%dT%H%M%S")
";VALUE=DATE:%Y%m%d"))
(concat keyword (format-time-string fmt time
(and org-icalendar-use-UTC-date-time
have-time))))))
(provide 'org-icalendar)

View File

@ -280,6 +280,11 @@ markup defined, the first one in the association list will be used."
(string :tag "Keyword")
(string :tag "Markup")))))
(defcustom org-export-latex-tag-markup "\\textbf{%s}"
"Markup for tags, as a printf format."
:group 'org-export-latex
:type 'string)
(defcustom org-export-latex-timestamp-markup "\\textit{%s}"
"A printf format string to be applied to time stamps."
:group 'org-export-latex
@ -952,28 +957,13 @@ Return a list reflecting the document structure."
(defun org-export-latex-parse-subcontent (level odd)
"Extract the subcontent of a section at LEVEL.
If ODD Is non-nil, assume subcontent only contains odd sections."
(let (nstars new-level)
;; In the search, we should not assume there will be exactly
;; LEVEL+1 stars in the next heading, as there may be more than
;; that number of stars. hence the regexp should be \\*{N,}
;; rather than just \\*{N} (i.e. no upper bound, but N is minimum
;; number of stars to expect.)
;; We then have to check how many stars were found, rather than
;; assuming there were exactly N.
(when (org-re-search-forward-unprotected
(concat "^\\(\\(?:\\*\\)\\{"
(number-to-string (+ (if odd 4 2) level))
",\\}\\) \\(.*\\)$")
nil t)
(setq nstars (1- (- (match-end 1) (match-beginning 1))))
(setq new-level (if odd
(/ (+ 3 nstars) 2);; not entirely sure why +3!
nstars)))
(if nstars
(org-export-latex-parse-global new-level odd)
nil) ; subcontent is nil
))
(if (not (org-re-search-forward-unprotected
(concat "^\\(\\(?:\\*\\)\\{"
(number-to-string (+ (if odd 4 2) level))
"\\}\\) \\(.*\\)$")
nil t))
nil ; subcontent is nil
(org-export-latex-parse-global (+ (if odd 2 1) level) odd)))
;;; Rendering functions:
(defun org-export-latex-global (content)
@ -1344,13 +1334,13 @@ links, keywords, lists, tables, fixed-width"
(replace-match "")
(replace-match (format "\\textbf{%s}" (match-string 0)) t t)))
;; convert tags
(when (re-search-forward "\\(:[a-zA-Z0-9_@]+\\)+:" nil t)
(when (re-search-forward "\\(:[a-zA-Z0-9_@#%]+\\)+:" nil t)
(if (or (not org-export-with-tags)
(plist-get remove-list :tags))
(replace-match "")
(replace-match
(org-export-latex-protect-string
(format "\\textbf{%s}"
(format org-export-latex-tag-markup
(save-match-data
(replace-regexp-in-string
"_" "\\\\_" (match-string 0)))))
@ -2253,11 +2243,11 @@ The conversion is made depending of STRING-BEFORE and STRING-AFTER."
"Convert plain text lists in current buffer into LaTeX lists."
(let (res)
(goto-char (point-min))
(while (org-re-search-forward-unprotected org-list-beginning-re nil t)
(while (org-search-forward-unenclosed org-item-beginning-re nil t)
(beginning-of-line)
(setq res (org-list-to-latex (org-list-parse-list t)
org-export-latex-list-parameters))
(while (string-match "^\\(\\\\item[ \t]+\\)\\[@start:\\([0-9]+\\)\\]"
(while (string-match "^\\(\\\\item[ \t]+\\)\\[@\\(?:start:\\)?\\([0-9]+\\)\\]"
res)
(setq res (replace-match
(concat (format "\\setcounter{enumi}{%d}"

File diff suppressed because it is too large Load Diff

View File

@ -290,6 +290,25 @@ This is in contrast to merely setting it to 0."
(match-beginning 0) string)))
(replace-match newtext fixedcase literal string))
(defmacro org-save-outline-visibility (use-markers &rest body)
"Save and restore outline visibility around BODY.
If USE-MARKERS is non-nil, use markers for the positions.
This means that the buffer may change while running BODY,
but it also means that the buffer should stay alive
during the operation, because otherwise all these markers will
point nowhere."
(declare (indent 1))
`(let ((data (org-outline-overlay-data ,use-markers)))
(unwind-protect
(progn
,@body
(org-set-outline-overlay-data data))
(when ,use-markers
(mapc (lambda (c)
(and (markerp (car c)) (move-marker (car c) nil))
(and (markerp (cdr c)) (move-marker (cdr c) nil)))
data)))))
(defmacro org-with-limited-levels (&rest body)
"Execute BODY with limited number of outline levels."
`(let* ((outline-regexp (org-get-limited-outline-regexp)))

View File

@ -181,7 +181,7 @@ you have a better idea of how to do this then please let us know."
(if (equal major-mode 'mh-folder-mode)
(mh-show)
(mh-show-show))
header-field)))
(org-trim header-field))))
(defun org-mhe-follow-link (folder article)
"Follow an MH-E link to FOLDER and ARTICLE.

View File

@ -148,6 +148,7 @@
(declare-function org-agenda-change-all-lines "org-agenda"
(newhead hdmarker &optional fixface just-this))
(declare-function org-verify-change-for-undo "org-agenda" (l1 l2))
(declare-function org-apply-on-list "org-list" (function init-value &rest args))
(defvar org-mouse-plain-list-regexp "\\([ \t]*\\)\\([-+*]\\|[0-9]+[.)]\\) "
"Regular expression that matches a plain list.")
@ -576,14 +577,11 @@ SCHEDULED: or DEADLINE: or ANYTHINGLIKETHIS:"
(goto-char (second contextdata))
(re-search-forward ".*" (third contextdata))))))
(defun org-mouse-for-each-item (function)
(save-excursion
(ignore-errors
(while t (org-previous-item)))
(ignore-errors
(while t
(funcall function)
(org-next-item)))))
(defun org-mouse-for-each-item (funct)
;; Functions called by `org-apply-on-list' need an argument
(let ((wrap-fun (lambda (c) (funcall funct))))
(when (org-in-item-p)
(org-apply-on-list wrap-fun nil))))
(defun org-mouse-bolp ()
"Return true if there only spaces, tabs, and '*' before point.

View File

@ -260,7 +260,7 @@ Here is an example:
:group 'org-protocol
:type '(alist))
(defcustom org-protocol-default-template-key "w"
(defcustom org-protocol-default-template-key nil
"The default org-remember-templates key to use."
:group 'org-protocol
:type 'string)

View File

@ -189,7 +189,14 @@ sitemap of files or summary page for a given project.
The following properties control the creation of a concept index.
:makeindex Create a concept index."
:makeindex Create a concept index.
Other properties affecting publication.
:body-only Set this to 't' to publish only the body of the
documents, excluding everything outside and
including the <body> tags in HTML, or
\begin{document}..\end{document} in LaTeX."
:group 'org-publish
:type 'alist)
@ -465,13 +472,19 @@ matching filenames."
(unless (plist-get (cdr prj) :components)
;; [[info:org:Selecting%20files]] shows how this is supposed to work:
(let* ((r (plist-get (cdr prj) :recursive))
(b (expand-file-name (plist-get (cdr prj) :base-directory)))
(b (expand-file-name (file-name-as-directory
(plist-get (cdr prj) :base-directory))))
(x (or (plist-get (cdr prj) :base-extension) "org"))
(e (plist-get (cdr prj) :exclude))
(i (plist-get (cdr prj) :include))
(xm (concat "^" b (if r ".+" "[^/]+") "\\.\\(" x "\\)$")))
(when (or
(and i (string-match i filename))
(and
i
(member filename
(mapcar
(lambda (file) (expand-file-name file b))
i)))
(and
(not (and e (string-match e filename)))
(string-match xm filename)))
@ -508,7 +521,9 @@ PUB-DIR is the publishing directory."
(setq export-buf-or-file
(funcall (intern (concat "org-export-as-" format))
(plist-get plist :headline-levels)
nil plist nil nil pub-dir))
nil plist nil
(plist-get plist :body-only)
pub-dir))
(when (and (bufferp export-buf-or-file)
(buffer-live-p export-buf-or-file))
(set-buffer export-buf-or-file)

View File

@ -574,7 +574,7 @@ to be run from that hook to function properly."
'org-tags-completion-function nil nil nil
'org-tags-history)))
(setq ins (mapconcat 'identity
(org-split-string ins (org-re "[^[:alnum:]_@]+"))
(org-split-string ins (org-re "[^[:alnum:]_@#%]+"))
":"))
(when (string-match "\\S-" ins)
(or (equal (char-before) ?:) (insert ":"))

View File

@ -34,6 +34,8 @@
(require 'org-macs)
(require 'org-compat)
(require 'ob-keys)
(require 'ob-comint)
(eval-when-compile
(require 'cl))
@ -165,6 +167,7 @@ For example, there is no ocaml-mode in Emacs, but the mode to use is
(defvar org-src-mode-map (make-sparse-keymap))
(define-key org-src-mode-map "\C-c'" 'org-edit-src-exit)
(defvar org-edit-src-force-single-line nil)
(defvar org-edit-src-from-org-mode nil)
(defvar org-edit-src-allow-write-back-p t)
@ -181,6 +184,8 @@ For example, there is no ocaml-mode in Emacs, but the mode to use is
immediately; otherwise it will ask whether you want to return
to the existing edit buffer.")
(defvar org-src-babel-info nil)
(define-minor-mode org-src-mode
"Minor mode for language major mode buffers generated by org.
This minor mode is turned on in two situations:
@ -189,13 +194,16 @@ This minor mode is turned on in two situations:
There is a mode hook, and keybindings for `org-edit-src-exit' and
`org-edit-src-save'")
(defun org-edit-src-code (&optional context code edit-buffer-name)
(defun org-edit-src-code (&optional context code edit-buffer-name quietp)
"Edit the source code example at point.
The example is copied to a separate buffer, and that buffer is switched
to the correct language mode. When done, exit with \\[org-edit-src-exit].
This will remove the original code in the Org buffer, and replace it with
the edited version. Optional argument CONTEXT is used by
\\[org-edit-src-save] when calling this function."
The example is copied to a separate buffer, and that buffer is
switched to the correct language mode. When done, exit with
\\[org-edit-src-exit]. This will remove the original code in the
Org buffer, and replace it with the edited version. Optional
argument CONTEXT is used by \\[org-edit-src-save] when calling
this function. See \\[org-src-window-setup] to configure the
display of windows containing the Org buffer and the code
buffer."
(interactive)
(unless (eq context 'save)
(setq org-edit-src-saved-temp-window-config (current-window-configuration)))
@ -203,6 +211,7 @@ the edited version. Optional argument CONTEXT is used by
(col (current-column))
(case-fold-search t)
(info (org-edit-src-find-region-and-lang))
(babel-info (org-babel-get-src-block-info))
(org-mode-p (eq major-mode 'org-mode))
(beg (make-marker))
(end (make-marker))
@ -267,11 +276,16 @@ the edited version. Optional argument CONTEXT is used by
(unless preserve-indentation
(setq total-nindent (or (org-do-remove-indentation) 0)))
(let ((org-inhibit-startup t))
(funcall lang-f))
(condition-case e
(funcall lang-f)
(error
(error "Language mode `%s' fails with: %S" lang-f (nth 1 e)))))
(set (make-local-variable 'org-edit-src-force-single-line) single)
(set (make-local-variable 'org-edit-src-from-org-mode) org-mode-p)
(set (make-local-variable 'org-edit-src-allow-write-back-p) allow-write-back-p)
(set (make-local-variable 'org-src-preserve-indentation) preserve-indentation)
(when babel-info
(set (make-local-variable 'org-src-babel-info) babel-info))
(when lfmt
(set (make-local-variable 'org-coderef-label-format) lfmt))
(when org-mode-p
@ -290,7 +304,7 @@ the edited version. Optional argument CONTEXT is used by
(set-buffer-modified-p nil)
(and org-edit-src-persistent-message
(org-set-local 'header-line-format msg)))
(message "%s" msg)
(unless quietp (message "%s" msg))
t)))
(defun org-edit-src-continue (e)
@ -321,6 +335,8 @@ the edited version. Optional argument CONTEXT is used by
(if (eq context 'edit) (delete-other-windows))
(org-switch-to-buffer-other-window buffer)
(if (eq context 'exit) (delete-other-windows)))
('switch-invisibly
(set-buffer buffer))
(t
(message "Invalid value %s for org-src-window-setup"
(symbol-name org-src-window-setup))
@ -654,6 +670,119 @@ the language, a switch telling if the content should be in a single line."
(org-add-hook 'org-src-mode-hook 'org-src-mode-configure-edit-buffer)
(defun org-src-associate-babel-session (info)
"Associate edit buffer with comint session."
(interactive)
(let ((session (cdr (assoc :session (nth 2 info)))))
(and session (not (string= session "none"))
(org-babel-comint-buffer-livep session)
((lambda (f) (and (fboundp f) (funcall f session)))
(intern (format "org-babel-%s-associate-session" (nth 0 info)))))))
(defun org-src-babel-configure-edit-buffer ()
(when org-src-babel-info
(org-src-associate-babel-session org-src-babel-info)))
(org-add-hook 'org-src-mode-hook 'org-src-babel-configure-edit-buffer)
(defmacro org-src-do-at-code-block (&rest body)
"Execute a command from an edit buffer in the Org-mode buffer."
`(let ((beg-marker org-edit-src-beg-marker))
(if beg-marker
(with-current-buffer (marker-buffer beg-marker)
(goto-char (marker-position beg-marker))
,@body))))
(defun org-src-do-key-sequence-at-code-block (&optional key)
"Execute key sequence at code block in the source Org buffer.
The command bound to KEY in the Org-babel key map is executed
remotely with point temporarily at the start of the code block in
the Org buffer.
This command is not bound to a key by default, to avoid conflicts
with language major mode bindings. To bind it to C-c @ in all
language major modes, you could use
(add-hook 'org-src-mode-hook
(lambda () (define-key org-src-mode-map \"\\C-c@\"
'org-src-do-key-sequence-at-code-block)))
In that case, for example, C-c @ t issued in code edit buffers
would tangle the current Org code block, C-c @ e would execute
the block and C-c @ h would display the other available
Org-babel commands."
(interactive "kOrg-babel key: ")
(if (equal key (kbd "C-g")) (keyboard-quit)
(org-edit-src-save)
(org-src-do-at-code-block
(call-interactively
(lookup-key org-babel-map key)))))
(defvar org-src-tab-acts-natively nil
"If non-nil, the effect of TAB in a code block is as if it were
issued in the language major mode buffer.")
(defun org-src-native-tab-command-maybe ()
"Perform language-specific TAB action.
Alter code block according to effect of TAB in the language major
mode."
(and org-src-tab-acts-natively
(org-babel-do-key-sequence-in-edit-buffer (kbd "TAB"))))
(add-hook 'org-tab-first-hook 'org-src-native-tab-command-maybe)
(defun org-src-font-lock-fontify-block (lang start end)
"Fontify code block.
This function is called by emacs automatic fontification, as long
as `org-src-fontify-natively' is non-nil. For manual
fontification of code blocks see `org-src-fontify-block' and
`org-src-fontify-buffer'"
(let* ((lang-mode (org-src-get-lang-mode lang))
(string (buffer-substring-no-properties start end))
(modified (buffer-modified-p))
(org-buffer (current-buffer)) pos next)
(remove-text-properties start end '(face nil))
(with-current-buffer
(get-buffer-create
(concat " org-src-fontification:" (symbol-name lang-mode)))
(delete-region (point-min) (point-max))
(insert string)
(unless (eq major-mode lang-mode) (funcall lang-mode))
(font-lock-fontify-buffer)
(setq pos (point-min))
(while (setq next (next-single-property-change pos 'face))
(put-text-property
(+ start (1- pos)) (+ start next) 'face
(get-text-property pos 'face) org-buffer)
(setq pos next)))
(add-text-properties
start end
'(font-lock-fontified t fontified t font-lock-multiline t))
(set-buffer-modified-p modified))
t) ;; Tell `org-fontify-meta-lines-and-blocks' that we fontified
(defun org-src-fontify-block ()
"Fontify code block at point."
(interactive)
(save-excursion
(let ((org-src-fontify-natively t)
(info (org-edit-src-find-region-and-lang)))
(font-lock-fontify-region (nth 0 info) (nth 1 info)))))
(defun org-src-fontify-buffer ()
"Fontify all code blocks in the current buffer"
(interactive)
(org-babel-map-src-blocks nil
(org-src-fontify-block)))
(defun org-src-get-lang-mode (lang)
"Return major mode that should be used for LANG.
LANG is a string, and the returned major mode is a symbol."
(intern
(concat
((lambda (l) (if (symbolp l) (symbol-name l) l))
(or (cdr (assoc lang org-src-lang-modes)) lang)) "-mode")))
(provide 'org-src)
;; arch-tag: 6a1fc84f-dec7-47be-a416-64be56bea5d8

View File

@ -369,8 +369,9 @@ and table.el tables."
(if (y-or-n-p "Convert table to Org-mode table? ")
(org-table-convert)))
((org-at-table-p)
(if (y-or-n-p "Convert table to table.el table? ")
(org-table-convert)))
(when (y-or-n-p "Convert table to table.el table? ")
(org-table-align)
(org-table-convert)))
(t (call-interactively 'table-insert))))
(defun org-table-create-or-convert-from-region (arg)

View File

@ -31,7 +31,7 @@
(require 'org)
(declare-function org-show-notification "org-clock" (parameters))
(declare-function org-notify "org-clock" (notification &optional play-sound))
(declare-function org-agenda-error "org-agenda" ())
(defvar org-timer-start-time nil
@ -145,25 +145,33 @@ With prefix arg STOP, stop it entirely."
(org-timer-set-mode-line 'off))
;;;###autoload
(defun org-timer (&optional restart)
(defun org-timer (&optional restart no-insert-p)
"Insert a H:MM:SS string from the timer into the buffer.
The first time this command is used, the timer is started. When used with
a \\[universal-argument] prefix, force restarting the timer.
When used with a double prefix argument \
\\[universal-argument] \\universal-argument], change all the timer string
When used with a double prefix argument \\[universal-argument], change all the timer string
in the region by a fixed amount. This can be used to recalibrate a timer
that was not started at the correct moment."
that was not started at the correct moment.
If NO-INSERT-P is non-nil, return the string instead of inserting
it in the buffer."
(interactive "P")
(if (equal restart '(4)) (org-timer-start))
(or org-timer-start-time (org-timer-start))
(insert (org-timer-value-string)))
(when (or (equal restart '(4)) (not org-timer-start-time))
(org-timer-start))
(if no-insert-p
(org-timer-value-string)
(insert (org-timer-value-string))))
(defun org-timer-value-string ()
(format org-timer-format (org-timer-secs-to-hms (floor (org-timer-seconds)))))
(defvar org-timer-timer-is-countdown nil)
(defun org-timer-seconds ()
(- (org-float-time (or org-timer-pause-time (current-time)))
(org-float-time org-timer-start-time)))
(if org-timer-timer-is-countdown
(- (org-float-time org-timer-start-time)
(org-float-time (current-time)))
(- (org-float-time (or org-timer-pause-time (current-time)))
(org-float-time org-timer-start-time))))
;;;###autoload
(defun org-timer-change-times-in-region (beg end delta)
@ -195,19 +203,22 @@ that was not started at the correct moment."
(defun org-timer-item (&optional arg)
"Insert a description-type item with the current timer value."
(interactive "P")
(let ((ind 0))
(save-excursion
(skip-chars-backward " \n\t")
(condition-case nil
(progn
(org-beginning-of-item)
(setq ind (org-get-indentation)))
(error nil)))
(or (bolp) (newline))
(org-indent-line-to ind)
(insert "- ")
(org-timer (if arg '(4)))
(insert ":: ")))
(cond
;; In a timer list, insert with `org-list-insert-item-generic'.
((and (org-in-item-p)
(save-excursion (org-beginning-of-item) (org-at-item-timer-p)))
(org-list-insert-item-generic
(point) nil (concat (org-timer (when arg '(4)) t) ":: ")))
;; In a list of another type, don't break anything: throw an error.
((org-in-item-p)
(error "This is not a timer list"))
;; Else, insert the timer correctly indented at bol.
(t
(beginning-of-line)
(org-indent-line-function)
(insert "- ")
(org-timer (when arg '(4)))
(insert ":: "))))
(defun org-timer-fix-incomplete (hms)
"If hms is a H:MM:SS string with missing hour or hour and minute, fix it."
@ -292,7 +303,9 @@ VALUE can be `on', `off', or `pause'."
(when (eval org-timer-current-timer)
(run-hooks 'org-timer-cancel-hook)
(cancel-timer org-timer-current-timer)
(setq org-timer-current-timer nil))
(setq org-timer-current-timer nil)
(setq org-timer-timer-is-countdown nil)
(org-timer-set-mode-line 'off))
(message "Last timer canceled"))
(defun org-timer-show-remaining-time ()
@ -309,10 +322,6 @@ VALUE can be `on', `off', or `pause'."
(message "%d minute(s) %d seconds left before next time out"
rmins rsecs))))
(defun bzg-test (&optional test)
(interactive "P")
test)
;;;###autoload
(defun org-timer-set-timer (&optional opt)
"Prompt for a duration and set a timer.
@ -353,9 +362,11 @@ replace any running timer."
(widen)
(goto-char pos)
(org-show-entry)
(org-get-heading))))
(or (ignore-errors (org-get-heading))
(concat "File:" (file-name-nondirectory (buffer-file-name)))))))
((eq major-mode 'org-mode)
(org-get-heading))
(or (ignore-errors (org-get-heading))
(concat "File:" (file-name-nondirectory (buffer-file-name)))))
(t (error "Not in an Org buffer"))))
timer-set)
(if (or (and org-timer-current-timer
@ -363,6 +374,7 @@ replace any running timer."
(y-or-n-p "Replace current timer? ")))
(not org-timer-current-timer))
(progn
(require 'org-clock)
(when org-timer-current-timer
(cancel-timer org-timer-current-timer))
(setq org-timer-current-timer
@ -370,8 +382,14 @@ replace any running timer."
secs nil `(lambda ()
(setq org-timer-current-timer nil)
(org-notify ,(format "%s: time out" hl) t)
(setq org-timer-timer-is-countdown nil)
(org-timer-set-mode-line 'off)
(run-hooks 'org-timer-done-hook))))
(run-hooks 'org-timer-set-hook))
(run-hooks 'org-timer-set-hook)
(setq org-timer-timer-is-countdown t
org-timer-start-time
(time-add (current-time) (seconds-to-time (* mins 60))))
(org-timer-set-mode-line 'on))
(message "No timer set"))))))
(provide 'org-timer)

View File

@ -142,13 +142,14 @@ ENTITY is a message entity."
(defun org-wl-store-link ()
"Store a link to a WL message or folder."
(cond
((memq major-mode '(wl-summary-mode mime-view-mode))
(org-wl-store-link-message))
((eq major-mode 'wl-folder-mode)
(org-wl-store-link-folder))
(t
nil)))
(unless (eobp)
(cond
((memq major-mode '(wl-summary-mode mime-view-mode))
(org-wl-store-link-message))
((eq major-mode 'wl-folder-mode)
(org-wl-store-link-folder))
(t
nil))))
(defun org-wl-store-link-folder ()
"Store a link to a WL folder."

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +0,0 @@
This directory contains files that are necessary or at least useful
companions for Org-mode under XEmacs:
noutline.el
Greg Chernov's port of the overlay-based implementation of
outline-mode. This is required, and until XEmacs uses this (or
another port), you need to install it with Org-mode. The "Installation"
section in the Manual covers also the installation of this package.
ps-print-invisible.el
Greg Chernovs modification to ps-print, to honor invisible text
properties during printing. This file is not required for running
Org-mode, but it is useful when trying to print partial trees.

File diff suppressed because it is too large Load Diff

View File

@ -1,225 +0,0 @@
;;; ps-print-invisible.el - addon to ps-print package that deals
;; with invisible text printing in xemacs
;; Author: Greg Chernov
;;
;; 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 2, 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:
;;
;; Put ps-print-invisible.el on your load path.
;; (require 'ps-print-invisible)
;; ps-print-buffer-with-faces will not print invisible parts of the buffer.
;; Work with invisible extents/text properties only
;; (xemacs hideshow and noutline packages).
(defun ps-generate-postscript-with-faces (from to)
;; Some initialization...
(setq ps-current-effect 0)
;; Build the reference lists of faces if necessary.
(when (or ps-always-build-face-reference
ps-build-face-reference)
(message "Collecting face information...")
(ps-build-reference-face-lists))
;; Black/white printer.
(setq ps-black-white-faces-alist nil)
(and (eq ps-print-color-p 'black-white)
(ps-extend-face-list ps-black-white-faces nil
'ps-black-white-faces-alist))
;; Generate some PostScript.
(save-restriction
(narrow-to-region from to)
(ps-print-ensure-fontified from to)
(let ((face 'default)
(position to))
(cond
((memq ps-print-emacs-type '(xemacs lucid))
;; Build the list of extents...
;;(debug)
(let ((a (cons 'dummy nil))
record type extent extent-list
(list-invisible (ps-print-find-invisible-xmas from to)))
(ps-x-map-extents 'ps-mapper nil from to a)
(setq a (sort (cdr a) 'car-less-than-car)
extent-list nil)
;; Loop through the extents...
(while a
(setq record (car a)
position (car record)
record (cdr record)
type (car record)
record (cdr record)
extent (car record))
;; Plot up to this record.
;; XEmacs 19.12: for some reason, we're getting into a
;; situation in which some of the records have
;; positions less than 'from'. Since we've narrowed
;; the buffer, this'll generate errors. This is a hack,
;; but don't call ps-plot-with-face unless from > point-min.
(and (>= from (point-min))
(ps-plot-with-face from (min position (point-max)) face))
(cond
((eq type 'push)
(and (or (ps-x-extent-face extent)
(extent-property extent 'invisible))
(setq extent-list (sort (cons extent extent-list)
'ps-extent-sorter))))
((eq type 'pull)
(setq extent-list (sort (delq extent extent-list)
'ps-extent-sorter))))
(setq face (if extent-list
(let ((prop (extent-property (car extent-list) 'invisible)))
(if (or (and (eq buffer-invisibility-spec t)
(not (null prop)))
(and (consp buffer-invisibility-spec)
(or (memq prop buffer-invisibility-spec)
(assq prop buffer-invisibility-spec))))
'emacs--invisible--face
(ps-x-extent-face (car extent-list))))
'default)
from position
a (cdr a)))))
((eq ps-print-emacs-type 'emacs)
(let ((property-change from)
(overlay-change from)
(save-buffer-invisibility-spec buffer-invisibility-spec)
(buffer-invisibility-spec nil)
before-string after-string)
(while (< from to)
(and (< property-change to) ; Don't search for property change
; unless previous search succeeded.
(setq property-change (next-property-change from nil to)))
(and (< overlay-change to) ; Don't search for overlay change
; unless previous search succeeded.
(setq overlay-change (min (ps-e-next-overlay-change from)
to)))
(setq position (min property-change overlay-change)
before-string nil
after-string nil)
;; The code below is not quite correct,
;; because a non-nil overlay invisible property
;; which is inactive according to the current value
;; of buffer-invisibility-spec nonetheless overrides
;; a face text property.
(setq face
(cond ((let ((prop (get-text-property from 'invisible)))
;; Decide whether this invisible property
;; really makes the text invisible.
(if (eq save-buffer-invisibility-spec t)
(not (null prop))
(or (memq prop save-buffer-invisibility-spec)
(assq prop save-buffer-invisibility-spec))))
'emacs--invisible--face)
((get-text-property from 'face))
(t 'default)))
(let ((overlays (ps-e-overlays-at from))
(face-priority -1)) ; text-property
(while (and overlays
(not (eq face 'emacs--invisible--face)))
(let* ((overlay (car overlays))
(overlay-invisible
(ps-e-overlay-get overlay 'invisible))
(overlay-priority
(or (ps-e-overlay-get overlay 'priority) 0)))
(and (> overlay-priority face-priority)
(setq before-string
(or (ps-e-overlay-get overlay 'before-string)
before-string)
after-string
(or (and (<= (ps-e-overlay-end overlay) position)
(ps-e-overlay-get overlay 'after-string))
after-string)
face-priority overlay-priority
face
(cond
((if (eq save-buffer-invisibility-spec t)
(not (null overlay-invisible))
(or (memq overlay-invisible
save-buffer-invisibility-spec)
(assq overlay-invisible
save-buffer-invisibility-spec)))
'emacs--invisible--face)
((ps-e-overlay-get overlay 'face))
(t face)
))))
(setq overlays (cdr overlays))))
;; Plot up to this record.
(and before-string
(ps-plot-string before-string))
(ps-plot-with-face from position face)
(and after-string
(ps-plot-string after-string))
(setq from position)))))
(ps-plot-with-face from to face))))
(defun ps-print-find-invisible-xmas (from to)
(let ((list nil))
(map-extents '(lambda (ex ignored)
(let ((prop (extent-property ex 'invisible)))
(if (or (and (eq buffer-invisibility-spec t)
(not (null prop)))
(or (memq prop buffer-invisibility-spec)
(assq prop buffer-invisibility-spec)))
(setq list (cons (list
(extent-start-position ex)
(extent-end-position ex))
list))))
nil)
(current-buffer)
from to nil 'start-and-end-in-region 'invisible)
(reverse list)))
(defun ps-mapper (extent list)
;;(debug)
(let ((beg (ps-x-extent-start-position extent))
(end (ps-x-extent-end-position extent))
(inv-lst list-invisible)
(found nil))
(while (and inv-lst
(not found))
(let ((inv-beg (caar inv-lst))
(inv-end (cadar inv-lst)))
(if (and (>= beg inv-beg)
(<= end inv-end)
(not (extent-property extent 'invisible)))
(setq found t))
(setq inv-lst (cdr inv-lst))))
(if (not found)
(nconc list
(list (list beg 'push extent)
(list end 'pull extent)))))
nil)
(provide 'ps-print-invisible)
;;; ps-print-invisible.el ends here