Using the Scopus api with xml output

| categories: xml, scopus, python | tags:

According to http://api.elsevier.com/documentation/AbstractRetrievalAPI.wadl , the native form of the Scopus abstract document is xml, and the full abstract cannot always be represented as json. So… I am going to just bite the bullet and learn to deal with the xml. This is a companion post to http://kitchingroup.cheme.cmu.edu/blog/2015/04/04/Making-highly-linked-bibliographies-from-the-Scopus-API/ . Most of the code in this post gets tangled out to scopus_xml.py. I know it is not totally robust yet, but I have been using it for a lot of analysis, and it works pretty well so far.

This is another long post, with code that probably runs off screen. You can see the end result of what we do in this post here: http://kitchingroup.cheme.cmu.edu/publications.html .

We start with a general function to return an xml elementtree. We build in some caching to avoid downloading things we already have; this is slow, and there are limits on how many times you can download.

import requests
import os
import xml.etree.ElementTree as ET

from my_scopus import MY_API_KEY

def get_abstract_info(EID, refresh=False):
    'Get and save the json data for EID.'
    base = 'scopus-xml/get_abstract_info'
    if not os.path.exists(base):
        os.makedirs(base)

    fname = '{0}/{1}'.format(base, EID)
    if os.path.exists(fname) and not refresh:
        with open(fname) as f:
            return ET.fromstring(f.read())

    # Otherwise retrieve and save results
    url = ("http://api.elsevier.com/content/abstract/eid/" + EID + '?view=META_ABS')
    resp = requests.get(url,
                    headers={'Accept':'application/xml',
                             'X-ELS-APIKey': MY_API_KEY})
    with open(fname, 'w') as f:
        f.write(resp.text.encode('utf-8'))

    results = ET.fromstring(resp.text.encode('utf-8'))

    return results

Next, we do some introspection to see what we have.

