-
-
Notifications
You must be signed in to change notification settings - Fork 878
/
defaults.R
249 lines (230 loc) · 10 KB
/
defaults.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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
#' @include utils.R
new_defaults = function(value = list()) {
defaults = value
locked = FALSE
get = function(name, default = FALSE, drop = TRUE) {
if (default) defaults = value # this is only a local version
if (missing(name)) defaults else {
if (drop && length(name) == 1) defaults[[name]] else {
setNames(defaults[name], name)
}
}
}
resolve = function(...) {
dots = list(...)
if (length(dots) == 0) return()
if (is.null(names(dots)) && length(dots) == 1 && is.list(dots[[1]]))
if (length(dots <- dots[[1]]) == 0) return()
dots
}
set2 = function(values) {
old = get(names(values), drop = FALSE)
if (length(values)) {
# TODO: change warning() to stop() and no longer whitelist JuliaCall
if (locked && !identical(names(values), 'Jfig.cur')) warning(
'The object is read-only and cannot be modified. If you have to modify it ',
'for a legitimate reason, call the method $lock(FALSE) on the object before $set(). ',
'Using $lock(FALSE) to modify the object will be enforced in future versions of knitr ',
'and this warning will become an error.',
immediate. = TRUE
)
defaults <<- merge(values)
}
invisible(old)
}
set = function(...) {
set2(resolve(...))
}
delete = function(keys) {
for (k in keys) defaults[[k]] <<- NULL
}
merge = function(values) merge_list(defaults, values)
restore = function(target = value) defaults <<- target
append = function(...) {
dots = resolve(...)
for (i in names(dots)) dots[[i]] <- c(defaults[[i]], dots[[i]])
set2(dots)
}
lock = function(status = TRUE) locked <<- status
list(
get = get, set = set, delete = delete, append = append, merge = merge,
restore = restore, lock = lock
)
}
#' Default and current chunk options
#'
#' Options for R code chunks. When running R code, the object \code{opts_chunk}
#' (default options) is not modified by chunk headers (local chunk options are
#' merged with default options), whereas \code{opts_current} (current options)
#' changes with different chunk headers and it always reflects the options for
#' the current chunk.
#'
#' Normally we set up the global options once in the first code chunk in a
#' document using \code{opts_chunk$set()}, so that all \emph{latter} chunks will
#' use these options. Note the global options set in one chunk will not affect
#' the options in this chunk itself, and that is why we often need to set global
#' options in a separate chunk.
#'
#' See \code{str(knitr::opts_chunk$get())} for a list of default chunk options.
#' @references Usage: \url{https://yihui.org/knitr/objects/}
#'
#' A list of available options:
#' \url{https://yihui.org/knitr/options/#chunk-options}
#' @note \code{opts_current} should be treated as read-only and you are supposed
#' to only query its values via \code{opts_current$get()}. Calling
#' \code{opts_current$set()} will throw an error.
#' @export
#' @examples opts_chunk$get('prompt'); opts_chunk$get('fig.keep')
opts_chunk = new_defaults(list(
eval = TRUE, echo = TRUE, results = 'markup', tidy = FALSE, tidy.opts = NULL,
collapse = FALSE, prompt = FALSE, comment = '##', highlight = TRUE,
size = 'normalsize', background = '#F7F7F7',
# value wrapped in I() means a change in default option later
# (e.g in fix_options, conditionally to other argument)
strip.white = I(TRUE),
cache = FALSE, cache.path = 'cache/', cache.vars = NULL, cache.lazy = TRUE,
dependson = NULL, autodep = FALSE, cache.rebuild = FALSE,
fig.keep = 'high', fig.show = 'asis', fig.align = 'default', fig.path = 'figure/',
dev = NULL, dev.args = NULL, dpi = 72, fig.ext = NULL, fig.width = 7, fig.height = 7,
fig.env = 'figure', fig.cap = NULL, fig.scap = NULL, fig.lp = 'fig:', fig.subcap = NULL,
fig.pos = '', out.width = NULL, out.height = NULL, out.extra = NULL, fig.retina = 1,
external = TRUE, sanitize = FALSE, interval = 1, aniopts = 'controls,loop',
warning = TRUE, error = TRUE, message = TRUE,
render = NULL,
ref.label = NULL, child = NULL, engine = 'R', split = FALSE, include = TRUE, purl = TRUE
))
#' @rdname opts_chunk
#' @export
opts_current = new_defaults()
opts_current$restore(opts_chunk$get())
#' @include plot.R
# a list of options attributes for RStudio
opts_chunk_attr = local({
opts = lapply(opts_chunk$get(), class)
opts[opts == 'NULL'] = 'character'
opts$results = list('markup', 'asis', 'hold', 'hide')
opts$fig.show = list('asis', 'hold', 'animate', 'hide')
opts$fig.keep = list('high', 'none', 'all', 'first', 'last')
opts$fig.align = list('default', 'left', 'right', 'center')
opts$fig.showtext = 'logical'
# quartz_ devices are for OS X only
opts$dev = names(auto_exts)
if (Sys.info()[['sysname']] != 'Darwin')
opts$dev = grep('^quartz_', opts$dev, value = TRUE, invert = TRUE)
if (.Platform$OS.type != 'windows')
opts$dev = setdiff(opts$dev, 'win.metafile')
opts$dev = opts$fig.format = as.list(opts$dev)
opts$fig.dpi = 'numeric'
opts$fig.ext = as.list(unique(auto_exts))
opts$external = opts$sanitize = NULL # hide these two rare options
opts$fig.process = 'function'
opts[c('fig.asp', 'fig.ncol')] = 'numeric'
opts$fig.dim = 'list'
opts$fig.id = 'logical'
opts[c(
'opts.label', 'resize.width', 'resize.height', 'fig.alt', 'fig.link', 'fig.sep',
'tab.cap', 'ffmpeg.bitrate', 'ffmpeg.format'
)] = 'character'
opts$lang = 'list'
opts$R.options = 'list'
opts$cache.comments = 'logical'
opts$cache.globals = 'list'
opts$animation.hook = list('ffmpeg', 'gifski')
for (i in c('class', 'attr')) {
for (j in c('source', 'output', 'message', 'warning', 'error', 'chunk')) {
opts[[paste(i, j, sep = '.')]] = 'character'
}
}
# for R Markdown paged tables
opts[paste0(c(
'max', 'sql.max', 'paged', 'rows', 'cols', 'cols.min', 'pages', 'paged', 'rownames'
), '.print')] = 'numeric'
opts
})
#' Set aliases for chunk options
#'
#' We do not have to use the chunk option names given in \pkg{knitr}; we can set
#' aliases for them. The aliases are a named character vector; the names are
#' aliases and the elements in this vector are the real option names.
#' @param ... Named arguments. Argument names are aliases, and argument values
#' are real option names.
#' @return \code{NULL}. \code{opts_knit$get('aliases')} is modified as the side effect.
#' @export
#' @examples set_alias(w = 'fig.width', h = 'fig.height')
#' # then we can use options w and h in chunk headers instead of fig.width and fig.height
set_alias = function(...) {
opts_knit$set(aliases = c(...))
}
#' Options for the knitr package
#'
#' Options including whether to use a progress bar when knitting a document, and
#' the base directory of images, etc.
#'
#' Besides the standard usage (\code{opts_knit$set()}), we can also set package
#' options prior to loading \code{knitr} or calling \code{knit()} using
#' \code{\link{options}()} in base R. A global option \code{knitr.package.foo}
#' in \code{options()} will be set as an option \code{foo} in \code{opts_knit},
#' i.e. global options in base R with the prefix \code{knitr.package.}
#' correspond to options in \code{opts_knit}. This can be useful to set package
#' options in \file{~/.Rprofile} without loading \pkg{knitr}.
#'
#' See \code{str(knitr::opts_knit$get())} for a list of default package options.
#' @references Usage: \url{https://yihui.org/knitr/objects/}
#'
#' A list of available options:
#' \url{https://yihui.org/knitr/options/#package-options}
#' @export
#' @examples opts_knit$get('verbose'); opts_knit$set(verbose = TRUE) # change it
#' if (interactive()) {
#' # for unnamed chunks, use 'fig' as the figure prefix
#' opts_knit$set(unnamed.chunk.label='fig')
#' knit('001-minimal.Rmd') # from https://github.com/yihui/knitr-examples
#' }
#' @include hooks-html.R
opts_knit = new_defaults(list(
progress = TRUE, verbose = FALSE, eval.after = c('fig.cap', 'fig.scap', 'fig.alt'),
base.dir = NULL, base.url = NULL, root.dir = NULL, child.path = '',
upload.fun = identity, global.device = FALSE, global.par = FALSE,
concordance = FALSE, documentation = 1L, self.contained = TRUE,
unnamed.chunk.label = 'unnamed-chunk', highr.opts = NULL,
label.prefix = c(table = 'tab:'), latex.tilde = NULL,
# internal options; users should not touch them
out.format = NULL, child = FALSE, parent = FALSE, tangle = FALSE, aliases = NULL,
header = c(highlight = '', tikz = '', framed = ''), global.pars = NULL
))
# tangle: whether I'm in tangle mode; child: whether I'm in child document mode;
# parent: whether I need to add parent preamble to the child output
# adjust opts_chunk and opts_knit according to options(), e.g.
# options(knitr.package.progress = FALSE) --> opts_knit$set(progress = FALSE),
# and options(knitr.chunk.tidy) --> opts_chunk$set(tidy = TRUE); this makes it
# possible to set options in ~/.Rprofile without loading knitr
adjust_opts_knit = function() {
# begin_hack: R CMD build does not evaluate .Rprofile, but I need a way to
# modify opts_chunk just for myself
if (nzchar(opts <- Sys.getenv('R_KNITR_OPTIONS')))
eval(parse_only(sprintf('base::options(%s)', opts)), envir = globalenv())
# end_hack
opts = options()
nms = names(opts)
if (length(nms <- grep('^knitr[.]', nms, value = TRUE)) == 0) return()
opts = opts[nms]
# strip off knitr.chunk from option names and set chunk options
i = grep('^knitr[.]chunk[.]', nms)
opts_chunk$set(setNames(opts[i], sub('^knitr[.]chunk[.]', '', nms[i])))
# similarly for knitr.package.options
i = grep('^knitr[.]package[.]', nms)
opts_knit$set(setNames(opts[i], sub('^knitr[.]package[.]', '', nms[i])))
}
#' Template for creating reusable chunk options
#'
#' Creates a template binding a label to a set of chunk options. Every chunk
#' that references the template label will have the specified set of options
#' applied to it.
#' @export
#' @examples opts_template$set(myfigures = list(fig.height = 4, fig.width = 4))
#' # later you can reuse these chunk options by 'opts.label', e.g.
#'
#' # <<foo, opts.label='myfigures'>>=
#'
#' # the above is equivalent to <<foo, fig.height=4, fig.width=4>>=
opts_template = new_defaults()