Skip to content

Commit

Permalink
Merge pull request nstrayer#22 from nstrayer/more_flexible_templating
Browse files Browse the repository at this point in the history
More flexible templating + Tests
  • Loading branch information
Nick Strayer authored Jun 2, 2020
2 parents da8e985 + b5cb16d commit 9388a0e
Show file tree
Hide file tree
Showing 24 changed files with 964 additions and 143 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

.DS_Store

cv.Rmd
cv.rmd

dd_cv.css

Expand All @@ -16,5 +16,5 @@ cv_files/
cv.pdf

*_cache/
render_cv.R
render_cv.r
inst/doc
9 changes: 5 additions & 4 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,16 @@ Imports:
purrr,
stringr,
magrittr,
usethis,
pagedown,
fs,
icon (>= 0.1.0)
icon (>= 0.1.0),
whisker
RoxygenNote: 7.0.2
Roxygen: list(markdown = TRUE)
Suggests:
knitr,
rmarkdown
rmarkdown,
testthat (>= 2.1.0)
VignetteBuilder: knitr
Remotes:
Remotes:
ropenscilabs/icon
6 changes: 4 additions & 2 deletions R/build_network_logo.R
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ build_network_logo <- function(position_data){
b = purrr::flatten_int( purrr::map(rep_counts, ~{tail(1:n, .x)}) )
)
}

