This repository has been archived by the owner on Dec 30, 2023. It is now read-only.
forked from nstrayer/cv
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request nstrayer#13 from nstrayer/cv_printer_class
Switched over to the new templates from datadrivencv pacakge
- Loading branch information
Showing
10 changed files
with
325 additions
and
31,120 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,255 @@ | ||
# This file contains all the code needed to parse and print various sections of your CV | ||
# from data. Feel free to tweak it as you desire! | ||
|
||
|
||
#' Create a CV_Printer object. | ||
#' | ||
#' @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. | ||
#' @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 pdf_mode Is the output being rendered into a pdf? Aka do links need | ||
#' to be stripped? | ||
#' @param sheet_is_publicly_readable If you're using google sheets for data, | ||
#' is the sheet publicly available? (Makes authorization easier.) | ||
#' @return A new `CV_Printer` object. | ||
create_CV_object <- function(data_location, | ||
pdf_mode = FALSE, | ||
html_location, | ||
pdf_location, | ||
sheet_is_publicly_readable = TRUE) { | ||
|
||
cv <- list( | ||
pdf_mode = pdf_mode, | ||
html_location = html_location, | ||
pdf_location = pdf_location, | ||
links = c() | ||
) | ||
|
||
is_google_sheets_location <- stringr::str_detect(data_location, "docs\\.google\\.com") | ||
|
||
if(is_google_sheets_location){ | ||
if(sheet_is_publicly_readable){ | ||
# This tells google sheets to not try and authenticate. Note that this will only | ||
# work if your sheet has sharing set to "anyone with link can view" | ||
googlesheets4::sheets_deauth() | ||
} else { | ||
# My info is in a public sheet so there's no need to do authentication but if you want | ||
# to use a private sheet, then this is the way you need to do it. | ||
# designate project-specific cache so we can render Rmd without problems | ||
options(gargle_oauth_cache = ".secrets") | ||
} | ||
|
||
cv$entries_data <- googlesheets4::read_sheet(data_location, sheet = "entries", skip = 1) %>% | ||
# Google sheets loves to turn columns into list ones if there are different types | ||
dplyr::mutate_if(is.list, purrr::map_chr, as.character) | ||
|
||
cv$skills <- googlesheets4::read_sheet(data_location, sheet = "language_skills", skip = 1) | ||
cv$text_blocks <- googlesheets4::read_sheet(data_location, sheet = "text_blocks", skip = 1) | ||
cv$contact_info <- googlesheets4::read_sheet(data_location, sheet = "contact_info", skip = 1) | ||
} else { | ||
# Want to go old-school with csvs? | ||
cv$entries_data <- readr::read_csv(paste0(data_location, "entries.csv")) | ||
cv$skills <- readr::read_csv(paste0(data_location, "language_skills.csv")) | ||
cv$text_blocks <- readr::read_csv(paste0(data_location, "text_blocks.csv")) | ||
cv$contact_info <- readr::read_csv(paste0(data_location, "contact_info.csv"), skip = 1) | ||
} | ||
|
||
|
||
# This year is assigned to the end date of "current" events to make sure they get sorted later. | ||
future_year <- lubridate::year(lubridate::ymd(Sys.Date())) + 10 | ||
|
||
# Clean up entries dataframe to format we need it for printing | ||
cv$entries_data %<>% | ||
tidyr::unite( | ||
tidyr::starts_with('description'), | ||
col = "description_bullets", | ||
sep = "\n- ", | ||
na.rm = TRUE | ||
) %>% | ||
dplyr::mutate( | ||
description_bullets = paste0("- ", description_bullets), | ||
end = ifelse(is.na(end), "Current", end), | ||
end_num = ifelse(tolower(end) %in% c("current", "now", ""), future_year, end), | ||
timeline = ifelse(is.na(start) | start == end, | ||
end, | ||
glue::glue('{end} - {start}')) | ||
) %>% | ||
dplyr::arrange(desc(end_num)) %>% | ||
dplyr::mutate_all(~ ifelse(is.na(.), 'N/A', .)) | ||
|
||
cv | ||
} | ||
|
||
|
||
# Remove links from a text block and add to internal list | ||
sanitize_links <- function(cv, text){ | ||
if(cv$pdf_mode){ | ||
link_titles <- stringr::str_extract_all(text, '(?<=\\[).+?(?=\\])')[[1]] | ||
link_destinations <- stringr::str_extract_all(text, '(?<=\\().+?(?=\\))')[[1]] | ||
|
||
n_links <- length(cv$links) | ||
n_new_links <- length(link_titles) | ||
|
||
if(n_new_links > 0){ | ||
# add links to links array | ||
cv$links <- c(cv$links, link_destinations) | ||
|
||
# Build map of link destination to superscript | ||
link_superscript_mappings <- purrr::set_names( | ||
paste0("<sup>", (1:n_new_links) + n_links, "</sup>"), | ||
paste0("(", link_destinations, ")") | ||
) | ||
|
||
# Replace the link destination and remove square brackets for title | ||
text <- text %>% | ||
stringr::str_replace_all(stringr::fixed(link_superscript_mappings)) %>% | ||
stringr::str_replace_all('\\[(.+?)\\]', "\\1") | ||
} | ||
} | ||
|
||
list(cv = cv, text = text) | ||
} | ||
|
||
|
||
#' @description Take a position data frame and the section id desired and prints the section to markdown. | ||
#' @param section_id ID of the entries section to be printed as encoded by the `section` column of the `entries` table | ||
print_section <- function(cv, section_id, glue_template = "default"){ | ||
|
||
if(glue_template == "default"){ | ||
glue_template <- " | ||
### {title} | ||
{loc} | ||
{institution} | ||
{timeline} | ||
{description_bullets} | ||
\n\n\n" | ||
} | ||
|
||
section_data <- dplyr::filter(cv$entries_data, section == section_id) | ||
|
||
# Take entire entries data frame and removes the links in descending order | ||
# so links for the same position are right next to each other in number. | ||
for(i in 1:nrow(section_data)){ | ||
for(col in c('title', 'description_bullets')){ | ||
strip_res <- sanitize_links(cv, section_data[i, col]) | ||
section_data[i, col] <- strip_res$text | ||
cv <- strip_res$cv | ||
} | ||
} | ||
|
||
print(glue::glue_data(section_data, glue_template)) | ||
|
||
invisible(strip_res$cv) | ||
} | ||
|
||
|
||
|
||
#' @description Prints out text block identified by a given label. | ||
#' @param label ID of the text block to print as encoded in `label` column of `text_blocks` table. | ||
print_text_block <- function(cv, label){ | ||
text_block <- dplyr::filter(cv$text_blocks, loc == label) %>% | ||
dplyr::pull(text) | ||
|
||
strip_res <- sanitize_links(cv, text_block) | ||
|
||
cat(strip_res$text) | ||
|
||
invisible(strip_res$cv) | ||
} | ||
|
||
|
||
|
||
#' @description Construct a bar chart of skills | ||
#' @param out_of The relative maximum for skills. Used to set what a fully filled in skill bar is. | ||
print_skill_bars <- function(cv, out_of = 5, bar_color = "#969696", bar_background = "#d9d9d9", glue_template = "default"){ | ||
|
||
if(glue_template == "default"){ | ||
glue_template <- " | ||
<div | ||
class = 'skill-bar' | ||
style = \"background:linear-gradient(to right, | ||
{bar_color} {width_percent}%, | ||
{bar_background} {width_percent}% 100%)\" | ||
>{skill}</div>" | ||
} | ||
cv$skills %>% | ||
dplyr::mutate(width_percent = round(100*level/out_of)) %>% | ||
glue::glue_data(glue_template) %>% | ||
print() | ||
|
||
invisible(cv) | ||
} | ||
|
||
|
||
|
||
#' @description List of all links in document labeled by their superscript integer. | ||
print_links <- function(cv) { | ||
n_links <- length(cv$links) | ||
if (n_links > 0) { | ||
cat(" | ||
Links {data-icon=link} | ||
-------------------------------------------------------------------------------- | ||
<br> | ||
") | ||
|
||
purrr::walk2(cv$links, 1:n_links, function(link, index) { | ||
print(glue::glue('{index}. {link}')) | ||
}) | ||
} | ||
|
||
invisible(cv) | ||
} | ||
|
||
|
||
|
||
#' @description Contact information section with icons | ||
print_contact_info <- function(cv){ | ||
glue::glue_data( | ||
cv$contact_info, | ||
"- <i class='fa fa-{icon}'></i> {contact}" | ||
) %>% print() | ||
|
||
invisible(cv) | ||
} | ||
|
||
|
||
|
||
#' @description Small addendum that links to pdf version of CV if currently HTML and HTML if currently PDF. | ||
print_link_to_other_format <- function(cv){ | ||
# When in export mode the little dots are unaligned, so fix that. | ||
if(cv$pdf_mode){ | ||
print(glue::glue("View this CV online with links at _{cv$html_location}_")) | ||
} else { | ||
print(glue::glue("[<i class='fas fa-download'></i> Download a PDF of this CV]({cv$pdf_location})")) | ||
} | ||
|
||
invisible(cv) | ||
} | ||
|
||
|
||
|
||
#' @description Appends some styles specific to PDF output. | ||
set_style <- function(cv){ | ||
# When in export mode the little dots are unaligned, so fix that. | ||
if(cv$pdf_mode) { | ||
cat(" | ||
<style> | ||
:root{ | ||
--decorator-outer-offset-left: -6.5px; | ||
} | ||
</style>") | ||
} | ||
|
||
invisible(cv) | ||
} |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.