Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
Last week I co-ran the FOSS4GUK conference in Edinburgh. It was great fun and thoroughly exhausting. Part of the preparation work I did was to produce an abstract booklet for the conference. This post is a guide to how I automated that with R and LaTeX.
R is a programming language focused on data analysis and LaTeX is a document preparation system. Both are open source. I used R to process and clean abstracts and LaTeX to type set the booklet, based on a template I found on Overleaf.
With hindsight I wish we had required speakers to submit abstract text in a form, but we allowed them to upload files. This lead to a tedious amount of copy and pasting from pdf, word and plain text. Once this was over I set up a delegates file with the following columns:
- name
- join
- day
- time
- room
- title
- affiliation
I populated it from the conference programme.
Next I used R to read each abstract file and join it to the delegate data. Each abstract was then written out to a new file in the format for the LaTeX document. Finally a list of these LaTeX ready abstracts was made:
library(tidyverse) library(janitor) f = list.files("~/Cloud/Michael/FOSS4G/talks/abstracts_clean") = read_csv("~/Cloud/Michael/FOSS4G/talks/abstract_book/talk_names.csv") %>% clean_names() lapply(f, function(i){ x = read_file(paste0("~/Cloud/Michael/FOSS4G/talks/abstracts_clean/", i)) y = str_remove(i, ".txt") z = filter(meta, join == y) fileConn = file(paste0("~/Cloud/Michael/FOSS4G/talks/abstract_book/abstracts/", i)) writeLines(c(paste0("\\begin{conf-abstract}[", z$day, "\\", str_sub(z$time, 1, 5), "\\", z$room, "]"), paste0("{", z$title, "}"), paste0("{", z$name, "}"), paste0("{", z$affiliation, "}"), "", x, "\\end{conf-abstract}"), fileConn) close(fileConn) }) f = list.files("~/Cloud/Michael/FOSS4G/talks/abstract_book/abstracts/") fileConn = file("~/Cloud/Michael/FOSS4G/talks/abstract_book/abstracts_list.txt") writeLines(paste0("\\input{abstracts/", f, "}"), fileConn) close(fileConn)
There’s a but here. LaTeX requires \\
for a new line, but R uses regex which makes the first \
an escape sequence to print the second \
. No doubt there’s some bash wizardry I could use to replace these (comments welcome), but I resorted to a find and replace in a text editor as I was on a rush to get the booklet finished! Here’s a list of characters/strings I had to replace and what I replaced them with:
- $ | \$
- % | \%
- _ | \_
- & | \&
- [Thu\ | [Thu\\
- [Fri\ | [Fri\\
- \Green] | \\Green]
- \Blue] | \\Blue]
There were also some oddly encoded '
from word (no surprise), which needed to be swapped. LaTeX likes “quotes” to be formatted like “quotes”, which are then rendered beautiful – I had to manually fix these.
Finally I ran the LaTeX compiler, after I’d added the abstract list to the following.
\documentclass[12pt]{book} \usepackage[a4paper,margin=3cm,innermargin=3cm]{geometry} \usepackage{needspace} \usepackage{marginnote} \renewcommand*{\margin}{\sffamily\footnotesize} \usepackage{imakeidx} \usepackage{hyperref} \makeindex[intoc] \newenvironment{conf-abstract}[4][]{ \needspace{10\baselineskip} \begin{center} { \renewcommand\textsuperscript[1]{} \phantomsection\addcontentsline{toc}{section} {\texorpdfstring{#2 (\emph{#3})}{#2 (#3)}} } {{\large\bfseries #2}\marginnote{#1}\par} \medskip {#3\par} \smallskip {\small #4\par} \end{center} }{% \bigskip \hrule \bigskip } \usepackage{etoolbox} \newcommand{\indexauthors}[1]{% \forcsvlist{\index}{#1} } \setcounter{tocdepth}{3} \setcounter{secnumdepth}{-1} \pagestyle{plain} \usepackage{graphicx} \begin{document} \begin{titlepage} \centering \vspace*{150px} {\bfseries\Huge Conference Abstracts\\ } \vfill \includegraphics[width=8cm]{../../logos/FOSS4G-LOGO@2x.png} % also works with logo.pdf \vfill \vfill \end{titlepage} \frontmatter %\maketitle \tableofcontents \mainmatter \chapter{Abstracts} % Specify conf-abstract like this: % \begin{conf-abstract}[optional text going into the margin note] % {Title of Paper} % {Authors (use \textsuperscript as institution markers)} % {Institutions (use \textsuperscript as institution markers)} % \indexauthors{Lastname1!Firstname 1, Lastname2!Firstname2} % Abstract text % \end{conf-abstract} % % It's probably best to generate the abstracts from a % database or something via a script. Don't forget to % check through for any special characters that need to % be escaped. \input{abstracts/Barter.txt} \input{abstracts/Bauszus.txt} \input{abstracts/Boerlage.txt} \input{abstracts/Constantinescu.txt} \input{abstracts/Cook.txt} \input{abstracts/Coulon.txt} \input{abstracts/Duncan.txt} \input{abstracts/Fleet.txt} \input{abstracts/Fleming.txt} \input{abstracts/Frerichs.txt} \input{abstracts/Gordon.txt} \input{abstracts/Graham.txt} \input{abstracts/Holderness.txt} \input{abstracts/Hopkin.txt} \input{abstracts/Ijaz.txt} \input{abstracts/Landy.txt} \input{abstracts/le_Riche.txt} \input{abstracts/Maire.txt} \input{abstracts/Milner.txt} \input{abstracts/Moon.txt} \input{abstracts/Moules.txt} \input{abstracts/Ormsby.txt} \input{abstracts/Rattey.txt} \input{abstracts/Razmjooei.txt} \input{abstracts/Reid.txt} \input{abstracts/Rowlingson.txt} \input{abstracts/Santos.txt} \input{abstracts/Scott.txt} \input{abstracts/Selwood.txt} \input{abstracts/Smith.txt} \input{abstracts/Spencer.txt} \input{abstracts/Stevenson.txt} \input{abstracts/Stubbins.txt} \input{abstracts/Taylor.txt} \input{abstracts/Turton.txt} \input{abstracts/Varley.txt} \input{abstracts/Vesanto.txt} \backmatter \end{document}
If I had more time I would play about with s, colours and automate some of the string replacement.
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.