14

Is there a smart way to cite tweets? I'm using the Chicago Manual of Style, and all they say is this, which is not really a guide, yet.

Ideally, you'd be able to have a macro where you just put the URL to the tweet in, a la:

\tweet{https://twitter.com/Horse_ebooks/status/382466889332445184}

... and then got the tweet in a nice box on your page, plus in the bibliography. Not sure if this is possible, even theoretically?

Relevant part of my preamble:

   \usepackage[backend=biber,isbn=false,notes]{biblatex-chicago}

In the main file, I have:

 \bibliography{biblio/biblio.bib}

What's the next step? Sorry to be grasping for straws like this, hope someone can help out!

  • Tweets are are relatively new version of communication and tend to be volatile (they can be deleted, unless retweeted). I am unsure whether the TeX world have already reacted to this kind of communication in the sense, that there are some .bib file fields for tweets. – user31729 Sep 20 '14 at 20:09
  • 1
    You can get pretty close using the @misc entry type, with the fields: author, title, date, note, and url. With some minor tweaking via \DeclareFieldFormat, you can match the specification you link to. I'd still want to use one of biblatex's \cite commands, however. – jon Sep 20 '14 at 20:29
  • 4
    Well in fact this is not a question about TeX, it's related with the kind of references you can use. And well the Chicago Manual Style doesn't take in account the tweets, I don't know if it does with conversations or another related reference. But when you want to cite ephemeral events such a tweet you must cite Creator, [title], [tweet], date. Notes. So you can redefine the style you're using or instead of, create a @misc entry in your database with biblatex. Perhaps the ISO 690:2010 could be helpful for you. – Aradnix Sep 20 '14 at 20:29
  • I agree with @jon: I'dadd them to a bibtex file under @misc{...} and give them an author, title, year and url. – user30471 Sep 21 '14 at 10:16
16

I like your question. Yes, it is possible get the tweet and add to bibliography.

I made a 'code' that allow to cite a tweet. Firstly, I am going to explain the idea, then I will explain the code. (It uses latex and python)

The idea

  1. It is possible get a tweet using curl (the string obtained is json format) and the latex package download allow to use curl.

  2. For convert format json to bibtex can be used a little script in python, that will obtain a .bib file with the tweet data. (I don't know if latex has some package to do this).

  3. finally, It is possible to define a little driver for tweet entry and some macros to manage the tweets.

The code

1. Get the tweet in format json

The download package allows you to get a tweet using curl. It is used in the following form:

\download[filelocalname]{url}

filelocalname is the name of the file in your computer. And the url is the url (json) of the tweet. This is important! In your question you show the example url:

https://twitter.com/Horse_ebooks/status/382466889332445184 but in this url it is only important the ìdnumber of the tweet, which is 382466889332445184. The url for used with download package is:

https://api.twitter.com/1/statuses/oembed.json?id=idnumber

i.e. in your example the url is:

https://api.twitter.com/1/statuses/oembed.json?id=382466889332445184

Then \tweetadd is a macro in latex that receives the idnumber and downloads the tweet in json format, and also saves it to disk with the name idnumber.tweet.

\def\tweetadd#1{\download[#1.tweet]{https://api.twitter.com/1/statuses/oembed.json?id=#1}}

2. Convert the tweet from json format to bibtex format. (twitt.py)

Beautiful Soup 4 is necessary. The installation instructions are here. Beautiful Soup 4 is used to get the tweet text, because in the file obtained with download package the tweet is in html format and Beautiful Soup 4 allows you to extract the text of the tweet and date.

The other python packages are standard (json, re and os). json decodes the file obtained with the download package (latex) and extracts the author name, author url, and url of the tweet. The other fields (username, date) are obtained with re.

How the python script (twitt.py) works is simple. The script input is the directory where are the files downloaded with the \download package and finds all the files with the .tweet extension. The script handles each file and create a file (.bib) with the bibtex data (a .bib file for each .tweet file).

The fileds of bibtex used are:

  • a. author Name of author of tweet.

  • b. title The tweet text.

  • c. url The tweet url.

  • d. nameaddon The username of the author (@...).

  • e. addendum The url of the profile of the author.

  • f. date The date of the tweet.

The entrykey is tweet:idnumber.

Finally, the script creates a .tex file that contains the \addbibresource for each .bib file. The name is tweetsinputbib.tex.

3. How run twitt.py from latex?

The script follows the method explained here using the \write18 package. As was said in point 2, the script needs the directory of the .tweet files (the same directory of .tex file); for this we use the \currfile package (latex). Important! The \currfile needs the -recorder option when latex is executed. For more information, read Full path of current file .

Then the definetweets macro runs the twitt.py script. (The script needs to be in the same directory of .tex)

\def\definetweets{%
\immediate\write18{python \currfileabsdir/twitt.py \currfileabsdir}
}

4. Other macros

The \tweet macro uses the bib fields and prints the tweet text, the date and the username.

\def\tweet#1{%
\par
\begin{minipage}[t]{0.95\columnwidth}%
\hfill\citetitle{#1}\par
\hfill--\citefield{#1}{nameaddon}, \space\citedate{#1}
\end{minipage}\par}

The \citetweet prints the tweet citation similarly to the form showed in the link that you reference.

\def\citetweet#1{%
In a Twitter post on \citedate{#1}, \citeauthor{#1} \mkbibparens{\citefield{#1}{nameaddon}} 
wrote, \mkbibquote{\citetitle{#1}}}

Here two format to the fields are defined: title (tweet) and nameaddon (username). The first prepends the word 'Tweet' to the title. The second puts the username between parens, and if hyperref package is used, attaches a link to the user's Twitter profile.

\DeclareFieldFormat{tweet}{Tweet:\space\emph{#1}}

\DeclareFieldFormat{username}{%
    \mkbibparens{%
      \ifhyperref
        {\href{\thefield{addendum}}{#1}}
        {#1}}}`

The tweet driver is the default misc driver of authoryear style of biblatex. (without the fields not used).

\DeclareBibliographyDriver{tweet}{%
  \usebibmacro{begentry}%
  \setunit{\addcomma\space}
  \usebibmacro{author}
  \printfield[username]{nameaddon}
  \newunit
  \setunit{\labelnamepunct}\newblock
  \printfield[tweet]{title}%
  \newunit\newblock
  \printdate
  \newunit\newblock
  \usebibmacro{url}%
  \newunit\newblock
  \setunit{\bibpagerefpunct}\newblock
  \usebibmacro{pageref}%
  \newunit\newblock
  \iftoggle{bbx:related}
    {\usebibmacro{related:init}%
     \usebibmacro{related}}
    {}%
  \usebibmacro{finentry}}

The Full files.

  1. the latex file. Name: tweetaddon.tex

\usepackage{download}
\usepackage[abspath]{currfile}[2012/05/06]
\RequirePackage{biblatex}

\def\tweetadd#1{\download[#1.tweet]{https://api.twitter.com/1/statuses/oembed.json?id=#1}}

\def\definetweets{%
\immediate\write18{python \currfileabsdir/twitt.py \currfileabsdir}
}

\def\tweet#1{%
\par
\begin{minipage}[t]{0.95\columnwidth}%
\hfill\citetitle{#1}\par
\hfill--\citefield{#1}{nameaddon}, \space\citedate{#1}
\end{minipage}\par}

\def\citetweet#1{%
In a Twitter post on \citedate{#1}, \citeauthor{#1} \mkbibparens{\citefield{#1}{nameaddon}} wrote, \mkbibquote{\citetitle{#1}}}

\DeclareFieldFormat{tweet}{Twitter post:\space\emph{#1}}

\DeclareFieldFormat{username}{%
    \mkbibparens{%
      \ifhyperref
        {\href{\thefield{addendum}}{#1}}
        {#1}}}

%Driver biblatex for tweet
\DeclareBibliographyDriver{tweet}{%
  \usebibmacro{begentry}%
  \setunit{\addcomma\space}
  \usebibmacro{author}
  \printfield[username]{nameaddon}
  \newunit
  \setunit{\labelnamepunct}\newblock
  \printfield[tweet]{title}%
  \newunit\newblock
  \printdate
  \newunit\newblock
  \usebibmacro{url+urldate}%
  \newunit\newblock
  \setunit{\bibpagerefpunct}\newblock
  \usebibmacro{pageref}%
  \newunit\newblock
  \iftoggle{bbx:related}
    {\usebibmacro{related:init}%
     \usebibmacro{related}}
    {}%
  \usebibmacro{finentry}}

  1. The python file. Name: twitt.py

import json
import re
from bs4 import  BeautifulSoup
import os

months={'January':'01','February':'02','March':'03','April':'04','May':'05','June':'06','July':'07','August':'08','September':'09','October':'10','November':'11','December':'12'}

def formatday(day):
    if int(day)<10:
        day='0'+day
    return day

def smplncndtex(string):
    chars={'&':'\&','%':'\%','$':'\$','#':'\#','_':'\_','{':'\{','}':'\}'}
    for item in chars:
        string=string.replace(item,chars[item])
    return string

class tweet:
    def __init__(self, directory=None,file=None):
        self.id=file.replace('.tweet','')
        self.file=file
        self.get_tweet_filecontent(directory)
        self.define_tweet()
        self.entrybib=simpleentrybibtex(self).entry

    def get_tweet_filecontent(self,directory):
        with open(os.path.join(directory,self.file)) as file:
            self.filecontent=file.read()

    def define_tweet(self):
        dcfcnt= json.loads(self.filecontent)
        soup=BeautifulSoup(dcfcnt['html'])
        self.tweet=unicode(smplncndtex(soup.find('p').text))  #in note
        self.author=unicode(smplncndtex(dcfcnt['author_name']))   #in author
        self.author_url=dcfcnt['author_url']   #in addendum
        self.url=dcfcnt['url']   #in url
        username =unicode(smplncndtex('@'+re.match('.+twitter.com/(.+)',self.author_url).group(1)))   #in nameaddon
        self.username=username
        all_a=soup.find_all('a')
        for atag in all_a:
            if atag.get('href')==self.url.replace('/statuses/','/status/'):
                match=re.match('(\w+)\s(\d+),\s(\d+)',atag.text)
                #print date_parts
                self.date= '%s-%s-%s' % (match.group(3),months[match.group(1)],formatday(match.group(2)))
                #print self.date

    def save_tweet(self,directory):
        with open(os.path.join(directory,self.id)+'.bib','w') as file:
            file.write(self.entrybib.encode('utf-8'))

class tweets:
    def __init__(self,directory):
        self.directory=directory
        self.tweets=[]
        self.get_tweets()

    def get_tweets(self):
        for file in os.listdir(self.directory):
            if file.endswith(".tweet"):
                a=tweet(self.directory,file)
                self.tweets.append(a)

class simpleentrybibtex:
    def __init__(self,ctt,entryname='tweet'):
        self.entry='@%s{tweet:%s,author={%s},title={{%s}},url={%s},nameaddon={{%s}},addendum={%s},date={%s}}' % (entryname,ctt.id,ctt.author,ctt.tweet, ctt.url, ctt.username, ctt.author_url, ctt.date)

if __name__ == "__main__":
    import sys
    if len(sys.argv) ==1:
        print 'It is necessary a directory'
    else:
        if os.path.exists(sys.argv[1]):
            directory=sys.argv[1]
        #directory='/home/carlos/latex/teste/testedownload'
            tw=tweets(directory)
            tex_input=file(os.path.join(directory,'tweetsinputbib.tex'),'w')
            for tweet in tw.tweets:
                tweet.save_tweet(directory)
                tex_input.write('\\addbibresource{%s}\n' % (tweet.id+'.bib'))
        else:
            print '%s is not a directory' % (sys.argv[1])

The MWE:

I used the biblatex package with the authoryear style. I think you can also use biblatex-chicago.


\documentclass{article}
\usepackage{hyperref}
\usepackage[utf8]{inputenc}  
\usepackage[style=authoryear,backend=biber]{biblatex}
\input{tweetaddon} %below of \usepackage{biblatex}
%add the tweet to use between \input{tweetaddon} and \definetweets 382466889332445184 is the id tweet in twitter, get it from url of the tweet.
\tweetadd{382466889332445184} 
\tweetadd{382467902751784961} 
\definetweets
\input{tweetsinputbib}        %input this file that contain the addresource
\begin{document}
A tweet:
\tweet{tweet:382466889332445184}  
Other tweet:
\tweet{tweet:382467902751784961}

Or cite a tweet in the form of your link.

\citetweet{tweet:382467902751784961}.

\printbibliography
\end{document}

The result


enter image description here

  • 4
    Instead of Python you could use Lua for the conversion, with the advantage that any (fairly recent) TeX distribution can use it via texlua. – egreg Sep 22 '14 at 16:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.