Turn an ISBN to a bibtex entry

| categories: bibtex | tags:

Occasionally, I need a bibtex entry for a book. Books are often identified by an ISBN number. Similar to using Crossref to get metadata about a DOI, we can use a web service to get metadata about an ISBN. From that, we might be able to construct a bibtex entry.

Here is an example of what we can get for ISBN 9780309095211. It does not seem to matter if there are dashes in the ISBN or not.

(with-current-buffer
        (url-retrieve-synchronously
"http://xisbn.worldcat.org/webservices/xid/isbn/9780309095211?method=getMetadata&format=json&fl=*")
      (buffer-substring url-http-end-of-headers (point-max)))
{
 "stat":"ok",
 "list":[{
	"url":["http://www.worldcat.org/oclc/224969280?referer=xid"],
	"publisher":"National Academies Press",
	"form":["BC"],
	"lccn":["2006016786"],
	"lang":"eng",
	"city":"Washington, D.C.",
	"author":"Committee on the Guide to Recruiting and Advancing Women Scientists and Engineers in Academia, Committee on Women in Science and Engineering, Policy and Global Affairs, National Research Council of the National Academies.",
	"ed":"[Online-Ausg.]",
	"year":"2006",
	"isbn":["9780309095211"],
	"title":"To recruit and advance women students and faculty in science and engineering",
	"oclcnum":["224969280",
	 "70060944",
	 "756709329",
	 "804792476",
	 "817950524",
	 "833420290",
	 "836338922",
	 "704551455"]}]}

We get a nice json data string back. We can parst that to get an actual data structure.

(with-current-buffer
        (url-retrieve-synchronously
"http://xisbn.worldcat.org/webservices/xid/isbn/9780309095211?method=getMetadata&format=json&fl=*")
      (json-read-from-string
        (buffer-substring url-http-end-of-headers (point-max))))
((list .
       [((oclcnum .
                  ["224969280" "70060944" "756709329" "804792476" "817950524" "833420290" "836338922" "704551455"])
         (title . "To recruit and advance women students and faculty in science and engineering")
         (isbn .
               ["9780309095211"])
         (year . "2006")
         (ed . "[Online-Ausg.]")
         (author . "Committee on the Guide to Recruiting and Advancing Women Scientists and Engineers in Academia, Committee on Women in Science and Engineering, Policy and Global Affairs, National Research Council of the National Academies.")
         (city . "Washington, D.C.")
         (lang . "eng")
         (lccn .
               ["2006016786"])
         (form .
               ["BC"])
         (publisher . "National Academies Press")
         (url .
              ["http://www.worldcat.org/oclc/224969280?referer=xid"]))])
 (stat . "ok"))

Ok, so we should check that stat is ok, then build the bibtex entry. Accessing the metadata below seems pretty hacky; but it works, and I don't understand the deep nesting of results, and there seems to be a vector in there.

(let* ((results  (with-current-buffer
                    (url-retrieve-synchronously
                     "http://xisbn.worldcat.org/webservices/xid/isbn/9780309095211?method=getMetadata&format=json&fl=*")
                  (json-read-from-string
                   (buffer-substring url-http-end-of-headers (point-max)))))
       (status (cdr (nth 1 results)))
       (metadata (aref (cdar results) 0)))

  (unless (string= "ok" status)
    (error "Status is %s" status))

  (concat "@book{,\n"
          (mapconcat (lambda (x)
                       (format "  %s={%s}," (car x) (cdr x)))
                     metadata "\n")
          "}\n"))
