Skip to content

Commit 262d8b5

Browse files
committed
Support for search with regular expressions.
1 parent 1912808 commit 262d8b5

File tree

7 files changed

+198
-144
lines changed

7 files changed

+198
-144
lines changed

DESCRIPTION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Package: packagefinder
22
Type: Package
33
Title: Comfortable Search for R Packages on CRAN, Either Directly from the R Console or with an R Studio Add-in
4-
Version: 0.3.1
4+
Version: 0.3.2
55
Authors@R: person("Joachim", "Zuckarelli", role = c("aut", "cre"), email = "[email protected]", comment = c(ORCID = "0000-0002-9280-3016"))
66
Maintainer: Joachim Zuckarelli <[email protected]>
77
Description: Search for R packages on CRAN directly from the R console, based on the packages' titles, short and long descriptions, or other fields. Combine multiple keywords with logical operators ('and', 'or'), view detailed information on any package and keep track of the latest package contributions to CRAN. If you don't want to search from the R console, use the comfortable R Studio add-in.

NEWS.md

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,17 @@
1+
# packagefinder 0.3.2
2+
3+
## Minor changes
4+
5+
* `findPackage()` and the RStudio add-in now support search with regular expressions (new argument `query` in `findPackage()`)
6+
* Button to save options in the RStudio add-in added to ensure correct storing of add-in default values.
7+
8+
9+
110
# packagefinder 0.3.1
211

312
## Bug fix
413

5-
Bug fixed that prevented intallation of the package on certain Linux distributions.
14+
* Bug fixed that prevented installation of the package on certain Linux distributions.
615

716

817

R/addin.r

+103-94
Large diffs are not rendered by default.

R/addintools.r

+14-12
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ getPackageDetailsHTML <- function(df) {
3737
"Reverse imports",
3838
"Reverse suggests"
3939
)
40-
40+
4141
headers <- c(
4242
"Name",
4343
"Short description",
@@ -57,7 +57,7 @@ getPackageDetailsHTML <- function(df) {
5757
"Reverse imports",
5858
"Reverse suggests"
5959
)
60-
60+
6161
placeholders <- c(
6262
NA,
6363
NA,
@@ -118,7 +118,7 @@ getPackageDetailsHTML <- function(df) {
118118
NA,
119119
NA
120120
)
121-
121+
122122
html <- "<div style=\"background-color: #FCFAFA; padding-left: 20px\">"
123123
for(i in 1:NROW(fields)) {
124124
if(!is.na(df[1, fields[i]])) {
@@ -186,7 +186,8 @@ processSearch <- function(search = TRUE, input, package.list) {
186186
}
187187
mode <- tolower(input$rad_mode)
188188
terms <- scan(text = input$txt_search, what = "character")
189-
res <- findPackage(terms, silent = TRUE, return.df = TRUE, mode = mode, case.sensitive = case.sensitive, always.sensitive = always.sensitive, index = getOption("packagefinder.index", NULL))
189+
if(!input$chk_regex) res <- findPackage(terms, silent = TRUE, return.df = TRUE, mode = mode, case.sensitive = case.sensitive, always.sensitive = always.sensitive, index = getOption("packagefinder.index", NULL))
190+
else res <- findPackage(query=terms, silent = TRUE, return.df = TRUE, mode = mode, case.sensitive = case.sensitive, always.sensitive = always.sensitive, index = getOption("packagefinder.index", NULL))
190191
}
191192
}
192193
}
@@ -202,7 +203,7 @@ processSearch <- function(search = TRUE, input, package.list) {
202203
}
203204
if(!is.null(res)) {
204205
num.results <- NROW(res)
205-
206+
206207
res[,"Long Description"] <- NULL
207208
orig.name <- res$Name
208209
res$GO <- NULL
@@ -226,7 +227,7 @@ processSearch <- function(search = TRUE, input, package.list) {
226227
}
227228
}
228229
}
229-
230+
230231
for(i in 1:NROW(res)) {
231232
if(orig.name[i] %in% inst[,"Package"]) {
232233
res$Installed[i] = "Installed"
@@ -235,19 +236,19 @@ processSearch <- function(search = TRUE, input, package.list) {
235236
res$Installed[i] <- paste0("<img src=\"https://www.zuckarelli.de/files/download-col.png\" style=\"height:32px\"
236237
title = \"Install package '", orig.name[i] , "' (with dependencies)\"/>")
237238
}
238-
239+
239240
res$ActionPDF[i] <- buildLink(
240241
link.url = paste0("https://cran.r-project.org/web/packages/", res$Name[i], "\\", res$Name[i], ".PDF"),
241242
image.url = "https://www.zuckarelli.de/files/PDF-col.png",
242243
tooltip = paste0("PDF manual of package '", res$Name[i], "'")
243244
)
244-
245+
245246
res$ActionWeb[i] <- buildLink(
246247
link.url = paste0("https://cran.r-project.org/web/", res$Name[i]),
247248
image.url = "https://www.zuckarelli.de/files/r-col.png",
248249
tooltip = paste0("CRAN website of package '", res$Name[i], "'")
249250
)
250-
251+
251252
github.url <- df_ext$GitHub[which(df_ext$Package == res$Name[i])]
252253
if(!is.na(github.url)) {
253254
res$ActionGitHub[i] <- buildLink(
@@ -260,13 +261,13 @@ processSearch <- function(search = TRUE, input, package.list) {
260261
res$ActionGitHub[i] <- ""
261262
}
262263
}
263-
264+
264265
res$Name = paste0("<span style=\"font-weight:bold\">", res$Name, "</span>")
265266
}
266267
else {
267268
num.results <- 0
268269
}
269-
270+
270271
return(list(df = res, df_ext = df_ext, num.results = num.results))
271272
}
272273

@@ -288,6 +289,7 @@ getPackageFinderCode <- function(input, search = TRUE, cran.days = 3) {
288289
terms <- scan(text = input$txt_search, what = "character")
289290
if(NROW(terms) > 1) terms <- paste0("c(", paste0(paste0("\"", terms, "\""), collapse = ", "), ")")
290291
else terms <- paste0("\"", terms, "\"")
292+
if(input$chk_regex) terms <- paste0("query = ", terms)
291293
code <- paste0("findPackage(", terms, mode, case.sensitive, always.sensitive, ")")
292294
}
293295
else {
@@ -314,4 +316,4 @@ waitUI <- function(code) {
314316
</table><p id='p1'>&nbsp;</p><p id='p2'>&nbsp;</p>"))
315317
),
316318
))
317-
}
319+
}

