docrev 0.10.1 → 0.11.0
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 +184 -173
- 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 +4 -2
- package/dist/lib/anchor-match.d.ts.map +1 -1
- package/dist/lib/anchor-match.js +52 -24
- package/dist/lib/anchor-match.js.map +1 -1
- package/dist/lib/annotations.d.ts +0 -6
- package/dist/lib/annotations.d.ts.map +1 -1
- package/dist/lib/annotations.js +26 -8
- package/dist/lib/annotations.js.map +1 -1
- package/dist/lib/build.d.ts.map +1 -1
- package/dist/lib/build.js +13 -10
- package/dist/lib/build.js.map +1 -1
- package/dist/lib/commands/build.d.ts.map +1 -1
- package/dist/lib/commands/build.js +5 -0
- package/dist/lib/commands/build.js.map +1 -1
- package/dist/lib/commands/doi.d.ts.map +1 -1
- package/dist/lib/commands/doi.js +14 -2
- package/dist/lib/commands/doi.js.map +1 -1
- package/dist/lib/commands/sync.d.ts.map +1 -1
- package/dist/lib/commands/sync.js +98 -107
- package/dist/lib/commands/sync.js.map +1 -1
- package/dist/lib/commands/utilities.js +164 -164
- package/dist/lib/commands/word-tools.js +8 -8
- package/dist/lib/comment-realign.d.ts +12 -21
- package/dist/lib/comment-realign.d.ts.map +1 -1
- package/dist/lib/comment-realign.js +40 -348
- package/dist/lib/comment-realign.js.map +1 -1
- package/dist/lib/dependencies.d.ts +10 -0
- package/dist/lib/dependencies.d.ts.map +1 -1
- package/dist/lib/dependencies.js +41 -9
- package/dist/lib/dependencies.js.map +1 -1
- package/dist/lib/doi.d.ts.map +1 -1
- package/dist/lib/doi.js +68 -80
- package/dist/lib/doi.js.map +1 -1
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +3 -1
- package/dist/lib/errors.js.map +1 -1
- package/dist/lib/grammar.js +3 -3
- package/dist/lib/import.d.ts +7 -4
- package/dist/lib/import.d.ts.map +1 -1
- package/dist/lib/import.js +58 -62
- package/dist/lib/import.js.map +1 -1
- package/dist/lib/macro-filter.lua +201 -201
- package/dist/lib/ooxml.d.ts +207 -0
- package/dist/lib/ooxml.d.ts.map +1 -0
- package/dist/lib/ooxml.js +634 -0
- package/dist/lib/ooxml.js.map +1 -0
- 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/rate-limiter.d.ts +8 -0
- package/dist/lib/rate-limiter.d.ts.map +1 -1
- package/dist/lib/rate-limiter.js +41 -4
- package/dist/lib/rate-limiter.js.map +1 -1
- package/dist/lib/sections.d.ts.map +1 -1
- package/dist/lib/sections.js +5 -2
- 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/dist/lib/types.d.ts +9 -1
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/word-extraction.d.ts.map +1 -1
- package/dist/lib/word-extraction.js +48 -307
- package/dist/lib/word-extraction.js.map +1 -1
- package/dist/lib/word.d.ts.map +1 -1
- package/dist/lib/word.js +80 -175
- package/dist/lib/word.js.map +1 -1
- package/dist/lib/wordcomments.d.ts.map +1 -1
- package/dist/lib/wordcomments.js +53 -92
- package/dist/lib/wordcomments.js.map +1 -1
- 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 +307 -276
- package/lib/annotations.ts +664 -644
- package/lib/build.ts +1770 -1766
- package/lib/citations.ts +160 -160
- package/lib/commands/build.ts +860 -855
- package/lib/commands/citations.ts +515 -515
- package/lib/commands/comments.ts +1050 -1050
- package/lib/commands/context.ts +176 -176
- package/lib/commands/core.ts +309 -309
- package/lib/commands/doi.ts +451 -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 +689 -709
- 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 +99 -517
- package/lib/config.ts +84 -84
- package/lib/crossref.ts +781 -781
- package/lib/csl.ts +191 -191
- package/lib/dependencies.ts +132 -98
- package/lib/diff-engine.ts +465 -465
- package/lib/doi-cache.ts +115 -115
- package/lib/doi.ts +879 -897
- package/lib/equations.ts +506 -506
- package/lib/errors.ts +350 -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 +906 -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/ooxml.ts +768 -0
- 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 +127 -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 +428 -425
- 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 +558 -550
- package/lib/undo.ts +250 -250
- package/lib/utils.ts +69 -69
- package/lib/variables.ts +179 -179
- package/lib/word-extraction.ts +525 -806
- package/lib/word.ts +526 -643
- package/lib/wordcomments.ts +789 -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
|
@@ -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
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parser-backed OOXML layer.
|
|
3
|
+
*
|
|
4
|
+
* A `.docx` is a zip of XML parts. Reading those parts with regexes breaks on
|
|
5
|
+
* the variability real Word emits: marker elements carry attributes beyond
|
|
6
|
+
* `w:id`, anchor text spans many runs, the WordprocessingML namespace can be
|
|
7
|
+
* bound to a prefix other than `w`, runs are separated by `<w:tab/>`/`<w:br/>`,
|
|
8
|
+
* and prose lives in parts other than `document.xml` (footnotes, endnotes,
|
|
9
|
+
* headers, footers).
|
|
10
|
+
*
|
|
11
|
+
* This module tokenizes the XML structurally and walks it once into an ordered
|
|
12
|
+
* flow of paragraphs, runs, text, track-change spans, and comment-range
|
|
13
|
+
* markers. Every reader (text extraction, comment anchors, headings) and the
|
|
14
|
+
* comment injector derive from that single walk — there is no second engine to
|
|
15
|
+
* drift from.
|
|
16
|
+
*/
|
|
17
|
+
import AdmZip from 'adm-zip';
|
|
18
|
+
export declare const WML_NS = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
|
|
19
|
+
/** Open a `.docx` package. Throws a clear error if it is not a valid zip. */
|
|
20
|
+
export declare function openDocx(docxPath: string): AdmZip;
|
|
21
|
+
/** Read a single part as UTF-8 text, or `null` when the part is absent. */
|
|
22
|
+
export declare function readPartText(zip: AdmZip, partName: string): string | null;
|
|
23
|
+
/**
|
|
24
|
+
* The WordprocessingML parts that carry running prose, in reading order:
|
|
25
|
+
* the main story first, then footnotes, endnotes, headers, and footers.
|
|
26
|
+
* A reader that opens only `document.xml` loses everything else.
|
|
27
|
+
*/
|
|
28
|
+
export declare function listProseParts(zip: AdmZip): string[];
|
|
29
|
+
/** Decode the XML entities that appear in `.docx` text and attribute values. */
|
|
30
|
+
export declare function decodeXmlEntities(text: string): string;
|
|
31
|
+
/** Encode text for placement inside an XML element (`<w:t>`). */
|
|
32
|
+
export declare function encodeXmlText(text: string): string;
|
|
33
|
+
/** Encode text for placement inside a double-quoted XML attribute value. */
|
|
34
|
+
export declare function encodeXmlAttr(text: string): string;
|
|
35
|
+
export interface XmlAttr {
|
|
36
|
+
/** Qualified name as written, e.g. `w:id`. */
|
|
37
|
+
name: string;
|
|
38
|
+
prefix: string;
|
|
39
|
+
local: string;
|
|
40
|
+
/** Entity-decoded value. */
|
|
41
|
+
value: string;
|
|
42
|
+
}
|
|
43
|
+
export type XmlTokenKind = 'open' | 'close' | 'selfclose' | 'text' | 'comment' | 'cdata' | 'decl' | 'pi';
|
|
44
|
+
export interface XmlToken {
|
|
45
|
+
kind: XmlTokenKind;
|
|
46
|
+
/** Byte offset of `<` (or text start) in the source. */
|
|
47
|
+
start: number;
|
|
48
|
+
/** Byte offset just past `>` (or text end) in the source. */
|
|
49
|
+
end: number;
|
|
50
|
+
/** Exact source slice [start, end). */
|
|
51
|
+
raw: string;
|
|
52
|
+
name?: string;
|
|
53
|
+
prefix?: string;
|
|
54
|
+
local?: string;
|
|
55
|
+
attrs?: XmlAttr[];
|
|
56
|
+
/** Entity-decoded text, for `text` and `cdata` tokens. */
|
|
57
|
+
text?: string;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Tokenize an XML string into an ordered, offset-tagged token stream.
|
|
61
|
+
* Quote-aware so a raw `>` inside an attribute value does not end a tag early.
|
|
62
|
+
*/
|
|
63
|
+
export declare function tokenizeXml(xml: string): XmlToken[];
|
|
64
|
+
export interface NsContext {
|
|
65
|
+
uriForPrefix(prefix: string): string | undefined;
|
|
66
|
+
/** True when an element token lives in the WordprocessingML namespace. */
|
|
67
|
+
isWml(token: XmlToken): boolean;
|
|
68
|
+
/** Value of the WML-namespaced attribute with the given local name, if present. */
|
|
69
|
+
wmlAttr(token: XmlToken, local: string): string | undefined;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Build a namespace context from a token stream. Declarations are read from
|
|
73
|
+
* every element (the root carries them in practice), so the WML namespace is
|
|
74
|
+
* matched by URI rather than by assuming the `w` prefix.
|
|
75
|
+
*/
|
|
76
|
+
export declare function resolveNamespaces(tokens: XmlToken[]): NsContext;
|
|
77
|
+
export type FlowItem = {
|
|
78
|
+
kind: 'text';
|
|
79
|
+
text: string;
|
|
80
|
+
} | {
|
|
81
|
+
kind: 'paraStart';
|
|
82
|
+
style: string | null;
|
|
83
|
+
level: number;
|
|
84
|
+
xmlStart: number;
|
|
85
|
+
} | {
|
|
86
|
+
kind: 'paraEnd';
|
|
87
|
+
} | {
|
|
88
|
+
kind: 'runStart';
|
|
89
|
+
xmlStart: number;
|
|
90
|
+
xmlContentStart: number;
|
|
91
|
+
} | {
|
|
92
|
+
kind: 'runEnd';
|
|
93
|
+
xmlEnd: number;
|
|
94
|
+
} | {
|
|
95
|
+
kind: 'commentStart';
|
|
96
|
+
id: string;
|
|
97
|
+
xmlStart: number;
|
|
98
|
+
xmlEnd: number;
|
|
99
|
+
} | {
|
|
100
|
+
kind: 'commentEnd';
|
|
101
|
+
id: string;
|
|
102
|
+
xmlStart: number;
|
|
103
|
+
xmlEnd: number;
|
|
104
|
+
} | {
|
|
105
|
+
kind: 'commentRef';
|
|
106
|
+
id: string;
|
|
107
|
+
} | {
|
|
108
|
+
kind: 'insStart';
|
|
109
|
+
} | {
|
|
110
|
+
kind: 'insEnd';
|
|
111
|
+
} | {
|
|
112
|
+
kind: 'delStart';
|
|
113
|
+
} | {
|
|
114
|
+
kind: 'delEnd';
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* Walk a part's XML once into an ordered flow. Text-bearing items appear in
|
|
118
|
+
* document order interleaved with paragraph, run, track-change, and
|
|
119
|
+
* comment-range boundaries, each tagged with the source offsets a later
|
|
120
|
+
* injection step needs.
|
|
121
|
+
*/
|
|
122
|
+
export declare function walkBody(xml: string, ns?: NsContext): FlowItem[];
|
|
123
|
+
export interface CommentRange {
|
|
124
|
+
id: string;
|
|
125
|
+
/** Concatenated anchor text between the range markers. */
|
|
126
|
+
anchor: string;
|
|
127
|
+
/** Start offset of the anchor in `text`. */
|
|
128
|
+
start: number;
|
|
129
|
+
/** End offset of the anchor in `text`. */
|
|
130
|
+
end: number;
|
|
131
|
+
/** True when the range encloses no text (a zero-width / point anchor). */
|
|
132
|
+
isEmpty: boolean;
|
|
133
|
+
}
|
|
134
|
+
export interface DocTextModel {
|
|
135
|
+
/** Plain text: runs concatenated, paragraphs joined with nothing between. */
|
|
136
|
+
text: string;
|
|
137
|
+
/** Comment ranges with offsets into `text`. */
|
|
138
|
+
comments: CommentRange[];
|
|
139
|
+
/** Heading paragraphs with their offset into `text`. */
|
|
140
|
+
headings: Array<{
|
|
141
|
+
style: string;
|
|
142
|
+
level: number;
|
|
143
|
+
text: string;
|
|
144
|
+
position: number;
|
|
145
|
+
}>;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Build the plain-text model used for comment-anchor matching. Runs are
|
|
149
|
+
* concatenated and paragraphs are joined with no separator, matching the
|
|
150
|
+
* coordinate system the placement engine expects, but namespace-aware and
|
|
151
|
+
* robust to marker-attribute variation and multi-run anchors.
|
|
152
|
+
*/
|
|
153
|
+
export declare function buildDocTextModel(xml: string): DocTextModel;
|
|
154
|
+
export interface TextRunSlot {
|
|
155
|
+
/** Source offset of the enclosing run's `<w:r>`. */
|
|
156
|
+
runOpenStart: number;
|
|
157
|
+
/** Source offset just past the enclosing run's `</w:r>`. */
|
|
158
|
+
runCloseEnd: number;
|
|
159
|
+
/** Raw `<w:rPr>...</w:rPr>` of the enclosing run, or '' when it has none. */
|
|
160
|
+
rPr: string;
|
|
161
|
+
/** Raw opening `<w:t ...>` tag of this text element. */
|
|
162
|
+
tOpenTag: string;
|
|
163
|
+
/** Source offset just past `<w:t ...>`. */
|
|
164
|
+
contentStart: number;
|
|
165
|
+
/** Source offset of `</w:t>`. */
|
|
166
|
+
contentEnd: number;
|
|
167
|
+
/** Raw (still XML-encoded) text between the `<w:t>` tags. */
|
|
168
|
+
content: string;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Index every `<w:t>` text element with its enclosing run's exact boundaries
|
|
172
|
+
* and run properties, derived from the token nesting rather than by scanning
|
|
173
|
+
* backwards for the nearest `<w:r`. This locates the correct run even when the
|
|
174
|
+
* text sits inside a hyperlink, a field, or an `mc:AlternateContent` block, and
|
|
175
|
+
* naturally ignores marker-like text that lives in attributes (it is not inside
|
|
176
|
+
* a `<w:t>`).
|
|
177
|
+
*/
|
|
178
|
+
export declare function indexTextRuns(xml: string): TextRunSlot[];
|
|
179
|
+
export interface ExtractedComment {
|
|
180
|
+
id: string;
|
|
181
|
+
author: string;
|
|
182
|
+
/** Full ISO date string as written, or '' when absent. */
|
|
183
|
+
date: string;
|
|
184
|
+
text: string;
|
|
185
|
+
/** Parent comment id for a reply, resolved from commentsExtended.xml. */
|
|
186
|
+
parentId?: string;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Extract comment bodies from `word/comments.xml` and reply threading from
|
|
190
|
+
* `word/commentsExtended.xml`. Structural elements are matched by local name
|
|
191
|
+
* in the WordprocessingML namespace, so a document that binds WML to a prefix
|
|
192
|
+
* other than `w` still yields its comments.
|
|
193
|
+
*/
|
|
194
|
+
export declare function extractComments(zip: AdmZip): ExtractedComment[];
|
|
195
|
+
/** Parts that can carry comment ranges, in reading order. */
|
|
196
|
+
export declare const COMMENT_PARTS: string[];
|
|
197
|
+
/**
|
|
198
|
+
* Comment ranges across every part that can hold them — not just
|
|
199
|
+
* `document.xml`, so a comment anchored in a footnote or endnote is found
|
|
200
|
+
* rather than silently lost. Positions are offsets into the concatenated
|
|
201
|
+
* `fullDocText`.
|
|
202
|
+
*/
|
|
203
|
+
export declare function buildCommentAnchorModel(zip: AdmZip): {
|
|
204
|
+
fullDocText: string;
|
|
205
|
+
comments: CommentRange[];
|
|
206
|
+
};
|
|
207
|
+
//# sourceMappingURL=ooxml.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ooxml.d.ts","sourceRoot":"","sources":["../../lib/ooxml.ts"],"names":[],"mappings":"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"}
|