쇼트코드 만들기
이 문서는 사용자 정의 쇼트코드를 만드는 방법을 설명합니다.
개요
숏코드는 다양한 콘텐츠를 생성하는 특별한 마크다운 지시어입니다. Quarto 숏코드는 Hugo 숏코드나 워드프레스 숏코드와 형식·기능이 비슷합니다.
예를 들어 아래 숏코드는 문서 메타데이터의 title을 출력합니다.
{{< meta title >}}기본 제공 숏코드
Quarto가 기본 제공하는 숏코드는 다음과 같습니다.
| 숏코드 | 설명 |
|---|---|
| version | Quarto CLI 버전 출력 |
| var | _variables.yml 값 출력 |
| meta | 문서 메타데이터 값 출력 |
| env | 시스템 환경 변수를 출력 |
| pagebreak | 네이티브 페이지 분할 삽입 |
| kbd | 키보드 단축키 표현 |
| video | 문서에 비디오 삽입 |
| include | 다른 qmd 내용을 포함 |
| embed | Jupyter 노트북 셀 삽입 |
| placeholder | 플레이스홀더 이미지를 문서에 추가 |
| lipsum | 플레이스홀더 텍스트를 문서에 추가 |
| contents | 문서 내 콘텐츠 재배치 |
빠른 시작
여기서는 간단한 쇼트코드 확장을 만드는 방법을 설명합니다. 이를 위해 quarto create 명령을 사용합니다. VS Code, Positron, RStudio를 사용 중이라면 각 통합 터미널에서 quarto create를 실행하세요.
시작하려면 쇼트코드 확장을 만들고 싶은 상위 디렉터리에서 quarto create extension shortcode를 실행합니다:
Terminal
$ quarto create extension shortcode
? Extension Name › shorty위와 같이 확장 이름을 묻는 프롬프트가 나타납니다. shorty를 입력하고 Enter를 누르면 쇼트코드 확장이 생성됩니다:
Creating extension at /Users/jjallaire/extensions/shorty/shorty:
- Created README.md
- Created _extensions/shorty/shorty.lua
- Created _extensions/shorty/_extension.yml
- Created .gitignore
- Created example.qmdVS Code, Positron, RStudio 안에서 실행했다면 확장 프로젝트를 여는 새 창이 열립니다.
_extensions/shorty/ 안의 파일 내용은 다음과 같습니다:
_extensions/shorty/_extension.yml
title: Shorty
author: J.J. Allaire
version: 1.0.0
quarto-required: ">=1.2.222"
contributes:
shortcodes:
- shorty.lua_extensions/shorty/shorty.lua
return {
['shorty'] = function(args, kwargs, meta)
return pandoc.Str("Hello from Shorty!")
end
}마지막으로 example.qmd 파일에는 확장을 실행해 보는 코드가 들어 있습니다. 예를 들면 다음과 같습니다:
example.qmd
---
title: "Shorty Example"
---
{{< shorty >}}쇼트코드를 개발하려면 example.qmd를 렌더/미리보기한 다음 shorty.lua를 수정하세요(shorty.lua를 변경하면 미리보기가 자동으로 새로고침됩니다).
개발
쇼트코드는 Lua로 만듭니다. Lua(또는 Pandoc 필터)에 익숙하지 않다면 다음 자료를 참고하세요:
Lua 개발 (Lua는 쇼트코드를 만드는 데 사용하는 언어입니다).
Lua API 참조. Quarto용 Lua 확장 API를 설명하며, 특히
quarto.shortcode.*항목을 참고하세요.
쇼트코드는 하나 이상의 인자를 받아 Pandoc AST 노드(또는 노드 목록)를 반환하는 Lua 함수로 구현합니다.
다음은 Quarto에 기본 포함된 env 쇼트코드의 구현입니다:
env.lua
function env(args)
local var = pandoc.utils.stringify(args[1])
local value = os.getenv(var)
if value ~= nil then
return pandoc.Str(value)
else
return pandoc.Null()
end
end쇼트코드의 인자는 args(1차원 배열)로 전달되며, 각 인자는 Pandoc 인라인 목록(즉, 텍스트를 파싱한 마크다운 AST)입니다.
pandoc.utils.stringify()를 사용해 인라인을 일반 문자열로 변환한 다음, os.getenv()로 값을 가져옵니다.
이 쇼트코드는 다음과 같이 사용합니다:
{{< env HOME >}}배포
확장 소스 코드가 GitHub 저장소에 있으면 GitHub 조직과 저장소 이름을 지정해 설치할 수 있습니다. 예:
Terminal
# install the current HEAD of the extension
quarto add cooltools/shorty
# install a branch or tagged release of the extension
quarto add cooltools/shorty@v1.2
quarto add cooltools/shorty@bugfix-22GitHub 저장소 대신 간단한 gzip 아카이브로 확장을 묶어 배포할 수도 있습니다. 자세한 내용은 확장 배포 문서를 참고하세요.
예시
Quarto 팀이 작성한 쇼트코드 확장 소스를 살펴보면 도움이 됩니다:
| 확장 | 설명 |
|---|---|
| fancy-text | LaTeX와 BibTeX 같은 꾸밈 문자열을 여러 포맷에서 보기 좋게 출력합니다. |
| fontawesome | HTML과 PDF 문서에서 Font Awesome 아이콘을 사용합니다. |
| video | HTML 문서와 Revealjs 프레젠테이션에 비디오를 임베드합니다. |
추가로 주석이 달린 예시를 아래에 제공합니다.
Raw 출력
쇼트코드는 렌더링 대상 포맷에 맞춰 출력을 조정할 수 있습니다. HTML에서는 풍부한 출력물을 조건부로 생성하면서도 PDF나 MS Word에서는 문서가 정상적으로 렌더링되게 하고 싶을 때 유용합니다.
pagebreak 쇼트코드는 여러 포맷에서 “native” 페이지 나누기를 생성합니다. 다음은 pagebreak 구현입니다:
pagebreak.lua
function pagebreak()
local raw = {
epub = '<p style="page-break-after: always;"> </p>',
html = '<div style="page-break-after: always;"></div>',
latex = '\\newpage{}',
ooxml = '<w:p><w:r><w:br w:type="page"/></w:r></w:p>',
odt = '<text:p text:style-name="Pagebreak"/>',
context = '\\page'
}
if quarto.doc.isFormat('docx') then
return pandoc.RawBlock('openxml', raw.ooxml)
elseif quarto.doc.isFormat('pdf') then
return pandoc.RawBlock('tex', raw.latex)
elseif quarto.doc.isFormat('odt') then
return pandoc.RawBlock('opendocument', raw.odt)
elseif quarto.doc.isFormat('epub') then
return pandoc.RawBlock('html', raw.epub)
elseif quarto.doc.isFormat('html') then
return pandoc.RawBlock('html', raw.html)
elseif quarto.doc.isFormat('context') then
return pandoc.RawBlock('context', raw.context)
else
-- fall back to insert a form feed character
return pandoc.Para{pandoc.Str '\f'}
end
endpandoc.RawBlock() 함수로 대상 포맷에 맞는 raw 콘텐츠를 출력합니다. Raw 블록은 출력 파일로 그대로 전달되며 마크다운으로 처리되지 않습니다.
이 쇼트코드는 다음과 같이 사용합니다:
{{< pagebreak >}}이름 있는 인자
앞의 예시는 단일 인자(env) 또는 인자 없음(pagebreak)을 사용합니다. 여기서는 이름 있는 인자 처리를 보여주기 위해 현재 git 리비전을 출력하는 git-rev 쇼트코드를 구현합니다. short 옵션으로 짧은 SHA1 값 또는 긴 값 중 무엇을 표시할지 결정합니다:
git.lua
-- run git and read its output
function git(command)
local p = io.popen("git " .. command)
local output = p:read('*all')
p:close()
return output
end
-- return a table containing shortcode definitions
-- defining shortcodes this way allows us to create helper
-- functions that are not themselves considered shortcodes
return {
["git-rev"] = function(args, kwargs)
-- command line args
local cmdArgs = ""
local short = pandoc.utils.stringify(kwargs["short"])
if short == "true" then
cmdArgs = cmdArgs .. "--short "
end
-- run the command
local cmd = "rev-parse " .. cmdArgs .. "HEAD"
local rev = git(cmd)
-- return as string
return pandoc.Str(rev)
end
}여기서 새로 등장한 점은 다음과 같습니다:
쇼트코드 함수를 전역으로 정의하는 대신 쇼트코드 정의를 담은 테이블을 반환합니다. 이렇게 하면 쇼트코드로 등록되지 않는 헬퍼 함수를 만들 수 있고, 이름에 대시(
-)가 들어가는 쇼트코드도 정의할 수 있습니다.쇼트코드 핸들러에
kwargs라는 새 인자를 추가했습니다. 이는 쇼트코드의 이름 있는 인자를 담고 있습니다.args와 마찬가지로kwargs의 값도 항상 Pandoc 인라인 목록이므로(마크다운을 인자로 받을 수 있음),short처럼 단순 불리언 값은pandoc.utils.stringify()로 문자열로 변환한 뒤"true"와 비교해야 합니다.
이 쇼트코드는 다음과 같이 사용합니다:
---
title: "My Document"
---
{{< git-rev >}}
{{< git-rev short=true >}}메타데이터 옵션
경우에 따라 쇼트코드 동작에 영향을 주는 옵션을 제공하고 싶을 수 있습니다. 쇼트코드 핸들러의 세 번째 인자(meta)로 문서/프로젝트 수준 메타데이터에 접근할 수 있습니다.
이번에는 git-rev 쇼트코드의 다른 버전을 구현해, 리비전을 일반 텍스트가 아니라 GitHub 링크로 출력해 보겠습니다. 이를 위해 github.owner와 github.repo 메타데이터 값을 사용합니다:
git.lua
function git(command)
local p = io.popen("git " .. command)
local output = p:read('*all')
p:close()
return output
end
return {
["git-rev"] = function(args, kwargs, meta)
-- run the command
local rev = git("rev-parse HEAD")
-- target repo
local owner = pandoc.utils.stringify(meta["github.owner"])
local repo = pandoc.utils.stringify(meta["github.repo"])
local url = "https://github.com/"
.. owner .. "/" .. repo .. "/" .. rev
-- return as link
return pandoc.Link(pandoc.Str(rev), url)
end
}args와 kwargs와 마찬가지로 meta 값도 항상 Pandoc 인라인 목록으로 제공되므로, 보통 pandoc.utils.stringify()로 문자열로 변환해야 합니다.
이 쇼트코드를 문서에서 사용하려면, 문서 옵션으로 GitHub 정보를 제공한 다음 원하는 위치에 쇼트코드를 삽입합니다:
---
title: "My Document"
github:
owner: quarto-dev
repo: quarto-cli
---
{{< git-rev >}}쇼트코드 등록과 GitHub 메타데이터는 프로젝트 수준의 _quarto.yml 파일이나 디렉터리 수준의 _metadata.yml 파일에 넣어도 됩니다.
Raw 인자
Quarto >= 1.3에서는 raw_args 매개변수를 추가해 쇼트코드에 전달되는 인라인 스트림의 원본에도 접근할 수 있습니다. 예:
function shorty(args, kwargs, meta, raw_args)
-- ...
end컨텍스트 인식
Quarto >= 1.5에서는 쇼트코드가 호출된 컨텍스트를 함수 호출의 다섯 번째 매개변수로 받을 수 있습니다. context는 block, inline, text 중 하나의 문자열입니다:
context가block이면 쇼트코드가 단독 블록으로 존재합니다context가inline이면 쇼트코드가 여러 인라인 노드 중 하나입니다context가text이면 쇼트코드가 Pandoc 노드의 텍스트 필드 안에 있습니다. 예를 들면:CodeBlock또는Code요소의 내용RawBlock또는RawInline요소의 내용Div,Span등 Pandoc 요소의 속성 값Link요소의 URLImage요소의 소스
function shorty(args, kwargs, meta, raw_args, context)
-- ...
end이스케이프
변수 숏코드 사용법을 문서화할 때(예: 이 문서처럼) 숏코드가 실제로 처리되지 않도록 막아야 할 수 있습니다. 방법은 두 가지입니다.
다음과 같이 중괄호를 추가해 숏코드 참조를 이스케이프합니다.
{{{< var version >}}}숏코드 처리를 막고 싶은 코드 블록에
shortcodes=false속성을 추가합니다.```{shortcodes=false} {{< var version >}} ```