R/htmltools.r

+16-14
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,12 @@ html.viewHTML <- function() {
2626

2727

2828
html.header <- function() {
29-
func.call <- deparse(getOption("packagefinder.call", ""))
30-
call.info <- paste0("<form>Original call: <input type=\"text\" readonly size=", round(nchar(func.call)*1.5,0)," style=\"border:0px;font-family:'Cutive Mono';font-size:17px\" value='", func.call,"' id=\"code\"><br><input type=\"button\" value=\"Copy to clipboard\" class=\"button\" onclick=\"var copyText=document.getElementById('code');copyText.select(); document.execCommand('copy')\"></form>")
31-
keywords.info <- paste(paste0("<span style=\"font-weight:bold;\">", getOption("packagefinder.keywords", ""), "</span>"), collapse=paste0(" <span style=\"color:#cfcfcf;\">", getOption("packagefinder.mode", ""), "</span> "))
32-
html.code <- paste0("
29+
func.call <- deparse(getOption("packagefinder.call", ""))
30+
call.info <- paste0("<form>Original call: <input type=\"text\" readonly size=", round(nchar(func.call)*1.5,0)," style=\"border:0px;font-family:'Cutive Mono';font-size:17px\" value='", func.call,"' id=\"code\"><br><input type=\"button\" value=\"Copy to clipboard\" class=\"button\" onclick=\"var copyText=document.getElementById('code');copyText.select(); document.execCommand('copy')\"></form>")
31+
keywords.info <- paste(paste0("<span style=\"font-weight:bold;\">", getOption("packagefinder.keywords", ""), "</span>"), collapse=paste0(" <span style=\"color:#cfcfcf;\">", getOption("packagefinder.mode", ""), "</span> "))
32+
if(getOption("packagefinder.searchtype", "") == "query") searchtype <- " (regular expression)"
33+
else searchtype <- " (keywords)"
34+
html.code <- paste0("
3335
<table>
3436
<tr>
3537
<td style=\"width:20%\">
@@ -38,7 +40,7 @@ html.header <- function() {
3840
<td style=\"padding-left:20px; width:80%\">
3941
<p style=\"font-size:36px;\">Search Results</p>
4042
<p>", call.info, "</p>
41-
<p>Search query: ", keywords.info, "</p>
43+
<p>Search", searchtype, ": ", keywords.info, "</p>
4244
<p><span style=\"font-weight:bold\">", getOption("packagefinder.num.results", "") ,"</span> of <span style=\"font-weight:bold\">", getOption("packagefinder.num.cran", ""), "</span> CRAN packages found in <span style=\"font-weight:bold\">", getOption("packagefinder.timediff", ""), "</span> seconds.</p>
4345
</td>
4446
</tr>
@@ -58,7 +60,7 @@ html.colorscore <- function(scores) {
5860
red <- format(as.hexmode(255-round(255 * scores/100,0)), width=2)
5961
green <- format(as.hexmode(255), width=2)
6062
blue <- format(as.hexmode(255-round(255 * scores/100,0)), width=2)
61-
63+
6264
return(paste0("#", red, green, blue))
6365
}
6466

@@ -76,9 +78,9 @@ html.formatdf <- function(df) {
7678
keywords <- getOption("packagefinder.keywords", NULL)
7779
df[,"Long Description"] <- textutils::HTMLencode(df[,"Long Description"])
7880
df[,NCOL(df)] <- NULL # Cut-off GO number
79-
# df[, "Score"] <- paste0(format(df[, "Score"], nsmall=1), "<span style=\"padding-left:10px; color:", html.colorscore(df[, "Score"]),"\">", html.getbar(df[, "Score"]), "</span>")
81+
# df[, "Score"] <- paste0(format(df[, "Score"], nsmall=1), "<span style=\"padding-left:10px; color:", html.colorscore(df[, "Score"]),"\">", html.getbar(df[, "Score"]), "</span>")
8082
df[, "Score"] <- paste0(format(df[, "Score"], nsmall=1), "<span style=\"padding-left:10px; color:#1ddb1d\">", html.getbar(df[, "Score"]), "</span>")
81-
83+
8284
if("Total Downloads" %in% colnames(df)) df[,"Total Downloads"] <- NULL
8385
df[,"Total Downloads"] <- paste0("<img src=\"https://cranlogs.r-pkg.org/badges/grand-total/", df$Name,"\"/>")
8486
linkspart.manual <- paste0("<a target=\"_blank\" href=\"https://cran.r-project.org/web/packages/", df$Name, "/", df$Name, ".pdf\"><img style=\"align-vertical:middle; padding-right:5px; width:28px\" src=\"http://www.zuckarelli.de/files/pdf-col.png\" /></a>")
@@ -87,13 +89,13 @@ html.formatdf <- function(df) {
8789
df$Links <- paste0("<div>", linkspart.manual, linkspart.cranpage, linkspart.google, "</div>")
8890
df[,"Install code"] <- paste0("<form> <input type=\"button\" class=\"button\" value=\"Copy\" onclick=\"var copyText=document.getElementById('install_",df$Name,"');copyText.select(); document.execCommand('copy')\"><input type \"text\" style=\"position: relative; left: -10000px;\" id=\"install_", df$Name,"\" value=\'install.packages(\"",df$Name,"\", dependencies = TRUE)'></form>")
8991
df$Name <- paste0("<a href=\"https://cran.r-project.org/package=", df$Name, "\">", df$Name, "</a>")
90-
92+
9193
for(i in 1:NROW(keywords)) {
9294
df$Name <- gsub(paste0("(.*^=",keywords[i],")"), "<span style=\"background-color:#e6f1ff\">\\1</span>", df$Name, ignore.case = TRUE, perl=TRUE)
9395
df[,"Short Description"] <- gsub(paste0("(",keywords[i],")"), "<span style=\"background-color:#e6f1ff\">\\1</span>", df[,"Short Description"], ignore.case = TRUE, perl=TRUE)
9496
df[,"Long Description"] <- gsub(paste0("(",keywords[i],")"), "<span style=\"background-color:#e6f1ff\">\\1</span>", df[,"Long Description"], ignore.case = TRUE, perl=TRUE)
9597
}
96-
98+
9799
css.cols <- rep("", NCOL(df))
98100
css.cols[1] <- "border-bottom:1pt solid #d1d1d1; padding: 7px; vertical-align:top"
99101
css.cols[2] <- "border-bottom:1pt solid #d1d1d1; padding: 7px; width:8%; vertical-align:top"
@@ -102,7 +104,7 @@ html.formatdf <- function(df) {
102104
css.cols[5] <- "border-bottom:1pt solid #d1d1d1; padding: 7px; vertical-align:top; text-align:center"
103105
css.cols[6] <- "border-bottom:1pt solid #d1d1d1; padding: 7px; width:10%; vertical-align:top; text-align:center"
104106
css.cols[7] <- "border-bottom:1pt solid #d1d1d1; padding: 7px; vertical-align:top; text-align:center"
105-
107+
106108
html.code <- htmlTable::htmlTable(
107109
df,
108110
align = paste0(c(rep("l", NCOL(df)-2),"c", "c")),
@@ -130,8 +132,8 @@ html.buildDoc <-function(body.html) {
130132
</style>
131133
</head>
132134
<body style=\"font-family:'Hind Madurai'; color:#494949; backgroundcolor:#FFFFFF;\">",
133-
body.html,
134-
"</body>
135+
body.html,
136+
"</body>
135137
<html>")
136138
return(html.code)
137-
}
139+
}

0 commit comments

Comments
 (0)