oc: Factor out string to cite export processor triplet conversion

* lisp/oc.el (org-cite-read-processor-declaration): New function.
(org-cite-store-export-processor): Use new function.
* testing/lisp/test-oc.el (test-org-cite/read-processor-declaration):
New test.
This commit is contained in:
Nicolas Goaziou 2021-11-30 13:24:30 +01:00
parent adadb5b554
commit 5d2e2cd1bc
2 changed files with 76 additions and 26 deletions

View File

@ -792,6 +792,39 @@ INFO is a plist used as a communication channel."
(cons (org-not-nil (car global))
(or (cdr local) (cdr global)))))))
(defun org-cite-read-processor-declaration (s)
"Read processor declaration from string S.
Return (NAME BIBLIOGRAPHY-STYLE CITATION-STYLE) triplet, when
NAME is the processor name, as a symbol, and both
BIBLIOGRAPHY-STYLE and CITATION-STYLE are strings or nil. Those
strings may contain spaces if they are enclosed within double
quotes.
String S is expected to contain between 1 and 3 tokens. The
function raises an error when it contains too few or too many
tokens. Spurious spaces are ignored."
(with-temp-buffer
(save-excursion (insert s))
(let ((result (list (read (current-buffer)))))
(dotimes (_ 2)
(skip-chars-forward " \t")
(cond
((eobp) (push nil result))
((char-equal ?\" (char-after))
(push (org-not-nil (read (current-buffer)))
result))
(t
(let ((origin (point)))
(skip-chars-forward "^ \t")
(push (org-not-nil (buffer-substring origin (point)))
result)))))
(skip-chars-forward " \t")
(unless (eobp)
(error "Trailing garbage following cite export processor declaration %S"
s))
(nreverse result))))
(defun org-cite-bibliography-style (info)
"Return expected bibliography style.
INFO is a plist used as a communication channel."
@ -1194,40 +1227,22 @@ INFO is the communication channel, as a plist. It is modified by side-effect."
Export processor is stored as a triplet, or nil.
When non-nil, it is defined as (NAME BIBLIOGRAPHY-STYLE CITATION-STYLE) where
NAME is a symbol, whereas BIBLIOGRAPHY-STYLE and CITATION-STYLE are strings,
or nil.
When non-nil, it is defined as (NAME BIBLIOGRAPHY-STYLE
CITATION-STYLE) where NAME is a symbol, whereas
BIBLIOGRAPHY-STYLE and CITATION-STYLE are strings, or nil.
INFO is the communication channel, as a plist. It is modified by side-effect."
INFO is the communication channel, as a plist. It is modified by
side-effect."
(let* ((err
(lambda (s)
(user-error "Invalid cite export processor definition: %S" s)))
(user-error "Invalid cite export processor declaration: %S" s)))
(processor
(pcase (plist-get info :cite-export)
((or "" `nil) nil)
;; Value is a string. It comes from a "cite_export"
;; keyword. It may contain between 1 and 3 tokens, the
;; first one being a symbol and the other (optional) two,
;; strings.
;; keyword.
((and (pred stringp) s)
(with-temp-buffer
(save-excursion (insert s))
(let ((result (list (read (current-buffer)))))
(dotimes (_ 2)
(skip-chars-forward " \t")
(cond
((eobp) (push nil result))
((char-equal ?\" (char-after))
(condition-case _
(push (org-not-nil (read (current-buffer))) result)
(error (funcall err s))))
(t
(let ((origin (point)))
(skip-chars-forward "^ \t")
(push (org-not-nil (buffer-substring origin (point)))
result)))))
(unless (eobp) (funcall err s))
(nreverse result))))
(org-cite-read-processor-declaration s))
;; Value is an alist. It must come from
;; `org-cite-export-processors' variable. Find the most
;; appropriate processor according to current export

View File

@ -763,6 +763,41 @@
:export-citation (lambda (_ s _ _) (throw :exit s)))
(org-export-as (org-export-create-backend))))))))
(ert-deftest test-org-cite/read-processor-declaration ()
"Test `org-cite-read-processor-declaration'."
;; Argument should contain 1-3 tokens.
(should-error
(org-cite-read-processor-declaration ""))
(should
(equal '(foo nil nil)
(org-cite-read-processor-declaration "foo")))
(should
(equal '(foo "bar" nil)
(org-cite-read-processor-declaration "foo bar")))
(should
(equal '(foo "bar" "baz")
(org-cite-read-processor-declaration "foo bar baz")))
(should-error
(org-cite-read-processor-declaration "foo bar baz qux"))
;; nil in second and third arguments is read as `nil'.
(should
(equal '(foo nil "baz")
(org-cite-read-processor-declaration "foo nil baz")))
(should
(equal '(foo "bar" nil)
(org-cite-read-processor-declaration "foo bar nil")))
;; Second and third arguments may contain spaces if they are quoted.
(should
(equal '(foo "bar baz" nil)
(org-cite-read-processor-declaration "foo \"bar baz\"")))
(should
(equal '(foo "bar" "baz qux")
(org-cite-read-processor-declaration "foo bar \"baz qux\"")))
;; Spurious spaces are ignored.
(should
(equal '(foo "bar" "baz")
(org-cite-read-processor-declaration " foo bar baz "))))
(ert-deftest test-org-cite/list-citations ()
"Test `org-cite-list-citations'."
(should