library-of-babel: adding vc-log by Luke Crook
[org-mode.git] / contrib / babel / library-of-babel.org
blobfea5b3f154aa0909c0c1726c01251f3038f119d0
1 #+title:    The Library of Babel
2 #+author:     Org-mode People
3 #+STARTUP:  odd hideblocks
5 * Introduction
6   The Library of Babel is an extensible collection of ready-made and
7   easily-shortcut-callable source-code blocks for handling common
8   tasks.  Org-babel comes pre-populated with the source-code blocks
9   located in this file. It is possible to add source-code blocks from
10   any org-mode file to the library by calling =(org-babel-lob-ingest
11   "path/to/file.org")=.
12   
13   This file is included in worg mainly less for viewing through the
14   web interface, and more for contribution through the worg git
15   repository.  If you have code snippets that you think others may
16   find useful please add them to this file and [[file:~/src/worg/worg-git.org::contribute-to-worg][contribute them]] to
17   worg.
18   
19   The raw Org-mode text of this file can be downloaded at
20   [[repofile:contrib/babel/library-of-babel.org][library-of-babel.org]]
22 * Simple
23 A collection of simple utility functions
25 #+srcname: echo
26 #+begin_src emacs-lisp :var input="echo'd"
27   input
28 #+end_src
30 * File I/O
31 ** reading and writing files
32 Read the contents of the file at =file=.  The =:results vector= and
33 =:results scalar= header arguments can be used to read the contents of
34 file as either a table or a string.
35 #+srcname: read
36 #+begin_src emacs-lisp :var file="" :var format=""
37   (if (string= format "csv")
38       (with-temp-buffer
39         (org-table-import (expand-file-name file) nil)
40         (org-table-to-lisp))
41     (with-temp-buffer
42       (insert-file-contents (expand-file-name file))
43       (buffer-string)))
44 #+end_src
46 Write =data= to a file at =file=.  If =data= is a list, then write it
47 as a table in traditional Org-mode table syntax.
48 #+srcname: write
49 #+begin_src emacs-lisp :var data="" :var file="" :var ext='()
50   (flet ((echo (r) (if (stringp r) r (format "%S" r))))
51     (with-temp-file file
52       (case (and (listp data)
53                  (or ext (intern (file-name-extension file))))
54         ('tsv (insert (orgtbl-to-tsv data '(:fmt echo))))
55         ('csv (insert (orgtbl-to-csv data '(:fmt echo))))
56         (t    (org-babel-insert-result data)))))
57   nil
58 #+end_src
60 ** remote files
61 **** json
62 Read local or remote file in [[http://www.json.org/][json]] format into emacs-lisp objects.
63 #+srcname: json
64 #+begin_src emacs-lisp :var file='() :var url='()
65   (require 'json)
66   (cond
67    (file
68     (with-temp-filebuffer file
69       (goto-char (point-min))
70       (json-read)))
71    (url
72     (require 'w3m)
73     (with-temp-buffer
74       (w3m-retrieve url)
75       (goto-char (point-min))
76       (json-read))))
77 #+end_src
79 **** Google docs
80 The following code blocks make use of the [[http://code.google.com/p/googlecl/][googlecl]] Google command line
81 tool.  This tool provides functionality for accessing Google services
82 from the command line, and the following code blocks use /googlecl/
83 for reading from and writing to Google docs with Org-mode code blocks.
85 ****** read a document from Google docs
86 The =google= command seems to be throwing "Moved Temporarily" errors
87 when trying to download textual documents, but this is working fine
88 for spreadsheets.
89 #+source: gdoc-read
90 #+begin_src emacs-lisp :var title="example" :var format="csv"
91   (let* ((file (concat title "." format))
92          (cmd (format "google docs get --format %S --title %S" format title)))
93     (message cmd) (message (shell-command-to-string cmd))
94     (prog1 (if (string= format "csv")
95                (with-temp-buffer
96                  (org-table-import (shell-quote-argument file) '(4))
97                  (org-table-to-lisp))
98              (with-temp-buffer
99                (insert-file-contents (shell-quote-argument file))
100                (buffer-string)))
101       (delete-file file)))
102 #+end_src
104 For example, a line like the following can be used to read the
105 contents of a spreadsheet named =num-cells= into a table.
106 : #+call: gdoc-read(title="num-cells"")
108 A line like the following can be used to read the contents of a
109 document as a string.
110 : #+call: gdoc-read(title="loremi", :format "txt")
112 ****** write a document to a Google docs
113 Write =data= to a google document named =title=.  If =data= is tabular
114 it will be saved to a spreadsheet, otherwise it will be saved as a
115 normal document.
116 #+source: gdoc-write
117 #+begin_src emacs-lisp :var title="babel-upload" :var data=fibs(n=10) :results silent
118   (let* ((format (if (listp data) "csv" "txt"))
119          (tmp-file (make-temp-file "org-babel-google-doc" nil (concat "." format)))
120          (cmd (format "google docs upload --title %S %S" title tmp-file)))
121     (with-temp-file tmp-file
122       (insert
123        (if (listp data)
124            (orgtbl-to-csv
125             data '(:fmt (lambda (el) (if (stringp el) el (format "%S" el)))))
126          (if (stringp data) data (format "%S" data)))))
127     (message cmd)
128     (prog1 (shell-command-to-string cmd) (delete-file tmp-file)))
129 #+end_src
131 example usage
132 : #+source: fibs
133 : #+begin_src emacs-lisp :var n=8
134 :   (flet ((fib (m) (if (< m 2) 1 (+ (fib (- m 1)) (fib (- m 2))))))
135 :     (mapcar (lambda (el) (list el (fib el))) (number-sequence 0 (- n 1))))
136 : #+end_src
138 : #+call: gdoc-write(title="fibs", data=fibs(n=10))
140 * Plotting code
142 ** R
143   Plot column 2 (y axis) against column 1 (x axis). Columns 3 and beyond, if present, are ignored.
145 #+srcname: R-plot(data=R-plot-example-data)
146 #+begin_src R
147 plot(data)
148 #+end_src
150 #+tblname: R-plot-example-data
151 | 1 |  2 |
152 | 2 |  4 |
153 | 3 |  9 |
154 | 4 | 16 |
155 | 5 | 25 |
157 #+lob: R-plot(data=R-plot-example-data)
159 #+resname: R-plot(data=R-plot-example-data)
160 : nil
162 ** Gnuplot
164 * Org reference
165 ** headline references
166 #+source: headline
167 #+begin_src emacs-lisp :var headline=top :var file='()
168   (save-excursion
169     (when file (get-file-buffer file))
170     (org-open-link-from-string (org-make-link-string headline))
171     (save-restriction
172       (org-narrow-to-subtree)
173       (buffer-string)))
174 #+end_src
176 #+call: headline(headline="headline references")
178 * Tables
179 ** LaTeX Table export
180 *** booktabs
181 This block can be used to wrap a table in the latex =booktabs=
182 environment, it takes the following arguments -- all but the first two
183 are optional.
184 | arg   | description                                |
185 |-------+--------------------------------------------|
186 | table | a reference to the table                   |
187 | align | optional alignment string                  |
188 | env   | optional environment, default to "tabular" |
189 | width | optional width specification string        |
191 #+srcname: booktabs
192 #+begin_src emacs-lisp :var table='((:head) hline (:body)) :var align='() :var env="tabular" :var width='() :noweb yes :results latex
193   (flet ((to-tab (tab)
194                  (orgtbl-to-generic
195                   (mapcar (lambda (lis)
196                             (if (listp lis)
197                                 (mapcar (lambda (el)
198                                           (if (stringp el)
199                                               el
200                                             (format "%S" el))) lis)
201                               lis)) tab)
202                   (list :lend " \\\\" :sep " & " :hline "\\hline"))))
203     (org-fill-template
204      "
205   \\begin{%env}%width%align
206   \\toprule
207   %table
208   \\bottomrule
209   \\end{%env}\n"
210      (list
211       (cons "env"       (or env "table"))
212       (cons "width"     (if width (format "{%s}" width) ""))
213       (cons "align"     (if align (format "{%s}" align) ""))
214       (cons "table"
215             ;; only use \midrule if it looks like there are column headers
216             (if (equal 'hline (second table))
217                 (concat (to-tab (list (first table)))
218                         "\n\\midrule\n"
219                         (to-tab (cddr table)))
220               (to-tab table))))))
221 #+end_src
223 *** longtable
224 This block can be used to wrap a table in the latex =longtable=
225 environment, it takes the following arguments -- all but the first two
226 are optional.
227 | arg       | description                                                 |
228 |-----------+-------------------------------------------------------------|
229 | table     | a reference to the table                                    |
230 | align     | optional alignment string                                   |
231 | width     | optional width specification string                         |
232 | hline     | the string to use as hline separator, defaults to "\\hline" |
233 | head      | optional "head" string                                      |
234 | firsthead | optional "firsthead" string                                 |
235 | foot      | optional "foot" string                                      |
236 | lastfoot  | optional "lastfoot" string                                  |
238 #+srcname: longtable
239 #+begin_src emacs-lisp :var table='((:table)) :var align='() :var width='() :var hline="\\hline" :var firsthead='() :var head='() :var foot='() :var lastfoot='() :noweb yes :results latex
240   (org-fill-template
241    "
242   \\begin{longtable}%width%align
243   %firsthead
244   %head
245   %foot
246   %lastfoot
247   
248   %table
249   \\end{longtable}\n"
250    (list
251     (cons "width"     (if width (format "{%s}" width) ""))
252     (cons "align"     (if align (format "{%s}" align) ""))
253     (cons "firsthead" (if firsthead (concat firsthead "\n\\endfirsthead\n") ""))
254     (cons "head"      (if head (concat head "\n\\endhead\n") ""))
255     (cons "foot"      (if foot (concat foot "\n\\endfoot\n") ""))
256     (cons "lastfoot"  (if lastfoot (concat lastfoot "\n\\endlastfoot\n") ""))
257     (cons "table" (orgtbl-to-generic
258                    (mapcar (lambda (lis)
259                              (if (listp lis)
260                                  (mapcar (lambda (el)
261                                            (if (stringp el)
262                                                el
263                                              (format "%S" el))) lis)
264                                lis)) table)
265                    (list :lend " \\\\" :sep " & " :hline hline)))))
266 #+end_src
268 ** Elegant lisp for transposing a matrix.
270 #+tblname: transpose-example
271 | 1 | 2 | 3 |
272 | 4 | 5 | 6 |
274 #+srcname: transpose
275 #+begin_src emacs-lisp :var table=transpose-example
276   (apply #'mapcar* #'list table)
277 #+end_src
279 #+resname:
280 | 1 | 4 |
281 | 2 | 5 |
282 | 3 | 6 |
284 * Misc
286 ** File-specific Version Control logging
287    :PROPERTIES:
288    :AUTHOR: Luke Crook
289    :END:
291 This function will attempt to retrieve the entire commit log for the
292 file associated with the current buffer and insert this log into the
293 export. The function uses the Emacs VC commands to interface to the
294 local version control system, but has only been tested to work with
295 Git. 'limit' is currently unsupported.
297 #+source: vc-log
298 #+headers: :var limit=-1
299 #+headers: :var buf=(buffer-name (current-buffer))
300 #+begin_src emacs-lisp
301   ;; Most of this code is copied from vc.el vc-print-log
302   (require 'vc)
303   (when (vc-find-backend-function
304          (vc-backend (buffer-file-name (get-buffer buf))) 'print-log)
305     (let ((limit -1)
306           (vc-fileset nil)
307           (backend nil)
308           (files nil))
309       (with-current-buffer (get-buffer buf)
310         (setq vc-fileset (vc-deduce-fileset t)) ; FIXME: Why t? --Stef
311         (setq backend (car vc-fileset))
312         (setq files (cadr vc-fileset)))
313       (with-temp-buffer 
314         (let ((status (vc-call-backend
315                        backend 'print-log files (current-buffer))))
316           (when (and (processp status)   ; Make sure status is a process
317                      (= 0 (process-exit-status status))) ; which has not terminated
318             (while (not (eq 'exit (process-status status)))
319               (sit-for 1 t)))
320           (buffer-string)))))
321 #+end_src
323 ** Trivial python code blocks
324 #+srcname: python-identity(a=1)
325 #+begin_src python
327 #+end_src
329 #+srcname: python-add(a=1, b=2)
330 #+begin_src python
331 a + b
332 #+end_src
334 * GANTT Charts
336 The =elispgantt= source block was sent to the mailing list by Eric
337 Fraga.  It was modified slightly by Tom Dye.
339 #+source: elispgantt
340 #+begin_src emacs-lisp :var table=gantttest
341   (let ((dates "")
342         (entries (nthcdr 2 table))
343         (milestones "")
344         (nmilestones 0)
345         (ntasks 0)
346         (projecttime 0)
347         (tasks "")
348         (xlength 1))
349     (message "Initial: %s\n" table)
350     (message "Entries: %s\n" entries)
351     (while entries
352       (let ((entry (first entries)))
353         (if (listp entry)
354             (let ((id (first entry))
355                   (type (nth 1 entry))
356                   (label (nth 2 entry))
357                   (task (nth 3 entry))
358                   (dependencies (nth 4 entry))
359                   (start (nth 5 entry))
360                   (duration (nth 6 entry))
361                   (end (nth 7 entry))
362                   (alignment (nth 8 entry)))
363               (if (> start projecttime) (setq projecttime start))
364               (if (string= type "task")
365                   (let ((end (+ start duration))
366                         (textposition (+ start (/ duration 2)))
367                         (flush ""))
368                     (if (string= alignment "left")
369                         (progn
370                           (setq textposition start)
371                           (setq flush "[left]"))
372                       (if (string= alignment "right")
373                           (progn
374                             (setq textposition end)
375                             (setq flush "[right]"))))
376                     (setq tasks
377                           (format "%s  \\gantttask{%s}{%s}{%d}{%d}{%d}{%s}\n"
378                                   tasks label task start end textposition flush))
379                     (setq ntasks (+ 1 ntasks))
380                     (if (> end projecttime)
381                         (setq projecttime end)))
382                 (if (string= type "milestone")
383                     (progn
384                       (setq milestones
385                             (format
386                              "%s  \\ganttmilestone{$\\begin{array}{c}\\mbox{%s}\\\\ \\mbox{%s}\\end{array}$}{%d}\n"
387                              milestones label task start))
388                       (setq nmilestones (+ 1 nmilestones)))
389                   (if (string= type "date")
390                       (setq dates (format "%s  \\ganttdateline{%s}{%d}\n"
391                                           dates label start))
392                     (message "Ignoring entry with type %s\n" type)))))
393           (message "Ignoring non-list entry %s\n" entry)) ; end if list entry
394         (setq entries (cdr entries))))  ; end while entries left
395     (format "\\pgfdeclarelayer{background}
396   \\pgfdeclarelayer{foreground}
397   \\pgfsetlayers{background,foreground}
398   \\renewcommand{\\ganttprojecttime}{%d}
399   \\renewcommand{\\ganttntasks}{%d}
400   \\noindent
401   \\begin{tikzpicture}[y=-0.75cm,x=0.75\\textwidth]
402     \\begin{pgfonlayer}{background}
403       \\draw[very thin, red!10!white] (0,1+\\ganttntasks) grid [ystep=0.75cm,xstep=1/\\ganttprojecttime] (1,0);
404       \\draw[\\ganttdatelinecolour] (0,0) -- (1,0);
405       \\draw[\\ganttdatelinecolour] (0,1+\\ganttntasks) -- (1,1+\\ganttntasks);
406     \\end{pgfonlayer}
407   %s
408   %s
409   %s
410   \\end{tikzpicture}" projecttime ntasks tasks milestones dates))
411 #+end_src