Function: bib-get-citations

bib-get-citations is a byte-compiled function defined in bib-cite.el.

Signature

(bib-get-citations KEYS-OBARRAY BIB-BUFFER NEW-BUFFER SUBSTITUTE)

Documentation

Put citations of KEYS-OBARRAY from BIB-BUFFER into NEW-BUFFER.

Substitute strings if SUBSTITUTE is t Return the-warnings as text.

Source Code

;; Defined in ~/.emacs.d/elpa/auctex-14.1.2/bib-cite.el
;; -------------------------------------------------------------------------
;; Routines to extract cite keys from text

;;    ... is truly remarkable, as shown in \citeN{Thomson77,Test56}. Every
;; \cite[{\it e.g.}]{Thomson77,Test56}

(defun bib-get-citations (keys-obarray bib-buffer new-buffer substitute)
  "Put citations of KEYS-OBARRAY from BIB-BUFFER into NEW-BUFFER.
Substitute strings if SUBSTITUTE is t
Return the-warnings as text."
  (let ((the-warnings)                  ;The only variable to remember...
        (case-fold-search t))           ;All other results go into new-buffer
    ;; bibtex is not case-sensitive for keys.
    (save-excursion
      (let ((the-text))
        (set-buffer bib-buffer)
        (mapatoms                         ;Do this for each cite-key found...
         (lambda (cite-key)
           (goto-char (point-min))
           (if (re-search-forward
                (concat "@[^{(]+[{(][\t ]*"
                        (regexp-quote (symbol-name cite-key))
                        "\\([, ]\\\|$\\)")
                ;;           ^^     ^  comma, space or end-of-line
                nil t)
               (setq the-text (concat the-text
                                      (buffer-substring
                                       (progn (beginning-of-line)(point))
                                       (progn (forward-sexp 2)(point)))
                                      "\n\n"))
             (setq the-warnings (concat the-warnings
                                        "Cannot find entry for: "
                                        (symbol-name cite-key) "\n"))))
         keys-obarray)
        (if (not the-text)
            (error "Sorry, could not find any of the references"))
        ;; Insert the citations in the new buffer
        (set-buffer new-buffer)
        (insert the-text)
        (goto-char 1))

      ;; We are at beginning of new-buffer.
      ;; Now handle crossrefs
      (let ((crossref-obarray (make-vector 201 0)))
        (while (re-search-forward
                "[, \t]*crossref[ \t]*=[ \t]*\\(\"\\|\{\\)" nil t)
          ;;handle {text} or "text" cases
          (if (string-equal "{" (match-string 1))
              (re-search-forward "[^\}]+" nil t)
            (re-search-forward "[^\"]+" nil t))
          (intern (match-string 0) crossref-obarray))
        ;; Now find the corresponding keys,
        ;; but add them only if not already in `keys-obarray'
        (set-buffer bib-buffer)
        (goto-char 1)
        (let ((the-text))
          (mapatoms                     ;Do this for each crossref key found...
           (lambda (crossref-key)
             (if (not (intern-soft (symbol-name crossref-key) keys-obarray))
                 (progn
                   ;; Not in keys-obarray, so not yet displayed.
                   (goto-char (point-min))
                   (if (re-search-forward
                        (concat "@[^{(]+[{(][\t ]*"
                                (regexp-quote (symbol-name crossref-key))
                                "\\(,\\|$\\)")
                        nil t)
                       (setq the-text
                             (concat the-text
                                     (buffer-substring
                                      (progn (beginning-of-line)(point))
                                      (progn (forward-sexp 2)(point)))
                                     "\n\n"))
                     (setq the-warnings
                           (concat the-warnings
                                   "Cannot find crossref entry for: "
                                   (symbol-name crossref-key) "\n"))))))
           crossref-obarray)
          ;; Insert the citations in the new buffer
          (set-buffer new-buffer)
          (goto-char (point-max))
          (if the-text
              (insert the-text)))
        (goto-char 1))

      ;; Now we have all citations in new-buffer, collect all used @String keys
      ;; Ex:  journal =      JPO,
      (let ((strings-obarray (make-vector 201 0)))
        (while (re-search-forward bib-string-regexp nil t)
          (intern (match-string 1) strings-obarray))
        ;; Now find the corresponding @String commands
        ;; Collect either the @string commands, or the string to substitute
        (set-buffer bib-buffer)
        (goto-char 1)
        (let ((string-alist)
              (the-text))
          (mapatoms                     ;Do this for each string-key found...
           (lambda (string-key)
             (goto-char (point-min))
             ;; search for @string{ key = {text}} or @string{ key = "text"}
             (if (re-search-forward
                  (concat "^[ \t]*@string[{(]"
                          (regexp-quote (symbol-name string-key))
                          "[\t ]*=[\t ]*\\(\"\\|\{\\)")
                  nil t)
                 (let ((the-string-start (1- (match-end 1))) ;catch bracket
                       ;;handle {text} or "text" cases
                       (the-string-end
                        (cond
                         ((string-equal "\"" (match-string 1))
                          (re-search-forward "[^\\]\"" nil t)
                          (point))
                         (t
                          (forward-char -1)
                          (forward-list 1)
                          (point)))))
                   (if substitute      ;Collect substitutions
                       (setq string-alist
                             (append
                              string-alist
                              (list
                               (cons (symbol-name string-key)
                                        ;(regexp-quote
                                     (buffer-substring the-string-start
                                                       the-string-end)))));)
                     ;;Collect the strings command themseves
                     (setq the-text
                           (concat the-text
                                   (buffer-substring
                                    (progn (forward-char 1)(point))
                                    (re-search-backward "^[ \t]*@string[{(]"
                                                        nil t))
                                   "\n"))))
               ;; @string entry not found
               (if (not (member-cis (symbol-name string-key)
                                    bib-string-ignored-warning))
                   (setq the-warnings
                         (concat the-warnings
                                 "Cannot find @String entry for: "
                                 (symbol-name string-key) "\n")))))
           strings-obarray)
          ;; Now we have `the-text' of @string commands,
          ;; or the `string-alist' to substitute.
          (set-buffer new-buffer)
          (if substitute
              (while string-alist
                (goto-char 1)
                (let* ((the-key (car (car string-alist)))
                       (the-string (cdr (car string-alist)))
                       (slashed-string  ; "J. of Geo.\" -> "J. of Geo.\\\\"
                        (replace-regexp-in-string
                         "\\\\" "\\\\" the-string t t)))

                  (while (re-search-forward
                          (concat "\\(^[, \t]*[a-zA-Z]+[ \t]*=[ \t]*\\)"
                                  (regexp-quote the-key)
                                  "\\([, \t\n]\\)")
                          nil t)
                    (replace-match (concat "\\1" slashed-string "\\2") t nil)))
                (setq string-alist (cdr string-alist)))
            ;; substitute is nil; Simply insert text of @string commands
            (goto-char 1)
            (if the-text
                (insert the-text "\n")))
          (goto-char 1))))

    ;; We are done!
    ;; Return the warnings...
    the-warnings))