@udx/mq 0.1.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/examples/analyze-document.js +191 -0
- package/examples/cross-linker.js +47 -0
- package/examples/demo-architecture.js +93 -0
- package/examples/demo.js +200 -0
- package/examples/filter-code-blocks.js +64 -0
- package/examples/generate-toc.js +71 -0
- package/examples/make-collapsible.js +61 -0
- package/examples/query-headings.js +56 -0
- package/examples/toc-generator.js +44 -0
- package/lib/core.js +347 -0
- package/lib/integrations/mcurl.js +125 -0
- package/lib/operations/analysis.js +344 -0
- package/lib/operations/extractors.js +247 -0
- package/lib/operations/index.js +151 -0
- package/lib/operations/transformers.js +411 -0
- package/lib/utils/parser.js +165 -0
- package/mq.js +656 -0
- package/package.json +67 -0
- package/readme.md +242 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parser utilities for Markdown Query
|
|
3
|
+
*
|
|
4
|
+
* Provides utilities for parsing queries and transforming expressions
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { fromMarkdown } from 'mdast-util-from-markdown';
|
|
8
|
+
import _ from 'lodash';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Parse a query into parts
|
|
12
|
+
* Splits a query string by pipe character and trims each part
|
|
13
|
+
*
|
|
14
|
+
* @param {string} query - Query string to parse
|
|
15
|
+
* @returns {Array} Array of query parts
|
|
16
|
+
*/
|
|
17
|
+
function parseQuery(query) {
|
|
18
|
+
return query.split('|').map(part => part.trim());
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Parse a transform query
|
|
23
|
+
* Splits a transformation query string by pipe character and parses each part
|
|
24
|
+
*
|
|
25
|
+
* @param {string} query - Transform query string to parse
|
|
26
|
+
* @returns {Array} Array of transform operations
|
|
27
|
+
*/
|
|
28
|
+
function parseTransformQuery(query) {
|
|
29
|
+
const parts = [];
|
|
30
|
+
let currentPart = '';
|
|
31
|
+
let depth = 0;
|
|
32
|
+
|
|
33
|
+
// Parse the query, handling nested parentheses
|
|
34
|
+
for (let i = 0; i < query.length; i++) {
|
|
35
|
+
const char = query[i];
|
|
36
|
+
|
|
37
|
+
if (char === '(') {
|
|
38
|
+
depth++;
|
|
39
|
+
} else if (char === ')') {
|
|
40
|
+
depth--;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (char === '|' && depth === 0) {
|
|
44
|
+
parts.push(currentPart.trim());
|
|
45
|
+
currentPart = '';
|
|
46
|
+
} else {
|
|
47
|
+
currentPart += char;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (currentPart.trim()) {
|
|
52
|
+
parts.push(currentPart.trim());
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Parse each part into selector and operation
|
|
56
|
+
return parts.map(part => {
|
|
57
|
+
const match = part.match(/(.+?)\s+\|=\s+(.+)/);
|
|
58
|
+
if (match) {
|
|
59
|
+
return {
|
|
60
|
+
selector: match[1].trim(),
|
|
61
|
+
operation: match[2].trim()
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
return { selector: part.trim() };
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Parse markdown to AST with error handling for malformed markdown
|
|
70
|
+
*
|
|
71
|
+
* @param {string} markdown - Markdown content to parse
|
|
72
|
+
* @param {boolean} verbose - Whether to output verbose logs
|
|
73
|
+
* @returns {Object} Markdown AST
|
|
74
|
+
*/
|
|
75
|
+
function parseMarkdown(markdown, verbose = false) {
|
|
76
|
+
try {
|
|
77
|
+
return fromMarkdown(markdown);
|
|
78
|
+
} catch (parseError) {
|
|
79
|
+
if (verbose) {
|
|
80
|
+
console.error(`Warning: Error parsing markdown: ${parseError.message}`);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Create a simplified AST for basic operations
|
|
84
|
+
const ast = {
|
|
85
|
+
type: 'root',
|
|
86
|
+
children: []
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
// Try to extract headings and content even from malformed markdown
|
|
90
|
+
const lines = markdown.split('\n');
|
|
91
|
+
let inCodeBlock = false;
|
|
92
|
+
let currentCodeBlock = null;
|
|
93
|
+
|
|
94
|
+
for (const line of lines) {
|
|
95
|
+
// Handle code blocks
|
|
96
|
+
if (line.trim().startsWith('```')) {
|
|
97
|
+
if (!inCodeBlock) {
|
|
98
|
+
// Start of code block
|
|
99
|
+
inCodeBlock = true;
|
|
100
|
+
currentCodeBlock = {
|
|
101
|
+
type: 'code',
|
|
102
|
+
lang: line.trim().substring(3).trim(),
|
|
103
|
+
value: ''
|
|
104
|
+
};
|
|
105
|
+
} else {
|
|
106
|
+
// End of code block
|
|
107
|
+
inCodeBlock = false;
|
|
108
|
+
if (currentCodeBlock) {
|
|
109
|
+
ast.children.push(currentCodeBlock);
|
|
110
|
+
currentCodeBlock = null;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Add content to code block if we're in one
|
|
117
|
+
if (inCodeBlock && currentCodeBlock) {
|
|
118
|
+
currentCodeBlock.value += line + '\n';
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Handle headings
|
|
123
|
+
if (line.startsWith('#')) {
|
|
124
|
+
// Count leading # characters for heading level
|
|
125
|
+
let level = 0;
|
|
126
|
+
for (let i = 0; i < line.length; i++) {
|
|
127
|
+
if (line[i] === '#') level++;
|
|
128
|
+
else break;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const text = line.substring(level).trim();
|
|
132
|
+
|
|
133
|
+
// Add heading to AST
|
|
134
|
+
ast.children.push({
|
|
135
|
+
type: 'heading',
|
|
136
|
+
depth: level,
|
|
137
|
+
children: [{ type: 'text', value: text }]
|
|
138
|
+
});
|
|
139
|
+
} else if (line.trim().length > 0) {
|
|
140
|
+
// Handle links in paragraphs
|
|
141
|
+
const linkMatch = line.match(/\[([^\]]+)\]\(([^)]+)\)/);
|
|
142
|
+
if (linkMatch) {
|
|
143
|
+
ast.children.push({
|
|
144
|
+
type: 'paragraph',
|
|
145
|
+
children: [{
|
|
146
|
+
type: 'link',
|
|
147
|
+
url: linkMatch[2],
|
|
148
|
+
children: [{ type: 'text', value: linkMatch[1] }]
|
|
149
|
+
}]
|
|
150
|
+
});
|
|
151
|
+
} else {
|
|
152
|
+
// Add paragraph for non-empty lines
|
|
153
|
+
ast.children.push({
|
|
154
|
+
type: 'paragraph',
|
|
155
|
+
children: [{ type: 'text', value: line.trim() }]
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return ast;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export { parseQuery, parseTransformQuery, parseMarkdown };
|