emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: "András Simonyi" <andras.simonyi@gmail.com>
To: emacs-orgmode list <emacs-orgmode@gnu.org>
Subject: [PATCH] oc-csl: Add support for sub-bibliographies
Date: Tue, 12 Jul 2022 00:13:01 +0200	[thread overview]
Message-ID: <CAOWRwxBj6ERpuQ_oYNvpVAHwBe7FzjeiFKsvaEFEdmTy-14XcQ@mail.gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 448 bytes --]

Dear All,

the attached patch adds support for filter-based sub-bibliographies in the "csl"
org-cite export processor. It supports the same syntax for specifying
filters as the biblatex processor and supports some of the biblatex
filter types, concretely, entry-type and keyword based filtering. It
also supports filtering based on CSL type (as opposed to bib(la)tex
type) and using any Lisp predicate as a filter.

best wishes,
András

[-- Attachment #2: 0001-oc-csl.el-Add-support-for-sub-bibliographies.patch --]
[-- Type: text/x-patch, Size: 7968 bytes --]

From 50db7f8ae94cf9a3799eccdf3d7ee69a2e7c4505 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A1s=20Simonyi?= <andras.simonyi@gmail.com>
Date: Mon, 11 Jul 2022 19:13:48 +0200
Subject: [PATCH] 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.
---
 etc/ORG-NEWS   | 13 +++++++-
 lisp/oc-csl.el | 83 +++++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 88 insertions(+), 8 deletions(-)

diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 4cda357f1..ce8675dea 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -239,7 +239,7 @@ This behaviour can be changed by supplying a =:align= parameter.
 
 The tabbing environment can be useful when generating simple tables which
 can be span multiple pages and when table cells are allowed to overflow.
-*** Support for =nocite= citations in the "csl" export processor
+*** Support for =nocite= citations and sub-bibliographies in the "csl" export processor
 
 The "csl" citation export processor now supports =nocite= style
 citations that add items to the printed bibliography without visible
@@ -251,6 +251,17 @@ instance,
 #+end_src
 
 includes all available items in the printed bibliography.
+
+The "csl" export processor now also supports sub-bibliographies that
+show only a subset of the references based on some criterion.  For
+example,
+
+#+begin_src org
+#+print_bibliography: :type book :keyword ai
+#+end_src
+
+prints a sub-bibliography containing the book entries with =ai= among
+their keywords.
 ** New functions and changes in function arguments
 
 *** New function ~org-element-cache-map~ for quick mapping across Org elements
diff --git a/lisp/oc-csl.el b/lisp/oc-csl.el
index a2bd6653c..0b2fe5c41 100644
--- a/lisp/oc-csl.el
+++ b/lisp/oc-csl.el
@@ -90,11 +90,23 @@
 ;; The part of the suffix before the locator is appended to reference's prefix.
 ;; If no locator term is used, but a number is present, then "page" is assumed.
 
+;; Filtered sub-bibliographies can be printed by passing filtering
+;; options to the "print_bibliography" keywords.  E.g.,
+;;
+;;    #+print_bibliography: :type book keyword: emacs
+;;
+;; If you need to use a key multiple times, you can separate its
+;; values with commas, but without any space in-between:
+;;
+;;    #+print_bibliography: :keyword abc,xyz :type article
+
 ;; This library was heavily inspired by and borrows from András Simonyi's
 ;; Citeproc Org (<https://github.com/andras-simonyi/citeproc-org>) library.
 ;; Many thanks to him!
 
 ;;; Code:
+(require 'cl-lib)
+(require 'map)
 (require 'bibtex)
 (require 'json)
 (require 'oc)
@@ -559,6 +571,10 @@ OUTPUT using Citeproc."
 	  (citeproc-append-citations structures processor))
 	(when nocite-ids
 	  (citeproc-add-uncited nocite-ids processor))
+        ;; All bibliographies have to be rendered in order to have
+        ;; correct citation numbers even if there are several
+        ;; sub-bibliograhies.
+        (org-cite-csl--rendered-bibliographies info)
 	(let (result
 	      (rendered (citeproc-render-citations
 			 processor
@@ -572,6 +588,62 @@ OUTPUT using Citeproc."
 	  (plist-put info :cite-citeproc-rendered-citations result)
 	  result))))
 
+(defun org-cite-csl--bibliography-filter (bib-props)
+  "Return the sub-bibliography filter corresponding to bibliography properties.
+
+BIB-PROPS should be a plist representing the properties
+associated with a \"print_bibliography\" keyword, as returned by
+`org-cite-bibliography-properties'."
+  (let (result
+	(remove-keyword-colon (lambda (x) (intern (substring (symbol-name x) 1)))))
+    (map-do
+     (lambda (key value)
+       (pcase key
+         ((or :keyword :notkeyword :nottype :notcsltype :filter)
+          (dolist (v (split-string value ","))
+	    (push (cons  (funcall remove-keyword-colon key) v) result)))
+         ((or :type :csltype)
+          (if (string-match-p "," value)
+              (user-error "The \"%s\" print_bibliography option does not support comma-separated values" key)
+            (push (cons (funcall remove-keyword-colon key) value) result)))))
+     bib-props)
+    result))
+
+(defun org-cite-csl--rendered-bibliographies (info)
+  "Return the rendered bibliographies.
+
+INFO is the export state, as a property list.
+
+Return an (OUTPUTS PARAMETERS) list where OUTPUTS is an alist
+of (BIB-PROPS . OUTPUT) pairs where each key is a property list
+of a \"print_bibliography\" keyword and the corresponding OUTPUT
+value is the bibliography as rendered by Citeproc."
+  (or (plist-get info :cite-citeproc-rendered-bibliographies)
+      (let (bib-plists bib-filters)
+        ;; Collect bibliography property lists and the corresponding
+        ;; Citeproc sub-bib filters.
+	(org-element-map (plist-get info :parse-tree) 'keyword
+          (lambda (keyword)
+            (when (equal "PRINT_BIBLIOGRAPHY" (org-element-property :key keyword))
+              (let ((bib-plist (org-cite-bibliography-properties keyword)))
+                (push bib-plist bib-plists)
+                (push (org-cite-csl--bibliography-filter bib-plist) bib-filters)))))
+        (setq bib-filters (nreverse bib-filters)
+              bib-plists (nreverse bib-plists))
+        ;; Render and return all bibliographies.
+        (let ((processor (org-cite-csl--processor info)))
+          (citeproc-add-subbib-filters bib-filters processor)
+          (pcase-let* ((format (org-cite-csl--output-format info))
+                       (`(,rendered-bibs . ,parameters)
+                        (citeproc-render-bib
+                         (org-cite-csl--processor info)
+                         format
+                         (org-cite-csl--no-citelinks-p info)))
+                       (outputs (cl-mapcar #'cons bib-plists rendered-bibs))
+                       (result (list outputs parameters)))
+            (plist-put info :cite-citeproc-rendered-bibliographies result)
+            result)))))
+
 \f
 ;;; Export capability
 (defun org-cite-csl-render-citation (citation _style _backend info)
@@ -585,16 +657,13 @@ INFO is the export state, as a property list."
       ;; process.
       (org-cite-parse-objects output))))
 
