Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
quarto-dev
GitHub Repository: quarto-dev/quarto-cli
Path: blob/main/src/resources/extensions/quarto/docusaurus/docusaurus.lua
12923 views
1
-- docusaurus.lua
2
-- Copyright (C) 2023 Posit Software, PBC
3
4
local kQuartoRawHtml = "quartoRawHtml"
5
local rawHtmlVars = pandoc.List()
6
7
local code_block = require('docusaurus_utils').code_block
8
9
local reactPreamble = pandoc.List()
10
11
local function addPreamble(preamble)
12
if not reactPreamble:includes(preamble) then
13
reactPreamble:insert(preamble)
14
end
15
end
16
17
local function Pandoc(doc)
18
-- insert exports at the top if we have them
19
if #rawHtmlVars > 0 then
20
local exports = ("export const %s =\n[%s];"):format(kQuartoRawHtml,
21
table.concat(
22
rawHtmlVars:map(function(var) return '`'.. var .. '`' end),
23
","
24
)
25
)
26
doc.blocks:insert(1, pandoc.RawBlock("markdown", exports .. "\n"))
27
end
28
29
-- insert react preamble if we have it
30
if #reactPreamble > 0 then
31
local preamble = table.concat(reactPreamble, "\n")
32
doc.blocks:insert(1, pandoc.RawBlock("markdown", preamble .. "\n"))
33
end
34
35
return doc
36
end
37
38
-- strip image attributes (which may result from
39
-- fig-format: retina) as they will result in an
40
-- img tag which won't hit the asset pipeline
41
local function Image(el)
42
el.attr = pandoc.Attr()
43
return el
44
end
45
46
-- header attributes only support id
47
local function Header(el)
48
el.attr = pandoc.Attr(el.identifier)
49
return el
50
end
51
52
-- transform 'mdx' into passthrough content, transform 'html'
53
-- into raw commamark to pass through via dangerouslySetInnerHTML
54
local function RawBlock(el)
55
if el.format == 'mdx' then
56
-- special mdx-code-block is not handled if whitespace is present after backtrick (#8333)
57
return pandoc.RawBlock("markdown", "````mdx-code-block\n" .. el.text .. "\n````")
58
elseif el.format == 'html' then
59
-- track the raw html vars (we'll insert them at the top later on as
60
-- mdx requires all exports be declared together)
61
local html = string.gsub(el.text, "\n+", "\n")
62
rawHtmlVars:insert(html)
63
64
-- generate a div container for the raw html and return it as the block
65
local html = ("<div dangerouslySetInnerHTML={{ __html: %s[%d] }} />")
66
:format(kQuartoRawHtml, #rawHtmlVars-1) .. "\n"
67
return pandoc.RawBlock("html", html)
68
end
69
end
70
71
local function DecoratedCodeBlock(node)
72
local el = node.code_block
73
return code_block(el, node.filename)
74
end
75
76
local function jsx(content)
77
return pandoc.RawBlock("markdown", content)
78
end
79
80
local function tabset(node)
81
-- note groupId
82
local groupId = ""
83
local group = node.attr.attributes["group"]
84
if group then
85
groupId = ([[ groupId="%s"]]):format(group)
86
end
87
88
-- create tabs
89
local tabs = pandoc.Div({})
90
tabs.content:insert(jsx("<Tabs" .. groupId .. ">"))
91
92
-- iterate through content
93
for i=1,#node.tabs do
94
local content = node.tabs[i].content
95
local title = node.tabs[i].title
96
97
tabs.content:insert(jsx(([[<TabItem value="%s">]]):format(pandoc.utils.stringify(title))))
98
if type(content) == "table" then
99
tabs.content:extend(content)
100
else
101
tabs.content:insert(content)
102
end
103
tabs.content:insert(jsx("</TabItem>"))
104
end
105
106
-- end tab and tabset
107
tabs.content:insert(jsx("</Tabs>"))
108
109
-- ensure we have required deps
110
addPreamble("import Tabs from '@theme/Tabs';")
111
addPreamble("import TabItem from '@theme/TabItem';")
112
113
return tabs
114
end
115
116
local function Table(tbl)
117
local out = pandoc.write(pandoc.Pandoc({tbl}), FORMAT, PANDOC_WRITER_OPTIONS)
118
-- if the table was written in a way that looks like HTML, then wrap it in the right RawBlock way
119
if string.match(out, "^%s*%<table") then
120
local unwrapped = pandoc.RawBlock('html', out)
121
return RawBlock(unwrapped)
122
end
123
end
124
125
quarto._quarto.ast.add_renderer("Tabset", function()
126
return quarto._quarto.format.isDocusaurusOutput()
127
end, function(node)
128
return tabset(node)
129
end)
130
131
quarto._quarto.ast.add_renderer("Callout", function()
132
return quarto._quarto.format.isDocusaurusOutput()
133
end, function(node)
134
local admonition = pandoc.Blocks({})
135
if node.title then
136
start = pandoc.Plain({})
137
start.content:insert(pandoc.RawInline("markdown", ":::" .. node.type .. "["))
138
start.content:extend(quarto.utils.as_inlines(node.title))
139
start.content:insert(pandoc.RawInline("markdown", "]\n"))
140
admonition:insert(start)
141
else
142
admonition:insert(pandoc.RawBlock("markdown", ":::" .. node.type))
143
end
144
local content = node.content
145
if type(content) == "table" then
146
admonition:extend(content)
147
else
148
admonition:insert(content)
149
end
150
admonition:insert(pandoc.RawBlock("markdown", ":::\n"))
151
return admonition
152
end)
153
154
quarto._quarto.ast.add_renderer("DecoratedCodeBlock", function()
155
return quarto._quarto.format.isDocusaurusOutput()
156
end, function(node)
157
local el = node.code_block
158
return code_block(el, node.filename)
159
end)
160
161
quarto._quarto.ast.add_renderer("FloatRefTarget", function()
162
return quarto._quarto.format.isDocusaurusOutput()
163
end, function(float)
164
float = quarto.doc.crossref.decorate_caption_with_crossref(float)
165
if quarto.doc.crossref.cap_location(float) == "top" then
166
return pandoc.Blocks({
167
pandoc.RawBlock("markdown", "<div id=\"" .. float.identifier .. "\">"),
168
pandoc.Div(quarto.utils.as_blocks(float.caption_long)),
169
pandoc.Div(quarto.utils.as_blocks(float.content)),
170
pandoc.RawBlock("markdown", "</div>")
171
})
172
else
173
return pandoc.Blocks({
174
pandoc.RawBlock("markdown", "<div id=\"" .. float.identifier .. "\">"),
175
pandoc.Div(quarto.utils.as_blocks(float.content)),
176
pandoc.Div(quarto.utils.as_blocks(float.caption_long)),
177
pandoc.RawBlock("markdown", "</div>")
178
})
179
end
180
end)
181
182
return {
183
{
184
traverse = "topdown",
185
Image = Image,
186
Header = Header,
187
RawBlock = RawBlock,
188
DecoratedCodeBlock = DecoratedCodeBlock,
189
CodeBlock = CodeBlock,
190
Table = Table,
191
},
192
{
193
Pandoc = Pandoc,
194
}
195
}
196