개요

Quarto는 마크다운 표 출력을 보다 쉽게 작성하고 사용자 정의할 수 있도록 다음과 같은 기능을 제공합니다.

  • 열 정렬과 열 너비 지정
  • 캡션, 서브캡션, 상호 참조 제공
  • 실행 가능한 코드 셀에서 동적으로 표 생성

이 문서에서는 이러한 기능을 자세히 다룹니다.

마크다운 표

가장 흔히 사용하는 마크다운 표는 파이프(|) 문자를 사용하는 파이프 테이블입니다. 파이프 테이블은 열별 정렬과 캡션을 지정할 수 있습니다. 예를 들면 다음과 같습니다.

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

: 파이프 테이블 구문 예시
파이프 테이블 구문 예시
Default Left Right Center
12 12 12 12
123 123 123 123
1 1 1 1

맨 앞과 맨 뒤의 파이프 문자는 생략 가능하지만 모든 열 사이에는 파이프가 있어야 합니다. 콜론은 예시처럼 열 정렬을 지정합니다. 헤더는 반드시 있어야 하지만 빈 셀을 사용해 헤더가 없는 표처럼 보이게 만들 수 있습니다.

파이프가 열 경계를 의미하므로 위 예시처럼 열을 세로로 정렬할 필요는 없습니다. 따라서 다음과 같이 작성해도 제대로 된 파이프 테이블입니다.

fruit| price
-----|-----:
apple|2.05
pear|1.37
orange|3.09

파이프 테이블 셀에는 문단, 목록 같은 블록 요소를 포함할 수 없으며, 여러 줄로 나뉠 수도 없습니다. 파이프 테이블에 columns 옵션으로 지정한 열 너비보다 긴 행이 있으면 표는 본문 폭 전체를 사용하고 셀 내용이 줄바꿈되며, 헤더와 본문을 구분하는 줄의 대시 개수 비율에 따라 상대적인 셀 너비가 결정됩니다.

예를 들어 ---|-는 첫 번째 열을 전체 폭의 3/4, 두 번째 열을 1/4로 만듭니다. 반면 모든 행이 열 너비보다 짧다면 셀 내용은 줄바꿈되지 않고 셀 크기는 내용에 맞춰집니다.

Bootstrap 클래스 사용

표 캡션 옆에 지정한 Bootstrap 표 클래스는 <table> 요소에 그대로 적용됩니다. 표 전체에 적용할 수 있는 클래스만 허용되며 다음과 같습니다. "primary", "secondary", "success", "danger", "warning", "info", "light", "dark", "striped", "hover", "active", "bordered", "borderless", "sm", "responsive", "responsive-sm", "responsive-md", "responsive-lg", "responsive-xl", "responsive-xxl".

다음 표는 행에 줄무늬를 적용하고 마우스를 올리면 강조되도록 렌더링됩니다.

| fruit  | price  |
|--------|--------|
| apple  | 2.05   |
| pear   | 1.37   |
| orange | 3.09   |

: 과일 가격 {.striped .hover}
과일 가격
fruit price
apple 2.05
pear 1.37
orange 3.09

작성 도구

셀 수가 적은 단순 표는 마크다운으로 직접 작성해도 간단합니다. 그러나 표가 커질수록 작성 도구를 사용하는 것이 좋습니다. 다음 도구를 참고하세요.

TablesGenerator 마크다운 표를 만들어 주는 온라인 도구
Emacs TableMode Emacs용 텍스트 기반 표 작성·편집 기능
Quarto Visual Editor 표 편집을 지원하는 .qmd용 비주얼 편집기

열 너비

앞서 설명했듯이 헤더 줄의 대시 개수 비율(예: ---|-으로 2열 표를 75% / 25%로 분할)로 열 너비를 지정할 수 있습니다.

또는 tbl-colwidths 속성(또는 문서 수준 옵션)을 사용해 명시적으로 열 너비를 지정할 수도 있습니다. 개별 마크다운 표에는 캡션 뒤에 속성을 추가하세요. 예시는 다음과 같습니다.

| fruit  | price  |
|--------|--------|
| apple  | 2.05   |
| pear   | 1.37   |
| orange | 3.09   |

: 과일 가격 {tbl-colwidths="[75,25]"}
과일 가격
fruit price
apple 2.05
pear 1.37
orange 3.09

표에 캡션이 없어도 tbl-colwidths만 지정할 수 있습니다.

| fruit  | price  |
|--------|--------|
| apple  | 2.05   |
| pear   | 1.37   |
| orange | 3.09   |

: {tbl-colwidths="[75,25]"}
fruit price
apple 2.05
pear 1.37
orange 3.09

표 여러 개에서 동일한 열 너비를 사용하려면 문서 수준 옵션으로 지정하세요.

---
title: "My Document"
format: html
tbl-colwidths: [75,25]
---

상호 참조

실행 가능한 코드 셀에서 생성한 표도 tbl- 접두사가 있는 레이블을 추가하면 상호 참조할 수 있습니다. 예시는 다음과 같습니다.

```{python}
#| label: tbl-planets
#| tbl-cap: Astronomical object

from IPython.display import Markdown
from tabulate import tabulate
table = [["Sun","696,000",1.989e30],
         ["Earth","6,371",5.972e24],
         ["Moon","1,737",7.34e22],
         ["Mars","3,390",6.39e23]]
Markdown(tabulate(
  table, 
  headers=["Astronomical object","R (km)", "mass (kg)"]
))
```
Table 1: Astronomical object
Astronomical object R (km) mass (kg)
Sun 696,000 1.989e+30
Earth 6,371 5.972e+24
Moon 1,737 7.34e+22
Mars 3,390 6.39e+23
Important레이블 접두사

표를 상호 참조하려면 레이블이 반드시 tbl-로 시작해야 합니다.

마크다운 표의 경우, 표 아래에 캡션을 추가하고 캡션 끝에 중괄호로 #tbl- 레이블을 지정합니다. 예:

| Col1 | Col2 | Col3 |
|------|------|------|
| A    | B    | C    |
| E    | F    | G    |
| A    | G    | G    |

