Nothing
check_bib <- function(bib_doi, bibfile) {
str_detect(bibfile, paste0("\\{", bib_doi, "\\}"))
}
correct_bib <- function(bib, bib_key, bibfile) {
if (!str_detect(bibfile, bib_key)) return(bib)
new_key <- paste(bib_key, sample(9999, 1), sep = "_")
return(str_replace(bib, bib_key, new_key))
}
crAddins <- function() {
current_yr <- as.numeric(format(Sys.Date(), "%Y"))
types <- cr_types()$data
types <- sort(setNames(types$id, types$label))
types <- c("Any Type" = "any", types)
choices <- stats::setNames(c("asc", "desc"), enc2utf8(c("\u25B2", "\u25BC")))
ui <- miniPage(
gadgetTitleBar("Add Crossref Citations"),
miniTabstripPanel(
miniTabPanel(
"Search Metadata", icon = icon("search"),
miniContentPanel(
fillRow(
flex = c(8, 1, 2, 1), height = "50px",
textInput(
"search_query", label = NULL, width = "100%",
placeholder = "Search, Select & Add"
),
h5("Sort:", class = "text-center"),
selectInput(
"search_sort",
label = NULL, width = "95%",
choices = c(
"Relevance" = "relevance",
"Published" = "published",
"Recent Changed" = "updated",
"Referenced" = "is-referenced-by-count"
)
),
selectInput(
"search_order",
label = NULL, width = "95%",
choices = choices,
selected = "desc"
)
),
tags$div(
style = "margin-top: -10px;",
fillRow(
flex = c(1, 1, 1, 1, 2), height = "60px",
textInput("search_author", label = "Author", width = "95%"),
textInput("search_container", label = "Journal/Container",
width = "95%"),
selectInput("search_type", label = "Type", width = "95%",
choices = types, selected = "journal-article"),
selectInput("search_date1", label = "Since", width = "95%",
choices = c(
"Any time" = "any",
seq(current_yr, current_yr - 4),
"Custom" = "custom"
)),
conditionalPanel(
condition = "input.search_date1 == 'custom'",
dateRangeInput("search_date2", label = "Select Range",
width = "95%", startview = "decade")
)
)
),
conditionalPanel(
condition = "input.search_query == ''",
hr(),
h4("Tips:"),
p("1. The crossref API doesn't support exact match right now. ",
"In fact, it returns all results based on each word being ",
'searched against. For example, "John Smith" in the author ',
'field will list out all results matches "John" OR "Smith", ',
'instead of searching for "John Smith" as a whole name.'),
p("2. If you want to find all publications by a person, try to ",
"put in his/her name in Author and put a space in the search box.")
),
uiOutput("selected_item"),
DT::dataTableOutput("search_table")
)
),
miniTabPanel(
"Search by DOI",
icon = icon("barcode"),
miniContentPanel(
h4(
"Add a new bibliography entry through Crossref DOI",
class = "text-center",
style = "padding-bottom: 15px;"
),
textInput(
"entered_dois",
label = NULL,
placeholder = "Enter a DOI to get started",
width = "95%"
),
uiOutput("selected_item2")
)
)
)
)
server <- function(input, output, session) {
rv <- reactiveValues(ref_loc = "")
if (file.exists("~/.rc_addin")) {
rv$ref_loc <- readLines("~/.rc_addin")
} else {
rv$ref_loc <- "references.bib"
writeLines("references.bib", "~/.rc_addin")
}
search_results <- reactive({
req(input$search_query)
search_flq <- NULL
if (input$search_container != "") {
search_flq <- c(search_flq,
`query.container-title` = input$search_container)
}
if (input$search_author != "") {
search_flq <- c(search_flq, `query.author` = input$search_author)
}
search_filter <- NULL
if (input$search_type != "any") {
search_filter <- c(search_filter, type = input$search_type)
}
if (input$search_date1 != "any") {
if (input$search_date1 == "custom") {
s_dates <- as.character(input$search_date2)
if (s_dates[1] != s_dates[2] & input$search_date2[1] != Sys.Date()) {
search_filter <- c(
search_filter,
from_pub_date = s_dates[1],
until_pub_date = s_dates[2]
)
}
} else {
search_filter <- c(search_filter,
from_pub_date = input$search_date1)
}
}
out <- cr_works(query = input$search_query, limit = 100,
select = c("DOI","type", "title", "URL",
"author","issued", "publisher",
"container-title"),
sort = input$search_sort,
order = input$search_order,
flq = search_flq,
filter = search_filter)
return(out$data)
})
output$search_table <- DT::renderDataTable({
req(input$search_query, search_results())
if ("title" %in% names(search_results())) {
if ("issued" %in% names(search_results())) {
search_dt <- search_results()[, c("title", "issued")]
} else {
search_dt <- search_results()[, c("title")]
}
} else {
search_dt <- data.frame(title = character(), issued = character())
}
DT::datatable(search_dt, selection = 'single', rownames = FALSE,
options = list(pageLength = 5, dom = 'tip'))
})
output$selected_item <- renderUI({
req(input$search_table_rows_selected)
selected_entry <- search_results()[input$search_table_rows_selected, ]
fillRow(
flex = c(8, 2), height = "120px",
tags$div(
style = "border: 1px solid #ddd; border-radius: 5px; padding: 5px; overflow-y: scroll; height: 120px; ",
h5(selected_entry$title),
tags$div(strong("Link: "),
tags$a(selected_entry$doi,
href = selected_entry$url,
target = "_blank")),
tags$div(
strong("Author(s): "),
ifelse(
is.null(selected_entry$author), "-",
paste0(paste0(selected_entry$author[[1]]$given, " ",
selected_entry$author[[1]]$family), collapse = ", ")
)
),
tags$div(strong("Journal/Container: "), selected_entry$container.title),
tags$div(strong("Issued: "), selected_entry$issued),
tags$div(strong("Type: "), selected_entry$type)
),
tags$div(
style = "margin-left: 5px;",
textInput(
"save_to",
label = "Save to",
width = "95%",
value = rv$ref_loc
),
actionButton(
"add_citations_article",
label = "Add to My Citations",
width = "95%",
class = "btn-primary"
)
)
)
})
observeEvent(input$add_citations_article, {
new_bib <- cr_cn(
dois = search_results()$doi[input$search_table_rows_selected]
)
if (is.null(new_bib)) {
updateActionButton(session, "add_citations_article",
label = "Something Wrong", icon = icon("times"))
} else {
if (!input$save_to %in% list.files()) {
file.create(input$save_to)
}
bib_file <- paste(readLines(input$save_to), collapse = " ")
new_bibentry <- cr_cn(
dois = search_results()$doi[input$search_table_rows_selected],
format = "bibentry"
)
if (check_bib(new_bibentry$doi, bib_file)) {
updateActionButton(session, "add_citations_article",
label = "Item Exist!", icon = icon("times"))
} else {
new_bib <- correct_bib(new_bib, new_bibentry$key, bib_file)
write(paste0(new_bib, "\n"), input$save_to, append = T)
updateActionButton(session, "add_citations_article",
label = "Added", icon = icon("check"))
}
}
})
# DOI panel
output$selected_item2 <- renderUI({
req(input$entered_dois)
if (substr(input$entered_dois, 1, 3) != "10.") return(NULL)
selected_entry <- cr_cn(dois = input$entered_dois,
format = "bibentry")
fillRow(
flex = c(8, 2), height = "120px",
tags$div(
style = "border: 1px solid #ddd; border-radius: 5px; padding: 5px; overflow-y: scroll; height: 120px; ",
h5(selected_entry$title),
tags$div(strong("Link: "),
tags$a(selected_entry$doi,
href = selected_entry$url,
target = "_blank")),
tags$div(
strong("Author(s): "),
ifelse(
is.null(selected_entry$author), "-",
selected_entry$author
)
),
tags$div(strong("Journal/Container: "),
ifelse(is.null(selected_entry$journal), "-",
selected_entry$journal)),
tags$div(strong("Year: "),
ifelse(is.null(selected_entry$year), "-",
selected_entry$year)),
tags$div(strong("Type: "),
ifelse(is.null(selected_entry$entry), "-",
selected_entry$entry))
),
tags$div(
style = "margin-left: 5px;",
textInput(
"save_to2",
label = "Save to",
width = "95%",
value = rv$ref_loc
),
actionButton(
"add_citations",
label = "Add to My Citations",
width = "95%",
class = "btn-primary"
)
)
)
})
observeEvent(input$add_citations, {
new_bib <- cr_cn(
dois = input$entered_dois
)
if (is.null(new_bib)) {
updateActionButton(session, "add_citations",
label = "Something Wrong", icon = icon("times"))
} else {
if (!input$save_to2 %in% list.files()) {
file.create(input$save_to2)
}
bib_file <- paste(readLines(input$save_to2), collapse = " ")
new_bibentry <- cr_cn(
dois = input$entered_dois,
format = "bibentry"
)
if (check_bib(new_bibentry$doi, bib_file)) {
updateActionButton(session, "add_citations",
label = "Item Exist!", icon = icon("times"))
} else {
new_bib <- correct_bib(new_bib, new_bibentry$key, bib_file)
write(paste0(new_bib, "\n"), input$save_to2, append = T)
updateActionButton(session, "add_citations",
label = "Added", icon = icon("check"))
}
}
})
observeEvent(input$save_to, {
writeLines(input$save_to, "~/.rc_addin")
rv$ref_loc <- input$save_to
})
observeEvent(input$save_to2, {
writeLines(input$save_to2, "~/.rc_addin")
rv$ref_loc <- input$save_to2
})
observeEvent(input$done, {
invisible(stopApp())
})
}
viewer <-
dialogViewer("Add Crossref Citations",
width = 800,
height = 600)
runGadget(ui, server, viewer = viewer)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.