@asciidoctor/core 4.0.0 → 4.0.2

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/src/reader.js CHANGED
@@ -675,22 +675,34 @@ export class Reader {
675
675
  }
676
676
 
677
677
  /** @param {string} msg @param {{ sourceLocation?: any, includeLocation?: any }} [opts] */
678
- _logWarn(msg, { sourceLocation, includeLocation } = {}) {
679
- let text = sourceLocation ? `${sourceLocation.lineInfo}: ${msg}` : msg
680
- if (includeLocation) text += ` (${includeLocation.lineInfo})`
681
- this.logger.warn(text)
678
+ _logWarn(msg, opts = {}) {
679
+ this.logger.warn(this._messageWithContext(msg, opts))
682
680
  }
683
681
  _logError(msg, opts = {}) {
684
- let text = opts.sourceLocation
685
- ? `${opts.sourceLocation.lineInfo}: ${msg}`
686
- : msg
687
- if (opts.includeLocation) text += ` (${opts.includeLocation.lineInfo})`
688
- this.logger.error(text)
682
+ this.logger.error(this._messageWithContext(msg, opts))
689
683
  }
690
684
  /** @param {string} msg @param {{ sourceLocation?: any }} [opts] */
691
- _logInfo(msg, { sourceLocation } = {}) {
692
- const text = sourceLocation ? `${sourceLocation.lineInfo}: ${msg}` : msg
693
- this.logger.info(text)
685
+ _logInfo(msg, opts = {}) {
686
+ this.logger.info(this._messageWithContext(msg, opts))
687
+ }
688
+
689
+ /**
690
+ * Build an auto-formatting message that keeps the cursor as a structured
691
+ * source_location (rather than baking it into the text). When displayed by a
692
+ * stderr Logger the location is rendered as a "<path>: line <N>: " prefix, but
693
+ * a MemoryLogger records it separately on the LogMessage so consumers can call
694
+ * getSourceLocation(). Mirrors Ruby's Logging#message_with_context.
695
+ * @param {string} msg
696
+ * @param {{ sourceLocation?: any, includeLocation?: any }} [opts]
697
+ * @internal
698
+ */
699
+ _messageWithContext(msg, { sourceLocation, includeLocation } = {}) {
700
+ if (!sourceLocation && !includeLocation) return msg
701
+ return Logger.AutoFormattingMessage.attach({
702
+ text: msg,
703
+ source_location: sourceLocation ?? null,
704
+ include_location: includeLocation ?? null,
705
+ })
694
706
  }
695
707
  }
696
708
 
@@ -1448,7 +1460,7 @@ export class PreprocessorReader extends Reader {
1448
1460
  }
1449
1461
 
1450
1462
  if (isUriish(target) || typeof this._dir !== 'string') {
1451
- if (!doc.getAttribute('allow-uri-read')) {
1463
+ if (!doc.hasAttribute('allow-uri-read')) {
1452
1464
  this._logWarn(
1453
1465
  `cannot include contents of URI: ${target} (allow-uri-read attribute not enabled)`,
1454
1466
  { sourceLocation: this.cursor }
@@ -176,7 +176,7 @@ export const Substitutors = {
176
176
  *
177
177
  * @param {string|string[]} text - The text to process; must not be null.
178
178
  * @param {string[]} [subs=NORMAL_SUBS] - The substitutions to perform.
179
- * @returns {string|string[]} Text with substitutions applied.
179
+ * @returns {Promise<string|string[]>} Text with substitutions applied.
180
180
  */
181
181
  async applySubs(text, subs = NORMAL_SUBS) {
182
182
  const isEmpty = Array.isArray(text) ? text.length === 0 : text.length === 0
@@ -290,7 +290,7 @@ export const Substitutors = {
290
290
  * Substitute quoted text (emphasis, strong, monospaced, etc.)
291
291
  *
292
292
  * @param {string} text
293
- * @returns {string}
293
+ * @returns {Promise<string>}
294
294
  */
295
295
  async subQuotes(text) {
296
296
  const compat = this.document.compatMode
@@ -462,7 +462,7 @@ export const Substitutors = {
462
462
  * Substitute inline macros (links, images, etc.)
463
463
  *
464
464
  * @param {string} text
465
- * @returns {string}
465
+ * @returns {Promise<string>}
466
466
  */
467
467
  async subMacros(text) {
468
468
  const foundSquareBracket = text.includes('[')
@@ -1357,7 +1357,7 @@ export const Substitutors = {
1357
1357
  * Substitute post replacements (hard line breaks).
1358
1358
  *
1359
1359
  * @param {string} text
1360
- * @returns {string}
1360
+ * @returns {Promise<string>}
1361
1361
  */
1362
1362
  async subPostReplacements(text) {
1363
1363
  if (
@@ -1395,7 +1395,7 @@ export const Substitutors = {
1395
1395
  *
1396
1396
  * @param {string} source
1397
1397
  * @param {boolean} processCallouts
1398
- * @returns {string}
1398
+ * @returns {Promise<string>}
1399
1399
  */
1400
1400
  async subSource(source, processCallouts) {
1401
1401
  return processCallouts
@@ -1407,7 +1407,7 @@ export const Substitutors = {
1407
1407
  * Substitute callout source references.
1408
1408
  *
1409
1409
  * @param {string} text
1410
- * @returns {string}
1410
+ * @returns {Promise<string>}
1411
1411
  */
1412
1412
  async subCallouts(text) {
1413
1413
  const calloutRx = this.hasAttribute('line-comment')
@@ -1436,7 +1436,7 @@ export const Substitutors = {
1436
1436
  *
1437
1437
  * @param {string} source
1438
1438
  * @param {boolean} processCallouts
1439
- * @returns {string}
1439
+ * @returns {Promise<string>}
1440
1440
  */
1441
1441
  async highlightSource(source, processCallouts) {
1442
1442
  const syntaxHl = this.document.syntaxHighlighter
@@ -1782,7 +1782,7 @@ export const Substitutors = {
1782
1782
  * Restore passthrough text by reinserting into placeholder positions.
1783
1783
  *
1784
1784
  * @param {string} text
1785
- * @returns {string}
1785
+ * @returns {Promise<string>}
1786
1786
  */
1787
1787
  async restorePassthroughs(text) {
1788
1788
  if (!text.includes(PASS_START)) return text
@@ -1974,7 +1974,7 @@ export const Substitutors = {
1974
1974
  * @param {string} attrlist
1975
1975
  * @param {string[]} [posattrs=[]]
1976
1976
  * @param {Object} [opts={}]
1977
- * @returns {Object}
1977
+ * @returns {Promise<Object>}
1978
1978
  */
1979
1979
  async parseAttributes(attrlist, posattrs = [], opts = {}) {
1980
1980
  if (!attrlist || attrlist.length === 0) return {}
@@ -234,9 +234,10 @@ export abstract class AbstractNode {
234
234
  * Construct a URI reference or data URI to the target image.
235
235
  *
236
236
  * If the target image is already a URI it is left untouched (unless data-uri
237
- * conversion is requested). The image is resolved relative to the directory
238
- * named by assetDirKey. When data-uri is enabled and the safe level permits,
239
- * the image is embedded as a Base64 data URI.
237
+ * conversion is requested). If the target image is a data URI, then it is
238
+ * already an embedded image, so it is returned as-is. The image is resolved
239
+ * relative to the directory named by assetDirKey. When data-uri is enabled and
240
+ * the safe level permits, the image is embedded as a Base64 data URI.
240
241
  *
241
242
  * NOTE: When the document has both 'data-uri' and 'allow-uri-read' enabled
242
243
  * and the resolved image URL is a remote URI, this method returns a Promise
@@ -469,10 +469,26 @@ export class Document extends AbstractBlock<string> {
469
469
  * @returns {string[]} The list of substitutions to apply.
470
470
  */
471
471
  private _resolveDocinfoSubs;
472
+ /**
473
+ * @private
474
+ * Restore the document attributes to a previously captured snapshot, discarding any
475
+ * body-level (re)assignments replayed while pre-computing text. Mirrors Ruby's
476
+ * restore_attributes-before-convert invariant.
477
+ * @param {Object} snapshot - The attributes snapshot to restore.
478
+ */
479
+ private _restoreAttributeSnapshot;
472
480
  /**
473
481
  * @private
474
482
  * Walk the block tree and pre-compute all async text values.
475
483
  * Handles titles (AbstractBlock), list item text, table cell text, and reftexts.
484
+ *
485
+ * Runs in two passes (see {@link parse}): with `resolveContent` false only titles and
486
+ * reftexts are substituted (so the reftext→id map can be built); with `resolveContent`
487
+ * true the list item / table cell / dlist text is substituted, resolving any natural
488
+ * cross-references against the now-complete map. Title/reftext pre-computation is
489
+ * idempotent (results are cached), so running it in both passes is a no-op the second time.
490
+ * @param {AbstractBlock} block - The block to resolve.
491
+ * @param {boolean} resolveContent - Whether to substitute list item / cell / dlist text.
476
492
  */
477
493
  private _resolveAllTexts;
478
494
  /**
package/types/index.d.cts CHANGED
@@ -54,6 +54,7 @@ import { Section } from './section.js';
54
54
  import { Reader } from './reader.js';
55
55
  import { SyntaxHighlighterBase } from './syntax_highlighter.js';
56
56
  import { LoggerManager } from './logging.js';
57
+ import { LogMessage } from './logging.js';
57
58
  import { MemoryLogger } from './logging.js';
58
59
  import { NullLogger } from './logging.js';
59
60
  import { HttpCache } from './http_cache.js';
@@ -83,4 +84,4 @@ import { deriveBackendTraits } from './converter.js';
83
84
  import { DefaultFactory as DefaultSyntaxHighlighterFactory } from './syntax_highlighter.js';
84
85
  import Html5Converter from './converter/html5.js';
85
86
  import { SyntaxHighlighter } from './syntax_highlighter.js';
86
- export { convert, convertFile, Document, DocumentTitle, Author, Footnote, ImageReference, RevisionInfo, Logger, AbstractNode, AbstractBlock, Inline, Block, List, ListItem, Section, Reader, SyntaxHighlighterBase, LoggerManager, MemoryLogger, NullLogger, HttpCache, MemoryHttpCache, HttpCacheManager, SafeMode, ContentModel, Timings, Registry, Processor, ProcessorExtension, Preprocessor, TreeProcessor, Postprocessor, IncludeProcessor, DocinfoProcessor, BlockProcessor, InlineMacroProcessor, BlockMacroProcessor, Extensions, Cursor, Converter as ConverterFactory, ConverterBase, CustomFactory as ConverterCustomFactory, DefaultConverterFactory, deriveBackendTraits, DefaultSyntaxHighlighterFactory, Html5Converter, SyntaxHighlighter };
87
+ export { convert, convertFile, Document, DocumentTitle, Author, Footnote, ImageReference, RevisionInfo, Logger, AbstractNode, AbstractBlock, Inline, Block, List, ListItem, Section, Reader, SyntaxHighlighterBase, LoggerManager, LogMessage, MemoryLogger, NullLogger, HttpCache, MemoryHttpCache, HttpCacheManager, SafeMode, ContentModel, Timings, Registry, Processor, ProcessorExtension, Preprocessor, TreeProcessor, Postprocessor, IncludeProcessor, DocinfoProcessor, BlockProcessor, InlineMacroProcessor, BlockMacroProcessor, Extensions, Cursor, Converter as ConverterFactory, ConverterBase, CustomFactory as ConverterCustomFactory, DefaultConverterFactory, deriveBackendTraits, DefaultSyntaxHighlighterFactory, Html5Converter, SyntaxHighlighter };
package/types/index.d.ts CHANGED
@@ -53,6 +53,7 @@ import { Section } from './section.js';
53
53
  import { Reader } from './reader.js';
54
54
  import { SyntaxHighlighterBase } from './syntax_highlighter.js';
55
55
  import { LoggerManager } from './logging.js';
56
+ import { LogMessage } from './logging.js';
56
57
  import { MemoryLogger } from './logging.js';
57
58
  import { NullLogger } from './logging.js';
58
59
  import { HttpCache } from './http_cache.js';
@@ -82,4 +83,4 @@ import { deriveBackendTraits } from './converter.js';
82
83
  import { DefaultFactory as DefaultSyntaxHighlighterFactory } from './syntax_highlighter.js';
83
84
  import Html5Converter from './converter/html5.js';
84
85
  import { SyntaxHighlighter } from './syntax_highlighter.js';
85
- export { convert, convertFile, Document, DocumentTitle, Author, Footnote, ImageReference, RevisionInfo, Logger, AbstractNode, AbstractBlock, Inline, Block, List, ListItem, Section, Reader, SyntaxHighlighterBase, LoggerManager, MemoryLogger, NullLogger, HttpCache, MemoryHttpCache, HttpCacheManager, SafeMode, ContentModel, Timings, Registry, Processor, ProcessorExtension, Preprocessor, TreeProcessor, Postprocessor, IncludeProcessor, DocinfoProcessor, BlockProcessor, InlineMacroProcessor, BlockMacroProcessor, Extensions, Cursor, Converter as ConverterFactory, ConverterBase, CustomFactory as ConverterCustomFactory, DefaultConverterFactory, deriveBackendTraits, DefaultSyntaxHighlighterFactory, Html5Converter, SyntaxHighlighter };
86
+ export { convert, convertFile, Document, DocumentTitle, Author, Footnote, ImageReference, RevisionInfo, Logger, AbstractNode, AbstractBlock, Inline, Block, List, ListItem, Section, Reader, SyntaxHighlighterBase, LoggerManager, LogMessage, MemoryLogger, NullLogger, HttpCache, MemoryHttpCache, HttpCacheManager, SafeMode, ContentModel, Timings, Registry, Processor, ProcessorExtension, Preprocessor, TreeProcessor, Postprocessor, IncludeProcessor, DocinfoProcessor, BlockProcessor, InlineMacroProcessor, BlockMacroProcessor, Extensions, Cursor, Converter as ConverterFactory, ConverterBase, CustomFactory as ConverterCustomFactory, DefaultConverterFactory, deriveBackendTraits, DefaultSyntaxHighlighterFactory, Html5Converter, SyntaxHighlighter };
@@ -95,22 +95,66 @@ export namespace Logger {
95
95
  export { BasicFormatter };
96
96
  export namespace AutoFormattingMessage {
97
97
  /**
98
- * Attach auto-formatting to any plain object carrying { text, source_location }.
99
- * @param {{text: string, source_location?: string}} obj
98
+ * Attach auto-formatting to any plain object carrying
99
+ * { text, source_location, include_location }.
100
+ *
101
+ * The location(s) are rendered only by inspect()/toString() (used when a
102
+ * stderr Logger formats the line); the structured `source_location` /
103
+ * `include_location` remain on the object so a MemoryLogger can record them
104
+ * on the resulting LogMessage without duplicating them inside `text`.
105
+ * @param {{text: string, source_location?: any, include_location?: any}} obj
100
106
  * @returns {typeof obj} The same object with inspect() and toString() added.
101
107
  */
102
108
  function attach(obj: {
103
109
  text: string;
104
- source_location?: string;
110
+ source_location?: any;
111
+ include_location?: any;
105
112
  }): typeof obj;
106
113
  }
107
114
  }
115
+ /** Wrapper stored by MemoryLogger; provides getSeverity/getText/getSourceLocation. */
116
+ export class LogMessage {
117
+ /**
118
+ * @param {string} severity - Severity label, e.g. 'ERROR'.
119
+ * @param {string|{text: string, source_location?: import('./reader.js').Cursor}|null} message
120
+ */
121
+ constructor(severity: string, message: string | {
122
+ text: string;
123
+ source_location?: import("./reader.js").Cursor;
124
+ } | null);
125
+ message: string | {
126
+ text: string;
127
+ source_location?: import("./reader.js").Cursor;
128
+ };
129
+ /** @type {string} */
130
+ severity: string;
131
+ /** @type {string} */
132
+ text: string;
133
+ /** @type {import('./reader.js').Cursor|null} */
134
+ sourceLocation: import("./reader.js").Cursor | null;
135
+ /**
136
+ * @returns {string} The severity label, e.g. 'ERROR'.
137
+ */
138
+ getSeverity(): string;
139
+ /**
140
+ * @returns {string} The message text.
141
+ */
142
+ getText(): string;
143
+ /**
144
+ * @returns {import('./reader.js').Cursor|undefined} The source location, if any.
145
+ */
146
+ getSourceLocation(): import("./reader.js").Cursor | undefined;
147
+ }
108
148
  /** In-memory logger that stores all log messages for later inspection. */
109
149
  export class MemoryLogger {
110
150
  static create(): MemoryLogger;
111
151
  level: number;
112
- messages: any[];
113
- getMessages(): any[];
152
+ /** @type {LogMessage[]} */
153
+ messages: LogMessage[];
154
+ /**
155
+ * @returns {LogMessage[]} The log messages recorded so far, in order.
156
+ */
157
+ getMessages(): LogMessage[];
114
158
  getMaxSeverity(): number;
115
159
  add(severity: any, message?: any, progname?: any): boolean;
116
160
  debug(msg: any, pn: any): boolean;
package/types/reader.d.ts CHANGED
@@ -123,13 +123,13 @@ export class Reader {
123
123
  createLogMessage(text: any, context?: {}): any;
124
124
  get logger(): any;
125
125
  /** @param {string} msg @param {{ sourceLocation?: any, includeLocation?: any }} [opts] */
126
- _logWarn(msg: string, { sourceLocation, includeLocation }?: {
126
+ _logWarn(msg: string, opts?: {
127
127
  sourceLocation?: any;
128
128
  includeLocation?: any;
129
129
  }): void;
130
130
  _logError(msg: any, opts?: {}): void;
131
131
  /** @param {string} msg @param {{ sourceLocation?: any }} [opts] */
132
- _logInfo(msg: string, { sourceLocation }?: {
132
+ _logInfo(msg: string, opts?: {
133
133
  sourceLocation?: any;
134
134
  }): void;
135
135
  }
@@ -4,9 +4,9 @@ export namespace Substitutors {
4
4
  *
5
5
  * @param {string|string[]} text - The text to process; must not be null.
6
6
  * @param {string[]} [subs=NORMAL_SUBS] - The substitutions to perform.
7
- * @returns {string|string[]} Text with substitutions applied.
7
+ * @returns {Promise<string|string[]>} Text with substitutions applied.
8
8
  */
9
- function applySubs(text: string | string[], subs?: string[]): string | string[];
9
+ function applySubs(text: string | string[], subs?: string[]): Promise<string | string[]>;
10
10
  /** Apply normal substitutions (alias for applySubs with default args). */
11
11
  function applyNormalSubs(text: any): Promise<string | string[]>;
12
12
  /** Apply substitutions for header metadata and attribute assignments.
@@ -32,9 +32,9 @@ export namespace Substitutors {
32
32
  * Substitute quoted text (emphasis, strong, monospaced, etc.)
33
33
  *
34
34
  * @param {string} text
35
- * @returns {string}
35
+ * @returns {Promise<string>}
36
36
  */
37
- function subQuotes(text: string): string;
37
+ function subQuotes(text: string): Promise<string>;
38
38
  /**
39
39
  * Substitute attribute references in the specified text.
40
40
  *
@@ -54,39 +54,39 @@ export namespace Substitutors {
54
54
  * Substitute inline macros (links, images, etc.)
55
55
  *
56
56
  * @param {string} text
57
- * @returns {string}
57
+ * @returns {Promise<string>}
58
58
  */
59
- function subMacros(text: string): string;
59
+ function subMacros(text: string): Promise<string>;
60
60
  /**
61
61
  * Substitute post replacements (hard line breaks).
62
62
  *
63
63
  * @param {string} text
64
- * @returns {string}
64
+ * @returns {Promise<string>}
65
65
  */
66
- function subPostReplacements(text: string): string;
66
+ function subPostReplacements(text: string): Promise<string>;
67
67
  /**
68
68
  * Apply verbatim substitutions on source.
69
69
  *
70
70
  * @param {string} source
71
71
  * @param {boolean} processCallouts
72
- * @returns {string}
72
+ * @returns {Promise<string>}
73
73
  */
74
- function subSource(source: string, processCallouts: boolean): string;
74
+ function subSource(source: string, processCallouts: boolean): Promise<string>;
75
75
  /**
76
76
  * Substitute callout source references.
77
77
  *
78
78
  * @param {string} text
79
- * @returns {string}
79
+ * @returns {Promise<string>}
80
80
  */
81
- function subCallouts(text: string): string;
81
+ function subCallouts(text: string): Promise<string>;
82
82
  /**
83
83
  * Highlight (colorize) the source code using a syntax highlighter.
84
84
  *
85
85
  * @param {string} source
86
86
  * @param {boolean} processCallouts
87
- * @returns {string}
87
+ * @returns {Promise<string>}
88
88
  */
89
- function highlightSource(source: string, processCallouts: boolean): string;
89
+ function highlightSource(source: string, processCallouts: boolean): Promise<string>;
90
90
  /**
91
91
  * Resolve line numbers to highlight from a test string.
92
92
  *
@@ -107,9 +107,9 @@ export namespace Substitutors {
107
107
  * Restore passthrough text by reinserting into placeholder positions.
108
108
  *
109
109
  * @param {string} text
110
- * @returns {string}
110
+ * @returns {Promise<string>}
111
111
  */
112
- function restorePassthroughs(text: string): string;
112
+ function restorePassthroughs(text: string): Promise<string>;
113
113
  /**
114
114
  * Resolve the list of comma-delimited subs against the possible options.
115
115
  *
@@ -143,9 +143,9 @@ export namespace Substitutors {
143
143
  * @param {string} attrlist
144
144
  * @param {string[]} [posattrs=[]]
145
145
  * @param {Object} [opts={}]
146
- * @returns {Object}
146
+ * @returns {Promise<Object>}
147
147
  */
148
- function parseAttributes(attrlist: string, posattrs?: string[], opts?: any): any;
148
+ function parseAttributes(attrlist: string, posattrs?: string[], opts?: any): Promise<any>;
149
149
  function extractAttributesFromText(text: any, defaultText?: any): Promise<any[]>;
150
150
  function extractCallouts(source: any): any[];
151
151
  function restoreCallouts(source: any, calloutMarks: any, sourceOffset?: any): Promise<string>;