Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Solving issue #35 #41

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,27 +1,33 @@
Package: rbbt
Title: R Interface to the Better BiBTex Zotero Connector
Version: 0.0.0.9000
Version: 0.0.1
Date: 2023-08-02
Authors@R: c(person("Dewey", "Dunnington",
email = "dewey@fishandwhistle.net", role = c("aut", "cre")),
person("Brenton M.", "Wiernik",
email = "brenton@wiernik.org", role = c("aut"))
email = "brenton@wiernik.org", role = c("aut")),
person("Wencheng", "Lau-Medrano",
email = "brenton@wiernik.org", role = c("ctb"))
)
Description: Connects R to the Better Bibtex for Zotero connector
<https://retorque.re/zotero-better-bibtex/>.
Depends: R (>= 3.4.0)
Depends: R (>= 4.1.0)
License: GPL-3
Encoding: UTF-8
LazyData: true
RoxygenNote: 7.1.1
RoxygenNote: 7.2.3
Imports:
httr,
rstudioapi,
clipr,
knitr,
xfun,
readr,
stringr,
rmarkdown,
fs
fs,
tools,
utils
Roxygen: list(markdown = TRUE)
URL: https://github.com/paleolimbot/rbbt
BugReports: https://github.com/paleolimbot/rbbt/issues
Expand Down
27 changes: 27 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,30 @@ export(bbt_return)
export(bbt_update_bib)
export(bbt_write_bib)
export(has_bbt)
importFrom(clipr,clipr_available)
importFrom(clipr,read_clip)
importFrom(clipr,write_clip)
importFrom(fs,is_absolute_path)
importFrom(httr,GET)
importFrom(httr,POST)
importFrom(httr,build_url)
importFrom(httr,content)
importFrom(httr,parse_url)
importFrom(knitr,current_input)
importFrom(knitr,purl)
importFrom(readr,default_locale)
importFrom(readr,read_file)
importFrom(readr,write_file)
importFrom(rmarkdown,yaml_front_matter)
importFrom(rstudioapi,getActiveDocumentContext)
importFrom(rstudioapi,insertText)
importFrom(rstudioapi,isAvailable)
importFrom(stringr,regex)
importFrom(stringr,str_extract)
importFrom(stringr,str_match_all)
importFrom(stringr,str_subset)
importFrom(tools,file_ext)
importFrom(utils,URLencode)
importFrom(utils,citation)
importFrom(utils,toBibtex)
importFrom(xfun,split_lines)
6 changes: 3 additions & 3 deletions R/addin.R
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

