Skip to content

Commit e2f5644

Browse files
author
pedro
committed
refactor: consolidate runtime state into Options table
1 parent cc4e473 commit e2f5644

File tree

1 file changed

+48
-49
lines changed

1 file changed

+48
-49
lines changed

_extensions/alerts-normalize/alerts-normalize.lua

Lines changed: 48 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,26 @@ local FormatDefaults = {
8181
}
8282

8383

84-
-- # State
85-
86-
local out_format
87-
local write_rules
84+
-- # Options
85+
86+
local Options = {
87+
format = 'pandoc-format',
88+
rules = nil,
89+
type_map = {},
90+
types = {
91+
-- core (all formats)
92+
note=true, warning=true, tip=true, caution=true, important=true,
93+
-- extended (obsidian, mkdocs, admonition ecosystems)
94+
info=true, success=true, question=true, failure=true, danger=true,
95+
bug=true, example=true, quote=true, abstract=true, hint=true,
96+
check=true, done=true, error=true, help=true, faq=true,
97+
attention=true,
98+
-- sphinx/myst
99+
seealso=true, todo=true,
100+
-- vitepress
101+
details=true,
102+
},
103+
}
88104

89105

90106
-- # Helpers
@@ -94,9 +110,9 @@ local function get_type(div)
94110
end
95111

96112
local function format_type(type_str)
97-
if write_rules.TypeCase == TypeCase.lower then
113+
if Options.rules.TypeCase == TypeCase.lower then
98114
return type_str:lower()
99-
elseif write_rules.TypeCase == TypeCase.upper then
115+
elseif Options.rules.TypeCase == TypeCase.upper then
100116
return type_str:upper()
101117
else
102118
return type_str
@@ -115,13 +131,13 @@ end
115131
local function write_div(div)
116132
local kind = format_type(get_type(div))
117133
local title = div.attributes.title -- nil if absent, '' if explicitly empty
118-
if out_format == 'pandoc-md' then
134+
if Options.format == 'pandoc-md' then
119135
-- intermediate: class only, preserve title attribute as-is
120136
div.classes = { kind }
121137
return div
122-
elseif write_rules.Prefix then
138+
elseif Options.rules.Prefix then
123139
-- Quarto: omit title attribute if nil, Quarto auto-generates from class
124-
div.classes = { write_rules.Prefix .. kind }
140+
div.classes = { Options.rules.Prefix .. kind }
125141
if title and title ~= '' then
126142
div.attributes.title = title
127143
else
@@ -146,7 +162,7 @@ local function write_blockquote(div)
146162
local kind = format_type(get_type(div))
147163
local title = div.attributes.title
148164
local collapse = div.attributes.collapse
149-
local suffix = write_rules.Collapse
165+
local suffix = Options.rules.Collapse
150166
and (collapse == 'true' and '-' or collapse == 'false' and '+' or '')
151167
or ''
152168
-- marker as RawInline to prevent Pandoc from escaping the brackets
@@ -166,8 +182,8 @@ end
166182

167183
local function write_fence(div)
168184
local kind = format_type(get_type(div))
169-
local title = write_rules.HasTitle and (div.attributes.title or '') or ''
170-
local collapse = write_rules.Collapse and div.attributes.collapse == 'true'
185+
local title = Options.rules.HasTitle and (div.attributes.title or '') or ''
186+
local collapse = Options.rules.Collapse and div.attributes.collapse == 'true'
171187
local cls = collapse and 'dropdown' or kind
172188
local open = pandoc.RawBlock('markdown', '```{' .. cls .. '} ' .. title)
173189
local close = pandoc.RawBlock('markdown', '```')
@@ -176,16 +192,16 @@ end
176192

177193
local function write_admonition(div)
178194
local kind = format_type(get_type(div))
179-
local title = write_rules.HasTitle and (' "' .. (div.attributes.title or '') .. '"') or ''
180-
local collapse = write_rules.Collapse and div.attributes.collapse == 'true'
195+
local title = Options.rules.HasTitle and (' "' .. (div.attributes.title or '') .. '"') or ''
196+
local collapse = Options.rules.Collapse and div.attributes.collapse == 'true'
181197
local marker = collapse and '???' or '!!!'
182198
local open = pandoc.RawBlock('markdown', marker .. ' ' .. kind .. title)
183199
return { open, indent_content(div.content) }
184200
end
185201

186202
local function write_directive(div)
187203
local kind = format_type(get_type(div))
188-
local title = write_rules.HasTitle and (div.attributes.title or '') or ''
204+
local title = Options.rules.HasTitle and (div.attributes.title or '') or ''
189205
local open = pandoc.RawBlock('rst', '.. ' .. kind .. ':: ' .. title)
190206
return { open, indent_content(div.content) }
191207
end
@@ -199,8 +215,8 @@ end
199215

200216
local function write_colon(div)
201217
local kind = format_type(get_type(div))
202-
local title = write_rules.HasTitle and (div.attributes.title or '') or ''
203-
local collapse = write_rules.Collapse and div.attributes.collapse == 'true'
218+
local title = Options.rules.HasTitle and (div.attributes.title or '') or ''
219+
local collapse = Options.rules.Collapse and div.attributes.collapse == 'true'
204220
local open = collapse
205221
and pandoc.RawBlock('markdown', ':::details ' .. title)
206222
or pandoc.RawBlock('markdown', ':::' .. kind .. ' ' .. title)
@@ -222,35 +238,18 @@ local Writers = {
222238
}
223239

