02 - Authoring Quarto

Quarto, anatomy

  1. Metadata: YAML

  2. Text: Markdown

  3. Code: knitr or jupyter

Add it all together, and you have beautiful, powerful, and useful outputs!

Literate programming

Literate programming is writing out the program logic in a human language with included (separated by a primitive markup) code snippets and macros. - Wikipedia

---
title: "ggplot2 demo"
date: "5/22/2021"
format: html
---

## Air Quality

There is a relationship between temperature and the ozone level.

```{r}
#| label: fig-airquality
library(ggplot2)
ggplot(airquality, aes(Temp, Ozone)) + 
  geom_point() + 
  geom_smooth(method = "loess"
)
```

1 Metadata

Metadata: YAML

“Yet Another Markup Language” or “YAML Ain’t Markup Language”

---
key: value
---

Output Options

---
format: something
---
---
format: html
---
---
format: pdf
---
---
format: revealjs
---

Then add option arguments!

---
format: 
  html:
    toc: true
    code-fold: true
---

Sub-options should be below the main format output and spacing matters!

---
format: 
  html:
    option1: text
    option2: logical
---

YAML for format: html

YAML is sensitive

---
format:html # invalid, no space between
---

---
format: # invalid, read as missing
html
---

---
format: 
  html: # valid but needs next object
---

Valid YAML can look a bit differently based on what all is needed

format: html # valid - there's a space

format:
  html # valid - there's 2x spaces on a new line and no trailing :

# valid - format = HTML with selections made
format: 
  html:
    toc: true

Why YAML?

To avoid manually typing out all the options, every time!

quarto render document.qmd --to html


quarto render document.qmd --to html -M code-fold:true


quarto render document.qmd --to html -M code-fold:true -P alpha:0.2 -P ratio:0.3

Demo: Navigating within RStudio

Quarto workflow

Executing the Quarto Render button in RStudio will call Quarto render in a background job - this will prevent Quarto rendering from cluttering up the R console, and gives you and easy way to stop.

Rendering

  1. Render in RStudio, starts a background job and previews the output
  1. System shell via quarto render
quarto render document.qmd # defaults to html
quarto render document.qmd --to pdf
quarto render document.qmd --to docx
  • Renders via terminal
  1. R console via quarto R package
library(quarto)
quarto_render("document.qmd") # defaults to html
quarto_render("document.qmd", output_format = "pdf")

Our Turn

  • Open RStudio and materials/workshop/visual-editor.qmd
  • Compare behavior of rendering from RStudio > Render, using the CLI with quarto render, and in R console via quarto::quarto_render()
02:00

Quarto linting

Lint, or a linter, is a static code analysis tool used to flag programming errors, bugs, stylistic errors and suspicious constructs. - Lint

Quarto YAML Intelligence

RStudio + VSCode provide rich tab-completion - start a word and tab to complete, or Ctrl + space to see all available options.

Your Turn

  • Open a new Quarto document in RStudio
  • Try Ctrl + space to see the available YAML options
  • Try out the tab-completion of any options you remember
02:00

HTML options

quarto.org/docs/reference/formats/html

You can use the HTML reference if needed.

Text & Markdown

Lists

Markdown Syntax Output
* unordered list
    + sub-item 1
    + sub-item 2
        - sub-sub-item 1
  • unordered list

    • sub-item 1

    • sub-item 2

      • sub-sub-item 1
*   item 2

    Continued (indent 4 spaces)
  • item 2

    Continued (indent 4 spaces)

1. ordered list
2. item 2
    i) sub-item 1
         A.  sub-sub-item 1
  1. ordered list

  2. item 2

    1. sub-item 1

      1. sub-sub-item 1
(@)  A list whose numbering

continues after

(@)  an interruption
  1. A list whose numbering

continues after

  1. an interruption
term
: definition
term

definition

Text Formatting

Markdown Syntax Output
*italics* and **bold**
italics and bold
superscript^2^ / subscript~2~
superscript2 / subscript2
~~strikethrough~~
strikethrough
`verbatim code`
verbatim code

