docrev 0.10.0 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitattributes +1 -1
- package/CHANGELOG.md +173 -164
- package/PLAN-tables-and-postprocess.md +850 -850
- package/README.md +431 -431
- package/bin/rev.js +11 -11
- package/bin/rev.ts +145 -145
- package/completions/rev.bash +127 -127
- package/completions/rev.ps1 +210 -210
- package/completions/rev.zsh +207 -207
- package/dist/lib/anchor-match.d.ts +1 -1
- package/dist/lib/anchor-match.d.ts.map +1 -1
- package/dist/lib/anchor-match.js +17 -47
- package/dist/lib/anchor-match.js.map +1 -1
- package/dist/lib/build.js +4 -4
- package/dist/lib/commands/context.d.ts +1 -1
- package/dist/lib/commands/context.d.ts.map +1 -1
- package/dist/lib/commands/context.js +1 -1
- package/dist/lib/commands/context.js.map +1 -1
- package/dist/lib/commands/sections.js +7 -7
- package/dist/lib/commands/sections.js.map +1 -1
- package/dist/lib/commands/sync.d.ts.map +1 -1
- package/dist/lib/commands/sync.js +15 -14
- package/dist/lib/commands/sync.js.map +1 -1
- package/dist/lib/commands/utilities.js +164 -164
- package/dist/lib/commands/verify-anchors.js +6 -6
- package/dist/lib/commands/verify-anchors.js.map +1 -1
- package/dist/lib/commands/word-tools.js +8 -8
- package/dist/lib/grammar.js +3 -3
- package/dist/lib/macro-filter.lua +201 -201
- package/dist/lib/pdf-comments.js +44 -44
- package/dist/lib/plugins.js +57 -57
- package/dist/lib/pptx-color-filter.lua +37 -37
- package/dist/lib/pptx-themes.js +115 -115
- package/dist/lib/sections.d.ts +35 -0
- package/dist/lib/sections.d.ts.map +1 -1
- package/dist/lib/sections.js +81 -0
- package/dist/lib/sections.js.map +1 -1
- package/dist/lib/spelling.js +2 -2
- package/dist/lib/templates.js +387 -387
- package/dist/lib/themes.js +51 -51
- package/docs-src/build.py +113 -113
- package/docs-src/extra.css +208 -208
- package/docs-src/md-to-html.lua +6 -6
- package/docs-src/template.html +116 -116
- package/eslint.config.js +27 -27
- package/lib/anchor-match.ts +276 -308
- package/lib/annotations.ts +644 -644
- package/lib/build.ts +1766 -1766
- package/lib/citations.ts +160 -160
- package/lib/commands/build.ts +855 -855
- package/lib/commands/citations.ts +515 -515
- package/lib/commands/comments.ts +1050 -1050
- package/lib/commands/context.ts +176 -174
- package/lib/commands/core.ts +309 -309
- package/lib/commands/doi.ts +435 -435
- package/lib/commands/file-ops.ts +372 -372
- package/lib/commands/history.ts +320 -320
- package/lib/commands/index.ts +87 -87
- package/lib/commands/init.ts +259 -259
- package/lib/commands/merge-resolve.ts +378 -378
- package/lib/commands/preview.ts +178 -178
- package/lib/commands/project-info.ts +244 -244
- package/lib/commands/quality.ts +517 -517
- package/lib/commands/response.ts +454 -454
- package/lib/commands/section-boundaries.ts +82 -82
- package/lib/commands/sections.ts +451 -451
- package/lib/commands/sync.ts +709 -706
- package/lib/commands/text-ops.ts +449 -449
- package/lib/commands/utilities.ts +448 -448
- package/lib/commands/verify-anchors.ts +272 -272
- package/lib/commands/word-tools.ts +340 -340
- package/lib/comment-realign.ts +517 -517
- package/lib/config.ts +84 -84
- package/lib/crossref.ts +781 -781
- package/lib/csl.ts +191 -191
- package/lib/dependencies.ts +98 -98
- package/lib/diff-engine.ts +465 -465
- package/lib/doi-cache.ts +115 -115
- package/lib/doi.ts +897 -897
- package/lib/equations.ts +506 -506
- package/lib/errors.ts +346 -346
- package/lib/format.ts +541 -541
- package/lib/git.ts +326 -326
- package/lib/grammar.ts +303 -303
- package/lib/image-registry.ts +180 -180
- package/lib/import.ts +911 -911
- package/lib/journals.ts +543 -543
- package/lib/macro-filter.lua +201 -201
- package/lib/macros.ts +273 -273
- package/lib/merge.ts +633 -633
- package/lib/orcid.ts +144 -144
- package/lib/pdf-comments.ts +263 -263
- package/lib/pdf-import.ts +524 -524
- package/lib/plugins.ts +362 -362
- package/lib/postprocess.ts +188 -188
- package/lib/pptx-color-filter.lua +37 -37
- package/lib/pptx-template.ts +469 -469
- package/lib/pptx-themes.ts +483 -483
- package/lib/protect-restore.ts +520 -520
- package/lib/rate-limiter.ts +94 -94
- package/lib/response.ts +197 -197
- package/lib/restore-references.ts +240 -240
- package/lib/review.ts +327 -327
- package/lib/schema.ts +488 -488
- package/lib/scientific-words.ts +73 -73
- package/lib/sections.ts +425 -335
- package/lib/slides.ts +756 -756
- package/lib/spelling.ts +334 -334
- package/lib/templates.ts +526 -526
- package/lib/themes.ts +742 -742
- package/lib/trackchanges.ts +247 -247
- package/lib/tui.ts +450 -450
- package/lib/types.ts +550 -550
- package/lib/undo.ts +250 -250
- package/lib/utils.ts +69 -69
- package/lib/variables.ts +179 -179
- package/lib/word-extraction.ts +806 -806
- package/lib/word.ts +643 -643
- package/lib/wordcomments.ts +840 -840
- package/mkdocs.yml +64 -64
- package/package.json +137 -137
- package/scripts/postbuild.js +47 -47
- package/skill/REFERENCE.md +539 -539
- package/skill/SKILL.md +295 -295
- package/tsconfig.json +26 -26
- package/types/index.d.ts +525 -525
package/lib/macro-filter.lua
CHANGED
|
@@ -1,201 +1,201 @@
|
|
|
1
|
-
--[[
|
|
2
|
-
docrev macro filter.
|
|
3
|
-
|
|
4
|
-
Reads a JSON sidecar describing one-argument LaTeX-style macros and expands
|
|
5
|
-
them per output FORMAT. Used for the built-in \tofill{X} (bold orange [X]
|
|
6
|
-
placeholder) and any user-declared macros from rev.yaml.
|
|
7
|
-
|
|
8
|
-
Sidecar path is passed via the DOCREV_MACROS_FILE environment variable, set
|
|
9
|
-
by build.ts before spawning pandoc. Env vars (not metadata) because pandoc's
|
|
10
|
-
filter traversal runs RawInline/RawBlock BEFORE Meta, so by the time we'd
|
|
11
|
-
read metadata the inline expansions have already happened.
|
|
12
|
-
|
|
13
|
-
Why raw OpenXML for docx? Pandoc 3.x's docx writer does NOT honor
|
|
14
|
-
`Span{style="color: #..."}` — those spans render as plain text with no
|
|
15
|
-
<w:color> run property. So for docx we emit raw <w:r> nodes directly. Same
|
|
16
|
-
reasoning for the pptx-color-filter.
|
|
17
|
-
|
|
18
|
-
For latex/pdf/beamer the markdown source already contains \tofill{X} as a raw
|
|
19
|
-
LaTeX inline; we leave it alone because build.ts injects a \providecommand
|
|
20
|
-
into header-includes. For html we emit a raw <span> with inline style. For
|
|
21
|
-
everything else (markdown, gfm, plain) we degrade to **bold [X]** so the
|
|
22
|
-
placeholder never silently disappears.
|
|
23
|
-
]]
|
|
24
|
-
|
|
25
|
-
local json = require('pandoc.json')
|
|
26
|
-
|
|
27
|
-
local macros_by_name = {}
|
|
28
|
-
|
|
29
|
-
local function load_sidecar()
|
|
30
|
-
local path = os.getenv('DOCREV_MACROS_FILE')
|
|
31
|
-
if not path or path == '' then
|
|
32
|
-
return
|
|
33
|
-
end
|
|
34
|
-
local fh = io.open(path, 'r')
|
|
35
|
-
if not fh then
|
|
36
|
-
io.stderr:write('docrev macro-filter: cannot read sidecar: ' .. path .. '\n')
|
|
37
|
-
return
|
|
38
|
-
end
|
|
39
|
-
local content = fh:read('*a')
|
|
40
|
-
fh:close()
|
|
41
|
-
local ok, parsed = pcall(json.decode, content)
|
|
42
|
-
if not ok or type(parsed) ~= 'table' or type(parsed.macros) ~= 'table' then
|
|
43
|
-
io.stderr:write('docrev macro-filter: malformed sidecar JSON\n')
|
|
44
|
-
return
|
|
45
|
-
end
|
|
46
|
-
for _, m in ipairs(parsed.macros) do
|
|
47
|
-
if type(m) == 'table' and type(m.name) == 'string' then
|
|
48
|
-
macros_by_name[m.name] = m
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
load_sidecar()
|
|
54
|
-
|
|
55
|
-
local function xml_escape(s)
|
|
56
|
-
return (s:gsub('&', '&'):gsub('<', '<'):gsub('>', '>'))
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
local function html_escape(s)
|
|
60
|
-
return (s
|
|
61
|
-
:gsub('&', '&')
|
|
62
|
-
:gsub('<', '<')
|
|
63
|
-
:gsub('>', '>')
|
|
64
|
-
:gsub('"', '"'))
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
-- Resolve effective style for a macro in the current pandoc format.
|
|
68
|
-
-- Per-format entry wins over `default` (replacement, not merge — matches
|
|
69
|
-
-- macros.ts semantics).
|
|
70
|
-
local function pick_style(macro, format)
|
|
71
|
-
if macro.formats and macro.formats[format] then
|
|
72
|
-
return macro.formats[format]
|
|
73
|
-
end
|
|
74
|
-
return macro.default or {}
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
-- Build the inside of the bracket: [prefix][arg][suffix], optionally without
|
|
78
|
-
-- brackets when style.bracket == false.
|
|
79
|
-
local function compose_text(style, arg)
|
|
80
|
-
local prefix = style.prefix or ''
|
|
81
|
-
local suffix = style.suffix or ''
|
|
82
|
-
local inner = prefix .. arg .. suffix
|
|
83
|
-
if style.bracket == false then
|
|
84
|
-
return inner
|
|
85
|
-
end
|
|
86
|
-
return '[' .. inner .. ']'
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
local function render_docx_run(style, arg)
|
|
90
|
-
local rpr = {}
|
|
91
|
-
if style.color then
|
|
92
|
-
table.insert(rpr, '<w:color w:val="' .. style.color .. '"/>')
|
|
93
|
-
end
|
|
94
|
-
if style.bold then
|
|
95
|
-
table.insert(rpr, '<w:b/>')
|
|
96
|
-
end
|
|
97
|
-
if style.italic then
|
|
98
|
-
table.insert(rpr, '<w:i/>')
|
|
99
|
-
end
|
|
100
|
-
local rpr_xml = ''
|
|
101
|
-
if #rpr > 0 then
|
|
102
|
-
rpr_xml = '<w:rPr>' .. table.concat(rpr) .. '</w:rPr>'
|
|
103
|
-
end
|
|
104
|
-
local text = xml_escape(compose_text(style, arg))
|
|
105
|
-
return '<w:r>' .. rpr_xml ..
|
|
106
|
-
'<w:t xml:space="preserve">' .. text .. '</w:t></w:r>'
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
local function render_html(style, arg)
|
|
110
|
-
local css = {}
|
|
111
|
-
if style.color then
|
|
112
|
-
table.insert(css, 'color:#' .. style.color)
|
|
113
|
-
end
|
|
114
|
-
if style.bold then
|
|
115
|
-
table.insert(css, 'font-weight:bold')
|
|
116
|
-
end
|
|
117
|
-
if style.italic then
|
|
118
|
-
table.insert(css, 'font-style:italic')
|
|
119
|
-
end
|
|
120
|
-
local text = html_escape(compose_text(style, arg))
|
|
121
|
-
if #css == 0 then
|
|
122
|
-
return '<span>' .. text .. '</span>'
|
|
123
|
-
end
|
|
124
|
-
return '<span style="' .. table.concat(css, ';') .. '">' .. text .. '</span>'
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
-- Fallback path: produce native pandoc inlines so the macro never silently
|
|
128
|
-
-- disappears in markdown/gfm/plain output. Used when the current format has
|
|
129
|
-
-- no native rich-text path (or we couldn't open the sidecar).
|
|
130
|
-
local function fallback_inlines(style, arg)
|
|
131
|
-
local doc = pandoc.read(compose_text(style, arg), 'markdown')
|
|
132
|
-
local inlines = pandoc.utils.blocks_to_inlines(doc.blocks)
|
|
133
|
-
if style.bold then
|
|
134
|
-
inlines = { pandoc.Strong(inlines) }
|
|
135
|
-
end
|
|
136
|
-
if style.italic then
|
|
137
|
-
inlines = { pandoc.Emph(inlines) }
|
|
138
|
-
end
|
|
139
|
-
return inlines
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
-- Match `\NAME{...}` (with balanced braces inside the argument is NOT
|
|
143
|
-
-- supported — the use case is plain placeholder text, mirroring the reference
|
|
144
|
-
-- filter; users who need nested braces should use a different mechanism).
|
|
145
|
-
local function parse_call(text)
|
|
146
|
-
local name, arg = text:match('^\\([A-Za-z][A-Za-z0-9]*)%s*{(.*)}%s*$')
|
|
147
|
-
if name and arg and macros_by_name[name] then
|
|
148
|
-
return name, arg
|
|
149
|
-
end
|
|
150
|
-
return nil, nil
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
local function expand_inline(el)
|
|
154
|
-
if el.format ~= 'tex' and el.format ~= 'latex' then
|
|
155
|
-
return nil
|
|
156
|
-
end
|
|
157
|
-
local name, arg = parse_call(el.text)
|
|
158
|
-
if not name then return nil end
|
|
159
|
-
local macro = macros_by_name[name]
|
|
160
|
-
local style = pick_style(macro, FORMAT)
|
|
161
|
-
|
|
162
|
-
if FORMAT == 'docx' then
|
|
163
|
-
return pandoc.RawInline('openxml', render_docx_run(style, arg))
|
|
164
|
-
elseif FORMAT == 'html' or FORMAT == 'html4' or FORMAT == 'html5' or FORMAT == 'chunkedhtml' then
|
|
165
|
-
return pandoc.RawInline('html', render_html(style, arg))
|
|
166
|
-
elseif FORMAT == 'latex' or FORMAT == 'beamer' or FORMAT == 'context' then
|
|
167
|
-
-- Leave the raw LaTeX as-is. build.ts injects \providecommand into
|
|
168
|
-
-- header-includes, so the LaTeX engine renders it directly.
|
|
169
|
-
return nil
|
|
170
|
-
else
|
|
171
|
-
return fallback_inlines(style, arg)
|
|
172
|
-
end
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
local function expand_block(el)
|
|
176
|
-
if el.format ~= 'tex' and el.format ~= 'latex' then
|
|
177
|
-
return nil
|
|
178
|
-
end
|
|
179
|
-
local name, arg = parse_call(el.text)
|
|
180
|
-
if not name then return nil end
|
|
181
|
-
local macro = macros_by_name[name]
|
|
182
|
-
local style = pick_style(macro, FORMAT)
|
|
183
|
-
|
|
184
|
-
if FORMAT == 'docx' then
|
|
185
|
-
return pandoc.RawBlock('openxml', '<w:p>' .. render_docx_run(style, arg) .. '</w:p>')
|
|
186
|
-
elseif FORMAT == 'html' or FORMAT == 'html4' or FORMAT == 'html5' or FORMAT == 'chunkedhtml' then
|
|
187
|
-
return pandoc.RawBlock('html', '<p>' .. render_html(style, arg) .. '</p>')
|
|
188
|
-
elseif FORMAT == 'latex' or FORMAT == 'beamer' or FORMAT == 'context' then
|
|
189
|
-
return nil
|
|
190
|
-
else
|
|
191
|
-
return pandoc.Para(fallback_inlines(style, arg))
|
|
192
|
-
end
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
function RawInline(el)
|
|
196
|
-
return expand_inline(el)
|
|
197
|
-
end
|
|
198
|
-
|
|
199
|
-
function RawBlock(el)
|
|
200
|
-
return expand_block(el)
|
|
201
|
-
end
|
|
1
|
+
--[[
|
|
2
|
+
docrev macro filter.
|
|
3
|
+
|
|
4
|
+
Reads a JSON sidecar describing one-argument LaTeX-style macros and expands
|
|
5
|
+
them per output FORMAT. Used for the built-in \tofill{X} (bold orange [X]
|
|
6
|
+
placeholder) and any user-declared macros from rev.yaml.
|
|
7
|
+
|
|
8
|
+
Sidecar path is passed via the DOCREV_MACROS_FILE environment variable, set
|
|
9
|
+
by build.ts before spawning pandoc. Env vars (not metadata) because pandoc's
|
|
10
|
+
filter traversal runs RawInline/RawBlock BEFORE Meta, so by the time we'd
|
|
11
|
+
read metadata the inline expansions have already happened.
|
|
12
|
+
|
|
13
|
+
Why raw OpenXML for docx? Pandoc 3.x's docx writer does NOT honor
|
|
14
|
+
`Span{style="color: #..."}` — those spans render as plain text with no
|
|
15
|
+
<w:color> run property. So for docx we emit raw <w:r> nodes directly. Same
|
|
16
|
+
reasoning for the pptx-color-filter.
|
|
17
|
+
|
|
18
|
+
For latex/pdf/beamer the markdown source already contains \tofill{X} as a raw
|
|
19
|
+
LaTeX inline; we leave it alone because build.ts injects a \providecommand
|
|
20
|
+
into header-includes. For html we emit a raw <span> with inline style. For
|
|
21
|
+
everything else (markdown, gfm, plain) we degrade to **bold [X]** so the
|
|
22
|
+
placeholder never silently disappears.
|
|
23
|
+
]]
|
|
24
|
+
|
|
25
|
+
local json = require('pandoc.json')
|
|
26
|
+
|
|
27
|
+
local macros_by_name = {}
|
|
28
|
+
|
|
29
|
+
local function load_sidecar()
|
|
30
|
+
local path = os.getenv('DOCREV_MACROS_FILE')
|
|
31
|
+
if not path or path == '' then
|
|
32
|
+
return
|
|
33
|
+
end
|
|
34
|
+
local fh = io.open(path, 'r')
|
|
35
|
+
if not fh then
|
|
36
|
+
io.stderr:write('docrev macro-filter: cannot read sidecar: ' .. path .. '\n')
|
|
37
|
+
return
|
|
38
|
+
end
|
|
39
|
+
local content = fh:read('*a')
|
|
40
|
+
fh:close()
|
|
41
|
+
local ok, parsed = pcall(json.decode, content)
|
|
42
|
+
if not ok or type(parsed) ~= 'table' or type(parsed.macros) ~= 'table' then
|
|
43
|
+
io.stderr:write('docrev macro-filter: malformed sidecar JSON\n')
|
|
44
|
+
return
|
|
45
|
+
end
|
|
46
|
+
for _, m in ipairs(parsed.macros) do
|
|
47
|
+
if type(m) == 'table' and type(m.name) == 'string' then
|
|
48
|
+
macros_by_name[m.name] = m
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
load_sidecar()
|
|
54
|
+
|
|
55
|
+
local function xml_escape(s)
|
|
56
|
+
return (s:gsub('&', '&'):gsub('<', '<'):gsub('>', '>'))
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
local function html_escape(s)
|
|
60
|
+
return (s
|
|
61
|
+
:gsub('&', '&')
|
|
62
|
+
:gsub('<', '<')
|
|
63
|
+
:gsub('>', '>')
|
|
64
|
+
:gsub('"', '"'))
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
-- Resolve effective style for a macro in the current pandoc format.
|
|
68
|
+
-- Per-format entry wins over `default` (replacement, not merge — matches
|
|
69
|
+
-- macros.ts semantics).
|
|
70
|
+
local function pick_style(macro, format)
|
|
71
|
+
if macro.formats and macro.formats[format] then
|
|
72
|
+
return macro.formats[format]
|
|
73
|
+
end
|
|
74
|
+
return macro.default or {}
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
-- Build the inside of the bracket: [prefix][arg][suffix], optionally without
|
|
78
|
+
-- brackets when style.bracket == false.
|
|
79
|
+
local function compose_text(style, arg)
|
|
80
|
+
local prefix = style.prefix or ''
|
|
81
|
+
local suffix = style.suffix or ''
|
|
82
|
+
local inner = prefix .. arg .. suffix
|
|
83
|
+
if style.bracket == false then
|
|
84
|
+
return inner
|
|
85
|
+
end
|
|
86
|
+
return '[' .. inner .. ']'
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
local function render_docx_run(style, arg)
|
|
90
|
+
local rpr = {}
|
|
91
|
+
if style.color then
|
|
92
|
+
table.insert(rpr, '<w:color w:val="' .. style.color .. '"/>')
|
|
93
|
+
end
|
|
94
|
+
if style.bold then
|
|
95
|
+
table.insert(rpr, '<w:b/>')
|
|
96
|
+
end
|
|
97
|
+
if style.italic then
|
|
98
|
+
table.insert(rpr, '<w:i/>')
|
|
99
|
+
end
|
|
100
|
+
local rpr_xml = ''
|
|
101
|
+
if #rpr > 0 then
|
|
102
|
+
rpr_xml = '<w:rPr>' .. table.concat(rpr) .. '</w:rPr>'
|
|
103
|
+
end
|
|
104
|
+
local text = xml_escape(compose_text(style, arg))
|
|
105
|
+
return '<w:r>' .. rpr_xml ..
|
|
106
|
+
'<w:t xml:space="preserve">' .. text .. '</w:t></w:r>'
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
local function render_html(style, arg)
|
|
110
|
+
local css = {}
|
|
111
|
+
if style.color then
|
|
112
|
+
table.insert(css, 'color:#' .. style.color)
|
|
113
|
+
end
|
|
114
|
+
if style.bold then
|
|
115
|
+
table.insert(css, 'font-weight:bold')
|
|
116
|
+
end
|
|
117
|
+
if style.italic then
|
|
118
|
+
table.insert(css, 'font-style:italic')
|
|
119
|
+
end
|
|
120
|
+
local text = html_escape(compose_text(style, arg))
|
|
121
|
+
if #css == 0 then
|
|
122
|
+
return '<span>' .. text .. '</span>'
|
|
123
|
+
end
|
|
124
|
+
return '<span style="' .. table.concat(css, ';') .. '">' .. text .. '</span>'
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
-- Fallback path: produce native pandoc inlines so the macro never silently
|
|
128
|
+
-- disappears in markdown/gfm/plain output. Used when the current format has
|
|
129
|
+
-- no native rich-text path (or we couldn't open the sidecar).
|
|
130
|
+
local function fallback_inlines(style, arg)
|
|
131
|
+
local doc = pandoc.read(compose_text(style, arg), 'markdown')
|
|
132
|
+
local inlines = pandoc.utils.blocks_to_inlines(doc.blocks)
|
|
133
|
+
if style.bold then
|
|
134
|
+
inlines = { pandoc.Strong(inlines) }
|
|
135
|
+
end
|
|
136
|
+
if style.italic then
|
|
137
|
+
inlines = { pandoc.Emph(inlines) }
|
|
138
|
+
end
|
|
139
|
+
return inlines
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
-- Match `\NAME{...}` (with balanced braces inside the argument is NOT
|
|
143
|
+
-- supported — the use case is plain placeholder text, mirroring the reference
|
|
144
|
+
-- filter; users who need nested braces should use a different mechanism).
|
|
145
|
+
local function parse_call(text)
|
|
146
|
+
local name, arg = text:match('^\\([A-Za-z][A-Za-z0-9]*)%s*{(.*)}%s*$')
|
|
147
|
+
if name and arg and macros_by_name[name] then
|
|
148
|
+
return name, arg
|
|
149
|
+
end
|
|
150
|
+
return nil, nil
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
local function expand_inline(el)
|
|
154
|
+
if el.format ~= 'tex' and el.format ~= 'latex' then
|
|
155
|
+
return nil
|
|
156
|
+
end
|
|
157
|
+
local name, arg = parse_call(el.text)
|
|
158
|
+
if not name then return nil end
|
|
159
|
+
local macro = macros_by_name[name]
|
|
160
|
+
local style = pick_style(macro, FORMAT)
|
|
161
|
+
|
|
162
|
+
if FORMAT == 'docx' then
|
|
163
|
+
return pandoc.RawInline('openxml', render_docx_run(style, arg))
|
|
164
|
+
elseif FORMAT == 'html' or FORMAT == 'html4' or FORMAT == 'html5' or FORMAT == 'chunkedhtml' then
|
|
165
|
+
return pandoc.RawInline('html', render_html(style, arg))
|
|
166
|
+
elseif FORMAT == 'latex' or FORMAT == 'beamer' or FORMAT == 'context' then
|
|
167
|
+
-- Leave the raw LaTeX as-is. build.ts injects \providecommand into
|
|
168
|
+
-- header-includes, so the LaTeX engine renders it directly.
|
|
169
|
+
return nil
|
|
170
|
+
else
|
|
171
|
+
return fallback_inlines(style, arg)
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
local function expand_block(el)
|
|
176
|
+
if el.format ~= 'tex' and el.format ~= 'latex' then
|
|
177
|
+
return nil
|
|
178
|
+
end
|
|
179
|
+
local name, arg = parse_call(el.text)
|
|
180
|
+
if not name then return nil end
|
|
181
|
+
local macro = macros_by_name[name]
|
|
182
|
+
local style = pick_style(macro, FORMAT)
|
|
183
|
+
|
|
184
|
+
if FORMAT == 'docx' then
|
|
185
|
+
return pandoc.RawBlock('openxml', '<w:p>' .. render_docx_run(style, arg) .. '</w:p>')
|
|
186
|
+
elseif FORMAT == 'html' or FORMAT == 'html4' or FORMAT == 'html5' or FORMAT == 'chunkedhtml' then
|
|
187
|
+
return pandoc.RawBlock('html', '<p>' .. render_html(style, arg) .. '</p>')
|
|
188
|
+
elseif FORMAT == 'latex' or FORMAT == 'beamer' or FORMAT == 'context' then
|
|
189
|
+
return nil
|
|
190
|
+
else
|
|
191
|
+
return pandoc.Para(fallback_inlines(style, arg))
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
function RawInline(el)
|
|
196
|
+
return expand_inline(el)
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
function RawBlock(el)
|
|
200
|
+
return expand_block(el)
|
|
201
|
+
end
|