@podlite/schema 0.0.66 → 0.0.67

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 (45) hide show
  1. package/CHANGELOG.podlite +12 -0
  2. package/esm/block-names.d.ts +1 -0
  3. package/esm/block-names.js +6 -1
  4. package/esm/block-names.js.map +1 -1
  5. package/esm/exportHtml.js +10 -5
  6. package/esm/exportHtml.js.map +1 -1
  7. package/esm/exportMarkdown.js +34 -36
  8. package/esm/exportMarkdown.js.map +1 -1
  9. package/esm/guard.d.ts +5 -0
  10. package/esm/guard.js +39 -0
  11. package/esm/guard.js.map +1 -0
  12. package/esm/index.d.ts +2 -1
  13. package/esm/index.js +2 -1
  14. package/esm/index.js.map +1 -1
  15. package/esm/pluggableParser.js +3 -0
  16. package/esm/pluggableParser.js.map +1 -1
  17. package/esm/plugin-data-table.js +2 -1
  18. package/esm/plugin-data-table.js.map +1 -1
  19. package/esm/plugin-tables.js +5 -2
  20. package/esm/plugin-tables.js.map +1 -1
  21. package/esm/selectors.d.ts +1 -0
  22. package/esm/selectors.js +42 -19
  23. package/esm/selectors.js.map +1 -1
  24. package/esm/types.d.ts +3 -0
  25. package/esm/version.d.ts +1 -1
  26. package/esm/version.js +1 -1
  27. package/lib/block-names.d.ts +1 -0
  28. package/lib/block-names.js +8 -2
  29. package/lib/exportHtml.js +10 -5
  30. package/lib/exportMarkdown.js +34 -36
  31. package/lib/guard.d.ts +5 -0
  32. package/lib/guard.js +47 -0
  33. package/lib/index.d.ts +2 -1
  34. package/lib/index.js +5 -1
  35. package/lib/pluggableParser.js +3 -0
  36. package/lib/plugin-data-table.js +2 -1
  37. package/lib/plugin-tables.js +5 -2
  38. package/lib/selectors.d.ts +1 -0
  39. package/lib/selectors.js +44 -20
  40. package/lib/types.d.ts +3 -0
  41. package/lib/version.d.ts +1 -1
  42. package/lib/version.js +1 -1
  43. package/package.json +1 -1
  44. package/schema/AstTree.json +69 -0
  45. package/schema/PodliteDocument.json +69 -0
package/lib/index.d.ts CHANGED
@@ -87,7 +87,8 @@ export declare const parseFormattingCodes: (text: string, options?: {
87
87
  export { default as toHtml } from './exportHtml';
88
88
  export { default as toMarkdown } from './exportMarkdown';
89
89
  export { default as Writer } from './writer';
90
- export { parseSelector, runSelector } from './selectors';
90
+ export { parseSelector, runSelector, filePathMatches } from './selectors';
91
+ export { markGuarded, isCovered } from './guard';
91
92
  export type { SelectorDoc, ParsedSelector } from './selectors';
92
93
  export { applyImageBase } from './image-base';
93
94
  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.isCovered = exports.markGuarded = exports.filePathMatches = 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;
43
43
  exports.toAst = toAst;
44
44
  exports.getTextContentFromNode = getTextContentFromNode;
45
45
  exports.getPodContentFromNode = getPodContentFromNode;
@@ -226,6 +226,10 @@ Object.defineProperty(exports, "Writer", { enumerable: true, get: function () {
226
226
  var selectors_1 = require("./selectors");
227
227
  Object.defineProperty(exports, "parseSelector", { enumerable: true, get: function () { return selectors_1.parseSelector; } });
228
228
  Object.defineProperty(exports, "runSelector", { enumerable: true, get: function () { return selectors_1.runSelector; } });
229
+ Object.defineProperty(exports, "filePathMatches", { enumerable: true, get: function () { return selectors_1.filePathMatches; } });
230
+ var guard_1 = require("./guard");
231
+ Object.defineProperty(exports, "markGuarded", { enumerable: true, get: function () { return guard_1.markGuarded; } });
232
+ Object.defineProperty(exports, "isCovered", { enumerable: true, get: function () { return guard_1.isCovered; } });
229
233
  var image_base_1 = require("./image-base");
230
234
  Object.defineProperty(exports, "applyImageBase", { enumerable: true, get: function () { return image_base_1.applyImageBase; } });
231
235
  var version_1 = require("./version");
@@ -11,6 +11,7 @@ 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");
14
15
  var ids_2 = require("./helpers/ids");
15
16
  Object.defineProperty(exports, "cleanIds", { enumerable: true, get: function () { return ids_2.cleanIds; } });
16
17
  Object.defineProperty(exports, "frozenIds", { enumerable: true, get: function () { return ids_2.frozenIds; } });
@@ -78,6 +79,7 @@ const podlitePluggable = ({ plugins = {} } = {}) => {
78
79
  (0, configPropagation_1.propagateConfigDefaults)(resultAfter.interator);
79
80
  (0, itemNumbering_1.promoteOrderedLists)(resultAfter.interator);
80
81
  (0, headingNumbering_1.attachHeadingNumberPrefix)(resultAfter.interator);
82
+ (0, guard_1.markGuarded)(resultAfter.interator);
81
83
  }
82
84
  return resultAfter;
83
85
  }
@@ -85,6 +87,7 @@ const podlitePluggable = ({ plugins = {} } = {}) => {
85
87
  (0, configPropagation_1.propagateConfigDefaults)(result.interator);
86
88
  (0, itemNumbering_1.promoteOrderedLists)(result.interator);
87
89
  (0, headingNumbering_1.attachHeadingNumberPrefix)(result.interator);
90
+ (0, guard_1.markGuarded)(result.interator);
88
91
  }
89
92
  return result;
90
93
  };
@@ -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
@@ -246,10 +246,12 @@ export interface Ambient {
246
246
  export interface Verbatim {
247
247
  type: 'verbatim';
248
248
  value: string;
249
+ guarded?: boolean;
249
250
  }
250
251
  export interface Text {
251
252
  type: 'text';
252
253
  value: string;
254
+ guarded?: boolean;
253
255
  }
254
256
  export interface Para {
255
257
  type: 'para';
@@ -309,6 +311,7 @@ export interface Block {
309
311
  margin: string;
310
312
  config?: Array<ConfigItem | BrokenConfigItem>;
311
313
  id?: string;
314
+ guarded?: boolean;
312
315
  }
313
316
  export interface BlockPod extends Block {
314
317
  name: 'pod';
package/lib/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "0.0.66";
1
+ export declare const version = "0.0.67";
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.67';
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.67",
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,
@@ -244,6 +244,9 @@
244
244
  },
245
245
  "id": {
246
246
  "type": "string"
247
+ },
248
+ "guarded": {
249
+ "type": "boolean"
247
250
  }
248
251
  },
249
252
  "required": [
@@ -394,6 +397,9 @@
394
397
  },
395
398
  "id": {
396
399
  "type": "string"
400
+ },
401
+ "guarded": {
402
+ "type": "boolean"
397
403
  }
398
404
  },
399
405
  "required": [
@@ -446,6 +452,9 @@
446
452
  },
447
453
  "id": {
448
454
  "type": "string"
455
+ },
456
+ "guarded": {
457
+ "type": "boolean"
449
458
  }
450
459
  },
451
460
  "required": [
@@ -465,6 +474,9 @@
465
474
  },
466
475
  "value": {
467
476
  "type": "string"
477
+ },
478
+ "guarded": {
479
+ "type": "boolean"
468
480
  }
469
481
  },
470
482
  "required": [
@@ -510,6 +522,9 @@
510
522
  },
511
523
  "id": {
512
524
  "type": "string"
525
+ },
526
+ "guarded": {
527
+ "type": "boolean"
513
528
  }
514
529
  },
515
530
  "required": [
@@ -570,6 +585,9 @@
570
585
  },
571
586
  "id": {
572
587
  "type": "string"
588
+ },
589
+ "guarded": {
590
+ "type": "boolean"
573
591
  }
574
592
  },
575
593
  "required": [
@@ -618,6 +636,9 @@
618
636
  },
619
637
  "id": {
620
638
  "type": "string"
639
+ },
640
+ "guarded": {
641
+ "type": "boolean"
621
642
  }
622
643
  },
623
644
  "required": [
@@ -666,6 +687,9 @@
666
687
  },