Headings

Markdown Syntax Output
# Header 1

Header 1

## Header 2

Header 2

### Header 3

Header 3

#### Header 4

Header 4

##### Header 5
Header 5
###### Header 6
Header 6

Tables

| Right | Left | Default | Center |
|------:|:-----|---------|:------:|
|   12  |  12  |    12   |    12  |
|  123  |  123 |   123   |   123  |
|    1  |    1 |     1   |     1  |
Right Left Default Center
12 12 12 12
123 123 123 123
1 1 1 1

Our Turn

  • Open materials/workshop/02-authoring/markdown-syntax.qmd
  • Explore, add to it, try out new syntax, discuss with your neighbor
03:00

Grid tables

+---------------+---------------+--------------------+
| Fruit         | Price         | Advantages         |
+===============+===============+====================+
| Bananas       | $1.34         | - built-in wrapper |
|               |               | - bright color     |
+---------------+---------------+--------------------+
| Oranges       | $2.10         | - cures scurvy     |
|               |               | - tasty            |
+---------------+---------------+--------------------+

: Sample grid table.
Sample grid table.
Fruit Price Advantages
Bananas $1.34
  • built-in wrapper
  • bright color
Oranges $2.10
  • cures scurvy
  • tasty

Grid table, alignment

Alignments can be specified as with pipe tables, by putting colons at the boundaries of the separator line after the header:

+---------------+---------------+--------------------+
| Right         | Left          | Centered           |
+==============:+:==============+:==================:+
| Bananas       | $1.34         | built-in wrapper   |
+---------------+---------------+--------------------+

For headerless tables, the colons go on the top line instead:

+--------------:+:--------------+:------------------:+
| Right         | Left          | Centered           |
+---------------+---------------+--------------------+

Note that grid tables are quite awkward to write with a plain text editor (because unlike pipe tables, the column indicators must align). The RStudio IDE’s Quarto Visual Editor can assist in making these tables.

Tables from code

knitr itself can turn R dataframes into tables with knitr::kable()

A very simple table generator, and it is simple by design. It is not intended to replace any other R packages for making tables. . . .

head(mtcars) |> 
  knitr::kable()
mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1

Quotes

Let us change our traditional attitude to the construction of programs: Instead of imagining that our main task is to instruct a computer what to do, let us concentrate rather on explaining to human beings what we want a computer to do. - Donald Knuth, Literate Programming 1

> Let us change our traditional attitude to the construction of programs: Instead of imagining that our main task is to instruct a computer what to do, let us concentrate rather on explaining to human beings what we want a computer to do. - Donald Knuth, Literate Programming

I like dogs
And I like cats

> I like dogs
> And I like cats

Code

Anatomy of a code chunk

```{r}
#| label: car-stuff
#| echo: false
mtcars %>% 
  distinct(cyl)
```
  • Has 3x backticks on each end ```
  • Indicate engine (r) between curly braces {r}
  • Place options underneath, behind the #| (hashpipe): #| option1: value

Code

The way you treat code is very different for different contexts

In a teaching scenario like today, I really want to display code

In a business, you may want to have a data-science facing output which displays the source code AND a stakeholder-facing output which hides the code

Code

If you simply want code highlighting, you can use 3x backticks + the language ```r

```r
head(mtcars)
```


Which returns the below but is not executed since there aren’t {} around the language:

head(mtcars)

If you instead want to see source code and evaluate it, you could use echo: true where echo: false would instead hide the code but still evaluate it.

```{r}
#| echo: true
1 + 1
```


1 + 1
[1] 2

Code

In some scenarios you want to both execute the code and return the FULL code including backticks, like today where I’m teaching! echo: fenced is a great option for this.

```{r}
#| echo: fenced
1 + 1
```


```{r}
1 + 1
```
[1] 2

Code

If you want to, you may return purely decorative code which is not executed

````
```{{r}}
1 + 1
```
````

Rendered as the below and not evaluated:

```{r}
1 + 1
```

