@podlite/schema 0.0.39 → 0.0.41
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/CHANGELOG.podlite +9 -0
- package/esm/grammar.js +399 -365
- package/esm/grammar.js.map +1 -1
- package/esm/helpers/parseAttributes.d.ts +2 -0
- package/esm/helpers/parseAttributes.js +12 -0
- package/esm/helpers/parseAttributes.js.map +1 -0
- package/esm/index.d.ts +1 -0
- package/esm/index.js +1 -0
- package/esm/index.js.map +1 -1
- package/esm/plugin-formatting-codes.js +10 -23
- package/esm/plugin-formatting-codes.js.map +1 -1
- package/esm/plugin-tables.js +44 -11
- package/esm/plugin-tables.js.map +1 -1
- package/lib/grammar.js +399 -365
- package/lib/helpers/parseAttributes.d.ts +2 -0
- package/lib/helpers/parseAttributes.js +35 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +3 -1
- package/lib/plugin-formatting-codes.js +10 -23
- package/lib/plugin-tables.js +44 -11
- package/package.json +2 -2
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.parseAttributes = void 0;
|
|
23
|
+
const parser = __importStar(require("../grammar"));
|
|
24
|
+
function parseAttributes(src) {
|
|
25
|
+
if (!src || !src.trim())
|
|
26
|
+
return [];
|
|
27
|
+
try {
|
|
28
|
+
return parser.parse(src, { startRule: 'attributesOnly' });
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return [];
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
exports.parseAttributes = parseAttributes;
|
|
35
|
+
//# sourceMappingURL=parseAttributes.js.map
|
package/lib/index.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export { makeInterator } from './ast-inerator';
|
|
|
11
11
|
export { makeTransformer, isNamedBlock, isSemanticBlock } from './helpers/makeTransformer';
|
|
12
12
|
export { toAny } from './exportAny';
|
|
13
13
|
export { makeAttrs } from './helpers/config';
|
|
14
|
+
export { parseAttributes } from './helpers/parseAttributes';
|
|
14
15
|
export { pluginCleanLocation } from './plugin-clean-location';
|
|
15
16
|
export { toAnyRules } from './helpers/plugins';
|
|
16
17
|
export { podlitePluggable, Podlite, PodliteExport, cleanIds, frozenIds } from './pluggableParser';
|
package/lib/index.js
CHANGED
|
@@ -25,7 +25,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
25
25
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
26
26
|
};
|
|
27
27
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
28
|
-
exports.version = exports.runSelector = exports.parseSelector = exports.Writer = exports.toMarkdown = exports.toHtml = exports.parse = exports.toTree = exports.isValidateError = exports.validateAst = exports.validateAstTree = exports.validatePodliteAst = exports.getPodContentFromNode = exports.getTextContentFromNode = exports.toAst = exports.frozenIds = exports.cleanIds = exports.podlitePluggable = exports.toAnyRules = exports.pluginCleanLocation = exports.makeAttrs = exports.toAny = exports.isSemanticBlock = exports.isNamedBlock = exports.makeTransformer = exports.makeInterator = void 0;
|
|
28
|
+
exports.version = exports.runSelector = exports.parseSelector = exports.Writer = exports.toMarkdown = exports.toHtml = exports.parse = exports.toTree = exports.isValidateError = exports.validateAst = exports.validateAstTree = exports.validatePodliteAst = exports.getPodContentFromNode = exports.getTextContentFromNode = exports.toAst = exports.frozenIds = exports.cleanIds = exports.podlitePluggable = exports.toAnyRules = exports.pluginCleanLocation = exports.parseAttributes = exports.makeAttrs = exports.toAny = exports.isSemanticBlock = exports.isNamedBlock = exports.makeTransformer = exports.makeInterator = void 0;
|
|
29
29
|
const ajv_1 = __importDefault(require("ajv"));
|
|
30
30
|
const pointer = __importStar(require("json-pointer"));
|
|
31
31
|
const jsonShemes = __importStar(require("../schema"));
|
|
@@ -45,6 +45,8 @@ var exportAny_1 = require("./exportAny");
|
|
|
45
45
|
Object.defineProperty(exports, "toAny", { enumerable: true, get: function () { return exportAny_1.toAny; } });
|
|
46
46
|
var config_1 = require("./helpers/config");
|
|
47
47
|
Object.defineProperty(exports, "makeAttrs", { enumerable: true, get: function () { return config_1.makeAttrs; } });
|
|
48
|
+
var parseAttributes_1 = require("./helpers/parseAttributes");
|
|
49
|
+
Object.defineProperty(exports, "parseAttributes", { enumerable: true, get: function () { return parseAttributes_1.parseAttributes; } });
|
|
48
50
|
var plugin_clean_location_1 = require("./plugin-clean-location");
|
|
49
51
|
Object.defineProperty(exports, "pluginCleanLocation", { enumerable: true, get: function () { return plugin_clean_location_1.pluginCleanLocation; } });
|
|
50
52
|
var plugins_1 = require("./helpers/plugins");
|
|
@@ -47,33 +47,20 @@ const middle = () => tree => {
|
|
|
47
47
|
content: visiter(n.content, ctx, visiter),
|
|
48
48
|
};
|
|
49
49
|
const conf = (0, config_1.default)(n, ctx);
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
if ((0, makeTransformer_2.isNamedBlock)(n.name))
|
|
50
|
+
const name = 'name' in n ? n.name : '';
|
|
51
|
+
// Blocks whose content is verbatim by default — fcode parsing only
|
|
52
|
+
// kicks in when :allow opts in (per spec, "Formatting within code blocks").
|
|
53
|
+
const isVerbatimDefault = ['code', 'data', 'markdown', 'picture', 'formula'].includes(name);
|
|
54
|
+
const allowValues = conf.getAllValues('allow');
|
|
55
|
+
if ((0, makeTransformer_2.isNamedBlock)(name))
|
|
57
56
|
return n;
|
|
58
|
-
|
|
59
|
-
if ((isCodeBlock || isDataBlock || isMarkdownBlock || isPictureBlock || isFormulaBlock) &&
|
|
60
|
-
allowValues.length == 0)
|
|
57
|
+
if (isVerbatimDefault && allowValues.length === 0)
|
|
61
58
|
return n;
|
|
62
59
|
const allowed = allowValues.sort();
|
|
63
60
|
const transformer = (0, makeTransformer_1.default)({
|
|
64
|
-
':verbatim': (n, ctx) => {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
if (allowed.length == 1 && allowed.includes('NONE'))
|
|
68
|
-
return n;
|
|
69
|
-
return fcparser.parse(n.value, { allowed });
|
|
70
|
-
},
|
|
71
|
-
':text': (n, ctx) => {
|
|
72
|
-
return fcparser.parse(n.value, { allowed });
|
|
73
|
-
},
|
|
74
|
-
':block': (n, ctx) => {
|
|
75
|
-
return transformerBlocks(n, { ...ctx });
|
|
76
|
-
},
|
|
61
|
+
':verbatim': (n, ctx) => fcparser.parse(n.value, { allowed }),
|
|
62
|
+
':text': (n, ctx) => fcparser.parse(n.value, { allowed }),
|
|
63
|
+
':block': (n, ctx) => transformerBlocks(n, { ...ctx }),
|
|
77
64
|
});
|
|
78
65
|
return { ...n, content: transformer(n.content, { ...ctx }) };
|
|
79
66
|
},
|
package/lib/plugin-tables.js
CHANGED
|
@@ -81,6 +81,36 @@ function parseTsv(text) {
|
|
|
81
81
|
const rows = lines.map(line => line.split('\t'));
|
|
82
82
|
return rows.filter(r => !(r.length === 1 && r[0].trim() === ''));
|
|
83
83
|
}
|
|
84
|
+
// Parse a MIME type value into the bare type and a map of parameters
|
|
85
|
+
// (RFC 6838 / RFC 7231 §3.1.1.1). Used to recognise the `header` parameter
|
|
86
|
+
// (RFC 4180 §3) on `:mime-type` of CSV/TSV =data blocks.
|
|
87
|
+
//
|
|
88
|
+
// Examples:
|
|
89
|
+
// "text/csv" → { type: 'text/csv', params: {} }
|
|
90
|
+
// "text/csv; header=present" → { type: 'text/csv', params: { header: 'present' } }
|
|
91
|
+
// "text/csv;charset=utf-8;header=absent" → { ..., params: { charset: 'utf-8', header: 'absent' } }
|
|
92
|
+
function parseMimeType(raw) {
|
|
93
|
+
if (!raw || typeof raw !== 'string')
|
|
94
|
+
return { type: '', params: {} };
|
|
95
|
+
const parts = raw.split(';').map(s => s.trim());
|
|
96
|
+
const type = (parts.shift() || '').toLowerCase();
|
|
97
|
+
const params = {};
|
|
98
|
+
for (const p of parts) {
|
|
99
|
+
if (!p)
|
|
100
|
+
continue;
|
|
101
|
+
const eq = p.indexOf('=');
|
|
102
|
+
if (eq < 0)
|
|
103
|
+
continue;
|
|
104
|
+
const key = p.slice(0, eq).trim().toLowerCase();
|
|
105
|
+
let value = p.slice(eq + 1).trim();
|
|
106
|
+
if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
|
|
107
|
+
value = value.slice(1, -1);
|
|
108
|
+
}
|
|
109
|
+
if (key)
|
|
110
|
+
params[key] = value;
|
|
111
|
+
}
|
|
112
|
+
return { type, params };
|
|
113
|
+
}
|
|
84
114
|
// Locate the first `=data` block with a matching `:key` attribute anywhere
|
|
85
115
|
// in the document tree.
|
|
86
116
|
function findDataBlockByKey(tree, key) {
|
|
@@ -161,15 +191,16 @@ function buildRowBlock(cells, isHeader) {
|
|
|
161
191
|
}
|
|
162
192
|
return block;
|
|
163
193
|
}
|
|
164
|
-
// Convert parsed CSV/TSV rows to plain `=row`/`=cell` blocks.
|
|
165
|
-
//
|
|
166
|
-
//
|
|
167
|
-
//
|
|
168
|
-
// table with
|
|
169
|
-
|
|
170
|
-
|
|
194
|
+
// Convert parsed CSV/TSV rows to plain `=row`/`=cell` blocks. When
|
|
195
|
+
// `hasHeader` is true (signalled by the `header=present` MIME parameter on
|
|
196
|
+
// the source `=data` block, per RFC 4180 §3), the first row is marked with
|
|
197
|
+
// `:header`. Default behaviour leaves all rows unmarked, matching authors
|
|
198
|
+
// who use a structured table with explicit `=begin row :header` or a
|
|
199
|
+
// Markdown GFM table.
|
|
200
|
+
function csvToTableContent(csvRows, hasHeader = false) {
|
|
201
|
+
return csvRows.map((row, i) => {
|
|
171
202
|
const cells = row.map(v => buildCellBlock(v.trim()));
|
|
172
|
-
return buildRowBlock(cells,
|
|
203
|
+
return buildRowBlock(cells, hasHeader && i === 0);
|
|
173
204
|
});
|
|
174
205
|
}
|
|
175
206
|
// ─── Error recovery (design notes Rules 2-4) ───────────────────────────────
|
|
@@ -418,7 +449,8 @@ exports.default = () => tree => {
|
|
|
418
449
|
console.warn(`[table] no =data block found for data:${ref.target} — rendered as empty`);
|
|
419
450
|
return { ...node, content: [] };
|
|
420
451
|
}
|
|
421
|
-
const
|
|
452
|
+
const rawMime = (0, config_1.default)(dataBlock, {}).getFirstValue('mime-type');
|
|
453
|
+
const { type: mimeType, params: mimeParams } = parseMimeType(rawMime);
|
|
422
454
|
const isCsv = mimeType === 'text/csv';
|
|
423
455
|
const isTsv = mimeType === 'text/tab-separated-values';
|
|
424
456
|
if (isCsv || isTsv) {
|
|
@@ -428,11 +460,12 @@ exports.default = () => tree => {
|
|
|
428
460
|
console.warn(`[table] ${isCsv ? 'CSV' : 'TSV'} parse produced no rows for data:${ref.target} — rendered as empty`);
|
|
429
461
|
return { ...node, content: [] };
|
|
430
462
|
}
|
|
431
|
-
const
|
|
463
|
+
const hasHeader = mimeParams.header === 'present';
|
|
464
|
+
const filledNode = { ...node, content: csvToTableContent(rows, hasHeader) };
|
|
432
465
|
return normalizeCellCounts(filledNode, `table data:${ref.target}`);
|
|
433
466
|
}
|
|
434
467
|
// Rule 4: source not tabular → render as code block so content remains visible
|
|
435
|
-
console.warn(`[table] =data :key<${ref.target}> has non-tabular mime-type ${
|
|
468
|
+
console.warn(`[table] =data :key<${ref.target}> has non-tabular mime-type ${rawMime || '(none)'} — rendered as =code`);
|
|
436
469
|
return buildCodeFromDataBlock(node, dataBlock);
|
|
437
470
|
}
|
|
438
471
|
// structured mode: transform row children (wrap implicit cells), then
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@podlite/schema",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.41",
|
|
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
|
"homepage": "https://podlite.org",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"build": "run-s build:pegjs build_lib build:ast ",
|
|
41
41
|
"build_lib": "yarn g:build",
|
|
42
42
|
"build:ast": "ts-node scripts/make-ast-scheme.ts",
|
|
43
|
-
"build:pegjs": "pegmill -o src/grammar.js src/grammar.pegjs && pegmill -o src/grammarfc.js src/grammarfc.pegjs",
|
|
43
|
+
"build:pegjs": "pegmill --allowed-start-rules Document,attributesOnly -o src/grammar.js src/grammar.pegjs && pegmill -o src/grammarfc.js src/grammarfc.pegjs",
|
|
44
44
|
"watch": "npx nodemon -e js,ts --exec 'yarn' build",
|
|
45
45
|
"watch:pegjs": "npx nodemon -e pegmill --exec 'yarn' build:pegjs",
|
|
46
46
|
"test": "yarn g:jest --passWithNoTests"
|