org-macro: Refactoring

* lisp/org-macro.el (org-macro-initialize-templates): Refactor function.
* testing/lisp/test-org-macro.el (test-org/macro-replace-all): Remove
  duplicate tests.  Add new test.
This commit is contained in:
Nicolas Goaziou 2018-03-23 23:40:56 +01:00
parent 28977b719c
commit d33e6eae51
2 changed files with 59 additions and 90 deletions

View File

@ -133,66 +133,57 @@ Templates are stored in buffer-local variable
function installs the following ones: \"property\",
\"time\". and, if the buffer is associated to a file,
\"input-file\" and \"modification-time\"."
(let* ((templates nil)
(update-templates
(lambda (cell)
(let ((old-template (assoc (car cell) templates)))
(if old-template (setcdr old-template (cdr cell))
(push cell templates))))))
;; Install "author, "date, "email", "keyword", "title" and
;; "results" macros.
(mapc update-templates
(list
(cons "author" (org-macro--find-keyword-value "AUTHOR"))
(cons "date"
(let* ((value (org-macro--find-keyword-value "DATE"))
(date (org-element-parse-secondary-string
value (org-element-restriction 'keyword))))
(if (and (consp date)
(not (cdr date))
(eq (org-element-type (car date)) 'timestamp))
(format "(eval (if (org-string-nw-p $1) %s %S))"
(format "(org-timestamp-format '%S $1)"
(org-element-copy (car date)))
value)
value)))
(cons "email" (org-macro--find-keyword-value "EMAIL"))
(cons "keyword" "(eval (org-macro--find-keyword-value $1))")
(cons "results" "$1")
(cons "title" (org-macro--find-keyword-value "TITLE"))))
;; Install "property", "time" macros.
(mapc update-templates
(list (cons "property"
"(eval (save-excursion
(let ((l $2))
(when (org-string-nw-p l)
(condition-case _
(let ((org-link-search-must-match-exact-headline t))
(org-link-search l nil t))
(error
(error \"Macro property failed: cannot find location %s\"
l)))))
(org-entry-get nil $1 'selective)))")
(cons "time" "(eval (format-time-string $1))")))
;; Install "input-file", "modification-time" macros.
(let ((visited-file (buffer-file-name (buffer-base-buffer))))
(when (and visited-file (file-exists-p visited-file))
(mapc update-templates
(list (cons "input-file" (file-name-nondirectory visited-file))
(cons "modification-time"
(format "(eval
(org-macro--counter-initialize) ;for "n" macro
(setq org-macro-templates
(nconc
;; Install user-defined macros.
(org-macro--collect-macros)
;; Install file-specific macros.
(let ((visited-file (buffer-file-name (buffer-base-buffer))))
(and visited-file
(file-exists-p visited-file)
(list
`("input-file" . ,(file-name-nondirectory visited-file))
`("modification-time" .
,(format "(eval
\(format-time-string $1
(or (and (org-string-nw-p $2)
(org-macro--vc-modified-time %s))
'%s)))"
(prin1-to-string visited-file)
(prin1-to-string
(nth 5 (file-attributes visited-file)))))))))
;; Initialize and install "n" macro.
(org-macro--counter-initialize)
(funcall update-templates
(cons "n" "(eval (org-macro--counter-increment $1 $2))"))
(setq org-macro-templates (nconc (org-macro--collect-macros) templates))))
(prin1-to-string visited-file)
(prin1-to-string
(nth 5 (file-attributes visited-file))))))))
;; Install built-in macros.
(list
'("n" . "(eval (org-macro--counter-increment $1 $2))")
`("author" . ,(org-macro--find-keyword-value "AUTHOR"))
`("email" . ,(org-macro--find-keyword-value "EMAIL"))
'("keyword" . "(eval (org-macro--find-keyword-value $1))")
'("results" . "$1")
'("time" . "(eval (format-time-string $1))")
`("title" . ,(org-macro--find-keyword-value "TITLE"))
'("property" . "(eval
(save-excursion
(let ((l $2))
(when (org-string-nw-p l)
(condition-case _
(let ((org-link-search-must-match-exact-headline t))
(org-link-search l nil t))
(error
(error \"Macro property failed: cannot find location %s\" l)))))
(org-entry-get nil $1 'selective)))")
`("date" .
,(let* ((value (org-macro--find-keyword-value "DATE"))
(date (org-element-parse-secondary-string
value (org-element-restriction 'keyword))))
(if (and (consp date)
(not (cdr date))
(eq 'timestamp (org-element-type (car date))))
(format "(eval (if (org-string-nw-p $1) %s %S))"
(format "(org-timestamp-format '%S $1)"
(org-element-copy (car date)))
value)
value)))))))
(defun org-macro-expand (macro templates)
"Return expanded MACRO, as a string.

View File

@ -77,39 +77,6 @@
(org-macro-initialize-templates)
(org-macro-replace-all org-macro-templates)
(buffer-string))))
;; Test special "property" macro. With only one argument, retrieve
;; property from current headline. Otherwise, the second argument
;; is a search option to get the property from another headline.
(should
(equal "1"
(org-test-with-temp-text
"* H\n:PROPERTIES:\n:A: 1\n:END:\n{{{property(A)}}}<point>"
(org-macro-initialize-templates)
(org-macro-replace-all org-macro-templates)
(buffer-substring-no-properties
(line-beginning-position) (line-end-position)))))
(should
(equal "1"
(org-test-with-temp-text
"* H\n:PROPERTIES:\n:A: 1\n:END:\n{{{property(A,)}}}<point>"
(org-macro-initialize-templates)
(org-macro-replace-all org-macro-templates)
(buffer-substring-no-properties
(line-beginning-position) (line-end-position)))))
(should
(equal
"1"
(org-test-with-temp-text
"* H1\n:PROPERTIES:\n:A: 1\n:END:\n* H2\n{{{property(A,*H1)}}}<point>"
(org-macro-initialize-templates)
(org-macro-replace-all org-macro-templates)
(buffer-substring-no-properties
(line-beginning-position) (line-end-position)))))
(should-error
(org-test-with-temp-text
"* H1\n:PROPERTIES:\n:A: 1\n:END:\n* H2\n{{{property(A,*???)}}}<point>"
(org-macro-initialize-templates)
(org-macro-replace-all org-macro-templates)))
;; Macro expansion ignores narrowing.
(should
(string-match
@ -136,7 +103,18 @@
"#+MACRO: macro expansion\n* COMMENT H1\n** H2\n<point>{{{macro}}}"
(org-macro-initialize-templates)
(org-macro-replace-all org-macro-templates)
(org-with-wide-buffer (buffer-string))))))
(org-with-wide-buffer (buffer-string)))))
;; User-defined macros take precedence over built-in macros.
(should
(equal
"foo"
(org-test-with-temp-text
"#+MACRO: title foo\n#+TITLE: bar\n<point>{{{title}}}"
(org-macro-initialize-templates)
(org-macro-replace-all org-macro-templates)
(goto-char (point-max))
(buffer-substring-no-properties (line-beginning-position)
(line-end-position))))))
(ert-deftest test-org-macro/property ()
"Test {{{property}}} macro."