@book{,
  oclcnum={[224969280 70060944 756709329 804792476 817950524 833420290 836338922 704551455]},
  title={To recruit and advance women students and faculty in science and engineering},
  isbn={[9780309095211]},
  year={2006},
  ed={[Online-Ausg.]},
  author={Committee on the Guide to Recruiting and Advancing Women Scientists and Engineers in Academia, Committee on Women in Science and Engineering, Policy and Global Affairs, National Research Council of the National Academies.},
  city={Washington, D.C.},
  lang={eng},
  lccn={[2006016786]},
  form={[BC]},
  publisher={National Academies Press},
  url={[http://www.worldcat.org/oclc/224969280?referer=xid]},}

That looks good to me. Let us finally wrap it into a function that will take an ISBN and bibtex file interactively, create a bibtex entry, and insert it if there is not an entry with a key like that already. If we have selected region, lI should note this code uses some functionality from my org-ref package (and when I am done here, I am adding it to the doi-utils package inside org-ref). This is a fancy function, built from the experience I have from writing doi-utils.

(defun isbn-to-bibtex (isbn bibfile)
  "Get bibtex entry for ISBN and insert it into BIBFILE unless an
entry with the generated key already exists in the file."
  (interactive
   (list
    (read-input
     "ISBN: "
     ;; now set initial input
     (cond
      ;; If region is active and it starts with a number, we use it
      ((and  (region-active-p)
             (s-match "^[0-9]" (buffer-substring (region-beginning) (region-end))))
       (buffer-substring (region-beginning) (region-end)))
      ;; if first entry in kill ring starts with a number assume it is an isbn
      ;; and use it as the guess
      ((if (s-match "^[0-9]" (car kill-ring))
           (car kill-ring)))
      ;; type or paste it in
      (t
       nil)))
    (ido-completing-read
     "Bibfile: "
     (append (f-entries "." (lambda (f) (f-ext? f "bib")))
             org-ref-default-bibliography))))

  (let* ((results (with-current-buffer
                      (url-retrieve-synchronously
                       (format
                        "http://xisbn.worldcat.org/webservices/xid/isbn/%s?method=getMetadata&format=json&fl=*"
                        isbn))
                    (json-read-from-string
                     (buffer-substring url-http-end-of-headers (point-max)))))
         (status (cdr (nth 1 results)))
         (metadata (aref (cdar results) 0))
         (new-entry)
         (new-key))

    ;; check if we got something
    (unless (string= "ok" status)
      (error "Status is %s" status))

    ;; construct an alphabetically sorted bibtex entry. I assume ISBN numbers go
    ;; with book entries.
    (setq new-entry
          (concat "\n@book{,\n"
                  (mapconcat
                   'identity
                   (loop for field in (-sort 'string-lessp (mapcar 'car metadata))
                         collect
                         (format "  %s={%s}," field (cdr (assoc field metadata))))
                   "\n")
                  "\n}\n"))

    ;; build entry in temp buffer to get the key so we can check for duplicates
    (setq new-entry (with-temp-buffer
                      (insert new-entry)
                      (org-ref-clean-bibtex-entry)
                      (setq new-key (bibtex-key-in-head))
                      (buffer-string)))
    (find-file bibfile)
    (goto-char (point-min))
    (when (search-forward new-key nil t)
      (beep)
      (setq new-key (read-input
                     (format  "%s already exists. Enter new key (C-g to cancel): " new-key)
                     new-key)))
    (goto-char (point-max))
    (insert new-entry)
    ;; set key. It is simplest to just replace it, even if it is the same.
    (bibtex-beginning-of-entry)
    (re-search-forward bibtex-entry-maybe-empty-head)
    (if (match-beginning bibtex-key-in-head)
        (delete-region (match-beginning bibtex-key-in-head)
                       (match-end bibtex-key-in-head)))
    (insert new-key)
    (bibtex-fill-entry)
    (save-buffer)))
isbn-to-bibtex

That is it, for the one ISBN I have tested it on, I get a nicely sorted bibtex entry in the file I select! Hopefully that means no more tedious bibtex entry entering for books! If you use org-ref, just update to the latest version and you should be able to use this function.

Now, back to that proposal I am writing that needs a lot of citations to books that are not in my bibtex file yet, but will be soon ;)

Copyright (C) 2015 by John Kitchin. See the License for information about copying.

org-mode source

Org-mode version = 8.2.10

Discuss on Twitter

Generating your bibliography in another file

| categories: bibtex | tags:

It has been proposal season. This particular round of proposals had a requirement to print the references in a separate file from the proposal. Usually I just build a pdf from org-mode, and then manually separate the references. That is not very fun if you have to do it several times. Here we examine a way to avoid this issue by using a new nobibliography link from org-ref with the bibentry LaTeX package.

We wrote this paper mehta-2014-ident-poten and this one xu-2014-relat.

Bibliography

Here is the resulting pdf, with no references: separate-bib.pdf.

1 Getting the references in another file

Now, we need to get the reference file. We create a new file, in org-mode, mostly for the convenience of exporting that to a pdf. Here is the code that does that.

(let* ((base (file-name-sans-extension
              (file-name-nondirectory (buffer-file-name))))
       (bbl (concat base ".bbl"))
       (orgfile (concat base "-references.org"))
       (pdffile (concat base "-references.pdf")))
  (with-temp-file orgfile
    (insert
     (format "#+LATEX_CLASS: cmu-article
#+OPTIONS: toc:nil

#+BEGIN_LaTeX
\\input{%s}
#+END_LaTeX
" bbl)))

  (find-file orgfile)
  (org-latex-export-to-pdf)
  (org-open-file pdffile))

And, here is the reference file: separate-bib.pdf

I think this would be integrated into a noexport build section of a document that would generate the pdf and references.

Copyright (C) 2014 by John Kitchin. See the License for information about copying.

org-mode source

Org-mode version = 8.2.7c

Discuss on Twitter

Navigating your bibtex file

| categories: bibtex | tags:

You may be able to tell I am spending some time cleaning up bibtex files these days. One of the things I need to do is navigate around a bibtex file easily. There are some built-in navigation keys within an entry.

navigation key strokes
next field C-j
end of field TAB
beginning of entry C-M-a
end of entry C-M-e

I am not aware of an easy way to navigate to the next or previous entry though. I would like something simple to do that. There is a regexp defined in bibtex "bibtex-entry-head", to search for the next or previous entry.

bibtex-entry-head
^[      ]*\(@[  ]*\(?:\(?:Article\|Book\(?:let\)?\|In\(?:Book\|Collection\|Proceedings\)\|M\(?:a\(?:nual\|stersThesis\)\|isc\)\|P\(?:\(?:hdThesi\|roceeding\)s\)\|TechReport\|Unpublished\)\)\)[        ]*[({][         
]*\([][[:alnum:].:;?!`'/*@+|()<>&_^$-]+\)

Here are two functions that do it. This was a little more subtle than I anticipated. The subtlety comes about if you are at the beginning of the entry, we need to move the cursor by a character, and then search forward because of the way re-search-forward works. I also wrote in an option for a prefix argument, so you can go forward or backward several entries.

(defun bibtex-next-entry (&optional n)
  "Jump to the beginning of the next bibtex entry. N is a prefix
argument. If it is numeric, jump that many entries
forward. Negative numbers do nothing."
  (interactive "P")
  ;; Note if we start at the beginning of an entry, nothing
  ;; happens. We need to move forward a char, and call again.
  (when (= (point) (save-excursion
                     (bibtex-beginning-of-entry)))
    (forward-char)
    (bibtex-next-entry))

  ;; search forward for an entry 
  (when 
      (re-search-forward bibtex-entry-head nil t (and (numberp n) n))
    ;; go to beginning of the entry
    (bibtex-beginning-of-entry)))


(defun bibtex-previous-entry (&optional n)
  "Jump to beginning of the previous bibtex entry. N is a prefix
argument. If it is numeric, jump that many entries back."
  (interactive "P")
  (bibtex-beginning-of-entry)
 (when 
     (re-search-backward bibtex-entry-head nil t (and (numberp n) n))
   (bibtex-beginning-of-entry)))
bibtex-previous-entry

That is pretty simple. Let us go ahead and bind these to M-n, and M-p, but only in bibtex-mode. Thanks to Xah Lee for this idea.

(defun jmax-bibtex-mode-keys ()
  "Modify keymaps used by `bibtex-mode'."
  (local-set-key (kbd "M-n") 'bibtex-next-entry)
  (local-set-key (kbd "M-p") 'bibtex-previous-entry))

;; add to bibtex-mode-hook
(add-hook 'bibtex-mode-hook 'jmax-bibtex-mode-keys)
jmax-bibtex-mode-keys

Now, C-n moves forward an entry, C-u 2 C-n moves you two entries, etc… and C-p moves you back an entry, while C-u 2 C-p moves you back two entries.

Finally, I sometimes want to jump to a field in an entry. Basically, I want a completion enabled function that lists the fields in the current entry, and then jumps to the selected field. Yes, you could simply do an incremental search forward or backward that is about as simple. But, then I would not get to remind myself how to do a completion command ;)

(defun jmax-bibtex-get-fields ()
  "Get a list of fields in a bibtex entry."
  (bibtex-beginning-of-entry)
  (remove "=type="
          (remove "=key="
                  (mapcar 'car (bibtex-parse-entry)))))

(defun jmax-bibtex-jump-to-field (field)
  "Jump to FIELD in the current bibtex entry"
  (interactive
   (list
    (ido-completing-read "Field: " (jmax-bibtex-get-fields))))
  (save-restriction
    (bibtex-narrow-to-entry)
    (bibtex-beginning-of-entry)
    (when
        ;; fields start with spaces, a field name, possibly more
        ;; spaces, then =
        (re-search-forward (format "^\\s-*%s\\s-*=" field) nil t))))
jmax-bibtex-jump-to-field

These functions live in https://github.com/jkitchin/jmax/blob/master/jmax-bibtex.el , which is the version we use on a regular basis.

Copyright (C) 2014 by John Kitchin. See the License for information about copying.

org-mode source

Org-mode version = 8.2.7c

Discuss on Twitter

Title casing bibtex entry journal titles

| categories: bibtex | tags:

I mostly love bibtex. You keep bibliographic entries in a central file, and you can cite them in your writing. Bibtex takes care of most of the formatting for you, but not always all of it. Lately, we have been writing some manuscripts for submission to ACS journals. They want the titles of journal articles included in the bibliography, preferrably in title-case, or in sentence case, but all the same format either way. Unfortunately, the achemso.bst bibtex format does not make this happen. You have to title-case or sentence case the titles themselves in your bibtex file. Well, at least we can get Emacs to do the heavy lifting on that for us.

First, the manual approach. Open your bibtex file, navigate to a title field, put your cursor on the first letter of the title, and press M-c until you get to the end of the title. That runs (capitalize-word). For a few titles, you might just do this. It does not take long.

For a lot of entries though, you might prefer some code to do it. Here we consider how to convert all article titles to Title case. The current code can be found at https://github.com/jkitchin/jmax/blob/master/jmax-bibtex.el .

First, we need to decide on some rules. We will capitalize every word in a title except for words like a, an, the, … unless they start the title. We do not want to change words with $, {} in them, or \, because these are either protected or LaTeX commands and we probably do not want to change them. The gist of our idea is to get the title, split it into words, capitalize each word that needs to be, join the words together, and then set the entry title to the new capitalized title.

We use functions from s.el , and doi-utils.org here.

(defvar jmax-lower-case-words
  '("a" "an" "on" "and" "for"
    "the" "of" "in")
  "List of words to keep lowercase")

(defun jmax-title-case-article (&optional key start end)
  "Convert a bibtex entry article title to title-case. The
arguments are optional, and are only there so you can use this
function with `bibtex-map-entries' to change all the title
entries in articles."
  (interactive)
  (bibtex-beginning-of-entry)

  (let* ((title (bibtex-autokey-get-field "title"))
         (words (split-string title))
         (lower-case-words '("a" "an" "on" "and" "for"
                             "the" "of" "in")))
    (when
        (string= "article" (downcase (cdr (assoc "=type=" (bibtex-parse-entry)))))
      (setq words (mapcar
                   (lambda (word)
                     (if (or
                          ;; match words containing {} or \ which are probably
                          ;; LaTeX or protected words
                          (string-match "\\$\\|{\\|}\\|\\\\" word)
                          ;; these words should not be capitalized, unless they
                          ;; are the first word
                          (-contains? lower-case-words (s-downcase word)))
                         word
                       (s-capitalize word)))
                   words))

      ;; Check if first word should be capitalized
      (when (-contains? jmax-lower-case-words (car words))
        (setf (car words) (s-capitalize (car words))))

      ;; this is defined in doi-utils
      (bibtex-set-field
       "title"
       (mapconcat 'identity words " "))
      (bibtex-fill-entry))))
jmax-title-case-article

Now, a single command converts this:

@article{campbell-2013-enthal-entrop,
  author =       {Charles T. Campbell and Jason R. V. Sellers},
  title =        {Enthalpies and entropies of adsorption on
                  well-defined oxide surfaces: experimental
                  measurements},
  journal =      CR,
  volume =       113,
  number =       6,
  pages =        {4106-4135},
  year =         2013,
  doi =          {10.1021/cr300329s},
  url =          {https://doi.org/10.1021/cr300329s},
  month =        6,
}

to this:

@article{campbell-2013-enthal-entrop,
  author =       {Charles T. Campbell and Jason R. V. Sellers},
  title =        {Enthalpies and Entropies of Adsorption on
                  Well-defined Oxide Surfaces: Experimental
                  Measurements},
  journal =      CR,
  volume =       113,
  number =       6,
  pages =        {4106-4135},
  year =         2013,
  doi =          {10.1021/cr300329s},
  url =          {https://doi.org/10.1021/cr300329s},
  month =        6,
}

We wrote the title case function so we can use it with bibtex-map-entries. That means we can fix every entry in a file by putting a comment at the top like this:

% (bibtex-map-entries 'jmax-title-case-article)  <- put cursor here. C-x C-e

The function is not perfect, and does not include every word that should not be capitalized. You will still want to review your entries, but hopefully this saves some typing in the end.

Copyright (C) 2014 by John Kitchin. See the License for information about copying.

org-mode source

Org-mode version = 8.2.7c

Discuss on Twitter

Abbreviated journal names in bibtex

| categories: bibtex | tags:

Some journals require abbreviated journal names in the bibliography, and some require full names. Unfortunately, it is not possible to have both in your bibtex file. Or is it…

It is possible to define a @string that is replaced in your bibtex file. If we have the definition of the @string in a separate file, we can specify its definition there, e.g. as an abbreviation, or as the full name. To make this useful, we need a simple way to add new journals, and to generate the definitions.

First, you can find accepted journal name abbreviations here: http://cassi.cas.org/search.jsp .

We are going to define a variable to hold the string definition, journal full name and an abbreviation. You can find our production version of what follows here: https://github.com/jkitchin/jmax/blob/master/jmax-bibtex.el

(defvar jmax-bibtex-abbreviations
  '(("ACAT" "ACS Catalysis" "ACS Catal.")
    ("AM" "Acta Materialia" "Acta Mater.")
    ("AMM" "Acta Metallurgica et Materialia" "Acta Metall. Mater.")
    ("AMiner" "American Mineralogist" "Am. Mineral.")
    ("AngC" "Angewandte Chemie-International Edition" "Angew. Chem. Int. Edit.")
    ("APLM" "APL Materials" "APL Mat.")
    ("ACBE" "Applied Catalysis B: Environmental" "Appl. Catal. B-Environ.")
    ("APL" "Applied Physics Letters" "Appl. Phys. Lett.")
    ("ASS" "Applied Surface Science" "Appl. Surf. Sci.")
    ("CL" "Catalysis Letters" "Catal. Lett.")
    ("CT" "Catalysis Today" "Catal. Today")
    ("CPL" "Chemical Physics Letters" "Chem. Phys. Lett")
    ("CR" "Chemical Reviews" "Chem. Rev.")
    ("CSR" "Chemical Society Reviews" "Chem. Soc. Rev.")
    ("CSR" "Chemical Society Reviews" "Chem. Soc. Rev.")
    ("CM" "Chemistry of Materials" "Chem. Mater.")
    ("CSA" "Colloids and Surfaces, A: Physicochemical and Engineering Aspects" "Colloids Surf., A")
    ("CPMS" "Computational Materials Science" "Comp. Mater. Sci.")
    ("CPC" "Computer Physics Communications" "Comput. Phys. Commun.")
    ("CGD" "Crystal Growth \\& Design" "Cryst. Growth Des.")
    ("CEC" "CrystEngComm" "CrystEngComm")
    ("ECST" "ECS Transactions" "ECS Trans.")
    ("EES" "Energy \\& Environmental Science" "Energy Environ. Sci.")
    ("HPR" "High Pressure Research" "High Pressure Res.")
    ("IC" "Inorganic Chemistry" "Inorg. Chem.")
    ("IECR" "Industrial \\& Engineering Chemistry Research" "Ind. Eng. Chem. Res.")
    ("JJAP" "Japanese Journal of Applied Physics" "Jpn. J. Appl. Phys.")
    ("JMatR" "Journal of  Materials Research" "J. Mater. Res.")
    ("JALC" "Journal of Alloys and Compounds" "J. Alloy Compd.")
    ("JAC" "Journal of Applied Crystallography" "J. Appl. Crystallogr.")
    ("JAP" "Journal of Applied Physics" "J. Appl. Phys.")
    ("JC" "Journal of Catalysis" "J. Catal.")
    ("JCP" "Journal of Chemical Physics" "J. Chem. Phys.")
    ("JCG" "Journal of Crystal Growth" "J. Crys. Growth")
    ("JMC" "Journal of Materials Chemistry" "J. Mater. Chem.")
    ("JMC" "Journal of Materials Chemistry" "J. Mater. Chem.")
    ("JMSL" "Journal of Materials Science Letters" "J. Mater. Sci. Lett.")
    ("JMS" "Journal of Membrane Science" "J. Memb. Sci.")
    ("JPE" "Journal of Phase Equilibria" "J. Phase Equilib.")
    ("JPCS" "Journal of Physics and Chemistry of Solids" "J. Phys. Chem. Solids")
    ("JPCM" "Journal of Physics: Condensed Matter" "J. Phys.: Condens. Matter")
    ("JSSC" "Journal of Solid State Chemistry" "J. Solid State Chem.")
    ("JACerS" "Journal of the American Ceramic Society" "J. Am. Ceram. Soc.")
    ("JACS" "Journal of the American Chemical Society" "J. Am. Chem. Soc.")
    ("JES" "Journal of The Electrochemical Society" "J. Electrochem. Soc.")
    ("JES" "Journal of The Electrochemical Society" "J. Electrochem. Soc.")
    ("JMS" "Journal of Membrane Science" "J. Memb. Sci.")
    ("JVST" "Journal of Vacuum Science \\& Technology A" "J. Vac. Sci. Technol. A")
    ("ML" "Materials Letters" "Mater. Lett.")
    ("MSE-BS" "Materials Science and Engineering B" "Mat. Sci. Eng. B-Solid")
    ("MOLSIM" "Molecular Simulation" "Mol. Sim.")
    ("Nature" "Nature" "Nature")
    ("NM" "Nature Materials" "Nat. Mater.")
    ("PML" "Philosophical Magazine Letters" "Phil. Mag. Lett.")
    ("PMA" "Philosophical Magazine A" "Phil. Mag. A")
    ("PA" "Physica A: Statistical Mechanics and its Applications" "Physica A")
    ("PB" "Physica B-Condensed Matter" "Physica B")
    ("PCCP" "Physical Chemistry Chemical Physics" "Phys. Chem. Chem. Phys.")
    ("PSSB" "physica status solidi (b)" "Phys. Status Solidi B")
    ("PRA" "Physical Review A" "Phys. Rev. A")
    ("PRB" "Physical Review B" "Phys. Rev. B")
    ("PRL" "Physical Review Letters" "Phys. Rev. Lett.")
    ("PCM" "Physics and Chemistry of Minerals" "Phys. Chem. Miner.")
    ("PSurfSci" "Progress in Surface Science" "Prog. Surf. Sci.")
    ("Science" "Science" "Science")
    ("SABC" "Sensors and Actuators B: Chemical" "Sensor. Actuat. B-Chem.")
    ("SS" "Surface Science" "Surf. Sci.")
    ("EPJB" "The European Physical Journal B" "Eur. Phys. J. B")
    ("JPC" "The Journal of Physical Chemistry" "J. Phys. Chem.")
    ("JPCB" "The Journal of Physical Chemistry  B" "J. Phys. Chem. B")
    ("JPCC" "The Journal of Physical Chemistry C" "J. Phys. Chem. C")
    ("JCP" "The Journal of Chemical Physics" "J. Chem. Phys.")
    ("TSF" "Thin Solid Films" "Thin Solid Films")
    ("TC" "Topics in Catalysis" "Top. Catal.")
    ("WR" "Water Research" "Water Res."))
  "List of (string journal-full-name journal-abbreviation)")
bibtex-abbreviations

This data structure will serve a few purposes.

  1. We will generate the bib files that define the @string definitions
  2. We will use it to modify bibtex files to use those strings.

First, here are some simple functions to generate the @string definitions.

(defun jmax-bibtex-generate-longtitles ()
  (interactive)
  (with-temp-file "longtitles.bib"
    (dolist (row bibtex-abbreviations)
      (insert (format "@string{%s=\"%s\"}\n"
                      (nth 0 row)
                      (nth 1 row))))))

(defun jmax-bibtex-generate-shorttitles ()
  (interactive)
  (with-temp-file "shorttitles.bib"
    (dolist (row bibtex-abbreviations)
      (insert (format "@string{%s=\"%s\"}\n"
                      (nth 0 row)
                      (nth 2 row))))))
jmax-bibtex-generate-shorttitles
(jmax-bibtex-generate-longtitles)
(jmax-bibtex-generate-shorttitles)

Here are the results of running that code: shorttitles.bib and longtitles.bib . This is the first step. We have the @strings defined. Now, we need to convert the names in a bibtex entry to use our string. We want to replace full names and abbreviated names with the @string.

(defun jmax-stringify-journal-name (&optional key start end)
  "replace journal name with a string. The strings are defined in `bibtex-abbreviations'."
  (interactive)
  (bibtex-beginning-of-entry)
  (when
      (string= "article"
               (downcase
                (cdr (assoc "=type=" (bibtex-parse-entry)))))
    (let* ((full-names (mapcar
                        (lambda (row)
                          (cons  (nth 1 row) (nth 0 row)))
                        bibtex-abbreviations))
           (abbrev-names (mapcar
                          (lambda (row)
                            (cons  (nth 2 row) (nth 0 row)))
                          bibtex-abbreviations))
           (journal (s-trim (bibtex-autokey-get-field "journal")))
           (bstring (or
                     (cdr (assoc journal full-names))
                     (cdr (assoc journal abbrev-names)))))
      (when bstring
        (bibtex-set-field "journal" bstring t)
        (bibtex-fill-entry)))))
jmax-stringify-journal-name

Now, with a single command, we can convert this:

@article{lizzit-2001-surfac-ru,
  author =       {S. Lizzit and A. Baraldi and A. Groso and K. Reuter
                  and M. Ganduglia-Pirovano and C. Stampfl and
                  M. Scheffler and M. Stichler and C. Keller and
                  W. Wurth and D. Menzel},
  title =        {Surface Core-level Shifts of Clean and
                  Oxygen-covered {R}u(0001)},
  journal =      {Physical Review B,
  volume =       63,
  number =       20,
  pages =        {nil},
  year =         2001,
  doi =          {10.1103/physrevb.63.205419},
  url =          {https://doi.org/10.1103/PhysRevB.63.205419},
  month =        5,
}

into this:

@article{lizzit-2001-surfac-ru,
  author =       {S. Lizzit and A. Baraldi and A. Groso and K. Reuter
                  and M. Ganduglia-Pirovano and C. Stampfl and
                  M. Scheffler and M. Stichler and C. Keller and
                  W. Wurth and D. Menzel},
  title =        {Surface Core-level Shifts of Clean and
                  Oxygen-covered {R}u(0001)},
  journal =      PRB,
  volume =       63,
  number =       20,
  pages =        {nil},
  year =         2001,
  doi =          {10.1103/physrevb.63.205419},
  url =          {https://doi.org/10.1103/PhysRevB.63.205419},
  month =        5,
}

If you have a lot of entries you want to modify, you can use bibtex-map-entries like this. Basically, put the elisp form in a comment, and then execute the elisp form

%% (bibtex-map-entries 'jmax-stringify-journal-name)  <- put cursor here. C-x C-e

This saves some effort. Over time, I will keep adding entries to the abbreviation table. As long as a standard journal name or abbreviation is in your bibtex file, this approach should work pretty well. After you replace the journal names with @string entries, you have to generate the string file, either shorttitles.bib or longtitles.bib, and in your LaTeX file, change your bibliography line to:

\bibliography{shorttitles,references}

The order is important. The @string definitions are in shorttitles.bib, and your bibtex entries in references.bib.

Copyright (C) 2014 by John Kitchin. See the License for information about copying.

org-mode source

Org-mode version = 8.2.7c

Discuss on Twitter
« Previous Page -- Next Page »