@lancar/lxui 1.0.0 → 1.0.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/CHANGELOG.md +215 -55
- package/LICENSE +1 -1
- package/README.md +224 -68
- package/fonts/accessibility/accessibility.css +34 -0
- package/fonts/accessibility/accessibility.min.css +2 -0
- package/fonts/accessibility/atkinson-hyperlegible/AtkinsonHyperlegible-400.woff2 +0 -0
- package/fonts/accessibility/atkinson-hyperlegible/AtkinsonHyperlegible-400Italic.woff2 +0 -0
- package/fonts/accessibility/atkinson-hyperlegible/AtkinsonHyperlegible-700.woff2 +0 -0
- package/fonts/accessibility/atkinson-hyperlegible/atkinson-hyperlegible.css +30 -0
- package/fonts/accessibility/atkinson-hyperlegible/atkinson-hyperlegible.min.css +2 -0
- package/fonts/fonts.css +357 -0
- package/fonts/fonts.min.css +2 -0
- package/fonts/mono/fira-code/FiraCode-400.woff2 +0 -0
- package/fonts/mono/fira-code/FiraCode-500.woff2 +0 -0
- package/fonts/mono/fira-code/FiraCode-700.woff2 +0 -0
- package/fonts/mono/fira-code/fira-code.css +30 -0
- package/fonts/mono/fira-code/fira-code.min.css +2 -0
- package/fonts/mono/jetbrains-mono/JetBrainsMono-400.woff2 +0 -0
- package/fonts/mono/jetbrains-mono/JetBrainsMono-500.woff2 +0 -0
- package/fonts/mono/jetbrains-mono/JetBrainsMono-700.woff2 +0 -0
- package/fonts/mono/jetbrains-mono/jetbrains-mono.css +30 -0
- package/fonts/mono/jetbrains-mono/jetbrains-mono.min.css +2 -0
- package/fonts/mono/mono.css +61 -0
- package/fonts/mono/mono.min.css +2 -0
- package/fonts/sans/ibm-plex-sans/IBMPlexSans-400.woff2 +0 -0
- package/fonts/sans/ibm-plex-sans/IBMPlexSans-400Italic.woff2 +0 -0
- package/fonts/sans/ibm-plex-sans/IBMPlexSans-500.woff2 +0 -0
- package/fonts/sans/ibm-plex-sans/IBMPlexSans-600.woff2 +0 -0
- package/fonts/sans/ibm-plex-sans/IBMPlexSans-700.woff2 +0 -0
- package/fonts/sans/ibm-plex-sans/ibm-plex-sans.css +48 -0
- package/fonts/sans/ibm-plex-sans/ibm-plex-sans.min.css +2 -0
- package/fonts/sans/inter/Inter-400.woff2 +0 -0
- package/fonts/sans/inter/Inter-500.woff2 +0 -0
- package/fonts/sans/inter/Inter-600.woff2 +0 -0
- package/fonts/sans/inter/Inter-700.woff2 +0 -0
- package/fonts/sans/inter/inter.css +39 -0
- package/fonts/sans/inter/inter.min.css +2 -0
- package/fonts/sans/manrope/Manrope-400.woff2 +0 -0
- package/fonts/sans/manrope/Manrope-500.woff2 +0 -0
- package/fonts/sans/manrope/Manrope-600.woff2 +0 -0
- package/fonts/sans/manrope/Manrope-700.woff2 +0 -0
- package/fonts/sans/manrope/manrope.css +39 -0
- package/fonts/sans/manrope/manrope.min.css +2 -0
- package/fonts/sans/plus-jakarta-sans/PlusJakartaSans-400.woff2 +0 -0
- package/fonts/sans/plus-jakarta-sans/PlusJakartaSans-400Italic.woff2 +0 -0
- package/fonts/sans/plus-jakarta-sans/PlusJakartaSans-500.woff2 +0 -0
- package/fonts/sans/plus-jakarta-sans/PlusJakartaSans-600.woff2 +0 -0
- package/fonts/sans/plus-jakarta-sans/PlusJakartaSans-700.woff2 +0 -0
- package/fonts/sans/plus-jakarta-sans/plus-jakarta-sans.css +48 -0
- package/fonts/sans/plus-jakarta-sans/plus-jakarta-sans.min.css +2 -0
- package/fonts/sans/sans.css +169 -0
- package/fonts/sans/sans.min.css +2 -0
- package/fonts/serif/literata/Literata-400.woff2 +0 -0
- package/fonts/serif/literata/Literata-400Italic.woff2 +0 -0
- package/fonts/serif/literata/Literata-600.woff2 +0 -0
- package/fonts/serif/literata/Literata-700.woff2 +0 -0
- package/fonts/serif/literata/literata.css +39 -0
- package/fonts/serif/literata/literata.min.css +2 -0
- package/fonts/serif/merriweather/Merriweather-400.woff2 +0 -0
- package/fonts/serif/merriweather/Merriweather-400Italic.woff2 +0 -0
- package/fonts/serif/merriweather/Merriweather-700.woff2 +0 -0
- package/fonts/serif/merriweather/merriweather.css +30 -0
- package/fonts/serif/merriweather/merriweather.min.css +2 -0
- package/fonts/serif/serif.css +106 -0
- package/fonts/serif/serif.min.css +2 -0
- package/fonts/serif/source-serif-4/SourceSerif4-400.woff2 +0 -0
- package/fonts/serif/source-serif-4/SourceSerif4-400Italic.woff2 +0 -0
- package/fonts/serif/source-serif-4/SourceSerif4-600.woff2 +0 -0
- package/fonts/serif/source-serif-4/SourceSerif4-700.woff2 +0 -0
- package/fonts/serif/source-serif-4/source-serif-4.css +39 -0
- package/fonts/serif/source-serif-4/source-serif-4.min.css +2 -0
- package/lx-grid.min.css +2 -2
- package/lx-utilities.min.css +2 -2
- package/lxeditor.min.css +2 -2
- package/lxfonts.min.css +2 -2
- package/lxicons.min.css +2 -2
- package/lxthemes.min.css +2 -2
- package/lxui.bundle.min.js +5 -5
- package/lxui.esm.min.js +3 -3
- package/lxui.js +3 -3
- package/lxui.min.css +1 -1
- package/lxui.min.js +3 -3
- package/lxui.rtl.min.css +1 -1
- package/package.json +3 -9
- package/types/index.d.ts +1 -1
- package/lxmarked.js +0 -276
- package/lxui.bundle.js +0 -540
- package/lxui.css +0 -2163
- package/lxui.esm.js +0 -669
- package/lxui.rtl.css +0 -2466
- package/marked.min.js +0 -69
package/lxmarked.js
DELETED
|
@@ -1,276 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* lxmarked.js v1.0.0
|
|
3
|
-
* Markdown → HTML parser with optional lxUI class integration.
|
|
4
|
-
* Drop-in replacement for marked.js.
|
|
5
|
-
*
|
|
6
|
-
* API:
|
|
7
|
-
* LxMarked.parse(src, options)
|
|
8
|
-
* LxMarked.parseInline(src)
|
|
9
|
-
*
|
|
10
|
-
* Options:
|
|
11
|
-
* gfm {boolean} true GitHub Flavored Markdown (tables, task lists, strikethrough)
|
|
12
|
-
* breaks {boolean} false Newlines → <br>
|
|
13
|
-
* lxui {boolean} false Inject lxUI utility classes
|
|
14
|
-
*/
|
|
15
|
-
;(function (root, factory) {
|
|
16
|
-
if (typeof module === 'object' && module.exports) module.exports = factory();
|
|
17
|
-
else root.LxMarked = factory();
|
|
18
|
-
}(typeof globalThis !== 'undefined' ? globalThis : this, function () {
|
|
19
|
-
'use strict';
|
|
20
|
-
|
|
21
|
-
// ── Helpers ────────────────────────────────────────────────────────────────
|
|
22
|
-
|
|
23
|
-
function esc(s) {
|
|
24
|
-
return String(s)
|
|
25
|
-
.replace(/&(?!(?:[a-zA-Z]+|#\d+|#x[\da-fA-F]+);)/g, '&')
|
|
26
|
-
.replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function slugify(s) {
|
|
30
|
-
return s.toLowerCase()
|
|
31
|
-
.replace(/[^\w\s-]/g, '')
|
|
32
|
-
.replace(/\s+/g, '-')
|
|
33
|
-
.replace(/-+/g, '-')
|
|
34
|
-
.replace(/^-|-$/g, '');
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// ── Inline parser ──────────────────────────────────────────────────────────
|
|
38
|
-
|
|
39
|
-
function parseInline(src) {
|
|
40
|
-
// 1. Protect inline code spans
|
|
41
|
-
const spans = [];
|
|
42
|
-
src = src.replace(/``([\s\S]+?)``|`([^`\n]+?)`/g, (_, a, b) => {
|
|
43
|
-
spans.push(`<code>${esc(a !== undefined ? a : b)}</code>`);
|
|
44
|
-
return `\x00c${spans.length - 1}\x00`;
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
// 2. Bold + italic combined
|
|
48
|
-
src = src.replace(/(\*\*\*|___)([\s\S]+?)\1/g, '<strong><em>$2</em></strong>');
|
|
49
|
-
// 3. Bold
|
|
50
|
-
src = src.replace(/\*\*([^*\n](?:[^*\n]|\*(?!\*))*)\*\*/g, '<strong>$1</strong>');
|
|
51
|
-
src = src.replace(/__([^_\n](?:[^_\n]|_(?!_))*)__/g, '<strong>$1</strong>');
|
|
52
|
-
// 4. Italic
|
|
53
|
-
src = src.replace(/\*([^\s*][^*\n]*[^\s*]|\S)\*/g, '<em>$1</em>');
|
|
54
|
-
src = src.replace(/_([^\s_][^_\n]*[^\s_]|\S)_/g, '<em>$1</em>');
|
|
55
|
-
// 5. Strikethrough
|
|
56
|
-
src = src.replace(/~~([^~\n]+)~~/g, '<del>$1</del>');
|
|
57
|
-
// 6. Images (before links)
|
|
58
|
-
src = src.replace(/!\[([^\]]*)\]\(([^)]+?)(?:\s+"([^"]*)")?\)/g,
|
|
59
|
-
(_, alt, href, title) =>
|
|
60
|
-
`<img src="${esc(href)}" alt="${esc(alt)}"${title ? ` title="${esc(title)}"` : ''} loading="lazy">`);
|
|
61
|
-
// 7. Links
|
|
62
|
-
src = src.replace(/\[([^\]]+)\]\(([^)]+?)(?:\s+"([^"]*)")?\)/g,
|
|
63
|
-
(_, text, href, title) =>
|
|
64
|
-
`<a href="${esc(href)}"${title ? ` title="${esc(title)}"` : ''} rel="noopener">${text}</a>`);
|
|
65
|
-
// 8. Auto-links
|
|
66
|
-
src = src.replace(/<(https?:\/\/[^>]+)>/g,
|
|
67
|
-
(_, url) => `<a href="${esc(url)}">${esc(url)}</a>`);
|
|
68
|
-
// 9. Hard line breaks
|
|
69
|
-
src = src.replace(/ \n/g, '<br>\n').replace(/\\\n/g, '<br>\n');
|
|
70
|
-
// 10. Restore code spans
|
|
71
|
-
return src.replace(/\x00c(\d+)\x00/g, (_, i) => spans[+i]);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// ── Block: list ────────────────────────────────────────────────────────────
|
|
75
|
-
|
|
76
|
-
function renderList(items, ordered, lxui) {
|
|
77
|
-
const tag = ordered ? 'ol' : 'ul';
|
|
78
|
-
const cls = lxui ? ` class="lx-list${ordered ? ' lx-list-decimal' : ''}"` : '';
|
|
79
|
-
const rows = items.map(item => {
|
|
80
|
-
// Task list
|
|
81
|
-
const t = item.match(/^\[([xX ])\] ([\s\S]*)/);
|
|
82
|
-
if (t) {
|
|
83
|
-
const checked = t[1].toLowerCase() === 'x';
|
|
84
|
-
return `<li><input type="checkbox"${checked ? ' checked' : ''} disabled aria-hidden="true"> ${parseInline(t[2])}</li>`;
|
|
85
|
-
}
|
|
86
|
-
// Nested list embedded?
|
|
87
|
-
return `<li>${parseInline(item)}</li>`;
|
|
88
|
-
});
|
|
89
|
-
return `<${tag}${cls}>\n${rows.join('\n')}\n</${tag}>\n`;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// ── Block: table ───────────────────────────────────────────────────────────
|
|
93
|
-
|
|
94
|
-
function renderTable(hdrLine, sepLine, bodyLines, lxui) {
|
|
95
|
-
const cols = c => c.replace(/^\||\|$/g, '').split('|').map(s => s.trim());
|
|
96
|
-
const aligns = cols(sepLine).map(c => {
|
|
97
|
-
if (/^:-+:$/.test(c)) return 'center';
|
|
98
|
-
if (/-+:$/.test(c)) return 'right';
|
|
99
|
-
if (/^:-/.test(c)) return 'left';
|
|
100
|
-
return null;
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
const th = cols(hdrLine).map((c, i) => {
|
|
104
|
-
const a = aligns[i] ? ` style="text-align:${aligns[i]}"` : '';
|
|
105
|
-
return `<th${a}>${parseInline(c)}</th>`;
|
|
106
|
-
}).join('');
|
|
107
|
-
|
|
108
|
-
const trs = bodyLines.filter(l => l.trim()).map(row =>
|
|
109
|
-
'<tr>' + cols(row).map((c, i) => {
|
|
110
|
-
const a = aligns[i] ? ` style="text-align:${aligns[i]}"` : '';
|
|
111
|
-
return `<td${a}>${parseInline(c)}</td>`;
|
|
112
|
-
}).join('') + '</tr>'
|
|
113
|
-
).join('\n');
|
|
114
|
-
|
|
115
|
-
const tblCls = lxui ? ' class="lx-table lx-table-bordered"' : '';
|
|
116
|
-
const wrap = lxui ? ' style="overflow-x:auto"' : '';
|
|
117
|
-
return `<div${wrap}><table${tblCls}>\n<thead><tr>${th}</tr></thead>\n<tbody>\n${trs}\n</tbody>\n</table></div>\n`;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// ── Main block parser ──────────────────────────────────────────────────────
|
|
121
|
-
|
|
122
|
-
function parse(src, opts) {
|
|
123
|
-
const { gfm = true, breaks = false, lxui = false } = opts || {};
|
|
124
|
-
src = src.replace(/\r\n|\r/g, '\n');
|
|
125
|
-
|
|
126
|
-
// Extract fenced code blocks first (highest priority)
|
|
127
|
-
const blocks = [];
|
|
128
|
-
src = src.replace(/^(`{3,}|~{3,})([\w+#\-. ]*)\n([\s\S]*?)\n?\1\s*$/gm,
|
|
129
|
-
(_, fence, info, code) => {
|
|
130
|
-
const lang = info.trim();
|
|
131
|
-
const langCls = lang ? ` class="language-${esc(lang)}"` : '';
|
|
132
|
-
const preCls = lxui ? ' class="lx-code-block"' : '';
|
|
133
|
-
blocks.push(`<pre${preCls}><code${langCls}>${esc(code.replace(/\n$/, ''))}</code></pre>`);
|
|
134
|
-
return `\x00B${blocks.length - 1}\x00`;
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
const lines = src.split('\n');
|
|
138
|
-
let out = '', i = 0;
|
|
139
|
-
|
|
140
|
-
while (i < lines.length) {
|
|
141
|
-
const line = lines[i];
|
|
142
|
-
|
|
143
|
-
// Blank
|
|
144
|
-
if (!line.trim()) { i++; continue; }
|
|
145
|
-
|
|
146
|
-
// Code block placeholder
|
|
147
|
-
const cbM = line.trim().match(/^\x00B(\d+)\x00$/);
|
|
148
|
-
if (cbM) { out += blocks[+cbM[1]] + '\n'; i++; continue; }
|
|
149
|
-
|
|
150
|
-
// ATX Heading
|
|
151
|
-
const hM = line.match(/^(#{1,6})\s+(.*?)(?:\s+#+)?\s*$/);
|
|
152
|
-
if (hM) {
|
|
153
|
-
const lvl = hM[1].length;
|
|
154
|
-
const txt = hM[2];
|
|
155
|
-
const id = slugify(txt.replace(/[*_`~]/g, ''));
|
|
156
|
-
out += `<h${lvl} id="${id}">${parseInline(txt)}</h${lvl}>\n`;
|
|
157
|
-
i++; continue;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// Setext headings
|
|
161
|
-
if (i + 1 < lines.length) {
|
|
162
|
-
if (/^=+\s*$/.test(lines[i + 1]) && line.trim()) {
|
|
163
|
-
out += `<h1 id="${slugify(line)}">${parseInline(line)}</h1>\n`;
|
|
164
|
-
i += 2; continue;
|
|
165
|
-
}
|
|
166
|
-
const isSetext2 = /^-+\s*$/.test(lines[i + 1]);
|
|
167
|
-
const notHR = !/^[-*_]{3,}\s*$/.test(line.trim());
|
|
168
|
-
if (isSetext2 && line.trim() && notHR) {
|
|
169
|
-
out += `<h2 id="${slugify(line)}">${parseInline(line)}</h2>\n`;
|
|
170
|
-
i += 2; continue;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Horizontal rule
|
|
175
|
-
if (/^(?:[-*_]\s*){3,}$/.test(line.trim())) {
|
|
176
|
-
out += '<hr>\n'; i++; continue;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// Blockquote
|
|
180
|
-
if (/^>\s?/.test(line)) {
|
|
181
|
-
const bq = [];
|
|
182
|
-
while (i < lines.length && (/^>\s?/.test(lines[i]) ||
|
|
183
|
-
(!lines[i].trim() && i + 1 < lines.length && /^>\s?/.test(lines[i + 1])))) {
|
|
184
|
-
bq.push(lines[i].replace(/^>\s?/, ''));
|
|
185
|
-
i++;
|
|
186
|
-
}
|
|
187
|
-
const cls = lxui ? ' class="lx-blockquote"' : '';
|
|
188
|
-
out += `<blockquote${cls}>\n${parse(bq.join('\n'), { gfm, breaks, lxui })}</blockquote>\n`;
|
|
189
|
-
continue;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// Indented code block (4 spaces / 1 tab)
|
|
193
|
-
if (/^( |\t)/.test(line)) {
|
|
194
|
-
const code = [];
|
|
195
|
-
while (i < lines.length && (/^( |\t)/.test(lines[i]) || !lines[i].trim())) {
|
|
196
|
-
code.push(lines[i].replace(/^ |\t/, ''));
|
|
197
|
-
i++;
|
|
198
|
-
}
|
|
199
|
-
// trim trailing blank lines
|
|
200
|
-
while (code.length && !code[code.length - 1].trim()) code.pop();
|
|
201
|
-
const preCls = lxui ? ' class="lx-code-block"' : '';
|
|
202
|
-
out += `<pre${preCls}><code>${esc(code.join('\n'))}</code></pre>\n`;
|
|
203
|
-
continue;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// Lists
|
|
207
|
-
const ulM = line.match(/^(\s*)[-*+]\s+([\s\S]+)/);
|
|
208
|
-
const olM = line.match(/^(\s*)\d+\.\s+([\s\S]+)/);
|
|
209
|
-
if (ulM || olM) {
|
|
210
|
-
const ordered = !!olM;
|
|
211
|
-
const baseIndent = (ordered ? olM : ulM)[1].length;
|
|
212
|
-
const listItems = [];
|
|
213
|
-
let cur = (ordered ? olM : ulM)[2];
|
|
214
|
-
|
|
215
|
-
i++;
|
|
216
|
-
while (i < lines.length) {
|
|
217
|
-
const l = lines[i];
|
|
218
|
-
if (!l.trim()) { i++; continue; }
|
|
219
|
-
|
|
220
|
-
const ul2 = l.match(/^(\s*)[-*+]\s+([\s\S]+)/);
|
|
221
|
-
const ol2 = l.match(/^(\s*)\d+\.\s+([\s\S]+)/);
|
|
222
|
-
const nxt = ordered ? ol2 : ul2;
|
|
223
|
-
|
|
224
|
-
if (nxt && nxt[1].length === baseIndent) {
|
|
225
|
-
listItems.push(cur.trim());
|
|
226
|
-
cur = nxt[2]; i++;
|
|
227
|
-
} else if (l.startsWith(' '.repeat(baseIndent + 2)) || l.startsWith('\t')) {
|
|
228
|
-
cur += ' ' + l.trim(); i++;
|
|
229
|
-
} else { break; }
|
|
230
|
-
}
|
|
231
|
-
listItems.push(cur.trim());
|
|
232
|
-
out += renderList(listItems, ordered, lxui);
|
|
233
|
-
continue;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
// GFM Table
|
|
237
|
-
if (gfm && i + 1 < lines.length && line.includes('|') &&
|
|
238
|
-
/^\|?[\s:|-]+[\s:|*-]*\|?$/.test((lines[i + 1] || '').trim())) {
|
|
239
|
-
const hdr = line;
|
|
240
|
-
const sep = lines[i + 1];
|
|
241
|
-
const body = [];
|
|
242
|
-
i += 2;
|
|
243
|
-
while (i < lines.length && lines[i].includes('|')) { body.push(lines[i]); i++; }
|
|
244
|
-
out += renderTable(hdr, sep, body, lxui);
|
|
245
|
-
continue;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
// Paragraph
|
|
249
|
-
const para = [];
|
|
250
|
-
while (i < lines.length) {
|
|
251
|
-
const l = lines[i];
|
|
252
|
-
if (!l.trim()) break;
|
|
253
|
-
if (/^#{1,6}\s/.test(l) || /^(?:[-*_]\s*){3,}$/.test(l.trim())) break;
|
|
254
|
-
if (/^>\s?/.test(l) || /^(\s*)[-*+]\s/.test(l) || /^(\s*)\d+\.\s/.test(l)) break;
|
|
255
|
-
if (/^\x00B/.test(l.trim()) || /^( |\t)/.test(l)) break;
|
|
256
|
-
if (gfm && i + 1 < lines.length &&
|
|
257
|
-
/^\|?[\s:|-]+[\s:|*-]*\|?$/.test((lines[i + 1] || '').trim())) break;
|
|
258
|
-
// setext
|
|
259
|
-
if (para.length && i + 1 < lines.length &&
|
|
260
|
-
(/^=+\s*$/.test(lines[i + 1]) || /^-+\s*$/.test(lines[i + 1]))) break;
|
|
261
|
-
para.push(l);
|
|
262
|
-
i++;
|
|
263
|
-
}
|
|
264
|
-
if (para.length) {
|
|
265
|
-
const txt = breaks
|
|
266
|
-
? para.join('<br>\n')
|
|
267
|
-
: para.join('\n');
|
|
268
|
-
out += `<p>${parseInline(txt)}</p>\n`;
|
|
269
|
-
} else { i++; }
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
return out;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
return { parse, parseInline };
|
|
276
|
-
}));
|