Skip to content
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
7 changes: 7 additions & 0 deletions .github/workflows/R-CMD-check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,13 @@ jobs:
actions: read

steps:
- name: Start HTML validation server
run: |
docker run --rm -p 8888:8888 -d ghcr.io/validator/validator:latest &&
echo "W3C_MARKUP_VALIDATOR_BASEURL=http://0.0.0.0:8888" >> "$GITHUB_ENV"
if: runner.os == 'Linux'
shell: bash

- uses: actions/checkout@v4

- uses: r-lib/actions/setup-r@v2
Expand Down
1 change: 1 addition & 0 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ Suggests:
downlit (>= 0.4.0),
htmlwidgets,
jsonlite,
curl,
rstudioapi,
miniUI,
rsconnect (>= 0.4.3),
Expand Down
2 changes: 1 addition & 1 deletion R/html.R
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ split_chapters = function(
# Need to take care of the div tags here before restore_part_html and
# restore_appendix_html erase the section ids of the hidden PART or APPENDIX
# sections.
if (split_level > 1) {
if (FALSE) {
body = x[(i5 + 1):(i6 - 1)]
h1 = grep('^<div (id="[^"]+" )?class="section level1("| )', body) + i5
h2 = grep('^<div (id="[^"]+" )?class="section level2("| )', body) + i5
Expand Down
8 changes: 7 additions & 1 deletion tests/rmd/split-section.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,16 @@ See chapter 2 now at \@ref(section-2)

# Section 2

## subsection 2 {#sub2}
## subsection 21 {#sub2}

```{r iris-plot, fig.cap = "A plot"}
plot(iris)
```

See figure \@ref(fig:iris-plot)

# subsection 22

# Section 3

## subsection 3
16 changes: 15 additions & 1 deletion tests/test-rmd.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
source('./testthat/helper-validate_html.R')
# only run this when NOT_CRAN is true (e.g., on Travis CI)
if (Sys.getenv('NOT_CRAN') == 'true') local({
all_files = function() {
Expand All @@ -9,10 +10,23 @@ if (Sys.getenv('NOT_CRAN') == 'true') local({
for (f in list.files('rmd', '[.]Rmd$', full.names = TRUE)) {
rmarkdown::render(f, envir = globalenv(), quiet = TRUE)
}

html_issues = simplify_html_validation(
validate_html(list.files("rmd", ".html$", full.names = TRUE))
)
if(nrow(html_issues) > 0)
stop(nrow(html_issues),
" HTML issues detected:\n ",
paste(html_issues$file, html_issues$messages, sep = ': ', collapse = '\n '))

# split by section works correctly
## id is used for html file name
sections_files = c("section-1.html", "subsection-1.html", "section-2.html", "sub2.html")
sections_files = c(
"section-1.html", "subsection-1.html",
"section-2.html", "sub2.html", "subsection-22.html",
"section-3.html", "subsection-3.html"
)

if (any(!file.exists(file.path("rmd", sections_files))))
stop("Failed to generate sections files")
## reference is working correctly (see #787)
Expand Down
39 changes: 39 additions & 0 deletions tests/testthat/helper-validate_html.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
validate_html <- function(
files,
# using same env variable old package to keep some compatibility
base_url = Sys.getenv('W3C_MARKUP_VALIDATOR_BASEURL')
) {
if(base_url == '' || length(files) == 0) return(NULL)
lapply(files, function(file) {
h <- curl::new_handle()
curl::handle_setform(handle = h, out = 'json', file = curl::form_file(file, "text/html"))
jsonlite::fromJSON(rawToChar(
curl::curl_fetch_memory(base_url, h)$content
))
})
}

simplify_html_validation <- function(results) {
if(is.null(results) || length(results) == 0) return(
data.frame(file=character(0), messages=character(0))
)
expected_errors <- c(
"Attribute “number” not allowed on element “div” at this point.",
"CSS: “border-top”: “solid\\9” is not a “color” value.",
"CSS: “border-bottom”: “solid\\9” is not a “color” value."

)
do.call(rbind, lapply(results,
function(result) {
if(is.null(result)) return(
data.frame(file=character(0), messages=character(0))
)
messages <- result$messages$message[result$messages$type == 'error']
messages <- messages[!messages %in% expected_errors]
data.frame(
file = if (length(messages) > 0) result$url else character(0),
messages = messages
)
}
))
}
Loading