: My Caption {#tbl-letters}

See @tbl-letters.

HTML 렌더링 결과:

A table with 3 columns and four rows. The text 'Table 1: My Caption' is above the header column. The text 'See tbl. 1' is aligned to the left underneath the last column.

자세한 내용은 상호 참조 문서를 참고하세요.

서브테이블

여러 개의 하위 표를 하나의 묶음으로 구성하려면, 기본 ID를 가진 div를 만들고 그 안에 있는 표마다 하위 ID(및 캡션)를 지정하세요. 예:

::: {#tbl-panel layout-ncol=2}
| Col1 | Col2 | Col3 |
|------|------|------|
| A    | B    | C    |
| E    | F    | G    |
| A    | G    | G    |

: First Table {#tbl-first}

| Col1 | Col2 | Col3 |
|------|------|------|
| A    | B    | C    |
| E    | F    | G    |
| A    | G    | G    |

: Second Table {#tbl-second}

Main Caption
:::

See @tbl-panel for details, especially @tbl-second.

HTML 렌더링 결과:

Two tables side-by-side. Both tables have 3 columns and 4 rows. The table on the left is titled '(a) First table'. The table on the right is titled '(b) Second Table'. Centered underneath both tables is the text 'Table 1: Main Caption'. The text 'See tbl. 2 for details, especially tbl. 2 (b)' is aligned to the left underneath that.

표의 “Main Caption”은 div 안 마지막 블록으로 제공된다는 점을 기억하세요.

캡션 위치

기본적으로 표 캡션은 표 위에 표시됩니다. tbl-cap-location 옵션으로 위치를 바꿀 수 있습니다.

---
tbl-cap-location: top
---

여러 형식에서 공유할 수 있도록 최상위에서 지정했습니다. 특정 형식에만 적용하려면 해당 format 옵션 옆에 둘 수 있습니다.

가능한 값은 다음과 같습니다.

설명
top 캡션을 표 위에 배치합니다.
bottom 캡션을 표 아래에 배치합니다.
margin 캡션을 여백에 배치합니다.

여백에 캡션을 두는 방법은 문서 레이아웃을 참고하세요.

계산 결과

앞에서 설명한 옵션은 모두 실행 가능한 코드 셀로 생성한 표에도 사용할 수 있습니다. 예를 들어 Python tabulate 패키지와 IPython display 모듈의 Markdown() 함수를 사용해 마크다운 표를 출력할 수 있습니다.

```{python}
#| label: tbl-planet-measures
#| tbl-cap: Astronomical object

from IPython.display import Markdown
from tabulate import tabulate
table = [["Sun","696,000",1.989e30],
         ["Earth","6,371",5.972e24],
         ["Moon","1,737",7.34e22],
         ["Mars","3,390",6.39e23]]
Markdown(tabulate(
  table, 
  headers=["Astronomical object","R (km)", "mass (kg)"]
))
```
Table 2: Astronomical object
Astronomical object R (km) mass (kg)
Sun 696,000 1.989e+30
Earth 6,371 5.972e+24
Moon 1,737 7.34e+22
Mars 3,390 6.39e+23

다음 예시는 knitr kable() 함수로 마크다운 표를 작성하면서 tbl-cap, tbl-colwidths 옵션을 적용합니다.

```{r}
#| label: tbl-cars
#| tbl-cap: "Cars"
#| tbl-colwidths: [60,40]

kable(head(cars))
```

코드 셀에서 표가 여러 개 생성되면 셀 옵션으로 서브캡션과 레이아웃을 지정할 수 있습니다.

```{python}
#| label: tbl-example
#| tbl-cap: "Example"
#| tbl-subcap: 
#|   - "MPG"
#|   - "Taxis"
#| layout-ncol: 2

import seaborn as sns
from IPython.display import Markdown, display
mpg = sns.load_dataset("mpg").head(10)
taxis = sns.load_dataset("taxis").head(10)

display(Markdown(mpg.to_markdown(index = False)))
display(Markdown(taxis.to_markdown(index = False)))
```

위 예시에서는 IPython에서 가져온 display() 함수를 사용해 하나의 셀에서 여러 출력을 렌더링합니다(기본적으로 셀은 마지막 표현식만 출력합니다).

```{r}
#| label: tbl-example
#| tbl-cap: "Example"
#| tbl-subcap: 
#|   - "Cars"
#|   - "Pressure"
#| layout-ncol: 2

library(knitr)
kable(head(cars))
kable(head(pressure))
```

계산형 표 스타일

Quarto는 계산으로 생성된 표에 추가 스타일을 적용합니다. 기본적으로 표는 더 작게 표시되고 줄무늬 행이 적용됩니다. 이 처리를 비활성화하려면 코드 셀에 plain 클래스를 추가하세요.

```{r}
#| classes: plain

tibble::tribble(
  ~fruit,   ~price,
  "apple",  2.05,
  "pear",   1.37,
  "orange", 3.09
) |> 
  gt::gt()
```

그리드 표

그리드 표는 문단, 코드 블록, 리스트 등을 셀에 포함할 수 있는 고급 마크다운 표입니다. 예시는 다음과 같습니다.

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

: 샘플 그리드 표.

HTML로 렌더링하면 다음과 같습니다.

샘플 그리드 표.
Fruit Price Advantages
Bananas $1.34
  • built-in wrapper
  • bright color
Oranges $2.10
  • cures scurvy
  • tasty

헤더와 본문을 구분하는 = 줄은 헤더 없는 표에서는 생략할 수 있습니다. 그리드 표의 셀에는 여러 문단, 코드 블록, 리스트 등 임의의 블록 요소를 포함할 수 있습니다.

파이프 테이블과 마찬가지로 구분선에 콜론을 배치해 정렬을 지정할 수 있습니다.

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

HTML로 렌더링하면 다음과 같습니다.

Right Left Centered
Bananas $1.34 built-in wrapper

헤더가 없는 표에서는 콜론을 윗줄에 배치합니다.

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

HTML 출력은 다음과 같습니다.

Right Left Centered

그리드 표는 열 인디케이터를 정렬해야 하므로 일반 텍스트 편집기에서 작성하기 까다롭습니다. 다음 도구를 활용해 보세요.

HTML 표

Quarto는 html RawBlock 노드(예: {=html}) 내부의 HTML 표를 처리해 출력 형식과 관계없이 마크다운 표로 변환합니다. 즉, 문서에 HTML 표 구문을 사용해도 모든 형식에서 마크다운 표로 변환됩니다. 또한 HTML을 출력하는 계산형 표 라이브러리도 다른 형식에서 사용할 수 있습니다.

다음은 원시 HTML 블록 예시입니다.

```{=html}
<table>
  <caption>위 섹션에서 설명했듯 Quarto 표는 매우 유용합니다.</caption>
  <thead>
    <tr>
      <th>Header 1</th>
      <th>Header 2</th>
    </tr>
  </thead>
  <tbody>
    <tr>
    <td><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/3/37/African_Bush_Elephant.jpg/220px-African_Bush_Elephant.jpg" alt="African Bush Elephant" /></td>
      <td>일반 출력</td>
    </tr>
  </tbody>
</table>
```

HTML과 PDF로 렌더링하면 다음과 같은 결과가 생성됩니다.

HTML 출력

위 섹션에서 설명했듯 Quarto 표는 매우 유용합니다.
Header 1 Header 2
African Bush Elephant 일반 출력

PDF 출력

캡션과 두 개의 헤더( Header 1, Header 2 ), 셀에는 코끼리 이미지와 'Regular Output' 텍스트가 있는 표를 보여 주는 PDF 스크린샷

또한 Quarto는 표 안에 마크다운 콘텐츠를 포함하는 기능도 지원합니다. 이를 사용하려면 span 또는 div 노드에 qmd 혹은 qmd-base64 데이터 속성을 지정합니다. 이 노드는 헤더, 푸터, 셀, 캡션 등 해당 콘텐츠가 허용되는 어느 곳에나 사용할 수 있습니다.

예를 들어 다음 표에는 상호 참조, 마크다운 서식, 숏코드가 포함되어 있습니다.

## HTML 표 예제 {#sec-html-tables}

```{=html}
<table>
  <caption><span data-qmd="[섹션 -@sec-html-tables]에서 설명했듯 Quarto 표는 매우 유용합니다."></span></caption>
  <thead>
    <tr>
      <th><span data-qmd="_Header 1_"></span></th>
      <th><span data-qmd="_Header 2_"></span></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><span data-qmd="{{< video https://www.youtube.com/embed/wo9vZccmqwc >}}"></span></td>
      <td>일반 출력</td>
    </tr>
  </tbody>
</table>
```

렌더링 결과는 다음과 같습니다.

HTML 표 예제

섹션 9에서 설명했듯 Quarto 표는 매우 유용합니다.
Header 1 Header 2
일반 출력

열/행 병합

여러 행 또는 열을 병합한 셀을 포함하는 표는 에서 지원됩니다.

PDF 여백을 제외한 모든 출력 형식

다만 마크다운에서는 그리드 표에 병합 셀을 그리기 어렵고, 파이프 테이블에서는 병합을 표현할 수 없습니다.

HTML에 익숙하거나 HTML을 생성하는 패키지를 사용한다면 colspan, rowspan 속성을 사용하는 것이 더 편리합니다.

I span two columns C1
I span two rows B2 C2
B3 C3
```{=html}
<table>
    <tr>
        <td colspan="2">I span two columns</td><td>C1</td>
    </tr>
    <tr>
        <td rowspan="2">I span two rows</td><td>B2</td><td>C2</td>
    </tr>
    <tr>
        <td>B3</td><td>C3</td>
    </tr>
</table>

```

개별 셀 정렬

마크다운은 열 수준 정렬은 지원하지만 개별 셀 정렬은 지원하지 않습니다. text-align, vertical-align 같은 CSS 속성은 원시 HTML을 통해서만 사용할 수 있습니다(PDF/LaTeX, PPTX에서는 아직 지원되지 않고, DOCX는 text-align만 지원함).

vertical-align: top vertical-align: middle vertical-align: bottom
text-align: left
text-align: center
text-align: right
```{=html}
<table>
  <tr>
    <td><img src="https://placehold.co/600x400/png"/></td>
    <td style="vertical-align: top">vertical-align: top</td>
    <td style="vertical-align: middle">vertical-align: middle</td>
    <td style="vertical-align: bottom">vertical-align: bottom</td>
  </tr>
  <tr>
    <td style="text-align: left">text-align: left</td>
  </tr>
  <tr>
    <td style="text-align: center">text-align: center</td>
  </tr>
  <tr>
    <td style="text-align: right">text-align: right</td>
  </tr>
</table>
 

```

Quarto 표 처리 비활성화

경우에 따라 Quarto의 HTML 표 처리가 R/Python 등에서 표 패키지가 생성한 HTML과 충돌할 수 있습니다.

HTML 표 처리를 비활성화하면 표가 마크다운으로 변환되지 않고, 다른 출력 형식에서도 렌더링되지 않으며, 상호 참조나 숏코드 같은 Quarto 마크다운 기능을 사용할 수 없습니다. 또한 Table 노드를 대상으로 하는 Lua 필터에서도 보이지 않습니다.

문서 또는 프로젝트 수준에서 html-table-processing 옵션으로 비활성화할 수 있습니다.

---
format:
  html:
    html-table-processing: none
---

Knitr, Jupyter 코드 셀 옵션으로도 설정할 수 있습니다.

```{r}
#| html-table-processing: none

# R Code that generates an HTML table
```

문서의 일부분만 비활성화하려면 html-table-processing="none" 속성을 가진 div로 감싸세요.

::: {html-table-processing="none"}

처리하지 않으려는 HTML 표가 포함된 콘텐츠.

:::

라이브러리 작성자를 위한 팁

HTML 표를 출력하는 라이브러리를 개발한다면 <table> 요소에 data-quarto-disable-processing="true" 속성을 추가해 Quarto의 처리를 비활성화할 수 있습니다.

<table data-quarto-disable-processing="true">
  ...
</table>

또한 HTML 원시 블록에 <!--| quarto-html-table-processing: none --> 주석을 추가하면 Quarto가 해당 블록을 처리하지 않습니다.