The general rule here is that if you want to return code verbatim, you need to have at least N + 1 on the backticks. So for a normal 3x backtick chunk… you’ll need?

Divs and Spans

Pandoc and therefore Quarto can parse “fenced Div blocks”

::: {.border}
This content can be styled with a border
:::

This content can be styled with a border

This is text with [special]{style="color:red;"} formatting.

This is text with special formatting.

You’re not limited to HTML/CSS concepts - Pandoc and Quarto also have “attributes” that can be assigned in this way.

Divs and Spans

  • You can think of a ::: div as a HTML <div> but it can also apply in specific situations to content in PDF
  • Similarly, [text]{.class} spans can be thought of a <span .class>Text</span> but again are a bit more transferable if using Pandoc/Quarto native attributes.

The following, if specifying a Quarto class can often apply between formats.

::: {.unnumbered .unlisted}
Text
:::

While the following is hard-coded as HTML.

<div style="font-size: 200px;">Text</div>

Callout Blocks

:::{.callout-note}
Note that there are five types of callouts, including: 
`note`, `tip`, `warning`, `caution`, and `important`.
:::

Note

Note that there are five types of callouts, including: note, tip, warning, caution, and important.

Warning

Callouts provide a simple way to attract attention, for example, to this warning.

This is important

Danger, callouts will really improve your writing.

Tip with caption

Caution, under construction

Here is something under construction

Callout markdown syntax

:::{.callout-note}
Note that there are five types of callouts, including:
`note`, `warning`, `important`, `tip`, and `caution`.
:::


:::{.callout-tip}
## Tip With Caption

This is an example of a callout with a caption.
:::



:::{.callout-caution collapse="true"}
## Expand To Learn About Collapse

This is an example of a 'folded' caution callout that can be expanded by the user. You can use `collapse="true"` to collapse it by default or `collapse="false"` to make a collapsible callout that is expanded by default.
:::

Your Turn

  • Open materials/workshop/02-authoring/callout-boxes.qmd
  • Try changing the types of callouts/remove them from code boxes and then render
  • Open materials/workshop/02-authoring/callout-pdf.qmd and render it as well
03:00

Figures

Basic markdown syntax:

![Boston Terrier](images/boston-terrier.png)

Boston Terrier

Figures w/ code

```{r}
#| fig-width: 4
#| fig-align: right

knitr::include_graphics("images/howard-gentleman.jpeg")
```

Fragments/spans

![Boston terrier](images/boston-terrier.png){fig-align="left"}

![](images/boston-terrier.png){fig-align="right" fig-alt="A photo a Boston Terrier."}

A photo a Boston Terrier.

Subfigures fenced div class

::: {#fig-bostons layout-ncol=2}

![Excited](images/boston-terrier.png){#fig-boston width="250px"}

![Sleeping](images/boston-sleep.png){#fig-sleep width="250px"}

Two states of Howard

:::

Subfigures

(a) Excited

(b) Sleeping

Figure 1: Two states of Howard

Subfigures

Paths

Quarto documents reference from their existing folder/directory.

You can reference sub-directories/folders easily:

![](images/image.png)

But what about going “backwards” i.e. to a parent directory?

This specific slide-deck is at "get-started-quarto/materials/02-authoring.qmd"

How to reference a image/file in parent directory i.e. "materials/?

Absolute vs Relative:

In places like markdown, YAML, or the command line/shell/terminal you’ll need to use absolute or relative file paths:

Absolute = BAD: "/Users/thomasmock/get-started-quarto" - who’s computer will this work on?

list.files("/Users/thomasmock/get-started-quarto")
 [1] "_extensions"              "_freeze"                 
 [3] "_quarto.yml"              "404.html"                
 [5] "404.qmd"                  "docs"                    
 [7] "index.html"               "index.qmd"               
 [9] "LICENSE.md"               "materials"               
[11] "preview-image-build.R"    "preview.jpeg"            
[13] "preview.png"              "README.md"               
[15] "schedule.qmd"             "site_libs"               
[17] "workshop-conf-2022.Rproj" "workshop-materials.qmd"  

Relative file paths

Better, HTML style relative paths: "../ = up one directory - ../../ = up two directories and so forth

  • /.. or / = start from root directory of your current computer
list.files("../")
 [1] "_extensions"              "_freeze"                 
 [3] "_quarto.yml"              "404.html"                
 [5] "404.qmd"                  "docs"                    
 [7] "index.html"               "index.qmd"               
 [9] "LICENSE.md"               "materials"               
[11] "preview-image-build.R"    "preview.jpeg"            
[13] "preview.png"              "README.md"               
[15] "schedule.qmd"             "site_libs"               
[17] "workshop-conf-2022.Rproj" "workshop-materials.qmd"  

"~/get-started-quarto/" where “~” is a shortcut for your home directory (like thomasmock on my computer)

list.files("~/get-started-quarto/")
 [1] "_extensions"              "_freeze"                 
 [3] "_quarto.yml"              "404.html"                
 [5] "404.qmd"                  "docs"                    
 [7] "index.html"               "index.qmd"               
 [9] "LICENSE.md"               "materials"               
[11] "preview-image-build.R"    "preview.jpeg"            
[13] "preview.png"              "README.md"               
[15] "schedule.qmd"             "site_libs"               
[17] "workshop-conf-2022.Rproj" "workshop-materials.qmd"  

Mental Model

Working left to right (parent to child)

list.files("~/get-started-quarto/materials")
 [1] "01-intro-quarto_files"      "01-intro-quarto.html"      
 [3] "01-intro-quarto.qmd"        "02-authoring.qmd"          
 [5] "02-authoring.rmarkdown"     "03-computation-editors.qmd"
 [7] "04-static-documents.qmd"    "05-presentations.qmd"      
 [9] "06-websites.qmd"            "07-plots-tables.qmd"       
[11] "08-advanced-knitr.qmd"      "images"                    
[13] "palmer-penguins.csv"        "resources_files"           
[15] "static"                     "test-layout.qmd"           
[17] "theme"                      "workshop"                  

Working right to left (child to parent)

list.files("../materials")
 [1] "01-intro-quarto_files"      "01-intro-quarto.html"      
 [3] "01-intro-quarto.qmd"        "02-authoring.qmd"          
 [5] "02-authoring.rmarkdown"     "03-computation-editors.qmd"
 [7] "04-static-documents.qmd"    "05-presentations.qmd"      
 [9] "06-websites.qmd"            "07-plots-tables.qmd"       
[11] "08-advanced-knitr.qmd"      "images"                    
[13] "palmer-penguins.csv"        "resources_files"           
[15] "static"                     "test-layout.qmd"           
[17] "theme"                      "workshop"                  

Referencing paths in R code

In code you can use here::here():

The goal of the here package is to enable easy file referencing in project-oriented workflows

list.files(here::here())
 [1] "_extensions"              "_freeze"                 
 [3] "_quarto.yml"              "404.html"                
 [5] "404.qmd"                  "docs"                    
 [7] "index.html"               "index.qmd"               
 [9] "LICENSE.md"               "materials"               
[11] "preview-image-build.R"    "preview.jpeg"            
[13] "preview.png"              "README.md"               
[15] "schedule.qmd"             "site_libs"               
[17] "workshop-conf-2022.Rproj" "workshop-materials.qmd"  

here() always starts at the top-level directory of a .RProj

here::here()

here::here()
[1] "/Users/thomasmock/get-started-quarto"
list.files(here::here())
 [1] "_extensions"              "_freeze"                 
 [3] "_quarto.yml"              "404.html"                
 [5] "404.qmd"                  "docs"                    
 [7] "index.html"               "index.qmd"               
 [9] "LICENSE.md"               "materials"               
[11] "preview-image-build.R"    "preview.jpeg"            
[13] "preview.png"              "README.md"               
[15] "schedule.qmd"             "site_libs"               
[17] "workshop-conf-2022.Rproj" "workshop-materials.qmd"  

here::here()

fs::file_info("preview.jpeg") |>  select(1:3)
# A tibble: 1 × 3
  path         type         size
  <fs::path>   <fct> <fs::bytes>
1 preview.jpeg <NA>           NA
fs::file_info(here::here("preview.jpeg")) |>  select(1:3)
# A tibble: 1 × 3
  path                                              type         size
  <fs::path>                                        <fct> <fs::bytes>
1 /Users/thomasmock/get-started-quarto/preview.jpeg file        3.08M


fs::file_info(here::here("materials/images/howard-gentleman.jpeg")) |>  select(1:3)
# A tibble: 1 × 3
  path                                                               type   size
  <fs::path>                                                         <fct> <fs:>
1 …masmock/get-started-quarto/materials/images/howard-gentleman.jpeg file   306K


# this also works
fs::file_info(here::here("materials", "images", "howard-gentleman.jpeg")) |>  select(1:3)
# A tibble: 1 × 3
  path                                                               type   size
  <fs::path>                                                         <fct> <fs:>
1 …masmock/get-started-quarto/materials/images/howard-gentleman.jpeg file   306K

Our Turn

  • Navigate to a file with the “cheat code” Ctrl + I and then edit

  • Open materials/workshop/02-authoring/figure-layout.qmd

  • To reference other directories:

  • Correct the image links:

  • Use here::here("path/to/content") in code

  • Use [](~/ProjectDir/path/to/content) in markdown

  • Use ../../path/to/content in YAML or in Markdown

05:00

Subfigures

::: {#fig-bostons layout-nrow=2}

![Excited](images/boston-terrier.png){#fig-boston width="250px"}

![Sleeping](images/boston-sleep.png){#fig-sleep width="250px"}

![Still Excited](images/boston-terrier.png){#fig-boston width="250px"}

![Still sleeping](images/boston-sleep.png){#fig-sleep width="250px"}

:::

Subfigures

Excited

Sleeping

Still Excited

Still sleeping

Two states of Howard, twice

Subfigures

::: {layout-ncol="2"}
![Excited](images/boston-terrier.png){width="250px"}

![Sleeping](images/boston-sleep.png){width="250px"}

![Still Excited](images/boston-terrier.png){width="250px"}

![Still sleeping](images/boston-sleep.png){width="250px"}

Two states of Howard, twice
:::

Excited

Sleeping

Still Excited

Still sleeping

Two states of Howard, twice

Figure Divs

Note that the last paragraph in the div block is used as the figure caption.

::: {#fig-dog}

<iframe width="560" height="315" src="https://www.youtube.com/embed/U-WQ277UZtY"></iframe>

Funny boston terrier videos
:::

Figure 2: Funny boston terrier videos

Figure Divs

Excited

Sleeping

Still Excited

Figure 3: Funny boston terrier videos

Your Turn

  • Open materials/workshop/02-authoring/figure-layout-2.qmd
  • Try out the various types of subfigures, chahing the nrow/ncol
03:00

Footnotes

Pandoc supports numbering and formatting footnotes.

Inline footnotes

Here is an inline note.^[Inlines notes are easier to write,
since you don't have to pick an identifier and move down to
type the note.]

Here is an inline note.1

Inline footnotes

Here is an footnore reference[^1]

[^1]: This can be easy in some situations when you have a really long note or
don't want to inline complex outputs.

Here is an footnore reference1

Notice in both situations that the footnote is placed at the bottom of the page in presentations, whereas in a document it would be hoverable or at the end of the document.

Cross References

Cross-references make it easier for readers to navigate your document by providing numbered references and hyperlinks to various entities like figures and tables.

![Elephant](elephant.png){#fig-elephant}

The presence of the caption (Elephant) and label (#fig-elephant) make this figure referenceable. This enables you to use the following syntax to refer to it elsewhere in the document:

See @fig-elephant for an illustration.

Diagrams w/ mermaid

```{mermaid}
flowchart LR
  A[Hard edge] --> B(Round edge)
  B --> C{Decision}
  C --> D[Result one]
  C --> E[Result two]
```