bbt_cite_addin <- function() {
# get the likely citation type from the current document context
context <- rstudioapi::getActiveDocumentContext()
context <- getActiveDocumentContext()
bbt_cite_cayw(
format = bbt_guess_format(bbt_rstudio_editor_filepath()),
.action = bbt_insert
Expand All @@ -17,7 +17,7 @@ bbt_bib_addin <- function() {

bbt_update_bib_addin <- function() {
context <- bbt_rstudio_editor_filepath()
if (!(tools::file_ext(context) %in% c("qmd", "Qmd", "rmd", "Rmd"))) {
if (!(file_ext(context) %in% c("qmd", "Qmd", "rmd", "Rmd"))) {
stop("Currently selected editor is not a .qmd, .rmd or .Rmd file", call. = FALSE)
}

Expand All @@ -26,7 +26,7 @@ bbt_update_bib_addin <- function() {
}

bbt_rstudio_editor_filepath <- function() {
context <- rstudioapi::getActiveDocumentContext()
context <- getActiveDocumentContext()
if (is.character(context$path)) {
context$path
} else {
Expand Down
12 changes: 6 additions & 6 deletions R/api.R
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ assert_bbt <- function() {
#'
bbt_call <- function(.endpoint, ...) {
url <- bbt_url(.endpoint = .endpoint, ...)
httr::content(httr::GET(url), as = "text", encoding = "UTF-8")
content(GET(url), as = "text", encoding = "UTF-8")
}

#' @rdname bbt_call
Expand All @@ -50,8 +50,8 @@ bbt_cayw <- function(..., .action = bbt_print) {
#' @rdname bbt_call
#' @export
bbt_call_json_rpc <- function(.method, ...) {
httr::content(
httr::POST(
content(
POST(
bbt_url("json-rpc"),
body = list(
jsonrpc = "2.0",
Expand All @@ -71,15 +71,15 @@ bbt_url <- function(.endpoint, ...) {
if(is.null(names(args))) {
url <- paste0(
.endpoint, "?", paste0(
vapply(args, utils::URLencode, reserved=TRUE, FUN.VALUE = character(1)),
vapply(args, URLencode, reserved=TRUE, FUN.VALUE = character(1)),
collapse = "&"
)
)
} else {
stopifnot(all(names(args) != ""))
url <- httr::parse_url(.endpoint)
url <- parse_url(.endpoint)
url$query <- as.list(args)
url <- httr::build_url(url)
url <- build_url(url)
}

url
Expand Down
2 changes: 1 addition & 1 deletion R/bbt-libraries.R
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#' if (has_bbt()) bbt_libraries()
#'
bbt_libraries <- function() {
groups <- rbbt::bbt_call_json_rpc("user.groups")
groups <- bbt_call_json_rpc("user.groups")
data.frame(
id = vapply(groups$result, function(x) x$id, integer(1)),
name = vapply(groups$result, function(x) x$name, character(1)),
Expand Down
41 changes: 38 additions & 3 deletions R/bbt.R
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,35 @@ bbt_bib <- function(keys, translator = getOption("rbbt.default.translator", "bib
return(.action(""))
}

index <- grep(pattern = "^rpkg_", x = keys, ignore.case = TRUE)

if(length(index) > 0){
rPkgs <- keys[index]

rPkgs <- gsub(pattern = "^rpkg_", replacement = "", x = rPkgs, ignore.case = TRUE)
rPkgs <- rPkgs |>

lapply(citation) |>

lapply(\(x) x[[1]]) |>

lapply(toBibtex) |>

lapply(as.character)

rPkgs <- mapply(x = rPkgs, y = keys[index],
FUN = \(x, y) c(gsub(pattern = "\\{[[:graph:]]*,$",
replacement = sprintf("\\{%s,", y),
x = x[1]), x[-1]),
SIMPLIFY = FALSE) |>

sapply(paste, collapse = "\n") |>

paste(collapse = "\n\n")

keys <- keys[-index]
}

assert_bbt()
translator <- match.arg(translator, choices = c("json", "biblatex", "bibtex", "cslyaml"))
result <- bbt_call_json_rpc(
Expand All @@ -95,6 +124,12 @@ bbt_bib <- function(keys, translator = getOption("rbbt.default.translator", "bib
if (!is.null(result$error)) {
stop(result$error$message, call. = FALSE)
} else {

if(length(index) > 0){
result$result[[3]] <- paste0(c(result$result[[3]], rPkgs, ""),
collapse = "\n")
}

.action(result$result[[3]])
}
}
Expand All @@ -110,8 +145,8 @@ bbt_bib <- function(keys, translator = getOption("rbbt.default.translator", "bib
#'
bbt_insert <- function(text) {
text <- paste(text, collapse = "\n")
if(rstudioapi::isAvailable()) {
rstudioapi::insertText(text = text)
if(isAvailable()) {
insertText(text = text)
} else {
cat(text)
}
Expand All @@ -138,6 +173,6 @@ bbt_return <- function(text) {
bbt_copy <- function(text) {
text <- paste(text, collapse = "\n")
message("Text copied to clipboard")
clipr::write_clip(text)
write_clip(text)
invisible(text)
}
19 changes: 10 additions & 9 deletions R/detect-citations.R
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

#' Detect pandoc-style citations
#'
#' By default, this omits any references within code chunks, inline R code,
Expand All @@ -7,8 +6,8 @@
#' [nocite front matter field](https://rmarkdown.rstudio.com/authoring_bibliographies_and_citations.html#Unused_References_(nocite)).
#'
#' @param path A character vector, file or URL whose contents may contain citation keys.
#' Multiple files can be passed in as a vector (e.g., from [list.files()]).
#' @param locale See [readr::default_locale()]. Use if encoding might
#' Multiple files can be passed in as a vector (e.g., from \link{list.files}).
#' @param locale See \link[readr]{default_locale}. Use if encoding might
#' be a problem.
#'
#' @return A character vector of unique citation keys.
Expand All @@ -17,15 +16,15 @@
#' @examples
#' bbt_detect_citations("\n@citation1 and [@citation2] but not \\@citation3")
#'
bbt_detect_citations <- function(path = bbt_guess_citation_context(), locale = readr::default_locale()) {
text <- vapply(path, readr::read_file, locale = locale, FUN.VALUE = character(1))
bbt_detect_citations <- function(path = bbt_guess_citation_context(), locale = default_locale()) {
text <- vapply(path, read_file, locale = locale, FUN.VALUE = character(1))
bbt_detect_citations_chr(text)
}

#' @rdname bbt_detect_citations
#' @export
bbt_guess_citation_context <- function() {
knitr_doc <- knitr::current_input()
knitr_doc <- current_input()
if (!is.null(knitr_doc)) {
knitr_doc
} else {
Expand All @@ -49,10 +48,12 @@ bbt_detect_citations_chr <- function(text) {
text <- gsub("\\(http.+?\\)", "", text)
text <- gsub("<http.+?>", "", text)

refs <- stringr::str_match_all(
text,
stringr::regex("[^a-zA-Z0-9\\\\]@([a-zA-Z0-9_\\.\\-:]+[a-zA-Z0-9])", multiline = TRUE, dotall = TRUE)
refs <- str_match_all(string = text, pattern = regex("[^a-zA-Z0-9\\\\]@([a-zA-Z0-9_\\.\\-:]+[a-zA-Z0-9])",
multiline = TRUE, dotall = TRUE)
)[[1]][, 2, drop = TRUE]

index <- !grepl(pattern = "(^fig-)|(^tbl-)", x = refs, ignore.case = TRUE)
refs <- refs[index]

unique(refs)
}
13 changes: 13 additions & 0 deletions R/rbbt.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# rbbt
#' @importFrom clipr clipr_available read_clip write_clip
#' @importFrom httr content POST parse_url build_url GET
#' @importFrom rstudioapi getActiveDocumentContext isAvailable insertText
#' @importFrom knitr current_input purl
#' @importFrom xfun split_lines
#' @importFrom readr default_locale read_file write_file
#' @importFrom stringr str_match_all regex str_subset str_extract
#' @importFrom rmarkdown yaml_front_matter
#' @importFrom fs is_absolute_path
#' @importFrom tools file_ext
#' @importFrom utils URLencode toBibtex citation
NULL
6 changes: 3 additions & 3 deletions R/update.R
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#'
#' @param path_rmd The path to the RMarkdown file.
#' @param path_bib The path to the bibliography file.
#' @param encoding Passed to [rmarkdown::yaml_front_matter()]
#' @param encoding Passed to \link[rmarkdown]{yaml_front_matter}
#' @param quiet Use `TRUE` to suppress message on successful write.
#' @inheritParams bbt_write_bib
#'
Expand Down Expand Up @@ -39,7 +39,7 @@ bbt_update_bib <- function(path_rmd,
#' @rdname bbt_update_bib
#' @export
bbt_guess_bib_file <- function(path_rmd, encoding = "UTF-8") {
front_matter <- rmarkdown::yaml_front_matter(path_rmd, encoding = encoding)
front_matter <- yaml_front_matter(path_rmd, encoding = encoding)
if (length(front_matter$bibliography) != 1) {
stop(
sprintf("Can't guess bibliography file from '%s' front matter", path_rmd),
Expand All @@ -48,7 +48,7 @@ bbt_guess_bib_file <- function(path_rmd, encoding = "UTF-8") {
}

bib_file <- front_matter$bibliography
if (!fs::is_absolute_path(bib_file)) {
if (!is_absolute_path(bib_file)) {
file.path(dirname(path_rmd), bib_file)
} else {
bib_file
Expand Down
2 changes: 1 addition & 1 deletion R/write-bib.R
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ bbt_write_bib <- function(path,
force(keys)

assert_bbt()
readr::write_file(
write_file(
bbt_bib(
setdiff(keys, ignore),
translator,
Expand Down
32 changes: 18 additions & 14 deletions README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -41,24 +41,28 @@ You will also need [Zotero](https://www.zotero.org/) installed and running, and

This package is most useful for the RStudio addins that insert citations and references into the editor. The "Insert Zotero Citation" will pop up a zotero search where you can search for a reference to add to your writing (Markdown, RMarkdown, or LaTeX). The "Insert Zotero Bibliography" addin inserts the bibliographical information corresponding to the selected item in the Zotero window. Finally, "Update bibliography for current document" runs `bbt_update_bib()` to update the bibliography based on the .Rmd file currently in the editor window. You can bind either of these to keyboard shortcuts in RStudio. The addins may behave differently depending on which file you have open (e.g., if you have a .bib file open, it will use the biblatex translator)...if you need more fine-grained control, try one of the console functions (like `bbt_bib()`!).

## knitr + rmarkdown integration
## RStudio shortcuts

To make this work seamlessly with [knitr](https://yihui.org/knitr/) and [rmarkdown](https://rmarkdown.rstudio.com/), use the "Update bibliography for current document" addin to write your bibliography file based on the citations in the currently selected document. You can use `bbt_update_bib("some_file.Rmd")` to detect citations and write your bibliography file from the console.
In RStudio, it is possible to assign a keyboard shortcut for **rbbt** addins. Just go to *Tools --> Modify Keyboard Shortcuts* and a small window will open with all the available commands to assign a keyboard shortcut. Then, using the **Scope** column, find the *Addin* type and configure the shortcuts for **rbbt** commands. For example: to set a shortcut for `bbt_update_bib()`, go to the row assigned for **"Update bibliography for current document from Zotero "**, click on the **Shortcut** column and press the desired key combination. It is recommended to define shortcuts for **"Update bibliography for current document from Zotero "** and **"Insert Zotero citation "** as they will be the most used.

## Programmatically fetch bibliography info
It should be noted that RStudio comes configured with some keyboard shortcuts, so it should be avoided that the newly defined shortcuts overlap (if this happens, a warning icon will be displayed in the shortcut assignment window).

Fetch bibliography text using a list of Better BibTex citation keys:
Also, for the commands to work correctly, they must be executed having the Rmd or Qmd file in the active tab in RStudio. That is to say, both addins mentioned above will detect the citations and the bibliography file from the active tab (from the main .Rmd or .Qmd file) from where the shortcut is executed, so you must make sure to have that document active when executing the commands, otherwise you will receive the following error message: **"Currently selected editor is not a .qmd, .rmd or .Rmd file "**.

```{r, comment=""}
# uses the citation keys you've defined with Better BibTeX
rbbt::bbt_bib("dunnington_etal18", translator = "biblatex", .action = bbt_print)
```
In RStudio, it is possible to assign a keyboard shortcut for rbbt addins. Just go to Tools --> Modify Keyboard Shortcuts and a small window will open with all the available commands to assign a keyboard shortcut. Then, using the **Scope** column, find the **Addin** type and configure the shortcuts for **rbbt** commands. For example: to set a shortcut for `bbt_update_bib()`, go to the row assigned for **"Update bibliography for current document from Zotero "**, click on the **Shortcut** column and press the desired key combination. It is recommended to define shortcuts for **"Update bibliography for current document from Zotero "** and **"Insert Zotero citation "** as they will be the most used.

Fetch bibliography text from selected items in Zotero:
## knitr + rmarkdown integration

```{r, comment=""}
# uses whatever is currently selected in the zotero window
rbbt::bbt_bib_selected(translator = "biblatex", .action = bbt_print)
```
To make this work seamlessly with [knitr](https://yihui.org/knitr/) and [rmarkdown](https://rmarkdown.rstudio.com/), use the "Update bibliography for current document" addin to write your bibliography file based on the citations in the currently selected document. You can use `bbt_update_bib("some_file.Rmd")` to detect citations and write your bibliography file from the console.

# Versions

## 0.0.1
* Add functionality for citing R packages. Now, if the user wants to cite a R package, could indicate it in the Rmd/Qmd file with the syntax `@rpkg_NameOfPackage` (e.g. `@rpkg_rbbt`). `bbt_detect_citations` and `bbt_update_bib` are now prepared for identify this syntax and adding to the bibliography using `citation` and `toBibtex` tools.
* R native pipe is used in some functions so now it is necessary to run **rbbt** in **R >= 4.1.0**.
* Subtle corrections and improvements in code and documentation.

## 0.0.0.9002

<!-- lazy way to test the bbt_update_bib() addon: @dunnington_etal18 -->
* Changes in `bbt_detect_citations` in order to avoid including citations that starts whether with *fig-* or *tbl-* (associtaed with Quarto syntaxis).
* Minor improvements in definiton of external functions and dependencies.
Loading