#' Create the files for an Advent of Code day
#'
#' @param day integer giving the day
#' @param open whether to open the created files. Defaults to `TRUE` in an
#' interactive R session.
#' @return `use_day()` returns `NULL`. `convert_clipboard_html_to_roxygen_md()`
#' invisibly returns the Roxygen markdown block. It also copies Roxygen
#' markdown block onto the clipboard.
#' @rdname use_day
#'
#' @details
#'
#' Creates a file for writing the functions to solve the problem: `R/dayxx.R`.
#' The text of the challenge is downloaded and inserted into the roxygen block.
#' One caveat is that you will have to manually add the markdown text for Part
#' Two yourself. BYou can use `convert_clipboard_html_to_roxygen_md()` to make
#' this easier. Once you can read the description, view the page source, copy
#' the html for that part of the problem. Run this function to create a Roxygen
#' version of the HTML.
#'
#' Also, creates a placeholder file for the problem input: `inst/inputxx.txt`.
#' Paste your input here.
#'
#' Also, creates a file for unit tests: `tests/testthat/test-dayxx.R`. This is
#' good place to test that the examples in the problem description work.
#'
#' Finally, creates a solution file: `inst/run-dayxx.R`. You should download
#' your personalized challenge input as `inst/inputxx.txt`. Your solution file
#' should read in this file and apply your functions to it. Once your solution
#' passes on the site, store it in `R/data-solutions.R`. Then the solution file
#' can load in your previous answer, rerun your solution, and check whether your
#' code no longer obtains the same solution.
#' @export
use_day <- function(day, year = 2018, open = interactive()) {
url <- sprintf("https://adventofcode.com/%s/day/%s", year, day)
data <- list(
dd_number = sprintf("%02.f", day),
url = url,
title = NA,
part_1 = NA
)
files <- get_day_files(day)
test_name <- sprintf("day%s", data$dd_number)
page <- xml2::read_html(url)
article <- xml2::xml_find_first(page, "/html/body/main/article")
title <- xml2::xml_find_first(page, "/html/body/main/article/h2")
title <- unlist(xml2::as_list(title))
title <- stringr::str_replace(title, "--- Day \\d+: ", "")
title <- stringr::str_replace(title, " ---", "")
data$title <- title
temp <- tempfile(fileext = ".html")
xml2::write_html(article, temp)
z <- knitr::pandoc(temp, "markdown", encoding = "UTF-8")
lines <- readr::read_lines(z)
lines <- lines[-c(1, 2, 3)]
lines <- paste0("#' ", lines, collapse = "\n")
data$part_1 <- lines
usethis::use_template(
"day.R",
save_as = files$main,
package = "adventofcode18",
data = data,
open = open
)
todo("Write your solution code here")
todo(
"Once you unlock Part Two, update the Roxygen block with the description")
usethis::use_template(
"input.txt",
save_as = files$input,
package = "adventofcode18",
data = list(x = "\n"),
open = open
)
todo("Copy your problem input into this file")
usethis::use_test(
name = test_name
)
todo("Write unit tests using the examples from the problem description")
usethis::use_template(
"solution.R",
save_as = files$solution,
package = "adventofcode18",
data = data,
open = open
)
todo("Run your solution on the input here. Once it works, update R/data-solutions.R")
invisible(NULL)
}
#' @rdname use_day
#' @export
#' @param input html code copied from the Advent of Code website
convert_clipboard_html_to_roxygen_md <- function(input = clipr::read_clip()) {
temp <- tempfile(fileext = ".html")
writeLines(input, temp)
z <- knitr::pandoc(temp, "markdown", encoding = "UTF-8")
lines <- readr::read_lines(z)
lines <- paste0("#' ", lines, collapse = "\n")
clipr::write_clip(lines)
done("Roxygen markdown block is on the clipboard")
invisible(lines)
}
remove_day <- function(day) {
file.remove(unlist(get_day_files(day)))
}
get_day_files <- function(day) {
dd_number <- sprintf("%02.f", day)
list(
main = sprintf("R/day%s.R", dd_number),
solution = sprintf("inst/run-day%s.R", dd_number),
test = sprintf("tests/testthat/test-day%s.R", dd_number),
input = sprintf("inst/input%s.txt", dd_number)
)
}
# These are all copied from usethis in order to match that package's style
todo <- function(..., .envir = parent.frame()) {
out <- glue::glue(..., .envir = .envir)
cat_line(bulletize(out, bullet = todo_bullet()))
}
todo_bullet <- function () crayon::red(clisymbols::symbol$bullet)
done <- function (..., .envir = parent.frame()) {
out <- glue::glue(..., .envir = .envir)
cat_line(bulletize(out, bullet = done_bullet()))
}
done_bullet <- function () crayon::green(clisymbols::symbol$tick)
bulletize <- function(line, bullet = "*") {
paste0(bullet, " ", line)
}
cat_line <- function(..., quiet = getOption("usethis.quiet", default = FALSE)) {
if (quiet) return(invisible())
cat(..., "\n", sep = "")
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.