From 4c7ed746f6d423dddf29628f16be141db2e4dd95 Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Mon, 20 Dec 2010 22:49:25 +0100 Subject: [PATCH 07/10] Add org-format-spec function * org.el (org-format-spec): New function. Signed-off-by: Julien Danjou --- lisp/org.el | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 62 insertions(+), 0 deletions(-) diff --git a/lisp/org.el b/lisp/org.el index c024916..56f0468 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -18867,6 +18867,7 @@ work correctly." ;;; Other stuff. + (defun org-insert-and-inherit-partially (&rest args) "Insert the arguments at point, partially inheriting properties from adjoining text. The properties are inherited only if they are not set on the argument." @@ -18883,6 +18884,67 @@ The properties are inherited only if they are not set on the argument." do (put-text-property place (1+ place) prop value)))))) +(defun org-format-spec (format specification) + "Return a string based on FORMAT and SPECIFICATION. +FORMAT is a string containing `format'-like specs like \"bash %u %k\", +while SPECIFICATION is an alist mapping from format spec characters +to values. Any text properties on a %-spec itself are propagated to +the text that it generates." + ;; Create a marker for current position, so we can use it to eval + ;; later. + (let ((marker (set-marker (make-marker) (point)))) + (with-temp-buffer + (insert format) + (goto-char (point-min)) + (while (search-forward "%" nil t) + (cond + ;; Quoted percent sign. + ((eq (char-after) ?%) + (delete-char 1)) + ;; %() style spec + ((looking-at "(.+)") + (let ((text + (org-with-point-at marker + (save-match-data + (org-eval (read (match-string 0))))))) + (org-insert-and-inherit-partially text) + ;; Delete the (foo) + (delete-region (+ (match-beginning 0) (length text)) + (+ (match-end 0) (length text))) + ;; Delete the percent sign. + (delete-region (1- (match-beginning 0)) (match-beginning 0)))) + ;; Valid format spec. + ((looking-at "\\(\\?\\)?\\([-+]?[0-9.]*\\)\\([ .;,:!?=|/<>]?\\)\\([a-zA-z]\\)") + (let* ((optional (match-string 1)) + (num (match-string 2)) + (punctuation (match-string 3)) + (spec (string-to-char (match-string 4))) + (val + (org-with-point-at marker + (save-match-data + (org-eval (cdr (assq spec specification))))))) + (if (or (not optional) + val) + (progn + (when (string= num "+") + (setq num (format "%d" (max 0 (- fill-column (current-column)))))) + ;; Pad result to desired length. + (let ((text (format (concat "%" num "s") + (concat val (if (and punctuation val (not (string= val ""))) + punctuation ""))))) + ;; Insert first, to preserve text properties. + (org-insert-and-inherit-partially text) + ;; Delete the specifier body. + (delete-region (+ (match-beginning 0) (length text)) + (+ (match-end 0) (length text))) + ;; Delete the percent sign. + (delete-region (1- (match-beginning 0)) (match-beginning 0)))) + (delete-region (1- (match-beginning 0)) (match-end 0))))) + ;; Signal an error on bogus format strings. + (t + (error "Invalid format string")))) + (buffer-string)))) + (defun org-toggle-fixed-width-section (arg) "Toggle the fixed-width export. If there is no active region, the QUOTE keyword at the current headline is -- 1.7.2.3