From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp12.migadu.com ([2001:41d0:2:bcc0::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms5.migadu.com with LMTPS id 6BZ1J8YurWKlZwEAbAwnHQ (envelope-from ) for ; Sat, 18 Jun 2022 03:47:50 +0200 Received: from aspmx1.migadu.com ([2001:41d0:2:bcc0::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp12.migadu.com with LMTPS id eAI2J8YurWITpwAAauVa8A (envelope-from ) for ; Sat, 18 Jun 2022 03:47:50 +0200 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 950D73E34F for ; Sat, 18 Jun 2022 03:47:47 +0200 (CEST) Received: from localhost ([::1]:59770 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1o2NYw-0001ys-AS for larch@yhetil.org; Fri, 17 Jun 2022 21:47:46 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49302) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1o2NYA-0001xA-DF for emacs-orgmode@gnu.org; Fri, 17 Jun 2022 21:46:58 -0400 Received: from mail-b.sr.ht ([173.195.146.151]:48986) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1o2NY7-0008Uo-45; Fri, 17 Jun 2022 21:46:58 -0400 Received: from git.sr.ht (unknown [173.195.146.142]) by mail-b.sr.ht (Postfix) with ESMTPSA id 4550F11F1C4; Sat, 18 Jun 2022 01:46:51 +0000 (UTC) From: ~theophilusx Date: Sat, 18 Jun 2022 11:13:34 +1000 Subject: [PATCH worg 2/2] Update and cleanup of LoB file Message-ID: <165551681074.2379.2372976577322130384-2@git.sr.ht> X-Mailer: git.sr.ht In-Reply-To: <165551681074.2379.2372976577322130384-0@git.sr.ht> To: emacs-orgmode@gnu.org Cc: bzg@gnu.org Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Received-SPF: pass client-ip=173.195.146.151; envelope-from=outgoing@sr.ht; helo=mail-b.sr.ht X-Spam_score_int: 2 X-Spam_score: 0.2 X-Spam_bar: / X-Spam_report: (0.2 / 5.0 requ) BAYES_00=-1.9, FREEMAIL_FORGED_REPLYTO=2.095, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-orgmode@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: ~theophilusx Errors-To: emacs-orgmode-bounces+larch=yhetil.org@gnu.org Sender: "Emacs-orgmode" X-Migadu-Flow: FLOW_IN X-Migadu-To: larch@yhetil.org X-Migadu-Country: US ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1655516870; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:list-id:list-help:list-unsubscribe: list-subscribe:list-post; bh=pRJMam0rP23PB/x5WjLIJ26kWzvVQb7qLdtUVDotrXg=; b=FUlmOoZjhlGZ0dNFiQoOyqmPW4SLbSF8zT7DYzZaS1G883w8a2eULj75amTM9amaXU06CX 2KSHcUaD24p65XQEOs2gHyp+IebWYfu65zXtJ1/UJ0Fg5MVxp78qyyVDocdFVsCfAgRynr WiZ+nNHrVDLXs51QQH2ltS4e2DPutgWEzKwGRir8f16y9B7WSt1Fle2Ih9NYAAwOYkpI9/ Hj8lKM4V+DmQFDUZUPc9wE4h/5Zm8a1azU+jyjx0IKa7u88LswheHYzAqQHHXFOkSLOsHR kePNLu38R8rk1+ivvlx8JS0wnCGyWMFpGr1RiIDBVRjnhbOByn1C/ilrvcyV7g== ARC-Seal: i=1; s=key1; d=yhetil.org; t=1655516870; a=rsa-sha256; cv=none; b=cL2xc4sjH2wVy87Brc4xqZnri1F77nOUjQIAeCCt/ZeiRcv2EVNGbyZJHbA0pZu1wjGe3i qaFfEp2gF45mqr+NaB2EtAaYUJBdGFTtR4KV6KZvukoVWKx0IL1782Xz69u1KJvpzxijQE zja5nuVC5ajUoenYGxOGz/2n3QrRLdW3hO+6gbTT9UFVRPSBbl2tPfVO4kzFdvwzfRpg6a WIsCwV+gySyy546imsRFzVhQSvPkXOg/Xv0QvCgfkfQfeMVls3PEvdqzvSR5IQNYAXAMEI eZLAQR8RMv9OqrLRoPzNKzR+9jP7eyHS1mStrrbqkiGm/Er1CjQ27nFxJ68WEQ== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=none; dmarc=fail reason="SPF not aligned (relaxed), No valid DKIM" header.from=sr.ht (policy=none); spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org" X-Migadu-Spam-Score: 1.12 Authentication-Results: aspmx1.migadu.com; dkim=none; dmarc=fail reason="SPF not aligned (relaxed), No valid DKIM" header.from=sr.ht (policy=none); spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org" X-Migadu-Queue-Id: 950D73E34F X-Spam-Score: 1.12 X-Migadu-Scanner: scn0.migadu.com X-TUID: iPTNM2950FyY From: Tim Cross - Add exmaple elispgantt test table and description - Fix some old tblname and headers arguments - Fix some missing quoting in exmaple blocks - fix block indentation - add missing name values Still a bit of cleanup work required, but a start... --- library-of-babel.org | 554 +++++++++++++++++++++++-------------------- 1 file changed, 294 insertions(+), 260 deletions(-) diff --git a/library-of-babel.org b/library-of-babel.org index e61c3d35..aa1772dd 100644 --- a/library-of-babel.org +++ b/library-of-babel.org @@ -29,7 +29,7 @@ A collection of simple utility functions: =20 #+name: echo #+begin_src emacs-lisp :var input=3D"echo'd" - input +input #+end_src =20 * File I/O @@ -42,13 +42,13 @@ file as either a table or a string. =20 #+name: read #+begin_src emacs-lisp :var file=3D"" :var format=3D"" - (if (string=3D format "csv") - (with-temp-buffer - (org-table-import (expand-file-name file) nil) - (org-table-to-lisp)) +(if (string=3D format "csv") (with-temp-buffer - (insert-file-contents (expand-file-name file)) - (buffer-string))) + (org-table-import (expand-file-name file) nil) + (org-table-to-lisp)) + (with-temp-buffer + (insert-file-contents (expand-file-name file)) + (buffer-string))) #+end_src =20 Write =3Ddata=3D to a file at =3Dfile=3D. If =3Ddata=3D is a list, then wri= te it @@ -56,14 +56,14 @@ as a table in traditional Org-mode table syntax. =20 #+name: write #+begin_src emacs-lisp :var data=3D"" :var file=3D"" :var ext=3D'() - (flet ((echo (r) (if (stringp r) r (format "%S" r)))) - (with-temp-file file - (case (and (listp data) - (or ext (intern (file-name-extension file)))) - ('tsv (insert (orgtbl-to-tsv data '(:fmt echo)))) - ('csv (insert (orgtbl-to-csv data '(:fmt echo)))) - (t (org-babel-insert-result data))))) - nil +(flet ((echo (r) (if (stringp r) r (format "%S" r)))) + (with-temp-file file + (case (and (listp data) + (or ext (intern (file-name-extension file)))) + ('tsv (insert (orgtbl-to-tsv data '(:fmt echo)))) + ('csv (insert (orgtbl-to-csv data '(:fmt echo)))) + (t (org-babel-insert-result data))))) +nil #+end_src =20 ** Remote files @@ -74,18 +74,18 @@ Read local or remote file in [[http://www.json.org/][json= ]] format into emacs-li =20 #+name: json #+begin_src emacs-lisp :var file=3D'() :var url=3D'() - (require 'json) - (cond - (file - (org-babel-with-temp-filebuffer file - (goto-char (point-min)) - (json-read))) - (url - (require 'w3m) - (with-temp-buffer - (w3m-retrieve url) - (goto-char (point-min)) - (json-read)))) +(require 'json) +(cond + (file + (org-babel-with-temp-filebuffer file + (goto-char (point-min)) + (json-read))) + (url + (require 'w3m) + (with-temp-buffer + (w3m-retrieve url) + (goto-char (point-min)) + (json-read)))) #+end_src =20 *** Google docs @@ -103,17 +103,17 @@ for spreadsheets. =20 #+name: gdoc-read #+begin_src emacs-lisp :var title=3D"example" :var format=3D"csv" - (let* ((file (concat title "." format)) - (cmd (format "google docs get --format %S --title %S" format title)= )) - (message cmd) (message (shell-command-to-string cmd)) - (prog1 (if (string=3D format "csv") - (with-temp-buffer - (org-table-import (shell-quote-argument file) '(4)) - (org-table-to-lisp)) +(let* ((file (concat title "." format)) + (cmd (format "google docs get --format %S --title %S" format title))) + (message cmd) (message (shell-command-to-string cmd)) + (prog1 (if (string=3D format "csv") (with-temp-buffer - (insert-file-contents (shell-quote-argument file)) - (buffer-string))) - (delete-file file))) + (org-table-import (shell-quote-argument file) '(4)) + (org-table-to-lisp)) + (with-temp-buffer + (insert-file-contents (shell-quote-argument file)) + (buffer-string))) + (delete-file file))) #+end_src =20 For example, a line like the following can be used to read the @@ -139,27 +139,30 @@ normal document. =20 #+name: gdoc-write #+begin_src emacs-lisp :var title=3D"babel-upload" :var data=3Dfibs(n=3D10) = :results silent - (let* ((format (if (listp data) "csv" "txt")) - (tmp-file (make-temp-file "org-babel-google-doc" nil (concat "." fo= rmat))) - (cmd (format "google docs upload --title %S %S" title tmp-file))) - (with-temp-file tmp-file - (insert - (if (listp data) - (orgtbl-to-csv - data '(:fmt (lambda (el) (if (stringp el) el (format "%S" el))))) - (if (stringp data) data (format "%S" data))))) - (message cmd) - (prog1 (shell-command-to-string cmd) (delete-file tmp-file))) +(let* ((format (if (listp data) "csv" "txt")) + (tmp-file (make-temp-file "org-babel-google-doc" nil (concat "." form= at))) + (cmd (format "google docs upload --title %S %S" title tmp-file))) + (with-temp-file tmp-file + (insert + (if (listp data) + (orgtbl-to-csv + data '(:fmt (lambda (el) (if (stringp el) el (format "%S" el))))) + (if (stringp data) data (format "%S" data))))) + (message cmd) + (prog1 (shell-command-to-string cmd) (delete-file tmp-file))) #+end_src =20 example usage -: #+name: fibs -: #+begin_src emacs-lisp :var n=3D8 -: (flet ((fib (m) (if (< m 2) 1 (+ (fib (- m 1)) (fib (- m 2)))))) -: (mapcar (lambda (el) (list el (fib el))) (number-sequence 0 (- n 1)))) -: #+end_src -: -: #+call: gdoc-write(title=3D"fibs", data=3Dfibs(n=3D10)) + +#+begin_example +,#+name: fibs +,#+begin_src emacs-lisp :var n=3D8 +(flet ((fib (m) (if (< m 2) 1 (+ (fib (- m 1)) (fib (- m 2)))))) + (mapcar (lambda (el) (list el (fib el))) (number-sequence 0 (- n 1)))) +,#+end_src + +,#+call: gdoc-write(title=3D"fibs", data=3Dfibs(n=3D10)) +#+end_example =20 * Plotting code =20 @@ -192,12 +195,12 @@ plot(data) =20 #+name: headline #+begin_src emacs-lisp :var headline=3D"" :var file=3D'() - (save-excursion - (when file (get-file-buffer file)) - (org-open-link-from-string (org-make-link-string headline)) - (save-restriction - (org-narrow-to-subtree) - (buffer-string))) +(save-excursion + (when file (get-file-buffer file)) + (org-open-link-from-string (org-make-link-string headline)) + (save-restriction + (org-narrow-to-subtree) + (buffer-string))) #+end_src =20 #+call: headline(headline=3D"Headline references") @@ -229,34 +232,34 @@ optional. =20 #+name: booktabs #+begin_src emacs-lisp :var table=3D'((:head) hline (:body)) :var align=3D'(= ) :var env=3D"tabular" :var width=3D'() :noweb yes :results latex - (flet ((to-tab (tab) - (orgtbl-to-generic - (mapcar (lambda (lis) - (if (listp lis) - (mapcar (lambda (el) - (if (stringp el) - el - (format "%S" el))) lis) - lis)) tab) - (list :lend " \\\\" :sep " & " :hline "\\hline")))) - (org-fill-template - " - \\begin{%env}%width%align - \\toprule - %table - \\bottomrule - \\end{%env}\n" - (list - (cons "env" (or env "table")) - (cons "width" (if width (format "{%s}" width) "")) - (cons "align" (if align (format "{%s}" align) "")) - (cons "table" - ;; only use \midrule if it looks like there are column headers - (if (equal 'hline (second table)) - (concat (to-tab (list (first table))) - "\n\\midrule\n" - (to-tab (cddr table))) - (to-tab table)))))) +(flet ((to-tab (tab) + (orgtbl-to-generic + (mapcar (lambda (lis) + (if (listp lis) + (mapcar (lambda (el) + (if (stringp el) + el + (format "%S" el))) lis) + lis)) tab) + (list :lend " \\\\" :sep " & " :hline "\\hline")))) + (org-fill-template + " +\\begin{%env}%width%align +\\toprule +%table +\\bottomrule +\\end{%env}\n" + (list + (cons "env" (or env "table")) + (cons "width" (if width (format "{%s}" width) "")) + (cons "align" (if align (format "{%s}" align) "")) + (cons "table" + ;; only use \midrule if it looks like there are column headers + (if (equal 'hline (second table)) + (concat (to-tab (list (first table))) + "\n\\midrule\n" + (to-tab (cddr table))) + (to-tab table)))))) #+end_src =20 *** longtable @@ -278,32 +281,32 @@ are optional. =20 #+name: longtable #+begin_src emacs-lisp :var table=3D'((:table)) :var align=3D'() :var width= =3D'() :var hline=3D"\\hline" :var firsthead=3D'() :var head=3D'() :var foot= =3D'() :var lastfoot=3D'() :noweb yes :results latex - (org-fill-template - " - \\begin{longtable}%width%align - %firsthead - %head - %foot - %lastfoot - - %table - \\end{longtable}\n" - (list - (cons "width" (if width (format "{%s}" width) "")) - (cons "align" (if align (format "{%s}" align) "")) - (cons "firsthead" (if firsthead (concat firsthead "\n\\endfirsthead\n") = "")) - (cons "head" (if head (concat head "\n\\endhead\n") "")) - (cons "foot" (if foot (concat foot "\n\\endfoot\n") "")) - (cons "lastfoot" (if lastfoot (concat lastfoot "\n\\endlastfoot\n") "")) - (cons "table" (orgtbl-to-generic - (mapcar (lambda (lis) - (if (listp lis) - (mapcar (lambda (el) - (if (stringp el) - el - (format "%S" el))) lis) - lis)) table) - (list :lend " \\\\" :sep " & " :hline hline))))) +(org-fill-template + " +\\begin{longtable}%width%align +%firsthead +%head +%foot +%lastfoot + +%table +\\end{longtable}\n" + (list + (cons "width" (if width (format "{%s}" width) "")) + (cons "align" (if align (format "{%s}" align) "")) + (cons "firsthead" (if firsthead (concat firsthead "\n\\endfirsthead\n") ""= )) + (cons "head" (if head (concat head "\n\\endhead\n") "")) + (cons "foot" (if foot (concat foot "\n\\endfoot\n") "")) + (cons "lastfoot" (if lastfoot (concat lastfoot "\n\\endlastfoot\n") "")) + (cons "table" (orgtbl-to-generic + (mapcar (lambda (lis) + (if (listp lis) + (mapcar (lambda (el) + (if (stringp el) + el + (format "%S" el))) lis) + lis)) table) + (list :lend " \\\\" :sep " & " :hline hline))))) #+end_src =20 *** booktabs-notes @@ -311,7 +314,7 @@ are optional. This source block builds on [[booktabs]]. It accepts two additional arguments, both of which are optional. =20 -#+tblname: arguments +#+name: arguments | arg | description | |--------+------------------------------------------------------| | notes | an org-mode table with footnotes | @@ -320,91 +323,91 @@ arguments, both of which are optional. An example footnote to the =3Darguments=3D table specifies the column span. Note the use of LaTeX, rather than Org-mode, markup. =20 -#+tblname: arguments-notes +#+name: arguments-notes | \multicolumn{2}{l}{This is a footnote to the \emph{arguments} table.} | =20 #+name: booktabs-notes #+begin_src emacs-lisp :var table=3D'((:head) hline (:body)) :var notes=3D'(= ) :var align=3D'() :var env=3D"tabular" :var width=3D'() :var lspace=3D'() :n= oweb yes :results latex - (flet ((to-tab (tab) - (orgtbl-to-generic - (mapcar (lambda (lis) - (if (listp lis) - (mapcar (lambda (el) - (if (stringp el) - el - (format "%S" el))) lis) - lis)) tab) - (list :lend " \\\\" :sep " & " :hline "\\hline")))) - (org-fill-template - " - \\begin{%env}%width%align - \\toprule - %table - \\bottomrule%spacer - %notes - \\end{%env}\n" - (list - (cons "env" (or env "table")) - (cons "width" (if width (format "{%s}" width) "")) - (cons "align" (if align (format "{%s}" align) "")) - (cons "spacer" (if lspace "\\addlinespace" "")) - (cons "table" - ;; only use \midrule if it looks like there are column headers - (if (equal 'hline (second table)) - (concat (to-tab (list (first table))) - "\n\\midrule\n" - (to-tab (cddr table))) - (to-tab table))) - (cons "notes" (if notes (to-tab notes) "")) - ))) +(flet ((to-tab (tab) + (orgtbl-to-generic + (mapcar (lambda (lis) + (if (listp lis) + (mapcar (lambda (el) + (if (stringp el) + el + (format "%S" el))) lis) + lis)) tab) + (list :lend " \\\\" :sep " & " :hline "\\hline")))) + (org-fill-template + " + \\begin{%env}%width%align + \\toprule + %table + \\bottomrule%spacer + %notes + \\end{%env}\n" + (list + (cons "env" (or env "table")) + (cons "width" (if width (format "{%s}" width) "")) + (cons "align" (if align (format "{%s}" align) "")) + (cons "spacer" (if lspace "\\addlinespace" "")) + (cons "table" + ;; only use \midrule if it looks like there are column headers + (if (equal 'hline (second table)) + (concat (to-tab (list (first table))) + "\n\\midrule\n" + (to-tab (cddr table))) + (to-tab table))) + (cons "notes" (if notes (to-tab notes) "")) + ))) #+end_src =20 ** Elegant lisp for transposing a matrix =20 -#+tblname: transpose-example +#+name: transpose-example | 1 | 2 | 3 | | 4 | 5 | 6 | =20 #+name: transpose #+begin_src emacs-lisp :var table=3Dtranspose-example - (apply #'mapcar* #'list table) +(apply #'mapcar* #'list table) #+end_src =20 -#+resname: +#+name: transpose-output | 1 | 4 | | 2 | 5 | | 3 | 6 | =20 ** Convert every element of a table to a string =20 -#+tblname: hetero-table +#+name: hetero-table | 1 | 2 | 3 | | a | b | c | =20 #+name: all-to-string #+begin_src emacs-lisp :var tbl=3D'() - (defun all-to-string (tbl) - (if (listp tbl) - (mapcar #'all-to-string tbl) - (if (stringp tbl) - tbl - (format "%s" tbl)))) - (all-to-string tbl) +(defun all-to-string (tbl) + (if (listp tbl) + (mapcar #'all-to-string tbl) + (if (stringp tbl) + tbl + (format "%s" tbl)))) +(all-to-string tbl) #+end_src =20 #+begin_src emacs-lisp :var tbl=3Dhetero-table - (mapcar (lambda (row) (mapcar (lambda (cell) (stringp cell)) row)) tbl) +(mapcar (lambda (row) (mapcar (lambda (cell) (stringp cell)) row)) tbl) #+end_src =20 -#+name: +#+name: stringp-output1 | nil | nil | nil | | t | t | t | =20 #+begin_src emacs-lisp :var tbl=3Dall-to-string(hetero-table) - (mapcar (lambda (row) (mapcar (lambda (cell) (stringp cell)) row)) tbl) +(mapcar (lambda (row) (mapcar (lambda (cell) (stringp cell)) row)) tbl) #+end_src =20 -#+name: +#+name: stringp-output2 | t | t | t | | t | t | t | =20 @@ -422,29 +425,29 @@ local version control system, but has only been tested = to work with Git. 'limit' is currently unsupported. =20 #+name: vc-log -#+headers: :var limit=3D-1 -#+headers: :var buf=3D(buffer-name (current-buffer)) +#+header: :var limit=3D-1 +#+header: :var buf=3D(buffer-name (current-buffer)) #+begin_src emacs-lisp - ;; Most of this code is copied from vc.el vc-print-log - (require 'vc) - (when (vc-find-backend-function - (vc-backend (buffer-file-name (get-buffer buf))) 'print-log) - (let ((limit -1) - (vc-fileset nil) - (backend nil) - (files nil)) - (with-current-buffer (get-buffer buf) - (setq vc-fileset (vc-deduce-fileset t)) ; FIXME: Why t? --Stef - (setq backend (car vc-fileset)) - (setq files (cadr vc-fileset))) - (with-temp-buffer - (let ((status (vc-call-backend - backend 'print-log files (current-buffer)))) - (when (and (processp status) ; Make sure status is a process - (=3D 0 (process-exit-status status))) ; which has not t= erminated - (while (not (eq 'exit (process-status status))) - (sit-for 1 t))) - (buffer-string))))) +;; Most of this code is copied from vc.el vc-print-log +(require 'vc) +(when (vc-find-backend-function + (vc-backend (buffer-file-name (get-buffer buf))) 'print-log) + (let ((limit -1) + (vc-fileset nil) + (backend nil) + (files nil)) + (with-current-buffer (get-buffer buf) + (setq vc-fileset (vc-deduce-fileset t)) ; FIXME: Why t? --Stef + (setq backend (car vc-fileset)) + (setq files (cadr vc-fileset))) + (with-temp-buffer + (let ((status (vc-call-backend + backend 'print-log files (current-buffer)))) + (when (and (processp status) ; Make sure status is a process + (=3D 0 (process-exit-status status))) ; which has not ter= minated + (while (not (eq 'exit (process-status status))) + (sit-for 1 t))) + (buffer-string))))) #+end_src =20 ** Trivial python code blocks @@ -463,22 +466,22 @@ a + b =20 #+name: lob-add #+begin_src emacs-lisp :var a=3D0 :var b=3D0 - (+ a b) +(+ a b) #+end_src =20 #+name: lob-minus #+begin_src emacs-lisp :var a=3D0 :var b=3D0 - (- a b) +(- a b) #+end_src =20 #+name: lob-times #+begin_src emacs-lisp :var a=3D0 :var b=3D0 - (* a b) +(* a b) #+end_src =20 #+name: lob-div #+begin_src emacs-lisp :var a=3D0 :var b=3D0 - (/ a b) +(/ a b) #+end_src =20 * GANTT Charts @@ -486,78 +489,109 @@ a + b The =3Delispgantt=3D source block was sent to the mailing list by Eric Fraga. It was modified slightly by Tom Dye. =20 + +** Example table of tasks and milestones for GANTT chart generation + +The following table describes the tasks and other relevant information for a= project. Each line is an /entry/ and there are three types of entry allowed= in this table: + +- task :: an actual task that has a start time, a duration and an end time. +- milestone :: a specific milestone in the project that has a start time alo= ne +- date :: a point in time that will be drawn as a vertical line in the GANTT= chart (e.g. start of each year). + +Each element of the chart will be annotated with the content of the /label/ = column of each entry. The first column of the table is ignored but I use it = to number the entries. The last column, titled /align/, is used to determine= where to place the /activity/ text for tasks, whether to the left or right o= f the bar or, if nothing is specified, centred within the bar itself. + +#+name: gantttesttable +| | type | label | activity | depends | start | duration | end = | align | +|----+-----------+-------+---------------+---------+-------+----------+-----= +-------| +| 1 | date | Start | | | 0 | | 0 = | | +| 2 | task | 1.1 | Lit survey | | 0 | 3 | 3 = | right | +| 3 | task | 1.2 | Develop model | 2 | 3 | 9 | 12 = | right | +| 4 | milestone | M1 | model | 3 | 12 | | 12 = | | +| 5 | task | 1.3 | Implement | 3 | 12 | 6 | 18 = | left | +| 6 | date | Y1 | | | 12 | | 12 = | | +| 7 | milestone | M2 | software | 5 | 18 | | 18 = | | +|----+-----------+-------+---------------+---------+-------+----------+-----= +-------| +| 8 | task | 2.1 | Surrogate | 3 | 15 | 6 | 21 = | left | +| 9 | task | 2.2 | Implement | 7 | 21 | 3 | 24 = | left | +| 10 | milestone | M3 | software | 8 | 24 | | 24 = | | +| 11 | date | End | | | 24 | | 24 = | | +|----+-----------+-------+---------------+---------+-------+----------+-----= +-------| +#+TBLFM: $1=3D1+@-1::$8=3D$6+$7::@5$6=3D@-1$+2::@6$6=3D@-1$+2::@8$6=3D@-2$+2= ::@9$6=3D3+@4$+2::@10$6=3D@-1$+2 + +** elispgantt + #+name: elispgantt -#+begin_src emacs-lisp :var table=3Dgantttest - (let ((dates "") - (entries (nthcdr 2 table)) - (milestones "") - (nmilestones 0) - (ntasks 0) - (projecttime 0) - (tasks "") - (xlength 1)) - (message "Initial: %s\n" table) - (message "Entries: %s\n" entries) - (while entries - (let ((entry (first entries))) - (if (listp entry) - (let ((id (first entry)) - (type (nth 1 entry)) - (label (nth 2 entry)) - (task (nth 3 entry)) - (dependencies (nth 4 entry)) - (start (nth 5 entry)) - (duration (nth 6 entry)) - (end (nth 7 entry)) - (alignment (nth 8 entry))) - (if (> start projecttime) (setq projecttime start)) - (if (string=3D type "task") - (let ((end (+ start duration)) - (textposition (+ start (/ duration 2))) - (flush "")) - (if (string=3D alignment "left") +#+begin_src emacs-lisp :var table=3Dgantttesttable +(let ((dates "") + (entries (nthcdr 2 table)) + (milestones "") + (nmilestones 0) + (ntasks 0) + (projecttime 0) + (tasks "") + (xlength 1)) + (message "Initial: %s\n" table) + (message "Entries: %s\n" entries) + (while entries + (let ((entry (first entries))) + (if (listp entry) + (let ((id (first entry)) + (type (nth 1 entry)) + (label (nth 2 entry)) + (task (nth 3 entry)) + (dependencies (nth 4 entry)) + (start (nth 5 entry)) + (duration (nth 6 entry)) + (end (nth 7 entry)) + (alignment (nth 8 entry))) + (if (> start projecttime) (setq projecttime start)) + (if (string=3D type "task") + (let ((end (+ start duration)) + (textposition (+ start (/ duration 2))) + (flush "")) + (if (string=3D alignment "left") + (progn + (setq textposition start) + (setq flush "[left]")) + (if (string=3D alignment "right") (progn - (setq textposition start) - (setq flush "[left]")) - (if (string=3D alignment "right") - (progn - (setq textposition end) - (setq flush "[right]")))) - (setq tasks - (format "%s \\gantttask{%s}{%s}{%d}{%d}{%d}{%s}\n" - tasks label task start end textposition fl= ush)) - (setq ntasks (+ 1 ntasks)) - (if (> end projecttime) - (setq projecttime end))) - (if (string=3D type "milestone") - (progn - (setq milestones - (format - "%s \\ganttmilestone{$\\begin{array}{c}\\mbox{= %s}\\\\ \\mbox{%s}\\end{array}$}{%d}\n" - milestones label task start)) - (setq nmilestones (+ 1 nmilestones))) - (if (string=3D type "date") - (setq dates (format "%s \\ganttdateline{%s}{%d}\n" - dates label start)) - (message "Ignoring entry with type %s\n" type))))) - (message "Ignoring non-list entry %s\n" entry)) ; end if list entry - (setq entries (cdr entries)))) ; end while entries left - (format "\\pgfdeclarelayer{background} - \\pgfdeclarelayer{foreground} - \\pgfsetlayers{background,foreground} - \\renewcommand{\\ganttprojecttime}{%d} - \\renewcommand{\\ganttntasks}{%d} - \\noindent - \\begin{tikzpicture}[y=3D-0.75cm,x=3D0.75\\textwidth] - \\begin{pgfonlayer}{background} - \\draw[very thin, red!10!white] (0,1+\\ganttntasks) grid [ystep=3D0.75= cm,xstep=3D1/\\ganttprojecttime] (1,0); - \\draw[\\ganttdatelinecolour] (0,0) -- (1,0); - \\draw[\\ganttdatelinecolour] (0,1+\\ganttntasks) -- (1,1+\\ganttntask= s); - \\end{pgfonlayer} - %s - %s - %s - \\end{tikzpicture}" projecttime ntasks tasks milestones dates)) + (setq textposition end) + (setq flush "[right]")))) + (setq tasks + (format "%s \\gantttask{%s}{%s}{%d}{%d}{%d}{%s}\n" + tasks label task start end textposition flus= h)) + (setq ntasks (+ 1 ntasks)) + (if (> end projecttime) + (setq projecttime end))) + (if (string=3D type "milestone") + (progn + (setq milestones + (format + "%s \\ganttmilestone{$\\begin{array}{c}\\mbox{%s= }\\\\ \\mbox{%s}\\end{array}$}{%d}\n" + milestones label task start)) + (setq nmilestones (+ 1 nmilestones))) + (if (string=3D type "date") + (setq dates (format "%s \\ganttdateline{%s}{%d}\n" + dates label start)) + (message "Ignoring entry with type %s\n" type))))) + (message "Ignoring non-list entry %s\n" entry)) ; end if list entry + (setq entries (cdr entries)))) ; end while entries left + (format "\\pgfdeclarelayer{background} +\\pgfdeclarelayer{foreground} +\\pgfsetlayers{background,foreground} +\\renewcommand{\\ganttprojecttime}{%d} +\\renewcommand{\\ganttntasks}{%d} +\\noindent +\\begin{tikzpicture}[y=3D-0.75cm,x=3D0.75\\textwidth] + \\begin{pgfonlayer}{background} + \\draw[very thin, red!10!white] (0,1+\\ganttntasks) grid [ystep=3D0.75cm= ,xstep=3D1/\\ganttprojecttime] (1,0); + \\draw[\\ganttdatelinecolour] (0,0) -- (1,0); + \\draw[\\ganttdatelinecolour] (0,1+\\ganttntasks) -- (1,1+\\ganttntasks); + \\end{pgfonlayer} +%s +%s +%s +\\end{tikzpicture}" projecttime ntasks tasks milestones dates)) #+end_src =20 * Available languages --=20 2.34.2