---
title: "Creating vitae templates"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Creating vitae templates}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
```

Résumé/CV templates are abundantly available in many varieties of themes and layouts. The `vitae` package provides a few of the more popular templates that are suitable for most resumes. The included templates are far from comprehensive - your favourite template may not be included, or perhaps you have created your own template. This vignette explains how your LaTeX CV can be used within the package using custom templates.

## Creating a vitae template

Extending `vitae` to support new templates involves a similar process to creating new `rmarkdown` document templates. An extended explanation for creating `rmarkdown` templates can be found in the [*Document Templates* chapter](https://bookdown.org/yihui/rmarkdown/document-templates.html) in ["R Markdown: The Definitive Guide"](https://bookdown.org/yihui/rmarkdown/).

Creating a template for vitae can be broken into three parts:
- Converting a CV into a Pandoc template
- Adding LaTeX macros for displaying CV entries
- Using the template with `rmarkdown`

### Converting a CV into a Pandoc template

Most elements that are included in the YAML header of an `rmarkdown` document are passed to your template via Pandoc variables. Pandoc variables can be included in your template file by surrounding the variable with `$`. These can be used to fill in basic CV details such as your name, occupation, and social links.

For example, suppose your document contains this YAML header:
```
name: "Mitchell O'Hara-Wild"
position: "vitae maintainer"
output: vitae::awesomecv
```

The `$name$` variable in the template would be substituted with `Mitchell O'Hara-Wild` and similarly, `$position$` would become `vitae maintainer`. Many templates won't follow this same structure exactly (some may split the name into first and last names), but most of the time there is a reasonable place for these variables. It is recommended that a consistent set of variables are used to make switching between templates easy.

The current list of variables used in the `vitae` templates are:

- name
- position
- address
- date
- profilepic
- www
- email
- twitter
- github
- linkedin
- aboutme
- headcolor

In the [moderncv template](https://github.com/xdanaux/moderncv), the position of 'vitae maintainer' is specified using `\position{vitae maintainer}`. Using Pandoc variables, this would be replaced with `\position{$position$}`, which allows the position to be defined in the `rmarkdown` document's YAML header.

However if a `position` has not been provided in the YAML header, this would leave us with `\position{}` (which might be okay for some templates, but is undesirable for most templates). To resolve this, we can use Pandoc to conditionally include this section with `$if(position)$\position{$position$}$endif$`.

The main content from an `rmarkdown` document is also included using Pandoc variables. The results from the main section of the document is stored in `$body$`. So in a typical LaTeX CV template, where there is usually pre-filled details about experience and employment, this can be completely replaced with `$body$`. There are a few other common variables to place within the template, which are typically placed in the same location as other templates. These variables include:

- body
- header-includes
- fontfamily
- fontfamilyoptions
- fontsize
- lang
- papersize
- classoption
- linestretch
- include-before
- include-after
- highlighting-macros

Placement of these variables can be found by looking at other template files provided in the package. The conversion of the moderncv template into a Pandoc template for `vitae` can be found on [GitHub](https://github.com/mitchelloharawild/vitae/blob/master/inst/rmarkdown/templates/moderncv/resources/moderncv.tex).

### Adding template specific code for displaying CV entries

The interface for producing entries in a CV varies greatly between templates. To support these various formats, template specific R functions are used to convert the `vitae` format of *what, when, with, where, and why* to output suitable for each template. These functions are specified using the `set_entry_formats()` function, which accepts output from `new_entry_formats()`.

The moderncv template provides many different layouts, of which I have selected the two that best suit `brief_entries` and `detailed_entries`.

#### brief_entries

The moderncv template `\cvitem` command generates an appropriate layout for brief entries. It expects inputs in this format:

```
\cvitem{Title}{Description}
```

An appropriate function for creating these items could be:

```r
moderncv_cv_entries <- new_entry_formats(
  brief = function(what, when, with){
    paste0(
      "\t\\cvitem{", when, "}{", what, ". ", with, "}",
      collapse = "\n"
    )
  },
  detailed = ... # See below
)
```

Note that `what`, `when` and `with` may contain more than one entry. This 
function combines each `\cvitem{}` into a single string by separating each entry
with a new line.

#### detailed_entries

For detailed CV entries, the moderncv `\cventry` command is appropriate. It expects inputs in this format:

```
\cventry{Year}{Degree}{Institution}{City}{Grade}{Description}
```

A function that can produce these entries is as follows:
```r
moderncv_cv_entries <- new_entry_formats(
  brief = ...,
  detailed = function(what, when, with, where, why){
    # Combine why inputs into a bullet list
    why <- lapply(why, function(x) {
      if(length(x) == 0) return("\\empty")
      paste(c(
        "\\begin{itemize}%",
        paste0("\\item ", x, "%"),
        "\\end{itemize}"
      ), collapse = "\n")
    })

    # Combine inputs into \cventry{} output
    paste0(
      paste0("\t\\cventry{", when, "}{", what, "}{", with, "}{", where, "}{}{", why, "}"),
      collapse = "\n"
    )
  }
)
```

### Using the template with rmarkdown

Once the Pandoc variables and LaTeX CV entry macros are set in the template, it is ready for use with the `vitae` package. The package provides the `cv_document` output format, which is suitable for use with custom templates. To use the custom template, your `rmarkdown` document's YAML header would look like this:

```
output:
  vitae::cv_document:
    template: my_custom_template.tex
```

You will also need to copy all of the LaTeX class (`.cls`) and style (`.sty`) files provided with the template into the same folder as your `rmarkdown` document. Once that is done, your new template should be ready to use with the `vitae` package.

## Contributing to the vitae package

If you've gone to the effort of successfully creating a new template with the `vitae` package, you may be interested in making it available for others to use. You can contribute to this package by submitting a pull request that adds your template to the package.

Adding your template to the package can be done with:

```{r add-template, eval = FALSE}
usethis::use_rmarkdown_template(
  template_name = "Curriculum Vitae (My custom format)",
  template_dir = "my_template",
  template_description = "The custom vitae template made by me!",
  template_create_dir = TRUE)
```

Then by navigating to the package's `inst/rmarkdown/templates/my_template` folder, you can add your Pandoc template to the `resources` folder, and your `.cls` and `.sty` files to the `skeleton` folder.

Once that is done, we can create a new `rmarkdown` output format that uses your template. These are added to the "R/formats.R" file, and will usually follow the same structure as other templates. The template argument to `cv_document` is a link to your Pandoc template in the package (accessed using `system.file`), and it is recommended that the supporting `.cls` and `.sty` files are copied using `copy_supporting_files`.

```{r}
#' @rdname cv_formats
#' @export
my_template <- function(...) {
  template <- system.file("rmarkdown", "templates", "my_template",
                          "resources", "my_template.tex", package="vitae")
  
  set_entry_formats(moderncv_cv_entries)
  copy_supporting_files("my_template")
  cv_document(..., template = template)
}
```

The automatically generated `skeleton.Rmd` document in the `skeleton` folder should be modified to be a basic example of using your template. Examples of this file can be found in other templates, and this template file can act as a useful test for your template!

All done! You should now be able to install your new version of the package with `devtools::install()`, and test out your new output format with:

```
output:
  vitae::my_template
```
