Skip to content

Commit dcc4f57

Browse files
author
hornik
committed
Enhancements for c88462.
git-svn-id: https://svn.r-project.org/R/trunk@88489 00db46b3-68df-0310-9c12-caf00c1e9a41
1 parent 3153c65 commit dcc4f57

File tree

1 file changed

+127
-31
lines changed

1 file changed

+127
-31
lines changed

src/library/tools/R/RdHelpers.R

Lines changed: 127 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -180,18 +180,41 @@ function(x)
180180
return(x)
181181
}
182182
bib <- R_bibentries()
183-
## <FIXME>
183+
cited <- Rd_expr_bibcite_keys_cited()
184184
## Would be nice to have a common reader for possibly multi-line
185185
## comma separated values ...
186-
keys <- strsplit(x, ",[[:space:]]*")[[1L]]
187-
if(any(keys == "*")) {
188-
keys <- c(keys, Rd_expr_bibcite_keys_cited())
189-
Rd_expr_bibcite_keys_cited(NULL)
186+
given <- strsplit(x, ",[[:space:]]*")[[1L]]
187+
if(any(given == "*"))
188+
given <- c(given[given != "*"], cited)
189+
Rd_expr_bibcite_keys_cited(setdiff(cited, given))
190+
y <- sort(unique(bib[.bibentry_get_key(bib) %in% given]))
191+
## Merge bibinfo data.
192+
keys <- .bibentry_get_key(y)
193+
store <- Rd_expr_bibinfo_data_store()
194+
for(k in intersect(keys, names(store))) {
195+
entry <- store[[k]]
196+
for(f in names(entry))
197+
y[k, f] <- entry[[f]]
190198
}
191-
y <- sort(unique(bib[bib$key %in% keys]))
192-
paste(sprintf("\\if{html}{\u2060\\out{<span id=\"reference+%s\">}}%s\\if{html}{\\out{</span>}}",
193-
string2id(unlist(y$key, use.names = FALSE)),
194-
toRd(y)),
199+
Rd_expr_bibinfo_data_store(store[setdiff(names(store), keys)])
200+
## Typically the bibinfo data would give headers or footers, but
201+
## these only get shown when printing bibenties in citation style,
202+
## so we have to add them ourselves.
203+
headers <- y[, "header"]
204+
headers <- unlist(ifelse(vapply(headers, is.null, NA), "", headers),
205+
use.names = FALSE)
206+
if(any(ind <- nzchar(headers)))
207+
headers[ind] <- paste(headers[ind], "\\cr")
208+
footers <- y[, "footer"]
209+
footers <- unlist(ifelse(vapply(footers, is.null, NA), "", footers),
210+
use.names = FALSE)
211+
if(any(ind <- nzchar(footers)))
212+
footers[ind] <- paste("\\cr", footers[ind])
213+
paste(sprintf("%s\\if{html}{\u2060\\out{<span id=\"reference+%s\">}}%s\\if{html}{\\out{</span>}}%s",
214+
headers,
215+
string2id(.bibentry_get_key(y)),
216+
toRd(y),
217+
footers),
195218
collapse = "\n\n")
196219
}
197220

@@ -210,33 +233,106 @@ function(x, textual = FALSE)
210233
{
211234
x <- trimws(x)
212235
bib <- R_bibentries()
213-
keys <- strsplit(x, ",[[:space:]]*")[[1L]]
214-
## Allow b<k>a to specify before b and after a.
215-
## Could also use
216-
## regmatches(keys, regexec("(.*<)?(.*)(>.*)?", keys))
217-
before <- after <- rep_len("", length(keys))
218-
if(any(ind <- grepl("<", keys))) {
219-
before[ind] <- sub("<.*", "", keys[ind])
220-
keys[ind] <- sub(".*<", "", keys[ind])
236+
given <- strsplit(x, ",[[:space:]]*")[[1L]]
237+
parts <- strsplit(given, "|", fixed = TRUE)
238+
parts <- parts[lengths(parts) %in% c(1L, 3L)]
239+
## Could complain about the others ...?
240+
keys <- after <- before <- rep_len("", length(parts))
241+
if(any(ind <- (lengths(parts) == 1L))) {
242+
keys[ind] <- unlist(parts[ind], use.names = FALSE)
221243
}
222-
if(any(ind <- grepl(">", keys))) {
223-
after[ind] <- sub(".*>", "", keys[ind])
224-
keys[ind] <- sub(">.*", "", keys[ind])
244+
if(any(ind <- (lengths(parts) == 3L))) {
245+
keys[ind] <- vapply(parts, `[`, "", 2L)
246+
after[ind] <- vapply(parts, `[`, "", 3L)
247+
before[ind] <- vapply(parts, `[`, "", 1L)
225248
}
226-
ind <- keys %in% unlist(bib$key)
249+
ind <- keys %in% .bibentry_get_key(bib)
227250
if(!all(ind)) {
228-
## <FIXME>
229-
## Should warn about keys not in the bibentries
230-
before <- before[ind]
231-
after <- after[ind]
251+
## Could complain about keys not in the bibentries ...?
232252
keys <- keys[ind]
253+
after <- after[ind]
254+
before <- before[ind]
255+
}
256+
n <- length(keys)
257+
if(n == 0L)
258+
return("")
259+
y <- character(n)
260+
prev <- Rd_expr_bibcite_keys_cited()
261+
if(textual) {
262+
for(i in seq_len(n)) {
263+
key <- keys[i]
264+
y[i] <- utils::citeNatbib(key, bib[key], after = after[i],
265+
previous = prev, textual = TRUE)
266+
prev <- c(prev, key)
267+
}
268+
if(any(ind <- nzchar(before)))
269+
before[ind] <- paste0(before[ind], " ")
270+
y <- paste0(before,
271+
sprintf("\\if{html}{\\out{<a href=\"#reference+%s\">}}",
272+
string2id(keys)),
273+
y,
274+
rep_len("\\if{html}{\\out{</a>}}", n),
275+
collapse = "; ")
276+
} else {
277+
bibp <- c("", "", ";", "a", "", ",")
278+
for(i in seq_len(n)) {
279+
key <- keys[i]
280+
y[i] <- utils::citeNatbib(key, bib[key],
281+
previous = prev, textual = FALSE,
282+
bibpunct = bibp)
283+
prev <- c(prev, key)
284+
}
285+
if(any(ind <- nzchar(before)))
286+
before[ind] <- paste0(before[ind], " ")
287+
if(any(ind <- nzchar(after)))
288+
after[ind] <- paste0(", ", after[ind])
289+
y <- paste0("(",
290+
paste0(before,
291+
sprintf("\\if{html}{\\out{<a href=\"#reference+%s\">}}",
292+
string2id(keys)),
293+
y,
294+
rep_len("\\if{html}{\\out{</a>}}", n),
295+
after,
296+
collapse = ";"),
297+
")")
233298
}
234299
Rd_expr_bibcite_keys_cited(keys, TRUE)
235-
## <FIXME>
236-
## This really needs a vectorized version of cite() ...
237-
before <- sprintf("\\if{html}{\\out{<a href=\"#reference+%s\">}}%s",
238-
string2id(keys), before)
239-
after <- sprintf("%s\\if{html}{\\out{</a>}}", after)
240-
utils::cite(keys, bib, textual, before, after)
300+
y
301+
}
302+
303+
Rd_expr_bibinfo_data_store <- local({
304+
.store <- NULL
305+
function(new, add = FALSE) {
306+
if(!missing(new)) {
307+
if(add) {
308+
key <- new[[1L]]
309+
val <- `names<-`(list(new[[3L]]), new[[2L]])
310+
.store[[key]] <<- c(.store[[key]], val)
311+
} else
312+
.store <<- new
313+
}
314+
else
315+
.store
316+
}
317+
})
318+
319+
Rd_expr_bibinfo <-
320+
function(key, field, value)
321+
{
322+
Rd_expr_bibinfo_data_store(list(trimws(key),
323+
trimws(field),
324+
gsub("\n\n", "\n", trimws(value))),
325+
add = TRUE)
326+
}
327+
328+
## utils:::.bibentry_get_key
329+
.bibentry_get_key <-
330+
function (x)
331+
{
332+
if(!length(x))
333+
return(character())
334+
keys <- lapply(unclass(x), attr, "key")
335+
keys[!lengths(keys)] <- ""
336+
unlist(keys, use.names = FALSE)
241337
}
242338

0 commit comments

Comments
 (0)