Skip to content

Instantly share code, notes, and snippets.

@baptiste
Last active May 7, 2017 04:34
Show Gist options
  • Save baptiste/d130a40782ca6cd503294aa2d3712b7a to your computer and use it in GitHub Desktop.
Save baptiste/d130a40782ca6cd503294aa2d3712b7a to your computer and use it in GitHub Desktop.
attempting to solve intersect([pacs,keywords,affiliation,fax,...], <this journal's tex idiosyncracy>) with yaml, R, knitr/brew, mustache, and pandoc
title: On physics and chemistry
authors:
- name: Lise Meitner
affiliation: [Kaiser Wilhelm Institute,
University of Berlin,
Manne Siegbahn Institute]
email: [email protected]
- name: Pierre Curie
affiliation: École Normale Supérieure
email: [email protected]
- name: Marie Curie
affiliation: [University of Paris,
Institut du Radium,
École Normale Supérieure]
email: [email protected]
fax: 123
pacs: [123, 456, 789]
keywords: [physics, science, everything]
abbreviations: [UV,IR]
brew_template <- function(in, out){
## pre-process input file to insert bits of glue extracted from the metadata and formatted according to journal syntax
## output a minimal pandoc tex template file with mostly hard-coded preamble
}
\author{Andrew N. Other}
\altaffiliation{A shared footnote}
\author{Fred T. Secondauthor}
\altaffiliation{Current address: Some other place, Othert\"own,
Germany}
\author{I. Ken Groupleader}
\altaffiliation{A shared footnote}
\email{[email protected]}
\phone{+123 (0)123 4445556}
\fax{+123 (0)123 4445557}
\affiliation[Unknown University]
{Department of Chemistry, Unknown University, Unknown Town}
\alsoaffiliation[Second University]
{Department of Chemistry, Second University, Nearby Town}
\author{Susanne K. Laborator}
\email{[email protected]}
\affiliation[BigPharma]
{Lead Discovery, BigPharma, Big Town, USA}
\author{Kay T. Finally}
\affiliation[Unknown University]
{Department of Chemistry, Unknown University, Unknown Town}
\alsoaffiliation[Second University]
{Department of Chemistry, Second University, Nearby Town}
\author[1,2,3]{Author One}
\author[2,*]{Author Two}
\author[1]{Author Three}
\affil[1]{Publications Department, The Optical Society (OSA), 2010 Massachusetts Avenue NW, Washington D.C., 20036}
\affil[2]{School of Science, University of Technology, 2000 J St. NW, Washington DC, 20036}
\affil[3]{School of Optics, University of Technology, 2000 J St. NW, Washington DC, 20036}
\affil[*]{Corresponding author: [email protected]}
---
date: "5/7/2017"
output: custom_process_journal:
journal: _journal1.tex
metadata: _metadata.yaml
pre_knit: brew_template
---
## First section
Lorem Ipsum
library(yaml)
meta <- yaml.load_file("_metadata.yaml")
unique(unlist(lapply(meta$authors, "[[", "affiliation")))
# [1] "Kaiser Wilhelm Institute" "University of Berlin" "Manne Siegbahn Institute"
# [4] "École Normale Supérieure" "University of Paris" "Institut du Radium"
library(glue)
tpl_author <- '{name}\\n{paste(affiliation, collapse=", ")}'
lapply(meta[["authors"]], glue_data, tpl_author)
# [[1]]
# Lise Meitner\nKaiser Wilhelm Institute, University of Berlin, Manne Siegbahn Institute
#
# [[2]]
# Pierre Curie\nÉcole Normale Supérieure
#
# [[3]]
# Marie Curie\nUniversity of Paris, Institut du Radium, École Normale Supérieure
## journal-dependent partial functions
fun_title <- function(meta) glue_data(meta, "\\title{{ {title} }}") # pretty standard
# this varies wildly: some require $^\dagger$ and to manually group unique addresses, etc.
# achemso example is pretty simple as it requires the full list and takes care of the groups at latex level
fun_authors <- function(meta) lapply(meta[["authors"]],
glue_data,
'\\author{{ {name} }}
\\address{{ {paste(affiliation, collapse=", ")} }}')
# combine pieces to be passed to the template skeleton to create the template for pandoc
preamble <- list(title = fun_title, authors = fun_authors)
lapply(preamble, do.call, list(meta=meta))
# $title
# \title{ On physics and chemistry }
#
# $authors
# $authors[[1]]
# \author{ Lise Meitner }
# \address{ Kaiser Wilhelm Institute, University of Berlin, Manne Siegbahn Institute }
#
# $authors[[2]]
# \author{ Pierre Curie }
# \address{ École Normale Supérieure }
#
# $authors[[3]]
# \author{ Marie Curie }
# \address{ University of Paris, Institut du Radium, École Normale Supérieure }
fun_title <- function(meta) glue_data(meta, "\\title{{ {title} }}")
fun_authors <- function(meta) lapply(meta[["authors"]],
glue_data,
'\\author{{ {name} }}
{ paste(sprintf("\\\\affiliation{%s}", affiliation), collapse="\\n") }')
preamble_journal2 <- list(title = fun_title, authors = fun_authors)
lapply(preamble_journal2, do.call, list(meta=meta))
# $title
# \title{ On physics and chemistry }
#
# $authors
# $authors[[1]]
# \author{ Lise Meitner }
# \affiliation{Kaiser Wilhelm Institute}
# \affiliation{University of Berlin}
# \affiliation{Manne Siegbahn Institute}
#
# $authors[[2]]
# \author{ Pierre Curie }
# \affiliation{École Normale Supérieure}
#
# $authors[[3]]
# \author{ Marie Curie }
# \affiliation{University of Paris}
# \affiliation{Institut du Radium}
# \affiliation{École Normale Supérieure}
\documentclass[journal=jacsat,manuscript=article]{achemso}
{title}
{authors}
{keywords}
\begin{document}
{body}
\end{document}
\documentclass[%
reprint,
amsmath,amssymb,
aps,
]{revtex4-1}
\begin{document}
{title}
{authors}
{keywords}
\begin{abstract}
{abstract}
\end{abstract}
{pacs}
\maketitle
{body}
\end{document}
@baptiste
Copy link
Author

baptiste commented May 7, 2017

The goal is to provide a unified interface to multiple journal templates (which typically use different syntax for affiliation, keywords, etc.). My idea is to bypass pandoc templates, the syntax of which I find extremely cumbersome (\author{$for(author)$$author$$sep$ \and $endfor$}), and generate on-the-fly simpler, partially hard-coded templates, based on the available metadata and journal-specific formatting rules (lapply(meta[["authors"]], glue_data, '\\author{{ {name} }})

The envisaged structure is as follows:

  • _metadata.yaml stores all metadata about the article in a generic human-readable form
  • a minimal Rmd header specifies a custom pandoc template with "mustache" {{}} syntax where those values are to be inserted via a pre_knit hook (using brew and/or glue/whisker)
  • knit + rmarkdown + pandoc the resulting document as usual using this auto-generated template for pandoc

@jimhester
Copy link

you can use glue::collapse(affiliation, ", ") in place of the paste calls, there are also some purrr functions that might make the list processing little more concise...

@baptiste
Copy link
Author

baptiste commented May 7, 2017

for reference the standard strategy with pandoc templates looks like this,

$if(author)$
\author{$for(author)$$author$$sep$ \and $endfor$}
$endif$
$if(institute)$
\providecommand{\institute}[1]{}
\institute{$for(institute)$$institute$$sep$ \and $endfor$}
$endif$
\date{$date$}

\begin{document}
$if(title)$
\maketitle
$endif$
$if(abstract)$
\begin{abstract}
$abstract$
\end{abstract}
$endif$

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment