@podlite/schema 0.0.66 → 0.0.68

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.
Files changed (76) hide show
  1. package/CHANGELOG.podlite +44 -0
  2. package/esm/ast-helpers.d.ts +25 -1
  3. package/esm/ast-helpers.js +101 -2
  4. package/esm/ast-helpers.js.map +1 -1
  5. package/esm/attribute-names.d.ts +5 -0
  6. package/esm/attribute-names.js +36 -0
  7. package/esm/attribute-names.js.map +1 -0
  8. package/esm/block-names.d.ts +1 -0
  9. package/esm/block-names.js +6 -1
  10. package/esm/block-names.js.map +1 -1
  11. package/esm/exportAny.js +2 -2
  12. package/esm/exportAny.js.map +1 -1
  13. package/esm/exportHtml.js +60 -22
  14. package/esm/exportHtml.js.map +1 -1
  15. package/esm/exportMarkdown.js +62 -52
  16. package/esm/exportMarkdown.js.map +1 -1
  17. package/esm/folded-sections.d.ts +1 -0
  18. package/esm/folded-sections.js +80 -0
  19. package/esm/folded-sections.js.map +1 -0
  20. package/esm/grammarfc.js +6099 -15834
  21. package/esm/grammarfc.js.map +1 -1
  22. package/esm/guard.d.ts +5 -0
  23. package/esm/guard.js +39 -0
  24. package/esm/guard.js.map +1 -0
  25. package/esm/helpers/corePlugins.js +9 -3
  26. package/esm/helpers/corePlugins.js.map +1 -1
  27. package/esm/helpers/html-attr.d.ts +1 -0
  28. package/esm/helpers/html-attr.js +6 -0
  29. package/esm/helpers/html-attr.js.map +1 -0
  30. package/esm/index.d.ts +6 -2
  31. package/esm/index.js +6 -2
  32. package/esm/index.js.map +1 -1
  33. package/esm/pluggableParser.d.ts +1 -1
  34. package/esm/pluggableParser.js +7 -1
  35. package/esm/pluggableParser.js.map +1 -1
  36. package/esm/plugin-data-table.js +2 -1
  37. package/esm/plugin-data-table.js.map +1 -1
  38. package/esm/plugin-tables.js +5 -2
  39. package/esm/plugin-tables.js.map +1 -1
  40. package/esm/selectors.d.ts +1 -0
  41. package/esm/selectors.js +42 -19
  42. package/esm/selectors.js.map +1 -1
  43. package/esm/types.d.ts +30 -16
  44. package/esm/version.d.ts +1 -1
  45. package/esm/version.js +1 -1
  46. package/lib/ast-helpers.d.ts +25 -1
  47. package/lib/ast-helpers.js +106 -3
  48. package/lib/attribute-names.d.ts +5 -0
  49. package/lib/attribute-names.js +41 -0
  50. package/lib/block-names.d.ts +1 -0
  51. package/lib/block-names.js +8 -2
  52. package/lib/exportAny.js +1 -1
  53. package/lib/exportHtml.js +62 -24
  54. package/lib/exportMarkdown.js +61 -51
  55. package/lib/folded-sections.d.ts +1 -0
  56. package/lib/folded-sections.js +84 -0
  57. package/lib/grammarfc.js +6099 -15834
  58. package/lib/guard.d.ts +5 -0
  59. package/lib/guard.js +47 -0
  60. package/lib/helpers/corePlugins.js +9 -3
  61. package/lib/helpers/html-attr.d.ts +1 -0
  62. package/lib/helpers/html-attr.js +10 -0
  63. package/lib/index.d.ts +6 -2
  64. package/lib/index.js +11 -1
  65. package/lib/pluggableParser.d.ts +1 -1
  66. package/lib/pluggableParser.js +8 -1
  67. package/lib/plugin-data-table.js +2 -1
  68. package/lib/plugin-tables.js +5 -2
  69. package/lib/selectors.d.ts +1 -0
  70. package/lib/selectors.js +44 -20
  71. package/lib/types.d.ts +30 -16
  72. package/lib/version.d.ts +1 -1
  73. package/lib/version.js +1 -1
  74. package/package.json +1 -1
  75. package/schema/AstTree.json +626 -405
  76. package/schema/PodliteDocument.json +626 -405
package/lib/guard.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ export declare const isCovered: (node: unknown, ctx?: {
2
+ maskMode?: boolean;
3
+ renderMode?: string;
4
+ }) => boolean;
5
+ export declare const markGuarded: <T>(node: T, inherited?: boolean) => T;
package/lib/guard.js ADDED
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.markGuarded = exports.isCovered = void 0;
7
+ const config_1 = __importDefault(require("./helpers/config"));
8
+ // Covered content is marked on the node, not decided at render time. A block
9
+ // carrying :masked or a G<> code can be lifted out of its document by =include,
10
+ // by a data: reference, by an alias expansion or by a selector; the mark travels
11
+ // with the node, so whatever pulls the node out cannot strip the cover off it.
12
+ const GUARD_CODE = 'G';
13
+ const isGuardCode = (node) => node.type === 'fcode' && node.name === GUARD_CODE;
14
+ const isMaskedBlock = (node) => {
15
+ if (node.type !== 'block')
16
+ return false;
17
+ const conf = (0, config_1.default)(node, {});
18
+ return conf.exists('masked') && Boolean(conf.getFirstValue('masked'));
19
+ };
20
+ // The mark says the content is covered; the render mode says whether the cover
21
+ // is applied. Draft shows what production hides, and the mark alone must not
22
+ // override that.
23
+ const isCovered = (node, ctx) => {
24
+ if (ctx?.maskMode)
25
+ return true;
26
+ if (ctx?.renderMode === 'draft')
27
+ return false;
28
+ return Boolean(node?.guarded);
29
+ };
30
+ exports.isCovered = isCovered;
31
+ const markGuarded = (node, inherited = false) => {
32
+ if (!node || typeof node !== 'object')
33
+ return node;
34
+ if (Array.isArray(node)) {
35
+ node.forEach(child => (0, exports.markGuarded)(child, inherited));
36
+ return node;
37
+ }
38
+ const target = node;
39
+ const covered = inherited || target.guarded === true || isGuardCode(target) || isMaskedBlock(target);
40
+ if (covered)
41
+ target.guarded = true;
42
+ if (Array.isArray(target.content))
43
+ target.content.forEach(child => (0, exports.markGuarded)(child, covered));
44
+ return node;
45
+ };
46
+ exports.markGuarded = markGuarded;
47
+ //# sourceMappingURL=guard.js.map
@@ -2,14 +2,20 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.core = void 0;
4
4
  const __1 = require("..");
5
+ const ast_helpers_1 = require("../ast-helpers");
6
+ const html_attr_1 = require("./html-attr");
5
7
  exports.core = {
6
8
  ':image': {
7
9
  toHtml: writer => node => {
8
10
  if (typeof node !== 'string' && 'type' in node && node.type === 'image') {
9
11
  writer.writeRaw(`<img`);
10
- writer.writeRaw(` src="${node.src}"`);
11
- if (node.alt) {
12
- writer.writeRaw(` alt="${node.alt}"`);
12
+ writer.writeRaw(` src="${(0, html_attr_1.quoteAttribute)(String(node.src ?? ''))}"`);
13
+ // html reads a missing alt as "this image is part of the content" and an
14
+ // empty one as "decorative", so an alternative text the author never wrote
15
+ // is left out
16
+ const alt = (0, ast_helpers_1.writtenValue)(node.alt);
17
+ if (alt !== undefined) {
18
+ writer.writeRaw(` alt="${(0, html_attr_1.quoteAttribute)(alt)}"`);
13
19
  }
14
20
  writer.writeRaw(`/>`);
15
21
  }
@@ -0,0 +1 @@
1
+ export declare const quoteAttribute: (value: string) => string;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.quoteAttribute = void 0;
4
+ // The value of an attribute written inside double quotes. The ampersand goes
5
+ // first: escaping it after the quote would rewrite the `&quot;` this produced. A
6
+ // value arrives as document text, so every `&` in it is a literal one the
7
+ // browser must not read as a character reference.
8
+ const quoteAttribute = (value) => value.replace(/&/g, '&amp;').replace(/"/g, '&quot;');
9
+ exports.quoteAttribute = quoteAttribute;
10
+ //# sourceMappingURL=html-attr.js.map
package/lib/index.d.ts CHANGED
@@ -4,6 +4,7 @@ export { PodliteDocument } from './types';
4
4
  export { AstTree } from './types';
5
5
  export * from './types';
6
6
  export * from './block-names';
7
+ export * from './attribute-names';
7
8
  export * from './blocks-helpers';
8
9
  export * from './query-helpers';
9
10
  export * from './ast-helpers';
@@ -14,10 +15,11 @@ export { toAny } from './exportAny';
14
15
  export { makeAttrs, codeConfigWithDefaults } from './helpers/config';
15
16
  export { parseAttributes } from './helpers/parseAttributes';
16
17
  export { readLinkConfig } from './helpers/link-config';
18
+ export { quoteAttribute } from './helpers/html-attr';
17
19
  export type { LinkConfig } from './helpers/link-config';
18
20
  export { pluginCleanLocation } from './plugin-clean-location';
19
21
  export { toAnyRules } from './helpers/plugins';
20
- export { podlitePluggable, Podlite, PodliteExport, cleanIds, frozenIds } from './pluggableParser';
22
+ export { podlitePluggable, Podlite, PodliteExport, cleanIds, frozenIds, headingId } from './pluggableParser';
21
23
  export declare function toAst(): {};
22
24
  export type SchemaValidationError = ErrorObject<string, Record<string, any>>;
23
25
  export declare function getTextContentFromNode(node: PodNode): string;
@@ -87,7 +89,9 @@ export declare const parseFormattingCodes: (text: string, options?: {
87
89
  export { default as toHtml } from './exportHtml';
88
90
  export { default as toMarkdown } from './exportMarkdown';
89
91
  export { default as Writer } from './writer';
90
- export { parseSelector, runSelector } from './selectors';
92
+ export { parseSelector, runSelector, filePathMatches } from './selectors';
93
+ export { markGuarded, isCovered } from './guard';
94
+ export { applyFoldedSections } from './folded-sections';
91
95
  export type { SelectorDoc, ParsedSelector } from './selectors';
92
96
  export { applyImageBase } from './image-base';
93
97
  export { version } from './version';
package/lib/index.js CHANGED
@@ -39,7 +39,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
39
39
  return (mod && mod.__esModule) ? mod : { "default": mod };
40
40
  };
41
41
  Object.defineProperty(exports, "__esModule", { value: true });
42
- exports.version = exports.applyImageBase = exports.runSelector = exports.parseSelector = exports.Writer = exports.toMarkdown = exports.toHtml = exports.parseFormattingCodes = exports.parse = exports.frozenIds = exports.cleanIds = exports.podlitePluggable = exports.toAnyRules = exports.pluginCleanLocation = exports.readLinkConfig = exports.parseAttributes = exports.codeConfigWithDefaults = exports.makeAttrs = exports.toAny = exports.isSemanticBlock = exports.isNamedBlock = exports.makeTransformer = exports.makeInterator = void 0;
42
+ exports.version = exports.applyImageBase = exports.applyFoldedSections = exports.isCovered = exports.markGuarded = exports.filePathMatches = exports.runSelector = exports.parseSelector = exports.Writer = exports.toMarkdown = exports.toHtml = exports.parseFormattingCodes = exports.parse = exports.headingId = exports.frozenIds = exports.cleanIds = exports.podlitePluggable = exports.toAnyRules = exports.pluginCleanLocation = exports.quoteAttribute = exports.readLinkConfig = exports.parseAttributes = exports.codeConfigWithDefaults = exports.makeAttrs = exports.toAny = exports.isSemanticBlock = exports.isNamedBlock = exports.makeTransformer = exports.makeInterator = void 0;
43
43
  exports.toAst = toAst;
44
44
  exports.getTextContentFromNode = getTextContentFromNode;
45
45
  exports.getPodContentFromNode = getPodContentFromNode;
@@ -55,6 +55,7 @@ const jsonShemes = __importStar(require("../schema"));
55
55
  const ast_inerator_1 = require("./ast-inerator");
56
56
  __exportStar(require("./types"), exports);
57
57
  __exportStar(require("./block-names"), exports);
58
+ __exportStar(require("./attribute-names"), exports);
58
59
  __exportStar(require("./blocks-helpers"), exports);
59
60
  __exportStar(require("./query-helpers"), exports);
60
61
  __exportStar(require("./ast-helpers"), exports);
@@ -74,6 +75,8 @@ var parseAttributes_1 = require("./helpers/parseAttributes");
74
75
  Object.defineProperty(exports, "parseAttributes", { enumerable: true, get: function () { return parseAttributes_1.parseAttributes; } });
75
76
  var link_config_1 = require("./helpers/link-config");
76
77
  Object.defineProperty(exports, "readLinkConfig", { enumerable: true, get: function () { return link_config_1.readLinkConfig; } });
78
+ var html_attr_1 = require("./helpers/html-attr");
79
+ Object.defineProperty(exports, "quoteAttribute", { enumerable: true, get: function () { return html_attr_1.quoteAttribute; } });
77
80
  var plugin_clean_location_1 = require("./plugin-clean-location");
78
81
  Object.defineProperty(exports, "pluginCleanLocation", { enumerable: true, get: function () { return plugin_clean_location_1.pluginCleanLocation; } });
79
82
  var plugins_1 = require("./helpers/plugins");
@@ -82,6 +85,7 @@ var pluggableParser_1 = require("./pluggableParser");
82
85
  Object.defineProperty(exports, "podlitePluggable", { enumerable: true, get: function () { return pluggableParser_1.podlitePluggable; } });
83
86
  Object.defineProperty(exports, "cleanIds", { enumerable: true, get: function () { return pluggableParser_1.cleanIds; } });
84
87
  Object.defineProperty(exports, "frozenIds", { enumerable: true, get: function () { return pluggableParser_1.frozenIds; } });
88
+ Object.defineProperty(exports, "headingId", { enumerable: true, get: function () { return pluggableParser_1.headingId; } });
85
89
  const parser = __importStar(require("./grammar"));
86
90
  const grammarfc_1 = require("./grammarfc");
87
91
  const parseAttributes_2 = require("./helpers/parseAttributes");
@@ -226,6 +230,12 @@ Object.defineProperty(exports, "Writer", { enumerable: true, get: function () {
226
230
  var selectors_1 = require("./selectors");
227
231
  Object.defineProperty(exports, "parseSelector", { enumerable: true, get: function () { return selectors_1.parseSelector; } });
228
232
  Object.defineProperty(exports, "runSelector", { enumerable: true, get: function () { return selectors_1.runSelector; } });
233
+ Object.defineProperty(exports, "filePathMatches", { enumerable: true, get: function () { return selectors_1.filePathMatches; } });
234
+ var guard_1 = require("./guard");
235
+ Object.defineProperty(exports, "markGuarded", { enumerable: true, get: function () { return guard_1.markGuarded; } });
236
+ Object.defineProperty(exports, "isCovered", { enumerable: true, get: function () { return guard_1.isCovered; } });
237
+ var folded_sections_1 = require("./folded-sections");
238
+ Object.defineProperty(exports, "applyFoldedSections", { enumerable: true, get: function () { return folded_sections_1.applyFoldedSections; } });
229
239
  var image_base_1 = require("./image-base");
230
240
  Object.defineProperty(exports, "applyImageBase", { enumerable: true, get: function () { return image_base_1.applyImageBase; } });
231
241
  var version_1 = require("./version");
@@ -1,5 +1,5 @@
1
1
  import { Plugins, PodliteDocument, parseOpt } from '.';
2
- export { cleanIds, frozenIds } from './helpers/ids';
2
+ export { cleanIds, frozenIds, headingId } from './helpers/ids';
3
3
  export interface podlitePluggableOpt {
4
4
  plugins?: Plugins;
5
5
  }
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.podlitePluggable = exports.frozenIds = exports.cleanIds = void 0;
6
+ exports.podlitePluggable = exports.headingId = exports.frozenIds = exports.cleanIds = void 0;
7
7
  const _1 = require(".");
8
8
  const exportMarkdown_1 = __importDefault(require("./exportMarkdown"));
9
9
  const ids_1 = __importDefault(require("./helpers/ids"));
@@ -11,9 +11,12 @@ const corePlugins_1 = __importDefault(require("./helpers/corePlugins"));
11
11
  const configPropagation_1 = require("./helpers/configPropagation");
12
12
  const headingNumbering_1 = require("./helpers/headingNumbering");
13
13
  const itemNumbering_1 = require("./helpers/itemNumbering");
14
+ const guard_1 = require("./guard");
15
+ const folded_sections_1 = require("./folded-sections");
14
16
  var ids_2 = require("./helpers/ids");
15
17
  Object.defineProperty(exports, "cleanIds", { enumerable: true, get: function () { return ids_2.cleanIds; } });
16
18
  Object.defineProperty(exports, "frozenIds", { enumerable: true, get: function () { return ids_2.frozenIds; } });
19
+ Object.defineProperty(exports, "headingId", { enumerable: true, get: function () { return ids_2.headingId; } });
17
20
  const podlitePluggable = ({ plugins = {} } = {}) => {
18
21
  let instance = function () { };
19
22
  let _plugins = [];
@@ -78,6 +81,8 @@ const podlitePluggable = ({ plugins = {} } = {}) => {
78
81
  (0, configPropagation_1.propagateConfigDefaults)(resultAfter.interator);
79
82
  (0, itemNumbering_1.promoteOrderedLists)(resultAfter.interator);
80
83
  (0, headingNumbering_1.attachHeadingNumberPrefix)(resultAfter.interator);
84
+ (0, guard_1.markGuarded)(resultAfter.interator);
85
+ resultAfter.interator = (0, folded_sections_1.applyFoldedSections)(resultAfter.interator);
81
86
  }
82
87
  return resultAfter;
83
88
  }
@@ -85,6 +90,8 @@ const podlitePluggable = ({ plugins = {} } = {}) => {
85
90
  (0, configPropagation_1.propagateConfigDefaults)(result.interator);
86
91
  (0, itemNumbering_1.promoteOrderedLists)(result.interator);
87
92
  (0, headingNumbering_1.attachHeadingNumberPrefix)(result.interator);
93
+ (0, guard_1.markGuarded)(result.interator);
94
+ result.interator = (0, folded_sections_1.applyFoldedSections)(result.interator);
88
95
  }
89
96
  return result;
90
97
  };
@@ -43,7 +43,8 @@ function resolveColumnIndex(col, headerRow, maxCols) {
43
43
  }
44
44
  const idx = headerRow.indexOf(col);
45
45
  if (idx === -1) {
46
- throw new Error(`column name "${col}" not found in header`);
46
+ const names = headerRow.map(h => `"${h}"`).join(', ');
47
+ throw new Error(`column name "${col}" not found in header; header has ${names}`);
47
48
  }
48
49
  return idx;
49
50
  }
@@ -508,6 +508,9 @@ exports.default = (opt = {}) => tree => {
508
508
  report('table-source-unreadable', `no =data block found for data:${ref.target}, table rendered as empty`, node);
509
509
  return { ...node, content: [] };
510
510
  }
511
+ // whatever is built out of a covered =data block is covered as well,
512
+ // otherwise the table is a way to read what the cover hides
513
+ const carryCover = built => (0, config_1.default)(dataBlock, {}).getFirstValue('masked') ? { ...built, guarded: true } : built;
511
514
  const rawMime = (0, config_1.default)(dataBlock, {}).getFirstValue('mime-type');
512
515
  const { type: mimeType, params: mimeParams } = parseMimeType(rawMime);
513
516
  const isCsv = mimeType === 'text/csv';
@@ -522,11 +525,11 @@ exports.default = (opt = {}) => tree => {
522
525
  const hasHeader = mimeParams.header === 'present';
523
526
  const allow = (0, config_1.default)(node, {}).getAllValues('allow');
524
527
  const filledNode = { ...node, content: csvToTableContent(rows, hasHeader, allow) };
525
- return normalizeCellCounts(filledNode, `table data:${ref.target}`, report);
528
+ return carryCover(normalizeCellCounts(filledNode, `table data:${ref.target}`, report));
526
529
  }
527
530
  // Rule 4: source not tabular → render as code block so content remains visible
528
531
  report('table-source-unreadable', `=data :key<${ref.target}> has non-tabular mime-type ${rawMime || '(none)'}, rendered as =code`, node);
529
- return buildCodeFromDataBlock(node, dataBlock);
532
+ return carryCover(buildCodeFromDataBlock(node, dataBlock));
530
533
  }
531
534
  // structured mode: transform row children (wrap implicit cells), then
532
535
  // apply Rule 2 cell count normalization.
@@ -31,4 +31,5 @@ export type ParsedSelector = {
31
31
  patterns: Pattern[];
32
32
  };
33
33
  export declare const parseSelector: (selector: string) => ParsedSelector | undefined;
34
+ export declare const filePathMatches: (docFile: string, target: string) => boolean;
34
35
  export declare const runSelector: <T extends SelectorDoc>(selector: string, docs: T[]) => T[] | PodNode[];
package/lib/selectors.js CHANGED
@@ -1,7 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.runSelector = exports.parseSelector = void 0;
3
+ exports.runSelector = exports.filePathMatches = exports.parseSelector = void 0;
4
4
  const index_1 = require("./index");
5
+ const parseAttributes_1 = require("./helpers/parseAttributes");
5
6
  // --- predicate parser ---------------------------------------------------
6
7
  const isIdentStart = (c) => /[a-zA-Z_]/.test(c);
7
8
  const isIdentCont = (c) => /[a-zA-Z0-9_-]/.test(c);
@@ -229,6 +230,39 @@ const parseSelector = (selector) => {
229
230
  return undefined;
230
231
  };
231
232
  exports.parseSelector = parseSelector;
233
+ // The operand is read by the same grammar as a declaration: the delimiters
234
+ // around it decide whether it is a string, a list or a number. Reading it as
235
+ // raw text would put values out of reach that a document can hold — a quoted
236
+ // string among them.
237
+ const readOperand = (raw) => {
238
+ const [item] = (0, parseAttributes_1.parseAttributes)(`:x<${raw}>`);
239
+ return item ? { value: item.value, type: item.type } : undefined;
240
+ };
241
+ // The declared value with its kind kept. makeAttrs flattens a list into the
242
+ // surrounding values, which loses the very thing equality compares.
243
+ const declaredValue = (node, name, ctx) => {
244
+ const anyNode = node;
245
+ const own = (Array.isArray(anyNode.config) ? anyNode.config : []).find(c => c && c.name === name);
246
+ if (own)
247
+ return { value: own.value, type: own.type };
248
+ const configured = (anyNode.name && ctx.config?.[anyNode.name]) || [];
249
+ const inherited = configured.find(c => c && c.name === name);
250
+ return inherited ? { value: inherited.value, type: inherited.type } : undefined;
251
+ };
252
+ const sameScalar = (a, b) => typeof a === typeof b && a === b;
253
+ // A list equals another list when their elements match one by one, in order; a
254
+ // value of one kind never equals a value of another.
255
+ const sameValue = (a, b) => {
256
+ if (Array.isArray(a.value) || Array.isArray(b.value)) {
257
+ if (!Array.isArray(a.value) || !Array.isArray(b.value))
258
+ return false;
259
+ return a.value.length === b.value.length && a.value.every((item, i) => sameScalar(item, b.value[i]));
260
+ }
261
+ return sameScalar(a.value, b.value);
262
+ };
263
+ // Membership runs over the values as declared. A string is one value, even
264
+ // when it holds spaces, so a word taken from its middle is not a member.
265
+ const valuesOf = (typed) => (Array.isArray(typed.value) ? typed.value : [typed.value]);
232
266
  const matchCondition = (node, cond, ctx) => {
233
267
  const attrs = (0, index_1.makeAttrs)(node, ctx);
234
268
  const exists = attrs.exists(cond.attrName);
@@ -244,30 +278,19 @@ const matchCondition = (node, cond, ctx) => {
244
278
  return !exists;
245
279
  }
246
280
  }
281
+ const declared = declaredValue(node, cond.attrName, ctx);
282
+ const operand = readOperand(cond.valueSpec.value);
247
283
  if (cond.valueSpec.kind === 'angle') {
248
- if (!exists)
284
+ if (!exists || !declared || !operand)
249
285
  return false;
250
- const equal = String(attrs.getFirstValue(cond.attrName)) === cond.valueSpec.value;
286
+ const equal = sameValue(declared, operand);
251
287
  return cond.modifier === '!' ? !equal : equal;
252
288
  }
253
289
  if (cond.valueSpec.kind === 'contains') {
254
- if (!exists)
290
+ if (!exists || !declared || !operand)
255
291
  return false;
256
- // Author-facing semantics: `:tags<a b c>` is a list of three elements.
257
- // Grammar parses unquoted identifier sequences as a single string, so
258
- // split string values on whitespace/comma to recover list shape.
259
- const tokens = [];
260
- for (const v of attrs.getAllValues(cond.attrName)) {
261
- if (typeof v === 'string') {
262
- for (const t of v.split(/[\s,]+/))
263
- if (t)
264
- tokens.push(t);
265
- }
266
- else {
267
- tokens.push(String(v));
268
- }
269
- }
270
- const present = tokens.includes(cond.valueSpec.value);
292
+ const values = valuesOf(declared);
293
+ const present = valuesOf(operand).every(wanted => values.some(held => sameScalar(held, wanted)));
271
294
  return cond.modifier === '!' ? !present : present;
272
295
  }
273
296
  return false;
@@ -388,6 +411,7 @@ const filePathMatches = (docFile, target) => {
388
411
  }
389
412
  return a === b || a.endsWith('/' + b) || b.endsWith('/' + a);
390
413
  };
414
+ exports.filePathMatches = filePathMatches;
391
415
  const getDocIDs = (doc) => {
392
416
  const ids = [];
393
417
  (0, index_1.getFromTree)(doc.node, 'NAME', 'TITLE').forEach(block => {
@@ -421,7 +445,7 @@ const runSelector = (selector, docs) => {
421
445
  matchedDocs = docs.filter(doc => getDocIDs(doc).includes(document));
422
446
  }
423
447
  else if (scheme === 'file' && document) {
424
- matchedDocs = docs.filter(doc => filePathMatches(doc.file, document));
448
+ matchedDocs = docs.filter(doc => (0, exports.filePathMatches)(doc.file, document));
425
449
  }
426
450
  else if (scheme && scheme !== 'doc' && scheme !== 'file') {
427
451
  return [];
package/lib/types.d.ts CHANGED
@@ -100,11 +100,16 @@ export interface Image {
100
100
  alt?: string;
101
101
  link?: string;
102
102
  }
103
+ export interface ParaBuilt {
104
+ type: 'para';
105
+ content: Array<Node | FormattingCodes>;
106
+ }
103
107
  export interface Toc {
104
108
  type: 'toc';
105
109
  title?: string;
106
110
  folded?: boolean;
107
111
  foldedLevels?: Record<number, boolean>;
112
+ location?: Location;
108
113
  content: TocList;
109
114
  }
110
115
  export interface TocList {
@@ -114,8 +119,8 @@ export interface TocList {
114
119
  }
115
120
  export interface TocItem {
116
121
  type: 'toc-item';
117
- node: PodNode;
118
- content: Array<Node>;
122
+ node: PodNode | ParaBuilt;
123
+ content: Array<Node | ParaBuilt>;
119
124
  }
120
125
  export interface BlockImage extends Omit<Block, 'content'> {
121
126
  name: 'image';
@@ -152,7 +157,7 @@ export interface FormattingCodeB {
152
157
  export interface FormattingCodeC {
153
158
  type: 'fcode';
154
159
  name: 'C';
155
- content?: Array<FormattingCodes | string>;
160
+ content?: Array<Node>;
156
161
  }
157
162
  export interface FormattingCodeE {
158
163
  type: 'fcode';
@@ -179,23 +184,23 @@ export interface FormattingCodeF {
179
184
  export interface FormattingCodeN {
180
185
  type: 'fcode';
181
186
  name: 'N';
182
- content?: Array<FormattingCodes | string>;
187
+ content?: Array<Node>;
183
188
  }
184
189
  export interface FormattingCodeX {
185
190
  type: 'fcode';
186
191
  name: 'X';
187
192
  entry: Array<string> | null;
188
- content?: Array<FormattingCodes | string>;
193
+ content?: Array<Node>;
189
194
  }
190
195
  export interface FormattingCodeZ {
191
196
  type: 'fcode';
192
197
  name: 'Z';
193
- content?: string;
198
+ content?: string | Text;
194
199
  }
195
200
  export interface FormattingCodeV {
196
201
  type: 'fcode';
197
202
  name: 'V';
198
- content?: string;
203
+ content?: string | Text;
199
204
  }
200
205
  export interface FormattingCodeS {
201
206
  type: 'fcode';
@@ -211,7 +216,7 @@ export interface FormattingCodeD {
211
216
  type: 'fcode';
212
217
  name: 'D';
213
218
  synonyms: Array<string>;
214
- content: string;
219
+ content: Array<Node>;
215
220
  }
216
221
  export interface FormattingCodeL {
217
222
  type: 'fcode';
@@ -225,18 +230,18 @@ export interface FormattingCodeW {
225
230
  name: 'W';
226
231
  meta: string | null;
227
232
  config?: ConfigItem[];
228
- content: string | Text | [Text];
233
+ content: Array<Node>;
229
234
  }
230
235
  export interface FormattingCodeI {
231
236
  type: 'fcode';
232
237
  name: 'I';
233
- meta: string;
234
- content: string | Text;
238
+ meta?: string;
239
+ content: Array<Node>;
235
240
  }
236
241
  export interface FormattingCodeAny {
237
242
  type: 'fcode';
238
243
  name: string;
239
- content?: Array<FormattingCodes | string>;
244
+ content?: Array<Node>;
240
245
  }
241
246
  export interface Ambient {
242
247
  type: 'ambient';
@@ -246,10 +251,12 @@ export interface Ambient {
246
251
  export interface Verbatim {
247
252
  type: 'verbatim';
248
253
  value: string;
254
+ guarded?: boolean;
249
255
  }
250
256
  export interface Text {
251
257
  type: 'text';
252
258
  value: string;
259
+ guarded?: boolean;
253
260
  }
254
261
  export interface Para {
255
262
  type: 'para';
@@ -258,6 +265,12 @@ export interface Para {
258
265
  location: Location;
259
266
  content: Array<Node | FormattingCodes>;
260
267
  }
268
+ export interface ParaTerm {
269
+ type: 'para';
270
+ name: 'term';
271
+ text: string;
272
+ content: Array<Node | FormattingCodes>;
273
+ }
261
274
  export interface Code {
262
275
  type: 'code';
263
276
  text: string;
@@ -271,8 +284,8 @@ export interface BlankLine {
271
284
  export interface List {
272
285
  type: 'list';
273
286
  level: string | number;
274
- content: Array<BlockItem | BlankLine | List>;
275
- list: 'itemized';
287
+ content: Array<BlockItem | BlockDefn | BlankLine | List>;
288
+ list: 'itemized' | 'task' | 'variable';
276
289
  }
277
290
  export interface ConfigItemKV {
278
291
  [key: string]: string | number | boolean;
@@ -309,6 +322,7 @@ export interface Block {
309
322
  margin: string;
310
323
  config?: Array<ConfigItem | BrokenConfigItem>;
311
324
  id?: string;
325
+ guarded?: boolean;
312
326
  }
313
327
  export interface BlockPod extends Block {
314
328
  name: 'pod';
@@ -384,7 +398,7 @@ export interface TableSeparator {
384
398
  export type BlockAny = BlockNamed;
385
399
  export interface BlockNamed extends Omit<Block, 'content'> {
386
400
  name: string;
387
- content: [(Verbatim | Para | Code)?] | Array<Image | BlockCaption> | RootBlock;
401
+ content: Array<Node> | RootBlock;
388
402
  }
389
403
  export interface BlockDiagram extends Omit<BlockNamed, 'content'> {
390
404
  name: 'Diagram';
@@ -405,7 +419,7 @@ export interface BlockFormula extends Omit<BlockNamed, 'content'> {
405
419
  content: [Verbatim];
406
420
  }
407
421
  export type FormattingCodes = FormattingCodeA | FormattingCodeC | FormattingCodeB | FormattingCodeD | FormattingCodeE | FormattingCodeF | FormattingCodeI | FormattingCodeL | FormattingCodeW | FormattingCodeN | FormattingCodeX | FormattingCodeZ | FormattingCodeV | FormattingCodeS | FormattingCodeAny;
408
- export type PodNode = Ambient | BlockPod | BlockData | BlockFormula | BlockCode | BlankLine | BlockNested | BlockMarkdown | BlockOutput | BlockInput | BlockInclude | BlockPara | BlockHead | BlockComment | BlockDefn | string | Para | Text | Code | BlockNamed | BlockAny | Verbatim | BlockTable | List | BlockConfig | BlockItem | Alias | BlockToc | BlockPicture | BlockImage | Image | RootBlock | Separator | BlockCaption | FormattingCodes | Toc;
422
+ export type PodNode = Ambient | BlockPod | BlockData | BlockFormula | BlockCode | BlankLine | BlockNested | BlockMarkdown | BlockOutput | BlockInput | BlockInclude | BlockPara | BlockHead | BlockComment | BlockDefn | string | Para | ParaTerm | ParaBuilt | Text | Code | BlockNamed | BlockAny | Verbatim | BlockTable | List | BlockConfig | BlockItem | Alias | BlockToc | BlockPicture | BlockImage | Image | RootBlock | Separator | BlockCaption | FormattingCodes | Toc;
409
423
  export type Node = PodNode;
410
424
  export type AstTree = Array<PodNode>;
411
425
  export type PodliteDocument = RootBlock;
package/lib/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "0.0.66";
1
+ export declare const version = "0.0.68";
package/lib/version.js CHANGED
@@ -2,5 +2,5 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.version = void 0;
4
4
  // generated by scripts/inject-version.mjs — do not edit by hand
5
- exports.version = '0.0.66';
5
+ exports.version = '0.0.68';
6
6
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@podlite/schema",
3
- "version": "0.0.66",
3
+ "version": "0.0.68",
4
4
  "description": "AST tools and schema for Podlite markup language — validate, traverse, and transform document trees",
5
5
  "main": "./lib/index.js",
6
6
  "sideEffects": false,