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 meta 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")

clean_names()

lapply(f, function(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*{\marginfont}{\sffamily\footnotesize}

\usepackage{imakeidx}
\usepackage{hyperref}
\makeindex[intoc]

\newenvironment{conf-abstract}[4][]{
\needspace{10\baselineskip}
\begin{center}
{ \renewcommand\textsuperscript[1]{}
{\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/[email protected]} % 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 fonts, colours and automate some of the string replacement.