-(defun org-cite-csl-render-bibliography (_keys _files _style _props _backend info)
+(defun org-cite-csl-render-bibliography (_keys _files _style props _backend info)
   "Export bibliography.
 INFO is the export state, as a property list."
   (org-cite-csl--barf-without-citeproc)
-  (pcase-let* ((format (org-cite-csl--output-format info))
-               (`(,output . ,parameters)
-                (citeproc-render-bib
-                 (org-cite-csl--processor info)
-                 format
-                 (org-cite-csl--no-citelinks-p info))))
+  (pcase-let*  ((format (org-cite-csl--output-format info))
+		(`(,outputs ,parameters) (org-cite-csl--rendered-bibliographies info))
+		(output (cdr (assoc props outputs))))
     (pcase format
       ('html
        (concat
-- 
2.25.1


             reply	other threads:[~2022-07-11 22:13 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-11 22:13 András Simonyi [this message]
2022-07-16  8:44 ` Ihor Radchenko
2022-07-20 22:03   ` András Simonyi
2022-07-21  6:06     ` András Simonyi
2022-07-23  4:00       ` Ihor Radchenko
2022-07-23 20:10         ` András Simonyi
2022-07-24  7:42           ` Ihor Radchenko
2022-07-25 18:18             ` András Simonyi
2022-07-25 18:44               ` Bruce D'Arcus
2022-07-26  6:23                 ` Fraga, Eric
2022-07-26  5:38               ` Ihor Radchenko
2022-07-28 21:36                 ` András Simonyi
2022-07-29  1:33                   ` Ihor Radchenko
2022-07-29 19:51                     ` András Simonyi
2022-07-31  2:33                       ` Ihor Radchenko
2022-08-02 10:53                         ` András Simonyi
2022-07-31  2:28 ` Ihor Radchenko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAOWRwxBj6ERpuQ_oYNvpVAHwBe7FzjeiFKsvaEFEdmTy-14XcQ@mail.gmail.com \
    --to=andras.simonyi@gmail.com \
    --cc=emacs-orgmode@gnu.org \
    --subject='Re: [PATCH] oc-csl: Add support for sub-bibliographies' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Code repositories for project(s) associated with this inbox:

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).