Skip to content

Commit

Permalink
chore: Spring clean for CRAN (#41)
Browse files Browse the repository at this point in the history
Linting and tidying
  • Loading branch information
csgillespie authored Jan 23, 2025
1 parent 16b692b commit 789d363
Show file tree
Hide file tree
Showing 20 changed files with 128 additions and 118 deletions.
1 change: 1 addition & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
^man-roxygen
^pkgdown$
^codecov\.yml$
^.lintr$
9 changes: 9 additions & 0 deletions .lintr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
linters: linters_with_defaults(
assignment_linter = NULL,
indentation_linter = NULL,
commented_code_linter = NULL,
object_length_linter = NULL,
line_length_linter(100),
cyclocomp_linter(complexity_limit = 15),
undesirable_operator_linter = undesirable_operator_linter(
op = list("<-" = "Please use '=' for assignment")))
54 changes: 18 additions & 36 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,41 +1,23 @@
Package: namer
Title: Names Your 'R Markdown' Chunks
Version: 0.1.8
Authors@R:
c(person(given = "Colin",
family = "Gillespie",
role = c("aut", "cre"),
email = "[email protected]"),
person(given = "Steph",
family = "Locke",
role = c("aut"),
email = "[email protected]"),
person(given = "Maëlle",
family = "Salmon",
role = "aut",
email = "[email protected]",
comment = c(ORCID = "0000-0002-2815-0399")),
person(given = "Ellis",
family = "Valentiner",
role = "ctb"),
person(given = "Charlie",
family = "Hadley",
role = "ctb",
comment = c(ORCID = "0000-0002-3039-6849")),
person(given = "Jumping Rivers",
role = "fnd",
comment = "https://jumpingrivers.com"),
person(given = "Han",
family = "Oostdijk",
role = "ctb",
comment = c(ORCID = "0000-0001-6710-4566")),
person(given = "Patrick",
family = "Schratz",
role = "ctb",
email = "[email protected]",
comment = c(ORCID = "0000-0003-0748-6624")))
Description: It names the 'R Markdown' chunks of files based on
the filename.
Version: 0.1.9
Authors@R: c(
person("Colin", "Gillespie", , "[email protected]", role = c("aut", "cre")),
person("Steph", "Locke", , "[email protected]", role = "aut"),
person("Maëlle", "Salmon", , "[email protected]", role = "aut",
comment = c(ORCID = "0000-0002-2815-0399")),
person("Ellis", "Valentiner", role = "ctb"),
person("Charlie", "Hadley", role = "ctb",
comment = c(ORCID = "0000-0002-3039-6849")),
person("Jumping Rivers", role = "fnd",
comment = "https://jumpingrivers.com"),
person("Han", "Oostdijk", role = "ctb",
comment = c(ORCID = "0000-0001-6710-4566")),
person("Patrick", "Schratz", , "[email protected]", role = "ctb",
comment = c(ORCID = "0000-0003-0748-6624"))
)
Description: It names the 'R Markdown' chunks of files based on the
filename.
License: MIT + file LICENSE
URL: https://github.com/jumpingrivers/namer,
https://jumpingrivers.github.io/namer/
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
YEAR: 2022
YEAR: 2025
COPYRIGHT HOLDER: namer authors
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# MIT License

Copyright (c) 2022 namer authors
Copyright (c) 2025 namer authors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
16 changes: 14 additions & 2 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
# namer 0.1.9 _2025-01-23_

* Allow to choose prefix for chunk names #2 (@statnmap, #30)
* New addins: (@statnmap, #30)
- Name current Rmd file
- Name file chosen in a directory
- Name chunks from a folder

# namer 0.1.8

* Update maintainer

# namer 0.1.7

* `name_dir_chunks()` now also names chunks in Quarto-Files. Note that Quarto chunks are labelled in the RMarkdown style (` ```{r mylabel} `), *not* in the Quarto style (see below):
* `name_dir_chunks()` now also names chunks in Quarto-Files.
Note that Quarto chunks are labelled in the RMarkdown style (` ```{r mylabel} `),
*not* in the Quarto style (see below):

````
```{r}
Expand All @@ -17,7 +27,9 @@

# namer 0.1.5

* `name_chunks()` and `name_dir_chunks()` are now able to unname all chunks before naming them. This ensures a consistent naming for all chunks instead of just labelling unnamed chunks (@pat-s, #23).
* `name_chunks()` and `name_dir_chunks()` are now able to unname all chunks before naming them.
This ensures a consistent naming for all chunks instead of
just labelling unnamed chunks (@pat-s, #23).

* new function `unname_dir_chunks()` that works in the same way as `name_dir_chunks()` (@pat-s, #23)

Expand Down
22 changes: 11 additions & 11 deletions R/name_chunks.R
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#' @title Name chunks in a single file
#'
#' @description Name unnamed chunks in a single file using the filename with extension stripped as basis.
#' @description Name unnamed chunks in a single file using the
#' filename with extension stripped as basis.
#'
#' @details When using namer, please check the edits
#' before pushing them to your code base. Such automatic
Expand All @@ -24,15 +25,15 @@
#' file.edit(temp_file_path)
#' }
#' file.remove(temp_file_path)
name_chunks <- function(path, unname = FALSE, prefix){
name_chunks <- function(path, unname = FALSE, prefix) {
# read the whole file
lines <- readLines(path)

# get chunk info
chunk_headers_info <- get_chunk_info(lines)

# early exit if no chunk
if(is.null(chunk_headers_info)){
if (is.null(chunk_headers_info)) {
return(invisible(TRUE))
}

Expand All @@ -48,9 +49,8 @@ name_chunks <- function(path, unname = FALSE, prefix){
# count unnamed chunks
no_unnamed <- length(unique(unnamed$index))


# act only if needed!
if(no_unnamed > 0){
if (no_unnamed > 0) {
if (missing(prefix)) {
# create new chunk names
filename <- fs::path_ext_remove(path)
Expand All @@ -68,7 +68,7 @@ name_chunks <- function(path, unname = FALSE, prefix){
existing_names <- unique(chunk_headers_info$name)
existing_names <- existing_names[!is.na(existing_names)]

if(any(new_chunk_names %in% existing_names)){
if (any(new_chunk_names %in% existing_names)) {
new_chunk_names[new_chunk_names %in% existing_names] <-
glue::glue("{new_chunk_names[new_chunk_names %in% existing_names]}-bis")
}
Expand All @@ -87,15 +87,15 @@ name_chunks <- function(path, unname = FALSE, prefix){

# re-get chunk names
new_chunk_headers_info <- get_chunk_info(lines)
if(length(unique(new_chunk_headers_info$name)) != nrow(new_chunk_headers_info)){
if (length(unique(new_chunk_headers_info$name)) != nrow(new_chunk_headers_info)) {
stop("Despite our efforts we'd be creating duplicate names.
Had you run our script on your R Markdown before?
Maybe namer::unname_chunks before running name_chunks.")
}

# save file
writeLines(lines, path)
}
}
return(invisible(TRUE))
}

Expand Down Expand Up @@ -128,7 +128,7 @@ Maybe namer::unname_chunks before running name_chunks.")
#' file.edit(file.path(temp_dir,
#' "examples", "example1.Rmd"))
#' }
name_dir_chunks <- function(dir, unname = FALSE){
name_dir_chunks = function(dir, unname = FALSE) {

if (isTRUE(unname)) {
cli::cat_rule("Unnaming all chunks")
Expand All @@ -137,13 +137,13 @@ name_dir_chunks <- function(dir, unname = FALSE){

cli::cat_rule("Naming all chunks")

rmds <- fs::dir_ls(dir, regexp = "*.[RrQq]md")
rmds = fs::dir_ls(dir, regexp = "*.[RrQq]md")
purrr::walk(rmds, chatty_name_chunks)

return(invisible(TRUE))
}

chatty_name_chunks <- function(path){
chatty_name_chunks = function(path) {
message(glue::glue("Scanning {path}..."))
name_chunks(path)
}
8 changes: 4 additions & 4 deletions R/name_chunks_addin.R
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
name_chunks_file_addin <- function(){
name_chunks_file_addin = function() {
name_chunks(path = rstudioapi::selectFile(filter = "R Markdown Files (*.Rmd)"))
}

name_chunks_addin <- function(){
prefix <- rstudioapi::showPrompt(title = "Chunk names prefix",
name_chunks_addin = function() {
prefix = rstudioapi::showPrompt(title = "Chunk names prefix",
message = "Leave empty to use filename (Default)", default = "")
if (prefix == "") {
name_chunks(path = rstudioapi::getActiveDocumentContext()$path)
Expand All @@ -12,6 +12,6 @@ name_chunks_addin <- function(){
}
}

name_chunks_directory_addin <- function(){
name_chunks_directory_addin = function() {
namer::name_dir_chunks(rstudioapi::selectDirectory())
}
14 changes: 7 additions & 7 deletions R/unname_chunks.R
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,18 @@ unname_chunks <- function(path, chunk_name_prefix = NULL) {
chunk_headers_info <- get_chunk_info(lines)

# early exit if no chunk
if(is.null(chunk_headers_info)){
if (is.null(chunk_headers_info)) {
return(invisible("TRUE"))
}

if ( is.null(chunk_name_prefix)){
if (is.null(chunk_name_prefix)) {
# preserve the setup label, delete the others
chunk_headers_info$name[chunk_headers_info$name != "setup"] <- ""
} else {
# preserve labels not starting with chunk_name_prefix
del_labels <- strtrim(chunk_headers_info$name,nchar(chunk_name_prefix)) %in%
del_labels <- strtrim(chunk_headers_info$name, nchar(chunk_name_prefix)) %in%
chunk_name_prefix
setup_label <- !(chunk_headers_info$name %in% 'setup')
setup_label <- !(chunk_headers_info$name %in% "setup")
del_labels <- del_labels & setup_label
chunk_headers_info$name[del_labels] <- ""
}
Expand Down Expand Up @@ -94,13 +94,13 @@ unname_chunks <- function(path, chunk_name_prefix = NULL) {
#' file.edit(file.path(temp_dir,
#' "examples", "example1.Rmd"))
#' }
unname_dir_chunks <- function(dir){
unname_dir_chunks <- function(dir) {
rmds <- fs::dir_ls(dir, regexp = "*.[Rr]md")
purrr::walk(rmds, chatty_unname_chunks)
return(invisible(TRUE))
}

chatty_unname_chunks <- function(path){
chatty_unname_chunks <- function(path) {
message(glue::glue("Scanning {path}..."))
unname_chunks(path)
}
Expand All @@ -111,5 +111,5 @@ chatty_unname_chunks <- function(path){
#' @export
unname_all_chunks <- function(path, chunk_name_prefix = NULL) {
warning("please use unname_chunks() instead of unname_all_chunks()", call. = FALSE)
unname_chunks(path,chunk_name_prefix = NULL)
unname_chunks(path, chunk_name_prefix = NULL)
}
32 changes: 15 additions & 17 deletions R/utils.R
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# not elegant, given a part of a header,
# transform it into the row of a tibble
transform_params <- function(params){
params_string <- try(eval(parse(text = paste('alist(', quote_label(params), ')'))),
transform_params <- function(params) {
params_string <- try(eval(parse(text = paste("alist(", quote_label(params), ")"))),
silent = TRUE)

if(inherits(params_string, "try-error")){
if (inherits(params_string, "try-error")) {
params <- sub(" ", ", ", params)
params_string <- eval(parse(text = paste('alist(', quote_label(params), ')')))
params_string <- eval(parse(text = paste("alist(", quote_label(params), ")")))
}

label <- parse_label(params_string[[1]])
Expand All @@ -16,23 +16,22 @@ transform_params <- function(params){
options = sub(params_string[[1]], "", params))
}


parse_label <- function(label){
parse_label <- function(label) {
language_name <- sub(" ", "\\/", label)
language_name <- unlist(strsplit(language_name, "\\/"))

if(length(language_name) == 1){
if (length(language_name) == 1) {
tibble::tibble(language = trimws(language_name[1]),
name = NA)
}else{
} else {
tibble::tibble(language = trimws(language_name[1]),
name = trimws(language_name[2]))
}
}

# from a chunk header
# to a tibble with language, name, option, option values
parse_chunk_header <- function(chunk_header){
parse_chunk_header <- function(chunk_header) {
# remove boundaries
chunk_header <- gsub("```\\{", "", chunk_header)
chunk_header <- gsub("\\}", "", chunk_header)
Expand All @@ -43,7 +42,7 @@ parse_chunk_header <- function(chunk_header){
}

digest_chunk_header <- function(chunk_header_index,
lines){
lines) {
# parse the chunk header
chunk_info <- parse_chunk_header(
lines[chunk_header_index])
Expand All @@ -57,7 +56,7 @@ digest_chunk_header <- function(chunk_header_index,

# helper to go from tibble with chunk info
# to header to write in R Markdown
re_write_headers <- function(info_df){
re_write_headers <- function(info_df) {
info_df %>%
dplyr::group_by(.data$index) %>%
dplyr::summarise(line = glue::glue("```{(language[1]) (name[1])(options)}",
Expand All @@ -69,12 +68,12 @@ re_write_headers <- function(info_df){
}

# helper to create a data.frame of chunk info
get_chunk_info <- function(lines){
get_chunk_info = function(lines) {
# find which lines are chunk starts
chunk_header_indices <- which(grepl("^```\\{[a-zA-Z0-9]", lines))
chunk_header_indices = which(grepl("^```\\{[a-zA-Z0-9]", lines))

# null if no chunks
if(length(chunk_header_indices) == 0){
if (length(chunk_header_indices) == 0L) {
return(NULL)
}
# parse these chunk headers
Expand All @@ -87,7 +86,7 @@ get_chunk_info <- function(lines){
# https://github.com/yihui/knitr/blob/2b3e617a700f6d236e22873cfff6cbc3568df568/R/parser.R#L148
# quote the chunk label if necessary
quote_label = function(x) {
x = gsub('^\\s*,?', '', x)
x = gsub("^\\s*,?", "", x)
if (grepl('^\\s*[^\'"](,|\\s*$)', x)) {
# <<a,b=1>>= ---> <<'a',b=1>>=
x = gsub('^\\s*([^\'"])(,|\\s*$)', "'\\1'\\2", x)
Expand All @@ -99,8 +98,7 @@ quote_label = function(x) {
}

# from knitr:::escape_latex()
clean_latex_special_characters <- function (x, newlines = FALSE, spaces = FALSE)
{
clean_latex_special_characters <- function(x, newlines = FALSE, spaces = FALSE) {
x <- gsub("\\\\", "-", x)
x <- gsub("([#$%&_{}])", "-", x)
x <- gsub("\\\\textbackslash", "-", x)
Expand Down
4 changes: 4 additions & 0 deletions README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,7 @@ remotes::install_github("jumpingrivers/namer")
## Code of Conduct

Please note that the namer project is released with a [Contributor Code of Conduct](https://jumpingrivers.github.io/namer/CODE_OF_CONDUCT.html). By contributing to this project, you agree to abide by its terms.

---

Maintained by [Jumping Rivers](https://www.jumpingrivers.com)
Loading

0 comments on commit 789d363

Please sign in to comment.