224240
local function write_callout(div)
225-
local writer = Writers[write_rules.Container]
241+
local writer = Writers[Options.rules.Container]
226242
if not writer then
227-
error('No writer for container: ' .. tostring(write_rules.Container), 2)
243+
error('No writer for container: ' .. tostring(Options.rules.Container), 2)
228244
end
229245
return writer(div)
230246
end
231247

232248

233249
-- # Normalizers
234250

235-
local TypeMap = {} -- optional kind remapping, e.g. info -> note
236-
237-
--- Known callout types for Pandoc/Sphinx plain div detection.
238-
local CalloutTypes = {
239-
-- core (all formats)
240-
note=true, warning=true, tip=true, caution=true, important=true,
241-
-- extended (obsidian, mkdocs, admonition ecosystems)
242-
info=true, success=true, question=true, failure=true, danger=true,
243-
bug=true, example=true, quote=true, abstract=true, hint=true,
244-
check=true, done=true, error=true, help=true, faq=true,
245-
attention=true,
246-
-- sphinx/myst
247-
seealso=true, todo=true,
248-
-- vitepress
249-
details=true,
250-
}
251-
252251
local function make_div(kind, blocks, title, collapse)
253-
kind = TypeMap[kind] or kind
252+
kind = Options.type_map[kind] or kind
254253
local attrs = {}
255254
if title and title ~= '' then attrs.title = title end
256255
if collapse == true then attrs.collapse = 'true' end
@@ -261,7 +260,7 @@ end
261260
--- GitHub / Obsidian: > [!WORD] or > [!word] — any casing accepted.
262261
--- [!NOTE]+ expanded, [!NOTE]- collapsed.
263262
local function normalize_github(bq)
264-
if out_format == 'github-format' or out_format == 'obsidian-format' then return nil end
263+
if Options.format == 'github-format' or Options.format == 'obsidian-format' then return nil end
265264
local first = bq.content[1]
266265
if not first or first.t ~= 'Para' then return nil end
267266
local marker = first.content[1]
@@ -305,18 +304,18 @@ end
305304
--- Quarto / Pandoc 3.9 / Sphinx / pandoc-md divs.
306305
local function normalize_div(div)
307306
-- Quarto: :::{.callout-*} — title and collapse already in attributes
308-
if out_format ~= 'quarto-format' then
307+
if Options.format ~= 'quarto-format' then
309308
local kind = div.classes[1] and div.classes[1]:match('^callout%-(.+)$')
310309
if kind then
311310
div.classes = { kind }
312311
return write_callout(div)
313312
end
314313
end
315314
-- Pandoc 3.9 / Sphinx / pandoc-md: :::{.note} — title from attribute or .title child
316-
if out_format ~= 'sphinx-format' and out_format ~= 'pandoc-format'
317-
and out_format ~= 'pandoc-md' then
315+
if Options.format ~= 'sphinx-format' and Options.format ~= 'pandoc-format'
316+
and Options.format ~= 'pandoc-md' then
318317
local kind = div.classes[1]
319-
if kind and CalloutTypes[kind] then
318+
if kind and Options.types[kind] then
320319
local title = div.attributes.title or nil
321320
local collapse_str = div.attributes.collapse
322321
local collapse = collapse_str == 'true' and true or nil
@@ -342,37 +341,37 @@ local function process_metadata(meta)
342341

343342
if not cfg then
344343
-- auto-detect
345-
out_format = quarto ~= nil and 'quarto-format' or 'pandoc-format'
344+
Options.format = quarto ~= nil and 'quarto-format' or 'pandoc-format'
346345
elseif type(cfg) == 'string' then
347346
-- alerts-normalize: pandoc-format
348-
out_format = cfg
347+
Options.format = cfg
349348
else
350349
-- alerts-normalize:
351350
-- out-format: pandoc-format
352351
-- custom-types:
353352
-- - spoiler
354353
-- - info: note
355354
local fmt = cfg['out-format']
356-
out_format = fmt and pandoc.utils.stringify(fmt)
355+
Options.format = fmt and pandoc.utils.stringify(fmt)
357356
or (quarto ~= nil and 'quarto-format' or 'pandoc-format')
358357
local types = cfg['custom-types']
359358
if types then
360359
for _, v in ipairs(types) do
361360
if type(v) == 'table' then
362361
-- mapping form: { info: note }
363362
for src, dst in pairs(v) do
364-
CalloutTypes[src] = true
365-
TypeMap[src] = pandoc.utils.stringify(dst)
363+
Options.types[src] = true
364+
Options.type_map[src] = pandoc.utils.stringify(dst)
366365
end
367366
else
368367
-- plain string: spoiler
369-
CalloutTypes[pandoc.utils.stringify(v)] = true
368+
Options.types[pandoc.utils.stringify(v)] = true
370369
end
371370
end
372371
end
373372
end
374373

375-
write_rules = FormatDefaults[out_format] or FormatDefaults['pandoc-format']
374+
Options.rules = FormatDefaults[Options.format] or FormatDefaults['pandoc-format']
376375
end
377376

378377
return {

0 commit comments

Comments
 (0)