from scopus_xml import *
#results = get_abstract_info('2-s2.0-84896759135')
#results = get_abstract_info('2-s2.0-84924911828')
results = get_abstract_info('2-s2.0-84901638552')
for el in results:
    print el.tag
    for el1 in el:
        print '  -->',el1.tag
    print
{http://www.elsevier.com/xml/svapi/abstract/dtd}coredata --> {http://prismstandard.org/namespaces/basic/2.0/}url --> {http://purl.org/dc/elements/1.1/}identifier --> {http://www.elsevier.com/xml/svapi/abstract/dtd}eid --> {http://prismstandard.org/namespaces/basic/2.0/}doi --> {http://purl.org/dc/elements/1.1/}title --> {http://prismstandard.org/namespaces/basic/2.0/}aggregationType --> {http://www.elsevier.com/xml/svapi/abstract/dtd}srctype --> {http://www.elsevier.com/xml/svapi/abstract/dtd}citedby-count --> {http://prismstandard.org/namespaces/basic/2.0/}publicationName --> {http://purl.org/dc/elements/1.1/}publisher --> {http://www.elsevier.com/xml/svapi/abstract/dtd}source-id --> {http://prismstandard.org/namespaces/basic/2.0/}issn --> {http://prismstandard.org/namespaces/basic/2.0/}volume --> {http://prismstandard.org/namespaces/basic/2.0/}startingPage --> {http://prismstandard.org/namespaces/basic/2.0/}endingPage --> {http://prismstandard.org/namespaces/basic/2.0/}pageRange --> {http://prismstandard.org/namespaces/basic/2.0/}coverDate --> {http://purl.org/dc/elements/1.1/}creator --> {http://purl.org/dc/elements/1.1/}description --> {http://www.elsevier.com/xml/svapi/abstract/dtd}link --> {http://www.elsevier.com/xml/svapi/abstract/dtd}link --> {http://www.elsevier.com/xml/svapi/abstract/dtd}link {http://www.elsevier.com/xml/svapi/abstract/dtd}affiliation --> {http://www.elsevier.com/xml/svapi/abstract/dtd}affilname {http://www.elsevier.com/xml/svapi/abstract/dtd}authors --> {http://www.elsevier.com/xml/svapi/abstract/dtd}author --> {http://www.elsevier.com/xml/svapi/abstract/dtd}author

Now, some examples for myself to see how to get things.

from scopus_xml import *

results = get_abstract_info('2-s2.0-84901638552')

coredata = results.find('./{http://www.elsevier.com/xml/svapi/abstract/dtd}coredata')

print coredata.find('{http://www.elsevier.com/xml/svapi/abstract/dtd}srctype').text
print coredata.find('{http://www.elsevier.com/xml/svapi/abstract/dtd}source-id').text

#authors = results.find('./{http://www.elsevier.com/xml/svapi/abstract/dtd}authors')
#for author in results.find('./{http://www.elsevier.com/xml/svapi/abstract/dtd}authors'):
#    print author.find('{http://www.elsevier.com/xml/ani/common}indexed-name').text

for creator in coredata.find('{http://purl.org/dc/elements/1.1/}creator'):
    print creator.attrib

print coredata.find('{http://purl.org/dc/elements/1.1/}title').text
print coredata.find('{http://prismstandard.org/namespaces/basic/2.0/}publicationName').text
print coredata.find('{http://prismstandard.org/namespaces/basic/2.0/}volume').text
print coredata.find('{http://prismstandard.org/namespaces/basic/2.0/}pageRange').text
print coredata.find('{http://prismstandard.org/namespaces/basic/2.0/}coverDate').text
print coredata.find('{http://www.elsevier.com/xml/svapi/abstract/dtd}citedby-count').text
print coredata.find('{http://prismstandard.org/namespaces/basic/2.0/}doi').text

for link in coredata.findall('{http://www.elsevier.com/xml/svapi/abstract/dtd}link'):
    if link.attrib['rel'] == 'scopus':
        print link.attrib['href']
    else:
        print link.attrib['href']

# alternative xpath to get the link
print coredata.find("./{http://www.elsevier.com/xml/svapi/abstract/dtd}link/[@rel='scopus']").attrib['href']
j 22746 {'auid': '55569461200', 'seq': '1'} Relating the electronic structure and reactivity of the 3d transition metal monoxide surfaces Catalysis Communications 52 60-64 2014-07-05 2 10.1016/j.catcom.2013.10.028 http://api.elsevier.com/content/abstract/scopus_id/84901638552 http://www.scopus.com/inward/record.url?partnerID=HzOxMe3b&scp=84901638552&origin=inward http://api.elsevier.com/content/search/scopus?query=refeid%282-s2.0-84901638552%29 http://www.scopus.com/inward/record.url?partnerID=HzOxMe3b&scp=84901638552&origin=inward

That is basically it. In the next sections, we basically recreate the previous functions from scopus.py using the xml data.

1 Authors

def get_author_link(EID):
    results = get_abstract_info(EID)
    authors = results.find('./{http://www.elsevier.com/xml/svapi/abstract/dtd}authors')
    if authors is None:
        return 'No authors found'
    s = []

    for author in authors:
        name = author.find('{http://www.elsevier.com/xml/ani/common}indexed-name').text
        auid = author.attrib['auid']
        s += ['<a href="http://www.scopus.com/authid/detail.url?origin=AuthorProfile&authorId={0}">{1}</a>'.format(auid, name)]

    return ', '.join(s)
from scopus_xml import *
print get_author_link('2-s2.0-84896759135')
print get_author_link('2-s2.0-84901638552')
<a href="http://www.scopus.com/authid/detail.url?origin=AuthorProfile&authorId=8724572500">Thompson R.L.</a>, <a href="http://www.scopus.com/authid/detail.url?origin=AuthorProfile&authorId=22981503200">Shi W.</a>, <a href="http://www.scopus.com/authid/detail.url?origin=AuthorProfile&authorId=6506329719">Albenze E.</a>, <a href="http://www.scopus.com/authid/detail.url?origin=AuthorProfile&authorId=23004637900">Kusuma V.A.</a>, <a href="http://www.scopus.com/authid/detail.url?origin=AuthorProfile&authorId=55676869000">Hopkinson D.</a>, <a href="http://www.scopus.com/authid/detail.url?origin=AuthorProfile&authorId=7003584159">Damodaran K.</a>, <a href="http://www.scopus.com/authid/detail.url?origin=AuthorProfile&authorId=55005205100">Lee A.S.</a>, <a href="http://www.scopus.com/authid/detail.url?origin=AuthorProfile&authorId=7004212771">Kitchin J.R.</a>, <a href="http://www.scopus.com/authid/detail.url?origin=AuthorProfile&authorId=6701399651">Luebke D.R.</a>, <a href="http://www.scopus.com/authid/detail.url?origin=AuthorProfile&authorId=24081524800">Nulwala H.</a>
<a href="http://www.scopus.com/authid/detail.url?origin=AuthorProfile&authorId=55569461200">Xu Z.</a>, <a href="http://www.scopus.com/authid/detail.url?origin=AuthorProfile&authorId=7004212771">Kitchin J.R.</a>

2 Journal

def get_journal_link(EID):
    results = get_abstract_info(EID)
    coredata = results.find('./{http://www.elsevier.com/xml/svapi/abstract/dtd}coredata')

    journal = coredata.find('{http://prismstandard.org/namespaces/basic/2.0/}publicationName').text
    sid = coredata.find('{http://www.elsevier.com/xml/svapi/abstract/dtd}source-id').text
    s = '<a href="http://www.scopus.com/source/sourceInfo.url?sourceId={sid}">{journal}</a>'

    return s.format(sid=sid, journal=journal)
from scopus_xml import *
print get_journal_link('2-s2.0-84901638552')
<a href="http://www.scopus.com/source/sourceInfo.url?sourceId=22746">Catalysis Communications</a>

3 DOI link

def get_doi_link(EID):
    results = get_abstract_info(EID)
    coredata = results.find('./{http://www.elsevier.com/xml/svapi/abstract/dtd}coredata')
    doi = coredata.find('{http://prismstandard.org/namespaces/basic/2.0/}doi')
    if doi is not None: doi = doi.text
    s = '<a href="https://doi.org/{doi}">doi:{doi}</a>'
    return s.format(doi=doi)
from scopus_xml import *
print get_doi_link('2-s2.0-84901638552')
doi:10.1016/j.catcom.2013.10.028

4 Abstract link

def get_abstract_link(EID):
    results = get_abstract_info(EID)
    coredata = results.find('./{http://www.elsevier.com/xml/svapi/abstract/dtd}coredata')

    data = get_abstract_info(EID)

    title = coredata.find('{http://purl.org/dc/elements/1.1/}title').text.encode('utf-8')
    link = coredata.find("./{http://www.elsevier.com/xml/svapi/abstract/dtd}link/[@rel='scopus']").attrib['href'].encode('utf-8')
    s = '<a href="{link}">{title}</a>'
    return s.format(link=link, title=title)
from scopus_xml import *
print get_abstract_link('2-s2.0-84901638552')
Relating the electronic structure and reactivity of the 3d transition metal monoxide surfaces

5 Citation image

def get_cite_img_link(EID):
    results = get_abstract_info(EID)
    coredata = results.find('./{http://www.elsevier.com/xml/svapi/abstract/dtd}coredata')
    doi = coredata.find('{http://prismstandard.org/namespaces/basic/2.0/}doi')
    if doi is not None: doi = doi.text
    s = '<img src="http://api.elsevier.com/content/abstract/citation-count?doi={doi}&httpAccept=image/jpeg&apiKey={apikey}"></img>'

    return s.format(doi=doi, apikey=MY_API_KEY, cite_link=None)
from scopus_xml import *
print get_cite_img_link('2-s2.0-84901638552')

6 Getting it all together

def get_html_citation(EID):
    results = get_abstract_info(EID)
    coredata = results.find('./{http://www.elsevier.com/xml/svapi/abstract/dtd}coredata')
    s = '{authors}, <i>{title}</i>, {journal}, <b>{volume}{issue}</b>, {pages}, ({year}), {doi}, {cites}.'

    issue = ''
    if coredata.find('{http://prismstandard.org/namespaces/basic/2.0/}issueIdentifier') is not None:
        issue = '({})'.format(    coredata.find('{http://prismstandard.org/namespaces/basic/2.0/}issueIdentifier').text)

    volume = coredata.find('{http://prismstandard.org/namespaces/basic/2.0/}volume')
    if volume is not None:
        volume = coredata.find('{http://prismstandard.org/namespaces/basic/2.0/}volume').text
    else:
        volume = 'None'

    pages = ''
    if coredata.find('{http://prismstandard.org/namespaces/basic/2.0/}pageRange') is not None:
        pages = 'p. ' + coredata.find('{http://prismstandard.org/namespaces/basic/2.0/}pageRange').text
    elif coredata.find('{http://www.elsevier.com/xml/svapi/abstract/dtd}article-number') is not None:
        pages = coredata.find('{http://www.elsevier.com/xml/svapi/abstract/dtd}article-number').text
    else:
        pages = 'no pages found'


    year = coredata.find('{http://prismstandard.org/namespaces/basic/2.0/}coverDate').text

    return s.format(authors=get_author_link(EID),
                    title=get_abstract_link(EID),
                    journal=get_journal_link(EID),
                    volume=volume,
                    issue=issue,
                    pages=pages,
                    year=year,
                    doi=get_doi_link(EID),
                    cites=get_cite_img_link(EID))
from scopus_xml import *
print '<ol>'
print '<li>',get_html_citation('2-s2.0-84896759135'),'</li>'
print
print '<li>',get_html_citation('2-s2.0-84924911828'),'</li>'
print
print '<li>',get_html_citation('2-s2.0-84901638552'),'</li>'
print '</ol>'
  1. Thompson R.L., Shi W., Albenze E., Kusuma V.A., Hopkinson D., Damodaran K., Lee A.S., Kitchin J.R., Luebke D.R., Nulwala H., Probing the effect of electron donation on CO2 absorbing 1,2,3-triazolide ionic liquids, RSC Advances, 4(25), p. 12748-12755, (2014-03-17), doi:10.1039/c3ra47097k, .
  2. Xu Z., Kitchin J.R., Relationships between the surface electronic and chemical properties of doped 4d and 5d late transition metal dioxides, Journal of Chemical Physics, 142(10), 104703, (2015-03-14), doi:10.1063/1.4914093, .
  3. Xu Z., Kitchin J.R., Relating the electronic structure and reactivity of the 3d transition metal monoxide surfaces, Catalysis Communications, 52, p. 60-64, (2014-07-05), doi:10.1016/j.catcom.2013.10.028, .

7 Finally getting my documents

Here we get the EIDs from a search query. We use these in the next section to get a new bibliography.

import requests
import json
from my_scopus import MY_API_KEY
resp = requests.get("http://api.elsevier.com/content/search/scopus?query=AU-ID(7004212771)&field=eid,aggregationType&count=100",
                    headers={'Accept':'application/json',
                             'X-ELS-APIKey': MY_API_KEY})

results = resp.json()

return [[str(r['eid']), str(r['prism:aggregationType'])] for r in results['search-results']["entry"] if str(r['prism:aggregationType']) == 'Journal']
2-s2.0-84924911828 Journal
2-s2.0-84923164062 Journal
2-s2.0-84924778427 Journal
2-s2.0-84924130725 Journal
2-s2.0-84901638552 Journal
2-s2.0-84898934670 Journal
2-s2.0-84896759135 Journal
2-s2.0-84896380535 Journal
2-s2.0-84896585411 Journal
2-s2.0-84916613197 Journal
2-s2.0-84908637059 Journal
2-s2.0-84880986072 Journal
2-s2.0-84881394200 Journal
2-s2.0-84873706643 Journal
2-s2.0-84876703352 Journal
2-s2.0-84867809683 Journal
2-s2.0-84864914806 Journal
2-s2.0-84865730756 Journal
2-s2.0-84864592302 Journal
2-s2.0-84863684845 Journal
2-s2.0-84866142469 Journal
2-s2.0-84861127526 Journal
2-s2.0-80052944171 Journal
2-s2.0-80051809046 Journal
2-s2.0-79953651013 Journal
2-s2.0-79952860396 Journal
2-s2.0-77956568341 Journal
2-s2.0-77954747189 Journal
2-s2.0-77956693843 Journal
2-s2.0-77949916234 Journal
2-s2.0-77955464573 Journal
2-s2.0-72049114200 Journal
2-s2.0-73149124752 Journal
2-s2.0-73149109096 Journal
2-s2.0-67449106405 Journal
2-s2.0-63649114440 Journal
2-s2.0-60849113132 Journal
2-s2.0-58649114498 Journal
2-s2.0-40949100780 Journal
2-s2.0-33750804660 Journal
2-s2.0-20544467859 Journal
2-s2.0-15744396507 Journal
2-s2.0-9744261716 Journal
2-s2.0-13444307808 Journal
2-s2.0-3042820285 Journal
2-s2.0-2942640180 Journal
2-s2.0-0142023762 Journal
2-s2.0-0141924604 Journal
2-s2.0-0037368024 Journal
2-s2.0-0037197884 Journal

8 And my html bibliography

This generates my blog bibliography page..

from scopus_xml import *

import requests
import json
from my_scopus import MY_API_KEY
resp = requests.get("http://api.elsevier.com/content/search/scopus?query=AU-ID(7004212771)&field=eid,aggregationType&count=100",
                    headers={'Accept':'application/json',
                             'X-ELS-APIKey': MY_API_KEY})

results = resp.json()

data = [[str(r['eid']), str(r['prism:aggregationType'])] for r in
        results['search-results']["entry"] if str(r['prism:aggregationType']) == 'Journal']


with open('../publications.html.mako', 'w') as f:
    f.write('''<%inherit file="_templates/site.mako" />
<article class="page_box">
<%self:filter chain="markdown">

<h1>Online collections of our work</h1>
Pick your favorite:
<ul>
<li><a href="http://orcid.org/0000-0003-2625-9232">orcid:0000-0003-2625-9232</a></li>

<li><a href="http://www.researcherid.com/rid/A-2363-2010">researcherid:A-2363-2010</a></li>

<li><a href="http://www.scopus.com/authid/detail.url?origin=AuthorProfile&authorId=7004212771">scopusid:7004212771</a></li>

<li><a href="https://scholar.google.com/citations?user=jD_4h7sAAAAJ">Google Scholar</a></li>

<li><a href="https://www.researchgate.net/profile/John_Kitchin">Research Gate</a></li>

<li><a href="https://www.growkudos.com/profiles/40205">Kudos</a></li>
</ul>

<h1>Publications</h1>
The authors are linked to their Scopus page, the title linked to the Scopus abstract, the journal linked to the Scopus journal page, and the DOI is linked to https://doi.org which normally redirects you to the journal page.

<ol reversed="reversed">
''')

    for eid,type in data:
        f.write('<li>{}</li>'.format(get_html_citation(eid)))
    f.write('''</ol>

</%self:filter>
</article>
''')

9 Summary

The XML format is not that intuitive to me. It takes some practice writing robust code, e.g. sometimes the find command does not find anything, and then there is not text attribute to get, so you should check for success on finding things. Also, some text is unicode, and you have to take care to encode it, which my library does not do uniformly. Finally, not all journals have things like volume or issue. My formatting code is not super flexible, so these bibliography entries show None in them occasionally. Still, it is not too bad, and this enables a lot of analysis of your publications, as well as displaying them in different ways. See the result of this page here: http://kitchingroup.cheme.cmu.edu/publications.html

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

Making highly linked bibliographies from the Scopus API

| categories: scopus, python | tags:

A given article entry in a bibliography might have the following kinds of links in it. I think we can generate these from a Scopus query.

We are going to look at the document above, with eid=2-s2.0-84901638552. This is another long post, so here is a teaser of what we are doing. For this eid, we want to generate an html entry where each part of the entry is clickable. Here is what we will be able to do by the end of this post:

from scopus import *

print '<ol>', get_html('2-s2.0-84901638552'), '</ol>'
  1. Xu Z.,Kitchin J.R., Relating the electronic structure and reactivity of the 3d transition metal monoxide surfaces, Catalysis Communications, 52, p. 60-64, (2014-07-05), doi:10.1016/j.catcom.2013.10.028, .

In this post, we work out code that works for this document. This code in the form shown here might not work on all entries, e.g. for ones that are in press and are missing data, or for APS journals that have no page range. Later, I will fix those so this is more robust. To minimize repeating the code below, I create a python module here called scopus.py . Tangle it out with org-babel-tangle. As in the last post , I am not sharing my API key here, since it is not clear if that key is private or not.

I like json, so we use that data format here. XML would be more robust, as the Scopus site admits not all of the data can be turned into the json format, but for now we stick to json for its simplicity.

import requests
import json, os
from my_scopus import MY_API_KEY

def get_abstract_info(EID, refresh=False):
    'Get and save the json data for EID.'
    base = 'scopus-data/get_abstract_info'
    if not os.path.exists(base):
        os.makedirs(base)

    fname = '{0}/{1}'.format(base, EID)
    if os.path.exists(fname) and not refresh:
        with open(fname) as f:
            return json.loads(f.read())

    # Otherwise retrieve and save results
    url = ("http://api.elsevier.com/content/abstract/eid/" + EID)
    resp = requests.get(url,
                    headers={'Accept':'application/json',
                             'X-ELS-APIKey': MY_API_KEY})
    results = json.loads(resp.text.encode('utf-8'))
    with open(fname, 'w') as f:
        f.write(json.dumps(results))

    return results

1 Author pages

Here, we generate the html that will make each author a clickable link that goes to their Scopus ID author page.

def get_author_link(EID):
    data = get_abstract_info(EID)
    result = data['abstracts-retrieval-response']
    html = '<a href="http://www.scopus.com/authid/detail.url?origin=AuthorProfile&authorId={0}">{1}</a>'
    authors = [html.format(auid, name) for auid, name in
               zip([x['@auid'] for x in result['authors']['author']],
                   [x['ce:indexed-name'] for x in result['authors']['author']])]

    return ','.join(authors)
from scopus import *
print get_author_link('2-s2.0-84901638552')
Xu Z.,Kitchin J.R.

2 Journal link

The most important pieces of information we need is the journal name and the source-id from the coredata.

from scopus import *
EID = '2-s2.0-84901638552'
data = get_abstract_info(EID)
result = data['abstracts-retrieval-response']
print result['coredata']['source-id']
print result['coredata']['prism:publicationName']
22746
Catalysis Communications
def get_journal_link(EID):
    data = get_abstract_info(EID)
    result = data['abstracts-retrieval-response']
    sid = result['coredata']['source-id']
    journal = result['coredata']['prism:publicationName']
    s = '<a href="http://www.scopus.com/source/sourceInfo.url?sourceId={sid}">{journal}</a>'

    return s.format(sid=sid, journal=journal)
from scopus import *
print get_journal_link('2-s2.0-84901638552')
Catalysis Communications

3 DOI link

It would be helpful to have a doi link, which is actually independent of Scopus so people without Scopus access can still access information.

from scopus import *
EID = '2-s2.0-84901638552'
data = get_abstract_info(EID)
result = data['abstracts-retrieval-response']
print result['coredata']['prism:doi']
10.1016/j.catcom.2013.10.028
def get_doi_link(EID):
    data = get_abstract_info(EID)
    result = data['abstracts-retrieval-response']
    s = '<a href="https://doi.org/{doi}">doi:{doi}</a>'
    return s.format(doi=result['coredata']['prism:doi'])
from scopus import *
print get_doi_link('2-s2.0-84901638552')
doi:10.1016/j.catcom.2013.10.028

4 Citation count image

It is nice to show impact of a paper by showing the citations. These change with time, so a static view is not ideal. Scopus provides a way to get an image they generate that should update when viewed. We need the doi to get that.

def get_cite_img_link(EID):
    data = get_abstract_info(EID)
    result = data['abstracts-retrieval-response']
    s = '<img src="http://api.elsevier.com/content/abstract/citation-count?doi={doi}&httpAccept=image/jpeg&apiKey={apikey}"></img>'
    return s.format(doi=result['coredata']['prism:doi'].strip(), apikey=MY_API_KEY)
from scopus import *
print get_cite_img_link('2-s2.0-84901638552')

5 The document link

The document link is sort of buried in the coredata. It seems like & has been replaced by &amp; in the json data so we have to do a clunky fix here.

from scopus import *
EID = '2-s2.0-84901638552'
data = get_abstract_info(EID)
result = data['abstracts-retrieval-response']

print result['coredata']['dc:title']
for ref in result['coredata']['link']:
    if ref['@rel'] == 'scopus':
        print ref['@href'].replace('&amp;', '&')
        break
Relating the electronic structure and reactivity of the 3d transition metal monoxide surfaces
http://www.scopus.com/inward/record.url?partnerID=HzOxMe3b&scp=84901638552&origin=inward
def get_abstract_link(EID):
    data = get_abstract_info(EID)
    result = data['abstracts-retrieval-response']
    title = result['coredata']['dc:title']
    for ref in result['coredata']['link']:
        if ref['@rel'] == 'scopus':
            link = ref['@href'].replace('&amp;', '&')

    s = '<a href="{link}">{title}</a>'
    return s.format(link=link, title=title)
from scopus import *
print get_abstract_link('2-s2.0-84901638552')
Relating the electronic structure and reactivity of the 3d transition metal monoxide surfaces

6 Putting it all together

Our goal is ultimately an html formatted citation where nearly every piece is a hyperlink to additional information, e.g. each author is linked to their page, the title is linked to the scopus document page, the journal is linked to the scopus journal page, a DOI link, and an image of the number of citations. Here it is.

def get_html(EID):
    data = get_abstract_info(EID)
    result = data['abstracts-retrieval-response']

    s = '<li>{authors}, <i>{title}</i>, {journal}, <b>{volume}{issue}</b>, p. {pages}, ({year}), {doi}, {cites}.</li>'

    issue = ''
    if result['coredata'].get('prism:issue'):
        issue = '({})'.format(result['coredata'].get('prism:issue'))
    return s.format(authors=get_author_link(EID),
                    title=get_abstract_link(EID),
                    journal=get_journal_link(EID),
                    volume=result['coredata'].get('prism:volume'),
                    issue=issue,
                    pages=result['coredata'].get('prism:pageRange'),
                    year=result['coredata'].get('prism:coverDate'),
                    doi=get_doi_link(EID),
                    cites=get_cite_img_link(EID))
from scopus import *
print get_html('2-s2.0-84901638552')
  • Xu Z.,Kitchin J.R., Relating the electronic structure and reactivity of the 3d transition metal monoxide surfaces, Catalysis Communications, 52, p. 60-64, (2014-07-05), doi:10.1016/j.catcom.2013.10.028, .
  • Well, that is the end for now. We have a reusable function that generates a nice HTML formatted citation that links out to many different resources. Why aren't all citations on the web this helpful?

    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

    Getting data from the Scopus API

    | categories: scopus, python | tags:

    I have been exploring the Scopus API (http://dev.elsevier.com/index.html ) lately. This is a RESTful API that allows you to retrieve data about publications via http requests, i.e. from a script. This service is not free; you need to be at an institution that has a Scopus license.

    Scopus is very good at finding your papers, and associating them with a Scopus ID. You don't have to do anything to get one, they make it. I have a Scopus ID (http://www.scopus.com/authid/detail.url?origin=AuthorProfile&authorId=7004212771 ) that has all this data via the web, but I wanted to get this data in a tabular form I could use and analyze. Sure you can download a CSV file from that page and analyze that, but I want to script it. I am just like that ;) To use the API, you need to get an API key (http://www.developers.elsevier.com/action/devprojects ). I still cannot figure out if this key is "private" so I am not going to share mine here. I have stored it in a python file called my_scopus.py, and I will import it in these examples.

    The code below is "wide", so apologies in advance that some of it will run out of the usual area it belongs.

    1 About me from Scopus

    There is an author API that provides a metrics view of a Scopus ID. Here this shows there are about 77 documents for me, cited about 3028 times. Why do I say "about"? Apparently there are two different databases that Scopus uses, one for the web, and one for this API, and they do not return the same data. It is close, but not the same. The API database includes thing that are published after 1995, and it may not be updated as quickly as the web database. For example the web page reports 79 documents and 3143 citations. In the next sections we will use the search API, which returns the same information as what is on the web. Here we just illustrate how to setup an http request in Python. I like json output, so we ask for it.

    import requests
    import json
    from my_scopus import MY_API_KEY
    
    resp = requests.get("http://api.elsevier.com/content/author?author_id=7004212771&view=metrics",
                        headers={'Accept':'application/json',
                                 'X-ELS-APIKey': MY_API_KEY})
    
    print json.dumps(resp.json(),
                     sort_keys=True,
                     indent=4, separators=(',', ': '))
    
    {
        "author-retrieval-response": [
            {
                "@_fa": "true",
                "@status": "found",
                "coauthor-count": "90",
                "coredata": {
                    "citation-count": "3028",
                    "cited-by-count": "2369",
                    "dc:identifier": "AUTHOR_ID:7004212771",
                    "document-count": "77",
                    "prism:url": "http://api.elsevier.com/content/author/author_id/7004212771"
                },
                "h-index": "18"
            }
        ]
    }
    

    2 Get my documents from Scopus

    To find my documents, we will use the Search API, http://api.elsevier.com/documentation/SCOPUSSearchAPI.wadl . We specify a Scopus ID, and to limit the quantity of data that comes back we specify that we want the dc:identifier field, which corresponds to the scopus id for each document. We will use that in the next section to get info for each document.

    import requests
    import json
    from my_scopus import MY_API_KEY
    resp = requests.get("http://api.elsevier.com/content/search/scopus?query=AU-ID(7004212771)&field=dc:identifier&count=100",
                        headers={'Accept':'application/json',
                                 'X-ELS-APIKey': MY_API_KEY})
    
    results = resp.json()
    
    return [[str(r['dc:identifier'])] for r in results['search-results']["entry"]]
    
    SCOPUS_ID:84924911828
    SCOPUS_ID:84923164062
    SCOPUS_ID:84924778427
    SCOPUS_ID:84924130725
    SCOPUS_ID:84901638552
    SCOPUS_ID:84898934670
    SCOPUS_ID:84896759135
    SCOPUS_ID:84896380535
    SCOPUS_ID:84896585411
    SCOPUS_ID:84916613197
    SCOPUS_ID:84908637059
    SCOPUS_ID:84880986072
    SCOPUS_ID:84881394200
    SCOPUS_ID:84873706643
    SCOPUS_ID:84876703352
    SCOPUS_ID:84872843990
    SCOPUS_ID:84872872509
    SCOPUS_ID:84872845400
    SCOPUS_ID:84872841108
    SCOPUS_ID:84872855250
    SCOPUS_ID:84872864754
    SCOPUS_ID:84886483703
    SCOPUS_ID:84872854676
    SCOPUS_ID:84867809683
    SCOPUS_ID:84864914806
    SCOPUS_ID:84865730756
    SCOPUS_ID:84864592302
    SCOPUS_ID:84863684845
    SCOPUS_ID:84866142469
    SCOPUS_ID:84861127526
    SCOPUS_ID:84857224144
    SCOPUS_ID:84857197729
    SCOPUS_ID:84856818654
    SCOPUS_ID:80052944171
    SCOPUS_ID:80051860134
    SCOPUS_ID:80051809046
    SCOPUS_ID:79953651013
    SCOPUS_ID:79952860396
    SCOPUS_ID:79951537083
    SCOPUS_ID:79251517782
    SCOPUS_ID:77956568341
    SCOPUS_ID:77954747189
    SCOPUS_ID:77956693843
    SCOPUS_ID:77949916234
    SCOPUS_ID:77955464573
    SCOPUS_ID:72049114200
    SCOPUS_ID:78649528829
    SCOPUS_ID:78649504144
    SCOPUS_ID:77952266872
    SCOPUS_ID:73149124752
    SCOPUS_ID:73149109096
    SCOPUS_ID:67449106405
    SCOPUS_ID:63649114440
    SCOPUS_ID:60849113132
    SCOPUS_ID:58649114498
    SCOPUS_ID:79952218110
    SCOPUS_ID:79952292116
    SCOPUS_ID:78049295221
    SCOPUS_ID:79952296916
    SCOPUS_ID:79952225819
    SCOPUS_ID:78049231913
    SCOPUS_ID:79952234104
    SCOPUS_ID:79952301915
    SCOPUS_ID:45149129361
    SCOPUS_ID:40949100780
    SCOPUS_ID:37349101648
    SCOPUS_ID:58049109348
    SCOPUS_ID:33750804660
    SCOPUS_ID:33645645065
    SCOPUS_ID:20544467859
    SCOPUS_ID:15744396507
    SCOPUS_ID:9744261716
    SCOPUS_ID:13444307808
    SCOPUS_ID:3042820285
    SCOPUS_ID:2942640180
    SCOPUS_ID:0142023762
    SCOPUS_ID:0141924604
    SCOPUS_ID:0037368024
    SCOPUS_ID:0037197884

    3 Retrieve info for a document

    Here, we work out how to retrieve data for a document. We use the Abstract API (http://api.elsevier.com/documentation/AbstractRetrievalAPI.wadl ). We again use a field to limit the amount of data. Here is an example that works for an article. Scopus also lists books and conferences so, we will see how that works later. Note the unicode stuff. I was getting some errors about non-ascii characters causing the json file not to read, and then issues in constructing the string. This was only a problem for some entries.

    import requests
    import json
    from my_scopus import MY_API_KEY
    
    def get_scopus_info(SCOPUS_ID):
        url = ("http://api.elsevier.com/content/abstract/scopus_id/"
              + SCOPUS_ID
              + "?field=authors,title,publicationName,volume,issueIdentifier,"
              + "prism:pageRange,coverDate,article-number,doi,citedby-count,prism:aggregationType")
        resp = requests.get(url,
                        headers={'Accept':'application/json',
                                 'X-ELS-APIKey': MY_API_KEY})
        results = json.loads(resp.text.encode('utf-8'))
    
        fstring = '{authors}, {title}, {journal}, {volume}, {articlenum}, ({date}). {doi} (cited {cites} times).\n'
        return fstring.format(authors=', '.join([au['ce:indexed-name'] for au in results['abstracts-retrieval-response']['authors']['author']]),
                              title=results['abstracts-retrieval-response']['coredata']['dc:title'].encode('utf-8'),
                              journal=results['abstracts-retrieval-response']['coredata']['prism:publicationName'].encode('utf-8'),
                              volume=results['abstracts-retrieval-response']['coredata']['prism:volume'].encode('utf-8'),
                              articlenum=(results['abstracts-retrieval-response']['coredata'].get('prism:pageRange') or
                                  results['abstracts-retrieval-response']['coredata'].get('article-number')).encode('utf-8'),
                              date=results['abstracts-retrieval-response']['coredata']['prism:coverDate'].encode('utf-8'),
                              doi='doi:' + results['abstracts-retrieval-response']['coredata']['prism:doi'].encode('utf-8'),
                              cites=int(results['abstracts-retrieval-response']['coredata']['citedby-count'].encode('utf-8')))
    
    
    
    print get_scopus_info('SCOPUS_ID:0037368024')
    
    Kitchin J.R., Barteau M.A., Chen J.G., A comparison of gold and molybdenum nanoparticles on TiO2(1 1 0) 1 × 2 reconstructed single crystal surfaces, Surface Science, 526, 323-331, (2003-03-01). doi:10.1016/S0039-6028(02)02679-1 (cited 27 times).
    

    4 Get information for all documents

    We will use the data we previously got in the long list of Scopus IDs. A few subtle points here are that I made that a nested list so it would print as a column, and so we will have to index each entry to get the scopus id. Also, it seems that some entries generate json that cannot be parsed by python, so we wrap this in a try block and skip those entries. We need to check for the entry being a Journal article, to avoid errors with our format string. We also need to accomodate journals that do not have page ranges, but have artice numbers instead. Finally, we will format each entry so there is some html code for it.

    import requests
    import json
    import textwrap
    from my_scopus import MY_API_KEY
    
    def get_scopus_info(SCOPUS_ID):
        url = ("http://api.elsevier.com/content/abstract/scopus_id/"
              + SCOPUS_ID
              + "?field=authors,title,publicationName,volume,issueIdentifier,"
              + "prism:pageRange,coverDate,article-number,doi,citedby-count,prism:aggregationType")
        resp = requests.get(url,
                        headers={'Accept':'application/json',
                                 'X-ELS-APIKey': MY_API_KEY})
    
        return json.loads(resp.text.encode('utf-8'))
    
    
    i = 0
    for sid in scopus_ids:
        # some entries seem to have json parse errors, so we catch those
        try:
            results = get_scopus_info(sid[0])  # index 0 because the input data is a 2d array
            if results['abstracts-retrieval-response']['coredata']['prism:aggregationType'] == 'Journal':
                i += 1
                fstring = '{authors}, {title}, {journal}, {volume}, {articlenum}, ({date}). <a href="https://doi.org/{doi}">{doi}</a> (cited {cites} times)\n\n'
    
                s = fstring.format(authors=', '.join([au['ce:indexed-name'].encode('utf-8') for au in results['abstracts-retrieval-response']['authors']['author']]),
                                   title=results['abstracts-retrieval-response']['coredata']['dc:title'].encode('utf-8'),
                                   journal=results['abstracts-retrieval-response']['coredata']['prism:publicationName'].encode('utf-8'),
                                   volume=results['abstracts-retrieval-response']['coredata'].get('prism:volume', 'None').encode('utf-8'),
                                   articlenum=str((results['abstracts-retrieval-response']['coredata'].get('prism:pageRange') or
                                               results['abstracts-retrieval-response']['coredata'].get('article-number'))).encode('utf-8'),
                                   date=results['abstracts-retrieval-response']['coredata']['prism:coverDate'].encode('utf-8'),
                                   doi='doi:' + results['abstracts-retrieval-response']['coredata']['prism:doi'].encode('utf-8'),
                                   cites=int(results['abstracts-retrieval-response']['coredata']['citedby-count'].encode('utf-8')))
                print '{0:3d}. {1}<br>'.format(i, s)
        except:
            print '{0:3d}. {1}'.format(i, sid)
    
    1. Xu Z., Kitchin J.R., Relationships between the surface electronic and chemical properties of doped 4d and 5d late transition metal dioxides, Journal of Chemical Physics, 142, 104703, (2015-03-14). doi:10.1063/1.4914093 (cited 0 times)
    2. Boes J.R., Gumuslu G., Miller J.B., Gellman A.J., Kitchin J.R., Estimating bulk-composition-dependent H2 adsorption energies on CuxPd1- x alloy (111) surfaces, ACS Catalysis, 5, 1020-1026, (2015-02-06). doi:10.1021/cs501585k (cited 0 times)
    3. Boes J.R., Kondratyuk P., Yin C., Miller J.B., Gellman A.J., Kitchin J.R., Core level shifts in Cu-Pd alloys as a function of bulk composition and structure, Surface Science, None, None, (2015-01-01). doi:10.1016/j.susc.2015.02.011 (cited 0 times)
    4. Xu Z., Rossmeisl J., Kitchin J.R., A linear response DFT+U study of trends in the oxygen evolution activity of transition metal rutile dioxides, Journal of Physical Chemistry C, 119, 4827-4833, (2015-01-01). doi:10.1021/jp511426q (cited 0 times)
    5. Xu Z., Kitchin J.R., Relating the electronic structure and reactivity of the 3d transition metal monoxide surfaces, Catalysis Communications, 52, 60-64, (2014-07-05). doi:10.1016/j.catcom.2013.10.028 (cited 2 times)
    6. Demeter E.L., Hilburg S.L., Washburn N.R., Collins T.J., Kitchin J.R., Electrocatalytic oxygen evolution with an immobilized TAML activator, Journal of the American Chemical Society, 136, 5603-5606, (2014-04-16). doi:10.1021/ja5015986 (cited 4 times)
    7. Thompson R.L., Shi W., Albenze E., Kusuma V.A., Hopkinson D., Damodaran K., Lee A.S., Kitchin J.R., Luebke D.R., Nulwala H., Probing the effect of electron donation on CO2 absorbing 1,2,3-triazolide ionic liquids, RSC Advances, 4, 12748-12755, (2014-03-17). doi:10.1039/c3ra47097k (cited 1 times)
    8. Mehta P., Salvador P.A., Kitchin J.R., Identifying potential BO2 oxide polymorphs for epitaxial growth candidates, ACS Applied Materials and Interfaces, 6, 3630-3639, (2014-03-12). doi:10.1021/am4059149 (cited 0 times)
    9. Miller S.D., Pushkarev V.V., Gellman A.J., Kitchin J.R., Simulating temperature programmed desorption of oxygen on Pt(111) using DFT derived coverage dependent desorption barriers, Topics in Catalysis, 57, 106-117, (2014-02-01). doi:10.1007/s11244-013-0166-3 (cited 2 times)
    10. Curnan M.T., Kitchin J.R., Effects of concentration, crystal structure, magnetism, and electronic structure method on first-principles oxygen vacancy formation energy trends in perovskites, Journal of Physical Chemistry C, 118, 28776-28790, (2014-01-01). doi:10.1021/jp507957n (cited 2 times)
    11. Xu Z., Kitchin J.R., Probing the coverage dependence of site and adsorbate configurational correlations on (111) surfaces of late transition metals, Journal of Physical Chemistry C, 118, 25597-25602, (2014-01-01). doi:10.1021/jp508805h (cited 0 times)
    12. Lee A.S., Eslick J.C., Miller D.C., Kitchin J.R., Comparisons of amine solvents for post-combustion CO2 capture: A multi-objective analysis approach, International Journal of Greenhouse Gas Control, 18, 68-74, (2013-10-01). doi:10.1016/j.ijggc.2013.06.020 (cited 3 times)
    13. Hallenbeck A.P., Kitchin J.R., Effects of O2 and SO2 on the capture capacity of a primary-amine based polymeric CO2 sorbent, Industrial and Engineering Chemistry Research, 52, 10788-10794, (2013-08-07). doi:10.1021/ie400582a (cited 7 times)
    13. ['SCOPUS_ID:84873706643'] 14. Calle-Vallejo F., Inoglu N.G., Su H.-Y., Martinez J.I., Man I.C., Koper M.T.M., Kitchin J.R., Rossmeisl J., Number of outer electrons as descriptor for adsorption processes on transition metals and their oxides, Chemical Science, 4, 1245-1249, (2013-03-01). doi:10.1039/c2sc21601a (cited 16 times)
    15. Lee A.S., Kitchin J.R., Chemical and molecular descriptors for the reactivity of amines with CO 2 , Industrial and Engineering Chemistry Research, 51, 13609-13618, (2012-10-24). doi:10.1021/ie301419q (cited 3 times)
    16. Rubin E.S., Mantripragada H., Marks A., Versteeg P., Kitchin J., The outlook for improved carbon capture technology, Progress in Energy and Combustion Science, 38, 630-671, (2012-10-01). doi:10.1016/j.pecs.2012.03.003 (cited 91 times)
    17. Akhade S.A., Kitchin J.R., Effects of strain, d-band filling, and oxidation state on the surface electronic structure and reactivity of 3d perovskite surfaces, Journal of Chemical Physics, 137, 084703, (2012-08-28). doi:10.1063/1.4746117 (cited 8 times)
    18. Landon J., Demeter E., Inoglu N., Keturakis C., Wachs I.E., Vasic R., Frenkel A.I., Kitchin J.R., Spectroscopic characterization of mixed Fe-Ni oxide electrocatalysts for the oxygen evolution reaction in alkaline electrolytes, ACS Catalysis, 2, 1793-1801, (2012-08-03). doi:10.1021/cs3002644 (cited 39 times)
    19. Chao R., Munprom R., Petrova R., Gerdes K., Kitchin J.R., Salvador P.A., Structure and relative thermal stability of mesoporous (La, Sr) MnO 3powders prepared using evaporation-induced self-assembly methods, Journal of the American Ceramic Society, 95, 2339-2346, (2012-07-01). doi:10.1111/j.1551-2916.2012.05236.x (cited 4 times)
    20. Kitchin J., Preface: Trends in computational catalysis, Topics in Catalysis, 55, 227-228, (2012-06-01). doi:10.1007/s11244-012-9808-0 (cited 0 times)
    21. Alesi W.R., Kitchin J.R., Evaluation of a primary amine-functionalized ion-exchange resin for CO 2 capture, Industrial and Engineering Chemistry Research, 51, 6907-6915, (2012-05-16). doi:10.1021/ie300452c (cited 15 times)
    22. Akhade S.A., Kitchin J.R., Effects of strain, d-band filling, and oxidation state on the bulk electronic structure of cubic 3d perovskites, Journal of Chemical Physics, 135, 104702, (2011-09-14). doi:10.1063/1.3631948 (cited 3 times)
    23. Man I.C., Su H.-Y., Calle-Vallejo F., Hansen H.A., Martinez J.I., Inoglu N.G., Kitchin J., Jaramillo T.F., Norskov J.K., Rossmeisl J., Universality in Oxygen Evolution Electrocatalysis on Oxide Surfaces, ChemCatChem, 3, 1159-1165, (2011-07-11). doi:10.1002/cctc.201000397 (cited 199 times)
    24. Inoglu N., Kitchin J.R., Identification of sulfur-tolerant bimetallic surfaces using dft parametrized models and atomistic thermodynamics, ACS Catalysis, 1, 399-407, (2011-04-01). doi:10.1021/cs200039t (cited 9 times)
    25. Miller S.D., Inoglu N., Kitchin J.R., Configurational correlations in the coverage dependent adsorption energies of oxygen atoms on late transition metal fcc(111) surfaces, Journal of Chemical Physics, 134, 104709, (2011-03-14). doi:10.1063/1.3561287 (cited 16 times)
    26. Alesi Jr. W.R., Gray M., Kitchin J.R., CO2 adsorption on supported molecular amidine systems on activated carbon, ChemSusChem, 3, 948-956, (2010-08-01). doi:10.1002/cssc.201000056 (cited 18 times)
    27. Landon J., Kitchin J.R., Electrochemical concentration of carbon dioxide from an oxygen/carbon dioxide containing gas stream, Journal of the Electrochemical Society, 157, None, (2010-07-23). doi:10.1149/1.3432440 (cited 3 times)
    28. Inoglu N., Kitchin J.R., Simple model explaining and predicting coverage-dependent atomic adsorption energies on transition metal surfaces, Physical Review B - Condensed Matter and Materials Physics, 82, 045414, (2010-07-16). doi:10.1103/PhysRevB.82.045414 (cited 14 times)
    29. Pennline H.W., Granite E.J., Luebke D.R., Kitchin J.R., Landon J., Weiland L.M., Separation of CO2 from flue gas using electrochemical cells, Fuel, 89, 1307-1314, (2010-06-01). doi:10.1016/j.fuel.2009.11.036 (cited 20 times)
    30. Inoglu N., Kitchin J.R., New solid-state table: Estimating d-band characteristics for transition metal atoms, Molecular Simulation, 36, 633-638, (2010-06-01). doi:10.1080/08927022.2010.481794 (cited 16 times)
    31. Tierney H.L., Baber A.E., Kitchin J.R., Sykes E.C.H., Hydrogen dissociation and spillover on individual isolated palladium atoms, Physical Review Letters, 103, 246102, (2009-12-10). doi:10.1103/PhysRevLett.103.246102 (cited 45 times)
    32. Miller S.D., Kitchin J.R., Uncertainty and figure selection for DFT based cluster expansions for oxygen adsorption on Au and Pt (111) surfaces, Molecular Simulation, 35, 920-927, (2009-09-01). doi:10.1080/08927020902833137 (cited 14 times)
    33. Inolu N., Kitchin J.R., Sulphur poisoning of water-gas shift catalysts: Site blocking and electronic structure modification, Molecular Simulation, 35, 936-941, (2009-09-01). doi:10.1080/08927020902833129 (cited 6 times)
    34. Kitchin J.R., Correlations in coverage-dependent atomic adsorption energies on Pd(111), Physical Review B - Condensed Matter and Materials Physics, 79, 205412, (2009-05-01). doi:10.1103/PhysRevB.79.205412 (cited 26 times)
    35. Han J.W., Kitchin J.R., Sholl D.S., Step decoration of chiral metal surfaces, Journal of Chemical Physics, 130, 124710, (2009-04-08). doi:10.1063/1.3096964 (cited 11 times)
    36. Miller S.D., Kitchin J.R., Relating the coverage dependence of oxygen adsorption on Au and Pt fcc(1 1 1) surfaces through adsorbate-induced surface electronic structure effects, Surface Science, 603, 794-801, (2009-03-01). doi:10.1016/j.susc.2009.01.021 (cited 39 times)
    37. Inoglu N., Kitchin J.R., Atomistic thermodynamics study of the adsorption and the effects of water-gas shift reactants on Cu catalysts under reaction conditions, Journal of Catalysis, 261, 188-194, (2009-01-25). doi:10.1016/j.jcat.2008.11.020 (cited 20 times)
    38. Kitchin J.R., Reuter K., Scheffler M., Alloy surface segregation in reactive environments: First-principles atomistic thermodynamics study of Ag3 Pd(111) in oxygen atmospheres, Physical Review B - Condensed Matter and Materials Physics, 77, 075437, (2008-02-29). doi:10.1103/PhysRevB.77.075437 (cited 49 times)
    39. Norskov J.K., Bligaard T., Logadottir A., Kitchin J.R., Chen J.G., Pandelov S., Stimming U., Response to "comment on 'trends in the exchange current for hydrogen evolution' [J. Electrochem. Soc., 152, J23 (2005)]", Journal of the Electrochemical Society, 153, 054612JES, (2006-11-14). doi:10.1149/1.2358292 (cited 9 times)
    40. Kitchin J.R., Norskov J.K., Barteau M.A., Chen J.G., Trends in the chemical properties of early transition metal carbide surfaces: A density functional study, Catalysis Today, 105, 66-73, (2005-07-15). doi:10.1016/j.cattod.2005.04.008 (cited 70 times)
    41. Norskov J.K., Bligaard T., Logadottir A., Kitchin J.R., Chen J.G., Pandelov S., Stimming U., Trends in the exchange current for hydrogen evolution, Journal of the Electrochemical Society, 152, None, (2005-04-07). doi:10.1149/1.1856988 (cited 282 times)
    42. Norskov J.K., Rossmeisl J., Logadottir A., Lindqvist L., Kitchin J.R., Bligaard T., Jonsson H., Origin of the overpotential for oxygen reduction at a fuel-cell cathode, Journal of Physical Chemistry B, 108, 17886-17892, (2004-11-18). doi:10.1021/jp047349j (cited 1055 times)
    43. Kitchin J.R., Norskov J.K., Barteau M.A., Chen J.G., Role of strain and ligand effects in the modification of the electronic and chemical Properties of bimetallic surfaces, Physical Review Letters, 93, None, (2004-10-08). doi:10.1103/PhysRevLett.93.156801 (cited 361 times)
    44. Mhadeshwar A.B., Kitchin J.R., Barteau M.A., Vlachos D.G., The role of adsorbate-adsorbate interactions in the rate controlling step and the most abundant reaction intermediate of NH 3 decomposition on RU, Catalysis Letters, 96, 13-22, (2004-07-01). doi:10.1023/B:CATL.0000029523.22277.e1 (cited 45 times)
    45. Kitchin J.R., Norskov J.K., Barteau M.A., Chen J.G., Modification of the surface electronic and chemical properties of Pt(111) by subsurface 3d transition metals, Journal of Chemical Physics, 120, 10240-10246, (2004-06-01). doi:10.1063/1.1737365 (cited 443 times)
    46. McCormick J.R., Kitchin J.R., Barteau M.A., Chen J.G., A four-point probe correlation of oxygen sensitivity to changes in surface resistivity of TiO2(0 0 1) and Pd-modified TiO2(0 0 1), Surface Science, 545, None, (2003-11-01). doi:10.1016/j.susc.2003.08.041 (cited 11 times)
    47. Kitchin J.R., Khan N.A., Barteau M.A., Chen J.G., Yakshinskiy B., Madey T.E., Elucidation of the active surface and origin of the weak metal-hydrogen bond on Ni/Pt(1 1 1) bimetallic surfaces: A surface science and density functional theory study, Surface Science, 544, 295-308, (2003-10-20). doi:10.1016/j.susc.2003.09.007 (cited 108 times)
    48. Kitchin J.R., Barteau M.A., Chen J.G., A comparison of gold and molybdenum nanoparticles on TiO2(1 1 0) 1 × 2 reconstructed single crystal surfaces, Surface Science, 526, 323-331, (2003-03-01). doi:10.1016/S0039-6028(02)02679-1 (cited 27 times)
    49. Song I.K., Kitchin J.R., Barteau M.A., H3PW12O40-functionalized tip for scanning tunneling microscopy, Proceedings of the National Academy of Sciences of the United States of America, 99, 6471-6475, (2002-04-30). doi:10.1073/pnas.072514399 (cited 12 times)

    5 Summary thoughts

    I see a lot of potential here for analytics on publications, generation of bibliography files, etc… Instead of retrieving this data every time, it would make much more sense to cache it, e.g. writing each result to a file that could then be used locally, and much faster. The downside of that is, the citations would not be updated in those files. The upside is, you could fix the titles so they are properly marked up. I do not know what the issues with some of the json files was. Some of them were unicode issues. Some other day I will try to track down the other ones.

    The entries could be made a lot more functional than this. Each author could be turned into a link back to the scopus author page, for example, the title could be linked to the scopus abstract page, etc… The citations could be a button that automatically updates (like the one in this post ). That is another exercise, for another day!

    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

    The orcid api and generating a bibtex file from it

    | categories: orcid, python | tags:

    I found this interesting package orcid-python 0.1 : Python Package Index . Unfortunately, it seems to have some issues and it did not work for me. But, the idea is pretty simple, there is a restful API (see http://members.orcid.org/api/tutorial-retrieve-data-public-api-curl-12-and-earlier ) that we can use to retrieve data. We explore that a bit here.

    I have an orcid:0000-0003-2625-9232 which contains my data. First, we just retrieve some basic information using Python.

    import requests
    import json
    
    resp = requests.get("http://pub.orcid.org/0000-0003-2625-9232",
                        headers={'Accept':'application/orcid+json'})
    
    print json.dumps(resp.json(),
                     sort_keys=True,
                     indent=4, separators=(',', ': '))
    
    {
        "message-version": "1.1",
        "orcid-profile": {
            "client-type": null,
            "group-type": null,
            "orcid": null,
            "orcid-activities": {
                "affiliations": null
            },
            "orcid-bio": {
                "applications": null,
                "contact-details": {
                    "address": {
                        "country": {
                            "value": "US",
                            "visibility": null
                        }
                    },
                    "email": []
                },
                "delegation": null,
                "external-identifiers": {
                    "external-identifier": [
                        {
                            "external-id-common-name": {
                                "value": "ResearcherID"
                            },
                            "external-id-orcid": {
                                "host": "orcid.org",
                                "path": "0000-0001-7707-4137",
                                "uri": "http://orcid.org/0000-0001-7707-4137",
                                "value": null
                            },
                            "external-id-reference": {
                                "value": "A-2363-2010"
                            },
                            "external-id-url": {
                                "value": "http://www.researcherid.com/rid/A-2363-2010"
                            }
                        },
                        {
                            "external-id-common-name": {
                                "value": "Scopus Author ID"
                            },
                            "external-id-orcid": {
                                "host": "orcid.org",
                                "path": "0000-0002-5982-8983",
                                "uri": "http://orcid.org/0000-0002-5982-8983",
                                "value": null
                            },
                            "external-id-reference": {
                                "value": "7004212771"
                            },
                            "external-id-url": {
                                "value": "http://www.scopus.com/inward/authorDetails.url?authorID=7004212771&partnerID=MN8TOARS"
                            }
                        }
                    ],
                    "visibility": null
                },
                "keywords": {
                    "keyword": [
                        {
                            "value": "Computational catalysis, electrochemistry, CO2 capture"
                        }
                    ],
                    "visibility": null
                },
                "personal-details": {
                    "family-name": {
                        "value": "Kitchin"
                    },
                    "given-names": {
                        "value": "John"
                    }
                },
                "researcher-urls": {
                    "researcher-url": [
                        {
                            "url": {
                                "value": "http://kitchingroup.cheme.cmu.edu"
                            },
                            "url-name": {
                                "value": "Research website"
                            }
                        }
                    ],
                    "visibility": null
                },
                "scope": null
            },
            "orcid-history": {
                "claimed": {
                    "value": true
                },
                "completion-date": {
                    "value": 1376581428004
                },
                "creation-method": "WEBSITE",
                "last-modified-date": {
                    "value": 1427557747595
                },
                "source": null,
                "submission-date": {
                    "value": 1376581211104
                },
                "visibility": null
            },
            "orcid-identifier": {
                "host": "orcid.org",
                "path": "0000-0003-2625-9232",
                "uri": "http://orcid.org/0000-0003-2625-9232",
                "value": null
            },
            "orcid-preferences": {
                "locale": "EN"
            },
            "type": "USER"
        }
    }
    

    That information is not too interesting, but it would allow you to scrape out my website, scopus id, and researcher id. Next, we look at the publications orcid knows about for me. These are integrated from a few sources, notably my ResearcherID:A-2363-2010, scopusid:7004212771, and http://crossref.org . The next code block prints the bibtex entry for the first few entries. The bibtex entries are not too well formed, and would need some cleaning, but it is a pretty good start.

    import requests
    import json
    
    resp = requests.get("http://pub.orcid.org/0000-0003-2625-9232/orcid-works",
                        headers={'Accept':'application/orcid+json'})
    
    results = resp.json()
    for i, result in enumerate( results['orcid-profile']['orcid-activities']
                                ['orcid-works']['orcid-work']):
        print result['work-citation']['citation'].encode('utf-8') + '\n'
        if i == 2:
            break
    
    @article{Xu_2015,doi = {10.1021/jp511426q},url = {https://doi.org/10.1021/jp511426q},year = 2015,month = {mar},publisher = {American Chemical Society ({ACS})},volume = {119},number = {9},pages = {4827--4833},author = {Zhongnan Xu and Jan Rossmeisl and John R. Kitchin},title = { A Linear Response {DFT}$\mathplus$ U Study of Trends in the Oxygen Evolution Activity of Transition Metal Rutile Dioxides },journal = {J. Phys. Chem. C}}
    
    @article{Xu_2015,doi = {10.1063/1.4914093},url = {https://doi.org/10.1063/1.4914093},year = 2015,month = {mar},publisher = {{AIP} Publishing},volume = {142},number = {10},pages = {104703},author = {Zhongnan Xu and John R. Kitchin},title = {Relationships between the surface electronic and chemical properties of doped 4d and 5d late transition metal dioxides},journal = {J. Chem. Phys.}}
    
    @article{Boes_2015,doi = {10.1016/j.susc.2015.02.011},url = {https://doi.org/10.1016/j.susc.2015.02.011},year = 2015,month = {mar},publisher = {Elsevier {BV}},author = {Jacob Boes and Peter Kondratyuk and Chunrong Yin and James B. Miller and Andrew J. Gellman and John R. Kitchin},title = {Core level shifts in Cu{\textendash}Pd alloys as a function of bulk composition and structure},journal = {Surface Science}}
    

    Let us look at a tabular form of that data so it is sortable. We attempt to remove some duplicates based on the title and doi. The duplicates come about because there is more than one source where this data is pulled from. This is a little tricky, we do a case insensitive title comparison, but that still fails if the titles have different white space in them, e.g. "111" vs "1 1 1", and different sources do that. Also, the DOIs are sometimes missing, and sometimes have different cases, and sometimes are not correct. This code tries to fix most of those issues.

    import requests
    import json
    
    resp = requests.get("http://pub.orcid.org/0000-0003-2625-9232/orcid-works",
                        headers={'Accept':'application/orcid+json'})
    results = resp.json()
    
    data = []
    TITLES, DOIs = [], []
    
    for i, result in enumerate( results['orcid-profile']['orcid-activities']
                                ['orcid-works']['orcid-work']):
        title = str(result['work-title']['title']['value'].encode('utf-8'))
        doi = 'None'
    
        for x in result.get('work-external-identifiers', []):
            for eid in result['work-external-identifiers']['work-external-identifier']:
                if eid['work-external-identifier-type'] == 'DOI':
                    doi = str(eid['work-external-identifier-id']['value'].encode('utf-8'))
    
        # AIP journals tend to have a \n in the DOI, and the doi is the second line. we get
        # that here.
        if len(doi.split('\n')) == 2:
            doi = doi.split('\n')[1]
    
        pub_date = result.get('publication-date', None)
        if pub_date:
            year = pub_date.get('year', None).get('value').encode('utf-8')
        else:
            year = 'Unknown'
    
        # Try to minimize duplicate entries that are found
        dup = False
        if title.lower() in TITLES:
            dup = True
        if (doi != 'None'
            and doi.lower() in DOIs):
            dup = True
    
        if not dup:
            # truncate title to first 50 characters
            print('| {3} | {0}  | {1} | [[doi:{2}]]|'.format(title[0:50], year, doi, result['work-type']))
    
        TITLES.append(title.lower())
        DOIs.append(doi.lower())
    
    | JOURNAL_ARTICLE  | A Linear Response DFT+ U Study of Trends in the Ox | 2015 | doi:10.1021/jp511426q                                |
    | JOURNAL_ARTICLE  | Relationships between the surface electronic and c | 2015 | doi:10.1063/1.4914093                                |
    | JOURNAL_ARTICLE  | Core level shifts in Cu–Pd alloys as a function    | 2015 | doi:10.1016/j.susc.2015.02.011                       |
    | JOURNAL_ARTICLE  | Estimating bulk-composition-dependent H2 adsorptio | 2015 | doi:10.1021/cs501585k                                |
    | JOURNAL_ARTICLE  | Probing the Coverage Dependence of Site and Adsorb | 2014 | doi:10.1021/jp508805h                                |
    | JOURNAL_ARTICLE  | Relating the electronic structure and reactivity o | 2014 | doi:10.1016/j.catcom.2013.10.028                     |
    | JOURNAL_ARTICLE  | Electrocatalytic Oxygen Evolution with an Immobili | 2014 | doi:10.1021/ja5015986                                |
    | JOURNAL_ARTICLE  | Identifying Potential BO 2 Oxide Polymorphs for Ep | 2014 | doi:10.1021/am4059149                                |
    | JOURNAL_ARTICLE  | Simulating temperature programmed desorption of ox | 2014 | doi:10.1007/s11244-013-0166-3                        |
    | JOURNAL_ARTICLE  | Probing the effect of electron donation on CO2 abs | 2014 | doi:10.1039/c3ra47097k                               |
    | JOURNAL_ARTICLE  | Effects of concentration, crystal structure, magne | 2014 | doi:10.1021/jp507957n                                |
    | JOURNAL_ARTICLE  | Effects of O 2 and SO 2 on the Capture Capacity of | 2013 | doi:10.1021/ie400582a                                |
    | JOURNAL_ARTICLE  | Number of outer electrons as descriptor for adsorp | 2013 | doi:None                                             |
    | JOURNAL_ARTICLE  | Interactions in 1-ethyl-3-methyl imidazolium tetra | 2013 | doi:https://doi.org/10.1016/j.molstruc.2013.01.046 |
    | JOURNAL_ARTICLE  | Comparisons of amine solvents for post-combustion  | 2013 | doi:https://doi.org/10.1016/j.ijggc.2013.06.020    |
    | JOURNAL_ARTICLE  | Chemical and Molecular Descriptors for the Reactiv | 2012 | doi:10.1021/ie301419q                                |
    | JOURNAL_ARTICLE  | Spectroscopic Characterization of Mixed Fe–Ni Ox   | 2012 | doi:10.1021/cs3002644                                |
    | REPORT           | Modeling Coverage Dependence in Surface Reaction N | 2012 | doi:10.2172/1149701                                  |
    | CONFERENCE_PAPER | Vibrational spectroscopy characterization of CO2-i | 2012 | doi:None                                             |
    | CONFERENCE_PAPER | The role of electrolytes in the oxygen evolution r | 2012 | doi:None                                             |
    | JOURNAL_ARTICLE  | The outlook for improved carbon capture technology | 2012 | doi:10.1016/j.pecs.2012.03.003                       |
    | JOURNAL_ARTICLE  | Structure and Relative Thermal Stability of Mesopo | 2012 | doi:10.1111/j.1551-2916.2012.05236.x                 |
    | JOURNAL_ARTICLE  | Preface: Trends in computational catalysis         | 2012 | doi:10.1007/s11244-012-9808-0                        |
    | CONFERENCE_PAPER | Exergetic analysis of chemical looping reforming   | 2012 | doi:None                                             |
    | JOURNAL_ARTICLE  | Evaluation of a Primary Amine-Functionalized Ion-E | 2012 | doi:10.1021/ie300452c                                |
    | CONFERENCE_PAPER | Electrocatalytic water oxidation using iron-center | 2012 | doi:None                                             |
    | JOURNAL_ARTICLE  | Effects of strain, d-band filling, and oxidation s | 2012 | doi:10.1063/1.4746117                                |
    | BOOK             | Coverage dependent adsorption properties of atomic | 2012 | doi:10.1039/9781849734776-00083                      |
    | CONFERENCE_PAPER | Comparisons of solvents for post-combustion CO2 ca | 2012 | doi:None                                             |
    | CONFERENCE_PAPER | Characterization of an ion exchange resin for CO2  | 2012 | doi:None                                             |
    | CONFERENCE_PAPER | Assessing the ability of using first principles to | 2012 | doi:None                                             |
    | JOURNAL_ARTICLE  | Universality in Oxygen Evolution Electrocatalysis  | 2011 | doi:10.1002/cctc.201000397                           |
    | CONFERENCE_PAPER | The effect of CO 2 partial pressure on capture wit | 2011 | doi:None                                             |
    | CONFERENCE_PAPER | Preparation of Mesoporous La 0.8Sr 0.2MnO 3 infilt | 2011 | doi:10.1149/1.3570235                                |
    | JOURNAL_ARTICLE  | Identification of sulfur-tolerant bimetallic surfa | 2011 | doi:10.1021/cs200039t                                |
    | JOURNAL_ARTICLE  | Effects of strain, d-band filling, and oxidation s | 2011 | doi:10.1063/1.3631948                                |
    | CONFERENCE_PAPER | Determining the conditions necessary for optimal C | 2011 | doi:None                                             |
    | JOURNAL_ARTICLE  | Configurational correlations in the coverage depen | 2011 | doi:10.1063/1.3561287                                |
    | CONFERENCE_PAPER | An electronic structure based understanding of ami | 2011 | doi:None                                             |
    | JOURNAL_ARTICLE  | CO2 Adsorption on Supported Molecular Amidine Syst | 2010 | doi:10.1002/cssc.201000056                           |
    | JOURNAL_ARTICLE  | Separation of CO2 from flue gas using electrochemi | 2010 | doi:10.1016/j.fuel.2009.11.036                       |
    | JOURNAL_ARTICLE  | New solid-state table: estimating d-band character | 2010 | doi:10.1080/08927022.2010.481794                     |
    | JOURNAL_ARTICLE  | Simple model explaining and predicting coverage-de | 2010 | doi:10.1103/PhysRevB.82.045414                       |
    | CONFERENCE_PAPER | Intrinsic and extrinsic factors associated with CO | 2010 | doi:None                                             |
    | JOURNAL_ARTICLE  | Electrochemical concentration of carbon dioxide fr | 2010 | doi:10.1149/1.3432440                                |
    | CONFERENCE_PAPER | Catalyzing the catalyst: Hydrogen dissociation and | 2010 | doi:None                                             |
    | JOURNAL_ARTICLE  | Uncertainty and figure selection for DFT based clu | 2009 | doi:10.1080/08927020902833137                        |
    | JOURNAL_ARTICLE  | Sulphur poisoning of water-gas shift catalysts: Si | 2009 | doi:10.1080/08927020902833129                        |
    | JOURNAL_ARTICLE  | Step decoration of chiral metal surfaces           | 2009 | doi:10.1063/1.3096964                                |
    | JOURNAL_ARTICLE  | Relating the coverage dependence of oxygen adsorpt | 2009 | doi:10.1016/j.susc.2009.01.021                       |
    | JOURNAL_ARTICLE  | Hydrogen Dissociation and Spillover on Individual  | 2009 | doi:10.1103/PhysRevLett.103.246102                   |
    | JOURNAL_ARTICLE  | Correlations in coverage-dependent atomic adsorpti | 2009 | doi:10.1103/PhysRevB.79.205412                       |
    | CONFERENCE_PAPER | Catalyzing the catalyst: Novel pathways to hydroge | 2009 | doi:None                                             |
    | JOURNAL_ARTICLE  | Atomistic thermodynamics study of the adsorption a | 2009 | doi:10.1016/j.jcat.2008.11.020                       |
    | CONFERENCE_PAPER | Ancillary oxygen-fired combustion using electroche | 2009 | doi:None                                             |
    | CONFERENCE_PAPER | Adsorbate Cu interactions and catalyst morphologie | 2009 | doi:None                                             |
    | CONFERENCE_PAPER | <title>Rotational isomeric state theory applied to | 2008 | doi:10.1117/12.776303                                |
    | CONFERENCE_PAPER | The effect of hydration on the adsorption of carbo | 2008 | doi:None                                             |
    | CONFERENCE_PAPER | Pt-decorated electrocatalysts for direct alcohol f | 2008 | doi:None                                             |
    | CONFERENCE_PAPER | PEM-based electrochemical separation of gases      | 2008 | doi:None                                             |
    | CONFERENCE_PAPER | First principles, atomistic thermodynamics for sul | 2008 | doi:None                                             |
    | CONFERENCE_PAPER | Evaluating uncertainty in Ab initio phase diagrams | 2008 | doi:None                                             |
    | JOURNAL_ARTICLE  | ENVR 1-Basic research needs to assure a secure ene | 2008 | doi:None                                             |
    | OTHER            | Density functional theory studies of alloys in het | 2008 | doi:10.1039/b608782p                                 |
    | JOURNAL_ARTICLE  | Alloy surface segregation in reactive environments | 2008 | doi:10.1103/PhysRevB.77.075437                       |
    | CONFERENCE_PAPER | A first principles evaluation of the role of subst | 2008 | doi:None                                             |
    | CONFERENCE_PAPER | Pt nanoparticle electrocatalyst synthesis for dire | 2007 | doi:None                                             |
    | CONFERENCE_PAPER | Pt nanoparticle anode electrocatalysts for direct  | 2007 | doi:None                                             |
    | JOURNAL_ARTICLE  | Response to &quot;comment on 'Trends in the exchan | 2006 | doi:10.1149/1.2358292                                |
    | JOURNAL_ARTICLE  | Trends in the exchange current for hydrogen evolut | 2005 | doi:10.1149/1.1856988                                |
    | JOURNAL_ARTICLE  | Trends in the chemical properties of early transit | 2005 | doi:10.1016/j.cattod.2005.04.008                     |
    | CONFERENCE_PAPER | Alloy surface segregation in reactive environments | 2005 | doi:None                                             |
    | JOURNAL_ARTICLE  | The role of adsorbate-adsorbate interactions in th | 2004 | doi:None                                             |
    | JOURNAL_ARTICLE  | Role of strain and ligand effects in the modificat | 2004 | doi:10.1103/PhysRevLett.93.156801                    |
    | JOURNAL_ARTICLE  | Origin of the overpotential for oxygen reduction a | 2004 | doi:10.1021/jp047349j                                |
    | JOURNAL_ARTICLE  | Modification of the surface electronic and chemica | 2004 | doi:10.1063/1.1737365                                |
    | JOURNAL_ARTICLE  | Elucidation of the active surface and origin of th | 2003 | doi:10.1016/j.susc.2003.09.007                       |
    | JOURNAL_ARTICLE  | A four-point probe correlation of oxygen sensitivi | 2003 | doi:10.1016/j.susc.2003.08.041                       |
    | JOURNAL_ARTICLE  | A comparison of gold and molybdenum nanoparticles  | 2003 | doi:10.1016/s0039-6028(02)02679-1                    |
    | JOURNAL_ARTICLE  | H3PW12O40-functionalized tip for scanning tunnelin | 2002 | doi:10.1073/pnas.072514399                           |
    | JOURNAL_ARTICLE  | Preparation of paramagnetic ligands for coordinati | 1997 | doi:None                                             |
    | JOURNAL_ARTICLE  | Preparation and Characterization of a Bis-Semiquin | 1995 | doi:10.1021/jo00117a004                              |
    | JOURNAL_ARTICLE  | SYNTHESIS AND CHARACTERIZATION OF TRISEMIQUINONE L | 1995 | doi:None                                             |
    

    Not too bad. Clearly we could do a lot more work to fine tune exactly what data we retrieve, and then what to do with it. The tools are all here to do that.

    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

    Making org-mode Python sessions look better

    | categories: orgmode, python | tags:

    Using sessions for python in org-mode has always bugged me a little bit. Mostly the appearance of >>> and … in the output. For example:

    print 8
    
    >>> >>> >>> 8
    

    Today on the org-mode mailing list someone suggested a patch that might fix that up. Hopefully that patch makes it into org-mode, but if you run off of ELPA like I do it will be some time before it appears in your working version.

    In the meantime, inspired by my recent post on updating multiple results, here we add a new hook function that removes these annoying characters from a Python session results section. Here is my version of this code. "^: >>>$"

    (defun org-babel-python-strip-session-chars ()
      "Remove >>> and ... from a Python session output."
      (when (and (string=
                  "python"
                  (org-element-property :language (org-element-at-point)))
                 (string-match
                  ":session"
                  (org-element-property :parameters (org-element-at-point))))
    
        (save-excursion
          (when (org-babel-where-is-src-block-result)
            (goto-char (org-babel-where-is-src-block-result))
            (end-of-line 1)
            ;(while (looking-at "[\n\r\t\f ]") (forward-char 1))
            (while (re-search-forward
                    "\\(>>> \\|\\.\\.\\. \\|: $\\|: >>>$\\)"
                    (org-element-property :end (org-element-at-point))
                    t)
              (replace-match "")
              ;; this enables us to get rid of blank lines and blank : >>>
              (beginning-of-line)
              (when (looking-at "^$")
                (kill-line)))))))
    
    (add-hook 'org-babel-after-execute-hook 'org-babel-python-strip-session-chars)
    
    org-babel-python-strip-session-chars (lambda nil (org-refresh-images))
    import matplotlib.pyplot as plt
    plt.plot([3, 4, 5])
    plt.show()
    
    def f(s):
        x = 2 * s
        # blank lines look like indentation errors
        return x
    
    print f(4)
    
    [<matplotlib.lines.Line2D object at 0x10955c290>]
    8
    
    print f(9)
    
    18
    

    Here we can make an inline figure.

    plt.figure()
    plt.plot([3, 4.5, 5])
    plt.savefig('images/session-fig.png')
    'images/session-fig.png'
    

    Not bad. It seems to work! Maybe this will make sessions more usable for me.

    [2015-03-12 Thu] New corner case, do not cause an error when results are silenced.

    print 6
    

    Testing getting rid of blank lines and empty : >>> lines.

    a = 2
    b = 3
    c = 4
    print
    print 'a=      ', a
    print 'b =     ', b
    print 'a + b = ', a+b
    
    a=       2
    b =      3
    a + b =  5
    

    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
    « Previous Page -- Next Page »