667
688
  "id": {
668
689
  "type": "string"
690
+ },
691
+ "guarded": {
692
+ "type": "boolean"
669
693
  }
670
694
  },
671
695
  "required": [
@@ -714,6 +738,9 @@
714
738
  },
715
739
  "id": {
716
740
  "type": "string"
741
+ },
742
+ "guarded": {
743
+ "type": "boolean"
717
744
  }
718
745
  },
719
746
  "required": [
@@ -762,6 +789,9 @@
762
789
  },
763
790
  "id": {
764
791
  "type": "string"
792
+ },
793
+ "guarded": {
794
+ "type": "boolean"
765
795
  }
766
796
  },
767
797
  "required": [
@@ -810,6 +840,9 @@
810
840
  },
811
841
  "id": {
812
842
  "type": "string"
843
+ },
844
+ "guarded": {
845
+ "type": "boolean"
813
846
  }
814
847
  },
815
848
  "required": [
@@ -864,6 +897,9 @@
864
897
  },
865
898
  "id": {
866
899
  "type": "string"
900
+ },
901
+ "guarded": {
902
+ "type": "boolean"
867
903
  }
868
904
  },
869
905
  "required": [
@@ -913,6 +949,9 @@
913
949
  },
914
950
  "id": {
915
951
  "type": "string"
952
+ },
953
+ "guarded": {
954
+ "type": "boolean"
916
955
  }
917
956
  },
918
957
  "required": [
@@ -961,6 +1000,9 @@
961
1000
  },
962
1001
  "id": {
963
1002
  "type": "string"
1003
+ },
1004
+ "guarded": {
1005
+ "type": "boolean"
964
1006
  }
965
1007
  },
966
1008
  "required": [
@@ -1159,6 +1201,9 @@
1159
1201
  },
1160
1202
  "value": {
1161
1203
  "type": "string"
1204
+ },
1205
+ "guarded": {
1206
+ "type": "boolean"
1162
1207
  }
1163
1208
  },
1164
1209
  "required": [
@@ -1275,6 +1320,9 @@
1275
1320
  },
1276
1321
  "id": {
1277
1322
  "type": "string"
1323
+ },
1324
+ "guarded": {
1325
+ "type": "boolean"
1278
1326
  }
1279
1327
  },
1280
1328
  "required": [
@@ -1323,6 +1371,9 @@
1323
1371
  },
1324
1372
  "id": {
1325
1373
  "type": "string"
1374
+ },
1375
+ "guarded": {
1376
+ "type": "boolean"
1326
1377
  }
1327
1378
  },
1328
1379
  "required": [
@@ -1408,6 +1459,9 @@
1408
1459
  "type": {
1409
1460
  "type": "string",
1410
1461
  "const": "block"
1462
+ },
1463
+ "guarded": {
1464
+ "type": "boolean"
1411
1465
  }
1412
1466
  },
1413
1467
  "required": [
@@ -1488,6 +1542,9 @@
1488
1542
  },
1489
1543
  "id": {
1490
1544
  "type": "string"
1545
+ },
1546
+ "guarded": {
1547
+ "type": "boolean"
1491
1548
  }
1492
1549
  },
1493
1550
  "required": [
@@ -1674,6 +1731,9 @@
1674
1731
  },
1675
1732
  "id": {
1676
1733
  "type": "string"
1734
+ },
1735
+ "guarded": {
1736
+ "type": "boolean"
1677
1737
  }
1678
1738
  },
1679
1739
  "required": [
@@ -1777,6 +1837,9 @@
1777
1837
  },
1778
1838
  "id": {
1779
1839
  "type": "string"
1840
+ },
1841
+ "guarded": {
1842
+ "type": "boolean"
1780
1843
  }
1781
1844
  },
1782
1845
  "required": [
@@ -1838,6 +1901,9 @@
1838
1901
  },
1839
1902
  "id": {
1840
1903
  "type": "string"
1904
+ },
1905
+ "guarded": {
1906
+ "type": "boolean"
1841
1907
  }
1842
1908
  },
1843
1909
  "required": [
@@ -1899,6 +1965,9 @@
1899
1965
  },
1900
1966
  "id": {
1901
1967
  "type": "string"
1968
+ },
1969
+ "guarded": {
1970
+ "type": "boolean"
1902
1971
  }
1903
1972
  },
1904
1973
  "required": [