@lobehub/ui 2.16.1 → 2.16.3
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/es/Accordion/AccordionItem.js +2 -2
- package/es/DraggablePanel/DraggablePanel.js +148 -68
- package/es/DraggableSideNav/DraggableSideNav.js +393 -285
- package/es/DraggableSideNav/style.js +2 -2
- package/es/DraggableSideNav/type.d.ts +4 -35
- package/es/hooks/useMarkdown/latex.d.ts +124 -12
- package/es/hooks/useMarkdown/latex.js +370 -66
- package/package.json +1 -1
|
@@ -1,5 +1,53 @@
|
|
|
1
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
2
|
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
3
|
+
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
|
|
4
|
+
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
|
5
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
6
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
7
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
1
8
|
import { renderToString } from 'katex';
|
|
2
9
|
|
|
10
|
+
// ============================================================================
|
|
11
|
+
// Utility Classes
|
|
12
|
+
// ============================================================================
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* PlaceholderManager - Manages temporary replacement and restoration of protected content
|
|
16
|
+
* Used to protect code blocks and LaTeX expressions during preprocessing
|
|
17
|
+
*/
|
|
18
|
+
var PlaceholderManager = /*#__PURE__*/function () {
|
|
19
|
+
function PlaceholderManager() {
|
|
20
|
+
var prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'PROTECTED';
|
|
21
|
+
_classCallCheck(this, PlaceholderManager);
|
|
22
|
+
_defineProperty(this, "placeholders", []);
|
|
23
|
+
_defineProperty(this, "prefix", void 0);
|
|
24
|
+
this.prefix = prefix;
|
|
25
|
+
}
|
|
26
|
+
_createClass(PlaceholderManager, [{
|
|
27
|
+
key: "add",
|
|
28
|
+
value: function add(content) {
|
|
29
|
+
var index = this.placeholders.length;
|
|
30
|
+
this.placeholders.push(content);
|
|
31
|
+
return "<<".concat(this.prefix, "_").concat(index, ">>");
|
|
32
|
+
}
|
|
33
|
+
}, {
|
|
34
|
+
key: "restore",
|
|
35
|
+
value: function restore(text) {
|
|
36
|
+
var _this = this;
|
|
37
|
+
return text.replaceAll(new RegExp("<<".concat(this.prefix, "_(\\d+)>>"), 'g'), function (_, index) {
|
|
38
|
+
return _this.placeholders[Number.parseInt(index)] || '';
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}, {
|
|
42
|
+
key: "clear",
|
|
43
|
+
value: function clear() {
|
|
44
|
+
this.placeholders = [];
|
|
45
|
+
}
|
|
46
|
+
}]);
|
|
47
|
+
return PlaceholderManager;
|
|
48
|
+
}(); // ============================================================================
|
|
49
|
+
// Helper Functions
|
|
50
|
+
// ============================================================================
|
|
3
51
|
// Helper: replace unescaped pipes with \vert within a LaTeX math fragment
|
|
4
52
|
var replaceUnescapedPipes = function replaceUnescapedPipes(formula) {
|
|
5
53
|
return (
|
|
@@ -52,13 +100,30 @@ export function escapeLatexPipes(text) {
|
|
|
52
100
|
// remark-gfm table parsing won't treat them as column separators.
|
|
53
101
|
// Leave code blocks/inline code untouched.
|
|
54
102
|
// Also ignore escaped dollars (\$) which are currency symbols
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
return
|
|
103
|
+
|
|
104
|
+
// Process code blocks first to protect them
|
|
105
|
+
var codeBlocks = [];
|
|
106
|
+
var content = text.replaceAll(/(```[\S\s]*?```|`[^\n`]*`)/g, function (match) {
|
|
107
|
+
codeBlocks.push(match);
|
|
108
|
+
return "<<CODE_".concat(codeBlocks.length - 1, ">>");
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// For display math, allow multiline
|
|
112
|
+
content = content.replaceAll(/\$\$([\S\s]*?)\$\$/g, function (match, display) {
|
|
113
|
+
return "$$".concat(replaceUnescapedPipes(display), "$$");
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
// For inline math, use non-greedy match that DOES NOT cross newlines
|
|
117
|
+
// This prevents issues in tables where $ might appear in different cells
|
|
118
|
+
content = content.replaceAll(/(?<!\\)\$(?!\$)([^\n$]*?)(?<!\\)\$(?!\$)/g, function (match, inline) {
|
|
119
|
+
return "$".concat(replaceUnescapedPipes(inline), "$");
|
|
61
120
|
});
|
|
121
|
+
|
|
122
|
+
// Restore code blocks
|
|
123
|
+
content = content.replaceAll(/<<CODE_(\d+)>>/g, function (_, index) {
|
|
124
|
+
return codeBlocks[Number.parseInt(index)];
|
|
125
|
+
});
|
|
126
|
+
return content;
|
|
62
127
|
}
|
|
63
128
|
|
|
64
129
|
/**
|
|
@@ -94,7 +159,7 @@ export function escapeTextUnderscores(text) {
|
|
|
94
159
|
*/
|
|
95
160
|
export function escapeCurrencyDollars(text) {
|
|
96
161
|
// Protect code blocks and existing LaTeX expressions from processing
|
|
97
|
-
var
|
|
162
|
+
var manager = new PlaceholderManager('PROTECTED');
|
|
98
163
|
var content = text.replaceAll(
|
|
99
164
|
// Match patterns to protect (in order):
|
|
100
165
|
// 1. Code blocks: ```...```
|
|
@@ -104,77 +169,26 @@ export function escapeCurrencyDollars(text) {
|
|
|
104
169
|
// 5. LaTeX bracket notation: \[...\]
|
|
105
170
|
// 6. LaTeX parenthesis notation: \(...\)
|
|
106
171
|
/(```[\S\s]*?```|`[^\n`]*`|\$\$[\S\s]*?\$\$|(?<!\\)\$(?!\$)(?=[\S\s]*?\\)[\S\s]*?(?<!\\)\$(?!\$)|\\\[[\S\s]*?\\]|\\\(.*?\\\))/g, function (match) {
|
|
107
|
-
|
|
108
|
-
return "<<PROTECTED_".concat(protectedStrings.length - 1, ">>");
|
|
172
|
+
return manager.add(match);
|
|
109
173
|
});
|
|
110
174
|
|
|
111
175
|
// Escape dollar signs that are clearly currency:
|
|
112
176
|
// - $ followed by a digit
|
|
113
177
|
// - Not preceded by another $ (to avoid breaking $$)
|
|
178
|
+
// - Not followed immediately by another $ (to avoid breaking $1$ LaTeX)
|
|
114
179
|
// - Followed by number patterns with optional commas, decimals, ranges, or plus signs
|
|
115
180
|
// Match patterns like: $20, $1,000, $19.99, $20-50, $300+, $1,000-2,000+
|
|
181
|
+
// But NOT: $1$, $2$ (these are LaTeX formulas)
|
|
116
182
|
// In the replacement: \\ = backslash, $$ = literal $, $1 = capture group 1
|
|
117
|
-
content = content.replaceAll(/(?<!\$)\$(\d{1,3}(?:,\d{3})*(?:\.\d+)?(?:-\d{1,3}(?:,\d{3})*(?:\.\d+)?)?\+?)/g, '\\$$$1');
|
|
183
|
+
content = content.replaceAll(/(?<!\$)\$(\d{1,3}(?:,\d{3})*(?:\.\d+)?(?:-\d{1,3}(?:,\d{3})*(?:\.\d+)?)?\+?)(?!\$)/g, '\\$$$1');
|
|
118
184
|
|
|
119
185
|
// Restore protected content
|
|
120
|
-
content =
|
|
121
|
-
return protectedStrings[Number.parseInt(index)];
|
|
122
|
-
});
|
|
186
|
+
content = manager.restore(content);
|
|
123
187
|
return content;
|
|
124
188
|
}
|
|
125
189
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
* 1. Protects code blocks from processing
|
|
129
|
-
* 2. Protects existing LaTeX expressions
|
|
130
|
-
* 3. Escapes dollar signs that likely represent currency
|
|
131
|
-
* 4. Converts LaTeX delimiters
|
|
132
|
-
* 5. Escapes mhchem commands and pipes
|
|
133
|
-
*
|
|
134
|
-
* @param content The input string containing LaTeX expressions
|
|
135
|
-
* @returns The processed string with proper LaTeX formatting
|
|
136
|
-
*/
|
|
137
|
-
export function preprocessLaTeX(str) {
|
|
138
|
-
// Step 1: Protect code blocks
|
|
139
|
-
// const codeBlocks: string[] = [];
|
|
140
|
-
// let content = str.replaceAll(/(```[\S\s]*?```|`[^\n`]+`)/g, (match, code) => {
|
|
141
|
-
// codeBlocks.push(code);
|
|
142
|
-
// return `<<CODE_BLOCK_${codeBlocks.length - 1}>>`;
|
|
143
|
-
// });
|
|
144
|
-
|
|
145
|
-
// // Step 2: Protect existing LaTeX expressions
|
|
146
|
-
// const latexExpressions: string[] = [];
|
|
147
|
-
// content = content.replaceAll(/(\$\$[\S\s]*?\$\$|\\\[[\S\s]*?\\]|\\\(.*?\\\))/g, (match) => {
|
|
148
|
-
// latexExpressions.push(match);
|
|
149
|
-
// return `<<LATEX_${latexExpressions.length - 1}>>`;
|
|
150
|
-
// });
|
|
151
|
-
|
|
152
|
-
// Step 3: Escape dollar signs that are likely currency indicators
|
|
153
|
-
// Deprecated, as it causes parsing errors for formulas starting with a number, such as `$1$`
|
|
154
|
-
// content = content.replaceAll(/\$(?=\d)/g, '\\$');
|
|
155
|
-
|
|
156
|
-
// Step 4: Restore LaTeX expressions
|
|
157
|
-
// content = content.replaceAll(
|
|
158
|
-
// /<<LATEX_(\d+)>>/g,
|
|
159
|
-
// (_, index) => latexExpressions[Number.parseInt(index)],
|
|
160
|
-
// );
|
|
161
|
-
|
|
162
|
-
// // Step 5: Restore code blocks
|
|
163
|
-
// content = content.replaceAll(
|
|
164
|
-
// /<<CODE_BLOCK_(\d+)>>/g,
|
|
165
|
-
// (_, index) => codeBlocks[Number.parseInt(index)],
|
|
166
|
-
// );
|
|
167
|
-
var content = str;
|
|
168
|
-
|
|
169
|
-
// Step 6: Apply additional escaping functions
|
|
170
|
-
// Escape currency dollar signs FIRST before other LaTeX processing
|
|
171
|
-
content = escapeCurrencyDollars(content);
|
|
172
|
-
content = convertLatexDelimiters(content);
|
|
173
|
-
content = escapeMhchemCommands(content);
|
|
174
|
-
content = escapeLatexPipes(content);
|
|
175
|
-
content = escapeTextUnderscores(content);
|
|
176
|
-
return content;
|
|
177
|
-
}
|
|
190
|
+
// Old simple preprocessLaTeX has been replaced by the comprehensive version below
|
|
191
|
+
// The new preprocessLaTeX provides the same default behavior with optional advanced featuresgit
|
|
178
192
|
|
|
179
193
|
/**
|
|
180
194
|
* Extracts the LaTeX formula after the last $$ delimiter if there's an odd number of $$ delimiters.
|
|
@@ -220,4 +234,294 @@ export var isLastFormulaRenderable = function isLastFormulaRenderable(text) {
|
|
|
220
234
|
console.log("LaTeX formula rendering error: ".concat(error));
|
|
221
235
|
return false;
|
|
222
236
|
}
|
|
223
|
-
};
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
// ============================================================================
|
|
240
|
+
// Advanced Preprocessing Functions
|
|
241
|
+
// ============================================================================
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Fixes common LaTeX syntax errors automatically
|
|
245
|
+
* - Balances unmatched braces
|
|
246
|
+
* - Balances \left and \right delimiters
|
|
247
|
+
*
|
|
248
|
+
* @param text The input string containing LaTeX expressions
|
|
249
|
+
* @returns The string with fixed LaTeX expressions
|
|
250
|
+
*/
|
|
251
|
+
export function fixCommonLaTeXErrors(text) {
|
|
252
|
+
return text.replaceAll(/(\$\$[\S\s]*?\$\$|\$[\S\s]*?\$)/g, function (match) {
|
|
253
|
+
var fixed = match;
|
|
254
|
+
|
|
255
|
+
// Fix unbalanced braces
|
|
256
|
+
var openBraces = (fixed.match(/(?<!\\){/g) || []).length;
|
|
257
|
+
var closeBraces = (fixed.match(/(?<!\\)}/g) || []).length;
|
|
258
|
+
if (openBraces > closeBraces) {
|
|
259
|
+
var diff = openBraces - closeBraces;
|
|
260
|
+
var closingBraces = '}'.repeat(diff);
|
|
261
|
+
// Insert before the closing delimiter
|
|
262
|
+
fixed = fixed.replace(/(\$\$?)$/, closingBraces + '$1');
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Fix unbalanced \left and \right
|
|
266
|
+
var leftDelims = (fixed.match(/\\left[(.<[{|]/g) || []).length;
|
|
267
|
+
var rightDelims = (fixed.match(/\\right[).>\]|}]/g) || []).length;
|
|
268
|
+
if (leftDelims > rightDelims) {
|
|
269
|
+
var _diff = leftDelims - rightDelims;
|
|
270
|
+
var rightDots = '\\right.'.repeat(_diff);
|
|
271
|
+
fixed = fixed.replace(/(\$\$?)$/, rightDots + '$1');
|
|
272
|
+
}
|
|
273
|
+
return fixed;
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Normalizes whitespace in LaTeX expressions
|
|
279
|
+
* - Removes extra spaces around $ delimiters
|
|
280
|
+
* - Normalizes multiple spaces to single space inside formulas
|
|
281
|
+
*
|
|
282
|
+
* @param text The input string containing LaTeX expressions
|
|
283
|
+
* @returns The string with normalized whitespace
|
|
284
|
+
*/
|
|
285
|
+
export function normalizeLatexSpacing(text) {
|
|
286
|
+
var result = text;
|
|
287
|
+
|
|
288
|
+
// Remove spaces inside $ delimiters (at the edges)
|
|
289
|
+
result = result.replaceAll(/\$\s+/g, '$');
|
|
290
|
+
result = result.replaceAll(/\s+\$/g, '$');
|
|
291
|
+
result = result.replaceAll(/\$\$\s+/g, '$$');
|
|
292
|
+
result = result.replaceAll(/\s+\$\$/g, '$$');
|
|
293
|
+
|
|
294
|
+
// Normalize multiple spaces inside formulas to single space
|
|
295
|
+
result = result.replaceAll(/(\$\$[\S\s]*?\$\$|\$[\S\s]*?\$)/g, function (match) {
|
|
296
|
+
return match.replaceAll(/\s{2,}/g, ' ');
|
|
297
|
+
});
|
|
298
|
+
return result;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Validates all LaTeX expressions in the text
|
|
303
|
+
* Returns detailed information about validation results
|
|
304
|
+
*
|
|
305
|
+
* @param text The input string containing LaTeX expressions
|
|
306
|
+
* @returns Validation results with errors if any
|
|
307
|
+
*/
|
|
308
|
+
export function validateLatexExpressions(text) {
|
|
309
|
+
var errors = [];
|
|
310
|
+
var totalExpressions = 0;
|
|
311
|
+
var pattern = /\$\$([\S\s]*?)\$\$|(?<!\\)\$(?!\$)([\S\s]*?)(?<!\\)\$(?!\$)/g;
|
|
312
|
+
var match;
|
|
313
|
+
while ((match = pattern.exec(text)) !== null) {
|
|
314
|
+
totalExpressions++;
|
|
315
|
+
var formula = match[1] || match[2];
|
|
316
|
+
var isDisplay = match[0].startsWith('$$');
|
|
317
|
+
try {
|
|
318
|
+
renderToString(formula, {
|
|
319
|
+
displayMode: isDisplay,
|
|
320
|
+
strict: 'warn',
|
|
321
|
+
throwOnError: true,
|
|
322
|
+
trust: false
|
|
323
|
+
});
|
|
324
|
+
} catch (error) {
|
|
325
|
+
errors.push({
|
|
326
|
+
formula: formula.slice(0, 50) + (formula.length > 50 ? '...' : ''),
|
|
327
|
+
message: error instanceof Error ? error.message : String(error),
|
|
328
|
+
position: match.index,
|
|
329
|
+
type: isDisplay ? 'display' : 'inline'
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
return {
|
|
334
|
+
errors: errors,
|
|
335
|
+
totalExpressions: totalExpressions,
|
|
336
|
+
valid: errors.length === 0
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Handles CJK (Chinese, Japanese, Korean) characters mixed with LaTeX
|
|
342
|
+
* Optionally adds spaces between CJK characters and LaTeX expressions for better rendering
|
|
343
|
+
*
|
|
344
|
+
* @param text The input string
|
|
345
|
+
* @param addSpaces Whether to add spaces between CJK and LaTeX (default: false)
|
|
346
|
+
* @returns The processed string
|
|
347
|
+
*/
|
|
348
|
+
export function handleCJKWithLatex(text) {
|
|
349
|
+
var addSpaces = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
350
|
+
if (!addSpaces) return text;
|
|
351
|
+
var result = text;
|
|
352
|
+
|
|
353
|
+
// Add space between CJK character and opening $
|
|
354
|
+
result = result.replaceAll(/([\u3040-\u30FF\u4E00-\u9FA5])(\$)/g, '$1 $2');
|
|
355
|
+
|
|
356
|
+
// Add space between closing $ and CJK character
|
|
357
|
+
result = result.replaceAll(/(\$)([\u3040-\u30FF\u4E00-\u9FA5])/g, '$1 $2');
|
|
358
|
+
return result;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// ============================================================================
|
|
362
|
+
// Advanced Preprocessing Options
|
|
363
|
+
// ============================================================================
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Comprehensive LaTeX preprocessing with configurable options
|
|
367
|
+
*
|
|
368
|
+
* This is the main preprocessing function that handles:
|
|
369
|
+
* - Currency symbol escaping (e.g., $20 → \$20)
|
|
370
|
+
* - LaTeX delimiter conversion (\[...\] → $$...$$)
|
|
371
|
+
* - Special character escaping (pipes, underscores, mhchem)
|
|
372
|
+
* - Optional error fixing and validation
|
|
373
|
+
* - Optional CJK character handling
|
|
374
|
+
*
|
|
375
|
+
* @param text The input string containing LaTeX and Markdown
|
|
376
|
+
* @param options Configuration options for fine-grained control
|
|
377
|
+
* @returns The preprocessed string
|
|
378
|
+
*
|
|
379
|
+
* @example
|
|
380
|
+
* ```ts
|
|
381
|
+
* // Default behavior (same as old preprocessLaTeX)
|
|
382
|
+
* preprocessLaTeX('向量$90^\\circ$,非 $0^\\circ$ 和 $180^\\circ$')
|
|
383
|
+
*
|
|
384
|
+
* // With custom options
|
|
385
|
+
* preprocessLaTeX(text, {
|
|
386
|
+
* fixErrors: true,
|
|
387
|
+
* validate: true,
|
|
388
|
+
* handleCJK: true
|
|
389
|
+
* })
|
|
390
|
+
* ```
|
|
391
|
+
*/
|
|
392
|
+
export function preprocessLaTeX(text) {
|
|
393
|
+
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
394
|
+
var _options$addCJKSpaces = options.addCJKSpaces,
|
|
395
|
+
addCJKSpaces = _options$addCJKSpaces === void 0 ? false : _options$addCJKSpaces,
|
|
396
|
+
_options$convertBrack = options.convertBrackets,
|
|
397
|
+
convertBrackets = _options$convertBrack === void 0 ? true : _options$convertBrack,
|
|
398
|
+
_options$escapeCurren = options.escapeCurrency,
|
|
399
|
+
escapeCurrency = _options$escapeCurren === void 0 ? true : _options$escapeCurren,
|
|
400
|
+
_options$escapeMhchem = options.escapeMhchem,
|
|
401
|
+
escapeMhchem = _options$escapeMhchem === void 0 ? true : _options$escapeMhchem,
|
|
402
|
+
_options$escapePipes = options.escapePipes,
|
|
403
|
+
escapePipes = _options$escapePipes === void 0 ? true : _options$escapePipes,
|
|
404
|
+
_options$escapeUnders = options.escapeUnderscores,
|
|
405
|
+
escapeUnderscores = _options$escapeUnders === void 0 ? true : _options$escapeUnders,
|
|
406
|
+
_options$fixErrors = options.fixErrors,
|
|
407
|
+
fixErrors = _options$fixErrors === void 0 ? false : _options$fixErrors,
|
|
408
|
+
_options$handleCJK = options.handleCJK,
|
|
409
|
+
handleCJK = _options$handleCJK === void 0 ? false : _options$handleCJK,
|
|
410
|
+
_options$normalizeSpa = options.normalizeSpacing,
|
|
411
|
+
normalizeSpacing = _options$normalizeSpa === void 0 ? false : _options$normalizeSpa,
|
|
412
|
+
_options$throwOnValid = options.throwOnValidationError,
|
|
413
|
+
throwOnValidationError = _options$throwOnValid === void 0 ? false : _options$throwOnValid,
|
|
414
|
+
_options$validate = options.validate,
|
|
415
|
+
validate = _options$validate === void 0 ? false : _options$validate;
|
|
416
|
+
var content = text;
|
|
417
|
+
|
|
418
|
+
// Phase 1: Currency escaping (if enabled)
|
|
419
|
+
if (escapeCurrency) {
|
|
420
|
+
content = escapeCurrencyDollars(content);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// Phase 2: Bracket conversion (if enabled)
|
|
424
|
+
if (convertBrackets) {
|
|
425
|
+
content = convertLatexDelimiters(content);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// Phase 3: LaTeX-specific escaping
|
|
429
|
+
if (escapeMhchem) {
|
|
430
|
+
content = escapeMhchemCommands(content);
|
|
431
|
+
}
|
|
432
|
+
if (escapePipes) {
|
|
433
|
+
content = escapeLatexPipes(content);
|
|
434
|
+
}
|
|
435
|
+
if (escapeUnderscores) {
|
|
436
|
+
content = escapeTextUnderscores(content);
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
// Phase 4: Error fixing (if enabled)
|
|
440
|
+
if (fixErrors) {
|
|
441
|
+
content = fixCommonLaTeXErrors(content);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// Phase 5: Whitespace normalization (if enabled)
|
|
445
|
+
if (normalizeSpacing) {
|
|
446
|
+
content = normalizeLatexSpacing(content);
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// Phase 6: CJK handling (if enabled)
|
|
450
|
+
if (handleCJK) {
|
|
451
|
+
content = handleCJKWithLatex(content, addCJKSpaces);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// Phase 7: Validation (if enabled)
|
|
455
|
+
if (validate) {
|
|
456
|
+
var validation = validateLatexExpressions(content);
|
|
457
|
+
if (!validation.valid) {
|
|
458
|
+
var errorMessage = "LaTeX validation failed (".concat(validation.errors.length, "/").concat(validation.totalExpressions, " expressions have errors):\n").concat(validation.errors.map(function (e) {
|
|
459
|
+
return " - [".concat(e.type, "] at position ").concat(e.position, ": ").concat(e.message, "\n Formula: ").concat(e.formula);
|
|
460
|
+
}).join('\n'));
|
|
461
|
+
if (throwOnValidationError) {
|
|
462
|
+
throw new Error(errorMessage);
|
|
463
|
+
} else {
|
|
464
|
+
console.warn(errorMessage);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
return content;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* Strict preprocessing mode - enables all safety features and validations
|
|
473
|
+
* Use this when you want maximum correctness and are willing to accept the performance cost
|
|
474
|
+
*
|
|
475
|
+
* @param text The input string
|
|
476
|
+
* @returns The preprocessed string with all features enabled
|
|
477
|
+
*
|
|
478
|
+
* @example
|
|
479
|
+
* ```ts
|
|
480
|
+
* const processed = preprocessLaTeXStrict(userInput)
|
|
481
|
+
* // Enables: error fixing, validation, CJK handling, space normalization
|
|
482
|
+
* ```
|
|
483
|
+
*/
|
|
484
|
+
export function preprocessLaTeXStrict(text) {
|
|
485
|
+
return preprocessLaTeX(text, {
|
|
486
|
+
addCJKSpaces: false,
|
|
487
|
+
// Usually don't want extra spaces
|
|
488
|
+
convertBrackets: true,
|
|
489
|
+
escapeCurrency: true,
|
|
490
|
+
escapeMhchem: true,
|
|
491
|
+
escapePipes: true,
|
|
492
|
+
escapeUnderscores: true,
|
|
493
|
+
fixErrors: true,
|
|
494
|
+
handleCJK: true,
|
|
495
|
+
normalizeSpacing: true,
|
|
496
|
+
throwOnValidationError: false,
|
|
497
|
+
// Warn but don't throw
|
|
498
|
+
validate: true
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
/**
|
|
503
|
+
* Minimal preprocessing mode - only essential operations
|
|
504
|
+
* Use this for better performance when you control the input
|
|
505
|
+
*
|
|
506
|
+
* @param text The input string
|
|
507
|
+
* @returns The preprocessed string with minimal processing
|
|
508
|
+
*
|
|
509
|
+
* @example
|
|
510
|
+
* ```ts
|
|
511
|
+
* const processed = preprocessLaTeXMinimal(trustedInput)
|
|
512
|
+
* // Only escapes currency and converts brackets
|
|
513
|
+
* ```
|
|
514
|
+
*/
|
|
515
|
+
export function preprocessLaTeXMinimal(text) {
|
|
516
|
+
return preprocessLaTeX(text, {
|
|
517
|
+
convertBrackets: true,
|
|
518
|
+
escapeCurrency: true,
|
|
519
|
+
escapeMhchem: false,
|
|
520
|
+
escapePipes: false,
|
|
521
|
+
escapeUnderscores: false,
|
|
522
|
+
fixErrors: false,
|
|
523
|
+
handleCJK: false,
|
|
524
|
+
normalizeSpacing: false,
|
|
525
|
+
validate: false
|
|
526
|
+
});
|
|
527
|
+
}
|