@asciidoctor/core 4.0.0-alpha.6 → 4.0.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/build/browser/index.js +204 -57
- package/build/node/index.cjs +204 -56
- package/package.json +2 -2
- package/src/browser/reader.js +2 -2
- package/src/browser.js +8 -1
- package/src/document.js +15 -1
- package/src/extensions.js +125 -22
- package/src/index.js +8 -1
- package/src/logging.js +41 -10
- package/src/parser.js +13 -2
- package/src/reader.js +25 -13
- package/src/substitutors.js +9 -9
- package/types/extensions.d.ts +68 -6
- package/types/index.d.cts +2 -1
- package/types/index.d.ts +2 -1
- package/types/logging.d.ts +49 -5
- package/types/reader.d.ts +2 -2
- package/types/substitutors.d.ts +18 -18
package/build/browser/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var version = "4.0.
|
|
1
|
+
var version = "4.0.1";
|
|
2
2
|
const packageJson = {
|
|
3
3
|
version: version};
|
|
4
4
|
|
|
@@ -1745,14 +1745,23 @@ Logger.BasicFormatter = class {
|
|
|
1745
1745
|
|
|
1746
1746
|
Logger.AutoFormattingMessage = {
|
|
1747
1747
|
/**
|
|
1748
|
-
* Attach auto-formatting to any plain object carrying
|
|
1749
|
-
*
|
|
1748
|
+
* Attach auto-formatting to any plain object carrying
|
|
1749
|
+
* { text, source_location, include_location }.
|
|
1750
|
+
*
|
|
1751
|
+
* The location(s) are rendered only by inspect()/toString() (used when a
|
|
1752
|
+
* stderr Logger formats the line); the structured `source_location` /
|
|
1753
|
+
* `include_location` remain on the object so a MemoryLogger can record them
|
|
1754
|
+
* on the resulting LogMessage without duplicating them inside `text`.
|
|
1755
|
+
* @param {{text: string, source_location?: any, include_location?: any}} obj
|
|
1750
1756
|
* @returns {typeof obj} The same object with inspect() and toString() added.
|
|
1751
1757
|
*/
|
|
1752
1758
|
attach(obj) {
|
|
1753
1759
|
obj.inspect = function () {
|
|
1754
1760
|
const sloc = this.source_location;
|
|
1755
|
-
|
|
1761
|
+
const iloc = this.include_location;
|
|
1762
|
+
let text = sloc ? `${sloc}: ${this.text}` : this.text;
|
|
1763
|
+
if (iloc) text += ` (${iloc})`;
|
|
1764
|
+
return text
|
|
1756
1765
|
};
|
|
1757
1766
|
obj.toString = obj.inspect;
|
|
1758
1767
|
return obj
|
|
@@ -1763,27 +1772,45 @@ Logger.AutoFormattingMessage = {
|
|
|
1763
1772
|
|
|
1764
1773
|
/** Wrapper stored by MemoryLogger; provides getSeverity/getText/getSourceLocation. */
|
|
1765
1774
|
class LogMessage {
|
|
1775
|
+
/**
|
|
1776
|
+
* @param {string} severity - Severity label, e.g. 'ERROR'.
|
|
1777
|
+
* @param {string|{text: string, source_location?: import('./reader.js').Cursor}|null} message
|
|
1778
|
+
*/
|
|
1766
1779
|
constructor(severity, message) {
|
|
1767
1780
|
this.message = message;
|
|
1781
|
+
/** @type {string} */
|
|
1768
1782
|
this.severity = severity; // string label, e.g. 'ERROR'
|
|
1769
1783
|
// AutoFormattingMessage objects carry { text, source_location }
|
|
1770
1784
|
if (message !== null && typeof message === 'object' && 'text' in message) {
|
|
1771
|
-
|
|
1772
|
-
this.
|
|
1785
|
+
/** @type {string} */
|
|
1786
|
+
this.text = message.text;
|
|
1787
|
+
/** @type {import('./reader.js').Cursor|null} */
|
|
1788
|
+
this.sourceLocation = message.source_location ?? null;
|
|
1773
1789
|
} else {
|
|
1774
|
-
this.
|
|
1775
|
-
this.
|
|
1790
|
+
this.text = message != null ? String(message) : '';
|
|
1791
|
+
this.sourceLocation = null;
|
|
1776
1792
|
}
|
|
1777
1793
|
}
|
|
1778
1794
|
|
|
1795
|
+
/**
|
|
1796
|
+
* @returns {string} The severity label, e.g. 'ERROR'.
|
|
1797
|
+
*/
|
|
1779
1798
|
getSeverity() {
|
|
1780
1799
|
return this.severity
|
|
1781
1800
|
}
|
|
1801
|
+
|
|
1802
|
+
/**
|
|
1803
|
+
* @returns {string} The message text.
|
|
1804
|
+
*/
|
|
1782
1805
|
getText() {
|
|
1783
|
-
return this.
|
|
1806
|
+
return this.text
|
|
1784
1807
|
}
|
|
1808
|
+
|
|
1809
|
+
/**
|
|
1810
|
+
* @returns {import('./reader.js').Cursor|undefined} The source location, if any.
|
|
1811
|
+
*/
|
|
1785
1812
|
getSourceLocation() {
|
|
1786
|
-
return this.
|
|
1813
|
+
return this.sourceLocation ?? undefined
|
|
1787
1814
|
}
|
|
1788
1815
|
}
|
|
1789
1816
|
|
|
@@ -1796,6 +1823,7 @@ class MemoryLogger {
|
|
|
1796
1823
|
// matching Ruby's MemoryLogger (level: UNKNOWN). The add() method stores all
|
|
1797
1824
|
// messages unconditionally — level is only used by the isDebug() guard.
|
|
1798
1825
|
this.level = Severity.UNKNOWN;
|
|
1826
|
+
/** @type {LogMessage[]} */
|
|
1799
1827
|
this.messages = [];
|
|
1800
1828
|
}
|
|
1801
1829
|
|
|
@@ -1803,6 +1831,9 @@ class MemoryLogger {
|
|
|
1803
1831
|
return new MemoryLogger()
|
|
1804
1832
|
}
|
|
1805
1833
|
|
|
1834
|
+
/**
|
|
1835
|
+
* @returns {LogMessage[]} The log messages recorded so far, in order.
|
|
1836
|
+
*/
|
|
1806
1837
|
getMessages() {
|
|
1807
1838
|
return this.messages
|
|
1808
1839
|
}
|
|
@@ -6268,7 +6299,7 @@ function resolveBrowserIncludePath(reader, target, attrlist) {
|
|
|
6268
6299
|
// ── Rule 2: target is an absolute URL (http:// / https:// / …) ───────────
|
|
6269
6300
|
} else if (isUriish(pTarget)) {
|
|
6270
6301
|
const descends = pathResolver.descendsFrom(pTarget, baseDir);
|
|
6271
|
-
if (descends === false && !doc.
|
|
6302
|
+
if (descends === false && !doc.hasAttribute('allow-uri-read')) {
|
|
6272
6303
|
return reader.replaceNextLine(_linkReplacement(reader, target, attrlist))
|
|
6273
6304
|
}
|
|
6274
6305
|
incPath = relpath = pTarget;
|
|
@@ -6302,7 +6333,7 @@ function resolveBrowserIncludePath(reader, target, attrlist) {
|
|
|
6302
6333
|
} else {
|
|
6303
6334
|
// Nested include: context dir is an absolute URL.
|
|
6304
6335
|
const ctxDescends = pathResolver.descendsFrom(ctxDir, baseDir);
|
|
6305
|
-
if (ctxDescends !== false || doc.
|
|
6336
|
+
if (ctxDescends !== false || doc.hasAttribute('allow-uri-read')) {
|
|
6306
6337
|
incPath = `${ctxDir}/${pTarget}`;
|
|
6307
6338
|
relpath = ctxDescends !== false ? incPath.slice(ctxDescends) : pTarget;
|
|
6308
6339
|
} else {
|
|
@@ -6966,22 +6997,34 @@ class Reader {
|
|
|
6966
6997
|
}
|
|
6967
6998
|
|
|
6968
6999
|
/** @param {string} msg @param {{ sourceLocation?: any, includeLocation?: any }} [opts] */
|
|
6969
|
-
_logWarn(msg,
|
|
6970
|
-
|
|
6971
|
-
if (includeLocation) text += ` (${includeLocation.lineInfo})`;
|
|
6972
|
-
this.logger.warn(text);
|
|
7000
|
+
_logWarn(msg, opts = {}) {
|
|
7001
|
+
this.logger.warn(this._messageWithContext(msg, opts));
|
|
6973
7002
|
}
|
|
6974
7003
|
_logError(msg, opts = {}) {
|
|
6975
|
-
|
|
6976
|
-
? `${opts.sourceLocation.lineInfo}: ${msg}`
|
|
6977
|
-
: msg;
|
|
6978
|
-
if (opts.includeLocation) text += ` (${opts.includeLocation.lineInfo})`;
|
|
6979
|
-
this.logger.error(text);
|
|
7004
|
+
this.logger.error(this._messageWithContext(msg, opts));
|
|
6980
7005
|
}
|
|
6981
7006
|
/** @param {string} msg @param {{ sourceLocation?: any }} [opts] */
|
|
6982
|
-
_logInfo(msg,
|
|
6983
|
-
|
|
6984
|
-
|
|
7007
|
+
_logInfo(msg, opts = {}) {
|
|
7008
|
+
this.logger.info(this._messageWithContext(msg, opts));
|
|
7009
|
+
}
|
|
7010
|
+
|
|
7011
|
+
/**
|
|
7012
|
+
* Build an auto-formatting message that keeps the cursor as a structured
|
|
7013
|
+
* source_location (rather than baking it into the text). When displayed by a
|
|
7014
|
+
* stderr Logger the location is rendered as a "<path>: line <N>: " prefix, but
|
|
7015
|
+
* a MemoryLogger records it separately on the LogMessage so consumers can call
|
|
7016
|
+
* getSourceLocation(). Mirrors Ruby's Logging#message_with_context.
|
|
7017
|
+
* @param {string} msg
|
|
7018
|
+
* @param {{ sourceLocation?: any, includeLocation?: any }} [opts]
|
|
7019
|
+
* @internal
|
|
7020
|
+
*/
|
|
7021
|
+
_messageWithContext(msg, { sourceLocation, includeLocation } = {}) {
|
|
7022
|
+
if (!sourceLocation && !includeLocation) return msg
|
|
7023
|
+
return Logger.AutoFormattingMessage.attach({
|
|
7024
|
+
text: msg,
|
|
7025
|
+
source_location: sourceLocation ?? null,
|
|
7026
|
+
include_location: includeLocation ?? null,
|
|
7027
|
+
})
|
|
6985
7028
|
}
|
|
6986
7029
|
}
|
|
6987
7030
|
|
|
@@ -7739,7 +7782,7 @@ class PreprocessorReader extends Reader {
|
|
|
7739
7782
|
}
|
|
7740
7783
|
|
|
7741
7784
|
if (isUriish(target) || typeof this._dir !== 'string') {
|
|
7742
|
-
if (!doc.
|
|
7785
|
+
if (!doc.hasAttribute('allow-uri-read')) {
|
|
7743
7786
|
this._logWarn(
|
|
7744
7787
|
`cannot include contents of URI: ${target} (allow-uri-read attribute not enabled)`,
|
|
7745
7788
|
{ sourceLocation: this.cursor }
|
|
@@ -10349,7 +10392,12 @@ class Parser {
|
|
|
10349
10392
|
}
|
|
10350
10393
|
}
|
|
10351
10394
|
(intro ?? section).blocks.push(newBlock);
|
|
10352
|
-
|
|
10395
|
+
// Reset the shared attributes object for the next block. Use Reflect.ownKeys
|
|
10396
|
+
// (not Object.keys) so the Symbol-keyed attribute entries (ATTR_ENTRIES_KEY)
|
|
10397
|
+
// are cleared too; otherwise the array of AttributeEntry objects leaks and
|
|
10398
|
+
// accumulates across blocks, causing reassigned attributes (e.g. a body-level
|
|
10399
|
+
// `:name:` redefined later) to all resolve to the final value at playback time.
|
|
10400
|
+
for (const key of Reflect.ownKeys(attributes)) delete attributes[key];
|
|
10353
10401
|
}
|
|
10354
10402
|
}
|
|
10355
10403
|
|
|
@@ -11196,7 +11244,13 @@ class Parser {
|
|
|
11196
11244
|
}
|
|
11197
11245
|
}
|
|
11198
11246
|
|
|
11199
|
-
|
|
11247
|
+
// Reflect.ownKeys (not Object.keys) so a block carrying only Symbol-keyed
|
|
11248
|
+
// attribute entries (ATTR_ENTRIES_KEY) — e.g. an `:attr:` entry immediately
|
|
11249
|
+
// preceding a list or table — still receives them, matching Ruby's
|
|
11250
|
+
// `attributes.empty?` where the `:attribute_entries` key is counted. Without this
|
|
11251
|
+
// the entries are dropped and the attribute is not played back for that block.
|
|
11252
|
+
if (Reflect.ownKeys(attributes).length > 0)
|
|
11253
|
+
block.updateAttributes(attributes);
|
|
11200
11254
|
block.commitSubs();
|
|
11201
11255
|
|
|
11202
11256
|
if (block.hasSub('callouts')) {
|
|
@@ -13466,6 +13520,7 @@ function _uniform(str, chr, len) {
|
|
|
13466
13520
|
* DSL interface for include processors.
|
|
13467
13521
|
*
|
|
13468
13522
|
* @typedef {DocumentProcessorDslInterface & {
|
|
13523
|
+
* handles(fn: (target: string) => boolean): void;
|
|
13469
13524
|
* handles(fn: (doc: Document, target: string) => boolean): void;
|
|
13470
13525
|
* }} IncludeProcessorDslInterface
|
|
13471
13526
|
*/
|
|
@@ -13516,7 +13571,7 @@ function _uniform(str, chr, len) {
|
|
|
13516
13571
|
* - Called with a single Function argument → stores it as the process block.
|
|
13517
13572
|
* - Called with non-Function arguments → invokes the stored process block.
|
|
13518
13573
|
*
|
|
13519
|
-
* The this context inside a stored process function is bound to the processor
|
|
13574
|
+
* The `this` context inside a stored process function is bound to the processor
|
|
13520
13575
|
* instance at definition time.
|
|
13521
13576
|
*/
|
|
13522
13577
|
const ProcessorDsl = {
|
|
@@ -13690,6 +13745,35 @@ const SyntaxProcessorDsl = {
|
|
|
13690
13745
|
const IncludeProcessorDsl = {
|
|
13691
13746
|
...DocumentProcessorDsl,
|
|
13692
13747
|
|
|
13748
|
+
/**
|
|
13749
|
+
* @overload
|
|
13750
|
+
* @param {(target: string) => boolean} fn - Predicate that receives only the include target.
|
|
13751
|
+
* @returns {void}
|
|
13752
|
+
*/
|
|
13753
|
+
/**
|
|
13754
|
+
* @overload
|
|
13755
|
+
* @param {(doc: Document, target: string) => boolean} fn - Predicate that receives the document and the include target.
|
|
13756
|
+
* @returns {void}
|
|
13757
|
+
*/
|
|
13758
|
+
/**
|
|
13759
|
+
* @overload
|
|
13760
|
+
* @param {Document} doc - The document being parsed.
|
|
13761
|
+
* @param {string} target - The include target.
|
|
13762
|
+
* @returns {boolean}
|
|
13763
|
+
*/
|
|
13764
|
+
/**
|
|
13765
|
+
* Register a function that decides whether this include processor handles a given target,
|
|
13766
|
+
* or invoke the registered handler.
|
|
13767
|
+
*
|
|
13768
|
+
* **Setter form** — register a predicate. The callback may accept either just the target
|
|
13769
|
+
* string (arity 1) or both the document and the target string (arity 2).
|
|
13770
|
+
*
|
|
13771
|
+
* **Invoker form** — call the registered predicate with `(doc, target)` and return its
|
|
13772
|
+
* result, or return `true` if no predicate has been registered.
|
|
13773
|
+
*
|
|
13774
|
+
* @param {...*} args
|
|
13775
|
+
* @returns {boolean | void}
|
|
13776
|
+
*/
|
|
13693
13777
|
handles(...args) {
|
|
13694
13778
|
if (args.length === 1 && typeof args[0] === 'function') {
|
|
13695
13779
|
const fn = args[0];
|
|
@@ -14457,6 +14541,8 @@ class ProcessorExtension extends Extension {
|
|
|
14457
14541
|
super(kind, instance, instance.config);
|
|
14458
14542
|
this.processMethod =
|
|
14459
14543
|
processMethod || ((...args) => instance.process(...args));
|
|
14544
|
+
/** @internal */
|
|
14545
|
+
this._direct = false;
|
|
14460
14546
|
}
|
|
14461
14547
|
}
|
|
14462
14548
|
|
|
@@ -14484,10 +14570,24 @@ const SYNTAX_PROCESSOR_CLASSES = {
|
|
|
14484
14570
|
* Registry holds the extensions which have been registered and activated, has
|
|
14485
14571
|
* methods for registering or defining a processor and looks up extensions
|
|
14486
14572
|
* stored in the registry during parsing.
|
|
14573
|
+
*
|
|
14574
|
+
* A registry can be reused across multiple conversions. Extensions registered
|
|
14575
|
+
* via a group block (passed to {@link Extensions.create} or
|
|
14576
|
+
* {@link Extensions.register}) are re-executed on every activation. Extensions
|
|
14577
|
+
* registered directly on the registry instance (e.g. `registry.preprocessor(fn)`)
|
|
14578
|
+
* are preserved across activations.
|
|
14579
|
+
*
|
|
14580
|
+
* @example
|
|
14581
|
+
* const registry = Extensions.create('my-ext', function () {
|
|
14582
|
+
* this.preprocessor(function () { ... })
|
|
14583
|
+
* })
|
|
14584
|
+
* // registry can be passed to multiple conversions safely
|
|
14487
14585
|
*/
|
|
14488
14586
|
class Registry {
|
|
14489
14587
|
constructor(groups = {}) {
|
|
14490
14588
|
this.groups = groups;
|
|
14589
|
+
/** @internal */
|
|
14590
|
+
this._activating = false;
|
|
14491
14591
|
this._reset();
|
|
14492
14592
|
}
|
|
14493
14593
|
|
|
@@ -14504,18 +14604,26 @@ class Registry {
|
|
|
14504
14604
|
...Object.values(Extensions.groups()),
|
|
14505
14605
|
...Object.values(this.groups),
|
|
14506
14606
|
];
|
|
14507
|
-
|
|
14508
|
-
|
|
14509
|
-
|
|
14510
|
-
if (
|
|
14511
|
-
|
|
14512
|
-
|
|
14513
|
-
|
|
14514
|
-
|
|
14607
|
+
this._activating = true;
|
|
14608
|
+
try {
|
|
14609
|
+
for (const group of extGroups) {
|
|
14610
|
+
if (typeof group === 'function') {
|
|
14611
|
+
// Check if it is a class (constructor) with an activate prototype method.
|
|
14612
|
+
if (
|
|
14613
|
+
group.prototype &&
|
|
14614
|
+
typeof group.prototype.activate === 'function'
|
|
14615
|
+
) {
|
|
14616
|
+
new group().activate(this);
|
|
14617
|
+
} else {
|
|
14618
|
+
// Plain function — call in the context of this registry (like instance_exec).
|
|
14619
|
+
group.length === 0 ? group.call(this) : group(this);
|
|
14620
|
+
}
|
|
14621
|
+
} else if (group && typeof group.activate === 'function') {
|
|
14622
|
+
group.activate(this);
|
|
14515
14623
|
}
|
|
14516
|
-
} else if (group && typeof group.activate === 'function') {
|
|
14517
|
-
group.activate(this);
|
|
14518
14624
|
}
|
|
14625
|
+
} finally {
|
|
14626
|
+
this._activating = false;
|
|
14519
14627
|
}
|
|
14520
14628
|
return this
|
|
14521
14629
|
}
|
|
@@ -15091,6 +15199,7 @@ class Registry {
|
|
|
15091
15199
|
}
|
|
15092
15200
|
|
|
15093
15201
|
const extension = new ProcessorExtension(kind, processorInstance);
|
|
15202
|
+
extension._direct = !this._activating;
|
|
15094
15203
|
extension.config.position === '>>'
|
|
15095
15204
|
? store.unshift(extension)
|
|
15096
15205
|
: store.push(extension);
|
|
@@ -15162,27 +15271,44 @@ class Registry {
|
|
|
15162
15271
|
}
|
|
15163
15272
|
|
|
15164
15273
|
store[name] = new ProcessorExtension(kind, processorInstance);
|
|
15274
|
+
store[name]._direct = !this._activating;
|
|
15165
15275
|
return store[name]
|
|
15166
15276
|
}
|
|
15167
15277
|
|
|
15168
15278
|
/** @internal */
|
|
15169
15279
|
_reset() {
|
|
15280
|
+
// Keep extensions registered directly (outside a group); only clear group-registered ones.
|
|
15281
|
+
// Extensions tagged with _direct=true survive across activations.
|
|
15282
|
+
const keepArr = (arr) => {
|
|
15283
|
+
const kept = arr?.filter((e) => e._direct) ?? [];
|
|
15284
|
+
return kept.length ? kept : null
|
|
15285
|
+
};
|
|
15286
|
+
const keepMap = (map) => {
|
|
15287
|
+
if (!map) return null
|
|
15288
|
+
const kept = Object.create(null);
|
|
15289
|
+
for (const [k, v] of Object.entries(map)) if (v._direct) kept[k] = v;
|
|
15290
|
+
return Object.keys(kept).length ? kept : null
|
|
15291
|
+
};
|
|
15170
15292
|
/** @internal */
|
|
15171
|
-
this._preprocessor_extensions =
|
|
15293
|
+
this._preprocessor_extensions = keepArr(this._preprocessor_extensions);
|
|
15172
15294
|
/** @internal */
|
|
15173
|
-
this._tree_processor_extensions =
|
|
15295
|
+
this._tree_processor_extensions = keepArr(this._tree_processor_extensions);
|
|
15174
15296
|
/** @internal */
|
|
15175
|
-
this._postprocessor_extensions =
|
|
15297
|
+
this._postprocessor_extensions = keepArr(this._postprocessor_extensions);
|
|
15176
15298
|
/** @internal */
|
|
15177
|
-
this._include_processor_extensions =
|
|
15299
|
+
this._include_processor_extensions = keepArr(
|
|
15300
|
+
this._include_processor_extensions
|
|
15301
|
+
);
|
|
15178
15302
|
/** @internal */
|
|
15179
|
-
this._docinfo_processor_extensions =
|
|
15303
|
+
this._docinfo_processor_extensions = keepArr(
|
|
15304
|
+
this._docinfo_processor_extensions
|
|
15305
|
+
);
|
|
15180
15306
|
/** @internal */
|
|
15181
|
-
this._block_extensions =
|
|
15307
|
+
this._block_extensions = keepMap(this._block_extensions);
|
|
15182
15308
|
/** @internal */
|
|
15183
|
-
this._block_macro_extensions =
|
|
15309
|
+
this._block_macro_extensions = keepMap(this._block_macro_extensions);
|
|
15184
15310
|
/** @internal */
|
|
15185
|
-
this._inline_macro_extensions =
|
|
15311
|
+
this._inline_macro_extensions = keepMap(this._inline_macro_extensions);
|
|
15186
15312
|
this.document = null;
|
|
15187
15313
|
}
|
|
15188
15314
|
|
|
@@ -15265,6 +15391,13 @@ const Extensions = {
|
|
|
15265
15391
|
/**
|
|
15266
15392
|
* Create a new Registry, optionally pre-populated with a named block.
|
|
15267
15393
|
*
|
|
15394
|
+
* When a `block` is provided it is stored as a group and re-executed on every
|
|
15395
|
+
* activation, making the registry safe to reuse across multiple conversions.
|
|
15396
|
+
* Without a `block`, any extensions registered directly on the returned registry
|
|
15397
|
+
* (e.g. `registry.preprocessor(fn)`) are stored in transient state that is
|
|
15398
|
+
* cleared on every activation — those registrations will be lost from the second
|
|
15399
|
+
* conversion onwards. Prefer the block form when the registry may be reused.
|
|
15400
|
+
*
|
|
15268
15401
|
* @param {string|null} [name=null] - Optional name for the group; auto-generated if omitted.
|
|
15269
15402
|
* @param {Function|null} [block=null] - Optional function to register as the group.
|
|
15270
15403
|
* @returns {Registry}
|
|
@@ -16145,8 +16278,16 @@ class Document extends AbstractBlock {
|
|
|
16145
16278
|
}
|
|
16146
16279
|
|
|
16147
16280
|
// Pre-compute all async text values (titles, list item text, cell text, reftexts)
|
|
16148
|
-
// so that synchronous getters work correctly during conversion.
|
|
16281
|
+
// so that synchronous getters work correctly during conversion. _resolveAllTexts
|
|
16282
|
+
// replays attribute entries in document order (mirroring conversion) so body-level
|
|
16283
|
+
// attribute (re)assignments are in scope; snapshot and restore the document
|
|
16284
|
+
// attributes so the downstream steps and conversion still start from the restored
|
|
16285
|
+
// (header) state, matching Ruby's restore_attributes-before-convert invariant.
|
|
16286
|
+
const attributesSnapshot = { ...this.attributes };
|
|
16149
16287
|
await this._resolveAllTexts(this);
|
|
16288
|
+
for (const key of Reflect.ownKeys(this.attributes))
|
|
16289
|
+
delete this.attributes[key];
|
|
16290
|
+
Object.assign(this.attributes, attributesSnapshot);
|
|
16150
16291
|
// Reset the footnote counter so that body-content footnotes (processed during conversion)
|
|
16151
16292
|
// start numbering from 1, reproducing Ruby's "out of sequence" quirk: title footnotes are
|
|
16152
16293
|
// numbered during parsing via apply_title_subs, then the counter restarts for body content.
|
|
@@ -17220,6 +17361,12 @@ class Document extends AbstractBlock {
|
|
|
17220
17361
|
* Handles titles (AbstractBlock), list item text, table cell text, and reftexts.
|
|
17221
17362
|
*/
|
|
17222
17363
|
async _resolveAllTexts(block) {
|
|
17364
|
+
// Replay this block's attribute entries (in document order, since the walk is
|
|
17365
|
+
// depth-first pre-order like conversion) so that body-level attribute assignments
|
|
17366
|
+
// and reassignments are in scope when the block's — and its descendants' and later
|
|
17367
|
+
// siblings' — title / list item / table cell / reftext values are substituted.
|
|
17368
|
+
// Mirrors AbstractBlock#convert, which calls playbackAttributes before converting.
|
|
17369
|
+
this.playbackAttributes(block.attributes);
|
|
17223
17370
|
// The header section lives outside document.blocks; pre-compute its title here so
|
|
17224
17371
|
// that doc.doctitle() returns the fully-substituted title (with replacements applied,
|
|
17225
17372
|
// e.g. ' → ’) rather than the header-subs-only fallback.
|
|
@@ -17948,7 +18095,7 @@ const Substitutors = {
|
|
|
17948
18095
|
*
|
|
17949
18096
|
* @param {string|string[]} text - The text to process; must not be null.
|
|
17950
18097
|
* @param {string[]} [subs=NORMAL_SUBS] - The substitutions to perform.
|
|
17951
|
-
* @returns {string|string[]} Text with substitutions applied.
|
|
18098
|
+
* @returns {Promise<string|string[]>} Text with substitutions applied.
|
|
17952
18099
|
*/
|
|
17953
18100
|
async applySubs(text, subs = NORMAL_SUBS) {
|
|
17954
18101
|
const isEmpty = Array.isArray(text) ? text.length === 0 : text.length === 0;
|
|
@@ -18062,7 +18209,7 @@ const Substitutors = {
|
|
|
18062
18209
|
* Substitute quoted text (emphasis, strong, monospaced, etc.)
|
|
18063
18210
|
*
|
|
18064
18211
|
* @param {string} text
|
|
18065
|
-
* @returns {string}
|
|
18212
|
+
* @returns {Promise<string>}
|
|
18066
18213
|
*/
|
|
18067
18214
|
async subQuotes(text) {
|
|
18068
18215
|
const compat = this.document.compatMode;
|
|
@@ -18234,7 +18381,7 @@ const Substitutors = {
|
|
|
18234
18381
|
* Substitute inline macros (links, images, etc.)
|
|
18235
18382
|
*
|
|
18236
18383
|
* @param {string} text
|
|
18237
|
-
* @returns {string}
|
|
18384
|
+
* @returns {Promise<string>}
|
|
18238
18385
|
*/
|
|
18239
18386
|
async subMacros(text) {
|
|
18240
18387
|
const foundSquareBracket = text.includes('[');
|
|
@@ -19129,7 +19276,7 @@ const Substitutors = {
|
|
|
19129
19276
|
* Substitute post replacements (hard line breaks).
|
|
19130
19277
|
*
|
|
19131
19278
|
* @param {string} text
|
|
19132
|
-
* @returns {string}
|
|
19279
|
+
* @returns {Promise<string>}
|
|
19133
19280
|
*/
|
|
19134
19281
|
async subPostReplacements(text) {
|
|
19135
19282
|
if (
|
|
@@ -19167,7 +19314,7 @@ const Substitutors = {
|
|
|
19167
19314
|
*
|
|
19168
19315
|
* @param {string} source
|
|
19169
19316
|
* @param {boolean} processCallouts
|
|
19170
|
-
* @returns {string}
|
|
19317
|
+
* @returns {Promise<string>}
|
|
19171
19318
|
*/
|
|
19172
19319
|
async subSource(source, processCallouts) {
|
|
19173
19320
|
return processCallouts
|
|
@@ -19179,7 +19326,7 @@ const Substitutors = {
|
|
|
19179
19326
|
* Substitute callout source references.
|
|
19180
19327
|
*
|
|
19181
19328
|
* @param {string} text
|
|
19182
|
-
* @returns {string}
|
|
19329
|
+
* @returns {Promise<string>}
|
|
19183
19330
|
*/
|
|
19184
19331
|
async subCallouts(text) {
|
|
19185
19332
|
const calloutRx = this.hasAttribute('line-comment')
|
|
@@ -19208,7 +19355,7 @@ const Substitutors = {
|
|
|
19208
19355
|
*
|
|
19209
19356
|
* @param {string} source
|
|
19210
19357
|
* @param {boolean} processCallouts
|
|
19211
|
-
* @returns {string}
|
|
19358
|
+
* @returns {Promise<string>}
|
|
19212
19359
|
*/
|
|
19213
19360
|
async highlightSource(source, processCallouts) {
|
|
19214
19361
|
const syntaxHl = this.document.syntaxHighlighter;
|
|
@@ -19554,7 +19701,7 @@ const Substitutors = {
|
|
|
19554
19701
|
* Restore passthrough text by reinserting into placeholder positions.
|
|
19555
19702
|
*
|
|
19556
19703
|
* @param {string} text
|
|
19557
|
-
* @returns {string}
|
|
19704
|
+
* @returns {Promise<string>}
|
|
19558
19705
|
*/
|
|
19559
19706
|
async restorePassthroughs(text) {
|
|
19560
19707
|
if (!text.includes(PASS_START)) return text
|
|
@@ -19746,7 +19893,7 @@ const Substitutors = {
|
|
|
19746
19893
|
* @param {string} attrlist
|
|
19747
19894
|
* @param {string[]} [posattrs=[]]
|
|
19748
19895
|
* @param {Object} [opts={}]
|
|
19749
|
-
* @returns {Object}
|
|
19896
|
+
* @returns {Promise<Object>}
|
|
19750
19897
|
*/
|
|
19751
19898
|
async parseAttributes(attrlist, posattrs = [], opts = {}) {
|
|
19752
19899
|
if (!attrlist || attrlist.length === 0) return {}
|
|
@@ -24690,4 +24837,4 @@ const manpage = /*#__PURE__*/Object.freeze({
|
|
|
24690
24837
|
default: ManPageConverter
|
|
24691
24838
|
});
|
|
24692
24839
|
|
|
24693
|
-
export { AbstractBlock, AbstractNode, Author, Block, BlockMacroProcessor, BlockProcessor, ContentModel, ConverterBase, CustomFactory$1 as ConverterCustomFactory, Converter as ConverterFactory, Cursor, DefaultFactory$1 as DefaultConverterFactory, DefaultFactory as DefaultSyntaxHighlighterFactory, DocinfoProcessor, Document, DocumentTitle, Extensions, Footnote, Html5Converter, HttpCache, HttpCacheManager, ImageReference, IncludeProcessor, Inline, InlineMacroProcessor, List, ListItem, Logger, LoggerManager, MemoryHttpCache, MemoryLogger, NullLogger, Postprocessor, Preprocessor, Processor, ProcessorExtension, Reader, Registry, RevisionInfo, SafeMode, Section, SyntaxHighlighter, SyntaxHighlighterBase, Timings, TreeProcessor, convert, deriveBackendTraits, getCoreVersion, getVersion, load };
|
|
24840
|
+
export { AbstractBlock, AbstractNode, Author, Block, BlockMacroProcessor, BlockProcessor, ContentModel, ConverterBase, CustomFactory$1 as ConverterCustomFactory, Converter as ConverterFactory, Cursor, DefaultFactory$1 as DefaultConverterFactory, DefaultFactory as DefaultSyntaxHighlighterFactory, DocinfoProcessor, Document, DocumentTitle, Extensions, Footnote, Html5Converter, HttpCache, HttpCacheManager, ImageReference, IncludeProcessor, Inline, InlineMacroProcessor, List, ListItem, LogMessage, Logger, LoggerManager, MemoryHttpCache, MemoryLogger, NullLogger, Postprocessor, Preprocessor, Processor, ProcessorExtension, Reader, Registry, RevisionInfo, SafeMode, Section, SyntaxHighlighter, SyntaxHighlighterBase, Timings, TreeProcessor, convert, deriveBackendTraits, getCoreVersion, getVersion, load };
|