[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
hyperbole: programmatic button creation
From: |
Jim Ottaway |
Subject: |
hyperbole: programmatic button creation |
Date: |
Thu, 20 Nov 2003 14:49:40 +0000 |
User-agent: |
Gnus/5.090024 (Oort Gnus v0.24) Emacs/21.2 (gnu/linux) |
I am trying to create a new hyperbole explicit button with a link to a
bibtex entry in a bibtex file. The idea is to use the reftex search
mechanism to ``cite'' a reference as a hyperbole button.
So far I have:
(defact link-to-bibtex-entry (entry)
"Find bibtex entry. ENTRY is a list: \(key file-name title\)"
(interactive (list (rft-hyp-get-citation)))
(funcall
(actype:action 'link-to-regexp-match)
;; regexp cribbed from reftex-cite.el
(concat "@[a-zA-Z]+[ \t\n\r]*[{(][ \t\n\r]*"
(regexp-quote (first entry)))
1 (second entry) nil))
The function `rft-hyp-get-citation' supplies a list: (key file-name
title). It uses a slightly modified form of
`reftex-extract-bib-entries' that adds an element with the file name of
the match (see code below).
This works well, as it stands, but it is not quite what I want. What I
would really like is to programmatically create the explicit button
using the list returned from `rft-hyp-get-citation', avoiding all the
prompts for button type and label in `hui:ebut-create'.
I have looked at the manual and the documentation for `ebut:create',
but I can not work out how to do this from the information supplied.
Does anyone have any experience of creating explicit buttons
programmatically?
Regards,
Jim Ottaway
Here is the code for `rft-hyp-get-citation':
(require 'cl)
(require 'reftex-cite)
(defun rft-hyp-get-citation ()
(let ((entry '()))
(flet ((reftex-extract-bib-entries
(buffers)
(rft-hyp-reftex-extract-bib-entries buffers)))
;; todo: only deals with single choices at the moment
(setq entry (car (reftex-offer-bib-menu)))
(list
(rft-hyp-strip-properties
(reftex-get-bib-field "&key" entry))
(reftex-get-bib-field "&file" entry)
(rft-hyp-strip-properties
(reftex-get-bib-field "title" entry))))))
(defun rft-hyp-reftex-extract-bib-entries (buffers)
;; Extract bib entries which match regexps from BUFFERS.
;; BUFFERS is a list of buffers or file names.
;; Return list with entries."
(let* (re-list first-re rest-re
(buffer-list (if (listp buffers) buffers (list buffers)))
found-list entry buffer1 buffer alist
key-point start-point end-point)
;; Read a regexp, completing on known citation keys.
(setq re-list
(split-string
(completing-read
"RegExp [ && RegExp...]: "
(if reftex-mode
(if (fboundp 'LaTeX-bibitem-list)
(LaTeX-bibitem-list)
(cdr (assoc 'bibview-cache
(symbol-value reftex-docstruct-symbol))))
nil)
nil nil nil 'reftex-cite-regexp-hist)
"[ \t]*&&[ \t]*"))
(setq first-re (car re-list) ; We'll use the first re to find things,
rest-re (cdr re-list)) ; the others to narrow down.
(if (string-match "\\`[ \t]*\\'" (or first-re ""))
(error "Empty regular expression"))
(save-excursion
(save-window-excursion
;; Walk through all bibtex files
(while buffer-list
(setq buffer (car buffer-list)
buffer-list (cdr buffer-list))
(if (and (bufferp buffer)
(buffer-live-p buffer))
(setq buffer1 buffer)
(setq buffer1 (reftex-get-file-buffer-force
buffer (not reftex-keep-temporary-buffers))))
(if (not buffer1)
(message "No such BibTeX file %s (ignored)" buffer)
(message "Scanning bibliography database %s" buffer1))
(set-buffer buffer1)
(save-excursion
(goto-char (point-min))
(while (re-search-forward first-re nil t)
(catch 'search-again
(setq key-point (point))
(unless (re-search-backward
"\\(\\`\\|[\n\r]\\)[ \t]*@\\([a-zA-Z]+\\)[
\t\n\r]*[{(]" nil t)
(throw 'search-again nil))
(setq start-point (point))
(goto-char (match-end 0))
(condition-case nil
(up-list 1)
(error (goto-char key-point)
(throw 'search-again nil)))
(setq end-point (point))
;; Ignore @string, @comment and @c entries or things
;; outside entries
(when (or (string= (downcase (match-string 2)) "string")
(string= (downcase (match-string 2)) "comment")
(string= (downcase (match-string 2)) "c")
(< (point) key-point)) ; this means match not in {}
(goto-char key-point)
(throw 'search-again nil))
;; Well, we have got a match
(setq entry (concat
(buffer-substring start-point (point)) "\n"))
;; Check if other regexp match as well
(setq re-list rest-re)
(while re-list
(unless (string-match (car re-list) entry)
;; nope - move on
(throw 'search-again nil))
(pop re-list))
(setq alist (reftex-parse-bibtex-entry
nil start-point end-point))
(push (cons "&entry" entry) alist)
;; ADDED
(push (cons "&file" (buffer-file-name)) alist)
;; check for crossref entries
(if (assoc "crossref" alist)
(setq alist
(append
alist (reftex-get-crossref-alist alist))))
;; format the entry
(push (cons "&formatted" (reftex-format-bib-entry alist))
alist)
;; make key the first element
(push (reftex-get-bib-field "&key" alist) alist)
;; add it to the list
(push alist found-list))))
(reftex-kill-temporary-buffers))))
(setq found-list (nreverse found-list))
;; Sorting
(cond
((eq 'author reftex-sort-bibtex-matches)
(sort found-list 'reftex-bib-sort-author))
((eq 'year reftex-sort-bibtex-matches)
(sort found-list 'reftex-bib-sort-year))
((eq 'reverse-year reftex-sort-bibtex-matches)
(sort found-list 'reftex-bib-sort-year-reverse))
(t found-list))))
- hyperbole: programmatic button creation,
Jim Ottaway <=