From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Jim Ottaway Newsgroups: gmane.emacs.help Subject: hyperbole: programmatic button creation Date: Thu, 20 Nov 2003 14:49:40 +0000 Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Message-ID: <87r803nlh7.fsf@lse.ac.uk> NNTP-Posting-Host: deer.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: sea.gmane.org 1069340879 422 80.91.224.253 (20 Nov 2003 15:07:59 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Thu, 20 Nov 2003 15:07:59 +0000 (UTC) Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Thu Nov 20 16:07:56 2003 Return-path: Original-Received: from monty-python.gnu.org ([199.232.76.173]) by deer.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 1AMqPU-0005dA-00 for ; Thu, 20 Nov 2003 16:07:56 +0100 Original-Received: from localhost ([127.0.0.1] helo=monty-python.gnu.org) by monty-python.gnu.org with esmtp (Exim 4.24) id 1AMrKX-0003h7-K2 for geh-help-gnu-emacs@m.gmane.org; Thu, 20 Nov 2003 11:06:53 -0500 Original-Received: from list by monty-python.gnu.org with tmda-scanned (Exim 4.24) id 1AMrJP-0003XU-P9 for help-gnu-emacs@gnu.org; Thu, 20 Nov 2003 11:05:43 -0500 Original-Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.24) id 1AMrIn-0003Bc-Sx for help-gnu-emacs@gnu.org; Thu, 20 Nov 2003 11:05:36 -0500 Original-Received: from [212.74.114.48] (helo=mk-smarthost-9.mail.uk.tiscali.com) by monty-python.gnu.org with esmtp (Exim 4.24) id 1AMrFy-0001I8-7a for help-gnu-emacs@gnu.org; Thu, 20 Nov 2003 11:02:10 -0500 Original-Received: from [80.225.212.122] (helo=runcible) by mk-smarthost-9.mail.uk.tiscali.com with esmtp (Exim 4.24) id 1AMqIO-000FmN-Vz for help-gnu-emacs@gnu.org; Thu, 20 Nov 2003 15:00:37 +0000 Original-Received: from jeho by runcible with local (Exim 3.35 #1 (Debian)) id 1AMq7o-00016a-00 for ; Thu, 20 Nov 2003 14:49:40 +0000 Original-To: help-gnu-emacs@gnu.org User-Agent: Gnus/5.090024 (Oort Gnus v0.24) Emacs/21.2 (gnu/linux) X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.2 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Xref: main.gmane.org gmane.emacs.help:14422 X-Report-Spam: http://spam.gmane.org/gmane.emacs.help:14422 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))))