Some time ago, I stumbled across WolframConnect, a set of libraries for Mathematica that supported posting and querying from a bunch of social media sites. So I tried it on Twitter, and it worked pretty well. However, apprently apathetic to this discovery, someone mentioned that “I’ll be impressed when I can tweet in LaTeX.” I believe I can impress him.

\write18 and \immediate

LaTeX provides a set of output streams that can be written to using the \write command. Of particular interest here is stream 18, which can directly write a command to the system shell. Due to the vulnerabilities that could be exploited due to this, most TeX distributions require you to add the --shell-escape argument before accepting \write18 commands.

We will also need to force the \write to run once the parser reaches it rather than when the page is finished being created. This is where the \immediate command comes in. So we could run something like cowsay in LaTeX by simply adding a line \immediate\write18{cowsay yes}. When compiling the TeX file, this will then happen:

❯ pdflatex --shell-escape meme.tex
This is pdfTeX, Version 3.141592653-2.6-1.40.22 (TeX Live 2021/Arch Linux) (preloaded format=pdflatex)
 \write18 enabled.
entering extended mode
(./meme.tex
LaTeX2e <2020-10-01> patch level 4
L3 programming layer <2021-02-18>
(/usr/share/texmf-dist/tex/latex/base/article.cls
Document Class: article 2020/04/10 v1.4m Standard LaTeX document class
(/usr/share/texmf-dist/tex/latex/base/size11.clo)) _____ 
< yes >
 ----- 
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

(/usr/share/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def) (./meme.aux)
[1{/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map}] (./meme.aux) )</usr/shar
e/texmf-dist/fonts/type1/public/amsfonts/cm/cmbx12.pfb></usr/share/texmf-dist/f
onts/type1/public/amsfonts/cm/cmr10.pfb></usr/share/texmf-dist/fonts/type1/publ
ic/amsfonts/cm/cmr12.pfb></usr/share/texmf-dist/fonts/type1/public/amsfonts/cm/
cmr17.pfb>
Output written on meme.pdf (1 page, 40293 bytes).
Transcript written on meme.log.

Twitter’s API

Requesting an API key was easy enough, though if a Twitter employee goes through the list of reasons why somebody would request an API key they would also happen to find “I’m trying to prove someone wrong by tweeting in LaTeX” now. However, Twitter’s API uses OAuth which is famously known to be a pain to deal with by hand. So we’ll use the Twurl package, which provides a curl-like interface to Twitter’s API.

To log in, we will run twurl authorize --consumer-key <key> --consumer-secret <secret> and follow the instructions to generate the require Oauth keys. That’s now enough for us to call a twurl instruction to post a tweet.

The TeX File

The final thing we’ll have to do is call twurl on /1.1/statuses/update.json as a \write18 command in LaTeX. So we can create a nice.tex file like the following:

\documentclass[11pt]{article}

\title{Just a Tweet}
\author{some guy}
\date{}

\newcommand{\tweetText}{Are you impressed now?}
\newcommand{\inReplyToStatusId}{<tweet_id>}
\newcommand{\username}{<reply_to_username>}

\immediate\write18{twurl -r 'status=are you impressed now \username&username=\username&in_reply_to_status_id=\inReplyToStatusId' /1.1/statuses/update.json}

%\immediate\write18{curl -XPOST --url 'https://api.twitter.com/1.1/statuses/update.json?status=\tweetText' --header 'authorization: OAuth oauth_consumer_key="\oauthCustomerKey", oauth_nonce="\generatedOauthNonce", oauth_signature="\generatedOauthSignature", oauth_signature_method="HMAC-SHA1", oauth_timestamp="\generatedTimestamp", oauth_token="\oauthToken", oauth_version="1.0"'}

\begin{document}

\maketitle

\section{Introduction}

Here's what we tweeted: \tweetText

\end{document}

And then we’ll run it through TeX to get a PDF with pdflatex --shell-escape nice.tex, which results in our tweet and an informative PDF:

Tweet and PDF output