-
Notifications
You must be signed in to change notification settings - Fork 30
/
Copy pathcompile.R
67 lines (63 loc) · 2.81 KB
/
compile.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
options(repos = "https://cran.rstudio.com")
dir.create('~/R', showWarnings = FALSE)
.libPaths('~/R')
# install xfun and tinytex
pkg_install = function(...) install.packages(..., quiet = TRUE)
pkg_install('xfun')
options(xfun.install.package = pkg_install)
xfun::pkg_load2(c('tinytex', 'rmarkdown'))
# install TinyTeX
suppressMessages(suppressWarnings(if (!tinytex:::is_tinytex()) tinytex::install_tinytex()))
p0 = tinytex::tl_pkgs() # the initial set of LaTeX packages installed
p1 = NULL # missing packages identified from the LaTeX log
# parse LaTeX errors from .log files, or compile .Rmd/.tex files to figure out
# missing LaTeX packages
for (f in list.files('.', '[.](Rmd|tex|log)$')) {
if (!file.exists(f)) next # the file might have been deleted
# different actions according to filenames extensions
switch(
xfun::file_ext(f),
Rmd = if (length(grep('^---\\s*$', readLines(f, n = 1)))) {
# the first line needs to be ---, in case it's a child Rmd file
xfun::pkg_load2('rmarkdown')
# make sure pandoc and pandoc-citeproc are installed
for (i in c('pandoc', 'pandoc-citeproc')) {
if (Sys.which(i) == '') system(paste('brew install', i))
}
rmarkdown::render(f)
},
tex = {
x = xfun::read_utf8(f)
# need to find \documentclass or \begin{document} in the .tex file
if (length(grep('\\\\documentclass', x)) == 0) next
n1 = length(i1 <- grep('\\\\begin\\{document\\}', x))
n2 = length(i2 <- grep('\\\\end\\{document\\}', x))
if (n1 * n2 == 0) next
if (n1 > 1 || n2 > 1) {
warning('More than one line of code contains \\begin{document} or \\end{document}')
next
}
# clear the document body, because it may have references to files that
# users forgot or didn't want to upload to this repo; this approach won't
# work for bibliography, but users can upload their LaTeX log in this case
xfun::write_utf8(c(x[1:i1], 'Hello world!', x[i2]), f)
r = '.*?((?:pdf|xe|lua)latex).*'
engine = if (length(grep(r, f))) gsub(r, '\\1', f)
# also try to infer engine from the comment like "% !TeX program = xelatex"
r = '^(?:% !TeX program\\s*=\\s*)([[:alnum:]-]+).*'
if (length(i <- grep(r, x))) engine = gsub(r, '\\1', x[i][1])
# if I can't infer the engine, use pdflatex by default
if (is.null(engine)) engine = 'pdflatex'
r = '.*?(bibtex|biber).*'
bib_engine = if (length(grep(r, f))) gsub(r, '\\1', f)
if (is.null(bib_engine)) bib_engine = 'bibtex'
tinytex::latexmk(f, engine = engine, bib_engine = bib_engine)
},
log = {
if (file.size(f) == 0) next
p1 = c(p1, tinytex::parse_packages(f))
}
)
}
p2 = setdiff(tinytex::tl_pkgs(), p0) # newly installed packages after compiling Rmd/tex files
saveRDS(list(p1, p2), file = 'packages.rds')