Skip to content
Merged
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
18 changes: 9 additions & 9 deletions R/cran.R
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ find_exports_without_examples <- function(lines) {
line <- lines[i]

# Start of doc block
if (grepl("^#'", line)) {
if (grepl("^##?'", line)) {
if (!in_doc_block) {
in_doc_block <- TRUE
has_export <- FALSE
Expand All @@ -143,12 +143,12 @@ find_exports_without_examples <- function(lines) {
}

# Check for export tag
if (grepl("^#'\\s*@export", line)) {
if (grepl("^##?'\\s*@export", line)) {
has_export <- TRUE
}

# Check for examples tag
if (grepl("^#'\\s*@examples", line)) {
if (grepl("^##?'\\s*@examples", line)) {
has_examples <- TRUE
}
} else if (in_doc_block) {
Expand Down Expand Up @@ -183,14 +183,14 @@ find_dontrun_examples <- function(lines) {
for (i in seq_along(lines)) {
line <- lines[i]

if (grepl("^#'", line)) {
if (grepl("^##?'", line)) {
if (!in_doc_block) {
in_doc_block <- TRUE
has_export <- FALSE
has_dontrun <- FALSE
}

if (grepl("^#'\\s*@export", line)) {
if (grepl("^##?'\\s*@export", line)) {
has_export <- TRUE
}

Expand Down Expand Up @@ -226,25 +226,25 @@ find_long_example_lines <- function(lines, filename) {
for (i in seq_along(lines)) {
line <- lines[i]

if (!grepl("^#'", line)) {
if (!grepl("^##?'", line)) {
in_examples <- FALSE
next
}

if (grepl("^#'\\s*@examples", line)) {
if (grepl("^##?'\\s*@examples", line)) {
in_examples <- TRUE
next
}

# Other tags end the examples block
if (grepl("^#'\\s*@[a-zA-Z]", line)) {
if (grepl("^##?'\\s*@[a-zA-Z]", line)) {
in_examples <- FALSE
next
}

if (in_examples) {
# Strip the #' prefix to get the actual example content
content <- sub("^#'\\s?", "", line)
content <- sub("^##?'\\s?", "", line)
if (nchar(content) > 100) {
found <- c(found,
paste0(filename, ":", i, " (", nchar(content), " chars)"))
Expand Down
10 changes: 5 additions & 5 deletions R/parse.R
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ parse_file <- function(file) {
lines <- readLines(file, encoding = "UTF-8", warn = FALSE)

# Find documentation blocks (consecutive #' lines)
doc_lines <- grep("^#'", lines)
doc_lines <- grep("^##?'", lines)

if (length(doc_lines) == 0) {
return(list())
Expand Down Expand Up @@ -43,21 +43,21 @@ parse_file <- function(file) {
result <- list()

for (block_lines in blocks) {
# Extract the comment text (strip #' prefix)
comment_text <- sub("^#'\\s?", "", lines[block_lines])
# Extract the comment text (strip #' or ##' prefix)
comment_text <- sub("^##?'\\s?", "", lines[block_lines])

# Find the object definition after the block. Blank lines and plain
# comments between the block and its object are allowed; another #'
# line means this block is orphaned (its object was moved or deleted).
next_line <- max(block_lines) + 1

while (next_line <= length(lines) &&
!grepl("^\\s*#'", lines[next_line]) &&
!grepl("^\\s*##?'", lines[next_line]) &&
grepl("^\\s*(#|$)", lines[next_line])) {
next_line <- next_line + 1
}

if (next_line > length(lines) || grepl("^\\s*#'", lines[next_line])) {
if (next_line > length(lines) || grepl("^\\s*##?'", lines[next_line])) {
warning("Documentation block at ", basename(file), ":",
block_lines[1], " is not followed by an object ",
"definition; its tags are ignored.", call. = FALSE)
Expand Down
30 changes: 30 additions & 0 deletions inst/tinytest/test_parse.R
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,33 @@ expect_equal(length(big$formals$names), 30L)
expect_equal(big$formals$names[30], "a30")
expect_true(all(grepl("= NULL$", big$formals$usage)))
unlink(tmp)

# ESS-style ##' comments parse like #' (PR #27).
tmp <- tempfile(fileext = ".R")
writeLines(c(
"##' Add one",
"##' @param x A number.",
"##' @export",
"add_one <- function(x) x + 1"
), tmp)
blocks <- tinyrox:::parse_file(tmp)
expect_equal(length(blocks), 1)
expect_equal(blocks[[1]]$object, "add_one")
unlink(tmp)

# The orphaned-block detector must recognise ##' too, so a stray ##' block
# can't bleed into the next object (the #18 regression for double-hash).
tmp <- tempfile(fileext = ".R")
writeLines(c(
"##' Orphaned block (its object was moved away)",
"##' @export",
"",
"##' Real",
"##' @export",
"real_fn <- function() 1"
), tmp)
expect_warning(blocks <- tinyrox:::parse_file(tmp),
pattern = "not followed by an object definition")
expect_equal(length(blocks), 1)
expect_equal(blocks[[1]]$object, "real_fn")
unlink(tmp)
Loading