Skip to content

Commit 7e07611

Browse files
andras-simonyiyantar92
authored andcommitted
oc-csl.el: Add support for sub-bibliographies
* lisp/oc-csl.el (org-cite-csl--rendered-bibliographies): New function to collect all #+print_bibliography keywords with their properties and call Citeproc to render all sub-bibliographies in one go as required by the API. Return the formatted bibliographies as values in an alist in which keys are the #+print_bibliography keyword options as plists. Cache the return value in the export communication channel. (org-cite-csl--bibliography-filter): New helper function to convert plists representing #+print_bibliography options to the alist filter form expected by Citeproc. (org-cite-csl--rendered-citations): Call `org-cite-csl--rendered-bibliographies' before rendering citations to make sure that the complete sub-bibliography information is added to the processor and, therefore, citation numbers are correct. (org-cite-csl--render-bibliography): Instead of directly calling Citeproc to render the bibliography, call `org-cite-csl--rendered-bibliographies' and retrieve the formatted bibliography from its return value based on the options passed as the `props' argument.
1 parent 785f003 commit 7e07611

File tree

2 files changed

+88
-8
lines changed

2 files changed

+88
-8
lines changed

etc/ORG-NEWS

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ This behaviour can be changed by supplying a =:align= parameter.
239239

240240
The tabbing environment can be useful when generating simple tables which
241241
can be span multiple pages and when table cells are allowed to overflow.
242-
*** Support for =nocite= citations in the "csl" export processor
242+
*** Support for =nocite= citations and sub-bibliographies in the "csl" export processor
243243

244244
The "csl" citation export processor now supports =nocite= style
245245
citations that add items to the printed bibliography without visible
@@ -251,6 +251,17 @@ instance,
251251
#+end_src
252252

253253
includes all available items in the printed bibliography.
254+
255+
The "csl" export processor now also supports sub-bibliographies that
256+
show only a subset of the references based on some criterion. For
257+
example,
258+
259+
#+begin_src org
260+
#+print_bibliography: :type book :keyword ai
261+
#+end_src
262+
263+
prints a sub-bibliography containing the book entries with =ai= among
264+
their keywords.
254265
** New functions and changes in function arguments
255266
*** ~org-fold-show-entry~ does not fold drawers by default anymore
256267

lisp/oc-csl.el

Lines changed: 76 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,23 @@
9090
;; The part of the suffix before the locator is appended to reference's prefix.
9191
;; If no locator term is used, but a number is present, then "page" is assumed.
9292

