Function: bibtex-search-crossref

bibtex-search-crossref is an interactive and byte-compiled function defined in bibtex.el.gz.

Signature

(bibtex-search-crossref CROSSREF-KEY &optional PNT SPLIT NOERROR)

Documentation

Move point to the beginning of BibTeX entry CROSSREF-KEY.

If bibtex-files is non-nil, search all these files. Otherwise the search is limited to the current buffer. Return position of entry if CROSSREF-KEY is found or nil otherwise. If CROSSREF-KEY is in the same buffer like current entry but before it an error is signaled. If NOERROR is non-nil this error is suppressed. Optional arg PNT is the position of the referencing entry. It defaults to position of point. If optional arg SPLIT is non-nil, split window so that both the referencing and the crossrefed entry are displayed.

If called interactively, CROSSREF-KEY defaults to either the crossref key of current entry or a key matched by bibtex-cite-matcher-alist, whatever is nearer to the position of point. SPLIT is t. NOERROR is nil for a crossref key, t otherwise.

Key Bindings

Aliases

bibtex-find-crossref (obsolete since 29.1)

Source Code

;; Defined in /usr/src/emacs/lisp/textmodes/bibtex.el.gz
             'bibtex-lessp))               ; PREDICATE

(defun bibtex-search-crossref (crossref-key &optional pnt split noerror)
  "Move point to the beginning of BibTeX entry CROSSREF-KEY.
If `bibtex-files' is non-nil, search all these files.
Otherwise the search is limited to the current buffer.
Return position of entry if CROSSREF-KEY is found or nil otherwise.
If CROSSREF-KEY is in the same buffer like current entry but before it
an error is signaled.  If NOERROR is non-nil this error is suppressed.
Optional arg PNT is the position of the referencing entry.  It defaults
to position of point.  If optional arg SPLIT is non-nil, split window
so that both the referencing and the crossrefed entry are displayed.

If called interactively, CROSSREF-KEY defaults to either the crossref key
of current entry or a key matched by `bibtex-cite-matcher-alist',
whatever is nearer to the position of point.  SPLIT is t.  NOERROR is nil
for a crossref key, t otherwise."
  (interactive
   (save-excursion
     (let* ((pnt (point))
            (_ (bibtex-beginning-of-entry))
            (end (cdr (bibtex-valid-entry t)))
            (_ (unless end (user-error "Not inside valid entry")))
            (beg (match-end 0)) ; set by `bibtex-valid-entry'
            (bounds (bibtex-search-forward-field "\\(OPT\\)?crossref" end))
            case-fold-search best temp crossref-key)
       (if bounds
           (setq crossref-key (bibtex-text-in-field-bounds bounds t)
                 best (cons (bibtex-dist pnt (bibtex-end-of-field bounds)
                                         (bibtex-start-of-field bounds))
                            crossref-key)))
       (dolist (matcher bibtex-cite-matcher-alist)
         (goto-char beg)
         (while (re-search-forward (car matcher) end t)
           (setq temp (bibtex-dist pnt (match-end (cdr matcher))
                                   (match-beginning (cdr matcher))))
           ;; Accept the key closest to the position of point.
           (if (or (not best) (< temp (car best)))
               (setq best (cons temp (match-string-no-properties
                                      (cdr matcher)))))))
       (goto-char pnt)
       (setq temp (bibtex-read-key "Find crossref key: " (cdr best) t))
       (list temp (point) t (not (and crossref-key
                                      (string= temp crossref-key)))))))

  (let (buffer pos eqb)
    (save-excursion
      (setq pos (bibtex-search-entry crossref-key t)
            buffer (current-buffer)))
    (setq eqb (eq buffer (current-buffer)))
    (cond ((not pos)
           (if split (message "Crossref key `%s' not found" crossref-key)))
          (split ; called (quasi) interactively
           (unless pnt (setq pnt (point)))
           (goto-char pnt)
           (if (and eqb (= pos (save-excursion (bibtex-beginning-of-entry))))
               (message "Key `%s' is current entry" crossref-key)
             (if eqb (select-window (split-window))
               (pop-to-buffer buffer))
             (bibtex-reposition-window pos)
             (beginning-of-line)
             (if (and eqb (> pnt pos) (not noerror))
                 (user-error "The referencing entry must precede the crossrefed entry"))))
          ;; `bibtex-search-crossref' is called noninteractively during
          ;; clean-up of an entry.  Then it is not possible to check
          ;; whether the current entry and the crossrefed entry have
          ;; the correct sorting order.
          (eqb (goto-char pos))
          (t (set-buffer buffer) (goto-char pos)))
    pos))