필터 만들기

개요

Pandoc과 Quarto의 기본 기능으로 원하는 작업을 정확히 할 수 없다면, 그 간극을 메워주는 Pandoc Filter를 거의 확실히 만들 수 있습니다.

Pandoc은 읽기/쓰기 모듈로 구성됩니다. 문서를 한 포맷에서 다른 포맷으로 변환할 때, 텍스트는 리더가 pandoc의 중간 표현인 “추상 구문 트리(abstract syntax tree, AST)”로 파싱하고, 라이터가 이를 대상 포맷으로 변환합니다. pandoc AST 형식은 pandoc-types 패키지의 Text.Pandoc.Definition 모듈에 정의되어 있습니다.

필터는 리더와 라이터 사이에서 AST를 수정하는 프로그램입니다.

INPUT --reader--> AST --filter--> AST --writer--> OUTPUT

Pandoc의 내장 인용 처리도 필터로 구현되어 있으며, Quarto의 여러 내부 확장(예: 상호 참조, 그림 레이아웃 등)도 마찬가지입니다.

Pandoc 필터는 Pandoc 내장 Lua 인터프리터를 사용하는 Lua로 작성할 수도 있고, Pandoc AST의 JSON 표현을 외부 프로세스와 파이프로 주고받는 방식으로 다른 언어로도 작성할 수 있습니다. 다음 이유로 Lua 필터 사용을 강력히 권장합니다:

  • 외부 의존성 없음
  • 고성능(직렬화/프로세스 실행 오버헤드 없음)
  • PandocQuarto Lua 헬퍼 함수 라이브러리 접근

필터 활성화

필터를 개발해 문서에서 사용하려면 문서의 filters 목록에 추가해야 합니다. 예를 들어 spellcheck 필터를 실행하도록 설정할 수 있습니다:

---
filters:
  - spellcheck.lua
---

기본적으로 사용자 필터는 Quarto 내장 필터보다 먼저 실행됩니다. 일부 필터는 이 동작을 바꾸는 것이 좋습니다. 예를 들어 spellcheck은 Quarto 필터보다 앞에서, fontawesome은 뒤에서 실행되도록 구성할 수 있습니다:

filters:
  - spellcheck.lua
  - quarto
  - fontawesome

한쪽 확장(spellcheck.lua)은 파일 확장자가 있고 다른 쪽(fontawesome)은 없습니다. 이는 배포 방식의 차이 때문입니다. 일반 Lua 파일로 배포되는 확장은 .lua를 사용하고, Quarto 확장으로 배포되는 필터는 그렇지 않습니다. 다음 절에서는 확장 형태의 필터를 만드는 방법을 다룹니다.

필터 확장

빠른 시작

여기서는 간단한 필터 확장을 만드는 방법을 설명합니다. 이를 위해 quarto create 명령을 사용합니다. VS Code, Positron, RStudio를 사용 중이라면 각 통합 터미널에서 quarto create를 실행하세요.

시작하려면 필터 확장을 만들 상위 디렉토리에서 quarto create extension filter를 실행하세요:

Terminal
$ quarto create extension filter
 ? Extension Name › fancy-header

위와 같이 확장 이름을 묻는 프롬프트가 표시됩니다. fancy-header를 입력하고 Enter를 누르면 필터 확장이 생성됩니다:

Creating extension at /Users/jjallaire/quarto/dev/fancy-header:
  - Created README.md
  - Created _extensions/fancy-header/_extension.yml
  - Created _extensions/fancy-header/fancy-header.lua
  - Created .gitignore
  - Created example.qmd

VS Code, Positron, RStudio에서 실행 중이라면 새 창이 열리며 확장 프로젝트가 표시됩니다.

_extensions/fancy-header/의 파일 내용은 다음과 같습니다:

_extensions/fancy-header/_extension.yml
title: Fancy-header
author: J.J. Allaire
version: 1.0.0
quarto-required: ">=99.9.0"
contributes:
  filters:
    - fancy-header.lua
_extensions/fancy-header/fancy-header.lua
-- Reformat all heading text 
function Header(el)
  el.content = pandoc.Emph(el.content)
  return el
end

마지막으로 example.qmd에는 확장을 사용해 보는 코드가 포함됩니다. 예:

example.qmd
---
title: "Fancy-header Example"
filters:
  - fancy-header
---

## Heading

This filter adds formatting to heading text.

example.qmdfilters 값은 필터 파일명(fancy-header.lua)이 아니라 확장 이름(fancy-header)이어야 합니다. 이렇게 하면 한 확장에 여러 필터를 묶을 수 있습니다:

_extensions/fancy-header/_extension.yml
contributes:
  filters:
    - fancy-header.lua
    - make-fancier.lua

사용자가 문서에서 확장을 사용하면 확장에 포함된 모든 필터가 적용됩니다.

필터를 개발하려면 example.qmd를 렌더/미리보기한 다음 fancy-header.lua를 수정하세요(fancy-header.lua가 변경되면 미리보기는 자동으로 새로고침됩니다).

개발

필터 확장 개발을 더 알아보려면:

  1. 필요하다면 Lua 개발을 복습하세요(필터는 Lua로 작성합니다).

  2. Pandoc의 Writing Lua Filters 문서를 확인하세요.

  3. Quarto의 Lua 확장 API를 설명하는 Lua API 참조를 읽어보세요.

JSON 필터를 작성하려면 Writing JSON filters 문서를 참고하세요.

새 필터 확장을 만들려면 위에서 설명한 quarto create extension filter 명령을 사용하세요.

배포

확장 소스가 GitHub 저장소에 있다면, GitHub 조직/저장소 이름을 참조해 프로젝트에 추가할 수 있습니다. 예:

Terminal
# target the current HEAD of the extension
quarto add cooltools/output-folding

# target a branch or tagged release of the extension
quarto add cooltools/output-folding@v1.2
quarto add cooltools/output-folding@bugfix-22

GitHub 저장소 대신 단순 gzip 아카이브로 확장을 묶어 배포할 수도 있습니다. 자세한 내용은 확장 배포 문서를 참고하세요.

예제

Quarto 팀이 만든 다음 필터 확장의 소스 코드를 살펴보는 것도 도움이 됩니다:

확장 이름 설명
latex-environment 커스텀 LaTeX 환경을 출력하는 Quarto 확장.
lightbox HTML 문서의 이미지에 라이트박스 처리를 적용합니다.