current_year <- lubridate::year(lubridate::ymd(Sys.Date()))
edges <- positions %>%
dplyr::select(id, start, end) %>%
dplyr::mutate(
end = ifelse(end == "Current", lubridate::year(lubridate::ymd(Sys.Date())), end),
end = ifelse(
tolower(end) == "Current" | is.na(end) | end == "N/A", current_year,
end),
start = ifelse(start == "N/A", end, start)
) %>%
purrr::pmap_dfr(function(id, start, end){
Expand Down
38 changes: 21 additions & 17 deletions R/use_csv_data_storage.R
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,36 @@
#' Sets up examples of the four CSVs needed for building CV
#'
#'
#' @param folder_name Name of the folder you want csvs stored in
#' @param folder_name Name of the folder you want csvs stored in relative to current working directory
#' @inheritParams use_ddcv_template
#'
#' @return A new folder `<folder_name>/` with `entries.csv`, `text_blocks.csv`, `language_skills.csv`, and `contact_info.csv` in it.
#' working directory.
#'
#' @examples
#'
#' \dontrun{
#' use_csv_data_storage(folder_name = "my_data")
#' }
#' # Make a temp directory for placing files
#' # This would be a real location for a typical situation
#' temp_dir <- fs::dir_create(fs::path(tempdir(), "cv_w_csvs"))
#'
#' datadrivencv::use_csv_data_storage(
#' folder_name = fs::path(temp_dir, "csv_data"),
#' create_output_dir = TRUE
#' )
#'
#' list.files(fs::path(temp_dir, "csv_data"))
#'
#' @export
use_csv_data_storage <- function(folder_name = "data"){
use_csv_data_storage <- function(folder_name = "data", create_output_dir = TRUE){

# Setup the folder for holding CSVs
data_folder <- fs::dir_create(folder_name)

copy_csv <- function(csv_name){
fs::file_copy(fs::path(system.file("templates/", package = "datadrivencv"), csv_name),
fs::path(data_folder, csv_name))
for(csv_file in c("entries.csv", "text_blocks.csv", "language_skills.csv","contact_info.csv" )){
use_ddcv_template(
file_name = csv_file,
output_dir = folder_name,
create_output_dir = create_output_dir,
warn_about_no_change = TRUE
)
}

copy_csv("entries.csv")
copy_csv("text_blocks.csv")
copy_csv("language_skills.csv")
copy_csv("contact_info.csv")

print(paste("Copied CSVs to ", data_folder))
print(paste("Copied CSVs to ", folder_name))
}
117 changes: 76 additions & 41 deletions R/use_datadriven_cv.R
Original file line number Diff line number Diff line change
Expand Up @@ -9,72 +9,107 @@
#' @param data_location Path of the spreadsheets holding all your data. This can
#' be either a URL to a google sheet with multiple sheets containing the four
#' data types or a path to a folder containing four `.csv`s with the neccesary
#' data. See \code{\link{use_csv_data_storage()}} for help setting up these `.csv`s.
#' data. See \code{\link{use_csv_data_storage()}} for help setting up these
#' `.csv`s.
#' @param pdf_location What location will the PDF of this CV be hosted at?
#' @param html_location What location will the HTML version of this CV be hosted
#' at?
#' @param source_location Where is the code to build your CV hosted?
#' @param open_files Should the added files be opened after creation?
#' @param which_files What files should be placed? Takes a vector of possible
#' values `c("cv.rmd", "dd_cv.css", "render_cv.r", "cv_printing_functions.r")`
#' or `"all"` for everything. This can be used to incrementally update the
#' printing functions or CSS without loosing customizations you've made to
#' other files.
#' @param output_dir Where should the files be placed? Defaults to your current working directory
#' @param use_network_logo Should logo be an interactive network based on your
#' CV data? Note that this uses the function
#' \code{\link{build_network_logo()}} so will introduce a dependency on this
#' package.
#' @inheritParams use_ddcv_template
#'
#' @return `cv.Rmd`, `dd_cv.css`, `render_cv.R`, and `CV_printing_functions.R` written to the current
#' working directory.
#' @return `cv.rmd`, `dd_cv.css`, `render_cv.r`, and `cv_printing_functions.r`
#' written to the current working directory.
#'
#' @examples
#'
#' \dontrun{
#' use_datadriven_cv(
#' full_name = "Nick Strayer",
#' data_location = "https://docs.google.com/spreadsheets/d/14MQICF2F8-vf8CKPF1m4lyGKO6_thG-4aSwat1e2TWc",
#' pdf_location = "https://github.com/nstrayer/cv/raw/master/strayer_cv.pdf",
#' html_location = "nickstrayer.me/cv/",
#' source_location = "https://github.com/nstrayer/cv"
#' )
#' }
#' # Make a temp directory for placing files
#' # This would be a real location for a typical situation
#' temp_dir <- fs::dir_create(fs::path(tempdir(), "my_cv"))
#'
#' use_datadriven_cv(
#' full_name = "Nick Strayer",
#' data_location = "https://docs.google.com/spreadsheets/d/14MQICF2F8-vf8CKPF1m4lyGKO6_thG-4aSwat1e2TWc",
#' pdf_location = "https://github.com/nstrayer/cv/raw/master/strayer_cv.pdf",
#' html_location = "nickstrayer.me/cv/",
#' source_location = "https://github.com/nstrayer/cv",
#' output_dir = temp_dir,
#' open_files = FALSE
#' )
#'
#' # Files should be where they were requested
#' list.files(temp_dir)
#'
#' @export
use_datadriven_cv <- function(full_name = "Sarah Arcos",
data_location = system.file("sample_data/", package = "datadrivencv"),
pdf_location = "https://github.com/nstrayer/cv/raw/master/strayer_cv.pdf",
html_location = "nickstrayer.me/datadrivencv/",
source_location = "https://github.com/nstrayer/datadrivencv",
which_files = "all",
output_dir = getwd(),
create_output_dir = FALSE,
use_network_logo = TRUE,
open_files = TRUE){

# Sets the main Rmd template
usethis::use_template(
template = "cv.Rmd",
package = "datadrivencv",
data = list(
full_name = full_name,
data_location = data_location,
pdf_location = pdf_location,
html_location = html_location,
source_location = source_location,
use_network_logo = use_network_logo
),
open = open_files
)
if(is.character(which_files) && which_files == "all"){
which_files <- c("cv.rmd", "dd_cv.css", "render_cv.r", "cv_printing_functions.r")
}
# Make case-insensitive
which_files <- tolower(which_files)

if("cv.rmd" %in% which_files){
# Sets the main Rmd template
use_ddcv_template(
file_name = "cv.rmd",
params = list(
full_name = full_name,
data_location = data_location,
pdf_location = pdf_location,
html_location = html_location,
source_location = source_location,
use_network_logo = use_network_logo
),
output_dir = output_dir,
create_output_dir = create_output_dir,
open_after_making = open_files
)
}

# Place the css as well
usethis::use_template(
template = "dd_cv.css",
package = "datadrivencv",
open = open_files
)
if("dd_cv.css" %in% which_files){
# Place the css as well
use_ddcv_template(
file_name = "dd_cv.css",
output_dir = output_dir,
create_output_dir
)
}

usethis::use_template(
template = "render_cv.R",
package = "datadrivencv",
open = open_files
)
if("render_cv.r" %in% which_files){
use_ddcv_template(
file_name = "render_cv.r",
output_dir = output_dir,
create_output_dir,
open_after_making = open_files
)
}

usethis::use_template(
template = "CV_printing_functions.R",
package = "datadrivencv"
)
if("cv_printing_functions.r" %in% which_files){
use_ddcv_template(
file_name = "cv_printing_functions.r",
output_dir = output_dir,
create_output_dir
)
}

}
60 changes: 60 additions & 0 deletions R/use_ddcv_template.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#' Use template file from package
#'
#' @param file_name Name of file from templates to use: e.g. `cv.rmd`.
#' @param params Parameters used to fill in `whisker` template
#' @param output_file_name Name of file after being placed.
#' @param output_dir Directory location for output to be placed in.
#' @param create_output_dir If the requested output directory is missing should it be created?
#' @param warn_about_no_change If there is no change between the new file and what was already there, should a warning be issued?
#' @param open_after_making Should the file be opened after it has been written?
#'
#' @return NULL
use_ddcv_template <- function(
file_name,
params = NULL,
output_file_name = file_name,
output_dir = getwd(),
create_output_dir = FALSE,
warn_about_no_change = TRUE,
open_after_making = FALSE){
output_dir_missing <- !fs::dir_exists(output_dir)

if(output_dir_missing & create_output_dir){
fs::dir_create(output_dir)
} else
if(output_dir_missing & !create_output_dir) {
stop(glue::glue("The requested output directory: {output_dir} doesn't exist. Either set create_output_dir = TRUE or manually make directory."))
}


template_loc <- fs::path(system.file("templates/", package = "datadrivencv"), file_name)
output_loc <- fs::path(output_dir, output_file_name)

template_text <- readr::read_file(template_loc)

if(!is.null(params)){
template_text <- whisker::whisker.render(template_text, data = params)
}

# Check if file exists already
already_exists <- fs::file_exists(output_loc)
if(already_exists){
# Check if the two files are identical
no_changes_made <- readr::read_file(output_loc) == template_text

if(no_changes_made & warn_about_no_change){
warning(glue::glue("{file_name} already exists and there are no differences with the current version."))
}
}

readr::write_file(template_text, output_loc)

# Open the file if requested
if(open_after_making){
if (rstudioapi::isAvailable() && rstudioapi::hasFun("navigateToFile")) {
rstudioapi::navigateToFile(output_loc)
} else {
utils::file.edit(output_loc)
}
}
}
16 changes: 8 additions & 8 deletions README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,10 @@ This code is all that's needed to setup a full CV. It outputs five files:

| File | Description |
| ---- | ---- |
|`cv.Rmd` | An RMarkdown file with various sections filled in. Edit this to fit your personal needs. |
|`cv.rmd` | An RMarkdown file with various sections filled in. Edit this to fit your personal needs. |
|`dd_cv.css` | A custom set of CSS styles that build on the default `Pagedown` "resume" template. Again, edit these as desired.|
| `render_cv.R` | Use this script to build your CV in both PDF and HTML at the same time. |
| `CV_printing_functions.R` | A series of functions that perform the dirty work of turning your spreadsheet data into markdown/html and making that output work for PDF printing. E.g. Replacing markdown links with superscripts and a links section, tweaking the CSS to account for chrome printing quirks, etc.. |
| `render_cv.r` | Use this script to build your CV in both PDF and HTML at the same time. |
| `cv_printing_functions.r` | A series of functions that perform the dirty work of turning your spreadsheet data into markdown/html and making that output work for PDF printing. E.g. Replacing markdown links with superscripts and a links section, tweaking the CSS to account for chrome printing quirks, etc.. |

# Storing your data in spreadsheets

Expand Down Expand Up @@ -154,19 +154,19 @@ The function `use_csv_data_storage()` will set these up for you.

# Rendering your CV

Now that you have the templates setup and you've configured your data, the last thing to do is render. The easiest way to do this is by opening `cv.Rmd` in RStudio and clicking the "Knit" button. This will render an HTML version of your CV. However, you most likely want a PDF version of your CV to go along with an HTML version. The easiest way to do this is to run the included script `render_cv.R`:
Now that you have the templates setup and you've configured your data, the last thing to do is render. The easiest way to do this is by opening `cv.rmd` in RStudio and clicking the "Knit" button. This will render an HTML version of your CV. However, you most likely want a PDF version of your CV to go along with an HTML version. The easiest way to do this is to run the included script `render_cv.r`:

### `render_cv.R`
### `render_cv.r`

```{r, eval = FALSE, echo = TRUE}
# Knit the HTML version
rmarkdown::render("cv.Rmd",
rmarkdown::render("cv.rmd",
params = list(pdf_mode = FALSE),
output_file = "cv.html")
# Knit the PDF version to temporary html location
tmp_html_cv_loc <- fs::file_temp(ext = ".html")
rmarkdown::render("cv.Rmd",
rmarkdown::render("cv.rmd",
params = list(pdf_mode = TRUE),
output_file = tmp_html_cv_loc)
Expand All @@ -182,7 +182,7 @@ embed_png("html_vs_pdf_output.png")



This script will render your CV in HTML and output it as `cv.html`, it will also turn on the `pdf_mode` parameter in `cv.Rmd`, which will strip the links out and place them at the end linked by inline superscripts. Once the pdf version is rendered to HTML, it will then turn that HTML into a PDF using `pagedown::chrome_print()`. By using this script you can easily make sure your get both versions rendered at the same time without having to manually go in and toggle the pdf mode parameter in the yaml header and then use the print dialog in your browser.
This script will render your CV in HTML and output it as `cv.html`, it will also turn on the `pdf_mode` parameter in `cv.rmd`, which will strip the links out and place them at the end linked by inline superscripts. Once the pdf version is rendered to HTML, it will then turn that HTML into a PDF using `pagedown::chrome_print()`. By using this script you can easily make sure your get both versions rendered at the same time without having to manually go in and toggle the pdf mode parameter in the yaml header and then use the print dialog in your browser.

# Questions?

Expand Down
Loading

0 comments on commit 9388a0e

Please sign in to comment.