diff options
Diffstat (limited to 'biblio/bibtex/utils/ebib')
-rw-r--r-- | biblio/bibtex/utils/ebib/ChangeLog | 1118 | ||||
-rw-r--r-- | biblio/bibtex/utils/ebib/INSTALL | 1 | ||||
-rw-r--r-- | biblio/bibtex/utils/ebib/README | 14 | ||||
-rw-r--r-- | biblio/bibtex/utils/ebib/VERSION | 1 | ||||
-rw-r--r-- | biblio/bibtex/utils/ebib/doc/ebib-manual.pdf | bin | 0 -> 257344 bytes | |||
-rw-r--r-- | biblio/bibtex/utils/ebib/doc/html/ebib-manual.css | 61 | ||||
-rw-r--r-- | biblio/bibtex/utils/ebib/doc/html/ebib-manual.html | 2224 | ||||
-rw-r--r-- | biblio/bibtex/utils/ebib/ebib.el | 3606 | ||||
-rw-r--r-- | biblio/bibtex/utils/ebib/info/ebib-manual.info | 2444 |
9 files changed, 9469 insertions, 0 deletions
diff --git a/biblio/bibtex/utils/ebib/ChangeLog b/biblio/bibtex/utils/ebib/ChangeLog new file mode 100644 index 0000000000..0dba0ab80c --- /dev/null +++ b/biblio/bibtex/utils/ebib/ChangeLog @@ -0,0 +1,1118 @@ +2009-07-13 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-search-crossref): new. + (ebib-entry-summary): modified to use with-help-window instead of + with-output-to-temp-buffer. + +2009-07-12 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-push-bibtex-key): renamed from ebib-push-entry-key + in accordance with ebib-insert-bibtex-key. + (ebib-insertion-commands): new. + (ebib-insertion-strings): removed. + +2008-08-01 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-entry-types-hash): removed. + (ebib-set-entry-types-hash): removed. + (ebib-set-unique-field-list): new. + (ebib-get-obl-fields): modified to use ebib-entry-types directly, + rather than the (now defunct) ebib-entry-types-hash. + (ebib-get-opt-fields): same. + (ebib-find-bibtex-entries): same. + (ebib-edit-entry-type): same. + +2008-06-15 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-read-string): bug fix: ebib would choke on bibtex + entries that have a space after the entry type but before the + opening parenthesis/brace. bug reported and fix provided by Rupert + Swarbrick. + +2008-05-31 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-index-window-size): "key buffer" in the doc string + changed to "index buffer". + +2008-05-30 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-call-file-viewer): modified to use + file-name-extension. is probably a safer bet that what i used + before: (last1 (split-string file "\\.")). + +2008-05-21 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-add-entry): bugfix: moved the code that creates + the hash table up, so that it appears before ebib-display-entry. + +2008-04-21 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el: fixed doc strings. + +2008-04-20 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-entry-summary): modified: if the ebib buffers are + visible, instead of putting the output in a temp buffer, the + relevant entry is displayed in the ebib buffers. + (ebib) help mode removed. + (ebib-show-log): modified: in split-frame layout the window's + dedicated flag must be temporarily unset in order to switch to the + strings-buffer. + (ebib-quit-log-buffer): same. + (ebib-set-index-highlight): modified: move cursor to beginning of + line after setting the highlight. + (ebib-set-fields-highlight): same. + (ebib-set-strings-highlight): same. + (ebib-edit-entry): removed goto-char and switch-to-buffer. + (line-number-at-pos): this is called line-number in xemacs, so an + alias is defined. + (ebib-match-paren-forward): added "" to error, to keep xemacs from complaining. + (ebib-match-quote-forward): same. + (ebib-setup-windows): added delete-other-windows in full-frame layout. + (ebib-export-to-db): modified to use gensym. + (ebib-export-to-file): same. + +2008-04-19 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-pre-ebib-window): new. + (ebib-setup-windows): added ebib-pre-ebib-window. + (ebib-quit): added ebib-pre-ebib-window. + (ebib-lower): modified to use ebib-pre-ebib-window. + (ebib-edit-entry-type): modified to use ebib-layout. + (ebib-edit-crossref): same. + (ebib-fill-entry-buffer): added skip-chars-forward: the cursor + usually appears directly after the field name. + (ebib-edit-crossref): modified to make the crossref field the + current field again. + (ebib-redisplay-current-field): same. + (ebib-temp-window): new. + (ebib-leave-multiline-edit): removed. + (ebib-leave-multiline-edit-buffer): new. + (ebib-quit-multiline-edit): new. + (ebib-cancel-multiline-edit): modified to use + ebib-leave-multiline-edit-buffer. + (ebib-edit-multiline-field): modified to use ebib-temp-window. + (ebib-edit-multiline-string): same. + (ebib-multiline-edit): modified: sets the buffer's modified flag + to nil. + (ebib-edit-strings): modified: in split-frame layout the window's + dedicated flag must be temporarily unset in order to switch to the + strings-buffer. + (ebib-quit-strings-buffer): same. + +2008-04-19 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib): added nil as second argument (norecord) to + select-window. + (ebib-setup-windows): modified. now uses ebib-layout to choose the + desired window layout. + (ebib-delete-window): removed. i really don't think we need this. + (ebib-lower): removed call to ebib-delete-windows. + (ebib-quit): modified: put all the kill-buffers into a mapc. + (ebib-select-other-window): removed. + (ebib-leave-ebib-windows): new. bound to "z" and "C-xb". + (ebib-lower): modified: now simply leaves the ebib buffers if + requested. rebound to "Z". + +2008-04-18 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-search-next): changed $ in search string to space: + with ebib-index-display-fields, index entries now have a space + after the entry key. + (ebib-call-file-viewer): new. + (ebib-file-regexp): added a space to the regexp. (!) + (ebib-browse-url-in-field): changed the doc string. + (ebib-view-file-in-field): new. + (ebib-view-file-in-field): new. bound to 'f' in the entry buffer. + (ebib-file-associations): changed default value: paths removed + from the programs, as start-process searches the user's PATH. + +2008-04-17 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-view-file): new. bound to 'f' in the index + buffer. (which means that 'f' is no longer bound to + ebib-print-filename. + +2008-04-11 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-layout): new. + * ebib.el (ebib-add-entry): used ebib-display-entry to insert the + new entry in the buffer. + +2008-04-11 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-add-entry): inserted a space in the format string + that puts the new entry key into the buffer. this way + ebib-set-index-highlight doesn't put the end of the highlight at + the next line. + +2008-03-26 Morgan Veyret <patzy@appart.kicks-ass.net> + + * ebib.el (ebib): changed to check if ebib is visible + already. window setup moved to ebib-setup-windows. + (ebib-setup-windows): new. + (ebib-delete-windows): new. + (ebib-select-other-window): new. Bound to C-xb. + (ebib-quit-entry-buffer): use get-buffer-window to find the index + buffer. + (ebib-entry-summary): modified to direct output to *Ebib-entry* + buffer. + +2008-03-26 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-index-mode): set truncate-lines to t, which works + better if ebib-index-dislay-fields is set. + (ebib-set-index-highlight): changed so that it highlights the + entire line if ebib-index-display-fields is set. + +2008-03-25 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-additional-fields): added 'file' to the default + value. + (ebib-url-regexp): changed doc string. + (ebib-standard-file-field): new. + (ebib-file-associations): new. + (ebib-file-regexp): new. + (ebib-file-search-dirs): new. + +2008-03-19 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-display-entry): added set-buffer. + +2008-03-18 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-index-display-fields): new. + (ebib-display-entry): new. + (ebib-fill-index-buffer): modified so as to make use of + ebib-display-entry. + (ebib-edit-keyname): same. + (ebib-set-index-highlight): changed end-of-line into + skip-chars-forward because of ebib-index-display-fields. + (ebib-select-entry): same. + +2007-11-15 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-syntax-table): modified the syntax classes for () + and [] to punctuation character. Not that it really matters, though. + +2007-11-10 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el: removed empty lines after the first line of doc + strings. (this is apparently not an Emacs convention...) + (ebib-read-entry): changed warning message for duplicate entries. + (ebib-read-string): same. + +2007-11-09 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-match-quote-forward): reworked a bit. + (ebib-show-log): new. + (ebib-index-mode-map): added "l" key, bound to ebib-show-log. + (ebib-log-mode-map): new. + (ebib-log-mode): new. + (ebib-quit-log-buffer): new. + (ebib-match-delim-forward): new. + (ebib-read-string): modified to use ebib-match-delim-forward. + (ebib-read-preamble): added a test to check for the result of + ebib-match-paren-forward. + (ebib-find-bibtex-entries): added test to check if + ebib-read-preamble returns non-nil. + (ebib-find-end-of-field): modified to use ebib-match-delim-forward. + (ebib-create-buffers): added initial message to the log buffer. + +2007-11-08 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-lower): added bury-buffer command for ebib-log-buffer. + (ebib-quit): added kill-buffer commands for ebib-log-buffer and ebib-strings-buffer. + +2007-11-07 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-merge-bibtex-file): added final call to ebib-log, + to insert "\n\f\n". + (ebib-find-bibtex-entries): added "Line" to warning message. + (ebib-read-string): same. + (ebib-read-entry): same. + (ebib-log): added save-excursion, so that the ebib log buffer is + only current during this function. also modified to no longer set + ebib-log-error to 0 unconditionally, instead checks if it's still + nil. also modified to use cond. + (ebib-match-brace-forward): new. this function handles braces {} + only. + (ebib-match-paren-forward): modified to handle parenthesis () and + braces {} differently. + (ebib-match-quote-forward): modified: logs an error when no + closing quote is found, and moves point to the char after the + opening quote. + +2007-11-07 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-log-error): new. + (ebib-create-buffers): added creating the log buffer. + (ebib-find-bibtex-entries): modified to use ebib-log. + (ebib-read-string): same. + (ebib-read-entry): same. + +2007-11-06 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-customize): added doc string. + (ebib-log-buffer): new. + (ebib-log): new. + (ebib-load-bibtex-file): modified to use ebib-log. + (ebib-merge-bibtex-file): same. + +2007-11-02 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-syntax-table): new. + (ebib-load-bibtex-file): modified to use with-syntax-table. + (ebib-merge-bibtex-file): same. + (ebib-import): same. + (ebib-store-multiline-text): check-parens removed. + +2007-10-31 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-init): removed test whether ~/.ebibrc exists; use + second (optional) argument to load instead. + +2007-10-29 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-marked-face): turned into a customisable option. + (ebib-fill-index-buffer): modified to use ebib-marked-face as a + face, rather than a variable. + (ebib-mark-entry): same. + +2007-10-29 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-fill-index-buffer): changed mapcar to mapc + (prevents compiler warning). fix provided by Leo + <sdl.web at gmail.com>. + (ebib): added autoload cookie. suggested by Leo + <sdl.web at gmail.com>. + (ebib-mark-entry): fixed typo: '(face ,ebib-marked-face) to `(face + ,ebib-marked-face). fix provided by Leo <sdl.web at gmail.com>. + +2007-10-22 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib): modified to store the buffer from which ebib is + called in ebib-push-buffer, so that it becomes the default for + pushing entries. Thanks to Sinisa Pajevic for the suggestion. + +2007-10-20 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-redisplay-current-field): modified. now redisplays + the entire entry buffer is the current field is crossref. (cutting + the value from the crossref field would leave the inherited field + values visible.) + (ebib-import): modified to use insert-buffer-substring, rather + than buffer-string and insert. this way, there is no need to + temporarily store the buffer contents in a variable. + (ebib-get-field-highlighted): modified so that it doesn't produce + an error if an entry contains a crossref to an entry that does not + exist. + (ebib-get-local-databases): variable bibfiles removed from the let. + +2007-10-20 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-local-bibtex-filenames): renamed from + ebib-local-bibtex-filname. this is now a list of strings, rather + than a string. thanks to Sinisa Pajevic for pointing out that a + \bibliography command can contain more than one .bib file. + (ebib-extract-bibfiles): removed. + (ebib-get-local-databases): modified to return a list of database + filenames. also now uses insert-buffer-substring, rather than a + combination of buffer-string and insert. + (ebib-insert-bibtex-key): modified so that it can handle multiple + bibtex files. this reflects the change to + ebib-local-bibtex-filenames. + (ebib-entry-summary): same. + +2007-10-19 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-push-entry-key): new. pushes the current entry + key, or the marked entry keys, to a buffer, using + ebib-insertion-strings. thanks to Sinisa Pajevic for suggesting + this feature. + (ebib-key "p"): changed to ebib-push-entry-key. + (ebib-key "r"): new. assigned to ebib-edit-preamble. + (ebib-prefixed-functions): ebib-push-entry-key added. + (ebib-push-buffer): new. holds the name of the last buffer to + which an entry was pushed, to present it as default in the next + push operation. + (ebib-insertion-strings): modified default value: 0 added. + +2007-10-11 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-get-field-highlighted): modified so as to show + field values inherited from a cross-referenced entry. + (ebib-crossref-face): new. + (ebib-edit-crossref): modified to redisplay the entire entry + buffer, not just the current field. + +2007-07-29 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-store-multiline-text): added a check to make sure + the text in the buffer doesn't contain unbalanced braces. + (ebib-filter-to-virtual-db): changed to give more feedback in the + minibuffer about what the user is doing. + +2007-06-26 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-insert-bibtex-key): changed to show the cite + command that the user has selected through the prefix argument. + +2007-04-26 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-standard-url-field): doc string modified. + +2007-04-06 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-allow-identical-fields): new. + (ebib-find-bibtex-fields): modified so as to use + ebib-allow-identical-fields. + +2007-03-30 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-url-regexp): bug fix: removed \l from default + value. + +2007-03-29 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el: Ebib 1.3.0 released. + +2007-03-29 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-index-mode-map): added "u" key. + (ebib-url-field): new. + (ebib-url-regexp): new. + (ebib-browse-url): new. + (ebib-call-browser): new. + (ebib-entry-mode-map): added "u" key. + (ebib-browse-url-in-field): new. + (ebib-call-browser-command): new. + +2007-03-28 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (raw-p): regexp "\".*?\" replaced with + "\"[^\"]*?\"". The dot doesn't match \n, so a multiline string + enclosed by double quotes was incorrectly recognised as a raw + string. + +2007-03-27 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-export-entry): ebib-execute-when + removed. ebib-marked-p replaced with ebib-called-with-prefix. + (ebib-export-single-entry): added ebib-execute-when. + (ebib-export-marked-entries): same. + (ebib-prefix-map): new. (actually, this is ebib-semicolon-map + reintroduced under a new name.) + (ebib-index-mode-map): binding of the prefix key ";" changed to + ebib-prefix-map. + (ebib-key): modified so that if the user redefines a key in + ebib-index-mode-map, it checks whether the function is bound in + ebib-prefix-map as well, and if so, binds it to the same + key. Furthermore, if the user unbinds a key, it is unbound in + ebib-prefix-map as well. + (ebib-marked-p): removed. + (ebib-prefixed-functions): new. + (ebib-prefix-key): new. + (ebib-key): modified so that it unsets the current prefix key if + the user redefines the prefix key with mark-prefix. + (ebib-index-mode-map): key bindings no longer done in the defvar + definition, but at top level with ebib-key. Using ebib-key has the + advantage that ebib-prefix-map is automatically set up correctly + as well. + +2007-03-26 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-called-with-prefix): new. + (ebib-marked-p): new. + (ebib-prefix-key): new. + (ebib-key): added clause for mark-prefix. + (ebib-delete-marked-entries): removed. + (ebib-delete-entry): modified to handle the prefix key. + (ebib-export-entry): modified to call either of two helper + functions, depending on whether it was called with or without + prefix key. + (ebib-export-single-entry): new. helper function for + ebib-export-entry. + (ebib-export-marked-entries): changed into helper function for + ebib-export-entry. + (ebib-print-database): removed. + (ebib-print-marked-entries): removed. + (ebib-semicolon-map): removed. + (ebib-index-mode-map): binding for L changed to + ebib-latex-entries, and binding for P changed to + ebib-print-entries. + (ebib-print-entries): made interactive and modified to handle + marked entries. + (ebib-latex-database): removed. + (ebib-latex-marked-entries): removed. + (ebib-latex-entries): made interactive and modified to handle + marked entries. + (ebib-mark-all): removed. + +2007-03-25 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-remove-entry-from-db): modified so that a deleted + entry is also deleted from edb-marked-entries if it's there. This + avoids problems when the user deletes a marked entry, and also + when he renames the entry key of a marked entry. + (ebib-delete-marked-entries): no longer sets edb-marked-entries to + nil, as the entries are removed one by one by + ebib-remove-entry-from-db. + (ebib-edit-keyname): modified so that it marks the renamed entry + if it was marked before the renaming. + (ebib-unmark-all): renamed to ebib-mark-all. + (ebib-mark-all): modified so that it marks all entries if there + are no marked entries. + (ebib-mark-entry): real-db removed from ebib-execute-when. + (ebib-export-entry): modified to include the entry name in the + messages passed to ebib-export-to-db and ebib-export-to-file. + (ebib-export-string): same with string abbreviation. + +2007-03-24 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-export-string): modified to make use of + ebib-export-to-db and ebib-export-to-file. + (ebib-export-all-strings): same. + (ebib-export-preamble): same. + (ebib-export-marked-entries): new. + (ebib-semicolon-map): new key "x" added. + (propertize): new. + (ebib-write-database): rewritten to stop XEmacs from + complaining. (See arch log for details.) + (ebib-export-to-file): modified documentation string, as it said + something about insert-fn that isn't correct. + (ebib-execute-helper): added marked-entries. + (ebib-delete-marked-entries): modified to use marked-entries. + (ebib-export-marked-entries): same. + (ebib-delete-marked-entries): added default clause to + ebib-execute-when. + (ebib-print-entries): new. contains most of the code of former + ebib-print-database. + (ebib-print-database): modified to use ebib-print-entries. + (ebib-print-marked-entries): new. + (define-prefix-command): new keys "P", "L" and "m". + (ebib-mark-entry): modified: no longer adds the text properties to + the entry key in the database, just in the index buffer. + (ebib-fill-index-buffer): modified so that it adds a highlight to + marked entries. + (ebib-latex-entries): new. contains most of the code of former + ebib-latex-database. + (ebib-latex-database): modified to use ebib-latex-entries. + (ebib-latex-marked-entries): new. + (ebib-unmark-all): new. + +2007-03-23 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-export-to-db): new. + (ebib-export-to-file): new. + (ebib-export-entry): modified to make use of ebib-export-to-db and + ebib-export-to-file. + +2007-03-20 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-edit-field): changed to unconditionally add braces + around the text the user enters. Formerly, this was done through + from-raw, which meant that if the user typed braces around the + text, these would disappear. + +2007-03-19 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (add-to-listq): added a test for Emacs < 22. + (ebib-index-mode-map): removed 'ebib-index-mode-map argument to + make-keymap. Emacs officially doesn't even allow it, and in XEmacs + it's optional. + (ebib-entry-mode-map): same. + (ebib-strings-mode-map): same. + (ebib-help-mode-map): same. + (ebib-semicolon-map): new. + (ebib-index-mode-map): added ";" key. + (ebib-remove-entry-from-db): bug fix: would delete the key of the + current entry from the keys list, regardless of which entry was + actually deleted. + (ebib-semicolon-map): added "d" key. + (ebib-delete-marked-entries): new. + (ebib-entry-mode-map): bindings of C-x b and C-x k changed to + 'undefined. + (disabled): removed. The predefined function undefined does the + same thing. + +2007-03-13 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-filter-to-virtual-db): removed the check for the + `type' field. What was actually meant was the `type*' field, and + since this is not in ebib-unique-field-list anyway, the user isn't + able to filter on it. + +2007-03-12 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-mark-entry): added again for the 1.3 branch. + +2007-03-12 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el: ebib 1.2.0 released. + +2007-03-12 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-mark-entry): removed in preparation for release. + +2007-03-12 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-print-database): bugfix: if ebib-print-tempfile is + set to "", which is its default value, the body of if-str would + not be executed. + (ebib-latex-database): same. + +2007-03-10 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-latex-database): new. + (ebib-print-preamble): new. + (ebib-print-multiline): new. + (ebib-latex-preamble): new. + (ebib-print-tempfile): new. + (ebib-print-database): modified to use ebib-print-preamble, + ebib-print-multiline and ebib-print-tempfile. + (ebib-latex-database): added real-db to ebib-execute-when. + (ebib-timestamp-format): new. + (ebib-insert-entry): modified to use format-time-string and ebib-timestamp-format. + (ebib-format-entry): same. + (ebib-yank-field-contents): renamed from ebib-paste-field-contents. + +2007-03-08 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-print-database): new. + +2007-03-06 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-index-scroll-down): new. replaces ebib-entry-page-up. + (ebib-index-scroll-up): new. replaces ebib-entry-page-down. + (ebib-follow-crossref): new. + (ebib-index-mode-map): added "F" key. + +2007-03-02 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-delete-entry): removed optional argument + entry-key, as it wasn't used at all. + +2007-03-01 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-paste-field-contents): sets this-command to t if + called illegally. that way, a second consecutive call to this + function is also recognised as illegal. + +2007-02-26 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-paste-field-contents): doc string slightly expanded. + +2007-02-25 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-paste-field-contents): added test for crossref field. + (ebib-paste-field-contents): modified so that repeatedly calling + this command walks around the kill ring, just like C-y/M-y. + +2007-02-23 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-move-to-field): bug fix: if the field being moved + to is type*, used to search for 'type', causing confusion with an + actual type field (e.g. in the entry type incollection.) now just + moves to (point-min). + (ebib-set-modified): bug fix: the modification flag of the index + buffer would be (re)set, regardless of whether it actually holds + the database whose modification flag is being (re)set. + +2007-02-22 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-execute-when): changed so that it does not produce + a spurious and if the envs list of a form only contains one element. + +2007-02-21 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-print-filter): changed the argument of interactive + from "p" to "P", to obtain the raw prefix argument. + (ebib-save-current-database): changed message to error. + (ebib-print-filter): added a default-clause to ebib-execute-when, + to produce a beep. + (ebib-prev-entry): same. + (ebib-next-entry): same. + (ebib-add-entry): same. + (ebib-goto-first-entry): same. + (ebib-goto-last-entry): same. + (ebib-edit-keyname): same. + (ebib-mark-entry): same. + (ebib-entry-page-up): same. + (ebib-entry-page-down): same. + (ebib-write-database): same. + (ebib-delete-entry): same. + (ebib-select-entry): same. + (ebib-export-entry): same. + (ebib-search): same. + (ebib-search-next): same. + (ebib-edit-strings): same. + (ebib-edit-preamble): same. + (ebib-export-preamble): same. + (ebib-virtual-db-and): same. + (ebib-virtual-db-or): same. + (ebib-virtual-db-not): same. + +2007-02-20 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-filter-to-virtual-db): fixed a bug: the additional + fields weren't included in the collection. + (ebib-edit-field): spurious progn removed. + (ebib-execute-helper): wrapped in an eval-and-compile because + otherwise XEmacs complains that the symbol ebib-execute-helper's + value as function is void. + (safe-write-region): new. GNU Emacs has an optional argument to + write-region that can be used to make sure the user doesn't + inadvertently overwrite an already existing file. XEmacs does not + have this argument. + (ebib-write-database): modified to use safe-write-region. + (ebib-insertion-strings): changed the default value from nil to + '((1 . "\\cite{%s}")). + +2007-02-19 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-index-mode-map): changed binding for + ebib-merge-bibtex-file from "m" to "M". + (ebib-index-mode-map): added binding "m" for ebib-mark-entry. + (ebib-mark-entry): new. + (ebib-marked-face): new. needed to accommodate xemacs. there must + be a better way to do this... Note that in xemacs, i know of no + better way than to use '(face highlight) for both the overlay + marking the current entry and to mark selected entries. that means + that you cannot tell if the current entry is selected or not. gnu + emacs has highlight and :inverse-video. (though the former may be + obsoleted at some point?) + (ebib-fill-index-buffer): changed to accommodate xemacs. (see + comment in the source.) + (ebib-index-buffer-help): updated. + (ebib-execute-when): new. + (ebib-execute-helper): new. + (when-entries): removed. its functionality is now covered by + ebib-execute-when. + (ebib-write-database): modified to use ebib-execute-when and if-str. + (ebib-export-entry): modified to use ebib-execute-when. also added + a check to make sure that the goal database is not virtual. + (ebib-export-preamble): same. + (ebib-export-all-strings): added a check to make sure the goal + database is not virtual. + (ebib-export-string): same. + (ebib-prev-entry): modified to use ebib-execute-when. + (ebib-next-entry): same. + (ebib-add-entry): same. + (ebib-close-database): same. + (ebib-goto-first-entry): same. + (ebib-goto-last-entry): same. + (ebib-edit-entry): same. + (ebib-edit-keyname): same. + (ebib-entry-page-up): same. + (ebib-entry-page-down): same. + (ebib-save-database): same. + (ebib-save-current-database): same. + (ebib-delete-entry): same. + (ebib-remove-key-from-buffer): same. + (ebib-select-entry): same. + (ebib-search): same. + (ebib-search-next): same. + (ebib-edit-strings): same. + (ebib-edit-preamble): same. + (ebib-next-database): same. + (ebib-prev-database): same. + (ebib-virtual-db-and): same. + (ebib-virtual-db-or): same. + (ebib-virtual-db-not): same. + (ebib-print-filter): same. + +2007-02-19 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el: ebib-1.1.4 released. + +2007-02-19 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-filter-to-virtual-db): changed the collection to + contain strings rather than symbols, because xemacs requires that. + +2007-02-18 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (add-to-listq): new. introduced mainly because xemacs + doesn't allow the fourth argument to add-to-list. (actually, i'm + not sure if emacs 21.4 supports it...) + +2007-02-13 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-quit): set ebib-strings-highlight to nil. + +2007-02-11 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-unique-field-list): new. used for TAB-completion + in ebib-filter-to-virtual-db. + (ebib-set-entry-types-hash): modified to set + ebib-unique-field-list. + (ebib-key): modified to keep the cond statement out of the + expansion. + (ebib-create-new-database): modified to take an optional database + argument: if supplied, returns a copy of that database. + (ebib-index-mode-map): added "&", "|", "~" and "V". + (ebib-virtual-db-and): new. + (ebib-virtual-db-or): new. + (ebib-virtual-db-not): new. + (ebib-filter-to-virtual-db): new. + (ebib-create-virtual-db): new. + (contains): new. + (ebib-run-filter): new. + (ebib-print-filter): new. + (ebib-write-database): modified to handle virtual databases. + (ebib-edit-entry): modified to exclude virtual databases. + (ebib-edit-keyname): same. + (ebib-save-current-database): same. + (ebib-save-database): same. + (ebib-merge-bibtex-file): same + (ebib-add-entry): same. + (ebib-delete-entry): same. + (ebib-export-entry): same. + (ebib-edit-strings): same. + (ebib-edit-preamble): same. + (ebib-export-preamble): same. + (ebib-import): same. + (ebib-fill-entry-buffer): modified so that it does not result in + an error if the current entry does not exist. This is needed in + case the user deletes an entry from a database that has a virtual + database that containe that entry. + (ebib-format-entry): put (eq key 'timestamp) first in the and + clause. no need to check timestamp and ebib-use-timestamp for any + other field. + (ebib-write-database): modified so that when a virtual database is + written to a file, it doesn't attempt to put an entry that is + still in a virtual database's keys-list but has been deleted in + the source database into the new database. (note: this is still + not the proper way to handle this. we need to find a clean way to + handle the consequences of an entry being deleted in a source + database.) + +2007-02-10 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (when-entries): included a declare indent statement. + (with-buffer-writable): same. + (edb): added fields `name' and `virtual'. + (ebib-fill-index-buffer): modified to use edb-name. + (ebib-load-bibtex-file): same. + (ebib-write-database): same. + (ebib-search-in-entry): added optional field argument. + +2007-02-04 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-goto-next-set): adapted to make use of + ebib-move-to-field. + (ebib-goto-prev-set): same. + (defentry): removed. + (ebib-preload): removed. + (ebib-additional-fields): removed. + (ebib-insert-entry): modified to insert a timestamp, depending on + the argument TIMESTAMP and on the setting of EBIB-USE-TIMESTAMP. + (ebib-add-entry): modified: it no longer adds a timestamp + itself (as it did after the change two days ago) but just requests + ebib-insert-entry to do so. + (ebib-read-entry): modified to request insertion of a timestamp. + (ebib-edit-keyname): modified so as to explicitly NOT insert a + timestamp. + (ebib-export-entry): modified so as to request insertion of a + timestamp, both when exporting to another database and to a file. + (ebib-find-bibtex-entries): modified: timestamp argument + added. This argument is simply passed on to ebib-read-entry. + (ebib-load-bibtex-file): modified so that no timestamp is inserted + into the entries read from file. + (ebib-import): modified to request insertion of a timestamp. + (ebib-format-entry): modified to insert a timestamp if required. + (ebib-export-entry): fixed a bug that kept ebib-export-filename + from being set. + (ebib-export-preamble): same. + +2007-02-03 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-format-fields): modified to check if hidden fields + should be shown. + (ebib-init): added a line to make timestamp a hidden field. + (ebib-hide-hidden-fields): new. + (ebib-toggle-hidden): new. + (ebib-move-to-field): new. + (ebib-find-visible-field): new. + (ebib-prev-field): rewritten to make use of ebib-move-to-field. + (ebib-next-field): same. + (ebib-goto-first-field): same. + (ebib-goto-last-field): same. + +2007-02-02 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-use-timestamp): new. + (ebib-add-entry): modified so that it adds a timestamp if + ebib-use-timestamp is set. + +2007-01-23 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-keys-window-size): new. + (ebib): modified to use ebib-keys-window-size. + (ebib-entry-page-up): same. + (ebib-entry-page-down): same. + (ebib-customize): new. + (ebib-index-mode-map): added "C" key command. + +2007-01-10 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib): added :prefix tag to defgroup. + +2006-12-17 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-export-preamble): bug (no message being given + after exporting the preamble) fixed. + +2006-12-13 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el: Ebib 0.28 released. + +2006-12-12 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-edit-crossref): fixed a bug that caused + ebib-set-modified not to be executed. + (ebib-set-modified): fixed. save-excursion should not be part of + the body of UNLESS. + (ebib-quit): ebib-default-type no longer set to nil. (quiting and + restarting ebib would leave it set to nil.) + (ebib-save-xrefs-first): new. + (ebib-compare-xrefs): new. + (ebib-format-database): modified to put crossreferencing entries + first. + +2006-11-13 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el: Ebib 0.27 released. + +2006-11-01 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-paste-field-contents): combined two nested if's + into one or'ed. + +2006-10-30 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-format-database): added argument db. + (ebib-format-strings): added argument db. + (ebib-sort-order): new. + (ebib-entry<): new. + (ebib-get-sortstring): new. + (ebib-insertion-strings): changed to an alist, so that multiple + insertion strings can be defined. + (ebib-insert-bibtex-key): modified to use the new ebib-insertion-strings. + +2006-10-24 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-insert-bibtex-key): changed to use a customisable + insertion string. + (ebib-insertion-string): new. + +2006-10-23 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el: Ebib 0.26 released. + +2006-10-23 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-set-entry-types-hash): new, to make customising + the entry types through the customisation buffer possible. + (defentry): modified, so that an entry defined with defentry is + also added to the list ebib-entry-types. + (ebib-additional-fields): renamed from ebib-ign-fields; modified + to check whether a field is already in the list before it is + added, so that it is not added twice when Ebib is closed and + restarted in the same Emacs session. + (ebib-find-bibtex-entries): added modify-syntax-entry, so that + users can type (e.g.) "o to create umlaut-o. + (ebib-format-database): use mapc on edb-keys-list rather than + maphash on edb-database, so that the entries are saved in + alphabetical order. (Following a suggestion of Thomas Schmitz.) + +2006-10-14 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el: added customisation group ebib. + +2006-10-01 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-remove-key-from-buffer): added when-entries, to + get rid of an error message when the last entry is deleted. + (ebib-find-end-of-field): fixed a nasty bug that occurred when + reading a .bib-file with an entry in which the last field is raw + and is immediately followed by the closing brace. Thanks to Thomas + Schmitz for bringing this to my attention. + +2006-09-14 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-ign-fields): code, uri and location removed. + +2006-08-29 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-find-bibtex-entries): changed to return a list of + the number of entries and number of strings found, and a boolean + for whether a preamble was found. + (ebib-load-bibtex-file): adapted to accept the new return value of + ebib-find-bibtex-entries. + (ebib-merge-bibtex-file): same. + (ebib-import): added. + +2006-08-28 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-import): added. + +2006-08-25 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el: rearranged some of the variable definitions, so that + the entry types can be defined in ebib.el rather than in .ebibrc. + (ebib-index-mode-map): put the key definitions back in. + (ebib-entry-mode-map): same. + (ebib-strings-mode-map): same. + +2006-08-18 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib): renamed the keys buffer to index buffer and the + fields buffer to entry buffer. + (ebib-key): new. to enable customisation of the command keys + through .ebibrc. + (ebib-index-mode-map): moved key definitions to .ebibrc. + (ebib-entry-mode-map): same. + (ebib-strings-mode-map): same. + +2006-08-17 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-add-entry): rewrote to use ebib-insert-entry. + +2006-08-15 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-delete-entry): split into three functions. + (ebib-remove-key-from-buffer): split off from ebib-delete-entry. + (ebib-remove-entry-from-db): split off from ebib-delete-entry. + (ebib-edit-keyname): new. because it partially does the same as + ebib-delete-entry, i split up the latter. + +2006-08-13 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-edit-field): added special clause for the annote + field, so that the user is dropped into the multiline edit buffer. + +2005-11-18 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-read-string): changed so that it does not store + the braces or quotes surrounding the string. + (ebib-match-quote-forward): added a check to make sure that when a + double quote is found at the search limit, this isn't mistakenly + taken as the matching quote if it is escaped by a backslash. + +2005-11-17 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-fields-mode-map): bound C-x k to + ebib-quit-fields-buffer. + (ebib-strings-mode-map): bound C-x b to ebib-lower, and C-x k to + ebib-quit-strings-buffer. + +2005-11-05 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-load-bibtex-file): use file-readable-p instead of + file-exits-p. + +2005-11-04 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-format-fields): new. formats the fields and calls + a function to output them. + (ebib-fill-fields-buffer): moved the actual formatting and + printing code to ebib-format-fields. + (ensure-extension): new. make sure a filename has a specific + extension. + (ebib-load-bibtex-file): changed to use ensure-extension. + (remove-from-string): changed to function. + (symbol-or-string): same. + (ebib-extract-bibfile): new. looks for a \bibliography command in + the current buffer and reads its filename. + (ebib-get-db-from-filename): new. retrieve a bibtex database based + on filename. + (ebib-get-local-database): new. finds a database to associate with + the LaTeX file in the current buffer. + (ebib-insert-bibtex-key): removed option to use a prefix + argument. instead uses ebib-get-local-database to select a + database to get the keys from. + (ebib-entry-summary): new. reads the key at point and displays its + entry in a *Help* buffer. + +2005-11-03 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-prefix): changed to function. + (next-elem): same. + (prev-elem): same. + (ebib-get-obl-fields): same. + (ebib-get-opt-fields): same. + +2005-11-02 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (when-entries): new. execute BODY when there is a + database open and it contains entries. + (ebib-prev-entry): test whether there are entries in the current + database. + (ebib-next-entry): same. + (ebib-prev-entry): test whether there are entries in the current + database. + (ebib-next-entry): same. + (ebib-goto-first-entry): same. + (ebib-goto-last-entry): same. + (ebib-edit-entry): same. + (ebib-entry-page-up): same. + (ebib-entry-page-down): same. + (ebib-delete-entry): same. + (ebib-select-entry): same. + (ebib-export-entry): same. + (ebib-search-next): same. + (ebib-edit-strings): test whether a database is open. + (ebib-edit-preamble): same. + (ebib-search): test whether there are entries in the current + database, and ask for search string inside the function, rather + than in (interactive). + (ebib-export-preamble): test whether a database is open. + (ebib-next-database): same. + (ebib-prev-database): same. + (disabled): new. does nothing except beep. used to disable C-x k + and C-x b in the fields and strings buffers. + +2005-11-02 Steve Youngs <steve@sxemacs.org> + + * ebib.el (ebib-init): Don't do anything with `ebib-keys-mode-map' + here. + (ebib-initial-keys-map): Removed. + (ebib-full-keys-map): Removed. + (ebib-keys-mode-map): Merge them into here. + (ebib-load-bibtex-file): Don't do anything with + `ebib-keys-mode-map' here. + (ebib-close-database): Ditto. + (ebib-fill-keys-buffer): Ditto. + (ebib-switch-to-database-nth): Make it compatible with + GNU/Emacs. + +2005-11-02 Joost Kremers <joostkremers@yahoo.com> + + * ebib.el (ebib-keys-mode): added C-x k and C-x b redefinitions + to ebib-initial-keys-map. + (ebib-fields-mode): same. + (ebib-strings-mode): same. + (ebib-t): removed. + +2005-11-02 Steve Youngs <steve@sxemacs.org> + + * ebib.el (ebib-init): Copy the "initial keys" keymap into + `ebib-keys-mode-map'. + (ebib-initial-keys-map): Define all the keys inside the variable + definition instead of at top level. + (ebib-full-keys-map): Ditto. Also make this keymap's parent be + `ebib-initial-keys-map' to save on double defining some keys. + (ebib-switch-to-database-nth): New. Convenience function for + switching between databases. + (ebib-fill-keys-buffer): Set the local keymap to `ebib-keys-mode-map'. + (ebib-load-bibtex-file): Copy the "full keys" keymap into + `ebib-keys-mode-map'. + (ebib-close-database): Copy the "initial keys" keymap into + `ebib-keys-mode-map' and reset the local map. + (ebib-fields-mode-map): Define the keys in the variable definition + instead of at top level. + (ebib-strings-mode-map): Ditto. + (ebib-help-mode-map): Ditto. + diff --git a/biblio/bibtex/utils/ebib/INSTALL b/biblio/bibtex/utils/ebib/INSTALL new file mode 100644 index 0000000000..fc6e755b9d --- /dev/null +++ b/biblio/bibtex/utils/ebib/INSTALL @@ -0,0 +1 @@ +For installation instructions, see the Ebib manual. diff --git a/biblio/bibtex/utils/ebib/README b/biblio/bibtex/utils/ebib/README new file mode 100644 index 0000000000..00ad31d814 --- /dev/null +++ b/biblio/bibtex/utils/ebib/README @@ -0,0 +1,14 @@ +Ebib + +(c) 2003-2008 Joost Kremers + +Ebib is a BibTeX database manager that runs in GNU Emacs and +XEmacs. With Ebib, you can create and manage .bib-files, all within +Emacs. It supports @string and @preamble definitions, multi-line field +values, searching, and integration with Emacs' (La)TeX mode. + +See the Ebib manual for usage and installation instructions. + +The latest release version of Ebib, contact information and mailing list +can be found at <http://ebib.sourceforge.net>. Development sources can be +found at <http://repo.or.cz/w/ebib.git>. diff --git a/biblio/bibtex/utils/ebib/VERSION b/biblio/bibtex/utils/ebib/VERSION new file mode 100644 index 0000000000..27f9cd322b --- /dev/null +++ b/biblio/bibtex/utils/ebib/VERSION @@ -0,0 +1 @@ +1.8.0 diff --git a/biblio/bibtex/utils/ebib/doc/ebib-manual.pdf b/biblio/bibtex/utils/ebib/doc/ebib-manual.pdf Binary files differnew file mode 100644 index 0000000000..cd8fa80dcf --- /dev/null +++ b/biblio/bibtex/utils/ebib/doc/ebib-manual.pdf diff --git a/biblio/bibtex/utils/ebib/doc/html/ebib-manual.css b/biblio/bibtex/utils/ebib/doc/html/ebib-manual.css new file mode 100644 index 0000000000..cf8e846b62 --- /dev/null +++ b/biblio/bibtex/utils/ebib/doc/html/ebib-manual.css @@ -0,0 +1,61 @@ +body { + font-family: Verdana, "Bitstream Vera Sans", sans-serif; + background-color: #c9c9c9; + color: #33333A; +} + +a { + text-decoration: none; + color: #533333; + font-weight: bold; +} + +a:hover { + text-decoration: none; + color: #cf1212; +} + +h1 { + text-align: center +} + +img { + border: 0; +} + +#main { + position: absolute; +/* margin-right: 20%; */ + margin-left: 50px; + top: 100px; + text-align: justify; + width: 600px; +} + +#menu { + position: absolute; +/* margin-left: 78%; */ + margin-left: 710px; + top: 120px; + width: 250px; + background-color: #a01c1c; + height: 740px; + padding: 10px; + color: #c9c9c9; +} + +#menu a { + text-decoration: none; + color: #ffa71d; +} + +#menu a:hover { + text-decoration: none; + color: #ffdf20; +} + +.bottom-dweller { + width: 100%; + position: absolute; + bottom: 0%; +} diff --git a/biblio/bibtex/utils/ebib/doc/html/ebib-manual.html b/biblio/bibtex/utils/ebib/doc/html/ebib-manual.html new file mode 100644 index 0000000000..a5ba2de5b4 --- /dev/null +++ b/biblio/bibtex/utils/ebib/doc/html/ebib-manual.html @@ -0,0 +1,2224 @@ +<?xml version="1.0" encoding="iso-8859-1"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <title>Ebib Manual</title> + <meta name="generator" content="muse.el" /> + <meta http-equiv="Content-Type" + content="text/html; charset=iso-8859-1" /> + <link rel="stylesheet" type="text/css" media="screen" href="ebib-manual.css" /> + </head> + <body> + <h1>Ebib Manual</h1> + <!-- Page published by Emacs Muse begins here --> +<div id="menu"> + +<div class="contents"> +<dl> +<dt> +<a href="#sec1">Installation</a> +</dt> +<dt> +<a href="#sec2">Basic Usage</a> +</dt> +<dd> +<dl> +<dt> +<a href="#sec3">Getting Started</a> +</dt> +<dt> +<a href="#sec4">Editing the Database</a> +</dt> +<dt> +<a href="#sec5">Saving a Database</a> +</dt> +<dt> +<a href="#sec6">Searching</a> +</dt> +<dt> +<a href="#sec7">LaTeX Integration</a> +</dt> +<dt> +<a href="#sec8">Cross-referencing</a> +</dt> +<dt> +<a href="#sec9">Printing the Database</a> +</dt> +<dt> +<a href="#sec10">Marking Entries</a> +</dt> +<dt> +<a href="#sec11">Calling a Browser</a> +</dt> +<dt> +<a href="#sec12">Viewing Files</a> +</dt> +</dl> +</dd> +<dt> +<a href="#sec13">Advanced Features</a> +</dt> +<dd> +<dl> +<dt> +<a href="#sec14">Screen Layout</a> +</dt> +<dt> +<a href="#sec15">Preloading <code>.bib</code> Files</a> +</dt> +<dt> +<a href="#sec16"><code>@Preamble</code> Definition</a> +</dt> +<dt> +<a href="#sec17"><code>@String</code> Definitions</a> +</dt> +<dt> +<a href="#sec18">Sorting the <code>.bib</code> file</a> +</dt> +<dt> +<a href="#sec19">Merging and Importing</a> +</dt> +<dt> +<a href="#sec20">Exporting Entries</a> +</dt> +<dt> +<a href="#sec21">Timestamps</a> +</dt> +<dt> +<a href="#sec22">Multiple Identical Fields</a> +</dt> +<dt> +<a href="#sec23">Virtual Databases</a> +</dt> +<dt> +<a href="#sec24">The Multiline Edit Buffer</a> +</dt> +</dl> +</dd> +<dt> +<a href="#sec25">The Ebib Buffers</a> +</dt> +<dd> +<dl> +<dt> +<a href="#sec26">The Index Buffer</a> +</dt> +<dt> +<a href="#sec27">The Entry Buffer</a> +</dt> +<dt> +<a href="#sec28">The Strings Buffer</a> +</dt> +</dl> +</dd> +<dt> +<a href="#sec29">Customisation</a> +</dt> +<dd> +<dl> +<dt> +<a href="#sec30">The Customisation Buffer</a> +</dt> +<dt> +<a href="#sec31">Modifying Key Bindings</a> +</dt> +</dl> +</dd> +</dl> +</div> + + +</div> + +<div id="main"> + +<p>Ebib is a program with which you can manage BibTeX database files without +having to edit the raw <code>.bib</code> files. It runs in GNU/Emacs, version 21.1 or +higher (lower versions are not supported) and XEmacs (at least from version +21.4; lower version have not been tested, but may work.)</p> + +<p>It should be noted that Ebib is <em>not</em> a minor or major mode for editing +BibTeX files. It is a program in itself, which just happens to make use of +Emacs as a working environment, in the same way that for example Gnus is.</p> + +<p>The advantage of having a BibTeX database manager inside Emacs is that X is +no longer required, as Emacs can run on the console, and also that some +integration with Emacs' TeX and LaTeX modes becomes possible. For example, +you can push a BibTeX key from Ebib to a LaTeX buffer, or, vice versa, when +you're in a LaTeX buffer, you can consult your BibTeX database and insert a +key from it into the document. Another advantage of Ebib is that it is +completely controlled by key commands: no stressful mouse movements are +required, as with most other (usually X-based) BibTeX database managers.</p> + + +<h2><a name="sec1" id="sec1"></a> +Installation</h2> + +<p class="first">To install Ebib, so that it will be loaded automatically when Emacs is +started, simply copy the file <code>ebib.el</code> to somewhere in your load path and +add the following line to Emacs' init file (<code>~/.emacs</code> for GNU/Emacs, +<code>~/.xemacs/init.el</code> for XEmacs):</p> + +<pre class="example"> +(autoload 'ebib "ebib" "Ebib, a BibTeX database manager." t) +</pre> + +<p>Note: if you do not know what your load path is set to, go to the <code>*scratch*</code> +buffer, type <code>load-path</code> on an empty line, put the cursor right after it and +type <code>C-j</code>. The value of <code>load-path</code> will then appear in the buffer.</p> + +<p>When Ebib is loaded, you can run it with <code>M-x ebib</code>. This command is also +used to return to Ebib when you have put the program in the background. You +can bind this command to a key sequence by putting something like the +following in Emacs' init file:</p> + +<pre class="example"> +(global-set-key "\C-ce" 'ebib) +</pre> + +<p>You can of course choose any key combination you like. (In Emacs, key +combinations of <code>C-c <letter></code> are reserved for the user, so that no package +may set them.)</p> + +<p>It is recommended to byte-compile the source, Ebib runs quite a lot faster +when it is byte-compiled. You can do this either within Emacs with <code>M-x +byte-compile-file</code>, or from your shell by going into the directory where you +put <code>ebib.el</code> and typing:</p> + +<pre class="example"> +emacs -batch -f batch-byte-compile ebib.el +</pre> + +<p>(Substitute <code>emacs</code> with <code>xemacs</code> if you use XEmacs.) This will create a file +<code>ebib.elc</code>, which Emacs will load instead of <code>ebib.el</code>. Byte-compiling Ebib may +produce a warning about functions that are ``not known to be +defined''. This can be safely ignored. GNU Emacs and XEmacs have some small +differences, and the functions reported in this warning are those used by +the other version. Ebib makes sure that the correct functions are called.</p> + + + + +<h2><a name="sec2" id="sec2"></a> +Basic Usage</h2> + +<p class="first">A BibTeX database is somewhat of a free-form database. A BibTeX entry +consists of a set of field-value pairs. Furthermore, each entry is known by +a unique key. The way that Ebib navigates this database is by having two +windows, one that contains a list of all the entry keys in the database, +and one that contains the fields and values of the currently highlighted +entry.</p> + +<p>When Ebib is started, the current windows in Emacs are hidden and the Emacs +frame is divided into two windows. The top one contains a buffer that is +called the <em>index buffer</em>, while the lower window contains the <em>entry +buffer</em>. When a database is loaded, the index buffer holds a list of all the +keys in the database. You can move through these keys with the cursor +keys. In the entry buffer, the fields of the currently highlighted entry +are shown, with their values.</p> + +<p>In this chapter, all basic functions of Ebib are described, so that you can +get startet with it. At times, reference will be made to later chapters, +where more specific functions are described.</p> + + + +<h3><a name="sec3" id="sec3"></a> +Getting Started</h3> + +<p class="first">Ebib is started with the command <code>M-x ebib</code>. Entering this command hides all +the windows in the current Emacs frame and replaces them with two windows: +the top one contains the index buffer, the bottom one, taking up the larger +part of the screen, contains the entry buffer. The index buffer is named +<code>none</code>, to indicate that no database has been loaded. If you open a database, +or start a new one, the index buffer will carry its name.</p> + +<p>You can quit Ebib by typing <code>q</code>. You will be asked for confirmation, and you +will receive a warning if you happen to have an unsaved database. The +command <code>z</code> can also be used to leave Ebib. However, unlike <code>q</code>, which +completely quits Ebib, <code>z</code> only lowers it, so that it remains active in the +background. The <code>.bib</code> files that you have opened remain loaded, and you can +return to them by typing <code>M-x ebib</code> again.</p> + + +<h4>Opening a <code>.bib</code> file</h4> + +<p class="first">Loading a <code>.bib</code> file into Ebib is done with the command <code>o</code>. Ebib reads the +file that you specify, and reports how many entries it found, how many +<code>@string</code> definitions it found, and whether a <code>@preamble</code> was found. Note that +when Ebib reads a <code>.bib</code> file, it only reads entry types (e.g. <code>book, article, +phdthesis</code> etc.) that it knows about. Fields (e.g. <code>author, title, year</code> etc.) +that Ebib does not know about, are loaded (and saved) but not displayed, so +they cannot be edited. Therefore, you should make sure that all the entry +types and fields that your databases use are defined. A sensible set has +been predefined, so that anyone who's using standard BibTeX entry types +should have no problem loading an existing <code>.bib</code> file into Ebib. If, +however, you have custom entry types, or custom fields in your <code>.bib</code> files, +you should read the chapter on customising Ebib to learn how to define +them, so that Ebib knows about them. (See <a href="#entry-types">Entry types</a>.)</p> + +<p>Every time Ebib reads a <code>.bib</code> file, it produces a few log messages. These +are written into a special buffer <code>*Ebib-log*</code>. If Ebib encounters entry +types in the <code>.bib</code> file that it doesn't know, it will log a warning. If Ebib +finds something that it believes to be incorrect, an error will be +logged. If any warnings or errors occur while loading the <code>.bib</code> file, Ebib +tells you so after loading the file. To view the log file, press <code>l</code> in the +index buffer.</p> + +<p>Note that even if it detects warnings or errors, Ebib will try to continue +parsing the rest of the <code>.bib</code> file. That means that normally, only the entry +in which an error occurs is not read. Entries occurring after the +problematic one are read.</p> + + + +<h4>Navigating a <code>.bib</code> file</h4> + +<p class="first">Once you've opened a <code>.bib</code> file, the keys of all the entries in the file are +shown in alphabetical order in the index buffer in the top Ebib window. (In +fact, it is possible to show more than just the entry key in this +buffer. See <a href="#index-display-fields">Index Display Fields</a> on how to accomplish this.) The first +entry is highlighted, meaning it is the current entry. The fields it holds +and their values are shown in the entry buffer in the bottom Ebib +window. The first field is the type field, which tells you what kind of +entry you're dealing with (i.e. <code>book, article</code>, etc.).</p> + +<p>Below the type field, Ebib displays (up to) three sets of fields. The first +set are the so-called obligatory fields, the fields that BibTeX requires to +be filled. The second group are the optional fields, which do not have to +be filled but which BibTeX will normally add to the bibliography if they do +have a value. The third group are the so-called additional fields. These +fields are usually ignored by BibTeX (note that BibTeX normally ignores +<em>all</em> fields it does not know), although there are bibliography styles that +treat some of these fields as optional rather than as additional; (i.e., +the <code>harvard</code> styles do typeset the <code>url</code> field, if present.)</p> + +<p>The first two groups of fields are different for each entry type, while the +third group are common to all entry types. You can use the additional +fields, for example, to add personal comments to the works in your +database. Ebib by default defines the following additional fields: +<code>crossref, url, annote, abstract, keywords, file</code> and <code>timestamp</code>. If these are +not sufficient for you, you need to customise Ebib and add your own +fields. (See <a href="#additional-fields">Additional Fields</a>, if you need to find out how to do that.)</p> + +<p>To move around in the index buffer, you can use the <code>up</code> and <code>down</code> cursor +keys, <code>C-p</code> and <code>C-n</code>, or for those more used to mutt's key bindings, <code>k</code> and +<code>j</code>. Furthermore, <code>Space</code> and <code>PgDn</code> move a screenful of entries down, while <code>b</code> +and <code>PgUp</code> move in the other direction. Lastly, <code>g</code> and <code>Home</code> move to the first +entry, while <code>G</code> and <code>End</code> move to the last one.</p> + +<p>Ebib is not restricted to opening just one <code>.bib</code> file at a time. You can +open more files by just typing <code>o</code> again and entering the filename. Ebib +numbers the databases: the number of each database is shown in the mode +line of the index buffer, directly before the database name. The keys 1—9 +provide a quick way of jumping from one database to another. Note that the +numbering is dynamic: if you have three databases opened and then close the +second, database 3 becomes database 2.</p> + +<p>With the <code>left</code> and <code>right</code> cursor keys, you can move to the previous or next +database. These keys wrap, so if you hit the <code>left</code> cursor key while the +first database is active, you move to the last database. If you are done +with a database and want to close it, type <code>c</code>. This closes the current +database. It does not leave Ebib, and all other databases you have open +will remain so.</p> + + + +<h4>Starting a New <code>.bib</code> File</h4> + +<p class="first">If you want to start a new <code>.bib</code> file from scratch, you cannot just go and +enter entries. You first have to give the database a name. So, to start a +new database, type <code>o</code> first, and give the new file a name. Once you have +done this, you can start adding entries to the database.</p> + + + + +<h3><a name="sec4" id="sec4"></a> +Editing the Database</h3> + +<p class="first">Of course, being able to open and view <code>.bib</code> files is only half the fun. One +needs to be able to edit the files as well. Ebib's essential editing +facilities are discussed here.</p> + + +<h4>Adding and Deleting Entries</h4> + +<p class="first">To add an entry to a database, you type <code>a</code>. When you do this, Ebib first +asks you for an entry key, as every entry must be identified by a unique +key. Just type a name for the new entry (say <code>jones1998</code>). Since the entry +key must be unique, Ebib will complain if you enter a key that already +exists.</p> + +<p>Note that if you should later decide that you want to change the key of an +entry, you can do so with the command <code>E</code>. So if you have an entry with the +key <code>jones1998</code> and you want to add another entry by Jones from 1998, you can +call the new one <code>jones1998b</code> and rename the existing one to <code>jones1998a</code>.</p> + +<p>Deleting an entry is done with <code>d</code>. Be careful with this: you will be asked +for confirmation, but once you've confirmed, the entry is gone, and it is +not possible to bring it back. There is no undo in Ebib. (If you haven't +saved the database yet, it is still possible to retrieve the deleted entry +from the <code>.bib</code> file, and otherwise it may still be in the backup file that +Ebib creates. See <a href="#saving-database">Saving a Database</a>.)</p> + + + +<h4>Editing Fields Values</h4> + +<p class="first">Editing the field values for an entry is done in the lower of the two Ebib +buffers, the so-called entry buffer. You can move focus to the entry buffer +by typing the command <code>e</code> in the index buffer.</p> + +<p>You can move between fields with the same keys that you use to move between +entries in the index buffer: the cursor keys <code>up</code> and <code>down</code>, <code>C-p</code> and <code>C-n</code>, or <code>j</code> +and <code>k</code>. <code>Space</code> and <code>PgDn</code> move to the next set of fields, while <code>PgUp</code> and <code>b</code> move +to the previous set of fields. <code>g</code> and <code>G</code>, and <code>Home</code> and <code>End</code> also work as +expected.</p> + +<p>Editing a field value can be done with <code>e</code>. For most fields, Ebib simply asks +you for a string value in the minibuffer. (Here, <code>RET</code> confirms the edit, +while <code>C-g</code> cancels it.) Although BibTeX requires that field values be +surrounded by braces {} (or double quotes "", but Ebib does not use those, +even though it can of course handle them when they are used in an existing +<code>.bib</code> file) you do not need to type these. Ebib adds them when it saves the +<code>.bib</code> file.</p> + +<p>Some fields, however, are handled in a special way. The first of these is +the <code>type</code> field: if you edit this field, you must enter one of the +predefined entry types. Ebib won't allow you to enter anything else. You +can use tab-completion in this case. Similarly, if you edit the <code>crossref</code> +field, Ebib requires that you fill in a key from the database. Here, too, +you can use tab-completion.</p> + +<p>Note that if you're adding a new entry, Ebib automatically puts you in the +entry buffer after you've typed the entry key: you don't have to type <code>e</code> to +move to the entry buffer. When creating a new entry, it is best to set the +<code>type</code> field first, because the <code>type</code> field determines which other fields are +available for an entry.</p> + +<p>Note also that after editing a field, Ebib (usually) puts you on the next +field. This is convenient if you're creating a new entry and need to fill +out several fields in a row.</p> + +<p>If you're done editing the fields of the entry, type <code>q</code> to move focus back +to the index buffer. (Note: keys may have different functions in the index +buffer and the entry buffer. <code>q</code> is a typical example: in the entry buffer, +it quits editing the entry and moves focus back to the index buffer. In the +index buffer, however, <code>q</code> quits Ebib.)</p> + + + +<h4>Editing Multiline Values</h4> + +<p class="first">Apart from the <code>type</code> and <code>crossref</code> field, there is another field that Ebib +handles in a special way when you edit its value. This is the <code>annote</code> +field. Most field values normally consist of a single line of +text. However, because the <code>annote</code> field is meant for creating annotated +bibliographies, it would not be very useful if you could only write one +line of text in this field. Therefore, when you edit the <code>annote</code> field, Ebib +puts you in the so-called <em>multiline edit buffer</em>. This is essentially a text +mode buffer that allows you to enter as much text as you like. To store the +text and leave the multiline edit buffer, type <code>C-x b</code>. (This is of course +the standard Emacs command to switch buffers. It is redefined in Ebib's +multiline edit buffer.)</p> + +<p>If you want to leave the multiline edit buffer without saving the text you +have just typed, you can use the command <code>C-x k</code>. This too is redefined in +the multiline edit buffer: it leaves the multiline edit buffer (and hides +it), but it does not actually kill the buffer.</p> + +<p>Multiline values are not restricted to the <code>annote</code> field. Any field can in +fact hold a multiline value. (Except of course the <code>type</code> and <code>crossref</code> +fields.) To give a field a multiline value, use <code>l</code> instead of <code>e</code>. You will +again be put in the multiline edit buffer, where you can edit the +value. Note that you can use <code>l</code> even if a field already has a single line +value. Ebib will just make that the first line in the multiline edit +buffer.</p> + +<p>When a field has a multiline value, only the first line is shown in the +entry buffer, for space reasons. To indicate that the value is multiline, a +plus sign <code>+</code> is placed in front of the value.</p> + +<p>By the way, the <code>e</code> key is smart about the way an entry must be edited. If +you press <code>e</code> on a field that already has a multiline value, regardless of +the fact whether it is the <code>annote</code> field or not, Ebib puts you in the +multiline edit buffer. Therefore, you need <code>l</code> only if you want to give a +field a multiline value when it doesn't have one yet.</p> + +<p>For more details on working with the multiline edit buffer, see +<a href="#multiline-edit-buffer">The Multiline Edit Buffer</a>.</p> + + + +<h4>Copy, cut, paste (yank), and delete</h4> + +<p class="first">A few more commands are available when you're in the entry buffer editing +field values. The commands <code>c</code>, <code>x</code> and <code>y</code> implement a copy and paste system: <code>c</code> +copies the contents of the current field to the kill ring, <code>x</code> kills the +contents of the current field to the kill ring, and <code>y</code> yanks (pastes) the +most recently killed text in the kill ring. You can type <code>y</code> repeatedly to +get the same effect you get in Emacs when you type <code>M-y</code> after an initial +<code>C-y</code>: every additional use of <code>y</code> moves back in the kill ring.</p> + +<p>Lastly, there is the command <code>d</code>, which deletes the contents of the current +field, without asking questions and without storing the text in the kill +ring.</p> + +<p>Note that <code>y</code> only works when the current field does not have a value +yet. This is to prevent you from accidentally overwriting a field value. If +you do want to yank text into a field that already has a value, simply hit +<code>d</code> first to delete the text.</p> + + + + +<h3><a name="sec5" id="sec5"></a> +Saving a Database</h3> + +<p><a name="saving-database" id="saving-database"></a> +When you have undertaken any kind of editing action on a database, it is +marked as modified, which is indicated in the mode line for the index +buffer. A modified database can be saved by typing <code>s</code>. This saves the +database to the file it was loaded from without asking for +confirmation. (It is similar to <code>C-x C-s</code> in Emacs.) If you're saving a file +for the first time after loading it, Ebib creates a backup file under the +same name appended with a tilde: <code><filename>.bib~</code>.</p> + +<p>If you have multiple databases open, have made changes in more than one of +them, and want to save all of them without going through each yourself, you +can use <code>S</code>. (That's a capital <code>S</code>.) This command saves all modified databases.</p> + +<p>Another way to save a database is to use the command <code>w</code>. Use this if you +want to write the database to another file than the one it was loaded +from. Ebib will ask you for a filename to save to, and will of course warn +you if that file happens to exist already. Note that this command is +similar to <code>C-x C-w</code> in Emacs, so that after using it, the new <code>.bib</code> file +becomes associated with the database.</p> + + + +<h3><a name="sec6" id="sec6"></a> +Searching</h3> + +<p><a name="searching" id="searching"></a> +Ebib provides several search methods. First, if you are in the index +buffer, the normal Emacs incremental searches, <code>C-s</code> and <code>C-r</code>, function as +expected. You can use them to search entry keys. Note that once you've +found the key you're searching, you must hit <code>ENTER</code> to make it active. Ebib +does not update the entry buffer during incremental search, as this would +be rather pointless: you're only interested in the entry you're searching +for, not in the entries you pass along the way.</p> + +<p>Of course, it is also possible to search the database itself. If you type +<code>/</code>, Ebib asks you for a search term. This can be a regular expression, to +allow for flexibility in searching. After hitting <code>ENTER</code>, Ebib will start +searching the database (starting from the current entry, <em>not</em> from the first +entry!) and will display the entry with the first occurrence of the search +string that it finds. All the occurrences of the search string in that +entry are highlighted.</p> + +<p>Ebib searches all the fields of each entry. It is not possible with <code>/</code> to +specify the fields to search. Note that if the search term is found in a +field with a multiline value, Ebib will highlight the <code>+</code> sign that it +displays in front of the field value. Keep an eye out for this when doing a +search, because Ebib only shows the first line of multiline values, and if +the search term appears in another line, the highlighted <code>+</code> is the only +indication that the search term was found. (Well, that and the fact that +Ebib does <em>not</em> say <code>Search string not found</code>, of course...)</p> + +<p>A search term may of course appear more than once in the database. To +search for the next occurrence, type <code>n</code>. This will continue searching for +the search string in the rest of the database. Again, the first entry found +to contain the search string is displayed. Note that <code>n</code> does not wrap: if +the end of the database is reached, Ebib stops searching. To continue +searching from the top, hit <code>g</code> and then <code>n</code>.</p> + +<p>The functions described here form Ebib's basic search functionality. Ebib +also has a much more powerful search mechanism in the form of <em>virtual +databases</em>. These are described later. (See <a href="#virtual-databases">Virtual Databases</a>.)</p> + + + +<h3><a name="sec7" id="sec7"></a> +LaTeX Integration</h3> + +<p class="first">Having a BibTeX database manager running inside Emacs has an additional +advantage: it makes it trivially easy to insert BibTeX keys in your LaTeX +documents.</p> + +<p>Ebib provides two functions for this. First, if you're in a LaTeX buffer, you +can call the function <code>ebib-insert-bibtex-key</code>. When you invoke this command, +Emacs prompts you for a key from the database(s) associated with the current +buffer, a citation command (that has to be typed <em>without</em> the backslash) and any +optional argument(s) the command allows. You can type the key using +TAB-completion, and after hitting <code>RET</code>, Emacs puts a BibTeX citation at the +cursor position in the current buffer with the key you selected.</p> + +<p>You can also do it the other way around: if you're in the index buffer in Ebib, +you can <em>push</em> an entry to a LaTeX buffer. To do this, use the key <code>p</code>. Ebib will +ask you for a buffer to push the entry to, a citation command and also any +optional arguments, and then insert a citation at the current cursor position in +the buffer you've supplied.</p> + +<p>For the citation command that <code>ebib-insert-bibtex-key</code> and the command key <code>p</code> ask +for can be any command that you need. But it is also possible to predefine a +list of citation commands which you can then enter at this prompt using tab +completion. For details on setting this up, see <a href="#insertion-commands">Insertion Commands</a>.</p> + +<p>There is another function that is available outside Ebib: +<code>ebib-entry-summary</code>. This command reads the key under the cursor in the +current buffer and displays the field values associated with that key in a +<code>*Help*</code> buffer. This allows you to quickly check a reference in a text.</p> + +<p>Probably the easiest way to use both <code>ebib-insert-bibtex-key</code> and +<code>ebib-entry-summary</code> is to bind them to a key sequence. For example, you +could put the following in your <code>~/.emacs</code>:</p> + +<pre class="example"> +(add-hook 'LaTeX-mode-hook #'(lambda () + (local-set-key "\C-cb" 'ebib-insert-bibtex-key))) +</pre> + +<p>This binds <code>C-c b</code> to the command <code>ebib-insert-bibtex-key</code> in AUCTeX's LaTeX +mode. (Note that commands of the form <code>C-c <letter></code> are reserved for the +user, and should therefore not be set by any package. For this reasons, +Ebib does not set this command automatically.)</p> + + +<h4>Consulting databases from within a LaTeX file</h4> + +<p class="first">The commands <code>ebib-insert-bibtex-key</code> and <code>ebib-entry-summary</code> must consult the +database or databases loaded in Ebib, and Ebib tries to be smart about +which database(s) to consult. Usually, a LaTeX file has a <code>\bibliography</code> +command somewhere toward the end, which names the <code>.bib</code> file or files that +contain the bibliography entries. If you consult a BibTeX database from +within a LaTeX file, Ebib first looks for a <code>\bibliography</code> command, reads +the <code>.bib</code> files from it, and then sees if those files happen to be open. If +they are, Ebib uses them to let you pick an entry key (in the case of +<code>ebib-insert-entry-key</code>) or to search for the entry (in the case of +<code>ebib-entry-summary</code>).</p> + +<p>Of course, it may be the case that the LaTeX file is actually part of a +bigger project, and that only the master file contains a <code>\bibliography</code> +command. To accommodate for this, Ebib checks whether the (buffer-local) +variable <code>TeX-master</code> is set to a filename. If it is, it reads that file and +tries to find the <code>\bibliography</code> command there. (Note: <code>TeX-master</code> is an +AUCTeX variable, which is used to keep track of multi-file projects. If you +don't use AUCTeX, this functionality doesn't work, and Ebib will only check +the current file for a <code>\bibliography</code> command.)</p> + +<p>Note that if one of the <code>.bib</code> files in the <code>\bibliography</code> command isn't +loaded, Ebib issues a warning message about this, and continues to check +for the next <code>.bib</code> file. These warning messages appear in the minibuffer, +but are probably directly overwritten again by further messages or prompts +Ebib produces, so check the <code>*Messages*</code> buffer if Ebib doesn't seem to be +able to find an entry that you're sure is in one of your databases.</p> + +<p>Another thing to keep in mind is that Ebib only looks for a <code>\bibliography</code> +command once: the first time either <code>ebib-insert-bibtex-entry</code> or +<code>ebib-entry-summary</code> is called. It stores the result of this search and uses +it the next time either of these commands is used. Therefore, if you make a +change to the <code>\bibliography</code> command, you must reload the file (use <code>M-x +revert-buffer</code>) to make sure Ebib rereads the <code>\bibliography</code> command.</p> + +<p>If no <code>\bibliography</code> command is found at all, either in the LaTeX file +itself, or in the master file, Ebib simply consults the current database, +i.e. the database that was active when Ebib was lowered with <code>z</code>.</p> + + + + +<h3><a name="sec8" id="sec8"></a> +Cross-referencing</h3> + +<p><a name="cross-referencing" id="cross-referencing"></a> +BibTeX has a cross-referencing facility. Suppose you have an entry <code>jones1998</code>, +which appeared in a book that is also in your database, say under <code>miller1998</code>. +You can tell BibTeX that <code>jones1998</code> is contained in <code>miller1998</code> by putting +<code>miller1998</code> in the <code>crossref</code> field. When BibTeX finds such a cross-reference, all +the fields of <code>jones1998</code> that don't have a value inherit their values from +<code>miller1998</code>. At the very least, this saves you some typing, but more importantly, +if two or more entries cross-reference the same entry, BibTeX automatically +includes the cross-referenced entry in the bibliography (and puts a reduced +reference in the cross-referencing entries).</p> + +<p>When you fill in the <code>crossref</code> field in Ebib, Ebib displays the values of the +cross-referenced entry in the entry buffer. To indicate that they are just +inherited values, they are marked with <code>ebib-crossref-face</code>, which by default is +red. (You can customise it, of course. See the customisation option +<a href="#crossref-face">Crossref Face</a>.) These values are just displayed for convenience: otherwise, Ebib +treats these fields as if they are empty. That is, they cannot be edited (to +edit them, you need to edit the cross-referenced entry), and it's not possible +to copy these values to the kill ring.</p> + +<p>If you're viewing an entry that has a cross-reference and you want to go to the +cross-referenced entry you can type <code>F</code>. This command reads the value of the +<code>crossref</code> field and then displays that entry. If you want to do the reverse, +i.e., see if the current entry is cross-referenced by any other entries, you can +use the key <code>N</code>. What this command actually does is to make the key of the current +entry the current search string and to search for its first occurrence <em>after</em> the +current entry. Like the normal search command <code>/</code>, <code>N</code> does not wrap and only +searches forward. So if you want to search for the next cross-referencing entry +you need to press <code>n</code> (i.e., lowercase <code>n</code>), and to continue searching from the +first entry, press <code>g</code> followed by <code>n</code>.</p> + +<p>Note that if you want to use BibTeX's cross-referencing options, you need to set +the option <a href="#save-xrefs-first">Save Xrefs first</a>. This tells Ebib to save all entries with a <code>crossref</code> +field first in the <code>.bib</code> file. Without this, BibTeX's cross-referencing will not +work reliably.</p> + + + +<h3><a name="sec9" id="sec9"></a> +Printing the Database</h3> + +<p><a name="printing-database" id="printing-database"></a> +Sometimes it may be useful to have a <code>.pdf</code> file or print-out of your +database. Although Ebib does not actually do the printing itself, it can +create a LaTeX file for you that you can compile and print. In fact, there +are two ways of doing this.</p> + +<p>The first is the command <code>L</code>. This command creates a simple LaTeX document +that essentially contains a <code>\nocite{*}</code> command followed by a +<code>\bibliography</code> command referring to the <code>.bib</code> file belonging to +the current database. You can then run the usual sequence of LaTeX, BibTeX, +LaTeX, LaTeX on this file, creating a document containing a list of all the +references in your database.</p> + +<p>The second command for printing a database is <code>P</code>. This command also creates +a LaTeX file. However, instead of simply providing a +<code>\nocite{*}</code> command, <code>P</code> creates a <code>tabular</code> environment for each +entry in the database listing all the fields of that entry and their +values.</p> + +<p>The difference between <code>L</code> and <code>P</code> should be obvious: with <code>L</code>, you get a list of +references created by BibTeX. This means that the references look the way +they will when actually used in a document, but it also means that the list +only contains the information that BibTeX deems relevant.</p> + +<p>With <code>P</code> you get an overview of your database with <em>all</em> the field values of +each entry, including the ones that BibTeX does not use. The entries are +not formatted as literature references, but in a way similar to how they +are shown in Ebib.</p> + +<p>By default, <code>P</code> only shows single-line field values. That is, multiline +values are normally excluded. If you want to include multiline values in +the print-out, you have to set the option <code>Print Multiline</code> in Ebib's +customisation buffer. (See <a href="#customisation-buffer">The Customisation Buffer</a>.) With this option set, +Ebib will include all multiline values in the LaTeX file that <code>P</code> +creates. Note however that Ebib does not change anything about the +formatting of the text in a multiline value. So if you plan to make (heavy) +use of this option, make sure that the way you type your text conforms to +LaTeX's conventions (e.g. empty lines to mark paragraphs, etc.) and doesn't +contain any characters such as <code>&</code> that are illegal in LaTeX. (Or, +alternatively, use LaTeX code in your multiline fields.)</p> + +<p>As mentioned, when you use either <code>L</code> or <code>P</code>, Ebib creates a LaTeX file. More +precisely, it creates a temporary buffer and writes the LaTeX code into it, +and then saves the contents of that buffer to a file. After it has done +that, Ebib lowers itself and instruct Emacs to open the file in a buffer, +which will then be properly set up as a LaTeX buffer. From there you can +run LaTeX and view the result.</p> + +<p>Before doing all this, Ebib asks you which file to write to. Be careful +with this: since this is supposed to be a temporary file, Ebib simply +assumes that if you provide a filename of an existing file, it can +overwrite that file without warning!</p> + +<p>A better way to tell Ebib which file to use is to set the option <code>Print +Tempfile</code> in Ebib's customisation buffer to some temporary file. When this +option is set, Ebib will always use this file to write to, and will not ask +you for a filename anymore when you type <code>L</code> or <code>P</code>.</p> + +<p>There are two more customisation options for printing the database. These +are <code>Print Preamble</code> and <code>LaTeX Preamble</code>. With these options, you can specify +what Ebib should put in the preamble of the LaTeX files it creates. Use +this if you want to use specific packages +(e.g. <code>\usepackage{a4}</code> or +<code>\usepackage{times})</code>. This is especially useful for <code>L</code>, since by +default, Ebib uses BibTeX's standard bibliography style. With the option +<code>LaTeX Preamble</code> you can set your preferred bibliography style. Details are +discussed in the chapter on customisation, see <a href="#customisation-buffer">The Customisation Buffer</a>.</p> + + + + +<h3><a name="sec10" id="sec10"></a> +Marking Entries</h3> + +<p class="first">Commands in the index buffer generally operate on one single entry, or on +all entries. For some, however, it may sometimes be useful to perform them +on more than one entry, but not necessarily all of them. This can be +achieved by marking entries. You can mark the entries you want to perform a +command on with the key <code>m</code>. This marks (or unmarks) the current +entry. Marked entries are displayed in inverse video (in GNU Emacs) or +white on red (in XEmacs; note that the face properties of marked entries +can be customised through the customisation option <a href="#marked-face">Marked Face</a>.)</p> + +<p>Of the commands discussed so far, four can be used on marked entries: <code>d</code>, <code>p</code>, +<code>L</code> and <code>P</code>. Note, however, that it is not enough to mark the entries you want +and then type any of these commands. If you do so, they will behave as if +no entries were marked. To get these commands to work on the marked +entries, you have to type a semicolon before them. That is, <code>; d</code> deletes all +marked entries, and <code>; L</code> and <code>; P</code> create a LaTeX file of only the marked +entries. The command <code>m</code> itself can also be used with the <code>;</code> prefix. If there +are any marked entries, <code>; m</code> unmarks them all. Otherwise, <code>; m</code> marks all +entries.</p> + +<p><code>; p</code> pushes all marked entries to a LaTeX buffer. It does so by putting them +all in a single <code>\cite</code> command, separated by commas, not by putting them in +separate <code>\cite</code> commands.</p> + + + +<h3><a name="sec11" id="sec11"></a> +Calling a Browser</h3> + +<p class="first">With more and more scientific literature becoming available on-line, it +becomes common to store URLs in a BibTeX database. Sometimes you may want +to load such a URL in your browser. Ebib provides a convenient way for +doing so.</p> + +<p>If you type <code>u</code> in the index buffer, Ebib takes the first URL stored in the +<code>url</code> field of the current entry and passes it to your browser. Furthermore, +in the entry buffer, you can use <code>u</code> on <em>any</em> field. If you happen to have more +than one URL stored in the relevant field, and you want to pass the second +(or third, etc.) to the browser, you can use a prefix argument. So typing +<code>M-2 u</code> sends the second URL to your browser, <code>M-3 u</code> the third, and so on.</p> + +<p>It is not even necessary that the relevant field contains <em>only</em> URLs. It may +contain other text mixed with the URLs: Ebib simply searches the URLs in +the field and ignores the rest of the text. Ebib considers every string of +characters that starts with <code>http://</code> or <code>https://</code> and that does not contain +whitespace or any of the characters <code>" ' <</code> or <code>></code> as a URL. Furthermore, Ebib +regards everything that is enclosed in a LaTeX <code>\url{...}</code> +command as a URL. This behaviour is controlled by a regular expression that +can be customised. (See <a href="#url-regexp">Url Regexp</a>.)</p> + +<p>There exists an Emacs function <code>browse-url</code>, which provides a nifty interface +to calling an external browser. In principle, Ebib uses this +function. However, if this function is not present on your installation, +you can set the option <a href="#browser-command">Browser Command</a> to call the browser.</p> + +<p>As just explained, if you press <code>u</code> in the index buffer, Ebib searches the +<code>url</code> field of the current entry for URLs. If you have the habit of putting +your URLs in another field, however, you may change the customisation +option <a href="#standard-url-field">Standard Url Field</a> and tell Ebib to use another field for searching +the URLs. (Keep in mind, though, that in the entry buffer, you can load a +URL from any field.)</p> + + + +<h3><a name="sec12" id="sec12"></a> +Viewing Files</h3> + +<p class="first">If you have electronic versions of the papers in your database stored on +your computer, you can use Ebib to call external viewers for these +files. The interface for this is similar to that for calling a browser: if +you press <code>f</code> in the index buffer, Ebib searches the <code>file</code> field for a +filename and when it finds one, calls an appropriate viewer.</p> + +<p>Just as with <code>u</code>, you can use <code>f</code> in the entry buffer as well, in which case it +can be used on any field, not just the <code>file</code> field. It is also possible to +have more than one filename in a field: you can select the one you want to +view with the prefix argument.</p> + +<p>Just as in the case of URLs, you can customise several things about the +file view functionality. The option <a href="#standard-file-field">Standard File Field</a> allows you to +customise the field that <code>f</code> extracts filenames from when pressed in the +index buffer. Extracting filenames is done with a regular expression, which +can be customised through the option <a href="#file-regexp">File Regexp</a>.</p> + +<p>The option <a href="#file-search-dirs">File Search Dirs</a> allows you to tell Ebib which directories it +needs to search for files. The default value is <code>~</code>, which means Ebib just +looks in your home dir. Since this is probably not where you keep your +files, you may want to customise this. Note that you can specify more than +one directory.</p> + +<p>Note that Ebib does not search directories recursively. It is possible, +however, to put subdirectories in the filenames. That is, if you put +something like <code>a/abney1987.pdf</code> in the <code>file</code> field, Ebib searches for the +relevant file in a subdirectory <code>a/</code> of the directories listed in the option +<code>File Search Dirs</code>. (Note that if you want to do this under Windows, you may +want to remove the backslash from the file regexp.)</p> + +<p>Ebib can call different external programs depending on the file type of the +relevant file, but you have to specify which programs to call. The option +<a href="#file-associations">File Associations</a> allows you to do this. By default, <code>.pdf</code> and <code>.ps</code> files are +handled, by <code>xpdf</code> and <code>gv</code>, respectively. You can specify further file types by +their extensions (do not include the dot). The program is searched for in +<code>PATH</code>, but you can of course specify the full path to the program.</p> + + + + +<h2><a name="sec13" id="sec13"></a> +Advanced Features</h2> + +<p class="first">The features discussed in the previous chapter should be sufficient to get +started using Ebib. However, Ebib has several more advanced features, which +are described in this chapter.</p> + + +<h3><a name="sec14" id="sec14"></a> +Screen Layout</h3> + +<p><a name="screen-layout" id="screen-layout"></a> +By default, Ebib takes over the entire Emacs frame it is started in. If you +have a wide enough screen, however, it may be more convenient to have Ebib +take up only part of the frame, so that you can have the LaTeX text you're +working on and Ebib visible at the same time. The option <a href="#layout">Layout</a> allows you +to do this, by giving you the ability to choose between a full-frame or a +split-frame layout.</p> + +<p>In the split-frame layout, the Ebib windows are displayed on the right of +the current frame, with the left part free for your document. In this +layout, some aspects of Ebib behave somewhat differently. Most importantly, +the multiline edit buffer is not displayed in the lower Ebib window, but in +the non-Ebib window on the left. (Obviously, after leaving the multiline +edit buffer, the original buffer is restored to that window.)</p> + +<p>Furthermore, pressing <code>z</code> in the index buffer leaves Ebib, but keeps the +buffers visible. You can get back to Ebib with the command <code>M-x ebib</code> (or any +key bound to it, of course), or simply by manually switching to the index +buffer. If you want to remove the Ebib buffers from the frame but keep Ebib +in the background, you can use <code>Z</code> (i.e. capital <code>Z</code>) in the index +buffer. (Note that <code>Z</code> is also available in the full-frame layout, but there +it is identical to <code>z</code>.)</p> + +<p>Lastly, the command <code>ebib-entry-summary</code> checks whether the Ebib buffers are +visible in the frame. If they are, it does not output the entry info in a +<code>*Help*</code> buffer, but rather displays the entry in Ebib itself.</p> + + + +<h3><a name="sec15" id="sec15"></a> +Preloading <code>.bib</code> Files</h3> + +<p class="first">Chances are that you will be doing most of your work with one or a few <code>.bib</code> +files, and you may find yourself opening the same file or files every time +you start Ebib. If so, you can tell Ebib to always load specific <code>.bib</code> files +on startup. To do this, specify the files in Ebib's customisation buffer, +under the option <a href="#preload-bib-files">Preload Bib Files</a>.</p> + + + +<h3><code><a name="sec16" id="sec16"></a>@Preamble</code> Definition</h3> + +<p class="first">Apart from database entries, BibTeX allows three more types of elements to +appear in a <code>.bib</code> file. These are <code>@comment</code>, <code>@preamble</code> and <code>@string</code> +definitions. Ebib provides facilities to handle the latter two. <code>@comment</code> +definitions cannot be added to a <code>.bib</code> file through Ebib, and if Ebib finds +one in a <code>.bib</code> file, it is simply ignored.</p> + +<p><code>@preamble</code> and <code>@string</code> definitions can be handled, however. Ebib allows you +to add one <code>@preamble</code> definition to the database. In principle, BibTeX +allows more than one such definition, but really one suffices, because you +can use the concatenation character <code>#</code> to include multiple TeX or LaTeX +commands. So, rather than having two <code>@preamble</code> definitions such as:</p> + +<pre class="example"> +@preamble{ "\newcommand{\noopsort}[1]{} " } +@preamble{ "\newcommand{\singleletter}[1]{#1} " } +</pre> + +<p>you can write this in your <code>.bib</code> +file:</p> + +<pre class="example"> +@preamble{ "\newcommand{\noopsort}[1]{} " + # "\newcommand{\singleletter}[1]{#1} " } +</pre> + +<p>Creating or editing a <code>@preamble</code> definition in Ebib is done by hitting <code>r</code> in +the index buffer. Ebib uses the multiline edit buffer for editing the text +of the <code>@preamble</code> definition, which means that as discussed above, <code>C-x b</code> +stores the <code>@preamble</code> text and returns focus to the index buffer, while <code>C-x +k</code> returns focus to the index buffer while abandoning any changes you may +have made. (For details on using the multiline edit buffer, see +<a href="#multiline-edit-buffer">The Multiline Edit Buffer</a>.)</p> + +<p>In order to create a <code>@preamble</code> as shown above in Ebib, you only have to +type the text between the braces. Ebib takes care of including the braces +of the <code>@preamble</code> command, but otherwise it saves the text exactly as you +enter it. So in order to get the preamble above, you'd have to type the +following in Ebib:</p> + +<pre class="example"> +"\newcommand{\noopsort}[1]{} " +# "\newcommand{\singleletter}[1]{#1} " +</pre> + +<p>Note that when Ebib loads a <code>.bib</code> file that contains more than one <code>@preamble</code> +definition, it concatenates all the strings in them in the manner just +described and saves them in one <code>@preamble</code> definition.</p> + + + +<h3><code><a name="sec17" id="sec17"></a>@String</code> Definitions</h3> + +<p class="first">If you press <code>t</code> in the index buffer, Ebib hides the entry buffer in the +lower window and replaces it with the <em>strings buffer</em>. In this buffer, you +can add, delete and edit <code>@string</code> definitions.</p> + +<p>Adding a <code>@string</code> definition is done with the command <code>a</code>. This will first ask +you for an abbreviation and then for the value to be associated with that +abbreviation. Once you've entered these, Ebib will sort the new +abbreviation into the buffer.</p> + +<p>Moving between the <code>@string</code> definitions can be done in the usual way: the +cursor keys <code>up</code> and <code>down</code>, <code>C-p</code> and <code>C-n</code> and <code>k</code> and <code>j</code> move up and down. <code>Space</code> +and <code>PgDn</code> move ten strings down, while <code>b</code> and <code>PgUp</code> move in the other +direction. The keys <code>g</code>, <code>G</code>, <code>Home</code> and <code>End</code> also function as expected.</p> + +<p>To delete a <code>@string</code> definition, use <code>d</code>. To edit the value of a definition, +use <code>e</code>. There is also a command <code>c</code>, which copies the value of the current +<code>@string</code> definition to the kill ring. Unlike in the entry buffer, there are +no corresponing commands <code>y</code> and <code>x</code>. (In fact, <code>x</code> does exist, but has another +function.) Yanking from the kill ring can be done with <code>C-y/M-y</code> in the +minibuffer when you edit a <code>@string</code>'s value. Cutting a <code>@string</code>'s value +is pointless, because a <code>@string</code> definition must have a value.</p> + +<p>Having defined <code>@string</code> definitions, there must of course be a way to use +them. Just giving a field a string abbreviation as value will not do, +because Ebib puts braces around the value that you enter when it writes the +<code>.bib</code> file, so that BibTeX will not recognise the abbreviation, and will not +expand it. BibTeX will only recognise an abbreviation if it appears in the +<code>.bib</code> file outside of any braces.</p> + +<p>To accomplish this, you must mark a field's value as <em>raw</em>. A raw field is a +field whose value is not surrounded by braces when the database is saved, +so that BibTeX recognises it as an abbreviation. To mark a field raw, press +<code>r</code>. An asterisk will appear before the field, indicating that it is +raw. Pressing <code>r</code> again will change the field back to normal. If you press <code>r</code> +on a field that does not have a value yet, Ebib will ask you for one.</p> + +<p>Note that this also makes it possible to enter field values that are +composed of concatenations of strings and abbreviations. The BibTeX +documentation for example explains that if you have defined:</p> + +<pre class="example"> +@string{WGA = "World Gnus Almanac"} +</pre> + +<p>you can create a BibTeX field +like this:</p> + +<pre class="example"> +title = 1966 # WGA +</pre> + +<p>which will produce ``1966 World +Gnus Almanac''. Or you can do:</p> + +<pre class="example"> +month = "1~" # jan +</pre> + +<p>which will produce someting +like ``1 January'', assuming your bibliography style has defined the +abbreviation <code>jan</code>. All this is possible with Ebib, simply by entering the +exact text including quotes or braces around the strings, and marking the +relevant field as raw.</p> + +<p>An easy way to enter a <code>@string</code> abbreviation as a field value is to use the +key <code>s</code> instead of <code>e</code>. If you type <code>s</code>, Ebib asks you for a <code>@string</code> abbreviation +to put in the current field, and automatically marks the field as raw. With +this command, Ebib only accepts <code>@string</code> definitions that are in the +database, so that by using <code>s</code> you can make sure you don't make any +typos. Note that you can use tab completion to complete a partial string.</p> + + + +<h3><a name="sec18" id="sec18"></a> +Sorting the <code>.bib</code> file</h3> + +<p><a name="sorting-bib-file" id="sorting-bib-file"></a> +By default, the entries in the database are saved to the <code>.bib</code> file in +alphabetical order according to entry key. If you only deal with the <code>.bib</code> +file through Ebib, you may not care in which order the entries are +saved. However, it may sometimes be desirable to be able to specify the +sort order of entries in more detail. (Apparently, this can be useful with +ConTeXt, for example.)</p> + +<p>You can specify a sort order in Ebib's customisation buffer. To sort the +entries, you must set at least one sort level (that is, a field to sort the +entries on). You can also specify more than one sort level: if two entries +have identical values for the first sort level, they will be sorted on the +second sort level. E.g., if the first sort level is <code>author</code> and the second +is <code>year</code>, then the entries are sorted by author, and those entries that have +identical values for the <code>author</code> field are sorted by year.</p> + +<p>A sort level is not restricted to a single field. You can specify more +fields for a single sort level. Within a single sort level, a second sort +field is used if the first sort field does not have a value. For example, +books that have an editor instead of an author will have an empty <code>author</code> +field. If you sort the database on the <code>author</code> field, such entries will all +appear at the beginning of the <code>.bib</code> file, which is most likely not what you +want.</p> + +<p>To remedy this, you can specify both the <code>author</code> and the <code>editor</code> fields for +the first sort level. Ebib will then sort an entry on its <code>author</code> field if +it has a value, and will otherwise use the value of the <code>editor</code> field.</p> + +<p>The difference between two sort fields within one sort level and two sort +levels is that a second sort <em>field</em> is an alternative for the first field +when it has no value, while a second sort <em>level</em> is an additional sort +criterion when two or more entries cannot be sorted on the first level, +because they have identical values.</p> + +<p>By default, the option <code>Sort Order</code> has no value, which means that the +entries in the <code>.bib</code> file are sorted according to entry key. Those that wish +to customise the sort order will usually want to set the first sort level +to <code>author editor</code>, and the second to <code>year</code>. In that way, the entries in the +<code>.bib</code> file are sorted according to author/editor, and entries with the same +author/editor are sorted by year.</p> + +<p>Entries that cannot be sorted on some sort level, because the sort fields +are empty, are sorted on entry key. (Keep in mind that if the first sort +level yields <em>no value</em> for a specific entry, Ebib does <em>not</em> use the second +sort level to sort that entry. It uses the entry key. The second sort level +is only used if the first yields <em>identical</em> values for two or more entries.)</p> + +<p>Note that if you have set the option <code>Save Xrefs First</code> (see +<a href="#cross-referencing">Cross-referencing</a>), it is pointless to set a sort order. Saving +cross-referencing entries first messes up any sort order, so Ebib simply +ignores the sort order if <code>Save Xrefs First</code> is set.</p> + + + +<h3><a name="sec19" id="sec19"></a> +Merging and Importing</h3> + +<p class="first">As described in the previous chapter, adding entries to a database can be +done manually with the key <code>a</code>. There are other ways of adding entries to a +database, however.</p> + +<p>With the command <code>M</code> you can merge a second <code>.bib</code> file into your current +database. When you hit <code>M</code>, you are asked for a filename. Ebib then reads the +entries in this file and adds them to the database. Duplicate entries (that +is, entries with an entry key that already exists in the database) will not +be loaded. Ebib logs a warning about each duplicate entry to its log +buffer, and displays a warning after loading the <code>.bib</code> file when this +happens.</p> + +<p>Another way to add entries to a database is to import them from an Emacs +buffer. If, for example, you find ready-formatted BibTeX entries in a text +file or e.g. on the internet, you can copy & paste them to any Emacs buffer +(e.g. the <code>*scratch*</code> buffer), and then execute the command <code>M-x +ebib-import</code>. Ebib then goes through the buffer and loads all BibTeX entries +it finds into the current database (i.e. the database that was active when +you lowered Ebib). If you call <code>ebib-import</code> while the region is active, Ebib +only reads the BibTeX entries in the region.</p> + + + +<h3><a name="sec20" id="sec20"></a> +Exporting Entries</h3> + +<p class="first">Sometimes it can be useful to copy entries from one database to another, or +to create a new <code>.bib</code> file with several entries from an existing +database. For this purpose, Ebib provides exporting facilities. To export +an entry to a <code>.bib</code> file, use the command <code>x</code>. Ebib will ask you for a +filename to export the entry to. (If you have already exported an entry +before, Ebib will present the filename you used as default, but you can of +course change it.)</p> + +<p>For obvious reasons, Ebib appends the entry to the file that you enter if +it already exists, it does not overwrite the file. If this is not what you +want, delete the file first, as Ebib provides no way to do this.</p> + +<p>If you have more than one database open in Ebib, it is also possible to +copy entries from one database to another. To do this, use the <code>x</code> command +with a numeric prefix argument. E.g., if the database you want to export an +entry to is the second database, type <code>M-2 x</code> to export the current entry to +it. The number of the database is given in the modeline of the index +buffer.</p> + +<p>If the database you're copying an entry to already contains an entry with +the same entry key, Ebib won't copy the entry, and issues an appropriate +warning message.</p> + +<p>Note that the command <code>x</code> can operate on marked entries. So to export several +entries in one go mark them and type <code>; x</code>. You can use a prefix argument in +the normal way: <code>M-2 ; x</code> exports the marked entries to database 2.</p> + +<p>Apart from entries, it is also possible to export the <code>@preamble</code> and <code>@string</code> +definitions. The <code>@preamble</code> definition is exported with the command <code>X</code> in the +index buffer. <code>@string</code> definitions can be exported in the strings buffer: <code>x</code> +in this buffer exports the current string, while <code>X</code> exports all <code>@string</code> +definitions in one go. All these commands function in the same way: when +used without a prefix argument, they ask for a filename, and then append +the relevent data to that file. With a numeric prefix argument, they copy +the relevant data to the corresponding open database.</p> + + + +<h3><a name="sec21" id="sec21"></a> +Timestamps</h3> + +<p><a name="timestamps" id="timestamps"></a> +Ebib provides the possibility to add a timestamp to every new entry, +recording the time it was added to the database. The timestamp is recorded +in the (additional) field <code>timestamp</code>. (By default, this field is not shown, +but you can make it visible by pressing <code>H</code> in the index buffer.)</p> + +<p>You can tell Ebib to create timestamps by setting the option <code>Use Timestamp</code> +in Ebib's customisation buffer. With this option set, a timestamp is +included in entries added to the database with <code>a</code>. Ebib will also add a +timestamp to entries imported from a buffer or merged from a file, and to +entries exported to another database or to a file. When importing or +exporting entries, existing timestamps will be overwritten. The logic +behind this is that the timestamp records the date and time when the entry +was added to the database, not when it was first created.</p> + +<p>Note that if this option is unset, the timestamp of an entry is retained +when it's imported or exported. Therefore, if you record timestamps and +want to im-/export entries without changing their timestamps, temporarily +unset this option.</p> + +<p>Ebib uses the function <code>format-time-string</code> to create the timestamp. The +format string that Ebib uses can be customised in Ebib's customisation +buffer. The default string is <code>"%a %b %e %T %Y"</code>, which produces a timestamp +of the form <code>"Mon Mar 12 01:03:26 2007"</code>. Obviously, this string is not +suited for sorting, so if you want to be able to sort on timestamps, you'll +need to customise the format string. See the documentation for +<code>format-time-string</code> on the options that are available.</p> + + + +<h3><a name="sec22" id="sec22"></a> +Multiple Identical Fields</h3> + +<p><a name="multiple-identical-fields" id="multiple-identical-fields"></a> +Under normal circumstances, a BibTeX entry only contains one occurrence of +each field. If BibTeX notices that an entry contains more than one +occurrence of an obligatory or optional field, it issues a warning. Ebib is +somewhat less gracious, it simply takes the value of the last occurrence +without giving any warning. (Note, by the way, that BibTeX will use the +value of the <em>first</em> occurrence, not the last.) When additional fields appear +more than once in an entry, BibTeX does not warn you, since it ignores +those fields anyway. Here, too, Ebib's standard behaviour is to ignore all +but the last value.</p> + +<p>However, some online reference management services ``use'' this feature of +BibTeX in that they put multiple <code>keywords</code> fields in the BibTeX entries that +they produce. If you were to import such an entry into Ebib, you would lose +all your keywords except the last one. To remedy this, you can tell Ebib +that it should allow multiple occurrences of a single field in a BibTeX +entry. You can do this by setting the customisation option +<a href="#allow-identical-fields">Allow Identical Fields</a>.</p> + +<p>With this option set, Ebib collapses the multiple occurrences into a single +occurrence. All the values of the different occurrences are collected and +stored in the single occurrence, separated by semicolons. That is, Ebib +does not retain the multiple occurrences, but it does retain the values. So +suppose you have an entry that contains the following <code>keywords</code> fields:</p> + +<pre class="example"> +@book{jones1998, + author = {Jones, Joan}, + year = {1998}, + ... + keywords = {sleep}, + keywords = {winter}, + keywords = {hybernation} +} +</pre> + +<p>If you load this entry into Ebib with the option <code>Allow Identical Fields</code> +set, you will get the following:</p> + +<pre class="example"> +@book{jones1998, + author = {Jones, Joan}, + year = {1998}, + ... + keywords = {sleep; winter; hybernation} +} +</pre> + + + +<h3><a name="sec23" id="sec23"></a> +Virtual Databases</h3> + +<p><a name="virtual-databases" id="virtual-databases"></a> +In the previous chapter, Ebib's basic search functionality was +discussed. (See <a href="#searching">Searching</a>.) Ebib also provides a much more sophisticated +search and filtering mechanism in the form of <em>virtual databases</em>.</p> + +<p>A virtual database is a database that is not associated with any <code>.bib</code> +file. Rather, it is created from another database by selecting entries from +it based on a specific search pattern, called a <em>filter</em>. This allows you, +for example, to select all entries from a database that contain the string +``Jones'' in their <code>author</code> field. A filter can be as complex as you want: +you can select all entries that do <em>not</em> contain ``Jones'' in the <code>author</code> +field, or all entries that contain ``Jones'' in either the <code>author</code> or the +<code>editor</code> field, or all entries that contain ``Jones'' in the <code>author</code> field, +and ``symbiotic hybernation'' in the <code>keyword</code> field, etc. Basically, the +filter can consist of an arbitray number of search criteria combined with +the logical operators <code>and, or</code> and <code>not</code>.</p> + + +<h4>Simple Selection</h4> + +<p class="first">Creating a virtual database is simple: press <code>&</code>, and Ebib will ask you for a +field to select on, and for a regular expression to select with. So if you +want to select all entries that contain ``Jones'' in the <code>author</code> field, you +press <code>&</code> and type <code>author</code> as the field and <code>Jones</code> as the regexp to filter on.</p> + +<p>Ebib will then create a virtual database containing the entries matching +your selection criterion. A virtual database has the same name as the +database it is based on, prepended with <code>V:</code>. It also has a number like any +other database, and you can move back and forth to other databases with the +number or cursor keys.</p> + +<p>If you don't want to filter on one specific field but rather want to select +all entries that match a certain regexp in any field, you can type <code>any</code> as +the field to filter on. So specifying <code>any</code> as the field and <code>Jones</code> as the +regexp, the virtual database will select all entries that have a field that +contains ``Jones'' in them.</p> + + + +<h4>Complex Filters</h4> + +<p class="first">Once you have a virtual database, it remains associated with the database +it was created from. This means that you can refine or extend the selection +(i.e. the filter) that the virtual database is based on. If, in the current +example, you want to include all the entries that have ``Jones'' in the +<code>editor</code> field, you have to perform a logical <code>or</code> operation: you want to +select an entry if it contains ``Jones'' in the <code>author</code> field (which you +already did) <em>or</em> if it contains ``Jones'' in the <code>editor</code> field.</p> + +<p>A short sidenote: the first impulse in a case like this might be to use <code>and</code> +instead of <code>or</code>: after all, you want to select all entries that contain +``Jones'' in the <code>author</code> field <em>and</em> all entries that contain ``Jones'' in the +<code>editor</code> field. However, the filter that you build up is used to test each +entry <em>individually</em> whether it meets the selection criterion. An entry meets +the criterion if it contains ``Jones'' in the <code>author</code> field <em>or</em> if it +contains ``Jones'' in the <code>editor</code> field. Therefore, <code>or</code> is the required +operator in this case. If you would use <code>and</code>, you would only get those +entries that contain ``Jones'' in both the <code>author</code> <em>and</em> <code>editor</code> fields.</p> + +<p>To perform a logical <code>or</code> operation, press the key <code>|</code>. As before, you will be +asked which field you want to filter on, and which regexp you want to +filter with. Ebib will then update the virtual database with all entries in +the original database that match the additional criterion.</p> + +<p>It is also possible to perform a logical <code>and</code> on the virtual database. Use +this if you want to select those entries that contain ``Jones'' in the +<code>author</code> field and e.g. ``symbiotic hybernation'' in the <code>keyword</code> field. A +logical <code>and</code> operation is done with the key <code>&</code>. (Note: this is the same key +that is used to create a virtual database. In fact, you can also create a +virtual database with <code>|</code>: when used in a normal database, <code>&</code> and <code>|</code> are +equivalent. They are only different in virtual databases.)</p> + +<p>Both the <code>&</code> and <code>|</code> commands can be used with the negative prefix argument <code>M--</code> +(or <code>C-u -</code>, which is identical). In this case, the search criterion is +negated. That is, the negative prefix argument performs a logical <code>not</code> +operation on the search criterion.</p> + +<p>That is, if you want to select all entries from a database that do <em>not</em> +contain ``Jones'' in the <code>author</code> field, you can do this by typing <code>M-- &</code> and +then filling out the relevant field and regexp. This prefix argument is +available both in real and in virtual databases.</p> + +<p>There is another way of performing a logical <code>not</code> operation, which is only +available in virtual databases: by pressing the key <code>~</code>, you invert the +current filter. That is, if you have a virtual database with all the +entries containing ``Jones'' in the <code>author</code> or in the <code>editor</code> field, and you +press <code>~</code>, the selection is inverted, and now contains all entries that do +<em>not</em> have ``Jones'' in the <code>author</code> or <code>editor</code> field.</p> + +<p>Although <code>~</code> and the negative prefix argument to <code>&</code> or <code>|</code> both perform logical +<code>not</code> operations, they are <em>not</em> equivalent: <code>~</code> negates the entire filter built +up so far, while the negative prefix argument only negates the single +selection criterion you enter with it.</p> + +<p>If you want to know what the filter for the current virtual database is +exactly, you can type <code>V</code>. This command displays the current filter in the +minibuffer. The filter is specified as a Lisp expression, meaning that the +operators appear before their operands, not in between them. That is, <code>x and +y</code> is written as <code>(and x y)</code>.</p> + +<p>With a prefix argument (any prefix argument will do), the command <code>V</code> not +only displays the current filter, but also reapplies it. This can be useful +when you've made changes to the source database: Ebib does not +automatically update a virtual database when its source database is +modified.</p> + + + +<h4>Properties of Virtual Databases</h4> + +<p class="first">Virtual databases differ from normal databases in several ways. First, they +cannot be modified: you cannot add or delete entries, and you cannot modify +the contents of fields. It is also not possible to import entries to them +or merge another file with them. Furthermore, it is not possible to export +entries to them or from them.</p> + +<p>A virtual database cannot be saved in the normal way with <code>s</code>, and the +command <code>S</code> to save all databases ignores virtual databases. If you want to +save a virtual database, you can use the command <code>w</code>. This command not only +saves the virtual database, it also changes it into a normal database, and +detaches it from its original source database, so that you can modify it +without affecting the source database.</p> + +<p>The command <code>L</code> also doesn't work with virtual databases. The reason for this +is that the virtual database is not associated with an actual <code>.bib</code> file, so +there is no file to create a list of references from. However, it is +possible to use the command <code>P</code> with a virtual database to create a list of +entries. See <a href="#printing-database">Printing the Database</a>, for details on these two commands.</p> + + + + +<h3><a name="sec24" id="sec24"></a> +The Multiline Edit Buffer</h3> + +<p><a name="multiline-edit-buffer" id="multiline-edit-buffer"></a> +As mentioned several times before, Ebib has a special multiline edit +buffer, which is used to edit field values that contain newlines (so-called +<em>multiline fields</em>), and also to edit the contents of the <code>@preamble</code> +command. This section discusses the details of this buffer.</p> + +<p>Ebib enters multiline edit mode in one of three cases: when you press <code>P</code> in +the index buffer, to edit the <code>@preamble</code> definition, when you hit <code>l</code> in the +entry buffer to edit the current field as multiline, or when you hit <code>e</code> on +the <code>annote</code> field, or on a field whose value already is multiline.</p> + +<p>The multiline edit buffer uses a special major mode, +<code>ebib-multiline-edit-mode</code>, which is derived from <code>text-mode</code>. The changes with +respect to <code>text-mode</code> are minor (see below), which means that any +customisations you may have made to <code>text-mode</code> will be available in the +multiline edit buffer.</p> + +<p>The settings that are specific for <code>ebib-multiline-edit-mode</code> are the +functions assigned to the key sequences <code>C-x b</code>, <code>C-x k</code> and <code>C-x C-s</code>. These key +sequences do not have their usual functions, but rather are redefined to +fit Ebib. Both <code>C-x b</code> and <code>C-x k</code> can be used to leave the multiline edit +buffer. <code>C-x b</code> will store the text as it is to the database, while <code>C-x k</code> +leaves the multiline edit buffer <em>without</em> storing the text, i.e., the +original value of the field or preamble that you were editing is +retained. If the text in the buffer was modified, <code>C-x k</code> asks you if you +really want to abandon your changes.</p> + +<p>If you leave the multitiline edit buffer with <code>C-x b</code> when the buffer is +empty (i.e., you deleted all the text, including the final newline), and +you were editing a field value or the <code>@preamble</code> definition, the field value +or preambleis deleted. (This is in fact the <em>only</em> way to delete the +<code>@preamble</code> definition. Field values on the other hand can also be deleted by +hitting <code>x</code> or <code>d</code> on them in the entry buffer.)</p> + +<p>The third command that is redefined in the multiline edit buffer is <code>C-x +C-s</code>. This command can be used to save the database. Because Ebib does not +do an autosave of the current database, it is advisable to save the +database manually every now and then to prevent data loss in case of +crashes. It would be annoying to have to leave the multiline edit buffer +every time you want to do this, so <code>C-x C-s</code> has been redefined to allow you +to do this from within the buffer.</p> + + + + +<h2><a name="sec25" id="sec25"></a> +The Ebib Buffers</h2> + +<p><a name="ebib-buffers" id="ebib-buffers"></a> +This chapter lists all the key commands that exist in Ebib, with a short +description and the actual command that they call. The latter information +is needed if you want to customise Ebib's key bindings. (See +<a href="#modifying-key-bindings">Modifying Key Bindings</a>.)</p> + + + +<h3><a name="sec26" id="sec26"></a> +The Index Buffer</h3> + +<dl> +<dt><strong><code>Up</code></strong></dt> +<dd>go to previous entry. <code>(ebib-prev-entry)</code></dd> + +<dt><strong><code>Down</code></strong></dt> +<dd>go to next entry. <code>(ebib-next-entry)</code></dd> + +<dt><strong><code>Right</code></strong></dt> +<dd>move to the next database. <code>(ebib-next-database)</code></dd> + +<dt><strong><code>Left</code></strong></dt> +<dd>move to the previous database. <code>(ebib-prev-database)</code></dd> + +<dt><strong><code>PgUp</code></strong></dt> +<dd>scroll the index buffer down. <code>(ebib-index-scroll-down)</code></dd> + +<dt><strong><code>PgDn</code></strong></dt> +<dd>scroll the index buffer up. <code>(ebib-index-scroll-up)</code></dd> + +<dt><strong><code>Home</code></strong></dt> +<dd>go to first entry. <code>(ebib-goto-first-entry)</code></dd> + +<dt><strong><code>End</code></strong></dt> +<dd>go to last entry. <code>(ebib-goto-last-entry)</code></dd> + +<dt><strong><code>Return</code></strong></dt> +<dd>make the entry under the cursor current. Use after e.g. <code>C-s</code>. +<code>(ebib-select-entry)</code></dd> + +<dt><strong><code>Space</code></strong></dt> +<dd>equivalent to <code>PgDn</code>.</dd> + +<dt><strong><code>1-9</code></strong></dt> +<dd>jump to the corresponding database.</dd> + +<dt><strong><code>/</code></strong></dt> +<dd>search the database. <code>(ebib-search)</code></dd> + +<dt><strong><code>&</code></strong></dt> +<dd>Create a virtual database, or perform a logical <code>and</code> on the current +virtual database. With negative prefix argument: apply a logical <code>not</code> to the +selectional criterion. <code>(ebib-virtual-db-and)</code></dd> + +<dt><strong><code>|</code></strong></dt> +<dd>Create a virtual database, or perform a logical <code>or</code> on the current +virtual database. With negative prefix argument: apply a logical <code>not</code> to the +selectional criterion. <code>(ebib-virtual-db-or)</code></dd> + +<dt><strong><code>~</code></strong></dt> +<dd>Perform a logical <code>not</code> on the current virtual +database. <code>(ebib-virtual-db-not)</code></dd> + +<dt><strong><code>a</code></strong></dt> +<dd>add an entry. <code>(ebib-add-entry)</code></dd> + +<dt><strong><code>b</code></strong></dt> +<dd>equivalent to <code>Pgup</code>.</dd> + +<dt><strong><code>c</code></strong></dt> +<dd>close the database. <code>(ebib-close-database)</code></dd> + +<dt><strong><code>C</code></strong></dt> +<dd>customise Ebib. <code>(ebib-customize)</code></dd> + +<dt><strong><code>d</code></strong></dt> +<dd>delete the current entry. <code>(ebib-delete-entry)</code></dd> + +<dt><strong><code>; d</code></strong></dt> +<dd>delete all marked entries.</dd> + +<dt><strong><code>e</code></strong></dt> +<dd>edit the current entry. <code>(ebib-edit-entry)</code></dd> + +<dt><strong><code>E</code></strong></dt> +<dd>edit the key of the current entry. <code>(ebib-edit-keyname)</code></dd> + +<dt><strong><code>f</code></strong></dt> +<dd>extract a filename from the <code>file</code> field and send it to an +appropriate viewer. With numeric prefix argument, extract the <em>n</em>-th +filename.</dd> + +<dt><strong><code>F</code></strong></dt> +<dd>follow <code>crossref</code> field. <code>(ebib-follow-crossref)</code></dd> + +<dt><strong><code>g</code></strong></dt> +<dd>equivalent to <code>Home</code>.</dd> + +<dt><strong><code>G</code></strong></dt> +<dd>equivalent to <code>End</code>.</dd> + +<dt><strong><code>H</code></strong></dt> +<dd>show/hide hidden fields. <code>(ebib-toggle-hidden)</code></dd> + +<dt><strong><code>j</code></strong></dt> +<dd>equivalent to <code>Down</code>.</dd> + +<dt><strong><code>J</code></strong></dt> +<dd>jump to another database. This accepts a numeric prefix argument, +but will ask you for a database number if there is +none. <code>(ebib-switch-to-database)</code></dd> + +<dt><strong><code>k</code></strong></dt> +<dd>equivalent to <code>Up</code>.</dd> + +<dt><strong><code>l</code></strong></dt> +<dd>show the log buffer. (<code>ebib-show-log</code>)</dd> + +<dt><strong><code>L</code></strong></dt> +<dd>create a LaTeX file from the current database that produces a list +of references formatted by BibTeX. <code>(ebib-latex-database)</code></dd> + +<dt><strong><code>; L</code></strong></dt> +<dd>create a LaTeX file with the marked entries only.</dd> + +<dt><strong><code>m</code></strong></dt> +<dd>mark (or unmark) the current entry. <code>(ebib-mark-entry)</code></dd> + +<dt><strong><code>; m</code></strong></dt> +<dd>unmark all marked entries.</dd> + +<dt><strong><code>M</code></strong></dt> +<dd>merge a <code>.bib</code> file. <code>(ebib-merge-bibtex-file)</code></dd> + +<dt><strong><code>n</code></strong></dt> +<dd>find next occurrence of the search string. <code>(ebib-search-next)</code></dd> + +<dt><strong><code>N</code></strong></dt> +<dd>search for entries cross-referencing the current one. <code>(ebib-search-crossref)</code></dd> + +<dt><strong><code>C-n</code></strong></dt> +<dd>equivalent to <code>Down</code>.</dd> + +<dt><strong><code>M-n</code></strong></dt> +<dd>equivalent to <code>PgDn</code>.</dd> + +<dt><strong><code>o</code></strong></dt> +<dd>open a <code>.bib</code> file. <code>(ebib-load-bibtex-file)</code></dd> + +<dt><strong><code>p</code></strong></dt> +<dd>push an entry to a LaTeX buffer <code>(ebib-push-bibtex-key)</code></dd> + +<dt><strong><code>; p</code></strong></dt> +<dd>push the marked entries to a LaTeX buffer.</dd> + +<dt><strong><code>C-p</code></strong></dt> +<dd>equivalent to <code>Up</code>.</dd> + +<dt><strong><code>M-p</code></strong></dt> +<dd>equivalent to <code>PgUp</code>.</dd> + +<dt><strong><code>P</code></strong></dt> +<dd>create a LaTeX file for printing the database, listing the entire +contents of each entry. <code>(ebib-print-database)</code></dd> + +<dt><strong><code>; P</code></strong></dt> +<dd>create a LaTeX file with the marked entries.</dd> + +<dt><strong><code>r</code></strong></dt> +<dd>show and edit the <code>@preamble</code> definition in the +database. <code>(ebib-edit-preamble)</code></dd> + +<dt><strong><code>q</code></strong></dt> +<dd>quit Ebib. This sets all variables to nil, unloads the database(s) +and quits Ebib. <code>(ebib-quit)</code></dd> + +<dt><strong><code>s</code></strong></dt> +<dd>save the database. <code>(ebib-save-current-database)</code></dd> + +<dt><strong><code>S</code></strong></dt> +<dd>save all modified databases. <code>(ebib-save-all-databases)</code></dd> + +<dt><strong><code>t</code></strong></dt> +<dd>show and edit the <code>@string</code> definitions in the +database. <code>(ebib-edit-strings)</code></dd> + +<dt><strong><code>u</code></strong></dt> +<dd>extract a URL from the <code>url</code> field and send it to a browser. With +numeric prefix argument, extract the <em>n</em>-th url.</dd> + +<dt><strong><code>V</code></strong></dt> +<dd>Display the filter of the current virtual database in the +minibuffer. With prefix argument: reapply the filter. <code>(ebib-print-filter)</code></dd> + +<dt><strong><code>w</code></strong></dt> +<dd>write the database to a different file. <code>(ebib-write-database)</code></dd> + +<dt><strong><code>x</code></strong></dt> +<dd>export the current entry to a file, or, when used with numeric +prefix argument, to another database. <code>(ebib-export-entry)</code></dd> + +<dt><strong><code>; x</code></strong></dt> +<dd>export the marked entries to a file, or, when used with a numeric +prefix argument, to another database.</dd> + +<dt><strong><code>C-x b</code></strong></dt> +<dd>equivalent to <code>z</code>.</dd> + +<dt><strong><code>C-x k</code></strong></dt> +<dd>equivalent to <code>q</code>.</dd> + +<dt><strong><code>X</code></strong></dt> +<dd>export the <code>@preamble</code> definition to a file or, when used with a +numeric prefix argument, to another database. <code>(ebib-export-preamble)</code></dd> + +<dt><strong><code>z</code></strong></dt> +<dd>move focus away from the Ebib windows. <code>(ebib-leave-ebib-windows)</code></dd> + +<dt><strong><code>Z</code></strong></dt> +<dd>put Ebib in the background. <code>(ebib-lower)</code></dd> +</dl> + +<p>One function is not bound to any key: <code>ebib-print-filename</code>.</p> + + +<h3><a name="sec27" id="sec27"></a> +The Entry Buffer</h3> + +<dl> +<dt><strong><code>Up</code></strong></dt> +<dd>go to the previous field. <code>(ebib-prev-field)</code></dd> + +<dt><strong><code>Down</code></strong></dt> +<dd>go to the next field. <code>(ebib-next-field)</code></dd> + +<dt><strong><code>PgUp</code></strong></dt> +<dd>go to the previous set of fields. <code>(ebib-goto-prev-set)</code></dd> + +<dt><strong><code>PgDn</code></strong></dt> +<dd>go to the next set of fields. <code>(ebib-goto-next-set)</code></dd> + +<dt><strong><code>Home</code></strong></dt> +<dd>go to the first field. <code>(ebib-goto-first-field)</code></dd> + +<dt><strong><code>End</code></strong></dt> +<dd>go to the last field. <code>(ebib-goto-last-field)</code></dd> + +<dt><strong><code>Space</code></strong></dt> +<dd>equivalent to <code>PgDn</code>.</dd> + +<dt><strong><code>b</code></strong></dt> +<dd>equivalent to <code>PgUp</code>.</dd> + +<dt><strong><code>c</code></strong></dt> +<dd>copy the contents of the current field to the kill +ring. <code>(ebib-copy-field-contents)</code></dd> + +<dt><strong><code>d</code></strong></dt> +<dd>delete the value of the current field. The deleted contents will <em>not</em> +be put in the kill ring, and is therefore irretrievably +lost. <code>(ebib-delete-field-contents)</code></dd> + +<dt><strong><code>e</code></strong></dt> +<dd>edit the current field. <code>(ebib-edit-fields)</code></dd> + +<dt><strong><code>f</code></strong></dt> +<dd>extract a filename from the current field and send it to an +appropriate viewer. With numeric prefix argument, extract the <em>n</em>-th +filename.</dd> + +<dt><strong><code>g</code></strong></dt> +<dd>equivalent to <code>Home</code>.</dd> + +<dt><strong><code>G</code></strong></dt> +<dd>equivalent to <code>End</code>.</dd> + +<dt><strong><code>j</code></strong></dt> +<dd>go to the next field. <code>(ebib-next-field)</code></dd> + +<dt><strong><code>k</code></strong></dt> +<dd>go to the previous field. <code>(ebib-prev-field)</code></dd> + +<dt><strong><code>l</code></strong></dt> +<dd>edit the current field as multiline. <code>(ebib-edit-multiline-field)</code></dd> + +<dt><strong><code>C-n</code></strong></dt> +<dd>equivalent to <code>Down</code>.</dd> + +<dt><strong><code>M-n</code></strong></dt> +<dd>equivalent to <code>PgDn</code>.</dd> + +<dt><strong><code>C-p</code></strong></dt> +<dd>equivalent to <code>Up</code>.</dd> + +<dt><strong><code>M-p</code></strong></dt> +<dd>equivalent to <code>PgUp</code>.</dd> + +<dt><strong><code>q</code></strong></dt> +<dd>quit editing the current entry and return focus to the index +buffer. <code>(ebib-quit-entry-buffer)</code></dd> + +<dt><strong><code>r</code></strong></dt> +<dd>toggle a field's ``raw'' status. <code>(ebib-toggle-raw)</code></dd> + +<dt><strong><code>s</code></strong></dt> +<dd>insert an abbreviation from the <code>@string</code> definitions in the +database. <code>(ebib-insert-abbreviation)</code></dd> + +<dt><strong><code>u</code></strong></dt> +<dd>extract a URL from the current field and send it to a browser. With +numeric prefix argument, extract the <em>n</em>-th url.</dd> + +<dt><strong><code>x</code></strong></dt> +<dd>cut the contents of the current field. Like <code>c</code>, <code>x</code> puts the contents +of the current field in the kill ring. <code>(ebib-cut-field-contents)</code></dd> + +<dt><strong><code>y</code></strong></dt> +<dd>yank the last element in the kill ring to the current +field. Repeated use of <code>y</code> functions like <code>C-y/M-y</code>. Note that no text will be +yanked if the field already has a value. <code>(ebib-yank-field-contents)</code></dd> +</dl> + + + +<h3><a name="sec28" id="sec28"></a> +The Strings Buffer</h3> + +<dl> +<dt><strong><code>Up</code></strong></dt> +<dd>go to the previous string. <code>(ebib-prev-string)</code></dd> + +<dt><strong><code>Down</code></strong></dt> +<dd>go to the next string. <code>(ebib-next-string)</code></dd> + +<dt><strong><code>PgUp</code></strong></dt> +<dd>go ten strings up. <code>(ebib-strings-page-up)</code></dd> + +<dt><strong><code>PgDn</code></strong></dt> +<dd>go ten strings down. <code>(ebib-strings-page-down)</code></dd> + +<dt><strong><code>Home</code></strong></dt> +<dd>go to the first string. <code>(ebib-goto-first-string)</code></dd> + +<dt><strong><code>End</code></strong></dt> +<dd>go to the last string. <code>(ebib-goto-last-string)</code></dd> + +<dt><strong><code>Space</code></strong></dt> +<dd>equivalent to <code>PgDn</code>.</dd> + +<dt><strong><code>a</code></strong></dt> +<dd>add a new <code>@string</code> definition. <code>(ebib-add-string)</code></dd> + +<dt><strong><code>b</code></strong></dt> +<dd>equivalent to <code>PgUp</code>.</dd> + +<dt><strong><code>c</code></strong></dt> +<dd>copy the text of the current string to the kill +ring. <code>(ebib-copy-string-contents)</code></dd> + +<dt><strong><code>d</code></strong></dt> +<dd>delete the current <code>@string</code> definition from the database. You will be +asked for confirmation. <code>(ebib-delete-string)</code></dd> + +<dt><strong><code>e</code></strong></dt> +<dd>edit the value of the current string. <code>(ebib-edit-string)</code></dd> + +<dt><strong><code>g</code></strong></dt> +<dd>equivalent to <code>Home</code>.</dd> + +<dt><strong><code>G</code></strong></dt> +<dd>equivalent to <code>End</code>.</dd> + +<dt><strong><code>j</code></strong></dt> +<dd>equivalent to <code>Down</code>.</dd> + +<dt><strong><code>k</code></strong></dt> +<dd>equivalent to <code>Up</code>.</dd> + +<dt><strong><code>l</code></strong></dt> +<dd>edit the value of the current string as +multiline. <code>(ebib-edit-multiline-string)</code></dd> + +<dt><strong><code>C-n</code></strong></dt> +<dd>equivalent to <code>Down</code>.</dd> + +<dt><strong><code>M-n</code></strong></dt> +<dd>equivalent to <code>PgDn</code>.</dd> + +<dt><strong><code>C-p</code></strong></dt> +<dd>equivalent to <code>Up</code>.</dd> + +<dt><strong><code>M-p</code></strong></dt> +<dd>equivalent to <code>PgUp</code>.</dd> + +<dt><strong><code>q</code></strong></dt> +<dd>quit the strings buffer and return focus to the index +buffer. <code>(ebib-quit-strings-buffer)</code></dd> + +<dt><strong><code>x</code></strong></dt> +<dd>export the current <code>@string</code> definition to a file or, when used with a +prefix argument, to another database. <code>(ebib-export-string)</code></dd> + +<dt><strong><code>X</code></strong></dt> +<dd>export all the <code>@string</code> definitions to a file or, when used with a +prefix argument, to another database. <code>(ebib-export-all-strings)</code></dd> +</dl> + + + + +<h2><a name="sec29" id="sec29"></a> +Customisation</h2> + +<p><a name="customisation" id="customisation"></a> +Ebib can be customised through Emacs' standard customisation interface. The +only thing that cannot be customised in this way are the key bindings. If +you wish to customise those, you have to use the file <code>~/.ebibrc</code>.</p> + + +<h3><a name="sec30" id="sec30"></a> +The Customisation Buffer</h3> + +<p><a name="customisation-buffer" id="customisation-buffer"></a> +Ebib's customisation group is a subgroup of the <code>Tex</code> group. It can be +invoked by typing <code>M-x customize-group RET ebib RET</code>, or by pressing <code>C</code> in +the index buffer. This chapter gives a short description of all the options +available in the customisation buffer.</p> + + +<h4>Default Type</h4> + +<p class="first">The default type is the default entry type given to a new entry. Every +entry in the Ebib database must have a type, because the type defines which +fields are available. When a new entry is created, Ebib gives it a default +type, which can be customised through this option. The standard value is +<code>article</code>.</p> + + + +<h4>Preload Bib Files</h4> + +<p><a name="preload-bib-files" id="preload-bib-files"></a> +This option allows you to specify which file(s) Ebib is to load when it +starts up. Specify one file per line, press the <code>INS</code> button to add more +files. You can complete a partial filename with <code>M-TAB</code>.</p> + + + +<h4>Additional Fields</h4> + +<p><a name="additional-fields" id="additional-fields"></a> +The additional fields are those fields that are available for all entry +types, and which BibTeX generally ignores. This option allows you to +specify which additional fields you wish to use in your database. Specify +one field per line, press the <code>INS</code> button to add more fields.</p> + +<p>By default, the following additional fields are defined: <code>crossref, url, +annote, abstract, keywords, file</code> and <code>timestamp</code>.</p> + + + +<h4>Layout</h4> + +<p><a name="layout" id="layout"></a> +The default value of this option is <code>full</code>, which means that Ebib takes over +the entire frame when it runs. Alternatively, you can select to specify a +width (in characters) yourself, in which case Ebib takes up the right part +of the frame, leaving the left part free. See <a href="#screen-layout">Screen Layout</a> for details.</p> + + + + +<h4>Index Window Size</h4> + +<p class="first">This option lets you specify the size of the index window at the top of the +Ebib screen. The default value is 10.</p> + + + +<h4>Index Display Fields</h4> + +<p><a name="index-display-fields" id="index-display-fields"></a> +This option allows you to specify fields that should be displayed next to +the entry key in the index buffer. By default, the index buffer only shows +the key of each entry, but if this is too little information, you can use +this option to display e.g. the title of each entry as well.</p> + + + +<h4>Insertion Commands</h4> + +<p><a name="insertion-commands" id="insertion-commands"></a> +With the command <code>ebib-insert-bibtex-key</code> or with the command key <code>p</code> in the index +buffer, you can insert a BibTeX key into a LaTeX buffer. This option allows you +to define the commands that are available through tab completion when these +functions ask for a citation command.</p> + +<p>The citation commands must be given <em>without</em> the leading backslash, as Ebib adds one. +Furthermore, you need to specify how many optional arguments each command can +have. When Ebib prompts you for a citation key, it will ask for as many optional +arguments as you specify here. (If you don't want to be asked for those optional +arguments, just fill in 0.)</p> + +<p>When Ebib prompts you for a citation command, the commands specified in this +option can be obtained through tab completion. However, it is not necessary to +fill in a command from this list here. You can also enter another command (in +which case Ebib asks for exactly one optional argument) or even no command at +all. In the latter case, Ebib does not ask for any optional arguments and simply +puts the key in the buffer without adding a backslash or curly braces.</p> + + + + +<h4>Sort Order</h4> + +<p class="first">The use of this option is explained above, see <a href="#sorting-bib-file">Sorting the .bib file</a>. To +create a sort order, click the <code>INS</code> button to create a sort level, and then +click the <code>INS</code> button under that sort level to enter a sort field. If you +want to add more than one sort field to the sort level, simply hit <code>INS</code> +again.</p> + + + +<h4>Save Xrefs First</h4> + +<p><a name="save-xrefs-first" id="save-xrefs-first"></a> +For cross-referencing to work, the cross-referencing entries must appear in +the <code>.bib</code> file <em>before</em> the cross-referenced entries. In order to tell Ebib to +save all entries with a <code>crossref</code> field first, you must set the option <code>Save +Xrefs First</code> in Ebib's customisation buffer. With this option set, BibTeX's +crossreferencing options work as intended.</p> + +<p>By default, this option is unset, because it (marginally) slows down saving +the <code>.bib</code> file somewhat.</p> + + + +<h4>Crossref Face</h4> + +<p><a name="crossref-face" id="crossref-face"></a> +Field values inherited from a cross-referenced entry are marked with this +face. By default, the face has red as foreground colour.</p> + + + +<h4>Marked Face</h4> + +<p><a name="marked-face" id="marked-face"></a> +When entries are marked (with <code>m</code>), they are highlighted in this face. By +default, GNU Emacs uses the text property <code>highlight</code>. XEmacs only allows +this on terminals, therefore it displays marked entries with a red +background and a white foreground colour. This option allows you to change +these defaults.</p> + + + +<h4>Use Timestamp</h4> + +<p class="first">If this option is set, Ebib will add a <code>timestamp</code> field to every new entry, +recording the date and time it was added to the database. See <a href="#timestamps">Timestamps</a>.</p> + + + +<h4>Timestamp Format</h4> + +<p class="first">This option specifies the format string that is used to create the +timestamp. The format string is used by <code>format-time-string</code> to create a time +representation. The default value is <code>"%a %b %e %T %Y"</code>, which produces a +timestamp of the form <code>"Mon Mar 12 01:03:26 2007"</code>. See the documentation for +<code>format-time-string</code> for the forms that the format string can take.</p> + + + +<h4>Standard Url Field</h4> + +<p><a name="standard-url-field" id="standard-url-field"></a> +This is the field that Ebib searches for URLs if you press <code>u</code> in the index +buffer. Its default value is <code>url</code>.</p> + + + +<h4>Url Regexp</h4> + +<p><a name="url-regexp" id="url-regexp"></a> +This is the regular expression that Ebib uses to search for URLs in a +field. The default value is:</p> + +<pre class="example"> +\\url{\(.*\)}\|https?://[^ '<>\"\n\t\f]+ +</pre> + +<p>With this regular expression, Ebib considers everything that is in a LaTeX +<code>\url{...}</code> command as a URL, and furthermore every string of +text that starts with <code>http://</code> or <code>https://</code> and does not contain whitespace +or one of the characters <code>' " <</code> or <code>></code>.</p> + + + +<h4>Browser Command</h4> + +<p><a name="browser-command" id="browser-command"></a> +If this option is unset (which is the default), Ebib uses the Emacs +function <code>browse-url</code> to start a browser. If this function does not exist, +you can set this option. For example, if you use the Firefox browser, set +this option to <code>firefox</code>.</p> + +<p>For this to work, the browser that you use must be able to handle a URL on +the command line.</p> + + + +<h4>Standard File Field</h4> + +<p><a name="standard-file-field" id="standard-file-field"></a> +This is the field that Ebib searches for filenames if you press <code>f</code> in the +index buffer. Its default value is <code>file</code>.</p> + + + +<h4>File Associations</h4> + +<p><a name="file-associations" id="file-associations"></a> +The programs used to view files. By default, programs for <code>.pdf</code> and <code>.ps</code> +files are specified, which should be available on most linux systems. If +you prefer other programs or are running on Windows, you'll can specify +them here. Note that Ebib searches the PATH for the programs, but you can +also specify full path names. Of course, it is also possible to add new +associations.</p> + +<p>Note that GNU/Emacs 23 (as yet unreleased) comes with <code>doc-view-mode</code>, which +provides a way to view <code>.pdf</code> and <code>.ps</code> files inside Emacs. (The files are +converted to <code>.png</code> format first.) If you prefer to use this mode, simply +leave the program field blank for the relevant file type.</p> + + + +<h4>File Regexp</h4> + +<p><a name="file-regexp" id="file-regexp"></a> +In order to find files in a field, Ebib uses a regular expression. The +default value is:</p> + +<pre class="example"> + [^?|\:*<>\" \n\t\f]+ +</pre> + +<p>This essentially means that every string of characters not containing any +of the characters</p> + +<pre class="example"> +? | \ : * < > " +</pre> + +<p>or space, newline, tab of formfeed. URLs can easily by recognised by the +prefix <code>http:</code>, but recognising files is not so straightforward. It is +therefore not advisable to put anything but filenames in the <code>file</code> field.</p> + + + +<h4>File Search Dirs</h4> + +<p><a name="file-search-dirs" id="file-search-dirs"></a> +This is the list of directories that Ebib searches for files. Note that +searching is not recursive: only the files listed here are searched, not +their subdirectories.</p> + + + +<h4>Print Preamble</h4> + +<p class="first">This option specifies the preamble that is to be added to the LaTeX file +Ebib creates for printing the database (i.e., the <code>P</code> command). By default, +the preamble is empty. You can set your own <code>\usepackage</code> +commands, or anything else you may need.</p> + + + +<h4>Print Multiline</h4> + +<p class="first">When this options is set, Ebib includes multiline field values when it +creates a LaTeX file with <code>P</code> (<code>ebib-print-database</code>). When unset, multiline +values are excluded, which saves space. By default, this option is unset.</p> + + + +<h4>Latex Preamble</h4> + +<p class="first">This option specifies the preamble to be added to the LaTeX file for +creating a list of references from the database (i.e., the <code>L</code> command). By +default, the line <code>\bibliographystyle{plain}</code> is put in the +preamble, but you may want to specify your own BibTeX packages and options.</p> + + + +<h4>Print Tempfile</h4> + +<p class="first">This option specifies the name and location of the temporary file Ebib +creates with the commands <code>ebib-print-database</code> and +<code>ebib-latex-database</code>. By default, this option has no value, +which means that Ebib will ask for a filename each time either of these +commands is called.</p> + + + +<h4>Allow Identical Fields</h4> + +<p><a name="allow-identical-fields" id="allow-identical-fields"></a> +If this option is set, Ebib stores the values of multiple occurrences of a +single field within an entry in a single occurrence of that field, +separated by semicolons. By default, this option is unset, because it slows +down the loading of <code>.bib</code> files. See <a href="#multiple-identical-fields">Multiple Identical Fields</a>.</p> + + + +<h4>Entry Types</h4> + +<p><a name="entry-types" id="entry-types"></a> +This option allows you to customise the entry types that Ebib uses. Each +entry type has a name, a set of obligatory fields and a set of optional +fields. You can add, alter or delete single fields in an entry type, or +whole entry types.</p> + +<p>If you want to add an entry type, hit the <code>INS</code> key on the top level and give +the new entry a name, then add obligatory and/or optional fields. It is not +necessary that an entry type has both obligatory and optional fields, you +can define an entry that has only obligatory or only optional fields.</p> + + + + +<h3><a name="sec31" id="sec31"></a> +Modifying Key Bindings</h3> + +<p><a name="modifying-key-bindings" id="modifying-key-bindings"></a> +If you are unhappy about Ebib's standard key bindings, you can change them +to anything you like. To do this, you have to create a file <code>~/.ebibrc</code> and +write your preferred key bindings in it. A key binding definition is built +up as follows:</p> + +<pre class="example"> +(ebib-key <buffer> <key> <command>) +</pre> + +<p><code><buffer></code> is either <code>index</code>, <code>entry</code> or <code>strings</code>, for the corresponding +buffer. <code><key></code> is a standard Emacs key description, and <code><command></code> is the +Ebib command to be associated with the key. The commands that can be used +here are listed in <a href="#ebib-buffers">The Ebib Buffers</a>. Note that it is possible to bind more +than one key to a single function: just add as many <code>ebib-key</code> statements as +necessary.</p> + +<p>As an example, the following binds <code>C-s</code> to <code>ebib-search</code> in the index buffer, +so that the database can be searched with <code>C-s</code> as well as with <code>/</code>:</p> + +<pre class="example"> +(ebib-key index "\C-s" ebib-search) +</pre> + +<p>If you want to unbind a key, you can simply leave out <code><command></code>. So if you +want to bind the command <code>ebib-delete-entry</code> to <code>D</code> rather than <code>d</code>, you need to +put the following in <code>.ebibrc</code>:</p> + +<pre class="example"> +(ebib-key index "D" ebib-delete-entry) +(ebib-key index "d") +</pre> + +<p>The first line binds <code>D</code> to the command <code>ebib-delete-entry</code>. The second line +unbinds <code>d</code>.</p> + +<p>If a command can be called with a prefix key (as for example +<code>ebib-delete-entry</code> can), <code>ebib-key</code> will automatically rebind the prefixed +version as well. So in the example above, the first line not only binds <code>D</code>, +it also binds <code>; D</code>. Similarly, the second line not only unbinds <code>d</code>, but also +<code>; d</code>.</p> + +<p>It is also possible to redefine the prefix key itself. To do this, you must +specify <code>mark-prefix</code> for <code><buffer></code>. The value of <code><command></code> is irrelevant +here, so it can be left out:</p> + +<pre class="example"> +(ebib-key mark-prefix ":") +</pre> + +<p>This sets up <code>:</code> as the new prefix key. Doing this automatically unbinds the +existing prefix key.</p> + +</div> + + + + +<!-- Page published by Emacs Muse ends here --> + </body> +</html> diff --git a/biblio/bibtex/utils/ebib/ebib.el b/biblio/bibtex/utils/ebib/ebib.el new file mode 100644 index 0000000000..34411629ce --- /dev/null +++ b/biblio/bibtex/utils/ebib/ebib.el @@ -0,0 +1,3606 @@ +;; Ebib v1.8.0 +;; +;; Copyright (c) 2003-2009 Joost Kremers +;; All rights reserved. +;; +;; Redistribution and use in source and binary forms, with or without +;; modification, are permitted provided that the following conditions +;; are met: +;; +;; 1. Redistributions of source code must retain the above copyright +;; notice, this list of conditions and the following disclaimer. +;; 2. Redistributions in binary form must reproduce the above copyright +;; notice, this list of conditions and the following disclaimer in the +;; documentation and/or other materials provided with the distribution. +;; 3. The name of the author may not be used to endorse or promote products +;; derived from this software without specific prior written permission. +;; +;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +;; OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +;; IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +;; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +;; NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE, +;; DATA, OR PROFITS ; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +;; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +;; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +;; THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +(require 'cl) + +;;;;;;;;;;;;;;;;;;;;;; +;; global variables ;; +;;;;;;;;;;;;;;;;;;;;;; + +;; user customisation + +(defgroup ebib nil "Ebib: a BibTeX database manager" :group 'Tex) + +(defcustom ebib-default-type 'article + "*The default type for a newly created BibTeX entry." + :group 'ebib + :type 'symbol) + +(defcustom ebib-preload-bib-files nil + "*List of .bib files to load automatically when Ebib starts." + :group 'ebib + :type '(repeat (file :must-match t))) + +(defcustom ebib-additional-fields '(crossref url annote abstract + keywords file timestamp) + "*List of the additional fields." + :group 'ebib + :type '(repeat (symbol :tag "Field"))) + +(defcustom ebib-layout 'full + "*Ebib window layout. +Full width: Ebib occupies the entire Emacs frame. + +Specify width: Ebib occupies the right side of the Emacs frame, +with the left side free for another window." + :group 'ebib + :type '(choice (const :tag "Full width" full) + (integer :tag "Specify width"))) + +(defcustom ebib-index-window-size 10 + "*The number of lines used for the index buffer window." + :group 'ebib + :type 'integer) + +(defcustom ebib-index-display-fields nil + "*List of the fields to display in the index buffer." + :group 'ebib + :type '(repeat (symbol :tag "Index Field"))) + +(defcustom ebib-insertion-commands '(("cite" . 1)) + "*A list of commands that can be used to insert an entry into a (La)TeX buffer. +For use with EBIB-INSERT-BIBTEX-KEY and EBIB-PUSH-BIBTEX-KEY." + :group 'ebib + :type '(repeat (cons :tag "Command" (string) (integer :tag "Optional arguments")))) + +(defcustom ebib-sort-order nil + "*The fields on which the BibTeX entries are to be sorted in the .bib file. +Sorting is done on different sort levels, and each sort level contains one +or more sort keys." + :group 'ebib + :type '(repeat (repeat :tag "Sort level" (symbol :tag "Sort field")))) + +(defcustom ebib-save-xrefs-first nil + "*If true, entries with a crossref field will be saved first in the .bib-file. +Setting this option has unpredictable results for the sort order +of entries, so it is not compatible with setting the Sort Order option." + :group 'ebib + :type 'boolean) + +(defface ebib-crossref-face '((t (:foreground "red"))) + "*Face used to indicate values inherited from crossreferenced entries." + :group 'ebib) + +(defface ebib-marked-face (if (featurep 'xemacs) + '((t (:foreground "white" :background "red"))) + '((t (:inverse-video t)))) + "*Face to indicate marked entries." + :group 'ebib) + +(defcustom ebib-use-timestamp nil + "*If true, new entries will get a time stamp. +The time stamp will be stored in a field \"timestamp\" that can +be made visible with the `H' command in the index buffer." + :group 'ebib + :type 'boolean) + +(defcustom ebib-timestamp-format "%a %b %e %T %Y" + "*Format of the time string used in the timestamp. +The format is passed unmodified to FORMAT-TIME-STRING, see the +documentation of that function for details." + :group 'ebib + :type 'string) + +(defcustom ebib-standard-url-field 'url + "*Standard field to store urls in. +In the index buffer, the command ebib-browse-url can be used to +send a url to a browser. This option sets the field from which +this command extracts the url." + :group 'ebib + :type 'symbol) + +(defcustom ebib-url-regexp "\\\\url{\\(.*\\)}\\|https?://[^ '<>\"\n\t\f]+" + "*Regular expression to extract urls." + :group 'ebib + :type 'string) + +(defcustom ebib-browser-command "" + "*Command to call the browser with. +GNU/Emacs has a function call-browser, which is used if this +option is unset." + :group 'ebib + :type '(string :tag "Browser command")) + +(defcustom ebib-standard-file-field 'file + "*Standard field to store filenames in. +In the index buffer, the command ebib-view-file can be used to +view a file externally. This option sets the field from which +this command extracts the filename." + :group 'ebib + :type 'symbol) + +(defcustom ebib-file-associations '(("pdf" . "xpdf") + ("ps" . "gv")) + "*List of file associations. +Lists file extensions together with external programs to handle +files with those extensions. If the external program is left +blank, Ebib tries to handle the file internally in +Emacs (e.g. with doc-view-mode)." + :group 'ebib + :type '(repeat (cons :tag "File association" + (string :tag "Extension") (string :tag "Command")))) + +(defcustom ebib-file-regexp "[^?|\\:*<>\" \n\t\f]+" + "*Regular expression to match filenames." + :group 'ebib + :type 'string) + +(defcustom ebib-file-search-dirs '("~") + "*List of directories to search for files." + :group 'ebib + :type '(repeat :tag "Search directories" (string :tag "Directory"))) + +(defcustom ebib-print-preamble nil + "*Preamble used for the LaTeX file for printing the database. +Each string is added to the preamble on a separate line." + :group 'ebib + :type '(repeat (string :tag "Add to preamble"))) + +(defcustom ebib-print-multiline nil + "*If set, multiline fields are included when printing the database." + :group 'ebib + :type 'boolean) + +(defcustom ebib-latex-preamble '("\\bibliographystyle{plain}") + "*Preamble used for the LaTeX file for BibTeXing the database. +Each string is added to the preamble on a separate line." + :group 'ebib + :type '(repeat (string :tag "Add to preamble"))) + +(defcustom ebib-print-tempfile "" + "*Temporary file for use with EBIB-PRINT-DATABASE and EBIB-LATEX-DATABASE." + :group 'ebib + :type '(file)) + +(defcustom ebib-allow-identical-fields nil + "*If set, Ebib handles multiple occurrences of a field gracefully." + :group 'ebib + :type 'boolean) + +(defvar ebib-unique-field-list nil + "Holds a list of all field names.") + +(defmacro add-to-listq (listvar element &optional append fn) + (if (or (featurep 'xemacs) + (string< emacs-version "22")) + `(add-to-list (quote ,listvar) ,element ,append) + `(add-to-list (quote ,listvar) ,element ,append ,fn))) + +(defun ebib-set-unique-field-list (var value) + "Sets EBIB-UNIQUE-FIELD-LIST on the basis of EBIB-ENTRY-TYPES" + (set-default var value) + (setq ebib-unique-field-list nil) + (mapc #'(lambda (entry) + (mapc #'(lambda (field) + (add-to-listq ebib-unique-field-list field t 'eq)) + (cadr entry)) + (mapc #'(lambda (field) + (add-to-listq ebib-unique-field-list field t 'eq)) + (caddr entry))) + value)) + +(defcustom ebib-entry-types + '((article ;; name of entry type + (author title journal year) ;; obligatory fields + (volume number pages month note)) ;; optional fields + + (book + (author title publisher year) + (editor volume number series address edition month note)) + + (booklet + (title) + (author howpublished address month year note)) + + (inbook + (author title chapter pages publisher year) + (editor volume series address edition month note)) + + (incollection + (author title booktitle publisher year) + (editor volume number series type chapter pages address edition month note)) + + (inproceedings + (author title booktitle year) + (editor pages organization publisher address month note)) + + (manual + (title) + (author organization address edition month year note)) + + (misc + () + (title author howpublished month year note)) + + (mastersthesis + (author title school year) + (address month note)) + + (phdthesis + (author title school year) + (address month note)) + + (proceedings + (title year) + (editor publisher organization address month note)) + + (techreport + (author title institution year) + (type number address month note)) + + (unpublished + (author title note) + (month year))) + + "List of entry type definitions for Ebib" + :group 'ebib + :type '(repeat (list :tag "Entry type" (symbol :tag "Name") + (repeat :tag "Obligatory fields" (symbol :tag "Field")) + (repeat :tag "Optional fields" (symbol :tag "Field")))) + :set 'ebib-set-unique-field-list) + +;; generic for all databases + +;; constants and variables that are set only once +(defconst ebib-bibtex-identifier "[^\"#%'(),={} \t\n\f]*" "Regexp describing a licit BibTeX identifier.") +(defconst ebib-version "1.8.0") +(defvar ebib-initialized nil "T if Ebib has been initialized.") + +;; buffers and highlights +(defvar ebib-index-buffer nil "The index buffer.") +(defvar ebib-entry-buffer nil "The entry buffer.") +(defvar ebib-strings-buffer nil "The strings buffer.") +(defvar ebib-multiline-buffer nil "Buffer for editing multiline strings.") +(defvar ebib-log-buffer nil "Buffer showing warnings and errors during loading of .bib files") +(defvar ebib-index-highlight nil "Highlight to mark the current entry.") +(defvar ebib-fields-highlight nil "Highlight to mark the current field.") +(defvar ebib-strings-highlight nil "Highlight to mark the current string.") + +;; general bookkeeping +(defvar ebib-minibuf-hist nil "Holds the minibuffer history for Ebib") +(defvar ebib-saved-window-config nil "Stores the window configuration when Ebib is called.") +(defvar ebib-pre-ebib-window nil "The window that was active when Ebib was called.") +(defvar ebib-pre-multiline-buffer nil "The buffer in the window before switching to the multiline edit buffer.") +(defvar ebib-export-filename nil "Filename to export entries to.") +(defvar ebib-push-buffer nil "Buffer to push entries to.") +(defvar ebib-search-string nil "Stores the last search string.") +(defvar ebib-editing nil "Indicates what the user is editing. +Its value can be 'strings, 'fields, or 'preamble.") +(defvar ebib-multiline-raw nil "Indicates whether the multiline text being edited is raw.") +(defvar ebib-log-error nil "Indicates whether an error was logged.") +(defvar ebib-local-bibtex-filenames nil + "A buffer-local variable holding a list of the name(s) of that buffer's .bib file(s)") +(make-variable-buffer-local 'ebib-local-bibtex-filenames) +(defvar ebib-syntax-table (make-syntax-table) "Syntax table used for reading .bib files.") +(modify-syntax-entry ?\[ "." ebib-syntax-table) +(modify-syntax-entry ?\] "." ebib-syntax-table) +(modify-syntax-entry ?\( "." ebib-syntax-table) +(modify-syntax-entry ?\) "." ebib-syntax-table) +(modify-syntax-entry ?\" "w" ebib-syntax-table) + +;; the databases + +;; each database is represented by a struct +(defstruct edb + (database (make-hash-table :test 'equal)) ; hashtable containing the database itself + (keys-list nil) ; sorted list of the keys in the database + (cur-entry nil) ; sublist of KEYS-LIST that starts with the current entry + (marked-entries nil) ; list of marked entries + (n-entries 0) ; number of entries stored in this database + (strings (make-hash-table :test 'equal)) ; hashtable with the @STRING definitions + (strings-list nil) ; sorted list of the @STRING abbreviations + (preamble nil) ; string with the @PREAMBLE definition + (filename nil) ; name of the BibTeX file that holds this database + (name nil) ; name of the database + (modified nil) ; has this database been modified? + (make-backup nil) ; do we need to make a backup of the .bib file? + (virtual nil)) ; is this a virtual database? + +;; the master list and the current database +(defvar ebib-databases nil "List of structs containing the databases.") +(defvar ebib-cur-db nil "The database that is currently active.") + +;;;;;; bookkeeping required when editing field values or @STRING definitions + +(defvar ebib-hide-hidden-fields t "If set to T, hidden fields are not shown.") + +;; these two variables are set when the user enters the entry buffer +(defvar ebib-cur-entry-hash nil "The hash table containing the data of the current entry.") +(defvar ebib-cur-entry-fields nil "The fields of the type of the current entry.") + +;; and these two are set by EBIB-FILL-ENTRY-BUFFER and EBIB-FILL-STRINGS-BUFFER, respectively +(defvar ebib-current-field nil "The current field.") +(defvar ebib-current-string nil "The current @STRING definition.") + +;; the prefix key is stored in a variable so that the user can customise it. +(defvar ebib-prefix-key ?\;) + +;; this is an AucTeX variable, but we want to check its value, so let's +;; keep the compiler from complaining. +(eval-when-compile + (defvar TeX-master)) + +;; this is to keep XEmacs from complaining. +(eval-when-compile + (if (featurep 'xemacs) + (defvar mark-active))) + +;; XEmacs has line-number, not line-number-at-pos. +(eval-and-compile + (if (featurep 'xemacs) + (defalias 'line-number-at-pos 'line-number))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; useful macros and functions ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defmacro nor (&rest args) + "Returns T if none of its arguments are true." + `(not (or ,@args))) + +;; we sometimes (often, in fact ;-) need to do something with a string, but +;; take special action (or do nothing) if that string is empty. IF-STR +;; makes that easier: + +(defmacro if-str (bindvar then &rest else) + "Execute THEN only if STRING is nonempty. +Format: (if-str (var value) then-form [else-forms]) VAR is bound +to VALUE, which is evaluated. If VAR is a nonempty string, +THEN-FORM is executed. If VAR is either \"\" or nil, ELSE-FORM is +executed. Returns the value of THEN or of ELSE." + (declare (indent 2)) + `(let ,(list bindvar) + (if (nor (null ,(car bindvar)) + (equal ,(car bindvar) "")) + ,then + ,@else))) + +(defmacro last1 (lst &optional n) + "Returns the last (or Nth last) element of LST." + `(car (last ,lst ,n))) + +;; we sometimes need to walk through lists. these functions yield the +;; element directly preceding or following ELEM in LIST. in order to work +;; properly, ELEM must be unique in LIST, obviously. if ELEM is the +;; first/last element of LIST, or if it is not contained in LIST at all, +;; the result is nil. +(defun next-elem (elem list) + (cadr (member elem list))) + +(defun prev-elem (elem list) + (if (or (equal elem (car list)) + (not (member elem list))) + nil + (last1 list (1+ (length (member elem list)))))) + +(defun read-string-at-point (chars) + "Reads a string at POINT delimited by CHARS and returns it. +CHARS is a string of characters that should not occur in the string." + (save-excursion + (skip-chars-backward (concat "^" chars)) + (let ((beg (point))) + (looking-at-goto-end (concat "[^" chars "]*")) + (buffer-substring-no-properties beg (point))))) + +(defun remove-from-string (string remove) + "Returns a copy of STRING with all the occurrences of REMOVE taken out. +REMOVE can be a regex." + (apply 'concat (split-string string remove))) + +(defun in-string (char string) + "Returns T if CHAR is in STRING, otherwise NIL." + (catch 'found + (do ((len (length string)) + (i 0 (1+ i))) + ((= i len) nil) + (if (eq char (aref string i)) + (throw 'found t))))) + +(defun ensure-extension (string ext) + "Makes sure STRING has the extension EXT, by appending it if necessary. +EXT should be an extension without the dot." + (if (string-match (concat "\\." ext "$") string) + string + (concat string "." ext))) + +(defmacro with-buffer-writable (&rest body) + "Makes the current buffer writable and executes the commands in BODY. +After BODY is executed, the buffer modified flag is unset." + (declare (indent defun)) + `(unwind-protect + (let ((buffer-read-only nil)) + ,@body) + (set-buffer-modified-p nil))) + +(defmacro safe-write-region (start end filename &optional append visit lockname mustbenew) + "XEmacs does not have the MUSTBENEW argument, so this is a way to implement it." + (if (featurep 'xemacs) + `(if (and (file-exists-p ,filename) + (not (y-or-n-p (format "File %s already exists; overwrite anyway? " ,filename)))) + (error "File %s exist" ,filename) + (write-region ,start ,end ,filename ,append ,visit ,lockname)) + `(write-region ,start ,end ,filename ,append ,visit ,lockname ,mustbenew))) + +(defun symbol-or-string (x) + "Returns the symbol-name of X if X is a symbol, otherwise return X. +Much like SYMBOL-NAME, except it does not throw an error if X is +not a symbol." + (if (symbolp x) + (symbol-name x) + x)) + +;; XEmacs doesn't know about propertize... +(if (not (fboundp 'propertize)) + (defun propertize (string &rest properties) + "Return a copy of STRING with text properties added. +First argument is the string to copy. Remaining arguments form a +sequence of PROPERTY VALUE pairs for text properties to add to +the result." + (let ((new-string (copy-sequence string))) + (add-text-properties 0 (length new-string) properties new-string) + new-string))) + +(defun region-active () + (if (featurep 'xemacs) + (region-active-p) + mark-active)) + +;; RAW-P determines if STRING is raw. note that we cannot do this by +;; simply checking whether STRING begins with { and ends with } (or +;; begins and ends with "), because something like "{abc} # D # {efg}" +;; would then be incorrectly recognised as non-raw. so we need to do +;; the following: take out everything that is between braces or +;; quotes, and see if anything is left. if there is, the original +;; string was raw, otherwise it was not. +;; +;; so i first check whether the string begins with { or ". if not, we +;; certainly have a raw string. (RAW-P recognises this through the default +;; clause of the COND.) if the first character is { or ", we first take out +;; every occurrence of backslash-escaped { and } or ", so that the rest of +;; the function does not get confused over them. +;; +;; then, if the first character is {, i use REMOVE-FROM-STRING to take out +;; every occurrence of the regex "{[^{]*?}", which translates to "the +;; smallest string that starts with { and ends with }, and does not contain +;; another {. IOW, it takes out the innermost braces and their +;; contents. because braces may be embedded, we have to repeat this step +;; until no more balanced braces are found in the string. (note that it +;; would be unwise to check for just the occurrence of { or }, because that +;; would throw RAW-P in an infinite loop if a string contains an unbalanced +;; brace.) +;; +;; for strings beginning with " i do the same, except that it is not +;; necessary to repeat this in a WHILE loop, for the simple reason that +;; strings surrounded with double quotes cannot be embedded; i.e., +;; "ab"cd"ef" is not a valid (BibTeX) string, while {ab{cd}ef} is. +;; +;; note: because these strings are to be fed to BibTeX and ultimately +;; (La)TeX, it might seem that we don't need to worry about strings +;; containing unbalanced braces, because (La)TeX would choke on them. but +;; the user may inadvertently enter such a string, and we therefore need to +;; be able to handle it. (alternatively, we could perform a check on +;; strings and warn the user.) + +(defun raw-p (string) + "Non-nil if STRING is raw." + (when (stringp string) + (cond + ((eq (string-to-char string) ?\{) + ;; we remove all occurrences of `\{' and of `\}' from the string: + (let ((clear-str (remove-from-string (remove-from-string string "[\\][{]") + "[\\][}]"))) + (while (and (in-string ?\{ clear-str) (in-string ?\} clear-str)) + (setq clear-str (remove-from-string clear-str "{[^{]*?}"))) + (> (length clear-str) 0))) + ((eq (string-to-char string) ?\") + (let ((clear-str (remove-from-string string "[\\][\"]"))) ; remove occurrences of `\"' + (setq clear-str (remove-from-string clear-str "\"[^\"]*?\"")) + (> (length clear-str) 0))) + (t t)))) + +(defun to-raw (string) + "Converts a string to its raw counterpart." + (if (and (stringp string) + (not (raw-p string))) + (substring string 1 -1) + string)) + +(defun from-raw (string) + "Converts a raw string to a non-raw one." + (if (raw-p string) + (concat "{" string "}") + string)) + +(defun multiline-p (string) + "True if STRING is multiline." + (if (stringp string) + (string-match "\n" string))) + +(defun first-line (string) + "Returns the first line of a multi-line string." + (string-match "\n" string) + (substring string 0 (match-beginning 0))) + +(defun sort-in-buffer (limit str) + "Moves POINT to the right position to insert STR in a buffer with lines sorted A-Z." + (let ((upper limit) + middle) + (when (> limit 0) + (let ((lower 0)) + (goto-char (point-min)) + (while (progn + (setq middle (/ (+ lower upper 1) 2)) + (goto-line middle) ; if this turns out to be where we need to be, + (beginning-of-line) ; this puts POINT at the right spot. + (> (- upper lower) 1)) ; if upper and lower differ by only 1, we have found the + ; position to insert the entry in. + (save-excursion + (let ((beg (point))) + (end-of-line) + (if (string< (buffer-substring-no-properties beg (point)) str) + (setq lower middle) + (setq upper middle))))))))) + +(defun match-all (match-str string) + "Highlights all the matches of MATCH-STR in STRING. +The return value is a list of two elements: the first is the +modified string, the second either t or nil, indicating whether a +match was found at all." + (do ((counter 0 (match-end 0))) + ((not (string-match match-str string counter)) (values string (not (= counter 0)))) + (add-text-properties (match-beginning 0) (match-end 0) '(face highlight) string))) + +(defun looking-at-goto-end (str &optional match) + "Like LOOKING-AT but moves point to the end of the matching string. +MATCH acts just like the argument to MATCH-END, and defaults to 0." + (or match (setq match 0)) + (let ((case-fold-search t)) + (if (looking-at str) + (goto-char (match-end match))))) + +;; this needs to be wrapped in an eval-and-compile, to keep Emacs from +;; complaining that ebib-execute-helper isn't defined when it compiles +;; ebib-execute-when. +(eval-and-compile + (defun ebib-execute-helper (env) + "Helper function for EBIB-EXECUTE-WHEN." + (cond + ((eq env 'entries) + '(and ebib-cur-db + (edb-cur-entry ebib-cur-db))) + ((eq env 'marked-entries) + '(and ebib-cur-db + (edb-marked-entries ebib-cur-db))) + ((eq env 'database) + 'ebib-cur-db) + ((eq env 'real-db) + '(and ebib-cur-db + (not (edb-virtual ebib-cur-db)))) + ((eq env 'virtual-db) + '(and ebib-cur-db + (edb-virtual ebib-cur-db))) + ((eq env 'no-database) + '(not ebib-cur-db)) + (t t)))) + +(defmacro ebib-execute-when (&rest forms) + "Macro to facilitate writing Ebib functions. +This functions essentially like a COND clause: the basic format +is (ebib-execute-when FORMS ...), where each FORM is built up +as (ENVIRONMENTS BODY). ENVIRONMENTS is a list of symbols (not +quoted) that specify under which conditions BODY is to be +executed. Valid symbols are: + +entries: execute when there are entries in the database, +marked-entries: execute when there are marked entries in the database, +database: execute if there is a database, +no-database: execute if there is no database, +real-db: execute when there is a database and it is real, +virtual-db: execute when there is a database and it is virtual, +default: execute if all else fails. + +Just like with COND, only one form is actually executed, the +first one that matches. If ENVIRONMENT contains more than one +condition, BODY is executed if they all match (i.e., the +conditions are AND'ed.)" + (declare (indent defun)) + `(cond + ,@(mapcar #'(lambda (form) + (cons (if (= 1 (length (car form))) + (ebib-execute-helper (caar form)) + `(and ,@(mapcar #'(lambda (env) + (ebib-execute-helper env)) + (car form)))) + (cdr form))) + forms))) + +;; the numeric prefix argument is 1 if the user gave no prefix argument at +;; all. the raw prefix argument is not always a number. so we need to do +;; our own conversion. +(defun ebib-prefix (num) + (when (numberp num) + num)) + +(defun ebib-called-with-prefix () + "Returns T if the command was called with a prefix key." + (if (featurep 'xemacs) + (member (character-to-event ebib-prefix-key) (append (this-command-keys) nil)) + (member (event-convert-list (list ebib-prefix-key)) + (append (this-command-keys-vector) nil)))) + +(defmacro ebib-export-to-db (num message copy-fn) + "Exports data to another database. +NUM is the number of the database to which the data is to be copied. + +MESSAGE is a string displayed in the echo area if the export was +succesful. It must contain a %d directive, which is used to +display the database number to which the entry was exported. + +COPY-FN is the function that actually copies the relevant +data. It must take as argument the database to which the data is +to be copied. COPY-FN must return T if the copying was +successful, and NIL otherwise." + (let ((goal-db (gensym))) + `(let ((,goal-db (nth (1- ,num) ebib-databases))) + (cond + ((not ,goal-db) + (error "Database %d does not exist" ,num)) + ((edb-virtual ,goal-db) + (error "Database %d is virtual" ,num)) + (t (when (funcall ,copy-fn ,goal-db) + (ebib-set-modified t ,goal-db) + (message ,message ,num))))))) + +(defmacro ebib-export-to-file (prompt-string message insert-fn) + "Exports data to a file. +PROMPT-STRING is the string that is used to ask for the filename +to export to. INSERT-FN must insert the data to be exported into +the current buffer: it is called within a WITH-TEMP-BUFFER, whose +contents is appended to the file the user enters. + +MESSAGE is shown in the echo area when the export was +successful. It must contain a %s directive, which is used to +display the actual filename." + (let ((filename (gensym))) + `(let ((insert-default-directory (not ebib-export-filename))) + (if-str (,filename (read-file-name + ,prompt-string "~/" nil nil ebib-export-filename)) + (with-temp-buffer + (funcall ,insert-fn) + (append-to-file (point-min) (point-max) ,filename) + (setq ebib-export-filename ,filename)))))) + +(defun ebib-temp-window () + "Returns a window to be used for temporary use." + (if (eq ebib-layout 'full) + (get-buffer-window ebib-entry-buffer) + ebib-pre-ebib-window)) + +(defun ebib-get-obl-fields (entry-type) + "Returns the obligatory fields of ENTRY-TYPE." + (nth 1 (assoc entry-type ebib-entry-types))) + +(defun ebib-get-opt-fields (entry-type) + "Returns the optional fields of ENTRY-TYPE." + (nth 2 (assoc entry-type ebib-entry-types))) + +(defun ebib-get-all-fields (entry-type) + "Returns all the fields of ENTRY-TYPE." + (cons 'type* (append (ebib-get-obl-fields entry-type) + (ebib-get-opt-fields entry-type) + ebib-additional-fields))) + +(defmacro ebib-retrieve-entry (entry-key db) + "Returns the hash table of the fields stored in DB under ENTRY-KEY." + `(gethash ,entry-key (edb-database ,db))) + +(defun ebib-erase-buffer (buffer) + (set-buffer buffer) + (with-buffer-writable + (erase-buffer))) + +(defun ebib-make-highlight (begin end buffer) + (let (highlight) + (if (featurep 'xemacs) + (progn + (setq highlight (make-extent begin end buffer)) + (set-extent-face highlight 'highlight)) + (progn + (setq highlight (make-overlay begin end buffer)) + (overlay-put highlight 'face 'highlight))) + highlight)) + +(defun ebib-move-highlight (highlight begin end buffer) + (if (featurep 'xemacs) + (set-extent-endpoints highlight begin end buffer) + (move-overlay highlight begin end buffer))) + +(defun ebib-highlight-start (highlight) + (if (featurep 'xemacs) + (extent-start-position highlight) + (overlay-start highlight))) + +(defun ebib-highlight-end (highlight) + (if (featurep 'xemacs) + (extent-end-position highlight) + (overlay-end highlight))) + +(defun ebib-delete-highlight (highlight) + (if (featurep 'xemacs) + (detach-extent highlight) + (delete-overlay highlight))) + +(defun ebib-set-index-highlight () + (set-buffer ebib-index-buffer) + (beginning-of-line) + (let ((beg (point))) + (if ebib-index-display-fields + (end-of-line) + (skip-chars-forward "^ ")) + (ebib-move-highlight ebib-index-highlight beg (point) ebib-index-buffer) + (beginning-of-line))) + +(defun ebib-set-fields-highlight () + (set-buffer ebib-entry-buffer) + (beginning-of-line) + (let ((beg (point))) + (looking-at-goto-end "[^ \t\n\f]*") + (ebib-move-highlight ebib-fields-highlight beg (point) ebib-entry-buffer) + (beginning-of-line))) + +(defun ebib-set-strings-highlight () + (set-buffer ebib-strings-buffer) + (beginning-of-line) + (let ((beg (point))) + (looking-at-goto-end "[^ \t\n\f]*") + (ebib-move-highlight ebib-strings-highlight beg (point) ebib-strings-buffer) + (beginning-of-line))) + +(defun ebib-display-entry (entry-key) + "Displays ENTRY-KEY in the index buffer at POINT." + (set-buffer ebib-index-buffer) + (insert (format "%-30s %s\n" + entry-key + (if ebib-index-display-fields + (let ((cur-entry-hash (ebib-retrieve-entry entry-key ebib-cur-db))) + (mapconcat #'(lambda (field) + (or + (to-raw (gethash field cur-entry-hash)) + "")) + ebib-index-display-fields + "; ")) + "")))) + +(defun ebib-redisplay-current-field () + "Redisplays the contents of the current field in the entry buffer." + (set-buffer ebib-entry-buffer) + (if (eq ebib-current-field 'crossref) + (progn + (ebib-fill-entry-buffer) + (setq ebib-current-field 'crossref) + (re-search-forward "^crossref") + (ebib-set-fields-highlight)) + (with-buffer-writable + (goto-char (ebib-highlight-start ebib-fields-highlight)) + (let ((beg (point))) + (end-of-line) + (delete-region beg (point))) + (insert (format "%-17s " (symbol-name ebib-current-field)) + (ebib-get-field-highlighted ebib-current-field ebib-cur-entry-hash)) + (ebib-set-fields-highlight)))) + +(defun ebib-redisplay-current-string () + "Redisplays the current string definition in the strings buffer." + (set-buffer ebib-strings-buffer) + (with-buffer-writable + (let ((str (to-raw (gethash ebib-current-string (edb-strings ebib-cur-db))))) + (goto-char (ebib-highlight-start ebib-strings-highlight)) + (let ((beg (point))) + (end-of-line) + (delete-region beg (point))) + (insert (format "%-18s %s" ebib-current-string + (if (multiline-p str) + (concat "+" (first-line str)) + (concat " " str)))) + (ebib-set-strings-highlight)))) + +(defun ebib-move-to-field (field direction) + "Moves the fields overlay to the line containing FIELD. +If DIRECTION is positive, searches forward, if DIRECTION is +negative, searches backward. If DIRECTION is 1 or -1, searches +from POINT, if DIRECTION is 2 or -2, searches from beginning or +end of buffer. If FIELD is not found in the entry buffer, the +overlay is not moved. FIELD must be a symbol." + + ;;Note: this function does NOT change the value of EBIB-CURRENT-FIELD! + + (set-buffer ebib-entry-buffer) + (if (eq field 'type*) + (goto-char (point-min)) + (multiple-value-bind (fn start limit) (if (>= direction 0) + (values 're-search-forward (point-min) (point-max)) + (values 're-search-backward (point-max) (point-min))) + ;; make sure we can get back to our original position, if the field + ;; cannot be found in the buffer: + (let ((current-pos (point))) + (when (evenp direction) + (goto-char start)) + (unless (funcall fn (concat "^" (symbol-name field)) limit t) + (goto-char current-pos))))) + (ebib-set-fields-highlight)) + +(defun ebib-create-collection (hashtable) + "Creates a list from the keys in HASHTABLE that can be used as COLLECTION in COMPLETING-READ. +The keys of HASHTABLE must be either symbols or strings." + (let ((result nil)) + (maphash #'(lambda (x y) + (setq result (cons (cons (symbol-or-string x) + 0) + result))) + hashtable) + result)) + +(defun ebib-get-field-highlighted (field current-entry &optional match-str) + ;; note: we need to work on a copy of the string, otherwise the highlights + ;; are made to the string as stored in the database. hence copy-sequence. + (let ((case-fold-search t) + (string (copy-sequence (gethash field current-entry))) + (raw " ") + (multiline " ") + (matched nil)) + ;; we have to do a couple of things now: + ;; - remove {} or "" around the string, if they're there + ;; - search for match-str + ;; - properly adjust the string if it's multiline + ;; but all this is not necessary if there was no string + (if (null string) + (let* ((xref (to-raw (gethash 'crossref current-entry))) + (xref-entry (ebib-retrieve-entry xref ebib-cur-db))) + (when xref-entry + (setq string (gethash field xref-entry)) + (if string + (setq string (propertize (to-raw string) 'face 'ebib-crossref-face 'fontified t)) + (setq string "")))) + (if (raw-p string) + (setq raw "*") + (setq string (to-raw string))) ; we have to make the string look nice + (when match-str + (multiple-value-setq (string matched) (match-all match-str string))) + (when (multiline-p string) + ;; IIUC PROPERTIZE shouldn't be necessary here, as the variable + ;; multiline is local and therefore the object it refers to should + ;; be GC'ed when the function returns. but for some reason, the + ;; plus sign is persistent, and if it's been highlighted as the + ;; result of a search, it stays that way. + (setq multiline (propertize "+" 'face nil)) + (setq string (first-line string)))) + (when (and matched + (string= multiline "+")) + (add-text-properties 0 1 '(face highlight) multiline)) + (concat raw multiline string))) + +(defun ebib-format-fields (entry fn &optional match-str) + (let* ((entry-type (gethash 'type* entry)) + (obl-fields (ebib-get-obl-fields entry-type)) + (opt-fields (ebib-get-opt-fields entry-type))) + (funcall fn (format "%-19s %s\n" "type" entry-type)) + (mapc #'(lambda (fields) + (funcall fn "\n") + (mapcar #'(lambda (field) + (unless (and (get field 'ebib-hidden) + ebib-hide-hidden-fields) + (funcall fn (format "%-17s " field)) + (funcall fn (or + (ebib-get-field-highlighted field entry match-str) + "")) + (funcall fn "\n"))) + fields)) + (list obl-fields opt-fields ebib-additional-fields)))) + +(defun ebib-fill-entry-buffer (&optional match-str) + "Fills the entry buffer with the fields of the current entry. +MATCH-STRING is a regexp that will be highlighted when it occurs in the +field contents." + (set-buffer ebib-entry-buffer) + (with-buffer-writable + (erase-buffer) + (when (and ebib-cur-db ; do we have a database? + (edb-keys-list ebib-cur-db) ; does it contain entries? + (gethash (car (edb-cur-entry ebib-cur-db)) + (edb-database ebib-cur-db))) ; does the current entry exist? + (ebib-format-fields (gethash (car (edb-cur-entry ebib-cur-db)) + (edb-database ebib-cur-db)) 'insert match-str) + (setq ebib-current-field 'type*) + (goto-char (point-min)) + (ebib-set-fields-highlight)))) +;; (skip-chars-forward "^ ")))) + +(defun ebib-set-modified (mod &optional db) + "Sets the modified flag of the database DB to MOD. +If DB is nil, it defaults to the current database, and the +modified flag of the index buffer is also (re)set. MOD must be +either T or NIL." + (unless db + (setq db ebib-cur-db)) + (setf (edb-modified db) mod) + (when (eq db ebib-cur-db) + (save-excursion + (set-buffer ebib-index-buffer) + (set-buffer-modified-p mod)))) + +(defun ebib-modified-p () + "Checks if any of the databases in Ebib were modified. +Returns the first modified database, or NIL if none was modified." + (let ((db (car ebib-databases))) + (while (and db + (not (edb-modified db))) + (setq db (next-elem db ebib-databases))) + db)) + +(defun ebib-create-new-database (&optional db) + "Creates a new database instance and returns it. +If DB is set to a database, the new database is a copy of DB." + (let ((new-db + (if (edb-p db) + (copy-edb db) + (make-edb)))) + (setq ebib-databases (append ebib-databases (list new-db))) + new-db)) + +(defun ebib-match-paren-forward (limit) + "Moves forward to the closing parenthesis matching the opening parenthesis at POINT. +This function handles parentheses () and braces {}. Does not +search/move beyond LIMIT. Returns T if a matching parenthesis was +found, NIL otherwise. If point was not at an opening parenthesis +at all, NIL is returned and point is not moved. If point was at +an opening parenthesis but no matching closing parenthesis was +found, an error is logged and point is moved one character +forward to allow parsing to continue." + (cond + ((eq (char-after) ?\{) + (ebib-match-brace-forward limit)) + ((eq (char-after) ?\() + ;; we wrap this in a condition-case because we need to log the error + ;; message outside of the save-restriction, otherwise we get the wrong + ;; line number. + (condition-case nil + (save-restriction + (narrow-to-region (point) limit) + ;; this is really a hack. we want to allow unbalanced parentheses in + ;; field values (bibtex does), so we cannot use forward-list + ;; here. for the same reason, looking for the matching paren by hand + ;; is pretty complicated. however, balanced parentheses can only be + ;; used to enclose entire entries (or @STRINGs or @PREAMBLEs) so we + ;; can be pretty sure we'll find it right before the next @ at the + ;; start of a line, or right before the end of the file. + (re-search-forward "^@" nil 0) + (skip-chars-backward "@ \n\t\f") + (forward-char -1) + (if (eq (char-after) ?\)) + t + (goto-char (1+ (point-min))) + (error ""))) + (error (ebib-log 'error "Error in line %d: Matching closing parenthesis not found!" (line-number-at-pos)) + nil))) + (t nil))) + +(defun ebib-match-delim-forward (limit) + "Moves forward to the closing delimiter matching the opening delimiter at POINT. +This function handles braces {} and double quotes \"\". Does not +search/move beyond LIMIT. Returns T if a matching delimiter was +found, NIL otherwise. If point was not at an opening delimiter at +all, NIL is returned and point is not moved. If point was at an +opening delimiter but no matching closing delimiter was found, an +error is logged and point is moved one character forward to allow +parsing to continue." + (cond + ((eq (char-after) ?\") + (ebib-match-quote-forward limit)) + ((eq (char-after) ?\{) + (ebib-match-brace-forward limit)) + (t nil))) + +(defun ebib-match-brace-forward (limit) + "Moves forward to the closing brace matching the opening brace at POINT. +Does not search/move beyond LIMIT. Returns T if a matching brace +was found, NIL otherwise. If point was not at an opening brace at +all, NIL is returned and point is not moved. If point was at an +opening brace but no matching closing brace was found, an error +is logged and point is moved one character forward to allow +parsing to continue." + (when (eq (char-after) ?\{) ; make sure we're really on a brace, otherwise return nil + (condition-case nil + (save-restriction + (narrow-to-region (point) limit) + (progn + (forward-list) + ;; all of ebib expects that point moves to the closing + ;; parenthesis, not right after it, so we adjust. + (forward-char -1) + t)) ; return t because a matching brace was found + (error (progn + (ebib-log 'error "Error in line %d: Matching closing brace not found!" (line-number-at-pos)) + (forward-char 1) + nil))))) + +(defun ebib-match-quote-forward (limit) + "Moves to the closing double quote matching the quote at POINT. +Does not search/move beyond LIMIT. Returns T if a matching quote +was found, NIL otherwise. If point was not at a double quote at +all, NIL is returned and point is not moved. If point was at a +quote but no matching closing quote was found, an error is logged +and point is moved one character forward to allow parsing to +continue." + (when (eq (char-after (point)) ?\") ; make sure we're on a double quote. + (condition-case nil + (save-restriction + (narrow-to-region (point) limit) + (while (progn + (forward-char) ; move forward because we're on a double quote + (skip-chars-forward "^\"") ; search the next double quote + (eq (char-before) ?\\))) ; if it's preceded by a backslash, keep on searching + (or (eq (char-after) ?\") + (progn + (goto-char (1+ (point-min))) + (error "")))) + (error (ebib-log 'error "Error in line %d: Matching closing quote not found!" (line-number-at-pos)) + nil)))) + +(defun ebib-insert-entry (entry-key fields db &optional sort timestamp) + "Stores the entry defined by ENTRY-KEY and FIELDS into DB. +Optional argument SORT indicates whether the KEYS-LIST must be +sorted after insertion. Default is NIL. Optional argument +TIMESTAMP indicates whether a timestamp is to be added to the +entry. Note that for a timestamp to be added, EBIB-USE-TIMESTAMP +must also be set to T." + (when (and timestamp ebib-use-timestamp) + (puthash 'timestamp (from-raw (format-time-string ebib-timestamp-format)) fields)) + (puthash entry-key fields (edb-database db)) + (ebib-set-modified t db) + (setf (edb-n-entries db) (1+ (edb-n-entries db))) + (setf (edb-keys-list db) + (if sort + (sort (cons entry-key (edb-keys-list db)) 'string<) + (cons entry-key (edb-keys-list db))))) + +(defun ebib-insert-string (abbr string db &optional sort) + "Stores the @STRING definition defined by ABBR and STRING into DB. +Optional argument SORT indicates whether the STRINGS-LIST must be sorted +after insertion. When loading or merging a file, for example, it is more +economic to sort KEYS-LIST manually after all entries in the file have been +added." + (puthash abbr (from-raw string) (edb-strings db)) + (ebib-set-modified t db) + (setf (edb-strings-list db) + (if sort + (sort (cons abbr (edb-strings-list db)) 'string<) + (cons abbr (edb-strings-list db))))) + +(defmacro ebib-cur-entry-key () + "Returns the key of the current entry in EBIB-CUR-DB." + `(car (edb-cur-entry ebib-cur-db))) + +(defun ebib-search-key-in-buffer (entry-key) + "Searches ENTRY-KEY in the index buffer. + +Moves point to the first character of the key and returns point." + (goto-char (point-min)) + (search-forward entry-key) + (beginning-of-line) + (point)) + +;; when we sort entries, we either use string< on the entry keys, or +;; ebib-entry<, if the user has defined a sort order. + +(defun ebib-entry< (x y) + "Returns T if entry X is smaller than entry Y. +The entries are compared based on the fields listed in EBIB-SORT-ORDER. X +and Y should be keys of entries in the current database." + (let* ((sort-list ebib-sort-order) + (sortstring-x (to-raw (ebib-get-sortstring x (car sort-list)))) + (sortstring-y (to-raw (ebib-get-sortstring y (car sort-list))))) + (while (and sort-list + (string= sortstring-x sortstring-y)) + (setq sort-list (cdr sort-list)) + (setq sortstring-x (to-raw (ebib-get-sortstring x (car sort-list)))) + (setq sortstring-y (to-raw (ebib-get-sortstring y (car sort-list))))) + (if (and sortstring-x sortstring-y) + (string< sortstring-x sortstring-y) + (string< x y)))) + +(defun ebib-get-sortstring (entry-key sortkey-list) + "Returns the field value on which the entry ENTRY-KEY is to be sorted. +ENTRY-KEY must be the key of an entry in the current database. SORTKEY-LIST +is a list of fields that are considered in order for the sort value." + (let ((sort-string nil)) + (while (and sortkey-list + (null (setq sort-string (gethash (car sortkey-list) + (ebib-retrieve-entry entry-key ebib-cur-db))))) + (setq sortkey-list (cdr sortkey-list))) + sort-string)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; main program execution ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;###autoload +(defun ebib () + "Ebib, a BibTeX database manager." + (interactive) + (if (or (equal (window-buffer) ebib-index-buffer) + (equal (window-buffer) ebib-entry-buffer)) + (error "Ebib already active") + ;; we save the buffer from which ebib is called + (setq ebib-push-buffer (current-buffer)) + ;; initialize ebib if required + (unless ebib-initialized + (ebib-init) + (if ebib-preload-bib-files + (mapc #'(lambda (file) + (ebib-load-bibtex-file file)) + ebib-preload-bib-files))) + ;; if ebib is visible, we just switch to the index buffer + (let ((index-window (get-buffer-window ebib-index-buffer))) + (if index-window + (select-window index-window nil) + (ebib-setup-windows))))) + +(defun ebib-setup-windows () + "Creates the window configuration we want for Ebib in the +current window." + ;; we save the current window configuration. + (setq ebib-saved-window-config (current-window-configuration)) + (if (eq ebib-layout 'full) + (delete-other-windows) + (setq ebib-pre-ebib-window (selected-window)) + (let ((ebib-window (split-window (selected-window) (- (window-width) ebib-layout) t))) + (select-window ebib-window nil))) + (let* ((index-window (selected-window)) + (entry-window (split-window index-window ebib-index-window-size))) + (switch-to-buffer ebib-index-buffer) + (set-window-buffer entry-window ebib-entry-buffer) + (unless (eq ebib-layout 'full) + (set-window-dedicated-p index-window t) + (set-window-dedicated-p entry-window t)))) + +(defun ebib-init () + "Initialises Ebib. +This function sets all variables to their initial values, creates the +buffers and reads the rc file." + (setq ebib-cur-entry-hash nil + ebib-current-field nil + ebib-minibuf-hist nil + ebib-saved-window-config nil) + (put 'timestamp 'ebib-hidden t) + (load "~/.ebibrc" t) + (ebib-create-buffers) + (setq ebib-index-highlight (ebib-make-highlight 1 1 ebib-index-buffer)) + (setq ebib-fields-highlight (ebib-make-highlight 1 1 ebib-entry-buffer)) + (setq ebib-strings-highlight (ebib-make-highlight 1 1 ebib-strings-buffer)) + (setq ebib-initialized t)) + +(defun ebib-create-buffers () + "Creates the buffers for Ebib." + ;; first we create a buffer for multiline editing. this one does *not* + ;; have a name beginning with a space, because undo-info is normally + ;; present in an edit buffer. + (setq ebib-multiline-buffer (get-buffer-create "*Ebib-edit*")) + (set-buffer ebib-multiline-buffer) + (ebib-multiline-edit-mode) + ;; then we create a buffer to hold the fields of the current entry. + (setq ebib-entry-buffer (get-buffer-create " *Ebib-entry*")) + (set-buffer ebib-entry-buffer) + (ebib-entry-mode) + ;; then we create a buffer to hold the @STRING definitions + (setq ebib-strings-buffer (get-buffer-create " *Ebib-strings*")) + (set-buffer ebib-strings-buffer) + (ebib-strings-mode) + ;; the log buffer + (setq ebib-log-buffer (get-buffer-create " *Ebib-log*")) + (set-buffer ebib-log-buffer) + (erase-buffer) + (insert "Ebib log messages\n\n(Press C-v or SPACE to scroll down, M-v or `b' to scroll up, `q' to quit.)\n\n\n") + (ebib-log-mode) + ;; and lastly we create a buffer for the entry keys. + (setq ebib-index-buffer (get-buffer-create " none")) + (set-buffer ebib-index-buffer) + (ebib-index-mode)) + +(defun ebib-quit () + "Quits Ebib. +The Ebib buffers are killed, all variables except the keymaps are set to nil." + (interactive) + (when (if (ebib-modified-p) + (yes-or-no-p "There are modified databases. Quit anyway? ") + (y-or-n-p "Quit Ebib? ")) + (mapc #'(lambda (buffer) + (kill-buffer buffer)) + (list ebib-entry-buffer + ebib-index-buffer + ebib-strings-buffer + ebib-multiline-buffer + ebib-log-buffer)) + (setq ebib-databases nil + ebib-index-buffer nil + ebib-entry-buffer nil + ebib-initialized nil + ebib-index-highlight nil + ebib-fields-highlight nil + ebib-strings-highlight nil + ebib-export-filename nil + ebib-pre-ebib-window nil) + (set-window-configuration ebib-saved-window-config) + (message ""))) + +(defun ebib-kill-emacs-query-function () + "Ask if the user wants to save the database loaded in Ebib when Emacs is +killed and the database has been modified." + (if (not (ebib-modified-p)) + t + (if (y-or-n-p "Save all unsaved Ebib databases? ") + (progn + (ebib-save-all-databases) + t) + (yes-or-no-p "Ebib database was modified. Kill anyway? ")))) + +(add-hook 'kill-emacs-query-functions 'ebib-kill-emacs-query-function) + +;;;;;;;;;;;;;;;; +;; index-mode ;; +;;;;;;;;;;;;;;;; + +(eval-and-compile + (define-prefix-command 'ebib-prefix-map) + (suppress-keymap ebib-prefix-map) + (defvar ebib-prefixed-functions '(ebib-delete-entry + ebib-latex-entries + ebib-mark-entry + ebib-print-entries + ebib-push-bibtex-key + ebib-export-entry))) + +;; macro to redefine key bindings. + +(defmacro ebib-key (buffer key &optional command) + (cond + ((eq buffer 'index) + (let ((one `(define-key ebib-index-mode-map ,key (quote ,command))) + (two (when (or (null command) + (member command ebib-prefixed-functions)) + `(define-key ebib-prefix-map ,key (quote ,command))))) + (if two + `(progn ,one ,two) + one))) + ((eq buffer 'entry) + `(define-key ebib-entry-mode-map ,key (quote ,command))) + ((eq buffer 'strings) + `(define-key ebib-strings-mode-map ,key (quote ,command))) + ((eq buffer 'mark-prefix) + `(progn + (define-key ebib-index-mode-map (format "%c" ebib-prefix-key) nil) + (define-key ebib-index-mode-map ,key 'ebib-prefix-map) + (setq ebib-prefix-key (string-to-char ,key)))))) + +(defvar ebib-index-mode-map + (let ((map (make-keymap))) + (suppress-keymap map) + map) + "Keymap for the ebib index buffer.") + +;; we define the keys with ebib-key rather than with define-key, because +;; that automatically sets up ebib-prefix-map as well. +(ebib-key index [up] ebib-prev-entry) +(ebib-key index [down] ebib-next-entry) +(ebib-key index [right] ebib-next-database) +(ebib-key index [left] ebib-prev-database) +(ebib-key index [prior] ebib-index-scroll-down) +(ebib-key index [next] ebib-index-scroll-up) +(ebib-key index [home] ebib-goto-first-entry) +(ebib-key index [end] ebib-goto-last-entry) +(ebib-key index [return] ebib-select-entry) +(ebib-key index " " ebib-index-scroll-up) +(ebib-key index "/" ebib-search) +(ebib-key index "&" ebib-virtual-db-and) +(ebib-key index "|" ebib-virtual-db-or) +(ebib-key index "~" ebib-virtual-db-not) +(ebib-key index ";" ebib-prefix-map) +(ebib-key index "a" ebib-add-entry) +(ebib-key index "b" ebib-index-scroll-down) +(ebib-key index "c" ebib-close-database) +(ebib-key index "C" ebib-customize) +(ebib-key index "d" ebib-delete-entry) +(ebib-key index "e" ebib-edit-entry) +(ebib-key index "E" ebib-edit-keyname) +(ebib-key index "f" ebib-view-file) +(ebib-key index "F" ebib-follow-crossref) +(ebib-key index "g" ebib-goto-first-entry) +(ebib-key index "G" ebib-goto-last-entry) +(ebib-key index "H" ebib-toggle-hidden) +(ebib-key index "j" ebib-next-entry) +(ebib-key index "J" ebib-switch-to-database) +(ebib-key index "k" ebib-prev-entry) +(ebib-key index "l" ebib-show-log) +(ebib-key index "L" ebib-latex-entries) +(ebib-key index "m" ebib-mark-entry) +(ebib-key index "M" ebib-merge-bibtex-file) +(ebib-key index "n" ebib-search-next) +(ebib-key index "N" ebib-search-crossref) +(ebib-key index [(control n)] ebib-next-entry) +(ebib-key index [(meta n)] ebib-index-scroll-up) +(ebib-key index "o" ebib-load-bibtex-file) +(ebib-key index "p" ebib-push-bibtex-key) +(ebib-key index [(control p)] ebib-prev-entry) +(ebib-key index [(meta p)] ebib-index-scroll-down) +(ebib-key index "P" ebib-print-entries) +(ebib-key index "r" ebib-edit-preamble) +(ebib-key index "q" ebib-quit) +(ebib-key index "s" ebib-save-current-database) +(ebib-key index "S" ebib-save-all-databases) +(ebib-key index "t" ebib-edit-strings) +(ebib-key index "u" ebib-browse-url) +(ebib-key index "V" ebib-print-filter) +(ebib-key index "w" ebib-write-database) +(ebib-key index "x" ebib-export-entry) +(ebib-key index "\C-xb" ebib-leave-ebib-windows) +(ebib-key index "\C-xk" ebib-quit) +(ebib-key index "X" ebib-export-preamble) +(ebib-key index "z" ebib-leave-ebib-windows) +(ebib-key index "Z" ebib-lower) + +(defun ebib-switch-to-database-nth (key) + (interactive (list (if (featurep 'xemacs) + (event-key last-command-event) + last-command-event))) + (ebib-switch-to-database (- (if (featurep 'xemacs) + (char-to-int key) + key) 48))) + +(mapc #'(lambda (key) + (define-key ebib-index-mode-map (format "%d" key) + 'ebib-switch-to-database-nth)) + '(1 2 3 4 5 6 7 8 9)) + +(define-derived-mode ebib-index-mode + fundamental-mode "Ebib-index" + "Major mode for the Ebib index buffer." + (setq buffer-read-only t) + (setq truncate-lines t)) + +(defun ebib-fill-index-buffer () + "Fills the index buffer with the list of keys in EBIB-CUR-DB. +If EBIB-CUR-DB is nil, the buffer is just erased and its name set +to \"none\"." + (set-buffer ebib-index-buffer) + (let ((buffer-read-only nil)) + (erase-buffer) + (if ebib-cur-db + (progn + ;; we may call this function when there are no entries in the + ;; database. if so, we don't need to do this: + (when (edb-cur-entry ebib-cur-db) + (mapc #'(lambda (entry) + (ebib-display-entry entry) + (when (member entry (edb-marked-entries ebib-cur-db)) + (save-excursion + (let ((beg (progn + (beginning-of-line) + (point)))) + (skip-chars-forward "^ ") + (add-text-properties beg (point) '(face ebib-marked-face)))))) + (edb-keys-list ebib-cur-db)) + (goto-char (point-min)) + (re-search-forward (format "^%s " (ebib-cur-entry-key))) + (beginning-of-line) + (ebib-set-index-highlight)) + (set-buffer-modified-p (edb-modified ebib-cur-db)) + (rename-buffer (concat (format " %d:" (1+ (- (length ebib-databases) + (length (member ebib-cur-db ebib-databases))))) + (edb-name ebib-cur-db)))) + (rename-buffer " none")))) + +(defun ebib-customize () + "Switches to Ebib's customisation group." + (interactive) + (ebib-lower) + (customize-group 'ebib)) + +(defun ebib-log (type format-string &rest args) + "Writes a message to Ebib's log buffer. +TYPE (a symbol) is the type of message. It can be LOG, which +writes the message to the log buffer only; MESSAGE, which writes +the message to the log buffer and outputs it with the function +MESSAGE; WARNING, which logs the message and sets the variable +EBIB-LOG-ERROR to 0; or ERROR, which logs the message and sets +the variable EBIB-LOG-ERROR to 1. The latter two can be used to +signal the user to check the log for warnings or errors." + (save-excursion + (set-buffer ebib-log-buffer) + (cond + ((eq type 'warning) + (or ebib-log-error ; if ebib-error-log is already set to 1, we don't want to overwrite it! + (setq ebib-log-error 0))) + ((eq type 'error) + (setq ebib-log-error 1)) + ((eq type 'message) + (apply 'message format-string args))) + (insert (apply 'format (concat format-string "\n") args)))) + +(defun ebib-load-bibtex-file (&optional file) + "Loads a BibTeX file into Ebib." + (interactive) + (unless file + (setq file (ensure-extension (read-file-name "File to open: " "~/") "bib"))) + (setq ebib-cur-db (ebib-create-new-database)) + (setf (edb-filename ebib-cur-db) (expand-file-name file)) + (setf (edb-name ebib-cur-db) (file-name-nondirectory (edb-filename ebib-cur-db))) + (setq ebib-log-error nil) ; we haven't found any errors + (ebib-log 'log "%s: Opening file %s" (format-time-string "%d %b %Y, %H:%M:%S") (edb-filename ebib-cur-db)) + ;; first, we empty the buffers + (ebib-erase-buffer ebib-index-buffer) + (ebib-erase-buffer ebib-entry-buffer) + (if (file-readable-p file) + ;; if the user entered the name of an existing file, we load it + ;; by putting it in a buffer and then parsing it. + (with-temp-buffer + (with-syntax-table ebib-syntax-table + (insert-file-contents file) + ;; if the user makes any changes, we'll want to create a back-up. + (setf (edb-make-backup ebib-cur-db) t) + (let ((result (ebib-find-bibtex-entries nil))) + (setf (edb-n-entries ebib-cur-db) (car result)) + (when (edb-keys-list ebib-cur-db) + (setf (edb-keys-list ebib-cur-db) (sort (edb-keys-list ebib-cur-db) 'string<))) + (when (edb-strings-list ebib-cur-db) + (setf (edb-strings-list ebib-cur-db) (sort (edb-strings-list ebib-cur-db) 'string<))) + (setf (edb-cur-entry ebib-cur-db) (edb-keys-list ebib-cur-db)) + ;; and fill the buffers. note that filling a buffer also makes + ;; that buffer active. therefore we do EBIB-FILL-INDEX-BUFFER + ;; later. + (ebib-set-modified nil) + (ebib-fill-entry-buffer) + ;; and now we tell the user the result + (ebib-log 'message "%d entries, %d @STRINGs and %s @PREAMBLE found in file." + (car result) + (cadr result) + (if (caddr result) + "a" + "no"))))) + ;; if the file does not exist, we need to issue a message. + (ebib-log 'message "(New file)")) + ;; what we have to do in *any* case, is fill the index buffer. (this + ;; even works if there are no keys in the database, e.g. when the + ;; user opened a new file or if no BibTeX entries were found. + (ebib-fill-index-buffer) + (when ebib-log-error + (message "%s found! Press `l' to check Ebib log buffer." (nth ebib-log-error '("Warnings" "Errors")))) + (ebib-log 'log "\n\f\n")) + +(defun ebib-merge-bibtex-file () + "Merges a BibTeX file into the database." + (interactive) + (unless (edb-virtual ebib-cur-db) + (if (not ebib-cur-db) + (error "No database loaded. Use `o' to open a database") + (let ((file (read-file-name "File to merge: "))) + (setq ebib-log-error nil) ; we haven't found any errors + (ebib-log 'log "%s: Merging file %s" (format-time-string "%d-%b-%Y: %H:%M:%S") (edb-filename ebib-cur-db)) + (with-temp-buffer + (with-syntax-table ebib-syntax-table + (insert-file-contents file) + (let ((n (ebib-find-bibtex-entries t))) + (setf (edb-keys-list ebib-cur-db) (sort (edb-keys-list ebib-cur-db) 'string<)) + (setf (edb-n-entries ebib-cur-db) (length (edb-keys-list ebib-cur-db))) + (when (edb-strings-list ebib-cur-db) + (setf (edb-strings-list ebib-cur-db) (sort (edb-strings-list ebib-cur-db) 'string<))) + (setf (edb-cur-entry ebib-cur-db) (edb-keys-list ebib-cur-db)) + (ebib-fill-entry-buffer) + (ebib-fill-index-buffer) + (ebib-set-modified t) + (ebib-log 'message "%d entries, %d @STRINGs and %s @PREAMBLE found in file." + (car n) + (cadr n) + (if (caddr n) + "a" + "no")) + (when ebib-log-error + (message "%s found! Press `l' to check Ebib log buffer." (nth ebib-log-error '("Warnings" "Errors")))) + (ebib-log 'log "\n\f\n")))))))) + +(defun ebib-find-bibtex-entries (timestamp) + "Finds the BibTeX entries in the current buffer. +The search is started at the beginnig of the buffer. All entries +found are stored in the hash table DATABASE of +EBIB-CUR-DB. Returns a three-element list: the first element is +the number of entries found, the second the number of @STRING +definitions, and the third is T or NIL, indicating whether a +@PREAMBLE was found. + +TIMESTAMP indicates whether a timestamp is to be added to each +entry. Note that a timestamp is only added if EBIB-USE-TIMESTAMP +is set to T." + (let ((n-entries 0) + (n-strings 0) + (preamble nil)) + (goto-char (point-min)) + (while (re-search-forward "^@" nil t) ; find the next entry + (let ((beg (point))) + (when (looking-at-goto-end (concat "\\(" ebib-bibtex-identifier "\\)[[:space:]]*[\(\{]") 1) + (let ((entry-type (downcase (buffer-substring-no-properties beg (point))))) + (looking-at-goto-end "[[:space:]]*[\(\{]") + (cond + ((equal entry-type "string") ; string and preamble must be treated differently + (if (ebib-read-string) + (setq n-strings (1+ n-strings)))) + ((equal entry-type "preamble") + (when (ebib-read-preamble) + (setq preamble t))) + ((equal entry-type "comment") ; ignore comments + (ebib-log 'log "Comment at line %d ignored" (line-number-at-pos)) + (ebib-match-paren-forward (point-max))) + ((assoc (intern-soft entry-type) ebib-entry-types) ; if the entry type has been defined + (if (ebib-read-entry entry-type timestamp) + (setq n-entries (1+ n-entries)))) + ;; anything else we report as an unknown entry type. + (t (ebib-log 'warning "Line %d: Unknown entry type `%s'. Skipping." (line-number-at-pos) entry-type) + (ebib-match-paren-forward (point-max)))))))) + (list n-entries n-strings preamble))) + +(defun ebib-read-string () + "Reads the @STRING definition beginning at the line POINT is on. +If a proper abbreviation and string are found, they are stored in the +database. Returns the string if one was read, nil otherwise." + (let ((limit (save-excursion ; we find the matching end parenthesis + (backward-char) + (ebib-match-paren-forward (point-max)) + (point)))) + (skip-chars-forward "\"#%'(),={} \n\t\f" limit) + (let ((beg (point))) + (when (looking-at-goto-end (concat "\\(" ebib-bibtex-identifier "\\)[ \t\n\f]*=") 1) + (if-str (abbr (buffer-substring-no-properties beg (point))) + (progn + (skip-chars-forward "^\"{" limit) + (let ((beg (point))) + (if-str (string (if (ebib-match-delim-forward limit) + (buffer-substring-no-properties beg (1+ (point))) + nil)) + (if (member abbr (edb-strings-list ebib-cur-db)) + (ebib-log 'warning (format "Line %d: @STRING definition `%s' duplicated. Skipping." + (line-number-at-pos) abbr)) + (ebib-insert-string abbr string ebib-cur-db)))))))))) + +(defun ebib-read-preamble () + "Reads the @PREAMBLE definition and stores it in EBIB-PREAMBLE. +If there was already another @PREAMBLE definition, the new one is +added to the existing one with a hash sign `#' between them." + (let ((beg (point))) + (forward-char -1) + (when (ebib-match-paren-forward (point-max)) + (let ((text (buffer-substring-no-properties beg (point)))) + (if (edb-preamble ebib-cur-db) + (setf (edb-preamble ebib-cur-db) (concat (edb-preamble ebib-cur-db) "\n# " text)) + (setf (edb-preamble ebib-cur-db) text)))))) + +(defun ebib-read-entry (entry-type &optional timestamp) + "Reads a BibTeX entry and stores it in DATABASE of EBIB-CUR-DB. +Returns the new EBIB-KEYS-LIST if an entry was found, nil +otherwise. Optional argument TIMESTAMP indicates whether a +timestamp is to be added. (Whether a timestamp is actually added, +also depends on EBIB-USE-TIMESTAMP.)" + (let ((entry-limit (save-excursion + (backward-char) + (ebib-match-paren-forward (point-max)) + (point))) + (beg (progn + (skip-chars-forward " \n\t\f") ; note the space! + (point)))) + (when (looking-at-goto-end (concat "\\(" + ebib-bibtex-identifier + "\\)[ \t\n\f]*,") + 1) ; this delimits the entry key + (let ((entry-key (buffer-substring-no-properties beg (point)))) + (if (member entry-key (edb-keys-list ebib-cur-db)) + (ebib-log 'warning "Line %d: Entry `%s' duplicated. Skipping." (line-number-at-pos) entry-key) + (let ((fields (ebib-find-bibtex-fields (intern-soft entry-type) entry-limit))) + (when fields ; if fields were found, we store them, and return T. + (ebib-insert-entry entry-key fields ebib-cur-db nil timestamp) + t))))))) + +(defun ebib-find-bibtex-fields (entry-type limit) + "Finds the fields of the BibTeX entry that starts on the line POINT is on. +Returns a hash table containing all the fields and values, or NIL +if none were found. ENTRY-TYPE is the type of the entry, which +will be recorded in the hash table. Before the search starts, +POINT is moved back to the beginning of the line." + (beginning-of-line) + ;; we assign a function to fn in order to avoid putting the test on + ;; ebib-allow-identical-fields in the while loop, where it would get + ;; tested with every field being read. + (let ((fn (if (not ebib-allow-identical-fields) + (symbol-function 'puthash) + #'(lambda (field-type field-contents fields) + (let ((existing-contents (gethash field-type fields))) + (puthash field-type (if existing-contents + (from-raw (concat (to-raw existing-contents) + "; " + (to-raw field-contents))) + field-contents) + fields)))))) + (let ((fields (make-hash-table :size 15))) + (while (progn + (skip-chars-forward "^," limit) ; we must move to the next comma, + (eq (char-after) ?,)) ; and make sure we are really on a comma. + (skip-chars-forward "\"#%'(),={} \n\t\f" limit) + (let ((beg (point))) + (when (looking-at-goto-end (concat "\\(" ebib-bibtex-identifier "\\)[ \t\n\f]*=") 1) + (let ((field-type (intern (downcase (buffer-substring-no-properties beg (point)))))) + (unless (eq field-type 'type*) ; the 'type*' key holds the entry type, so we can't use it + (let ((field-contents (ebib-get-field-contents limit))) + (when field-contents + (funcall fn field-type field-contents fields)))))))) + (when (> (hash-table-count fields) 0) + (puthash 'type* entry-type fields) + fields)))) + +(defun ebib-get-field-contents (limit) + "Gets the contents of a BibTeX field. +LIMIT indicates the end of the entry, beyond which the function will not +search." + (skip-chars-forward "#%'(),=} \n\t\f" limit) + (let ((beg (point))) + (buffer-substring-no-properties beg (ebib-find-end-of-field limit)))) + +(defun ebib-find-end-of-field (limit) + "Moves POINT to the end of a field's contents and returns POINT. +The contents of a field is delimited by a comma or by the closing brace of +the entry. The latter is at position LIMIT." + (while (and (not (eq (char-after) ?\,)) + (< (point) limit)) + (ebib-match-delim-forward limit) ; check if we're on a delimiter and if so, jump to the matching closing delimiter + (forward-char 1)) + (if (= (point) limit) + (skip-chars-backward " \n\t\f")) + (point)) + +(defun ebib-leave-ebib-windows () + "Leaves the Ebib windows, lowering them if necessary." + (interactive) + (ebib-lower t)) + +(defun ebib-lower (&optional soft) + "Hides the Ebib windows. +If optional argument SOFT is non-nil, just switch to a non-Ebib +buffer if Ebib is not occupying the entire frame." + (interactive) + (unless (member (window-buffer) (list ebib-index-buffer + ebib-entry-buffer + ebib-strings-buffer + ebib-multiline-buffer + ebib-log-buffer)) + (error "Ebib is not active ")) + (if (and soft + (not (eq ebib-layout 'full))) + (select-window ebib-pre-ebib-window nil) + (set-window-configuration ebib-saved-window-config)) + (mapc #'(lambda (buffer) + (bury-buffer buffer)) + (list ebib-index-buffer + ebib-entry-buffer + ebib-strings-buffer + ebib-multiline-buffer + ebib-log-buffer))) + +(defun ebib-prev-entry () + "Moves to the previous BibTeX entry." + (interactive) + (ebib-execute-when + ((entries) + ;; if the current entry is the first entry, + (if (eq (edb-cur-entry ebib-cur-db) (edb-keys-list ebib-cur-db)) + (beep) ; just beep. + (setf (edb-cur-entry ebib-cur-db) (last (edb-keys-list ebib-cur-db) + (1+ (length (edb-cur-entry ebib-cur-db))))) + (goto-char (ebib-highlight-start ebib-index-highlight)) + (forward-line -1) + (ebib-set-index-highlight) + (ebib-fill-entry-buffer))) + ((default) + (beep)))) + +(defun ebib-next-entry () + "Moves to the next BibTeX entry." + (interactive) + (ebib-execute-when + ((entries) + (if (= (length (edb-cur-entry ebib-cur-db)) 1) ; if we're on the last entry, + (beep) ; just beep. + (setf (edb-cur-entry ebib-cur-db) + (last (edb-keys-list ebib-cur-db) (1- (length (edb-cur-entry ebib-cur-db))))) + (goto-char (ebib-highlight-start ebib-index-highlight)) + (forward-line 1) + (ebib-set-index-highlight) + (ebib-fill-entry-buffer))) + ((default) + (beep)))) + +(defun ebib-add-entry () + "Adds a new entry to the database." + (interactive) + (ebib-execute-when + ((real-db) + (if-str (entry-key (read-string "New entry key: ")) + (progn + (if (member entry-key (edb-keys-list ebib-cur-db)) + (error "Key already exists") + (set-buffer ebib-index-buffer) + (sort-in-buffer (1+ (edb-n-entries ebib-cur-db)) entry-key) + ;; we create the hash table *before* the call to + ;; ebib-display-entry, because that function refers to the + ;; hash table if ebib-index-display-fields is set. + (let ((fields (make-hash-table))) + (puthash 'type* ebib-default-type fields) + (ebib-insert-entry entry-key fields ebib-cur-db t t)) + (with-buffer-writable + (ebib-display-entry entry-key)) + (forward-line -1) ; move one line up to position the cursor on the new entry. + (ebib-set-index-highlight) + (setf (edb-cur-entry ebib-cur-db) (member entry-key (edb-keys-list ebib-cur-db))) + (ebib-fill-entry-buffer) + (ebib-edit-entry) + (ebib-set-modified t))))) + ((no-database) + (error "No database open. Use `o' to open a database first")) + ((default) + (beep)))) + +(defun ebib-close-database () + "Closes the current BibTeX database." + (interactive) + (ebib-execute-when + ((database) + (when (if (edb-modified ebib-cur-db) + (yes-or-no-p "Database modified. Close it anyway? ") + (y-or-n-p "Close database? ")) + (let ((to-be-deleted ebib-cur-db) + (new-db (next-elem ebib-cur-db ebib-databases))) + (setq ebib-databases (delete to-be-deleted ebib-databases)) + (if ebib-databases ; do we still have another database loaded? + (progn + (setq ebib-cur-db (or new-db + (last1 ebib-databases))) + (unless (edb-cur-entry ebib-cur-db) + (setf (edb-cur-entry ebib-cur-db) (edb-keys-list ebib-cur-db))) + (ebib-fill-entry-buffer) + (ebib-fill-index-buffer)) + ;; otherwise, we have to clean up a little and empty all the buffers. + (setq ebib-cur-db nil) + (mapc #'(lambda (buf) ; this is just to avoid typing almost the same thing three times... + (set-buffer (car buf)) + (with-buffer-writable + (erase-buffer)) + (ebib-delete-highlight (cadr buf))) + (list (list ebib-entry-buffer ebib-fields-highlight) + (list ebib-index-buffer ebib-index-highlight) + (list ebib-strings-buffer ebib-strings-highlight))) + ;; multiline edit buffer + (set-buffer ebib-multiline-buffer) + (with-buffer-writable + (erase-buffer)) + (set-buffer ebib-index-buffer) + (rename-buffer " none")) + (message "Database closed.")))))) + +(defun ebib-goto-first-entry () + "Moves to the first BibTeX entry in the database." + (interactive) + (ebib-execute-when + ((entries) + (setf (edb-cur-entry ebib-cur-db) (edb-keys-list ebib-cur-db)) + (set-buffer ebib-index-buffer) + (goto-char (point-min)) + (ebib-set-index-highlight) + (ebib-fill-entry-buffer)) + ((default) + (beep)))) + +(defun ebib-goto-last-entry () + "Moves to the last entry in the BibTeX database." + (interactive) + (ebib-execute-when + ((entries) + (setf (edb-cur-entry ebib-cur-db) (last (edb-keys-list ebib-cur-db))) + (set-buffer ebib-index-buffer) + (goto-line (edb-n-entries ebib-cur-db)) + (ebib-set-index-highlight) + (ebib-fill-entry-buffer)) + ((default) + (beep)))) + +(defun ebib-edit-entry () + "Edits the current BibTeX entry." + (interactive) + (ebib-execute-when + ((real-db entries) + (setq ebib-cur-entry-hash (ebib-retrieve-entry (ebib-cur-entry-key) ebib-cur-db)) + (setq ebib-cur-entry-fields (ebib-get-all-fields (gethash 'type* ebib-cur-entry-hash))) + (select-window (get-buffer-window ebib-entry-buffer) nil)) + ((default) + (beep)))) + +(defun ebib-edit-keyname () + "Changes the key of a BibTeX entry." + (interactive) + (ebib-execute-when + ((real-db entries) + (let ((cur-keyname (ebib-cur-entry-key))) + (if-str (new-keyname (read-string (format "Change `%s' to: " cur-keyname) + cur-keyname)) + (if (member new-keyname (edb-keys-list ebib-cur-db)) + (error (format "Key `%s' already exists" new-keyname)) + (unless (string= cur-keyname new-keyname) + (let ((fields (ebib-retrieve-entry cur-keyname ebib-cur-db)) + (marked (member cur-keyname (edb-marked-entries ebib-cur-db)))) + (ebib-remove-entry-from-db cur-keyname ebib-cur-db) + (ebib-remove-key-from-buffer cur-keyname) + (ebib-insert-entry new-keyname fields ebib-cur-db t nil) + (setf (edb-cur-entry ebib-cur-db) (member new-keyname (edb-keys-list ebib-cur-db))) + (sort-in-buffer (edb-n-entries ebib-cur-db) new-keyname) + (with-buffer-writable + (ebib-display-entry new-keyname)) + (forward-line -1) ; move one line up to position the cursor on the new entry. + (ebib-set-index-highlight) + (ebib-set-modified t) + (when marked (ebib-mark-entry)))))))) + ((default) + (beep)))) + +(defun ebib-mark-entry () + "Marks or unmarks the current entry." + (interactive) + (if (ebib-called-with-prefix) + (ebib-execute-when + ((marked-entries) + (setf (edb-marked-entries ebib-cur-db) nil) + (ebib-fill-index-buffer)) + ((entries) + (setf (edb-marked-entries ebib-cur-db) (copy-sequence (edb-keys-list ebib-cur-db))) + (ebib-fill-index-buffer)) + ((default) + (beep))) + (ebib-execute-when + ((entries) + (set-buffer ebib-index-buffer) + (with-buffer-writable + (if (member (ebib-cur-entry-key) (edb-marked-entries ebib-cur-db)) + (progn + (setf (edb-marked-entries ebib-cur-db) + (delete (ebib-cur-entry-key) (edb-marked-entries ebib-cur-db))) + (remove-text-properties (ebib-highlight-start ebib-index-highlight) + (ebib-highlight-end ebib-index-highlight) + '(face ebib-marked-face))) + (setf (edb-marked-entries ebib-cur-db) (sort (cons (ebib-cur-entry-key) + (edb-marked-entries ebib-cur-db)) + 'string<)) + (add-text-properties (ebib-highlight-start ebib-index-highlight) + (ebib-highlight-end ebib-index-highlight) + '(face ebib-marked-face))))) + ((default) + (beep))))) + +(defun ebib-index-scroll-down () + "Moves one page up in the database." + (interactive) + (ebib-execute-when + ((entries) + (scroll-down) + (ebib-select-entry)) + ((default) + (beep)))) + +(defun ebib-index-scroll-up () + "Moves one page down in the database." + (interactive) + (ebib-execute-when + ((entries) + (scroll-up) + (ebib-select-entry)) + ((default) + (beep)))) + +(defun ebib-format-entry (key db timestamp) + "Formats entry KEY from database DB into the current buffer in BibTeX format. +If TIMESTAMP is T, a timestamp is added to the entry if +EBIB-USE-TIMESTAMP is T." + (let ((entry (ebib-retrieve-entry key db))) + (when entry + (insert (format "@%s{%s,\n" (gethash 'type* entry) key)) + (maphash #'(lambda (key value) + (unless (or (eq key 'type*) + (and (eq key 'timestamp) timestamp ebib-use-timestamp)) + (insert (format "\t%s = %s,\n" key value)))) + entry) + (if (and timestamp ebib-use-timestamp) + (insert (format "\ttimestamp = {%s}" (format-time-string ebib-timestamp-format))) + (delete-char -2)) ; the final ",\n" must be deleted + (insert "\n}\n\n")))) + +(defun ebib-format-strings (db) + "Formats the @STRING commands in database DB." + (maphash #'(lambda (key value) + (insert (format "@STRING{%s = %s}\n" key value))) + (edb-strings db)) + (insert "\n")) + +(defun ebib-compare-xrefs (x y) + (gethash 'crossref (ebib-retrieve-entry x ebib-cur-db))) + +(defun ebib-format-database (db) + "Writes database DB into the current buffer in BibTeX format." + (when (edb-preamble db) + (insert (format "@PREAMBLE{%s}\n\n" (edb-preamble db)))) + (ebib-format-strings db) + (let ((sorted-list (copy-list (edb-keys-list db)))) + (cond + (ebib-save-xrefs-first + (setq sorted-list (sort sorted-list 'ebib-compare-xrefs))) + (ebib-sort-order + (setq sorted-list (sort sorted-list 'ebib-entry<)))) + (mapc #'(lambda (key) (ebib-format-entry key db nil)) sorted-list))) + +(defun ebib-save-database (db) + "Saves the database DB." + (ebib-execute-when + ((real-db) + (when (and (edb-make-backup db) + (file-exists-p (edb-filename db))) + (rename-file (edb-filename db) (concat (edb-filename db) "~") t) + (setf (edb-make-backup db) nil)) + (with-temp-buffer + (ebib-format-database db) + (write-region (point-min) (point-max) (edb-filename db))) + (ebib-set-modified nil db)))) + +(defun ebib-write-database () + "Writes the current database to a different file. +Can also be used to change a virtual database into a real one." + (interactive) + (ebib-execute-when + ((database) + (if-str (new-filename (read-file-name "Save to file: " "~/")) + (progn + (with-temp-buffer + (ebib-format-database ebib-cur-db) + (safe-write-region (point-min) (point-max) new-filename nil nil nil t)) + ;; if SAFE-WRITE-REGION was cancelled by the user because he + ;; didn't want to overwrite an already existing file with his + ;; new database, it throws an error, so the next lines will not + ;; be executed. hence we can safely set (EDB-FILENAME DB) and + ;; (EDB-NAME DB). + (setf (edb-filename ebib-cur-db) new-filename) + (setf (edb-name ebib-cur-db) (file-name-nondirectory new-filename)) + (rename-buffer (concat (format " %d:" (1+ (- (length ebib-databases) + (length (member ebib-cur-db ebib-databases))))) + (edb-name ebib-cur-db))) + (ebib-execute-when + ((virtual-db) + (setf (edb-virtual ebib-cur-db) nil) + (setf (edb-database ebib-cur-db) + (let ((new-db (make-hash-table :test 'equal))) + (mapc #'(lambda (key) + (let ((entry (gethash key (edb-database ebib-cur-db)))) + (when entry + (puthash key (copy-hash-table entry) new-db)))) + (edb-keys-list ebib-cur-db)) + new-db)))) + (ebib-set-modified nil)))) + ((default) + (beep)))) + +(defun ebib-save-current-database () + "Saves the current database." + (interactive) + (ebib-execute-when + ((real-db) + (if (not (edb-modified ebib-cur-db)) + (message "No changes need to be saved.") + (ebib-save-database ebib-cur-db))) + ((virtual-db) + (error "Cannot save a virtual database. Use `w' to write to a file.")))) + +(defun ebib-save-all-databases () + "Saves all currently open databases if they were modified." + (interactive) + (ebib-execute-when + ((database) + (mapc #'(lambda (db) + (when (edb-modified db) + (ebib-save-database db))) + ebib-databases) + (message "All databases saved.")))) + +(defun ebib-print-filename () + "Displays the filename of the current database in the minibuffer." + (interactive) + (message (edb-filename ebib-cur-db))) + +(defun ebib-follow-crossref () + "Goes to the entry mentioned in the crossref field of the current entry." + (interactive) + (let ((new-cur-entry (to-raw (gethash 'crossref + (ebib-retrieve-entry (ebib-cur-entry-key) ebib-cur-db))))) + (setf (edb-cur-entry ebib-cur-db) + (or (member new-cur-entry (edb-keys-list ebib-cur-db)) + (edb-cur-entry ebib-cur-db)))) + (ebib-fill-entry-buffer) + (ebib-fill-index-buffer)) + +(defun ebib-toggle-hidden () + (interactive) + (setq ebib-hide-hidden-fields (not ebib-hide-hidden-fields)) + (ebib-fill-entry-buffer)) + +(defun ebib-delete-entry () + "Deletes the current entry from the database." + (interactive) + (if (ebib-called-with-prefix) + (ebib-execute-when + ((real-db marked-entries) + (when (y-or-n-p "Delete all marked entries? ") + (mapc #'(lambda (entry) + (ebib-remove-entry-from-db entry ebib-cur-db (not (string= entry (ebib-cur-entry-key))))) + (edb-marked-entries ebib-cur-db)) + (message "Marked entries deleted.") + (ebib-set-modified t) + (ebib-fill-entry-buffer) + (ebib-fill-index-buffer))) + ((default) + (beep))) + (ebib-execute-when + ((real-db entries) + (let ((cur-entry (ebib-cur-entry-key))) + (when (y-or-n-p (format "Delete %s? " cur-entry)) + (ebib-remove-entry-from-db cur-entry ebib-cur-db) + (ebib-remove-key-from-buffer cur-entry) + (ebib-fill-entry-buffer) + (ebib-set-modified t) + (message (format "Entry `%s' deleted." cur-entry))))) + ((default) + (beep))))) + +(defun ebib-remove-entry-from-db (entry-key db &optional new-cur-entry) + "Removes ENTRY-KEY from DB. +Optional argument NEW-CUR-ENTRY is the key of the entry that is +to become the new current entry. It it is NIL, the entry after +the deleted one becomes the new current entry. If it is T, the +current entry is not changed." + (remhash entry-key (edb-database db)) + (setf (edb-n-entries db) (1- (edb-n-entries db))) + (cond + ((null new-cur-entry) (setq new-cur-entry (cadr (edb-cur-entry db)))) + ((stringp new-cur-entry) t) + (t (setq new-cur-entry (ebib-cur-entry-key)))) + (setf (edb-keys-list db) (delete entry-key (edb-keys-list db))) + (setf (edb-marked-entries db) (delete entry-key (edb-marked-entries db))) + (setf (edb-cur-entry db) (member new-cur-entry (edb-keys-list db))) + (unless (edb-cur-entry db) ; if (edb-cur-entry db) is nil, we deleted the last entry. + (setf (edb-cur-entry db) (last (edb-keys-list db))))) + +(defun ebib-remove-key-from-buffer (entry-key) + "Removes ENTRY-KEY from the index buffer and highlights the current entry." + (with-buffer-writable + (let ((beg (ebib-search-key-in-buffer entry-key))) + (forward-line 1) + (delete-region beg (point)))) + (ebib-execute-when + ((entries) + (ebib-search-key-in-buffer (ebib-cur-entry-key)) + (ebib-set-index-highlight)))) + +(defun ebib-select-entry () + "Makes the entry at POINT the current entry." + (interactive) + (ebib-execute-when + ((entries) + (beginning-of-line) + (let ((beg (point))) + (let* ((key (save-excursion + (skip-chars-forward "^ ") + (buffer-substring-no-properties beg (point)))) + (new-cur-entry (member key (edb-keys-list ebib-cur-db)))) + (when new-cur-entry + (setf (edb-cur-entry ebib-cur-db) new-cur-entry) + (ebib-set-index-highlight) + (ebib-fill-entry-buffer))))) + ((default) + (beep)))) + +(defun ebib-export-entry (prefix) + "Copies entries to another database. +The prefix argument indicates which database to copy the entry +to. If no prefix argument is present, a filename is asked to +which the entry is appended." + (interactive "P") + (let ((num (ebib-prefix prefix))) + (if (ebib-called-with-prefix) + (ebib-export-marked-entries num) + (ebib-export-single-entry num)))) + +(defun ebib-export-single-entry (num) + "Copies the current entry to another database. +NUM indicates which database to copy the entry to. If it is NIL, +a filename is asked to which the entry is appended." + (ebib-execute-when + ((real-db entries) + (if num + (ebib-export-to-db num (format "Entry `%s' copied to database %%d." (ebib-cur-entry-key)) + #'(lambda (db) + (let ((entry-key (ebib-cur-entry-key))) + (if (member entry-key (edb-keys-list db)) + (error "Entry key `%s' already exists in database %d" entry-key num) + (ebib-insert-entry entry-key + (copy-hash-table (ebib-retrieve-entry entry-key + ebib-cur-db)) + db t t) + ;; if this is the first entry in the target DB, + ;; its CUR-ENTRY must be set! + (when (null (edb-cur-entry db)) + (setf (edb-cur-entry db) (edb-keys-list db))) + t)))) ; we must return T, WHEN does not always do this. + (ebib-export-to-file (format "Export `%s' to file: " (ebib-cur-entry-key)) + (format "Entry `%s' exported to %%s." (ebib-cur-entry-key)) + #'(lambda () + (insert "\n") + (ebib-format-entry (ebib-cur-entry-key) ebib-cur-db t))))) + ((default) + (beep)))) + +(defun ebib-export-marked-entries (num) + "Copies the marked entries to another database. +NUM indicates which database to copy the entry to. If it is NIL, +a filename is asked to which the entry is appended." + (ebib-execute-when + ((real-db marked-entries) + (if num + (ebib-export-to-db + num "Entries copied to database %d." + #'(lambda (db) + (mapc #'(lambda (entry-key) + (if (member entry-key (edb-keys-list db)) + (error "Entry key `%s' already exists in database %d" entry-key num) + (ebib-insert-entry entry-key + (copy-hash-table (ebib-retrieve-entry entry-key + ebib-cur-db)) + db t t))) + (edb-marked-entries ebib-cur-db)) + ;; if the target DB was empty before, its CUR-ENTRY must be set! + (when (null (edb-cur-entry db)) + (setf (edb-cur-entry db) (edb-keys-list db))) + t)) ; we must return T, WHEN does not always do this. + (ebib-export-to-file "Export to file: " "Entries exported to %s." + #'(lambda () + (mapc #'(lambda (entry-key) + (insert "\n") + (ebib-format-entry entry-key ebib-cur-db t)) + (edb-marked-entries ebib-cur-db)))))) + ((default) + (beep)))) + +(defun ebib-search () + "Search the current Ebib database. +The search is conducted with STRING-MATCH and can therefore be a +regexp. Searching starts with the current entry." + (interactive) + (ebib-execute-when + ((entries) + (if-str (search-str (read-string "Search database for: ")) + (progn + (setq ebib-search-string search-str) + ;; first we search the current entry + (if (ebib-search-in-entry ebib-search-string + (ebib-retrieve-entry (ebib-cur-entry-key) ebib-cur-db)) + (ebib-fill-entry-buffer ebib-search-string) + ;; if the search string wasn't found in the current entry, we continue searching. + (ebib-search-next))))) + ((default) + (beep)))) + +(defun ebib-search-next () + "Searches the next occurrence of EBIB-SEARCH-STRING. +Searching starts at the entry following the current entry. If a +match is found, the matching entry is shown and becomes the new +current entry." + (interactive) + (ebib-execute-when + ((entries) + (if (null ebib-search-string) + (message "No search string") + (let ((cur-search-entry (cdr (edb-cur-entry ebib-cur-db)))) + (while (and cur-search-entry + (null (ebib-search-in-entry ebib-search-string + (gethash (car cur-search-entry) + (edb-database ebib-cur-db))))) + (setq cur-search-entry (cdr cur-search-entry))) + (if (null cur-search-entry) + (message (format "`%s' not found" ebib-search-string)) + (setf (edb-cur-entry ebib-cur-db) cur-search-entry) + (set-buffer ebib-index-buffer) + (goto-char (point-min)) + (re-search-forward (format "^%s " (ebib-cur-entry-key))) + (beginning-of-line) + (ebib-set-index-highlight) + (ebib-fill-entry-buffer ebib-search-string))))) + ((default) + (beep)))) + +(defun ebib-search-in-entry (search-str entry &optional field) + "Searches one entry of the ebib database. +Returns a list of fields in ENTRY that match the regexp +SEARCH-STR, or NIL if no matches were found. If FIELD is given, +only that field is searched." + (let ((case-fold-search t) ; we want to ensure a case-insensitive search + (result nil)) + (if field + (let ((value (gethash field entry))) + (when (and (stringp value) ; the type* field has a symbol as value + (string-match search-str value)) + (setq result (list field)))) + (maphash #'(lambda (field value) + (when (and (stringp value) ; the type* field has a symbol as value + (string-match search-str value)) + (setq result (cons field result)))) + entry)) + result)) + +(defun ebib-search-crossref () + "Searches the database for the key of the current entry. +This is useful in searching the entries that cross-reference the +current entry." + (interactive) + (setq ebib-search-string (car (edb-cur-entry ebib-cur-db))) + (ebib-search-next)) + +(defun ebib-edit-strings () + "Edits the @STRING definitions in the database." + (interactive) + (ebib-execute-when + ((real-db) + (ebib-fill-strings-buffer) + (select-window (get-buffer-window ebib-entry-buffer) nil) + (set-window-dedicated-p (selected-window) nil) + (switch-to-buffer ebib-strings-buffer) + (unless (eq ebib-layout 'full) + (set-window-dedicated-p (selected-window) t)) + (goto-char (point-min))) + ((default) + (beep)))) + +(defun ebib-edit-preamble () + "Edits the @PREAMBLE definition in the database." + (interactive) + (ebib-execute-when + ((real-db) + (select-window (ebib-temp-window) nil) + (ebib-multiline-edit 'preamble (edb-preamble ebib-cur-db))) + ((default) + (beep)))) + +(defun ebib-export-preamble (prefix) + "Exports the @PREAMBLE definition. +If a prefix argument is given, it is taken as the database to +export the preamble to. If the goal database already has a +preamble, the new preamble will be appended to it. If no prefix +argument is given, the user is asked to enter a filename to which +the preamble is appended." + (interactive "P") + (ebib-execute-when + ((real-db) + (if (null (edb-preamble ebib-cur-db)) + (error "No @PREAMBLE defined") + (let ((num (ebib-prefix prefix))) + (if num + (ebib-export-to-db num "@PREAMBLE copied to database %d" + #'(lambda (db) + (let ((text (edb-preamble ebib-cur-db))) + (if (edb-preamble db) + (setf (edb-preamble db) (concat (edb-preamble db) "\n# " text)) + (setf (edb-preamble db) text))))) + (ebib-export-to-file "Export @PREAMBLE to file: " + "@PREAMBLE exported to %s" + #'(lambda () + (insert (format "\n@preamble{%s}\n\n" (edb-preamble ebib-cur-db))))))))) + ((default) + (beep)))) + +(defun ebib-print-entries () + "Creates a LaTeX file listing the entries. +Either prints the entire database, or the marked entries." + (interactive) + (ebib-execute-when + ((entries) + (let ((entries (if (ebib-called-with-prefix) + (edb-marked-entries ebib-cur-db) + (edb-keys-list ebib-cur-db)))) + (if-str (tempfile (if (not (string= "" ebib-print-tempfile)) + ebib-print-tempfile + (read-file-name "Use temp file: " "~/" nil nil))) + (progn + (with-temp-buffer + (insert "\\documentclass{article}\n\n") + (when ebib-print-preamble + (mapc #'(lambda (string) + (insert (format "%s\n" string))) + ebib-print-preamble)) + (insert "\n\\begin{document}\n\n") + (mapc #'(lambda (entry-key) + (insert "\\begin{tabular}{p{0.2\\textwidth}p{0.8\\textwidth}}\n") + (let ((entry (ebib-retrieve-entry entry-key ebib-cur-db))) + (insert (format "\\multicolumn{2}{l}{\\texttt{%s (%s)}}\\\\\n" + entry-key (symbol-name (gethash 'type* entry)))) + (insert "\\hline\n") + (mapc #'(lambda (field) + (if-str (value (gethash field entry)) + (when (or (not (multiline-p value)) + ebib-print-multiline) + (insert (format "%s: & %s\\\\\n" + field (to-raw value)))))) + (cdr (ebib-get-all-fields (gethash 'type* entry))))) + (insert "\\end{tabular}\n\n") + (insert "\\bigskip\n\n")) + entries) + (insert "\\end{document}\n") + (write-region (point-min) (point-max) tempfile)) + (ebib-lower) + (find-file tempfile))))) + ((default) + (beep)))) + +(defun ebib-latex-entries () + "Creates a LaTeX file that \\nocites entries from the database. +Operates either on all entries or on the marked entries." + (interactive) + (ebib-execute-when + ((real-db entries) + (if-str (tempfile (if (not (string= "" ebib-print-tempfile)) + ebib-print-tempfile + (read-file-name "Use temp file: " "~/" nil nil))) + (progn + (with-temp-buffer + (insert "\\documentclass{article}\n\n") + (when ebib-print-preamble + (mapc #'(lambda (string) + (insert (format "%s\n" string))) + ebib-latex-preamble)) + (insert "\n\\begin{document}\n\n") + (if (ebib-called-with-prefix) + (mapc #'(lambda (entry) + (insert (format "\\nocite{%s}\n" entry))) + (edb-marked-entries ebib-cur-db)) + (insert "\\nocite{*}\n")) + (insert (format "\n\\bibliography{%s}\n\n" (expand-file-name (edb-filename ebib-cur-db)))) + (insert "\\end{document}\n") + (write-region (point-min) (point-max) tempfile)) + (ebib-lower) + (find-file tempfile)))) + ((default) + (beep)))) + +(defun ebib-switch-to-database (num) + (interactive "NSwitch to database number: ") + (let ((new-db (nth (1- num) ebib-databases))) + (if new-db + (progn + (setq ebib-cur-db new-db) + (ebib-fill-entry-buffer) + (ebib-fill-index-buffer)) + (error "Database %d does not exist" num)))) + +(defun ebib-next-database () + (interactive) + (ebib-execute-when + ((database) + (let ((new-db (next-elem ebib-cur-db ebib-databases))) + (unless new-db + (setq new-db (car ebib-databases))) + (setq ebib-cur-db new-db) + (ebib-fill-entry-buffer) + (ebib-fill-index-buffer))))) + +(defun ebib-prev-database () + (interactive) + (ebib-execute-when + ((database) + (let ((new-db (prev-elem ebib-cur-db ebib-databases))) + (unless new-db + (setq new-db (last1 ebib-databases))) + (setq ebib-cur-db new-db) + (ebib-fill-entry-buffer) + (ebib-fill-index-buffer))))) + +(defun ebib-browse-url (num) + "Asks a browser to load the URL in the standard URL field. +The standard URL field may contain more than one URL, if they're +whitespace-separated. In that case, a numeric prefix argument +specifies which URL to choose. + +By \"standard URL field\" is meant the field defined in the +customisation variable EBIB-STANDARD-URL-FIELD. Its default value +is `url'." + (interactive "p") + (ebib-execute-when + ((entries) + (let ((url (to-raw (gethash ebib-standard-url-field + (ebib-retrieve-entry (ebib-cur-entry-key) ebib-cur-db))))) + (when (not (and url + (ebib-call-browser url num))) + (error "No url found in field `%s'" ebib-standard-url-field)))) + ((default) + (beep)))) + +(defun ebib-call-browser (urls n) + "Passes the Nth url in URLS to a browser. +URLs must be a string of whitespace-separated urls." + (let ((url (nth (1- n) + (let ((start 0) + (result nil)) + (while (string-match ebib-url-regexp urls start) + (add-to-list 'result (match-string 0 urls) t) + (setq start (match-end 0))) + result)))) + (cond + ((string-match "\\\\url{\\(.*?\\)}" url) + (setq url (match-string 1 url))) + ((string-match ebib-url-regexp url) + (setq url (match-string 0 url))) + (t (setq url nil))) + (when url + (if (not (string= ebib-browser-command "")) + (start-process "Ebib-browser" nil ebib-browser-command url) + (browse-url url))))) + +(defun ebib-view-file (num) + "Views a file in the standard file field. +The standard file field may contain more than one filename, if +they're whitespace-separated. In that case, a numeric prefix +argument specifies which file to choose. + +By \"standard file field\" is meant the field defined in the +customisation variable EBIB-STANDARD-FILE-FIELD. Its default +value is `file'." + (interactive "p") + (ebib-execute-when + ((entries) + (let ((filename (to-raw (gethash ebib-standard-file-field + (ebib-retrieve-entry (ebib-cur-entry-key) ebib-cur-db))))) + (when (not (and filename + (ebib-call-file-viewer filename num))) + (error "No valid filename found in field `%s'" ebib-standard-file-field)))) + ((default) + (beep)))) + +(defun ebib-call-file-viewer (files n) + "Passes the Nth file in FILES to an external viewer. +FILES must be a string of whitespace-separated filenames." + (let* ((file (nth (1- n) + (let ((start 0) + (result nil)) + (while (string-match ebib-file-regexp files start) + (add-to-list 'result (match-string 0 files) t) + (setq start (match-end 0))) + result))) + (ext (file-name-extension file))) + (let ((file-full-path (locate-file file ebib-file-search-dirs))) + (when file-full-path + (if-str (viewer (cdr (assoc ext ebib-file-associations))) + (start-process (concat "ebib " ext " viewer process") nil viewer file-full-path) + (ebib-lower) + (find-file file-full-path)))))) + +(defun ebib-virtual-db-and (not) + "Filters entries into a virtual database. +If the current database is a virtual database already, perform a +logical AND on the entries." + (interactive "p") + (ebib-execute-when + ((entries) + (ebib-filter-to-virtual-db 'and not)) + ((default) + (beep)))) + +(defun ebib-virtual-db-or (not) + "Filters entries into a virtual database. +If the current database is a virtual database already, perform a +logical OR with the entries in the original database." + (interactive "p") + (ebib-execute-when + ((entries) + (ebib-filter-to-virtual-db 'or not)) + ((default) + (beep)))) + +(defun ebib-virtual-db-not () + "Negates the current virtual database." + (interactive) + (ebib-execute-when + ((virtual-db) + (setf (edb-virtual ebib-cur-db) + (if (eq (car (edb-virtual ebib-cur-db)) 'not) + (cadr (edb-virtual ebib-cur-db)) + `(not ,(edb-virtual ebib-cur-db)))) + (ebib-run-filter (edb-virtual ebib-cur-db) ebib-cur-db) + (ebib-fill-entry-buffer) + (ebib-fill-index-buffer)) + ((default) + (beep)))) + +(defun ebib-filter-to-virtual-db (bool not) + "Filters the current database to a virtual database. +BOOL is the operator to be used, either `and' or `or'. If NOT<0, +a logical `not' is applied to the selection." + (let ((field (completing-read (format "Filter: %s(contains <field> <regexp>)%s. Enter field: " + (if (< not 0) "(not " "") + (if (< not 0) ")" "")) + (cons '("any" 0) + (mapcar #'(lambda (x) + (cons (symbol-name x) 0)) + (append ebib-unique-field-list ebib-additional-fields))) + nil t))) + (setq field (intern-soft field)) + (let ((regexp (read-string (format "Filter: %s(contains %s <regexp>)%s. Enter regexp: " + (if (< not 0) "(not " "") + field + (if (< not 0) ")" ""))))) + (ebib-execute-when + ((virtual-db) + (setf (edb-virtual ebib-cur-db) `(,bool ,(edb-virtual ebib-cur-db) + ,(if (>= not 0) + `(contains ,field ,regexp) + `(not (contains ,field ,regexp)))))) + ((real-db) + (setq ebib-cur-db (ebib-create-virtual-db field regexp not)))) + (ebib-run-filter (edb-virtual ebib-cur-db) ebib-cur-db) + (ebib-fill-entry-buffer) + (ebib-fill-index-buffer)))) + +(defun ebib-create-virtual-db (field regexp not) + "Creates a virtual database based on EBIB-CUR-DB." + ;; a virtual database is a database whose edb-virtual field contains an + ;; expression that selects entries. this function only sets that + ;; expression, it does not actually filter the entries. + (let ((new-db (ebib-create-new-database ebib-cur-db))) + (setf (edb-virtual new-db) (if (>= not 0) + `(contains ,field ,regexp) + `(not (contains ,field ,regexp)))) + (setf (edb-filename new-db) nil) + (setf (edb-name new-db) (concat "V:" (edb-name new-db))) + (setf (edb-modified new-db) nil) + (setf (edb-make-backup new-db) nil) + new-db)) + +(defmacro contains (field regexp) + ;; Note: the variable ENTRY is *not* bound in this macro! The function + ;; calling CONTAINS *must* set ENTRY to an actual Ebib entry. The point + ;; of this macro is to facilitate defining filters for virtual databases. + ;; It enables us to define filters of the form: + + ;; (and (not (contains author "Chomsky")) (contains year "1995")) + + `(ebib-search-in-entry ,regexp entry ,(unless (eq field 'any) `(quote ,field)))) + +(defun ebib-run-filter (filter db) + "Runs FILTER on DB" + (setf (edb-keys-list db) + (sort (let ((result nil)) + (maphash #'(lambda (key value) + (let ((entry value)) ; this is necessary for actually running the filter + (when (eval filter) + (setq result (cons key result))))) + (edb-database db)) + result) + 'string<)) + (setf (edb-n-entries db) (length (edb-keys-list db))) + (setf (edb-cur-entry db) (edb-keys-list db))) + +(defun ebib-print-filter (num) + "Displays the filter of the current virtual database. +With any prefix argument, reapplies the filter to the +database. This can be useful when the source database was +modified." + (interactive "P") + (ebib-execute-when + ((virtual-db) + (when num + (ebib-run-filter (edb-virtual ebib-cur-db) ebib-cur-db) + (ebib-fill-entry-buffer) + (ebib-fill-index-buffer)) + (message "%S" (edb-virtual ebib-cur-db))) + ((default) + (beep)))) + +(defun ebib-show-log () + "Displays the contents of the log buffer." + (interactive) + (select-window (get-buffer-window ebib-entry-buffer) nil) + (set-window-dedicated-p (selected-window) nil) + (switch-to-buffer ebib-log-buffer) + (unless (eq ebib-layout 'full) + (set-window-dedicated-p (selected-window) t))) + +(defun ebib-push-bibtex-key () + "Pushes the current entry to a LaTeX buffer. +The user is prompted for the buffer to push the entry into." + (interactive) + (let ((called-with-prefix (ebib-called-with-prefix))) + (ebib-execute-when + ((entries) + (let ((buffer (read-buffer (if called-with-prefix + "Push marked entries to buffer: " + "Push entry to buffer: ") + ebib-push-buffer t)) + insert-string) + (when buffer + (setq ebib-push-buffer buffer) + (let ((keys (if called-with-prefix + (when (edb-marked-entries ebib-cur-db) + (mapconcat #'(lambda (x) x) + (edb-marked-entries ebib-cur-db) + ",")) + (car (edb-cur-entry ebib-cur-db))))) + (if-str (command (completing-read "Command to use: " ebib-insertion-commands + nil nil nil ebib-insertion-commands)) + (let* ((n-opt-args (or + (cdr (assoc command ebib-insertion-commands)) + 1)) + (opt-args (loop for i from 1 to n-opt-args + collect (read-from-minibuffer (format "Optional argument %d: " i))))) + (while (equal (car opt-args) "") ; empty args at the beginning of the list don't need + (setq opt-args (cdr opt-args))) ; to be included. + (setq insert-string (format "\\%s%s{%s}" command + (mapconcat #'(lambda (str) + (format "[%s]" str)) + opt-args "") + keys))) + (setq insert-string keys))) + (when insert-string + (save-excursion + (set-buffer buffer) + (insert insert-string)) + (message "Pushed entries to buffer %s" buffer))))) + ((default) + (beep))))) + +;;;;;;;;;;;;;;;; +;; entry-mode ;; +;;;;;;;;;;;;;;;; + +(defvar ebib-entry-mode-map + (let ((map (make-keymap))) + (suppress-keymap map) + (define-key map [up] 'ebib-prev-field) + (define-key map [down] 'ebib-next-field) + (define-key map [prior] 'ebib-goto-prev-set) + (define-key map [next] 'ebib-goto-next-set) + (define-key map [home] 'ebib-goto-first-field) + (define-key map [end] 'ebib-goto-last-field) + (define-key map " " 'ebib-goto-next-set) + (define-key map "b" 'ebib-goto-prev-set) + (define-key map "c" 'ebib-copy-field-contents) + (define-key map "d" 'ebib-delete-field-contents) + (define-key map "e" 'ebib-edit-field) + (define-key map "f" 'ebib-view-file-in-field) + (define-key map "g" 'ebib-goto-first-field) + (define-key map "G" 'ebib-goto-last-field) + (define-key map "j" 'ebib-next-field) + (define-key map "k" 'ebib-prev-field) + (define-key map "l" 'ebib-edit-multiline-field) + (define-key map [(control n)] 'ebib-next-field) + (define-key map [(meta n)] 'ebib-goto-prev-set) + (define-key map [(control p)] 'ebib-prev-field) + (define-key map [(meta p)] 'ebib-goto-next-set) + (define-key map "q" 'ebib-quit-entry-buffer) + (define-key map "r" 'ebib-toggle-raw) + (define-key map "s" 'ebib-insert-abbreviation) + (define-key map "u" 'ebib-browse-url-in-field) + (define-key map "x" 'ebib-cut-field-contents) + (define-key map "\C-xb" 'undefined) + (define-key map "\C-xk" 'undefined) + (define-key map "y" 'ebib-yank-field-contents) + map) + "Keymap for the Ebib entry buffer.") + +(define-derived-mode ebib-entry-mode + fundamental-mode "Ebib-entry" + "Major mode for the Ebib entry buffer." + (setq buffer-read-only t) + (setq truncate-lines t)) + +(defun ebib-quit-entry-buffer () + "Quits editing the entry." + (interactive) + (select-window (get-buffer-window ebib-index-buffer) nil)) + +(defun ebib-find-visible-field (field direction) + "Finds the first visible field before or after FIELD. +If DIRECTION is negative, search the preceding fields, otherwise +search the succeeding fields. If FIELD is visible itself, return +that. If there is no preceding/following visible field, return +NIL. If EBIB-HIDE-HIDDEN-FIELDS is NIL, return FIELD." + (when ebib-hide-hidden-fields + (let ((fn (if (>= direction 0) + 'next-elem + 'prev-elem))) + (while (and field + (get field 'ebib-hidden)) + (setq field (funcall fn field ebib-cur-entry-fields))))) + field) + +(defun ebib-prev-field () + "Moves to the previous field." + (interactive) + (let ((new-field (ebib-find-visible-field (prev-elem ebib-current-field ebib-cur-entry-fields) -1))) + (if (null new-field) + (beep) + (setq ebib-current-field new-field) + (ebib-move-to-field ebib-current-field -1)))) + +(defun ebib-next-field () + "Moves to the next field." + (interactive) + (let ((new-field (ebib-find-visible-field (next-elem ebib-current-field ebib-cur-entry-fields) 1))) + (if (null new-field) + (when (interactive-p) ; i call this function after editing a field, + ; and we don't want a beep then + (beep)) + (setq ebib-current-field new-field) + (ebib-move-to-field ebib-current-field 1)))) + +(defun ebib-goto-first-field () + "Moves to the first field." + (interactive) + (let ((new-field (ebib-find-visible-field (car ebib-cur-entry-fields) 1))) + (if (null new-field) + (beep) + (setq ebib-current-field new-field) + (ebib-move-to-field ebib-current-field -1)))) + +(defun ebib-goto-last-field () + "Moves to the last field." + (interactive) + (let ((new-field (ebib-find-visible-field (last1 ebib-cur-entry-fields) -1))) + (if (null new-field) + (beep) + (setq ebib-current-field new-field) + (ebib-move-to-field ebib-current-field 1)))) + +(defun ebib-goto-next-set () + "Moves to the next set of fields." + (interactive) + (cond + ((eq ebib-current-field 'type*) (ebib-next-field)) + ((member ebib-current-field ebib-additional-fields) (ebib-goto-last-field)) + (t (let* ((entry-type (gethash 'type* ebib-cur-entry-hash)) + (obl-fields (ebib-get-obl-fields entry-type)) + (opt-fields (ebib-get-opt-fields entry-type)) + (new-field nil)) + (when (member ebib-current-field obl-fields) + (setq new-field (ebib-find-visible-field (car opt-fields) 1))) + ;; new-field is nil if there are no opt-fields + (when (or (member ebib-current-field opt-fields) + (null new-field)) + (setq new-field (ebib-find-visible-field (car ebib-additional-fields) 1))) + (if (null new-field) + (ebib-goto-last-field) ; if there was no further set to go to, + ; go to the last field of the current set + (setq ebib-current-field new-field) + (ebib-move-to-field ebib-current-field 1)))))) + +(defun ebib-goto-prev-set () + "Moves to the previous set of fields." + (interactive) + (unless (eq ebib-current-field 'type*) + (let* ((entry-type (gethash 'type* ebib-cur-entry-hash)) + (obl-fields (ebib-get-obl-fields entry-type)) + (opt-fields (ebib-get-opt-fields entry-type)) + (new-field nil)) + (if (member ebib-current-field obl-fields) + (ebib-goto-first-field) + (when (member ebib-current-field ebib-additional-fields) + (setq new-field (ebib-find-visible-field (last1 opt-fields) -1))) + (when (or (member ebib-current-field opt-fields) + (null new-field)) + (setq new-field (ebib-find-visible-field (last1 obl-fields) -1))) + (if (null new-field) + (ebib-goto-first-field) + (setq ebib-current-field new-field) + (ebib-move-to-field ebib-current-field -1)))))) + +(defun ebib-edit-entry-type () + "Edits the entry type." + ;; we don't want the completion buffer to be shown in the index window, + ;; so we need to switch to an appropriate window first. we do this in an + ;; unwind-protect to make sure we always get back to the entry buffer. + (unwind-protect + (progn + (if (eq ebib-layout 'full) + (other-window 1) + (select-window ebib-pre-ebib-window) nil) + (if-str (new-type (completing-read "type: " ebib-entry-types nil t)) + (progn + (puthash 'type* (intern-soft new-type) ebib-cur-entry-hash) + (ebib-fill-entry-buffer) + (setq ebib-cur-entry-fields (ebib-get-all-fields (gethash 'type* ebib-cur-entry-hash))) + (ebib-set-modified t)))) + (select-window (get-buffer-window ebib-entry-buffer) nil))) + +(defun ebib-edit-crossref () + "Edits the crossref field." + ;; we don't want the completion buffer to be shown in the index window, + ;; so we need to switch to an appropriate window first. we do this in an + ;; unwind-protect to make sure we always get back to the entry buffer. + (unwind-protect + (progn + (if (eq ebib-layout 'full) + (other-window 1) + (select-window ebib-pre-ebib-window) nil) + (let ((collection (ebib-create-collection (edb-database ebib-cur-db)))) + (if-str (key (completing-read "Key to insert in `crossref': " collection nil t)) + (progn + (puthash 'crossref (from-raw key) ebib-cur-entry-hash) + (ebib-set-modified t))))) + (select-window (get-buffer-window ebib-entry-buffer) nil) + ;; we now redisplay the entire entry buffer, so that the crossref'ed + ;; fields show up. this also puts the cursor back on the type field. + (ebib-fill-entry-buffer) + (setq ebib-current-field 'crossref) + (re-search-forward "^crossref") + (ebib-set-fields-highlight))) + +;; we should modify ebib-edit-field, so that it calls the appropriate +;; helper function, which asks the user for the new value and just returns +;; that. storing it should then be done by ebib-edit-field, no matter what +;; sort of field the user edits. + +(defun ebib-edit-field () + "Edits a field of a BibTeX entry." + (interactive) + (cond + ((eq ebib-current-field 'type*) (ebib-edit-entry-type)) + ((eq ebib-current-field 'crossref) (ebib-edit-crossref)) + ((eq ebib-current-field 'annote) (ebib-edit-multiline-field)) + (t + (let ((init-contents (gethash ebib-current-field ebib-cur-entry-hash)) + (raw nil)) + (if (multiline-p init-contents) + (ebib-edit-multiline-field) + (when init-contents + (if (raw-p init-contents) + (setq raw t) + (setq init-contents (to-raw init-contents)))) + (if-str (new-contents (read-string (format "%s: " (symbol-name ebib-current-field)) + (if init-contents + (cons init-contents 0) + nil) + ebib-minibuf-hist)) + (puthash ebib-current-field (if raw + new-contents + (concat "{" new-contents "}")) + ebib-cur-entry-hash) + (remhash ebib-current-field ebib-cur-entry-hash)) + (ebib-redisplay-current-field) + ;; we move to the next field, but only if ebib-edit-field was + ;; called interactively, otherwise we get a strange bug in + ;; ebib-toggle-raw... + (if (interactive-p) (ebib-next-field)) + (ebib-set-modified t)))))) + +(defun ebib-browse-url-in-field (num) + "Browses a URL in the current field. +The field may contain a whitespace-separated set of URLs. The +prefix argument indicates which URL is to be sent to the +browser." + (interactive "p") + (let ((urls (to-raw (gethash ebib-current-field ebib-cur-entry-hash)))) + (if (not (and urls + (ebib-call-browser urls num))) + (error "No url found in field `%s'" ebib-current-field)))) + +(defun ebib-view-file-in-field (num) + "Views a file in the current field. +The field may contain a whitespace-separated set of +filenames. The prefix argument indicates which file is to be +viewed." + (interactive "p") + (let ((files (to-raw (gethash ebib-current-field ebib-cur-entry-hash)))) + (if (not (and files + (ebib-call-file-viewer files num))) + (error "No valid filename found in field `%s'" ebib-current-field)))) + +(defun ebib-copy-field-contents () + "Copies the contents of the current field to the kill ring." + (interactive) + (unless (eq ebib-current-field 'type*) + (let ((contents (gethash ebib-current-field ebib-cur-entry-hash))) + (when (stringp contents) + (kill-new contents) + (message "Field contents copied."))))) + +(defun ebib-cut-field-contents () + "Kills the contents of the current field. The killed text is put in the kill ring." + (interactive) + (unless (eq ebib-current-field 'type*) + (let ((contents (gethash ebib-current-field ebib-cur-entry-hash))) + (when (stringp contents) + (remhash ebib-current-field ebib-cur-entry-hash) + (kill-new contents) + (ebib-redisplay-current-field) + (ebib-set-modified t) + (message "Field contents killed."))))) + +(defun ebib-yank-field-contents (arg) + "Inserts the last killed text into the current field. +If the current field already has a contents, nothing is inserted, +unless the previous command was also ebib-yank-field-contents, +then the field contents is replaced with the previous yank. That +is, multiple uses of this command function like the combination +of C-y/M-y. Prefix arguments also work the same as with C-y/M-y." + (interactive "P") + (if (or (eq ebib-current-field 'type*) ; we cannot yank into the type* or crossref fields + (eq ebib-current-field 'crossref) + (unless (eq last-command 'ebib-yank-field-contents) + (gethash ebib-current-field ebib-cur-entry-hash))) ; nor into a field already filled + (progn + (setq this-command t) + (beep)) + (let ((new-contents (current-kill (cond + ((listp arg) (if (eq last-command 'ebib-yank-field-contents) + 1 + 0)) + ((eq arg '-) -2) + (t (1- arg)))))) + (when new-contents + (puthash ebib-current-field new-contents ebib-cur-entry-hash) + (ebib-redisplay-current-field) + (ebib-set-modified t))))) + +(defun ebib-delete-field-contents () + "Deletes the contents of the current field. +The deleted text is not put in the kill ring." + (interactive) + (if (eq ebib-current-field 'type*) + (beep) + (remhash ebib-current-field ebib-cur-entry-hash) + (ebib-redisplay-current-field) + (ebib-set-modified t) + (message "Field contents deleted."))) + +(defun ebib-toggle-raw () + "Toggles the raw status of the current field contents." + (interactive) + (unless (or (eq ebib-current-field 'type*) + (eq ebib-current-field 'crossref)) + (let ((contents (gethash ebib-current-field ebib-cur-entry-hash))) + (if (not contents) ; if there is no value, + (progn + (ebib-edit-field) ; the user can enter one, which we must then make raw + (let ((new-contents (gethash ebib-current-field ebib-cur-entry-hash))) + (when new-contents + ;; note: we don't have to check for empty string, since that is + ;; already done in ebib-edit-field + (puthash ebib-current-field (to-raw new-contents) ebib-cur-entry-hash)))) + (if (raw-p contents) + (puthash ebib-current-field (from-raw contents) ebib-cur-entry-hash) + (puthash ebib-current-field (to-raw contents) ebib-cur-entry-hash))) + (ebib-redisplay-current-field) + (ebib-set-modified t)))) + +(defun ebib-edit-multiline-field () + "Edits the current field in multiline-mode." + (interactive) + (unless (or (eq ebib-current-field 'type*) + (eq ebib-current-field 'crossref)) + (let ((text (gethash ebib-current-field ebib-cur-entry-hash))) + (if (raw-p text) + (setq ebib-multiline-raw t) + (setq text (to-raw text)) + (setq ebib-multiline-raw nil)) + (select-window (ebib-temp-window) nil) + (ebib-multiline-edit 'fields text)))) + +(defun ebib-insert-abbreviation () + "Inserts an abbreviation from the ones defined in the database." + (interactive) + (if (gethash ebib-current-field ebib-cur-entry-hash) + (beep) + (when (edb-strings-list ebib-cur-db) + (unwind-protect + (progn + (other-window 1) + (let* ((collection (ebib-create-collection (edb-strings ebib-cur-db))) + (string (completing-read "Abbreviation to insert: " collection nil t))) + (when string + (puthash ebib-current-field string ebib-cur-entry-hash) + (ebib-set-modified t)))) + (other-window 1) + ;; we can't do this earlier, because we would be writing to the index buffer... + (ebib-redisplay-current-field) + (ebib-next-field))))) + +;;;;;;;;;;;;;;;;;; +;; strings-mode ;; +;;;;;;;;;;;;;;;;;; + +(defvar ebib-strings-mode-map + (let ((map (make-keymap))) + (suppress-keymap map) + (define-key map [up] 'ebib-prev-string) + (define-key map [down] 'ebib-next-string) + (define-key map [prior] 'ebib-strings-page-up) + (define-key map [next] 'ebib-strings-page-down) + (define-key map [home] 'ebib-goto-first-string) + (define-key map [end] 'ebib-goto-last-string) + (define-key map " " 'ebib-strings-page-down) + (define-key map "a" 'ebib-add-string) + (define-key map "b" 'ebib-strings-page-up) + (define-key map "c" 'ebib-copy-string-contents) + (define-key map "d" 'ebib-delete-string) + (define-key map "e" 'ebib-edit-string) + (define-key map "g" 'ebib-goto-first-string) + (define-key map "G" 'ebib-goto-last-string) + (define-key map "j" 'ebib-next-string) + (define-key map "k" 'ebib-prev-string) + (define-key map "l" 'ebib-edit-multiline-string) + (define-key map [(control n)] 'ebib-next-string) + (define-key map [(meta n)] 'ebib-strings-page-down) + (define-key map [(control p)] 'ebib-prev-string) + (define-key map [(meta p)] 'ebib-strings-page-up) + (define-key map "q" 'ebib-quit-strings-buffer) + (define-key map "x" 'ebib-export-string) + (define-key map "X" 'ebib-export-all-strings) + (define-key map "\C-xb" 'disabled) + (define-key map "\C-xk" 'disabled) + map) + "Keymap for the ebib strings buffer.") + +(define-derived-mode ebib-strings-mode + fundamental-mode "Ebib-strings" + "Major mode for the Ebib strings buffer." + (setq buffer-read-only t) + (setq truncate-lines t)) + +(defun ebib-quit-strings-buffer () + "Quits editing the @STRING definitions." + (interactive) + (set-window-dedicated-p (selected-window) nil) + (switch-to-buffer ebib-entry-buffer) + (unless (eq ebib-layout 'full) + (set-window-dedicated-p (selected-window) t)) + (select-window (get-buffer-window ebib-index-buffer) nil)) + +(defun ebib-prev-string () + "Moves to the previous string." + (interactive) + (if (equal ebib-current-string (car (edb-strings-list ebib-cur-db))) ; if we're on the first string + (beep) + ;; go to the beginnig of the highlight and move upward one line. + (goto-char (ebib-highlight-start ebib-strings-highlight)) + (forward-line -1) + (setq ebib-current-string (prev-elem ebib-current-string (edb-strings-list ebib-cur-db))) + (ebib-set-strings-highlight))) + +(defun ebib-next-string () + "Moves to the next string." + (interactive) + (if (equal ebib-current-string (last1 (edb-strings-list ebib-cur-db))) + (when (interactive-p) (beep)) + (goto-char (ebib-highlight-start ebib-strings-highlight)) + (forward-line 1) + (setq ebib-current-string (next-elem ebib-current-string (edb-strings-list ebib-cur-db))) + (ebib-set-strings-highlight))) + +(defun ebib-goto-first-string () + "Moves to the first string." + (interactive) + (setq ebib-current-string (car (edb-strings-list ebib-cur-db))) + (goto-char (point-min)) + (ebib-set-strings-highlight)) + +(defun ebib-goto-last-string () + "Moves to the last string." + (interactive) + (setq ebib-current-string (last1 (edb-strings-list ebib-cur-db))) + (goto-char (point-max)) + (forward-line -1) + (ebib-set-strings-highlight)) + +(defun ebib-strings-page-up () + "Moves 10 entries up in the database." + (interactive) + (let ((number-of-strings (length (edb-strings-list ebib-cur-db))) + (remaining-number-of-strings (length (member ebib-current-string (edb-strings-list ebib-cur-db))))) + (if (<= (- number-of-strings remaining-number-of-strings) 10) + (ebib-goto-first-string) + (setq ebib-current-string (nth + (- number-of-strings remaining-number-of-strings 10) + (edb-strings-list ebib-cur-db))) + (goto-char (ebib-highlight-start ebib-strings-highlight)) + (forward-line -10) + (ebib-set-strings-highlight))) + (message ebib-current-string)) + +(defun ebib-strings-page-down () + "Moves 10 entries down in the database." + (interactive) + (let ((number-of-strings (length (edb-strings-list ebib-cur-db))) + (remaining-number-of-strings (length (member ebib-current-string (edb-strings-list ebib-cur-db))))) + (if (<= remaining-number-of-strings 10) + (ebib-goto-last-string) + (setq ebib-current-string (nth + (- number-of-strings remaining-number-of-strings -10) + (edb-strings-list ebib-cur-db))) + (goto-char (ebib-highlight-start ebib-strings-highlight)) + (forward-line 10) + (ebib-set-strings-highlight))) + (message ebib-current-string)) + +(defun ebib-fill-strings-buffer () + "Fills the strings buffer with the @STRING definitions." + (set-buffer ebib-strings-buffer) + (with-buffer-writable + (erase-buffer) + (dolist (elem (edb-strings-list ebib-cur-db)) + (let ((str (to-raw (gethash elem (edb-strings ebib-cur-db))))) + (insert (format "%-18s %s\n" elem + (if (multiline-p str) + (concat "+" (first-line str)) + (concat " " str))))))) + (goto-char (point-min)) + (setq ebib-current-string (car (edb-strings-list ebib-cur-db))) + (ebib-set-strings-highlight) + (set-buffer-modified-p nil)) + +(defun ebib-edit-string () + "Edits the value of an @STRING definition +When the user enters an empty string, the value is not changed." + (interactive) + (let ((init-contents (to-raw (gethash ebib-current-string (edb-strings ebib-cur-db))))) + (if (multiline-p init-contents) + (ebib-edit-multiline-string) + (if-str (new-contents (read-string (format "%s: " ebib-current-string) + (if init-contents + (cons init-contents 0) + nil) + ebib-minibuf-hist)) + (progn + (puthash ebib-current-string (from-raw new-contents) (edb-strings ebib-cur-db)) + (ebib-redisplay-current-string) + (ebib-next-string) + (ebib-set-modified t)) + (error "@STRING definition cannot be empty"))))) + +(defun ebib-copy-string-contents () + "Copies the contents of the current string to the kill ring." + (interactive) + (let ((contents (gethash ebib-current-string (edb-strings ebib-cur-db)))) + (kill-new contents) + (message "String value copied."))) + +(defun ebib-delete-string () + "Deletes the current @STRING definition from the database." + (interactive) + (when (y-or-n-p (format "Delete @STRING definition %s? " ebib-current-string)) + (remhash ebib-current-string (edb-strings ebib-cur-db)) + (with-buffer-writable + (let ((beg (progn + (goto-char (ebib-highlight-start ebib-strings-highlight)) + (point)))) + (forward-line 1) + (delete-region beg (point)))) + (let ((new-cur-string (next-elem ebib-current-string (edb-strings-list ebib-cur-db)))) + (setf (edb-strings-list ebib-cur-db) (delete ebib-current-string (edb-strings-list ebib-cur-db))) + (when (null new-cur-string) ; deleted the last string + (setq new-cur-string (last1 (edb-strings-list ebib-cur-db))) + (forward-line -1)) + (setq ebib-current-string new-cur-string)) + (ebib-set-strings-highlight) + (ebib-set-modified t) + (message "@STRING definition deleted."))) + +(defun ebib-add-string () + "Creates a new @STRING definition." + (interactive) + (if-str (new-abbr (read-string "New @STRING abbreviation: ")) + (progn + (if (member new-abbr (edb-strings-list ebib-cur-db)) + (error (format "%s already exists" new-abbr))) + (if-str (new-string (read-string (format "Value for %s: " new-abbr))) + (progn + (ebib-insert-string new-abbr new-string ebib-cur-db t) + (sort-in-buffer (length (edb-strings-list ebib-cur-db)) new-abbr) + (with-buffer-writable + (insert (format "%-19s %s\n" new-abbr new-string))) + (forward-line -1) + (ebib-set-strings-highlight) + (setq ebib-current-string new-abbr) + (ebib-set-modified t)))))) + +(defun ebib-export-string (prefix) + "Exports the current @STRING. +The prefix argument indicates which database to copy the string +to. If no prefix argument is present, a filename is asked to +which the string is appended." + (interactive "P") + (let ((num (ebib-prefix prefix))) + (if num + (ebib-export-to-db num (format "@STRING definition `%s' copied to database %%d" ebib-current-string) + #'(lambda (db) + (let ((abbr ebib-current-string) + (string (gethash ebib-current-string (edb-strings ebib-cur-db)))) + (if (member abbr (edb-strings-list db)) + (error "@STRING definition already exists in database %d" num) + (ebib-insert-string abbr string db t))))) + (ebib-export-to-file (format "Export @STRING definition `%s' to file: " ebib-current-string) + (format "@STRING definition `%s' exported to %%s" ebib-current-string) + #'(lambda () + (insert (format "\n@string{%s = %s}\n" + ebib-current-string + (gethash ebib-current-string (edb-strings ebib-cur-db))))))))) + +(defun ebib-export-all-strings (prefix) + "Exports all @STRING definitions. +If a prefix argument is given, it is taken as the database to +copy the definitions to. Without prefix argument, asks for a file +to append them to." + (interactive "P") + (when ebib-current-string ; there is always a current string, unless there are no strings + (let ((num (ebib-prefix prefix))) + (if num + (ebib-export-to-db + num "All @STRING definitions copied to database %d" + #'(lambda (db) + (mapc #'(lambda (abbr) + (if (member abbr (edb-strings-list db)) + (message "@STRING definition `%s' already exists in database %d" abbr num) + (ebib-insert-string abbr (gethash abbr (edb-strings ebib-cur-db)) db t))) + (edb-strings-list ebib-cur-db)))) + (ebib-export-to-file "Export all @STRING definitions to file: " + "All @STRING definitions exported to %s" + #'(lambda () + (insert (format "\n")) ; to keep things tidy. + (ebib-format-strings ebib-cur-db))))))) + +(defun ebib-edit-multiline-string () + "Edits the current string in multiline-mode." + (interactive) + (select-window (ebib-temp-window) nil) + (ebib-multiline-edit 'string (to-raw (gethash ebib-current-string (edb-strings ebib-cur-db))))) + +;;;;;;;;;;;;;;;;;;;;;;;;; +;; multiline edit mode ;; +;;;;;;;;;;;;;;;;;;;;;;;;; + +(define-derived-mode ebib-multiline-edit-mode + text-mode "Ebib-edit" + "Major mode for editing multiline values in Ebib." + ;; we redefine some basic keys because we need them to leave this buffer. + (local-set-key "\C-xb" 'ebib-quit-multiline-edit) + (local-set-key "\C-x\C-s" 'ebib-save-from-multiline-edit) + (local-set-key "\C-xk" 'ebib-cancel-multiline-edit)) + +(defun ebib-multiline-edit (type &optional starttext) + "Switches to Ebib's multiline edit buffer. +STARTTEXT is a string that contains the initial text of the buffer." + ;; note: the buffer is put in the currently active window! + (setq ebib-pre-multiline-buffer (current-buffer)) + (switch-to-buffer ebib-multiline-buffer) + (set-buffer-modified-p nil) + (erase-buffer) + (setq ebib-editing type) + (when starttext + (insert starttext) + (goto-char (point-min)) + (set-buffer-modified-p nil))) + +(defun ebib-quit-multiline-edit () + "Quits the multiline edit buffer, saving the text." + (interactive) + (ebib-store-multiline-text) + (ebib-leave-multiline-edit-buffer) + (cond + ((eq ebib-editing 'fields) + (ebib-next-field)) + ((eq ebib-editing 'strings) + (ebib-next-string))) + (message "Text stored.")) + +(defun ebib-cancel-multiline-edit () + "Quits the multiline edit buffer and discards the changes." + (interactive) + (catch 'no-cancel + (when (buffer-modified-p) + (unless (y-or-n-p "Text has been modified. Abandon changes? ") + (throw 'no-cancel nil))) + (ebib-leave-multiline-edit-buffer))) + +(defun ebib-leave-multiline-edit-buffer () + "Leaves the multiline edit buffer. +Restores the previous buffer in the window that the multiline +edit buffer was shown in." + (switch-to-buffer ebib-pre-multiline-buffer) + (cond + ((eq ebib-editing 'preamble) + (select-window (get-buffer-window ebib-index-buffer) nil)) + ((eq ebib-editing 'fields) + ;; in full-frame layout, select-window isn't necessary, but it doesn't hurt either. + (select-window (get-buffer-window ebib-entry-buffer) nil) + (ebib-redisplay-current-field)) + ((eq ebib-editing 'strings) + ;; in full-frame layout, select-window isn't necessary, but it doesn't hurt either. + (select-window (get-buffer-window ebib-strings-buffer) nil) + (ebib-redisplay-current-string)))) + +(defun ebib-save-from-multiline-edit () + "Saves the database from within the multiline edit buffer. +The text being edited is stored before saving the database." + (interactive) + (ebib-store-multiline-text) + (ebib-save-database ebib-cur-db) + (set-buffer-modified-p nil)) + +(defun ebib-store-multiline-text () + "Stores the text being edited in the multiline edit buffer." + (let ((text (buffer-substring-no-properties (point-min) (point-max)))) + (cond + ((eq ebib-editing 'preamble) + (if (equal text "") + (setf (edb-preamble ebib-cur-db) nil) + (setf (edb-preamble ebib-cur-db) text))) + ((eq ebib-editing 'fields) + (if (equal text "") + (remhash ebib-current-field ebib-cur-entry-hash) + (when (not ebib-multiline-raw) + (setq text (from-raw text))) + (puthash ebib-current-field text ebib-cur-entry-hash))) + ((eq ebib-editing 'strings) + (if (equal text "") + ;; with ERROR, we avoid execution of EBIB-SET-MODIFIED and + ;; MESSAGE, but we also do not switch back to the strings + ;; buffer. this may not be so bad, actually, because the user + ;; may want to change his edit. + (error "@STRING definition cannot be empty ") + (setq text (from-raw text)) ; strings cannot be raw + (puthash ebib-current-string text (edb-strings ebib-cur-db)))))) + (ebib-set-modified t)) + +;;;;;;;;;;;;;;;;;;; +;; ebib-log-mode ;; +;;;;;;;;;;;;;;;;;;; + +(defvar ebib-log-mode-map + (let ((map (make-keymap))) + (suppress-keymap map) + (define-key map " " 'scroll-up) + (define-key map "b" 'scroll-down) + (define-key map "q" 'ebib-quit-log-buffer) + map) + "Keymap for the ebib log buffer.") + +(define-derived-mode ebib-log-mode + fundamental-mode "Ebib-log" + "Major mode for the Ebib log buffer." + (local-set-key "\C-xb" 'ebib-quit-log-buffer) + (local-set-key "\C-xk" 'ebib-quit-log-buffer)) + +(defun ebib-quit-log-buffer () + "Exits the log buffer." + (interactive) + (set-window-dedicated-p (selected-window) nil) + (switch-to-buffer ebib-entry-buffer) + (unless (eq ebib-layout 'full) + (set-window-dedicated-p (selected-window) t)) + (select-window (get-buffer-window ebib-index-buffer) nil)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; functions for non-Ebib buffers ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun ebib-import () + "Searches for BibTeX entries in the current buffer. +The entries are added to the current database (i.e. the database +that was active when Ebib was lowered. Works on the whole buffer, +or on the region if it is active." + (interactive) + (if (not ebib-cur-db) + (error "No database loaded. Use `o' to open a database") + (if (edb-virtual ebib-cur-db) + (error "Cannot import to a virtual database") + (with-syntax-table ebib-syntax-table + (save-excursion + (save-restriction + (if (region-active) + (narrow-to-region (region-beginning) + (region-end))) + (let ((buffer (current-buffer))) + (with-temp-buffer + (insert-buffer-substring buffer) + (let ((n (ebib-find-bibtex-entries t))) + (setf (edb-keys-list ebib-cur-db) (sort (edb-keys-list ebib-cur-db) 'string<)) + (setf (edb-n-entries ebib-cur-db) (length (edb-keys-list ebib-cur-db))) + (when (edb-strings-list ebib-cur-db) + (setf (edb-strings-list ebib-cur-db) (sort (edb-strings-list ebib-cur-db) 'string<))) + (setf (edb-cur-entry ebib-cur-db) (edb-keys-list ebib-cur-db)) + (ebib-fill-entry-buffer) + (ebib-fill-index-buffer) + (ebib-set-modified t) + (message (format "%d entries, %d @STRINGs and %s @PREAMBLE found in buffer." + (car n) + (cadr n) + (if (caddr n) + "a" + "no")))))))))))) + +(defun ebib-get-db-from-filename (filename) + "Returns the database struct associated with FILENAME." + (catch 'found + (mapc #'(lambda (db) + (if (string= (file-name-nondirectory (edb-filename db)) filename) + (throw 'found db))) + ebib-databases) + nil)) + +(defun ebib-get-local-databases () + "Returns a list of .bib files associated with the file in the current LaTeX buffer. +Each element in the list is a string holding the name of the .bib +file. This function simply searches the current LaTeX file or its +master file for a \\bibliography command and returns the file(s) +given in its argument. If no \\bibliography command is found, +returns the symbol NONE." + (let ((texfile-buffer (current-buffer)) + texfile) + ;; if AucTeX's TeX-master is used and set to a string, we must + ;; search that file for a \bibliography command, as it's more + ;; likely to be in there than in the file we're in. + (and (boundp 'TeX-master) + (stringp TeX-master) + (setq texfile (ensure-extension TeX-master "tex"))) + (with-temp-buffer + (if (and texfile (file-readable-p texfile)) + (insert-file-contents texfile) + (insert-buffer-substring texfile-buffer)) + (save-excursion + (goto-char (point-min)) + (if (re-search-forward "\\\\bibliography{\\(.*?\\)}" nil t) + (mapcar #'(lambda (file) + (ensure-extension file "bib")) + (split-string (buffer-substring-no-properties (match-beginning 1) (match-end 1)) ",[ ]*")) + 'none))))) + +(defun ebib-insert-bibtex-key () + "Inserts a BibTeX key at POINT. +The user is prompted for a BibTeX key and has to choose one from +the database(s) associated with the current LaTeX file, or from +the current database if there is no \\bibliography command. Tab +completion works." + (interactive) + (ebib-execute-when + ((database) + (or ebib-local-bibtex-filenames + (setq ebib-local-bibtex-filenames (ebib-get-local-databases))) + (let (collection insert-string) + (if (eq ebib-local-bibtex-filenames 'none) + (if (null (edb-cur-entry ebib-cur-db)) + (error "No entries found in current database") + (setq collection (ebib-create-collection (edb-database ebib-cur-db)))) + (mapc #'(lambda (file) + (let ((db (ebib-get-db-from-filename file))) + (cond + ((null db) + (message "Database %s not loaded" file)) + ((null (edb-cur-entry db)) + (message "No entries in database %s" file)) + (t (setq collection (append (ebib-create-collection (edb-database db)) + collection)))))) + ebib-local-bibtex-filenames)) + (when collection + (let ((key (completing-read "Key to insert: " collection nil t nil ebib-minibuf-hist))) + (if-str (command (completing-read "Command to use: " ebib-insertion-commands + nil nil nil ebib-insertion-commands)) + (let* ((n-opt-args (or + (cdr (assoc command ebib-insertion-commands)) + 1)) + (opt-args (loop for i from 1 to n-opt-args + collect (read-from-minibuffer (format "Optional argument %d: " i))))) + (while (equal (car opt-args) "") ; empty args at the beginning of the list don't need + (setq opt-args (cdr opt-args))) ; to be included. + (setq insert-string (format "\\%s%s{%s}" command + (mapconcat #'(lambda (str) + (format "[%s]" str)) + opt-args "") + key))) + (setq insert-string key))) + (when insert-string + (insert insert-string))))) + ((default) + (error "No database loaded")))) + +(defun ebib-entry-summary () + "Shows the fields of the key at POINT. +The key is searched in the database associated with the LaTeX +file, or in the current database if no \\bibliography command can +be found." + (interactive) + (ebib-execute-when + ((database) + (or ebib-local-bibtex-filenames + (setq ebib-local-bibtex-filenames (ebib-get-local-databases))) + (let ((key (read-string-at-point "\"#%'(),={} \n\t\f")) + entry + database) + (if (eq ebib-local-bibtex-filenames 'none) + (if (not (member key (edb-keys-list ebib-cur-db))) + (error "Entry `%s' is not in the current database" key) + (setq entry (gethash key (edb-database ebib-cur-db))) + (setq database ebib-cur-db)) + (multiple-value-setq (entry database) + (catch 'found + (mapc #'(lambda (file) + (let ((db (ebib-get-db-from-filename file))) + (if (null db) + (message "Database %s not loaded" file) + (if (member key (edb-keys-list db)) + (throw 'found (values (gethash key (edb-database db)) db)))))) + ebib-local-bibtex-filenames) + (list nil nil)))) + (if (null entry) + (error "Entry `%s' not found" key) + (let ((index-window (get-buffer-window ebib-index-buffer))) + (if (not index-window) + (with-help-window "*Help*" + (ebib-format-fields entry 'princ)) + (with-selected-window index-window + (setq ebib-cur-db database) + (ebib-fill-index-buffer) + (setf (edb-cur-entry ebib-cur-db) (member key (edb-keys-list ebib-cur-db))) + (goto-char (point-min)) + (re-search-forward (format "^%s " key)) + (beginning-of-line) + (ebib-set-index-highlight)) + (ebib-fill-entry-buffer)))))) + ((default) + (error "No database(s) loaded")))) + +(provide 'ebib) + +;;; ebib ends here diff --git a/biblio/bibtex/utils/ebib/info/ebib-manual.info b/biblio/bibtex/utils/ebib/info/ebib-manual.info new file mode 100644 index 0000000000..fc0ec3fd61 --- /dev/null +++ b/biblio/bibtex/utils/ebib/info/ebib-manual.info @@ -0,0 +1,2444 @@ +This is /home/joost/programs/ebib/manual/texi/ebib-manual.info, +produced by makeinfo version 4.12 from +/home/joost/programs/ebib/manual/texi/ebib-manual.texi. + +INFO-DIR-SECTION Emacs +START-INFO-DIR-ENTRY +* Ebib: (ebib). A BibTeX database manager that runs in Emacs and XEmacs +END-INFO-DIR-ENTRY + + +File: ebib-manual.info, Node: Top, Next: Installation, Prev: (dir), Up: (dir) + +Overview +******** + +Ebib is a program with which you can manage BibTeX database files +without having to edit the raw `.bib' files. It runs in GNU/Emacs, +version 21.1 or higher (lower versions are not supported) and XEmacs +(at least from version 21.4; lower version have not been tested, but +may work.) + + It should be noted that Ebib is _not_ a minor or major mode for +editing BibTeX files. It is a program in itself, which just happens to +make use of Emacs as a working environment, in the same way that for +example Gnus is. + + The advantage of having a BibTeX database manager inside Emacs is +that X is no longer required, as Emacs can run on the console, and also +that some integration with Emacs' TeX and LaTeX modes becomes possible. +For example, you can push a BibTeX key from Ebib to a LaTeX buffer, or, +vice versa, when you're in a LaTeX buffer, you can consult your BibTeX +database and insert a key from it into the document. Another advantage +of Ebib is that it is completely controlled by key commands: no +stressful mouse movements are required, as with most other (usually +X-based) BibTeX database managers. + +* Menu: + +* Installation:: +* Basic Usage:: +* Advanced Features:: +* The Ebib Buffers:: +* Customisation:: + + +File: ebib-manual.info, Node: Installation, Next: Basic Usage, Prev: Top, Up: Top + +1 Installation +************** + +To install Ebib, so that it will be loaded automatically when Emacs is +started, simply copy the file `ebib.el' to somewhere in your load path +and add the following line to Emacs' init file (`~/.emacs' for +GNU/Emacs, `~/.xemacs/init.el' for XEmacs): + + + (autoload 'ebib "ebib" "Ebib, a BibTeX database manager." t) + + Note: if you do not know what your load path is set to, go to the +`*scratch*' buffer, type `load-path' on an empty line, put the cursor +right after it and type `C-j'. The value of `load-path' will then +appear in the buffer. + + When Ebib is loaded, you can run it with `M-x ebib'. This command is +also used to return to Ebib when you have put the program in the +background. You can bind this command to a key sequence by putting +something like the following in Emacs' init file: + + + (global-set-key "\C-ce" 'ebib) + + You can of course choose any key combination you like. (In Emacs, key +combinations of `C-c <letter>' are reserved for the user, so that no +package may set them.) + + It is recommended to byte-compile the source, Ebib runs quite a lot +faster when it is byte-compiled. You can do this either within Emacs +with `M-x byte-compile-file', or from your shell by going into the +directory where you put `ebib.el' and typing: + + + emacs -batch -f batch-byte-compile ebib.el + + (Substitute `emacs' with `xemacs' if you use XEmacs.) This will +create a file `ebib.elc', which Emacs will load instead of `ebib.el'. +Byte-compiling Ebib may produce a warning about functions that are "not +known to be defined". This can be safely ignored. GNU Emacs and XEmacs +have some small differences, and the functions reported in this warning +are those used by the other version. Ebib makes sure that the correct +functions are called. + + +File: ebib-manual.info, Node: Basic Usage, Next: Advanced Features, Prev: Installation, Up: Top + +2 Basic Usage +************* + +A BibTeX database is somewhat of a free-form database. A BibTeX entry +consists of a set of field-value pairs. Furthermore, each entry is +known by a unique key. The way that Ebib navigates this database is by +having two windows, one that contains a list of all the entry keys in +the database, and one that contains the fields and values of the +currently highlighted entry. + + When Ebib is started, the current windows in Emacs are hidden and +the Emacs frame is divided into two windows. The top one contains a +buffer that is called the _index buffer_, while the lower window +contains the _entry buffer_. When a database is loaded, the index +buffer holds a list of all the keys in the database. You can move +through these keys with the cursor keys. In the entry buffer, the +fields of the currently highlighted entry are shown, with their values. + + In this chapter, all basic functions of Ebib are described, so that +you can get startet with it. At times, reference will be made to later +chapters, where more specific functions are described. + +* Menu: + +* Getting Started:: +* Editing the Database:: +* Saving a Database:: +* Searching:: +* LaTeX Integration:: +* Cross-referencing:: +* Printing the Database:: +* Marking Entries:: +* Calling a Browser:: +* Viewing Files:: + + +File: ebib-manual.info, Node: Getting Started, Next: Editing the Database, Prev: Basic Usage, Up: Basic Usage + +2.1 Getting Started +=================== + +Ebib is started with the command `M-x ebib'. Entering this command +hides all the windows in the current Emacs frame and replaces them with +two windows: the top one contains the index buffer, the bottom one, +taking up the larger part of the screen, contains the entry buffer. The +index buffer is named `none', to indicate that no database has been +loaded. If you open a database, or start a new one, the index buffer +will carry its name. + + You can quit Ebib by typing `q'. You will be asked for confirmation, +and you will receive a warning if you happen to have an unsaved +database. The command `z' can also be used to leave Ebib. However, +unlike `q', which completely quits Ebib, `z' only lowers it, so that it +remains active in the background. The `.bib' files that you have opened +remain loaded, and you can return to them by typing `M-x ebib' again. + +* Menu: + +* Opening a `.bib' file:: +* Navigating a `.bib' file:: +* Starting a New `.bib' File:: + + +File: ebib-manual.info, Node: Opening a `.bib' file, Next: Navigating a `.bib' file, Prev: Getting Started, Up: Getting Started + +2.1.1 Opening a `.bib' file +--------------------------- + +Loading a `.bib' file into Ebib is done with the command `o'. Ebib +reads the file that you specify, and reports how many entries it found, +how many `@string' definitions it found, and whether a `@preamble' was +found. Note that when Ebib reads a `.bib' file, it only reads entry +types (e.g. `book, article, phdthesis' etc.) that it knows about. +Fields (e.g. `author, title, year' etc.) that Ebib does not know +about, are loaded (and saved) but not displayed, so they cannot be +edited. Therefore, you should make sure that all the entry types and +fields that your databases use are defined. A sensible set has been +predefined, so that anyone who's using standard BibTeX entry types +should have no problem loading an existing `.bib' file into Ebib. If, +however, you have custom entry types, or custom fields in your `.bib' +files, you should read the chapter on customising Ebib to learn how to +define them, so that Ebib knows about them. (See *note Entry types: +entry-types.) + + Every time Ebib reads a `.bib' file, it produces a few log messages. +These are written into a special buffer `*Ebib-log*'. If Ebib +encounters entry types in the `.bib' file that it doesn't know, it will +log a warning. If Ebib finds something that it believes to be +incorrect, an error will be logged. If any warnings or errors occur +while loading the `.bib' file, Ebib tells you so after loading the +file. To view the log file, press `l' in the index buffer. + + Note that even if it detects warnings or errors, Ebib will try to +continue parsing the rest of the `.bib' file. That means that normally, +only the entry in which an error occurs is not read. Entries occurring +after the problematic one are read. + + +File: ebib-manual.info, Node: Navigating a `.bib' file, Next: Starting a New `.bib' File, Prev: Opening a `.bib' file, Up: Getting Started + +2.1.2 Navigating a `.bib' file +------------------------------ + +Once you've opened a `.bib' file, the keys of all the entries in the +file are shown in alphabetical order in the index buffer in the top +Ebib window. (In fact, it is possible to show more than just the entry +key in this buffer. See *note Index Display Fields: +index-display-fields. on how to accomplish this.) The first entry is +highlighted, meaning it is the current entry. The fields it holds and +their values are shown in the entry buffer in the bottom Ebib window. +The first field is the type field, which tells you what kind of entry +you're dealing with (i.e. `book, article', etc.). + + Below the type field, Ebib displays (up to) three sets of fields. +The first set are the so-called obligatory fields, the fields that +BibTeX requires to be filled. The second group are the optional fields, +which do not have to be filled but which BibTeX will normally add to +the bibliography if they do have a value. The third group are the +so-called additional fields. These fields are usually ignored by BibTeX +(note that BibTeX normally ignores _all_ fields it does not know), +although there are bibliography styles that treat some of these fields +as optional rather than as additional; (i.e., the `harvard' styles do +typeset the `url' field, if present.) + + The first two groups of fields are different for each entry type, +while the third group are common to all entry types. You can use the +additional fields, for example, to add personal comments to the works +in your database. Ebib by default defines the following additional +fields: `crossref, url, annote, abstract, keywords, file' and +`timestamp'. If these are not sufficient for you, you need to customise +Ebib and add your own fields. (See *note Additional Fields: +additional-fields, if you need to find out how to do that.) + + To move around in the index buffer, you can use the `up' and `down' +cursor keys, `C-p' and `C-n', or for those more used to mutt's key +bindings, `k' and `j'. Furthermore, `Space' and `PgDn' move a screenful +of entries down, while `b' and `PgUp' move in the other direction. +Lastly, `g' and `Home' move to the first entry, while `G' and `End' +move to the last one. + + Ebib is not restricted to opening just one `.bib' file at a time. +You can open more files by just typing `o' again and entering the +filename. Ebib numbers the databases: the number of each database is +shown in the mode line of the index buffer, directly before the +database name. The keys 1--9 provide a quick way of jumping from one +database to another. Note that the numbering is dynamic: if you have +three databases opened and then close the second, database 3 becomes +database 2. + + With the `left' and `right' cursor keys, you can move to the +previous or next database. These keys wrap, so if you hit the `left' +cursor key while the first database is active, you move to the last +database. If you are done with a database and want to close it, type +`c'. This closes the current database. It does not leave Ebib, and all +other databases you have open will remain so. + + +File: ebib-manual.info, Node: Starting a New `.bib' File, Prev: Navigating a `.bib' file, Up: Getting Started + +2.1.3 Starting a New `.bib' File +-------------------------------- + +If you want to start a new `.bib' file from scratch, you cannot just go +and enter entries. You first have to give the database a name. So, to +start a new database, type `o' first, and give the new file a name. +Once you have done this, you can start adding entries to the database. + + +File: ebib-manual.info, Node: Editing the Database, Next: Saving a Database, Prev: Getting Started, Up: Basic Usage + +2.2 Editing the Database +======================== + +Of course, being able to open and view `.bib' files is only half the +fun. One needs to be able to edit the files as well. Ebib's essential +editing facilities are discussed here. + +* Menu: + +* Adding and Deleting Entries:: +* Editing Fields Values:: +* Editing Multiline Values:: +* Copy:: + + +File: ebib-manual.info, Node: Adding and Deleting Entries, Next: Editing Fields Values, Prev: Editing the Database, Up: Editing the Database + +2.2.1 Adding and Deleting Entries +--------------------------------- + +To add an entry to a database, you type `a'. When you do this, Ebib +first asks you for an entry key, as every entry must be identified by a +unique key. Just type a name for the new entry (say `jones1998'). Since +the entry key must be unique, Ebib will complain if you enter a key +that already exists. + + Note that if you should later decide that you want to change the key +of an entry, you can do so with the command `E'. So if you have an +entry with the key `jones1998' and you want to add another entry by +Jones from 1998, you can call the new one `jones1998b' and rename the +existing one to `jones1998a'. + + Deleting an entry is done with `d'. Be careful with this: you will +be asked for confirmation, but once you've confirmed, the entry is +gone, and it is not possible to bring it back. There is no undo in +Ebib. (If you haven't saved the database yet, it is still possible to +retrieve the deleted entry from the `.bib' file, and otherwise it may +still be in the backup file that Ebib creates. See *note Saving a +Database: saving-database.) + + +File: ebib-manual.info, Node: Editing Fields Values, Next: Editing Multiline Values, Prev: Adding and Deleting Entries, Up: Editing the Database + +2.2.2 Editing Fields Values +--------------------------- + +Editing the field values for an entry is done in the lower of the two +Ebib buffers, the so-called entry buffer. You can move focus to the +entry buffer by typing the command `e' in the index buffer. + + You can move between fields with the same keys that you use to move +between entries in the index buffer: the cursor keys `up' and `down', +`C-p' and `C-n', or `j' and `k'. `Space' and `PgDn' move to the next +set of fields, while `PgUp' and `b' move to the previous set of fields. +`g' and `G', and `Home' and `End' also work as expected. + + Editing a field value can be done with `e'. For most fields, Ebib +simply asks you for a string value in the minibuffer. (Here, `RET' +confirms the edit, while `C-g' cancels it.) Although BibTeX requires +that field values be surrounded by braces {} (or double quotes "", but +Ebib does not use those, even though it can of course handle them when +they are used in an existing `.bib' file) you do not need to type +these. Ebib adds them when it saves the `.bib' file. + + Some fields, however, are handled in a special way. The first of +these is the `type' field: if you edit this field, you must enter one +of the predefined entry types. Ebib won't allow you to enter anything +else. You can use tab-completion in this case. Similarly, if you edit +the `crossref' field, Ebib requires that you fill in a key from the +database. Here, too, you can use tab-completion. + + Note that if you're adding a new entry, Ebib automatically puts you +in the entry buffer after you've typed the entry key: you don't have to +type `e' to move to the entry buffer. When creating a new entry, it is +best to set the `type' field first, because the `type' field determines +which other fields are available for an entry. + + Note also that after editing a field, Ebib (usually) puts you on the +next field. This is convenient if you're creating a new entry and need +to fill out several fields in a row. + + If you're done editing the fields of the entry, type `q' to move +focus back to the index buffer. (Note: keys may have different +functions in the index buffer and the entry buffer. `q' is a typical +example: in the entry buffer, it quits editing the entry and moves +focus back to the index buffer. In the index buffer, however, `q' quits +Ebib.) + + +File: ebib-manual.info, Node: Editing Multiline Values, Next: Copy, Prev: Editing Fields Values, Up: Editing the Database + +2.2.3 Editing Multiline Values +------------------------------ + +Apart from the `type' and `crossref' field, there is another field that +Ebib handles in a special way when you edit its value. This is the +`annote' field. Most field values normally consist of a single line of +text. However, because the `annote' field is meant for creating +annotated bibliographies, it would not be very useful if you could only +write one line of text in this field. Therefore, when you edit the +`annote' field, Ebib puts you in the so-called _multiline edit buffer_. +This is essentially a text mode buffer that allows you to enter as much +text as you like. To store the text and leave the multiline edit +buffer, type `C-x b'. (This is of course the standard Emacs command to +switch buffers. It is redefined in Ebib's multiline edit buffer.) + + If you want to leave the multiline edit buffer without saving the +text you have just typed, you can use the command `C-x k'. This too is +redefined in the multiline edit buffer: it leaves the multiline edit +buffer (and hides it), but it does not actually kill the buffer. + + Multiline values are not restricted to the `annote' field. Any field +can in fact hold a multiline value. (Except of course the `type' and +`crossref' fields.) To give a field a multiline value, use `l' instead +of `e'. You will again be put in the multiline edit buffer, where you +can edit the value. Note that you can use `l' even if a field already +has a single line value. Ebib will just make that the first line in the +multiline edit buffer. + + When a field has a multiline value, only the first line is shown in +the entry buffer, for space reasons. To indicate that the value is +multiline, a plus sign `+' is placed in front of the value. + + By the way, the `e' key is smart about the way an entry must be +edited. If you press `e' on a field that already has a multiline value, +regardless of the fact whether it is the `annote' field or not, Ebib +puts you in the multiline edit buffer. Therefore, you need `l' only if +you want to give a field a multiline value when it doesn't have one yet. + + For more details on working with the multiline edit buffer, see +*note The Multiline Edit Buffer: multiline-edit-buffer. + + +File: ebib-manual.info, Node: Copy, Prev: Editing Multiline Values, Up: Editing the Database + +2.2.4 Copy, cut, paste (yank), and delete +----------------------------------------- + +A few more commands are available when you're in the entry buffer +editing field values. The commands `c', `x' and `y' implement a copy +and paste system: `c' copies the contents of the current field to the +kill ring, `x' kills the contents of the current field to the kill +ring, and `y' yanks (pastes) the most recently killed text in the kill +ring. You can type `y' repeatedly to get the same effect you get in +Emacs when you type `M-y' after an initial `C-y': every additional use +of `y' moves back in the kill ring. + + Lastly, there is the command `d', which deletes the contents of the +current field, without asking questions and without storing the text in +the kill ring. + + Note that `y' only works when the current field does not have a value +yet. This is to prevent you from accidentally overwriting a field +value. If you do want to yank text into a field that already has a +value, simply hit `d' first to delete the text. + + +File: ebib-manual.info, Node: Saving a Database, Next: Searching, Prev: Editing the Database, Up: Basic Usage + +2.3 Saving a Database +===================== + +When you have undertaken any kind of editing action on a database, it is +marked as modified, which is indicated in the mode line for the index +buffer. A modified database can be saved by typing `s'. This saves the +database to the file it was loaded from without asking for +confirmation. (It is similar to `C-x C-s' in Emacs.) If you're saving a +file for the first time after loading it, Ebib creates a backup file +under the same name appended with a tilde: `<filename>.bib~'. + + If you have multiple databases open, have made changes in more than +one of them, and want to save all of them without going through each +yourself, you can use `S'. (That's a capital `S'.) This command saves +all modified databases. + + Another way to save a database is to use the command `w'. Use this +if you want to write the database to another file than the one it was +loaded from. Ebib will ask you for a filename to save to, and will of +course warn you if that file happens to exist already. Note that this +command is similar to `C-x C-w' in Emacs, so that after using it, the +new `.bib' file becomes associated with the database. + + +File: ebib-manual.info, Node: Searching, Next: LaTeX Integration, Prev: Saving a Database, Up: Basic Usage + +2.4 Searching +============= + +Ebib provides several search methods. First, if you are in the index +buffer, the normal Emacs incremental searches, `C-s' and `C-r', +function as expected. You can use them to search entry keys. Note that +once you've found the key you're searching, you must hit `ENTER' to +make it active. Ebib does not update the entry buffer during +incremental search, as this would be rather pointless: you're only +interested in the entry you're searching for, not in the entries you +pass along the way. + + Of course, it is also possible to search the database itself. If you +type `/', Ebib asks you for a search term. This can be a regular +expression, to allow for flexibility in searching. After hitting +`ENTER', Ebib will start searching the database (starting from the +current entry, _not_ from the first entry!) and will display the entry +with the first occurrence of the search string that it finds. All the +occurrences of the search string in that entry are highlighted. + + Ebib searches all the fields of each entry. It is not possible with +`/' to specify the fields to search. Note that if the search term is +found in a field with a multiline value, Ebib will highlight the `+' +sign that it displays in front of the field value. Keep an eye out for +this when doing a search, because Ebib only shows the first line of +multiline values, and if the search term appears in another line, the +highlighted `+' is the only indication that the search term was found. +(Well, that and the fact that Ebib does _not_ say `Search string not +found', of course...) + + A search term may of course appear more than once in the database. To +search for the next occurrence, type `n'. This will continue searching +for the search string in the rest of the database. Again, the first +entry found to contain the search string is displayed. Note that `n' +does not wrap: if the end of the database is reached, Ebib stops +searching. To continue searching from the top, hit `g' and then `n'. + + The functions described here form Ebib's basic search functionality. +Ebib also has a much more powerful search mechanism in the form of +_virtual databases_. These are described later. (See *note Virtual +Databases: virtual-databases.) + + +File: ebib-manual.info, Node: LaTeX Integration, Next: Cross-referencing, Prev: Searching, Up: Basic Usage + +2.5 LaTeX Integration +===================== + +Having a BibTeX database manager running inside Emacs has an additional +advantage: it makes it trivially easy to insert BibTeX keys in your +LaTeX documents. + + Ebib provides two functions for this. First, if you're in a LaTeX +buffer, you can call the function `ebib-insert-bibtex-key'. When you +invoke this command, Emacs prompts you for a key from the database(s) +associated with the current buffer, a citation command (that has to be +typed _without_ the backslash) and any optional argument(s) the command +allows. You can type the key using TAB-completion, and after hitting +`RET', Emacs puts a BibTeX citation at the cursor position in the +current buffer with the key you selected. + + You can also do it the other way around: if you're in the index +buffer in Ebib, you can _push_ an entry to a LaTeX buffer. To do this, +use the key `p'. Ebib will ask you for a buffer to push the entry to, a +citation command and also any optional arguments, and then insert a +citation at the current cursor position in the buffer you've supplied. + + For the citation command that `ebib-insert-bibtex-key' and the +command key `p' ask for can be any command that you need. But it is +also possible to predefine a list of citation commands which you can +then enter at this prompt using tab completion. For details on setting +this up, see *note Insertion Commands: insertion-commands. + + There is another function that is available outside Ebib: +`ebib-entry-summary'. This command reads the key under the cursor in the +current buffer and displays the field values associated with that key +in a `*Help*' buffer. This allows you to quickly check a reference in a +text. + + Probably the easiest way to use both `ebib-insert-bibtex-key' and +`ebib-entry-summary' is to bind them to a key sequence. For example, you +could put the following in your `~/.emacs': + + + (add-hook 'LaTeX-mode-hook #'(lambda () + (local-set-key "\C-cb" 'ebib-insert-bibtex-key))) + + This binds `C-c b' to the command `ebib-insert-bibtex-key' in +AUCTeX's LaTeX mode. (Note that commands of the form `C-c <letter>' are +reserved for the user, and should therefore not be set by any package. +For this reasons, Ebib does not set this command automatically.) + +* Menu: + +* Consulting databases from within a LaTeX file:: + + +File: ebib-manual.info, Node: Consulting databases from within a LaTeX file, Prev: LaTeX Integration, Up: LaTeX Integration + +2.5.1 Consulting databases from within a LaTeX file +--------------------------------------------------- + +The commands `ebib-insert-bibtex-key' and `ebib-entry-summary' must +consult the database or databases loaded in Ebib, and Ebib tries to be +smart about which database(s) to consult. Usually, a LaTeX file has a +`\bibliography' command somewhere toward the end, which names the +`.bib' file or files that contain the bibliography entries. If you +consult a BibTeX database from within a LaTeX file, Ebib first looks +for a `\bibliography' command, reads the `.bib' files from it, and then +sees if those files happen to be open. If they are, Ebib uses them to +let you pick an entry key (in the case of `ebib-insert-entry-key') or +to search for the entry (in the case of `ebib-entry-summary'). + + Of course, it may be the case that the LaTeX file is actually part +of a bigger project, and that only the master file contains a +`\bibliography' command. To accommodate for this, Ebib checks whether +the (buffer-local) variable `TeX-master' is set to a filename. If it +is, it reads that file and tries to find the `\bibliography' command +there. (Note: `TeX-master' is an AUCTeX variable, which is used to keep +track of multi-file projects. If you don't use AUCTeX, this +functionality doesn't work, and Ebib will only check the current file +for a `\bibliography' command.) + + Note that if one of the `.bib' files in the `\bibliography' command +isn't loaded, Ebib issues a warning message about this, and continues +to check for the next `.bib' file. These warning messages appear in the +minibuffer, but are probably directly overwritten again by further +messages or prompts Ebib produces, so check the `*Messages*' buffer if +Ebib doesn't seem to be able to find an entry that you're sure is in +one of your databases. + + Another thing to keep in mind is that Ebib only looks for a +`\bibliography' command once: the first time either +`ebib-insert-bibtex-entry' or `ebib-entry-summary' is called. It stores +the result of this search and uses it the next time either of these +commands is used. Therefore, if you make a change to the +`\bibliography' command, you must reload the file (use `M-x +revert-buffer') to make sure Ebib rereads the `\bibliography' command. + + If no `\bibliography' command is found at all, either in the LaTeX +file itself, or in the master file, Ebib simply consults the current +database, i.e. the database that was active when Ebib was lowered with +`z'. + + +File: ebib-manual.info, Node: Cross-referencing, Next: Printing the Database, Prev: LaTeX Integration, Up: Basic Usage + +2.6 Cross-referencing +===================== + +BibTeX has a cross-referencing facility. Suppose you have an entry +`jones1998', which appeared in a book that is also in your database, +say under `miller1998'. You can tell BibTeX that `jones1998' is +contained in `miller1998' by putting `miller1998' in the `crossref' +field. When BibTeX finds such a cross-reference, all the fields of +`jones1998' that don't have a value inherit their values from +`miller1998'. At the very least, this saves you some typing, but more +importantly, if two or more entries cross-reference the same entry, +BibTeX automatically includes the cross-referenced entry in the +bibliography (and puts a reduced reference in the cross-referencing +entries). + + When you fill in the `crossref' field in Ebib, Ebib displays the +values of the cross-referenced entry in the entry buffer. To indicate +that they are just inherited values, they are marked with +`ebib-crossref-face', which by default is red. (You can customise it, +of course. See the customisation option *note Crossref Face: +crossref-face.) These values are just displayed for convenience: +otherwise, Ebib treats these fields as if they are empty. That is, they +cannot be edited (to edit them, you need to edit the cross-referenced +entry), and it's not possible to copy these values to the kill ring. + + If you're viewing an entry that has a cross-reference and you want +to go to the cross-referenced entry you can type `F'. This command +reads the value of the `crossref' field and then displays that entry. +If you want to do the reverse, i.e., see if the current entry is +cross-referenced by any other entries, you can use the key `N'. What +this command actually does is to make the key of the current entry the +current search string and to search for its first occurrence _after_ the +current entry. Like the normal search command `/', `N' does not wrap +and only searches forward. So if you want to search for the next +cross-referencing entry you need to press `n' (i.e., lowercase `n'), +and to continue searching from the first entry, press `g' followed by +`n'. + + Note that if you want to use BibTeX's cross-referencing options, you +need to set the option *note Save Xrefs first: save-xrefs-first. This +tells Ebib to save all entries with a `crossref' field first in the +`.bib' file. Without this, BibTeX's cross-referencing will not work +reliably. + + +File: ebib-manual.info, Node: Printing the Database, Next: Marking Entries, Prev: Cross-referencing, Up: Basic Usage + +2.7 Printing the Database +========================= + +Sometimes it may be useful to have a `.pdf' file or print-out of your +database. Although Ebib does not actually do the printing itself, it can +create a LaTeX file for you that you can compile and print. In fact, +there are two ways of doing this. + + The first is the command `L'. This command creates a simple LaTeX +document that essentially contains a `\nocite{*}' command followed by a +`\bibliography' command referring to the `.bib' file belonging to the +current database. You can then run the usual sequence of LaTeX, BibTeX, +LaTeX, LaTeX on this file, creating a document containing a list of all +the references in your database. + + The second command for printing a database is `P'. This command also +creates a LaTeX file. However, instead of simply providing a +`\nocite{*}' command, `P' creates a `tabular' environment for each +entry in the database listing all the fields of that entry and their +values. + + The difference between `L' and `P' should be obvious: with `L', you +get a list of references created by BibTeX. This means that the +references look the way they will when actually used in a document, but +it also means that the list only contains the information that BibTeX +deems relevant. + + With `P' you get an overview of your database with _all_ the field +values of each entry, including the ones that BibTeX does not use. The +entries are not formatted as literature references, but in a way +similar to how they are shown in Ebib. + + By default, `P' only shows single-line field values. That is, +multiline values are normally excluded. If you want to include +multiline values in the print-out, you have to set the option `Print +Multiline' in Ebib's customisation buffer. (See *note The Customisation +Buffer: customisation-buffer.) With this option set, Ebib will include +all multiline values in the LaTeX file that `P' creates. Note however +that Ebib does not change anything about the formatting of the text in +a multiline value. So if you plan to make (heavy) use of this option, +make sure that the way you type your text conforms to LaTeX's +conventions (e.g. empty lines to mark paragraphs, etc.) and doesn't +contain any characters such as `&' that are illegal in LaTeX. (Or, +alternatively, use LaTeX code in your multiline fields.) + + As mentioned, when you use either `L' or `P', Ebib creates a LaTeX +file. More precisely, it creates a temporary buffer and writes the +LaTeX code into it, and then saves the contents of that buffer to a +file. After it has done that, Ebib lowers itself and instruct Emacs to +open the file in a buffer, which will then be properly set up as a +LaTeX buffer. From there you can run LaTeX and view the result. + + Before doing all this, Ebib asks you which file to write to. Be +careful with this: since this is supposed to be a temporary file, Ebib +simply assumes that if you provide a filename of an existing file, it +can overwrite that file without warning! + + A better way to tell Ebib which file to use is to set the option +`Print Tempfile' in Ebib's customisation buffer to some temporary file. +When this option is set, Ebib will always use this file to write to, +and will not ask you for a filename anymore when you type `L' or `P'. + + There are two more customisation options for printing the database. +These are `Print Preamble' and `LaTeX Preamble'. With these options, +you can specify what Ebib should put in the preamble of the LaTeX files +it creates. Use this if you want to use specific packages (e.g. +`\usepackage{a4}' or `\usepackage{times})'. This is especially useful +for `L', since by default, Ebib uses BibTeX's standard bibliography +style. With the option `LaTeX Preamble' you can set your preferred +bibliography style. Details are discussed in the chapter on +customisation, see *note The Customisation Buffer: customisation-buffer. + + +File: ebib-manual.info, Node: Marking Entries, Next: Calling a Browser, Prev: Printing the Database, Up: Basic Usage + +2.8 Marking Entries +=================== + +Commands in the index buffer generally operate on one single entry, or +on all entries. For some, however, it may sometimes be useful to +perform them on more than one entry, but not necessarily all of them. +This can be achieved by marking entries. You can mark the entries you +want to perform a command on with the key `m'. This marks (or unmarks) +the current entry. Marked entries are displayed in inverse video (in +GNU Emacs) or white on red (in XEmacs; note that the face properties of +marked entries can be customised through the customisation option *note +Marked Face: marked-face.) + + Of the commands discussed so far, four can be used on marked +entries: `d', `p', `L' and `P'. Note, however, that it is not enough to +mark the entries you want and then type any of these commands. If you +do so, they will behave as if no entries were marked. To get these +commands to work on the marked entries, you have to type a semicolon +before them. That is, `; d' deletes all marked entries, and `; L' and +`; P' create a LaTeX file of only the marked entries. The command `m' +itself can also be used with the `;' prefix. If there are any marked +entries, `; m' unmarks them all. Otherwise, `; m' marks all entries. + + `; p' pushes all marked entries to a LaTeX buffer. It does so by +putting them all in a single `\cite' command, separated by commas, not +by putting them in separate `\cite' commands. + + +File: ebib-manual.info, Node: Calling a Browser, Next: Viewing Files, Prev: Marking Entries, Up: Basic Usage + +2.9 Calling a Browser +===================== + +With more and more scientific literature becoming available on-line, it +becomes common to store URLs in a BibTeX database. Sometimes you may +want to load such a URL in your browser. Ebib provides a convenient way +for doing so. + + If you type `u' in the index buffer, Ebib takes the first URL stored +in the `url' field of the current entry and passes it to your browser. +Furthermore, in the entry buffer, you can use `u' on _any_ field. If +you happen to have more than one URL stored in the relevant field, and +you want to pass the second (or third, etc.) to the browser, you can +use a prefix argument. So typing `M-2 u' sends the second URL to your +browser, `M-3 u' the third, and so on. + + It is not even necessary that the relevant field contains _only_ +URLs. It may contain other text mixed with the URLs: Ebib simply +searches the URLs in the field and ignores the rest of the text. Ebib +considers every string of characters that starts with `http://' or +`https://' and that does not contain whitespace or any of the +characters `" ' <' or `>' as a URL. Furthermore, Ebib regards +everything that is enclosed in a LaTeX `\url{...}' command as a URL. +This behaviour is controlled by a regular expression that can be +customised. (See *note Url Regexp: url-regexp.) + + There exists an Emacs function `browse-url', which provides a nifty +interface to calling an external browser. In principle, Ebib uses this +function. However, if this function is not present on your installation, +you can set the option *note Browser Command: browser-command. to call +the browser. + + As just explained, if you press `u' in the index buffer, Ebib +searches the `url' field of the current entry for URLs. If you have the +habit of putting your URLs in another field, however, you may change +the customisation option *note Standard Url Field: standard-url-field. +and tell Ebib to use another field for searching the URLs. (Keep in +mind, though, that in the entry buffer, you can load a URL from any +field.) + + +File: ebib-manual.info, Node: Viewing Files, Prev: Calling a Browser, Up: Basic Usage + +2.10 Viewing Files +================== + +If you have electronic versions of the papers in your database stored on +your computer, you can use Ebib to call external viewers for these +files. The interface for this is similar to that for calling a browser: +if you press `f' in the index buffer, Ebib searches the `file' field +for a filename and when it finds one, calls an appropriate viewer. + + Just as with `u', you can use `f' in the entry buffer as well, in +which case it can be used on any field, not just the `file' field. It +is also possible to have more than one filename in a field: you can +select the one you want to view with the prefix argument. + + Just as in the case of URLs, you can customise several things about +the file view functionality. The option *note Standard File Field: +standard-file-field. allows you to customise the field that `f' +extracts filenames from when pressed in the index buffer. Extracting +filenames is done with a regular expression, which can be customised +through the option *note File Regexp: file-regexp. + + The option *note File Search Dirs: file-search-dirs. allows you to +tell Ebib which directories it needs to search for files. The default +value is `~', which means Ebib just looks in your home dir. Since this +is probably not where you keep your files, you may want to customise +this. Note that you can specify more than one directory. + + Note that Ebib does not search directories recursively. It is +possible, however, to put subdirectories in the filenames. That is, if +you put something like `a/abney1987.pdf' in the `file' field, Ebib +searches for the relevant file in a subdirectory `a/' of the +directories listed in the option `File Search Dirs'. (Note that if you +want to do this under Windows, you may want to remove the backslash +from the file regexp.) + + Ebib can call different external programs depending on the file type +of the relevant file, but you have to specify which programs to call. +The option *note File Associations: file-associations. allows you to do +this. By default, `.pdf' and `.ps' files are handled, by `xpdf' and +`gv', respectively. You can specify further file types by their +extensions (do not include the dot). The program is searched for in +`PATH', but you can of course specify the full path to the program. + + +File: ebib-manual.info, Node: Advanced Features, Next: The Ebib Buffers, Prev: Basic Usage, Up: Top + +3 Advanced Features +******************* + +The features discussed in the previous chapter should be sufficient to +get started using Ebib. However, Ebib has several more advanced +features, which are described in this chapter. + +* Menu: + +* Screen Layout:: +* Preloading `.bib' Files:: +* `@Preamble' Definition:: +* `@String' Definitions:: +* Sorting the `.bib' file:: +* Merging and Importing:: +* Exporting Entries:: +* Timestamps:: +* Multiple Identical Fields:: +* Virtual Databases:: +* The Multiline Edit Buffer:: + + +File: ebib-manual.info, Node: Screen Layout, Next: Preloading `.bib' Files, Prev: Advanced Features, Up: Advanced Features + +3.1 Screen Layout +================= + +By default, Ebib takes over the entire Emacs frame it is started in. If +you have a wide enough screen, however, it may be more convenient to +have Ebib take up only part of the frame, so that you can have the +LaTeX text you're working on and Ebib visible at the same time. The +option *note Layout: layout. allows you to do this, by giving you the +ability to choose between a full-frame or a split-frame layout. + + In the split-frame layout, the Ebib windows are displayed on the +right of the current frame, with the left part free for your document. +In this layout, some aspects of Ebib behave somewhat differently. Most +importantly, the multiline edit buffer is not displayed in the lower +Ebib window, but in the non-Ebib window on the left. (Obviously, after +leaving the multiline edit buffer, the original buffer is restored to +that window.) + + Furthermore, pressing `z' in the index buffer leaves Ebib, but keeps +the buffers visible. You can get back to Ebib with the command `M-x +ebib' (or any key bound to it, of course), or simply by manually +switching to the index buffer. If you want to remove the Ebib buffers +from the frame but keep Ebib in the background, you can use `Z' (i.e. +capital `Z') in the index buffer. (Note that `Z' is also available in +the full-frame layout, but there it is identical to `z'.) + + Lastly, the command `ebib-entry-summary' checks whether the Ebib +buffers are visible in the frame. If they are, it does not output the +entry info in a `*Help*' buffer, but rather displays the entry in Ebib +itself. + + +File: ebib-manual.info, Node: Preloading `.bib' Files, Next: `@Preamble' Definition, Prev: Screen Layout, Up: Advanced Features + +3.2 Preloading `.bib' Files +=========================== + +Chances are that you will be doing most of your work with one or a few +`.bib' files, and you may find yourself opening the same file or files +every time you start Ebib. If so, you can tell Ebib to always load +specific `.bib' files on startup. To do this, specify the files in +Ebib's customisation buffer, under the option *note Preload Bib Files: +preload-bib-files. + + +File: ebib-manual.info, Node: `@Preamble' Definition, Next: `@String' Definitions, Prev: Preloading `.bib' Files, Up: Advanced Features + +3.3 `@Preamble' Definition +========================== + +Apart from database entries, BibTeX allows three more types of elements +to appear in a `.bib' file. These are `@comment', `@preamble' and +`@string' definitions. Ebib provides facilities to handle the latter +two. `@comment' definitions cannot be added to a `.bib' file through +Ebib, and if Ebib finds one in a `.bib' file, it is simply ignored. + + `@preamble' and `@string' definitions can be handled, however. Ebib +allows you to add one `@preamble' definition to the database. In +principle, BibTeX allows more than one such definition, but really one +suffices, because you can use the concatenation character `#' to +include multiple TeX or LaTeX commands. So, rather than having two +`@preamble' definitions such as: + + + @preamble{ "\newcommand{\noopsort}[1]{} " } + @preamble{ "\newcommand{\singleletter}[1]{#1} " } + + you can write this in your `.bib' file: + + + @preamble{ "\newcommand{\noopsort}[1]{} " + # "\newcommand{\singleletter}[1]{#1} " } + + Creating or editing a `@preamble' definition in Ebib is done by +hitting `r' in the index buffer. Ebib uses the multiline edit buffer +for editing the text of the `@preamble' definition, which means that as +discussed above, `C-x b' stores the `@preamble' text and returns focus +to the index buffer, while `C-x k' returns focus to the index buffer +while abandoning any changes you may have made. (For details on using +the multiline edit buffer, see *note The Multiline Edit Buffer: +multiline-edit-buffer.) + + In order to create a `@preamble' as shown above in Ebib, you only +have to type the text between the braces. Ebib takes care of including +the braces of the `@preamble' command, but otherwise it saves the text +exactly as you enter it. So in order to get the preamble above, you'd +have to type the following in Ebib: + + + "\newcommand{\noopsort}[1]{} " + # "\newcommand{\singleletter}[1]{#1} " + + Note that when Ebib loads a `.bib' file that contains more than one +`@preamble' definition, it concatenates all the strings in them in the +manner just described and saves them in one `@preamble' definition. + + +File: ebib-manual.info, Node: `@String' Definitions, Next: Sorting the `.bib' file, Prev: `@Preamble' Definition, Up: Advanced Features + +3.4 `@String' Definitions +========================= + +If you press `t' in the index buffer, Ebib hides the entry buffer in the +lower window and replaces it with the _strings buffer_. In this buffer, +you can add, delete and edit `@string' definitions. + + Adding a `@string' definition is done with the command `a'. This +will first ask you for an abbreviation and then for the value to be +associated with that abbreviation. Once you've entered these, Ebib will +sort the new abbreviation into the buffer. + + Moving between the `@string' definitions can be done in the usual +way: the cursor keys `up' and `down', `C-p' and `C-n' and `k' and `j' +move up and down. `Space' and `PgDn' move ten strings down, while `b' +and `PgUp' move in the other direction. The keys `g', `G', `Home' and +`End' also function as expected. + + To delete a `@string' definition, use `d'. To edit the value of a +definition, use `e'. There is also a command `c', which copies the +value of the current `@string' definition to the kill ring. Unlike in +the entry buffer, there are no corresponing commands `y' and `x'. (In +fact, `x' does exist, but has another function.) Yanking from the kill +ring can be done with `C-y/M-y' in the minibuffer when you edit a +`@string''s value. Cutting a `@string''s value is pointless, because a +`@string' definition must have a value. + + Having defined `@string' definitions, there must of course be a way +to use them. Just giving a field a string abbreviation as value will +not do, because Ebib puts braces around the value that you enter when +it writes the `.bib' file, so that BibTeX will not recognise the +abbreviation, and will not expand it. BibTeX will only recognise an +abbreviation if it appears in the `.bib' file outside of any braces. + + To accomplish this, you must mark a field's value as _raw_. A raw +field is a field whose value is not surrounded by braces when the +database is saved, so that BibTeX recognises it as an abbreviation. To +mark a field raw, press `r'. An asterisk will appear before the field, +indicating that it is raw. Pressing `r' again will change the field +back to normal. If you press `r' on a field that does not have a value +yet, Ebib will ask you for one. + + Note that this also makes it possible to enter field values that are +composed of concatenations of strings and abbreviations. The BibTeX +documentation for example explains that if you have defined: + + + @string{WGA = "World Gnus Almanac"} + + you can create a BibTeX field like this: + + + title = 1966 # WGA + + which will produce "1966 World Gnus Almanac". Or you can do: + + + month = "1~" # jan + + which will produce someting like "1 January", assuming your +bibliography style has defined the abbreviation `jan'. All this is +possible with Ebib, simply by entering the exact text including quotes +or braces around the strings, and marking the relevant field as raw. + + An easy way to enter a `@string' abbreviation as a field value is to +use the key `s' instead of `e'. If you type `s', Ebib asks you for a +`@string' abbreviation to put in the current field, and automatically +marks the field as raw. With this command, Ebib only accepts `@string' +definitions that are in the database, so that by using `s' you can make +sure you don't make any typos. Note that you can use tab completion to +complete a partial string. + + +File: ebib-manual.info, Node: Sorting the `.bib' file, Next: Merging and Importing, Prev: `@String' Definitions, Up: Advanced Features + +3.5 Sorting the `.bib' file +=========================== + +By default, the entries in the database are saved to the `.bib' file in +alphabetical order according to entry key. If you only deal with the +`.bib' file through Ebib, you may not care in which order the entries +are saved. However, it may sometimes be desirable to be able to specify +the sort order of entries in more detail. (Apparently, this can be +useful with ConTeXt, for example.) + + You can specify a sort order in Ebib's customisation buffer. To sort +the entries, you must set at least one sort level (that is, a field to +sort the entries on). You can also specify more than one sort level: if +two entries have identical values for the first sort level, they will +be sorted on the second sort level. E.g., if the first sort level is +`author' and the second is `year', then the entries are sorted by +author, and those entries that have identical values for the `author' +field are sorted by year. + + A sort level is not restricted to a single field. You can specify +more fields for a single sort level. Within a single sort level, a +second sort field is used if the first sort field does not have a +value. For example, books that have an editor instead of an author will +have an empty `author' field. If you sort the database on the `author' +field, such entries will all appear at the beginning of the `.bib' +file, which is most likely not what you want. + + To remedy this, you can specify both the `author' and the `editor' +fields for the first sort level. Ebib will then sort an entry on its +`author' field if it has a value, and will otherwise use the value of +the `editor' field. + + The difference between two sort fields within one sort level and two +sort levels is that a second sort _field_ is an alternative for the +first field when it has no value, while a second sort _level_ is an +additional sort criterion when two or more entries cannot be sorted on +the first level, because they have identical values. + + By default, the option `Sort Order' has no value, which means that +the entries in the `.bib' file are sorted according to entry key. Those +that wish to customise the sort order will usually want to set the +first sort level to `author editor', and the second to `year'. In that +way, the entries in the `.bib' file are sorted according to +author/editor, and entries with the same author/editor are sorted by +year. + + Entries that cannot be sorted on some sort level, because the sort +fields are empty, are sorted on entry key. (Keep in mind that if the +first sort level yields _no value_ for a specific entry, Ebib does +_not_ use the second sort level to sort that entry. It uses the entry +key. The second sort level is only used if the first yields _identical_ +values for two or more entries.) + + Note that if you have set the option `Save Xrefs First' (see *note +Cross-referencing: cross-referencing.), it is pointless to set a sort +order. Saving cross-referencing entries first messes up any sort order, +so Ebib simply ignores the sort order if `Save Xrefs First' is set. + + +File: ebib-manual.info, Node: Merging and Importing, Next: Exporting Entries, Prev: Sorting the `.bib' file, Up: Advanced Features + +3.6 Merging and Importing +========================= + +As described in the previous chapter, adding entries to a database can +be done manually with the key `a'. There are other ways of adding +entries to a database, however. + + With the command `M' you can merge a second `.bib' file into your +current database. When you hit `M', you are asked for a filename. Ebib +then reads the entries in this file and adds them to the database. +Duplicate entries (that is, entries with an entry key that already +exists in the database) will not be loaded. Ebib logs a warning about +each duplicate entry to its log buffer, and displays a warning after +loading the `.bib' file when this happens. + + Another way to add entries to a database is to import them from an +Emacs buffer. If, for example, you find ready-formatted BibTeX entries +in a text file or e.g. on the internet, you can copy & paste them to +any Emacs buffer (e.g. the `*scratch*' buffer), and then execute the +command `M-x ebib-import'. Ebib then goes through the buffer and loads +all BibTeX entries it finds into the current database (i.e. the +database that was active when you lowered Ebib). If you call +`ebib-import' while the region is active, Ebib only reads the BibTeX +entries in the region. + + +File: ebib-manual.info, Node: Exporting Entries, Next: Timestamps, Prev: Merging and Importing, Up: Advanced Features + +3.7 Exporting Entries +===================== + +Sometimes it can be useful to copy entries from one database to +another, or to create a new `.bib' file with several entries from an +existing database. For this purpose, Ebib provides exporting +facilities. To export an entry to a `.bib' file, use the command `x'. +Ebib will ask you for a filename to export the entry to. (If you have +already exported an entry before, Ebib will present the filename you +used as default, but you can of course change it.) + + For obvious reasons, Ebib appends the entry to the file that you +enter if it already exists, it does not overwrite the file. If this is +not what you want, delete the file first, as Ebib provides no way to do +this. + + If you have more than one database open in Ebib, it is also possible +to copy entries from one database to another. To do this, use the `x' +command with a numeric prefix argument. E.g., if the database you want +to export an entry to is the second database, type `M-2 x' to export +the current entry to it. The number of the database is given in the +modeline of the index buffer. + + If the database you're copying an entry to already contains an entry +with the same entry key, Ebib won't copy the entry, and issues an +appropriate warning message. + + Note that the command `x' can operate on marked entries. So to +export several entries in one go mark them and type `; x'. You can use +a prefix argument in the normal way: `M-2 ; x' exports the marked +entries to database 2. + + Apart from entries, it is also possible to export the `@preamble' +and `@string' definitions. The `@preamble' definition is exported with +the command `X' in the index buffer. `@string' definitions can be +exported in the strings buffer: `x' in this buffer exports the current +string, while `X' exports all `@string' definitions in one go. All +these commands function in the same way: when used without a prefix +argument, they ask for a filename, and then append the relevent data to +that file. With a numeric prefix argument, they copy the relevant data +to the corresponding open database. + + +File: ebib-manual.info, Node: Timestamps, Next: Multiple Identical Fields, Prev: Exporting Entries, Up: Advanced Features + +3.8 Timestamps +============== + +Ebib provides the possibility to add a timestamp to every new entry, +recording the time it was added to the database. The timestamp is +recorded in the (additional) field `timestamp'. (By default, this field +is not shown, but you can make it visible by pressing `H' in the index +buffer.) + + You can tell Ebib to create timestamps by setting the option `Use +Timestamp' in Ebib's customisation buffer. With this option set, a +timestamp is included in entries added to the database with `a'. Ebib +will also add a timestamp to entries imported from a buffer or merged +from a file, and to entries exported to another database or to a file. +When importing or exporting entries, existing timestamps will be +overwritten. The logic behind this is that the timestamp records the +date and time when the entry was added to the database, not when it was +first created. + + Note that if this option is unset, the timestamp of an entry is +retained when it's imported or exported. Therefore, if you record +timestamps and want to im-/export entries without changing their +timestamps, temporarily unset this option. + + Ebib uses the function `format-time-string' to create the timestamp. +The format string that Ebib uses can be customised in Ebib's +customisation buffer. The default string is `"%a %b %e %T %Y"', which +produces a timestamp of the form `"Mon Mar 12 01:03:26 2007"'. +Obviously, this string is not suited for sorting, so if you want to be +able to sort on timestamps, you'll need to customise the format string. +See the documentation for `format-time-string' on the options that are +available. + + +File: ebib-manual.info, Node: Multiple Identical Fields, Next: Virtual Databases, Prev: Timestamps, Up: Advanced Features + +3.9 Multiple Identical Fields +============================= + +Under normal circumstances, a BibTeX entry only contains one occurrence +of each field. If BibTeX notices that an entry contains more than one +occurrence of an obligatory or optional field, it issues a warning. +Ebib is somewhat less gracious, it simply takes the value of the last +occurrence without giving any warning. (Note, by the way, that BibTeX +will use the value of the _first_ occurrence, not the last.) When +additional fields appear more than once in an entry, BibTeX does not +warn you, since it ignores those fields anyway. Here, too, Ebib's +standard behaviour is to ignore all but the last value. + + However, some online reference management services "use" this +feature of BibTeX in that they put multiple `keywords' fields in the +BibTeX entries that they produce. If you were to import such an entry +into Ebib, you would lose all your keywords except the last one. To +remedy this, you can tell Ebib that it should allow multiple +occurrences of a single field in a BibTeX entry. You can do this by +setting the customisation option *note Allow Identical Fields: +allow-identical-fields. + + With this option set, Ebib collapses the multiple occurrences into a +single occurrence. All the values of the different occurrences are +collected and stored in the single occurrence, separated by semicolons. +That is, Ebib does not retain the multiple occurrences, but it does +retain the values. So suppose you have an entry that contains the +following `keywords' fields: + + + @book{jones1998, + author = {Jones, Joan}, + year = {1998}, + ... + keywords = {sleep}, + keywords = {winter}, + keywords = {hybernation} + } + + If you load this entry into Ebib with the option `Allow Identical +Fields' set, you will get the following: + + + @book{jones1998, + author = {Jones, Joan}, + year = {1998}, + ... + keywords = {sleep; winter; hybernation} + } + + +File: ebib-manual.info, Node: Virtual Databases, Next: The Multiline Edit Buffer, Prev: Multiple Identical Fields, Up: Advanced Features + +3.10 Virtual Databases +====================== + +In the previous chapter, Ebib's basic search functionality was +discussed. (See *note Searching: searching.) Ebib also provides a much +more sophisticated search and filtering mechanism in the form of +_virtual databases_. + + A virtual database is a database that is not associated with any +`.bib' file. Rather, it is created from another database by selecting +entries from it based on a specific search pattern, called a _filter_. +This allows you, for example, to select all entries from a database +that contain the string "Jones" in their `author' field. A filter can +be as complex as you want: you can select all entries that do _not_ +contain "Jones" in the `author' field, or all entries that contain +"Jones" in either the `author' or the `editor' field, or all entries +that contain "Jones" in the `author' field, and "symbiotic hybernation" +in the `keyword' field, etc. Basically, the filter can consist of an +arbitray number of search criteria combined with the logical operators +`and, or' and `not'. + +* Menu: + +* Simple Selection:: +* Complex Filters:: +* Properties of Virtual Databases:: + + +File: ebib-manual.info, Node: Simple Selection, Next: Complex Filters, Prev: Virtual Databases, Up: Virtual Databases + +3.10.1 Simple Selection +----------------------- + +Creating a virtual database is simple: press `&', and Ebib will ask you +for a field to select on, and for a regular expression to select with. +So if you want to select all entries that contain "Jones" in the +`author' field, you press `&' and type `author' as the field and +`Jones' as the regexp to filter on. + + Ebib will then create a virtual database containing the entries +matching your selection criterion. A virtual database has the same name +as the database it is based on, prepended with `V:'. It also has a +number like any other database, and you can move back and forth to +other databases with the number or cursor keys. + + If you don't want to filter on one specific field but rather want to +select all entries that match a certain regexp in any field, you can +type `any' as the field to filter on. So specifying `any' as the field +and `Jones' as the regexp, the virtual database will select all entries +that have a field that contains "Jones" in them. + + +File: ebib-manual.info, Node: Complex Filters, Next: Properties of Virtual Databases, Prev: Simple Selection, Up: Virtual Databases + +3.10.2 Complex Filters +---------------------- + +Once you have a virtual database, it remains associated with the +database it was created from. This means that you can refine or extend +the selection (i.e. the filter) that the virtual database is based on. +If, in the current example, you want to include all the entries that +have "Jones" in the `editor' field, you have to perform a logical `or' +operation: you want to select an entry if it contains "Jones" in the +`author' field (which you already did) _or_ if it contains "Jones" in +the `editor' field. + + A short sidenote: the first impulse in a case like this might be to +use `and' instead of `or': after all, you want to select all entries +that contain "Jones" in the `author' field _and_ all entries that +contain "Jones" in the `editor' field. However, the filter that you +build up is used to test each entry _individually_ whether it meets the +selection criterion. An entry meets the criterion if it contains +"Jones" in the `author' field _or_ if it contains "Jones" in the +`editor' field. Therefore, `or' is the required operator in this case. +If you would use `and', you would only get those entries that contain +"Jones" in both the `author' _and_ `editor' fields. + + To perform a logical `or' operation, press the key `|'. As before, +you will be asked which field you want to filter on, and which regexp +you want to filter with. Ebib will then update the virtual database +with all entries in the original database that match the additional +criterion. + + It is also possible to perform a logical `and' on the virtual +database. Use this if you want to select those entries that contain +"Jones" in the `author' field and e.g. "symbiotic hybernation" in the +`keyword' field. A logical `and' operation is done with the key `&'. +(Note: this is the same key that is used to create a virtual database. +In fact, you can also create a virtual database with `|': when used in +a normal database, `&' and `|' are equivalent. They are only different +in virtual databases.) + + Both the `&' and `|' commands can be used with the negative prefix +argument `M--' (or `C-u -', which is identical). In this case, the +search criterion is negated. That is, the negative prefix argument +performs a logical `not' operation on the search criterion. + + That is, if you want to select all entries from a database that do +_not_ contain "Jones" in the `author' field, you can do this by typing +`M-- &' and then filling out the relevant field and regexp. This prefix +argument is available both in real and in virtual databases. + + There is another way of performing a logical `not' operation, which +is only available in virtual databases: by pressing the key `~', you +invert the current filter. That is, if you have a virtual database with +all the entries containing "Jones" in the `author' or in the `editor' +field, and you press `~', the selection is inverted, and now contains +all entries that do _not_ have "Jones" in the `author' or `editor' +field. + + Although `~' and the negative prefix argument to `&' or `|' both +perform logical `not' operations, they are _not_ equivalent: `~' +negates the entire filter built up so far, while the negative prefix +argument only negates the single selection criterion you enter with it. + + If you want to know what the filter for the current virtual database +is exactly, you can type `V'. This command displays the current filter +in the minibuffer. The filter is specified as a Lisp expression, +meaning that the operators appear before their operands, not in between +them. That is, `x and y' is written as `(and x y)'. + + With a prefix argument (any prefix argument will do), the command +`V' not only displays the current filter, but also reapplies it. This +can be useful when you've made changes to the source database: Ebib +does not automatically update a virtual database when its source +database is modified. + + +File: ebib-manual.info, Node: Properties of Virtual Databases, Prev: Complex Filters, Up: Virtual Databases + +3.10.3 Properties of Virtual Databases +-------------------------------------- + +Virtual databases differ from normal databases in several ways. First, +they cannot be modified: you cannot add or delete entries, and you +cannot modify the contents of fields. It is also not possible to import +entries to them or merge another file with them. Furthermore, it is not +possible to export entries to them or from them. + + A virtual database cannot be saved in the normal way with `s', and +the command `S' to save all databases ignores virtual databases. If you +want to save a virtual database, you can use the command `w'. This +command not only saves the virtual database, it also changes it into a +normal database, and detaches it from its original source database, so +that you can modify it without affecting the source database. + + The command `L' also doesn't work with virtual databases. The reason +for this is that the virtual database is not associated with an actual +`.bib' file, so there is no file to create a list of references from. +However, it is possible to use the command `P' with a virtual database +to create a list of entries. See *note Printing the Database: +printing-database, for details on these two commands. + + +File: ebib-manual.info, Node: The Multiline Edit Buffer, Prev: Virtual Databases, Up: Advanced Features + +3.11 The Multiline Edit Buffer +============================== + +As mentioned several times before, Ebib has a special multiline edit +buffer, which is used to edit field values that contain newlines +(so-called _multiline fields_), and also to edit the contents of the +`@preamble' command. This section discusses the details of this buffer. + + Ebib enters multiline edit mode in one of three cases: when you +press `P' in the index buffer, to edit the `@preamble' definition, when +you hit `l' in the entry buffer to edit the current field as multiline, +or when you hit `e' on the `annote' field, or on a field whose value +already is multiline. + + The multiline edit buffer uses a special major mode, +`ebib-multiline-edit-mode', which is derived from `text-mode'. The +changes with respect to `text-mode' are minor (see below), which means +that any customisations you may have made to `text-mode' will be +available in the multiline edit buffer. + + The settings that are specific for `ebib-multiline-edit-mode' are the +functions assigned to the key sequences `C-x b', `C-x k' and `C-x C-s'. +These key sequences do not have their usual functions, but rather are +redefined to fit Ebib. Both `C-x b' and `C-x k' can be used to leave +the multiline edit buffer. `C-x b' will store the text as it is to the +database, while `C-x k' leaves the multiline edit buffer _without_ +storing the text, i.e., the original value of the field or preamble +that you were editing is retained. If the text in the buffer was +modified, `C-x k' asks you if you really want to abandon your changes. + + If you leave the multitiline edit buffer with `C-x b' when the +buffer is empty (i.e., you deleted all the text, including the final +newline), and you were editing a field value or the `@preamble' +definition, the field value or preambleis deleted. (This is in fact the +_only_ way to delete the `@preamble' definition. Field values on the +other hand can also be deleted by hitting `x' or `d' on them in the +entry buffer.) + + The third command that is redefined in the multiline edit buffer is +`C-x C-s'. This command can be used to save the database. Because Ebib +does not do an autosave of the current database, it is advisable to +save the database manually every now and then to prevent data loss in +case of crashes. It would be annoying to have to leave the multiline +edit buffer every time you want to do this, so `C-x C-s' has been +redefined to allow you to do this from within the buffer. + + +File: ebib-manual.info, Node: The Ebib Buffers, Next: Customisation, Prev: Advanced Features, Up: Top + +4 The Ebib Buffers +****************** + +This chapter lists all the key commands that exist in Ebib, with a short +description and the actual command that they call. The latter +information is needed if you want to customise Ebib's key bindings. (See +*note Modifying Key Bindings: modifying-key-bindings.) + +* Menu: + +* The Index Buffer:: +* The Entry Buffer:: +* The Strings Buffer:: + + +File: ebib-manual.info, Node: The Index Buffer, Next: The Entry Buffer, Prev: The Ebib Buffers, Up: The Ebib Buffers + +4.1 The Index Buffer +==================== + +*`Up'* + go to previous entry. `(ebib-prev-entry)' + +*`Down'* + go to next entry. `(ebib-next-entry)' + +*`Right'* + move to the next database. `(ebib-next-database)' + +*`Left'* + move to the previous database. `(ebib-prev-database)' + +*`PgUp'* + scroll the index buffer down. `(ebib-index-scroll-down)' + +*`PgDn'* + scroll the index buffer up. `(ebib-index-scroll-up)' + +*`Home'* + go to first entry. `(ebib-goto-first-entry)' + +*`End'* + go to last entry. `(ebib-goto-last-entry)' + +*`Return'* + make the entry under the cursor current. Use after e.g. `C-s'. + `(ebib-select-entry)' + +*`Space'* + equivalent to `PgDn'. + +*`1-9'* + jump to the corresponding database. + +*`/'* + search the database. `(ebib-search)' + +*`&'* + Create a virtual database, or perform a logical `and' on the + current virtual database. With negative prefix argument: apply a + logical `not' to the selectional criterion. `(ebib-virtual-db-and)' + +*`|'* + Create a virtual database, or perform a logical `or' on the current + virtual database. With negative prefix argument: apply a logical + `not' to the selectional criterion. `(ebib-virtual-db-or)' + +*`~'* + Perform a logical `not' on the current virtual database. + `(ebib-virtual-db-not)' + +*`a'* + add an entry. `(ebib-add-entry)' + +*`b'* + equivalent to `Pgup'. + +*`c'* + close the database. `(ebib-close-database)' + +*`C'* + customise Ebib. `(ebib-customize)' + +*`d'* + delete the current entry. `(ebib-delete-entry)' + +*`; d'* + delete all marked entries. + +*`e'* + edit the current entry. `(ebib-edit-entry)' + +*`E'* + edit the key of the current entry. `(ebib-edit-keyname)' + +*`f'* + extract a filename from the `file' field and send it to an + appropriate viewer. With numeric prefix argument, extract the + _n_-th filename. + +*`F'* + follow `crossref' field. `(ebib-follow-crossref)' + +*`g'* + equivalent to `Home'. + +*`G'* + equivalent to `End'. + +*`H'* + show/hide hidden fields. `(ebib-toggle-hidden)' + +*`j'* + equivalent to `Down'. + +*`J'* + jump to another database. This accepts a numeric prefix argument, + but will ask you for a database number if there is none. + `(ebib-switch-to-database)' + +*`k'* + equivalent to `Up'. + +*`l'* + show the log buffer. (`ebib-show-log') + +*`L'* + create a LaTeX file from the current database that produces a list + of references formatted by BibTeX. `(ebib-latex-database)' + +*`; L'* + create a LaTeX file with the marked entries only. + +*`m'* + mark (or unmark) the current entry. `(ebib-mark-entry)' + +*`; m'* + unmark all marked entries. + +*`M'* + merge a `.bib' file. `(ebib-merge-bibtex-file)' + +*`n'* + find next occurrence of the search string. `(ebib-search-next)' + +*`N'* + search for entries cross-referencing the current one. + `(ebib-search-crossref)' + +*`C-n'* + equivalent to `Down'. + +*`M-n'* + equivalent to `PgDn'. + +*`o'* + open a `.bib' file. `(ebib-load-bibtex-file)' + +*`p'* + push an entry to a LaTeX buffer `(ebib-push-bibtex-key)' + +*`; p'* + push the marked entries to a LaTeX buffer. + +*`C-p'* + equivalent to `Up'. + +*`M-p'* + equivalent to `PgUp'. + +*`P'* + create a LaTeX file for printing the database, listing the entire + contents of each entry. `(ebib-print-database)' + +*`; P'* + create a LaTeX file with the marked entries. + +*`r'* + show and edit the `@preamble' definition in the database. + `(ebib-edit-preamble)' + +*`q'* + quit Ebib. This sets all variables to nil, unloads the database(s) + and quits Ebib. `(ebib-quit)' + +*`s'* + save the database. `(ebib-save-current-database)' + +*`S'* + save all modified databases. `(ebib-save-all-databases)' + +*`t'* + show and edit the `@string' definitions in the database. + `(ebib-edit-strings)' + +*`u'* + extract a URL from the `url' field and send it to a browser. With + numeric prefix argument, extract the _n_-th url. + +*`V'* + Display the filter of the current virtual database in the + minibuffer. With prefix argument: reapply the filter. + `(ebib-print-filter)' + +*`w'* + write the database to a different file. `(ebib-write-database)' + +*`x'* + export the current entry to a file, or, when used with numeric + prefix argument, to another database. `(ebib-export-entry)' + +*`; x'* + export the marked entries to a file, or, when used with a numeric + prefix argument, to another database. + +*`C-x b'* + equivalent to `z'. + +*`C-x k'* + equivalent to `q'. + +*`X'* + export the `@preamble' definition to a file or, when used with a + numeric prefix argument, to another database. + `(ebib-export-preamble)' + +*`z'* + move focus away from the Ebib windows. `(ebib-leave-ebib-windows)' + +*`Z'* + put Ebib in the background. `(ebib-lower)' + + One function is not bound to any key: `ebib-print-filename'. + + +File: ebib-manual.info, Node: The Entry Buffer, Next: The Strings Buffer, Prev: The Index Buffer, Up: The Ebib Buffers + +4.2 The Entry Buffer +==================== + +*`Up'* + go to the previous field. `(ebib-prev-field)' + +*`Down'* + go to the next field. `(ebib-next-field)' + +*`PgUp'* + go to the previous set of fields. `(ebib-goto-prev-set)' + +*`PgDn'* + go to the next set of fields. `(ebib-goto-next-set)' + +*`Home'* + go to the first field. `(ebib-goto-first-field)' + +*`End'* + go to the last field. `(ebib-goto-last-field)' + +*`Space'* + equivalent to `PgDn'. + +*`b'* + equivalent to `PgUp'. + +*`c'* + copy the contents of the current field to the kill ring. + `(ebib-copy-field-contents)' + +*`d'* + delete the value of the current field. The deleted contents will + _not_ be put in the kill ring, and is therefore irretrievably + lost. `(ebib-delete-field-contents)' + +*`e'* + edit the current field. `(ebib-edit-fields)' + +*`f'* + extract a filename from the current field and send it to an + appropriate viewer. With numeric prefix argument, extract the + _n_-th filename. + +*`g'* + equivalent to `Home'. + +*`G'* + equivalent to `End'. + +*`j'* + go to the next field. `(ebib-next-field)' + +*`k'* + go to the previous field. `(ebib-prev-field)' + +*`l'* + edit the current field as multiline. `(ebib-edit-multiline-field)' + +*`C-n'* + equivalent to `Down'. + +*`M-n'* + equivalent to `PgDn'. + +*`C-p'* + equivalent to `Up'. + +*`M-p'* + equivalent to `PgUp'. + +*`q'* + quit editing the current entry and return focus to the index + buffer. `(ebib-quit-entry-buffer)' + +*`r'* + toggle a field's "raw" status. `(ebib-toggle-raw)' + +*`s'* + insert an abbreviation from the `@string' definitions in the + database. `(ebib-insert-abbreviation)' + +*`u'* + extract a URL from the current field and send it to a browser. With + numeric prefix argument, extract the _n_-th url. + +*`x'* + cut the contents of the current field. Like `c', `x' puts the + contents of the current field in the kill ring. + `(ebib-cut-field-contents)' + +*`y'* + yank the last element in the kill ring to the current field. + Repeated use of `y' functions like `C-y/M-y'. Note that no text + will be yanked if the field already has a value. + `(ebib-yank-field-contents)' + + +File: ebib-manual.info, Node: The Strings Buffer, Prev: The Entry Buffer, Up: The Ebib Buffers + +4.3 The Strings Buffer +====================== + +*`Up'* + go to the previous string. `(ebib-prev-string)' + +*`Down'* + go to the next string. `(ebib-next-string)' + +*`PgUp'* + go ten strings up. `(ebib-strings-page-up)' + +*`PgDn'* + go ten strings down. `(ebib-strings-page-down)' + +*`Home'* + go to the first string. `(ebib-goto-first-string)' + +*`End'* + go to the last string. `(ebib-goto-last-string)' + +*`Space'* + equivalent to `PgDn'. + +*`a'* + add a new `@string' definition. `(ebib-add-string)' + +*`b'* + equivalent to `PgUp'. + +*`c'* + copy the text of the current string to the kill ring. + `(ebib-copy-string-contents)' + +*`d'* + delete the current `@string' definition from the database. You + will be asked for confirmation. `(ebib-delete-string)' + +*`e'* + edit the value of the current string. `(ebib-edit-string)' + +*`g'* + equivalent to `Home'. + +*`G'* + equivalent to `End'. + +*`j'* + equivalent to `Down'. + +*`k'* + equivalent to `Up'. + +*`l'* + edit the value of the current string as multiline. + `(ebib-edit-multiline-string)' + +*`C-n'* + equivalent to `Down'. + +*`M-n'* + equivalent to `PgDn'. + +*`C-p'* + equivalent to `Up'. + +*`M-p'* + equivalent to `PgUp'. + +*`q'* + quit the strings buffer and return focus to the index buffer. + `(ebib-quit-strings-buffer)' + +*`x'* + export the current `@string' definition to a file or, when used + with a prefix argument, to another database. `(ebib-export-string)' + +*`X'* + export all the `@string' definitions to a file or, when used with a + prefix argument, to another database. `(ebib-export-all-strings)' + + +File: ebib-manual.info, Node: Customisation, Prev: The Ebib Buffers, Up: Top + +5 Customisation +*************** + +Ebib can be customised through Emacs' standard customisation interface. +The only thing that cannot be customised in this way are the key +bindings. If you wish to customise those, you have to use the file +`~/.ebibrc'. + +* Menu: + +* The Customisation Buffer:: +* Modifying Key Bindings:: + + +File: ebib-manual.info, Node: The Customisation Buffer, Next: Modifying Key Bindings, Prev: Customisation, Up: Customisation + +5.1 The Customisation Buffer +============================ + +Ebib's customisation group is a subgroup of the `Tex' group. It can be +invoked by typing `M-x customize-group RET ebib RET', or by pressing +`C' in the index buffer. This chapter gives a short description of all +the options available in the customisation buffer. + +* Menu: + +* Default Type:: +* Preload Bib Files:: +* Additional Fields:: +* Layout:: +* Index Window Size:: +* Index Display Fields:: +* Insertion Commands:: +* Sort Order:: +* Save Xrefs First:: +* Crossref Face:: +* Marked Face:: +* Use Timestamp:: +* Timestamp Format:: +* Standard Url Field:: +* Url Regexp:: +* Browser Command:: +* Standard File Field:: +* File Associations:: +* File Regexp:: +* File Search Dirs:: +* Print Preamble:: +* Print Multiline:: +* Latex Preamble:: +* Print Tempfile:: +* Allow Identical Fields:: +* Entry Types:: + + +File: ebib-manual.info, Node: Default Type, Next: Preload Bib Files, Prev: The Customisation Buffer, Up: The Customisation Buffer + +5.1.1 Default Type +------------------ + +The default type is the default entry type given to a new entry. Every +entry in the Ebib database must have a type, because the type defines +which fields are available. When a new entry is created, Ebib gives it +a default type, which can be customised through this option. The +standard value is `article'. + + +File: ebib-manual.info, Node: Preload Bib Files, Next: Additional Fields, Prev: Default Type, Up: The Customisation Buffer + +5.1.2 Preload Bib Files +----------------------- + +This option allows you to specify which file(s) Ebib is to load when it +starts up. Specify one file per line, press the `INS' button to add more +files. You can complete a partial filename with `M-TAB'. + + +File: ebib-manual.info, Node: Additional Fields, Next: Layout, Prev: Preload Bib Files, Up: The Customisation Buffer + +5.1.3 Additional Fields +----------------------- + +The additional fields are those fields that are available for all entry +types, and which BibTeX generally ignores. This option allows you to +specify which additional fields you wish to use in your database. +Specify one field per line, press the `INS' button to add more fields. + + By default, the following additional fields are defined: `crossref, +url, annote, abstract, keywords, file' and `timestamp'. + + +File: ebib-manual.info, Node: Layout, Next: Index Window Size, Prev: Additional Fields, Up: The Customisation Buffer + +5.1.4 Layout +------------ + +The default value of this option is `full', which means that Ebib takes +over the entire frame when it runs. Alternatively, you can select to +specify a width (in characters) yourself, in which case Ebib takes up +the right part of the frame, leaving the left part free. See *note +Screen Layout: screen-layout. for details. + + +File: ebib-manual.info, Node: Index Window Size, Next: Index Display Fields, Prev: Layout, Up: The Customisation Buffer + +5.1.5 Index Window Size +----------------------- + +This option lets you specify the size of the index window at the top of +the Ebib screen. The default value is 10. + + +File: ebib-manual.info, Node: Index Display Fields, Next: Insertion Commands, Prev: Index Window Size, Up: The Customisation Buffer + +5.1.6 Index Display Fields +-------------------------- + +This option allows you to specify fields that should be displayed next +to the entry key in the index buffer. By default, the index buffer only +shows the key of each entry, but if this is too little information, you +can use this option to display e.g. the title of each entry as well. + + +File: ebib-manual.info, Node: Insertion Commands, Next: Sort Order, Prev: Index Display Fields, Up: The Customisation Buffer + +5.1.7 Insertion Commands +------------------------ + +With the command `ebib-insert-bibtex-key' or with the command key `p' +in the index buffer, you can insert a BibTeX key into a LaTeX buffer. +This option allows you to define the commands that are available +through tab completion when these functions ask for a citation command. + + The citation commands must be given _without_ the leading backslash, +as Ebib adds one. Furthermore, you need to specify how many optional +arguments each command can have. When Ebib prompts you for a citation +key, it will ask for as many optional arguments as you specify here. +(If you don't want to be asked for those optional arguments, just fill +in 0.) + + When Ebib prompts you for a citation command, the commands specified +in this option can be obtained through tab completion. However, it is +not necessary to fill in a command from this list here. You can also +enter another command (in which case Ebib asks for exactly one optional +argument) or even no command at all. In the latter case, Ebib does not +ask for any optional arguments and simply puts the key in the buffer +without adding a backslash or curly braces. + + +File: ebib-manual.info, Node: Sort Order, Next: Save Xrefs First, Prev: Insertion Commands, Up: The Customisation Buffer + +5.1.8 Sort Order +---------------- + +The use of this option is explained above, see *note Sorting the .bib +file: sorting-bib-file. To create a sort order, click the `INS' button +to create a sort level, and then click the `INS' button under that sort +level to enter a sort field. If you want to add more than one sort +field to the sort level, simply hit `INS' again. + + +File: ebib-manual.info, Node: Save Xrefs First, Next: Crossref Face, Prev: Sort Order, Up: The Customisation Buffer + +5.1.9 Save Xrefs First +---------------------- + +For cross-referencing to work, the cross-referencing entries must +appear in the `.bib' file _before_ the cross-referenced entries. In +order to tell Ebib to save all entries with a `crossref' field first, +you must set the option `Save Xrefs First' in Ebib's customisation +buffer. With this option set, BibTeX's crossreferencing options work as +intended. + + By default, this option is unset, because it (marginally) slows down +saving the `.bib' file somewhat. + + +File: ebib-manual.info, Node: Crossref Face, Next: Marked Face, Prev: Save Xrefs First, Up: The Customisation Buffer + +5.1.10 Crossref Face +-------------------- + +Field values inherited from a cross-referenced entry are marked with +this face. By default, the face has red as foreground colour. + + +File: ebib-manual.info, Node: Marked Face, Next: Use Timestamp, Prev: Crossref Face, Up: The Customisation Buffer + +5.1.11 Marked Face +------------------ + +When entries are marked (with `m'), they are highlighted in this face. +By default, GNU Emacs uses the text property `highlight'. XEmacs only +allows this on terminals, therefore it displays marked entries with a +red background and a white foreground colour. This option allows you to +change these defaults. + + +File: ebib-manual.info, Node: Use Timestamp, Next: Timestamp Format, Prev: Marked Face, Up: The Customisation Buffer + +5.1.12 Use Timestamp +-------------------- + +If this option is set, Ebib will add a `timestamp' field to every new +entry, recording the date and time it was added to the database. See +*note Timestamps: timestamps. + + +File: ebib-manual.info, Node: Timestamp Format, Next: Standard Url Field, Prev: Use Timestamp, Up: The Customisation Buffer + +5.1.13 Timestamp Format +----------------------- + +This option specifies the format string that is used to create the +timestamp. The format string is used by `format-time-string' to create +a time representation. The default value is `"%a %b %e %T %Y"', which +produces a timestamp of the form `"Mon Mar 12 01:03:26 2007"'. See the +documentation for `format-time-string' for the forms that the format +string can take. + + +File: ebib-manual.info, Node: Standard Url Field, Next: Url Regexp, Prev: Timestamp Format, Up: The Customisation Buffer + +5.1.14 Standard Url Field +------------------------- + +This is the field that Ebib searches for URLs if you press `u' in the +index buffer. Its default value is `url'. + + +File: ebib-manual.info, Node: Url Regexp, Next: Browser Command, Prev: Standard Url Field, Up: The Customisation Buffer + +5.1.15 Url Regexp +----------------- + +This is the regular expression that Ebib uses to search for URLs in a +field. The default value is: + + + \\url{\(.*\)}\|https?://[^ '<>\"\n\t\f]+ + + With this regular expression, Ebib considers everything that is in a +LaTeX `\url{...}' command as a URL, and furthermore every string of +text that starts with `http://' or `https://' and does not contain +whitespace or one of the characters `' " <' or `>'. + + +File: ebib-manual.info, Node: Browser Command, Next: Standard File Field, Prev: Url Regexp, Up: The Customisation Buffer + +5.1.16 Browser Command +---------------------- + +If this option is unset (which is the default), Ebib uses the Emacs +function `browse-url' to start a browser. If this function does not +exist, you can set this option. For example, if you use the Firefox +browser, set this option to `firefox'. + + For this to work, the browser that you use must be able to handle a +URL on the command line. + + +File: ebib-manual.info, Node: Standard File Field, Next: File Associations, Prev: Browser Command, Up: The Customisation Buffer + +5.1.17 Standard File Field +-------------------------- + +This is the field that Ebib searches for filenames if you press `f' in +the index buffer. Its default value is `file'. + + +File: ebib-manual.info, Node: File Associations, Next: File Regexp, Prev: Standard File Field, Up: The Customisation Buffer + +5.1.18 File Associations +------------------------ + +The programs used to view files. By default, programs for `.pdf' and +`.ps' files are specified, which should be available on most linux +systems. If you prefer other programs or are running on Windows, you'll +can specify them here. Note that Ebib searches the PATH for the +programs, but you can also specify full path names. Of course, it is +also possible to add new associations. + + Note that GNU/Emacs 23 (as yet unreleased) comes with +`doc-view-mode', which provides a way to view `.pdf' and `.ps' files +inside Emacs. (The files are converted to `.png' format first.) If you +prefer to use this mode, simply leave the program field blank for the +relevant file type. + + +File: ebib-manual.info, Node: File Regexp, Next: File Search Dirs, Prev: File Associations, Up: The Customisation Buffer + +5.1.19 File Regexp +------------------ + +In order to find files in a field, Ebib uses a regular expression. The +default value is: + + + [^?|\:*<>\" \n\t\f]+ + + This essentially means that every string of characters not +containing any of the characters + + + ? | \ : * < > " + + or space, newline, tab of formfeed. URLs can easily by recognised by +the prefix `http:', but recognising files is not so straightforward. It +is therefore not advisable to put anything but filenames in the `file' +field. + + +File: ebib-manual.info, Node: File Search Dirs, Next: Print Preamble, Prev: File Regexp, Up: The Customisation Buffer + +5.1.20 File Search Dirs +----------------------- + +This is the list of directories that Ebib searches for files. Note that +searching is not recursive: only the files listed here are searched, not +their subdirectories. + + +File: ebib-manual.info, Node: Print Preamble, Next: Print Multiline, Prev: File Search Dirs, Up: The Customisation Buffer + +5.1.21 Print Preamble +--------------------- + +This option specifies the preamble that is to be added to the LaTeX file +Ebib creates for printing the database (i.e., the `P' command). By +default, the preamble is empty. You can set your own `\usepackage' +commands, or anything else you may need. + + +File: ebib-manual.info, Node: Print Multiline, Next: Latex Preamble, Prev: Print Preamble, Up: The Customisation Buffer + +5.1.22 Print Multiline +---------------------- + +When this options is set, Ebib includes multiline field values when it +creates a LaTeX file with `P' (`ebib-print-database'). When unset, +multiline values are excluded, which saves space. By default, this +option is unset. + + +File: ebib-manual.info, Node: Latex Preamble, Next: Print Tempfile, Prev: Print Multiline, Up: The Customisation Buffer + +5.1.23 Latex Preamble +--------------------- + +This option specifies the preamble to be added to the LaTeX file for +creating a list of references from the database (i.e., the `L' +command). By default, the line `\bibliographystyle{plain}' is put in the +preamble, but you may want to specify your own BibTeX packages and +options. + + +File: ebib-manual.info, Node: Print Tempfile, Next: Allow Identical Fields, Prev: Latex Preamble, Up: The Customisation Buffer + +5.1.24 Print Tempfile +--------------------- + +This option specifies the name and location of the temporary file Ebib +creates with the commands `ebib-print-database' and +`ebib-latex-database'. By default, this option has no value, which +means that Ebib will ask for a filename each time either of these +commands is called. + + +File: ebib-manual.info, Node: Allow Identical Fields, Next: Entry Types, Prev: Print Tempfile, Up: The Customisation Buffer + +5.1.25 Allow Identical Fields +----------------------------- + +If this option is set, Ebib stores the values of multiple occurrences +of a single field within an entry in a single occurrence of that field, +separated by semicolons. By default, this option is unset, because it +slows down the loading of `.bib' files. See *note Multiple Identical +Fields: multiple-identical-fields. + + +File: ebib-manual.info, Node: Entry Types, Prev: Allow Identical Fields, Up: The Customisation Buffer + +5.1.26 Entry Types +------------------ + +This option allows you to customise the entry types that Ebib uses. Each +entry type has a name, a set of obligatory fields and a set of optional +fields. You can add, alter or delete single fields in an entry type, or +whole entry types. + + If you want to add an entry type, hit the `INS' key on the top level +and give the new entry a name, then add obligatory and/or optional +fields. It is not necessary that an entry type has both obligatory and +optional fields, you can define an entry that has only obligatory or +only optional fields. + + +File: ebib-manual.info, Node: Modifying Key Bindings, Prev: The Customisation Buffer, Up: Customisation + +5.2 Modifying Key Bindings +========================== + +If you are unhappy about Ebib's standard key bindings, you can change +them to anything you like. To do this, you have to create a file +`~/.ebibrc' and write your preferred key bindings in it. A key binding +definition is built up as follows: + + + (ebib-key <buffer> <key> <command>) + + `<buffer>' is either `index', `entry' or `strings', for the +corresponding buffer. `<key>' is a standard Emacs key description, and +`<command>' is the Ebib command to be associated with the key. The +commands that can be used here are listed in *note The Ebib Buffers: +ebib-buffers. Note that it is possible to bind more than one key to a +single function: just add as many `ebib-key' statements as necessary. + + As an example, the following binds `C-s' to `ebib-search' in the +index buffer, so that the database can be searched with `C-s' as well +as with `/': + + + (ebib-key index "\C-s" ebib-search) + + If you want to unbind a key, you can simply leave out `<command>'. +So if you want to bind the command `ebib-delete-entry' to `D' rather +than `d', you need to put the following in `.ebibrc': + + + (ebib-key index "D" ebib-delete-entry) + (ebib-key index "d") + + The first line binds `D' to the command `ebib-delete-entry'. The +second line unbinds `d'. + + If a command can be called with a prefix key (as for example +`ebib-delete-entry' can), `ebib-key' will automatically rebind the +prefixed version as well. So in the example above, the first line not +only binds `D', it also binds `; D'. Similarly, the second line not +only unbinds `d', but also `; d'. + + It is also possible to redefine the prefix key itself. To do this, +you must specify `mark-prefix' for `<buffer>'. The value of `<command>' +is irrelevant here, so it can be left out: + + + (ebib-key mark-prefix ":") + + This sets up `:' as the new prefix key. Doing this automatically +unbinds the existing prefix key. + + + +Tag Table: +Node: Top306 +Node: Installation1617 +Node: Basic Usage3491 +Node: Getting Started4888 +Node: Opening a `.bib' file5998 +Node: Navigating a `.bib' file7877 +Node: Starting a New `.bib' File11112 +Node: Editing the Database11577 +Node: Adding and Deleting Entries12036 +Node: Editing Fields Values13302 +Node: Editing Multiline Values15775 +Node: Copy18126 +Node: Saving a Database19243 +Ref: saving-database19405 +Node: Searching20522 +Ref: searching20665 +Node: LaTeX Integration22865 +Node: Consulting databases from within a LaTeX file25311 +Node: Cross-referencing27912 +Ref: cross-referencing28083 +Node: Printing the Database30419 +Ref: printing-database30596 +Node: Marking Entries34409 +Node: Calling a Browser35969 +Node: Viewing Files38119 +Node: Advanced Features40505 +Node: Screen Layout41118 +Ref: screen-layout41285 +Node: Preloading `.bib' Files42823 +Node: `@Preamble' Definition43382 +Node: `@String' Definitions45672 +Node: Sorting the `.bib' file49149 +Ref: sorting-bib-file49348 +Node: Merging and Importing52352 +Node: Exporting Entries53738 +Node: Timestamps55949 +Ref: timestamps56109 +Node: Multiple Identical Fields57700 +Ref: multiple-identical-fields57890 +Node: Virtual Databases59817 +Ref: virtual-databases60008 +Node: Simple Selection61101 +Node: Complex Filters62241 +Node: Properties of Virtual Databases66271 +Node: The Multiline Edit Buffer67611 +Ref: multiline-edit-buffer67784 +Node: The Ebib Buffers70188 +Ref: ebib-buffers70336 +Node: The Index Buffer70675 +Node: The Entry Buffer75718 +Node: The Strings Buffer78064 +Node: Customisation79808 +Ref: customisation79924 +Node: The Customisation Buffer80208 +Ref: customisation-buffer80399 +Node: Default Type81184 +Node: Preload Bib Files81667 +Ref: preload-bib-files81846 +Node: Additional Fields82049 +Ref: additional-fields82222 +Node: Layout82629 +Ref: layout82780 +Node: Index Window Size83102 +Node: Index Display Fields83393 +Ref: index-display-fields83587 +Node: Insertion Commands83872 +Ref: insertion-commands84055 +Node: Sort Order85161 +Node: Save Xrefs First85654 +Ref: save-xrefs-first85824 +Node: Crossref Face86284 +Ref: crossref-face86451 +Node: Marked Face86583 +Ref: marked-face86743 +Node: Use Timestamp87050 +Node: Timestamp Format87387 +Node: Standard Url Field87933 +Ref: standard-url-field88114 +Node: Url Regexp88227 +Ref: url-regexp88391 +Node: Browser Command88799 +Ref: browser-command88974 +Node: Standard File Field89315 +Ref: standard-file-field89505 +Node: File Associations89624 +Ref: file-associations89806 +Node: File Regexp90475 +Ref: file-regexp90642 +Node: File Search Dirs91104 +Ref: file-search-dirs91278 +Node: Print Preamble91446 +Node: Print Multiline91869 +Node: Latex Preamble92266 +Node: Print Tempfile92720 +Node: Allow Identical Fields93176 +Ref: allow-identical-fields93368 +Node: Entry Types93685 +Ref: entry-types93832 +Node: Modifying Key Bindings94371 +Ref: modifying-key-bindings94536 + +End Tag Table + + +Local Variables: +coding: iso-8859-1 +End: |