| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644 | ;;; oc-csl.el --- csl citation processor for Org -*- lexical-binding: t; -*-;; Copyright (C) 2021-2022 Free Software Foundation, Inc.;; Author: Nicolas Goaziou <mail@nicolasgoaziou.fr>;; This file is part of GNU Emacs.;; GNU Emacs is free software: you can redistribute it and/or modify;; it under the terms of the GNU General Public License as published by;; the Free Software Foundation, either version 3 of the License, or;; (at your option) any later version.;; GNU Emacs is distributed in the hope that it will be useful,;; but WITHOUT ANY WARRANTY; without even the implied warranty of;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the;; GNU General Public License for more details.;; You should have received a copy of the GNU General Public License;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.;;; Commentary:;; This library registers the `csl' citation processor, which provides;; the "export" capability for citations.;; The processor relies on the external Citeproc Emacs library, which must be;; available prior to loading this library.;; By default, citations are rendered in Chicago author-date CSL style.  You can;; use another style file by specifying it in `org-cite-export-processors' or;; from within the document by adding the file name to "cite_export" keyword;;;;    #+cite_export: csl /path/to/style-file.csl;;    #+cite_export: csl "/path/to/style-file.csl";;;; With the variable `org-cite-csl-styles-dir' set appropriately, the;; above can even be shortened to;;;;     #+cite_export: csl style-file.csl;;;; Styles can be downloaded, for instance, from the Zotero Style Repository;; (<https://www.zotero.org/styles>).  Dependent styles (which are not "unique";; in the Zotero Style Repository terminology) are not supported.;; The processor uses the "en-US" CSL locale file shipped with Org for rendering;; localized dates and terms in the references, independently of the language;; settings of the Org document.  Additional CSL locales can be made available;; by setting `org-cite-csl-locales-dir' to a directory containing the locale;; files in question (see <https://github.com/citation-style-language/locales>;; for such files).;; Bibliography is defined with the "bibliography" keyword.  It supports files;; with ".bib", ".bibtex", and ".json" extensions.  References are exported using;; the "print_bibliography" keyword.;; The library supports the following citation styles:;;;; - author (a), including bare (b), caps (c), bare-caps (bc), full (f),;;   caps-full (cf), and bare-caps-full (bcf) variants,;; - noauthor (na), including bare (b), caps (c) and bare-caps (bc) variants,;; - year (y), including a bare (b) variant,;; - text (t). including caps (c), full (f), and caps-full (cf) variants,;; - default style, including bare (b), caps (c) and bare-caps (bc) variants.;; CSL styles recognize "locator" in citation references' suffix.  For example,;; in the citation;;;;     [cite:see @Tarski-1965 chapter 1, for an example];;;; "chapter 1" is the locator.  The whole citation is rendered as;;;;     (see Tarski 1965, chap. 1 for an example);;;; in the default CSL style.;;;; The locator starts with a locator term, among "bk.", "bks.", "book", "chap.",;; "chaps.", "chapter", "col.", "cols.", "column", "figure", "fig.", "figs.",;; "folio", "fol.", "fols.", "number", "no.", "nos.", "line", "l.", "ll.",;; "note", "n.", "nn.", "opus", "op.", "opp.", "page", "p.", "pp.", "paragraph",;; "para.", "paras.", "¶", "¶¶", "§", "§§", "part", "pt.", "pts.", "section",;; "sec.", "secs.", "sub verbo", "s.v.", "s.vv.", "verse", "v.", "vv.",;; "volume", "vol.", and "vols.".  It ends with the last comma or digit in the;; suffix, whichever comes last, or runs till the end of the suffix.;;;; 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.;; 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 'bibtex)(require 'json)(require 'oc)(require 'citeproc nil t)(declare-function citeproc-style-cite-note "ext:citeproc")(declare-function citeproc-proc-style "ext:citeproc")(declare-function citeproc-bt-entry-to-csl "ext:citeproc")(declare-function citeproc-locale-getter-from-dir "ext:citeproc")(declare-function citeproc-create "ext:citeproc")(declare-function citeproc-citation-create "ext:citeproc")(declare-function citeproc-append-citations "ext:citeproc")(declare-function citeproc-render-citations "ext:citeproc")(declare-function citeproc-render-bib "ext:citeproc")(declare-function citeproc-hash-itemgetter-from-any "ext:citeproc")(declare-function org-element-interpret-data "org-element" (data))(declare-function org-element-map "org-element" (data types fun &optional info first-match no-recursion with-affiliated))(declare-function org-element-property "org-element" (property element))(declare-function org-element-put-property "org-element" (element property value))(declare-function org-export-data "org-export" (data info))(declare-function org-export-derived-backend-p "org-export" (backend &rest backends))(declare-function org-export-get-footnote-number "org-export" (footnote info &optional data body-first));;; Customization;;;; Location of CSL directories(defcustom org-cite-csl-locales-dir nil  "Directory of CSL locale files.If nil then only the fallback en-US locale will be available."  :group 'org-cite  :package-version '(Org . "9.5")  :type '(choice          (directory :tag "Locales directory")          (const :tag "Use en-US locale only" nil))  ;; It's not obvious to me that arbitrary locations are safe.;;;  :safe #'string-or-null-p  )(defcustom org-cite-csl-styles-dir nil  "Directory of CSL style files.Relative style file names are expanded according to document'sdefault directory.  If it fails and the variable is non-nil, Orglooks for style files in this directory, too."  :group 'org-cite  :package-version '(Org . "9.5")  :type '(choice          (directory :tag "Styles directory")          (const :tag "No central directory for style files" nil))  ;; It's not obvious to me that arbitrary locations are safe.;;;  :safe #'string-or-null-p  );;;; Citelinks(defcustom org-cite-csl-link-cites t  "When non-nil, link cites to references."  :group 'org-cite  :package-version '(Org . "9.5")  :type 'boolean  :safe #'booleanp)(defcustom org-cite-csl-no-citelinks-backends '(ascii)  "List of export back-ends for which cite linking is disabled.Cite linking for export back-ends derived from any of the back-ends listed here,is also disabled."  :group 'org-cite  :package-version '(Org . "9.5")  :type '(repeat symbol));;;; Output-specific variables(defcustom org-cite-csl-html-hanging-indent "1.5em"  "Size of hanging-indent for HTML output in valid CSS units."  :group 'org-cite  :package-version '(Org . "9.5")  :type 'string  :safe #'stringp)(defcustom org-cite-csl-html-label-width-per-char "0.6em"  "Character width in CSS units for calculating entry label widths.Used only when `second-field-align' is activated by the used CSL style."  :group 'org-cite  :package-version '(Org . "9.5")  :type 'string  :safe #'stringp)(defcustom org-cite-csl-latex-hanging-indent "1.5em"  "Size of hanging-indent for LaTeX output in valid LaTeX units."  :group 'org-cite  :package-version '(Org . "9.5")  :type 'string  :safe #'stringp);;; Internal variables(defconst org-cite-csl--etc-dir  (let ((oc-root (file-name-directory (locate-library "oc"))))    (cond     ;; First check whether it looks like we're running from the main     ;; Org repository.     ((let ((csl-org (expand-file-name "../etc/csl/" oc-root)))        (and (file-directory-p csl-org) csl-org)))     ;; Next look for the directory alongside oc.el because package.el     ;; and straight will put all of org-mode/lisp/ in org-mode/.     ((let ((csl-pkg (expand-file-name "etc/csl/" oc-root)))        (and (file-directory-p csl-pkg) csl-pkg)))     ;; Finally fall back the location used by shared system installs     ;; and when running directly from Emacs repository.     (t      (expand-file-name "org/csl/" data-directory))))  "Directory containing CSL-related data files.")(defconst org-cite-csl--fallback-locales-dir org-cite-csl--etc-dir  "Fallback CSL locale files directory.")(defconst org-cite-csl--fallback-style-file  (expand-file-name "chicago-author-date.csl"                    org-cite-csl--etc-dir)  "Default CSL style file, or nil.If nil then the Chicago author-date style is used as a fallback.")(defconst org-cite-csl--label-alist  '(("bk."       . "book")    ("bks."      . "book")    ("book"      . "book")    ("chap."     . "chapter")    ("chaps."    . "chapter")    ("chapter"   . "chapter")    ("col."      . "column")    ("cols."     . "column")    ("column"    . "column")    ("figure"    . "figure")    ("fig."      . "figure")    ("figs."     . "figure")    ("folio"     . "folio")    ("fol."      . "folio")    ("fols."     . "folio")    ("number"    . "number")    ("no."       . "number")    ("nos."      . "number")    ("line"      . "line")    ("l."        . "line")    ("ll."       . "line")    ("note"      . "note")    ("n."        . "note")    ("nn."       . "note")    ("opus"      . "opus")    ("op."       . "opus")    ("opp."      . "opus")    ("page"      . "page")    ("p"         . "page")    ("p."        . "page")    ("pp."       . "page")    ("paragraph" . "paragraph")    ("para."     . "paragraph")    ("paras."    . "paragraph")    ("¶"         . "paragraph")    ("¶¶"        . "paragraph")    ("part"      . "part")    ("pt."       . "part")    ("pts."      . "part")    ("§"         . "section")    ("§§"        . "section")    ("section"   . "section")    ("sec."      . "section")    ("secs."     . "section")    ("sub verbo" . "sub verbo")    ("s.v."      . "sub verbo")    ("s.vv."     . "sub verbo")    ("verse"     . "verse")    ("v."        . "verse")    ("vv."       . "verse")    ("volume"    . "volume")    ("vol."      . "volume")    ("vols."     . "volume"))  "Alist mapping locator names to locators.")(defconst org-cite-csl--label-regexp  ;; Prior to Emacs-27.1 argument of `regexp' form must be a string literal.  ;; It is the reason why `rx' is avoided here.  (rx-to-string   `(seq (or line-start space)         (regexp ,(regexp-opt (mapcar #'car org-cite-csl--label-alist) t))         (0+ digit)         (or word-end line-end space " "))   t)  "Regexp matching a label in a citation reference suffix.Label is in match group 1.");;; Internal functions(defun org-cite-csl--barf-without-citeproc ()  "Raise an error if Citeproc library is not loaded."  (unless (featurep 'citeproc)    (error "Citeproc library is not loaded")))(defun org-cite-csl--note-style-p (info)  "Non-nil when bibliography style implies wrapping citations in footnotes.INFO is the export state, as a property list."  (citeproc-style-cite-note   (citeproc-proc-style    (org-cite-csl--processor info))))(defun org-cite-csl--create-structure-params (citation info)  "Return citeproc structure creation params for CITATION object.STYLE is the citation style, as a string or nil. INFO is the export state, asa property list."  (let ((style (org-cite-citation-style citation info)))    (pcase style      ;; "author" style.      (`(,(or "author" "a") . ,variant)       (pcase variant	 ((or "bare" "b") '(:mode author-only :suppress-affixes t))	 ((or "caps" "c") '(:mode author-only :capitalize-first t))	 ((or "full" "f") '(:mode author-only :ignore-et-al t))	 ((or "bare-caps" "bc") '(:mode author-only :suppress-affixes t :capitalize-first t))	 ((or "bare-full" "bf") '(:mode author-only :suppress-affixes t :ignore-et-al t))	 ((or "caps-full" "cf") '(:mode author-only :capitalize-first t :ignore-et-al t))	 ((or "bare-caps-full" "bcf") '(:mode author-only :suppress-affixes t :capitalize-first t :ignore-et-al t))	 (_ '(:mode author-only))))      ;; "noauthor" style.      (`(,(or "noauthor" "na") . ,variant)       (pcase variant	 ((or "bare" "b") '(:mode suppress-author :suppress-affixes t))	 ((or "caps" "c") '(:mode suppress-author :capitalize-first t))	 ((or "bare-caps" "bc")          '(:mode suppress-author :suppress-affixes t :capitalize-first t))	 (_ '(:mode suppress-author))))      ;; "year" style.      (`(,(or "year" "y") . ,variant)       (pcase variant	 ((or "bare" "b") '(:mode year-only :suppress-affixes t))	 (_ '(:mode year-only))))      ;; "text" style.      (`(,(or "text" "t") . ,variant)       (pcase variant         ((or "caps" "c") '(:mode textual :capitalize-first t))         ((or "full" "f") '(:mode textual :ignore-et-al t))         ((or "caps-full" "cf") '(:mode textual :ignore-et-al t :capitalize-first t))         (_ '(:mode textual))))      ;; Default "nil" style.      (`(,_ . ,variant)       (pcase variant         ((or "caps" "c") '(:capitalize-first t))         ((or "bare" "b") '(:suppress-affixes t))         ((or "bare-caps" "bc") '(:suppress-affixes t :capitalize-first t))         (_  nil)))      ;; This should not happen.      (_ (error "Invalid style: %S" style)))))(defun org-cite-csl--no-citelinks-p (info)  "Non-nil when export BACKEND should not create cite-reference links."  (or (not org-cite-csl-link-cites)      (and org-cite-csl-no-citelinks-backends           (apply #'org-export-derived-backend-p                  (plist-get info :back-end)                  org-cite-csl-no-citelinks-backends))      ;; No references are being exported anyway.      (not (org-element-map (plist-get info :parse-tree) 'keyword             (lambda (k)               (equal "PRINT_BIBLIOGRAPHY" (org-element-property :key k)))             info t))))(defun org-cite-csl--output-format (info)  "Return expected Citeproc's output format.INFO is the export state, as a property list.  The return value is a symbolcorresponding to one of the output formats supported by Citeproc: `html',`latex', or `org'."  (let ((backend (plist-get info :back-end)))    (cond     ((org-export-derived-backend-p backend 'html) 'html)     ((org-export-derived-backend-p backend 'latex) 'latex)     (t 'org))))(defun org-cite-csl--style-file (info)  "Return style file associated to current export process.INFO is the export state, as a property list.When file name is relative, look for it in buffer's defaultdirectory, failing that in `org-cite-csl-styles-dir' if non-nil.Raise an error if no style file can be found."  (pcase (org-cite-bibliography-style info)    ('nil org-cite-csl--fallback-style-file)    ((and (pred file-name-absolute-p) file) file)    ((and (pred file-exists-p) file) (expand-file-name file))    ((and (guard org-cite-csl-styles-dir)          (pred (lambda (f)                  (file-exists-p                   (expand-file-name f org-cite-csl-styles-dir))))          file)     (expand-file-name file org-cite-csl-styles-dir))    (other     (user-error "CSL style file not found: %S" other))))(defun org-cite-csl--locale-getter ()  "Return a locale getter.The getter looks for locales in `org-cite-csl-locales-dir' directory.  If itcannot find them, it retrieves the default \"en_US\" from`org-cite-csl--fallback-locales-dir'."  (lambda (loc)    (or (and org-cite-csl-locales-dir             (ignore-errors               (funcall (citeproc-locale-getter-from-dir org-cite-csl-locales-dir)                        loc)))        (funcall (citeproc-locale-getter-from-dir                  org-cite-csl--fallback-locales-dir)                 loc))))(defun org-cite-csl--processor (info)  "Return Citeproc processor reading items from current bibliography.INFO is the export state, as a property list.Newly created processor is stored as the value of the `:cite-citeproc-processor'property in INFO."  (or (plist-get info :cite-citeproc-processor)      (let* ((bibliography (plist-get info :bibliography))             (locale (or (plist-get info :language) "en_US"))             (processor              (citeproc-create               (org-cite-csl--style-file info)               (citeproc-hash-itemgetter-from-any bibliography)               (org-cite-csl--locale-getter)               locale)))        (plist-put info :cite-citeproc-processor processor)        processor)))(defun org-cite-csl--parse-reference (reference info)  "Return Citeproc's structure associated to citation REFERENCE.INFO is the export state, as a property list.The result is a association list.  Keys are: `id', `prefix',`suffix',`location', `locator' and `label'."  (let (label location-start locator-start location locator prefix suffix)    ;; Parse suffix.  Insert it in a temporary buffer to find    ;; different parts: pre-label, label, locator, location (label +    ;; locator), and suffix.    (with-temp-buffer      (save-excursion        (insert (org-element-interpret-data                 (org-element-property :suffix reference))))      (cond       ((re-search-forward org-cite-csl--label-regexp nil t)        (setq location-start (match-beginning 0))        (setq label (cdr (assoc (match-string 1) org-cite-csl--label-alist)))        (goto-char (match-end 1))        (skip-chars-forward "[:space:] ")        (setq locator-start (point)))       ((re-search-forward (rx digit) nil t)        (setq location-start (match-beginning 0))        (setq label "page")        (setq locator-start location-start))       (t        (setq suffix (org-element-property :suffix reference))))      ;; Find locator's end, and suffix, if any. To that effect, look      ;; for the last comma or digit after label, whichever comes      ;; last.      (unless suffix        (goto-char (point-max))        (let ((re (rx (or "," (group digit)))))          (when (re-search-backward re location-start t)            (goto-char (or (match-end 1) (match-beginning 0)))            (setq location (buffer-substring location-start (point)))            (setq locator (org-trim (buffer-substring locator-start (point))))            ;; Skip comma in suffix.            (setq suffix                  (org-cite-parse-objects                   (buffer-substring (match-end 0) (point-max))                   t)))))      (setq prefix            (org-cite-concat             (org-element-property :prefix reference)             (and location-start                  (org-cite-parse-objects                   (buffer-substring 1 location-start)                   t)))))    ;; Return value.    (let ((export           (lambda (data)             (org-string-nw-p              (org-trim               ;; When Citeproc exports to Org syntax, avoid mix and               ;; matching output formats by also generating Org               ;; syntax for prefix and suffix.               (if (eq 'org (org-cite-csl--output-format info))                   (org-element-interpret-data data)                 (org-export-data data info)))))))      `((id . ,(org-element-property :key reference))        (prefix . ,(funcall export prefix))        (suffix . ,(funcall export suffix))        (locator . ,locator)        (label . ,label)        (location . ,location)))))(defun org-cite-csl--create-structure (citation info)  "Create Citeproc structure for CITATION object.INFO is the export state, as a property list."  (let* ((cites (mapcar (lambda (r)                          (org-cite-csl--parse-reference r info))                        (org-cite-get-references citation)))         (footnote (org-cite-inside-footnote-p citation)))    ;; Global prefix is inserted in front of the prefix of the first    ;; reference.    (let ((global-prefix (org-element-property :prefix citation)))      (when global-prefix        (let* ((first (car cites))               (prefix-item (assq 'prefix first)))          (setcdr prefix-item                  (concat (org-element-interpret-data global-prefix)                          " "                          (cdr prefix-item))))))    ;; Global suffix is appended to the suffix of the last reference.    (let ((global-suffix (org-element-property :suffix citation)))      (when global-suffix        (let* ((last (org-last cites))               (suffix-item (assq 'suffix last)))          (setcdr suffix-item                  (concat (cdr suffix-item)                          " "                          (org-element-interpret-data global-suffix))))))    ;; Check if CITATION needs wrapping, i.e., it should be wrapped in    ;; a footnote, but isn't yet.    (when (and (not footnote) (org-cite-csl--note-style-p info))      (org-cite-adjust-note citation info)      (setq footnote (org-cite-wrap-citation citation info)))    ;; Return structure.    (apply #'citeproc-citation-create           `(:note-index             ,(and footnote (org-export-get-footnote-number footnote info))             :cites ,cites             ,@(org-cite-csl--create-structure-params citation info)))))(defun org-cite-csl--rendered-citations (info)  "Return the rendered citations as an association list.INFO is the export state, as a property list.Return an alist (CITATION . OUTPUT) where CITATION object has been rendered asOUTPUT using Citeproc."  (or (plist-get info :cite-citeproc-rendered-citations)      (let* ((citations (org-cite-list-citations info))             (processor (org-cite-csl--processor info))             (structures              (mapcar (lambda (c) (org-cite-csl--create-structure c info))                      citations)))        (citeproc-append-citations structures processor)        (let* ((rendered                (citeproc-render-citations                 processor                 (org-cite-csl--output-format info)                 (org-cite-csl--no-citelinks-p info)))               (result (seq-mapn #'cons citations rendered)))          (plist-put info :cite-citeproc-rendered-citations result)          result))));;; Export capability(defun org-cite-csl-render-citation (citation _style _backend info)  "Export CITATION object.INFO is the export state, as a property list."  (org-cite-csl--barf-without-citeproc)  (let ((output (cdr (assq citation (org-cite-csl--rendered-citations info)))))    (if (not (eq 'org (org-cite-csl--output-format info)))        output      ;; Parse Org output to re-export it during the regular export      ;; process.      (org-cite-parse-objects output))))(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 format      ('html       (concat        (and (cdr (assq 'second-field-align parameters))             (let* ((max-offset (cdr (assq 'max-offset parameters)))                    (char-width                     (string-to-number org-cite-csl-html-label-width-per-char))                    (char-width-unit                     (progn                       (string-match (number-to-string char-width)                                     org-cite-csl-html-label-width-per-char)                       (substring org-cite-csl-html-label-width-per-char                                  (match-end 0)))))               (format                "<style>.csl-left-margin{float: left; padding-right: 0em;} .csl-right-inline{margin: 0 0 0 %d%s;}</style>"                (* max-offset char-width)                char-width-unit)))        (and (cdr (assq 'hanging-indent parameters))             (format              "<style>.csl-entry{text-indent: -%s; margin-left: %s;}</style>"              org-cite-csl-html-hanging-indent              org-cite-csl-html-hanging-indent))        output))      ('latex       (if (cdr (assq 'hanging-indent parameters))           (format "\\begin{hangparas}{%s}{1}\n%s\n\\end{hangparas}"                   org-cite-csl-latex-hanging-indent                   output)         output))      (_       ;; Parse Org output to re-export it during the regular export       ;; process.       (org-cite-parse-elements output)))))(defun org-cite-csl-finalizer (output _keys _files _style _backend info)  "Add \"hanging\" package if missing from LaTeX output.OUTPUT is the export document, as a string.  INFO is the export state, as aproperty list."  (org-cite-csl--barf-without-citeproc)  (if (not (eq 'latex (org-cite-csl--output-format info)))      output    (with-temp-buffer      (save-excursion (insert output))      (when (search-forward "\\begin{document}" nil t)        (goto-char (match-beginning 0))        ;; Ensure that \citeprocitem is defined for citeproc-el.        (insert "\\makeatletter\n\\newcommand{\\citeprocitem}[2]{\\hyper@linkstart{cite}{citeproc_bib_item_#1}#2\\hyper@linkend}\n\\makeatother\n\n")        ;; Ensure there is a \usepackage{hanging} somewhere or add one.        (let ((re (rx "\\usepackage" (opt "[" (*? nonl) "]") "{hanging}")))          (unless (re-search-backward re nil t)            (insert "\\usepackage[notquote]{hanging}\n"))))      (buffer-string))));;; Register `csl' processor(org-cite-register-processor 'csl  :export-citation #'org-cite-csl-render-citation  :export-bibliography #'org-cite-csl-render-bibliography  :export-finalizer #'org-cite-csl-finalizer  :cite-styles  '((("author" "a") ("bare" "b") ("caps" "c") ("full" "f") ("bare-caps" "bc") ("caps-full" "cf") ("bare-caps-full" "bcf"))    (("noauthor" "na") ("bare" "b") ("caps" "c") ("bare-caps" "bc"))    (("year" "y") ("bare" "b"))    (("text" "t") ("caps" "c") ("full" "f") ("caps-full" "cf"))    (("nil") ("bare" "b") ("caps" "c") ("bare-caps" "bc"))))(provide 'oc-csl);;; oc-csl.el ends here
 |