93+
;; Filtered sub-bibliographies can be printed by passing filtering
94+
;; options to the "print_bibliography" keywords. E.g.,
95+
;;
96+
;; #+print_bibliography: :type book keyword: emacs
97+
;;
98+
;; If you need to use a key multiple times, you can separate its
99+
;; values with commas, but without any space in-between:
100+
;;
101+
;; #+print_bibliography: :keyword abc,xyz :type article
102+
93103
;; This library was heavily inspired by and borrows from András Simonyi's
94104
;; Citeproc Org (<https://github.com/andras-simonyi/citeproc-org>) library.
95105
;; Many thanks to him!
96106

97107
;;; Code:
108+
(require 'cl-lib)
109+
(require 'map)
98110
(require 'bibtex)
99111
(require 'json)
100112
(require 'oc)
@@ -559,6 +571,10 @@ OUTPUT using Citeproc."
559571
(citeproc-append-citations structures processor))
560572
(when nocite-ids
561573
(citeproc-add-uncited nocite-ids processor))
574+
;; All bibliographies have to be rendered in order to have
575+
;; correct citation numbers even if there are several
576+
;; sub-bibliograhies.
577+
(org-cite-csl--rendered-bibliographies info)
562578
(let (result
563579
(rendered (citeproc-render-citations
564580
processor
@@ -572,6 +588,62 @@ OUTPUT using Citeproc."
572588
(plist-put info :cite-citeproc-rendered-citations result)
573589
result))))
574590

591+
(defun org-cite-csl--bibliography-filter (bib-props)
592+
"Return the sub-bibliography filter corresponding to bibliography properties.
593+
594+
BIB-PROPS should be a plist representing the properties
595+
associated with a \"print_bibliography\" keyword, as returned by
596+
`org-cite-bibliography-properties'."
597+
(let (result
598+
(remove-keyword-colon (lambda (x) (intern (substring (symbol-name x) 1)))))
599+
(map-do
600+
(lambda (key value)
601+
(pcase key
602+
((or :keyword :notkeyword :nottype :notcsltype :filter)
603+
(dolist (v (split-string value ","))
604+
(push (cons (funcall remove-keyword-colon key) v) result)))
605+
((or :type :csltype)
606+
(if (string-match-p "," value)
607+
(user-error "The \"%s\" print_bibliography option does not support comma-separated values" key)
608+
(push (cons (funcall remove-keyword-colon key) value) result)))))
609+
bib-props)
610+
result))
611+
612+
(defun org-cite-csl--rendered-bibliographies (info)
613+
"Return the rendered bibliographies.
614+
615+
INFO is the export state, as a property list.
616+
617+
Return an (OUTPUTS PARAMETERS) list where OUTPUTS is an alist
618+
of (BIB-PROPS . OUTPUT) pairs where each key is a property list
619+
of a \"print_bibliography\" keyword and the corresponding OUTPUT
620+
value is the bibliography as rendered by Citeproc."
621+
(or (plist-get info :cite-citeproc-rendered-bibliographies)
622+
(let (bib-plists bib-filters)
623+
;; Collect bibliography property lists and the corresponding
624+
;; Citeproc sub-bib filters.
625+
(org-element-map (plist-get info :parse-tree) 'keyword
626+
(lambda (keyword)
627+
(when (equal "PRINT_BIBLIOGRAPHY" (org-element-property :key keyword))
628+
(let ((bib-plist (org-cite-bibliography-properties keyword)))
629+
(push bib-plist bib-plists)
630+
(push (org-cite-csl--bibliography-filter bib-plist) bib-filters)))))
631+
(setq bib-filters (nreverse bib-filters)
632+
bib-plists (nreverse bib-plists))
633+
;; Render and return all bibliographies.
634+
(let ((processor (org-cite-csl--processor info)))
635+
(citeproc-add-subbib-filters bib-filters processor)
636+
(pcase-let* ((format (org-cite-csl--output-format info))
637+
(`(,rendered-bibs . ,parameters)
638+
(citeproc-render-bib
639+
(org-cite-csl--processor info)
640+
format
641+
(org-cite-csl--no-citelinks-p info)))
642+
(outputs (cl-mapcar #'cons bib-plists rendered-bibs))
643+
(result (list outputs parameters)))
644+
(plist-put info :cite-citeproc-rendered-bibliographies result)
645+
result)))))
646+
575647

576648
;;; Export capability
577649
(defun org-cite-csl-render-citation (citation _style _backend info)
@@ -585,16 +657,13 @@ INFO is the export state, as a property list."
585657
;; process.
586658
(org-cite-parse-objects output))))
587659

588-
(defun org-cite-csl-render-bibliography (_keys _files _style _props _backend info)
660+
(defun org-cite-csl-render-bibliography (_keys _files _style props _backend info)
589661
"Export bibliography.
590662
INFO is the export state, as a property list."
591663
(org-cite-csl--barf-without-citeproc)
592-
(pcase-let* ((format (org-cite-csl--output-format info))
593-
(`(,output . ,parameters)
594-
(citeproc-render-bib
595-
(org-cite-csl--processor info)
596-
format
597-
(org-cite-csl--no-citelinks-p info))))
664+
(pcase-let* ((format (org-cite-csl--output-format info))
665+
(`(,outputs ,parameters) (org-cite-csl--rendered-bibliographies info))
666+
(output (cdr (assoc props outputs))))
598667
(pcase format
599668
('html
600669
(concat

0 commit comments

Comments
 (0)