@braincrew-lab/langchain-canvas 0.7.5 → 0.7.6
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.
|
@@ -141,6 +141,107 @@ function docxStats(root) {
|
|
|
141
141
|
substitutedFonts: substitutedFonts(root)
|
|
142
142
|
};
|
|
143
143
|
}
|
|
144
|
+
|
|
145
|
+
// src/io/symbolBullets.ts
|
|
146
|
+
var SYMBOL_FONT_BULLETS = {
|
|
147
|
+
symbol: {
|
|
148
|
+
61623: "\u2022"
|
|
149
|
+
// • bullet — Word's default list bullet
|
|
150
|
+
},
|
|
151
|
+
wingdings: {
|
|
152
|
+
61548: "\u25CF",
|
|
153
|
+
// ● black circle
|
|
154
|
+
61549: "\u274D",
|
|
155
|
+
// ❍ shadowed white circle
|
|
156
|
+
61550: "\u25A0",
|
|
157
|
+
// ■ black square
|
|
158
|
+
61551: "\u25A1",
|
|
159
|
+
// □ white square
|
|
160
|
+
61553: "\u2751",
|
|
161
|
+
// ❑ lower-right shadowed white square
|
|
162
|
+
61557: "\u25C6",
|
|
163
|
+
// ◆ black diamond
|
|
164
|
+
61607: "\u25AA",
|
|
165
|
+
// ▪ black small square
|
|
166
|
+
61656: "\u27A2",
|
|
167
|
+
// ➢ three-d top-lighted right arrowhead
|
|
168
|
+
61692: "\u2714",
|
|
169
|
+
// ✔ heavy check mark
|
|
170
|
+
61694: "\u2611"
|
|
171
|
+
// ☑ ballot box with check
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
function isPrivateUse(codePoint) {
|
|
175
|
+
return codePoint >= 57344 && codePoint <= 63743;
|
|
176
|
+
}
|
|
177
|
+
function primaryFont(fontFamily) {
|
|
178
|
+
const first = fontFamily.split(",")[0] ?? "";
|
|
179
|
+
return first.trim().replace(/^['"]|['"]$/g, "").toLowerCase();
|
|
180
|
+
}
|
|
181
|
+
function standardBullet(codePoint, fontFamily) {
|
|
182
|
+
const table = SYMBOL_FONT_BULLETS[primaryFont(fontFamily)];
|
|
183
|
+
return table?.[codePoint] ?? null;
|
|
184
|
+
}
|
|
185
|
+
function drawnOnPage(root, selectorText) {
|
|
186
|
+
return selectorText.split(",").some((part) => {
|
|
187
|
+
const base = part.trim().replace(/::?(before|after)\s*$/i, "").trim();
|
|
188
|
+
if (!base) return false;
|
|
189
|
+
try {
|
|
190
|
+
return root.querySelector(base) !== null;
|
|
191
|
+
} catch {
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
function styleRules(sheet) {
|
|
197
|
+
const found = [];
|
|
198
|
+
const stack = [...sheet.cssRules];
|
|
199
|
+
while (stack.length) {
|
|
200
|
+
const rule = stack.pop();
|
|
201
|
+
if (rule.cssRules?.length) {
|
|
202
|
+
stack.push(...rule.cssRules);
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
if (rule.style && rule.selectorText) found.push(rule);
|
|
206
|
+
}
|
|
207
|
+
return found;
|
|
208
|
+
}
|
|
209
|
+
function restoreSymbolBullets(root) {
|
|
210
|
+
const swaps = [];
|
|
211
|
+
for (const style of Array.from(root.querySelectorAll("style"))) {
|
|
212
|
+
let rules;
|
|
213
|
+
try {
|
|
214
|
+
rules = style.sheet ? styleRules(style.sheet) : [];
|
|
215
|
+
} catch {
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
for (const rule of rules) {
|
|
219
|
+
const content = rule.style.getPropertyValue("content");
|
|
220
|
+
if (!content) continue;
|
|
221
|
+
const font = rule.style.getPropertyValue("font-family");
|
|
222
|
+
if (!font) continue;
|
|
223
|
+
if (!drawnOnPage(root, rule.selectorText)) continue;
|
|
224
|
+
let next = "";
|
|
225
|
+
let changed = false;
|
|
226
|
+
for (const character of content) {
|
|
227
|
+
const code = character.codePointAt(0) ?? 0;
|
|
228
|
+
const standard = isPrivateUse(code) ? standardBullet(code, font) : null;
|
|
229
|
+
if (standard === null) {
|
|
230
|
+
next += character;
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
next += standard;
|
|
234
|
+
changed = true;
|
|
235
|
+
swaps.push({ from: character, to: standard, font: primaryFont(font) });
|
|
236
|
+
}
|
|
237
|
+
if (changed) rule.style.setProperty("content", next);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
return swaps;
|
|
241
|
+
}
|
|
242
|
+
function redrawnFonts(swaps) {
|
|
243
|
+
return [...new Set(swaps.map((swap) => swap.font))];
|
|
244
|
+
}
|
|
144
245
|
var BANNER = "Preview only \u2014 to change it, ask in chat or select some text.";
|
|
145
246
|
function DocxPreview({
|
|
146
247
|
artifactId,
|
|
@@ -151,6 +252,7 @@ function DocxPreview({
|
|
|
151
252
|
const hostRef = useRef(null);
|
|
152
253
|
const [status, setStatus] = useState("loading");
|
|
153
254
|
const [stats, setStats] = useState(null);
|
|
255
|
+
const [redrawn, setRedrawn] = useState([]);
|
|
154
256
|
const [picked, setPicked] = useState(null);
|
|
155
257
|
const setSelections = useCanvasStore((s) => s.setSelections);
|
|
156
258
|
useEffect(() => {
|
|
@@ -160,6 +262,7 @@ function DocxPreview({
|
|
|
160
262
|
if (!host) return;
|
|
161
263
|
setStatus("loading");
|
|
162
264
|
setStats(null);
|
|
265
|
+
setRedrawn([]);
|
|
163
266
|
setPicked(null);
|
|
164
267
|
(async () => {
|
|
165
268
|
const { renderAsync } = await loadOptional(
|
|
@@ -181,6 +284,7 @@ function DocxPreview({
|
|
|
181
284
|
});
|
|
182
285
|
if (!live) return;
|
|
183
286
|
stampDocxAddresses(host);
|
|
287
|
+
setRedrawn(redrawnFonts(restoreSymbolBullets(host)));
|
|
184
288
|
setStats(docxStats(host));
|
|
185
289
|
setStatus("ready");
|
|
186
290
|
let fittedFor = host.clientWidth;
|
|
@@ -262,7 +366,18 @@ function DocxPreview({
|
|
|
262
366
|
stats.substitutedFonts.length > 0 && /* @__PURE__ */ jsxs("span", { className: "cv-docx__fonts", children: [
|
|
263
367
|
"substituted: ",
|
|
264
368
|
stats.substitutedFonts.join(", ")
|
|
265
|
-
] })
|
|
369
|
+
] }),
|
|
370
|
+
redrawn.length > 0 && /* @__PURE__ */ jsxs(
|
|
371
|
+
"span",
|
|
372
|
+
{
|
|
373
|
+
className: "cv-docx__redrawn",
|
|
374
|
+
title: "This document writes its list bullets as characters in a symbol font's own private area, which no other font can draw. They are shown here as the standard characters that mean the same mark; the stored file is unchanged.",
|
|
375
|
+
children: [
|
|
376
|
+
"bullets redrawn: ",
|
|
377
|
+
redrawn.join(", ")
|
|
378
|
+
]
|
|
379
|
+
}
|
|
380
|
+
)
|
|
266
381
|
]
|
|
267
382
|
}
|
|
268
383
|
)
|
|
@@ -10,7 +10,7 @@ function formatSize(size) {
|
|
|
10
10
|
return `${(size / (1024 * 1024)).toFixed(1)} MB`;
|
|
11
11
|
}
|
|
12
12
|
var DocxPreview = lazy(
|
|
13
|
-
() => import('./DocxPreview-
|
|
13
|
+
() => import('./DocxPreview-NGT3Z5KW.js').then((m) => ({ default: m.DocxPreview }))
|
|
14
14
|
);
|
|
15
15
|
function iconFor(mediaType, name) {
|
|
16
16
|
if (mediaType?.startsWith("image/")) return "\u{1F5BC}\uFE0F";
|
package/dist/index.js
CHANGED
|
@@ -2264,7 +2264,7 @@ var ChartRenderer = lazy(() => import('./ChartRenderer-TBTWNPV7.js').then((m) =>
|
|
|
2264
2264
|
var DocumentRenderer = lazy(() => import('./DocumentRenderer-ZGJXDVKG.js').then((m) => ({ default: m.DocumentRenderer })));
|
|
2265
2265
|
var TableRenderer = lazy(() => import('./TableRenderer-YTOF2ZIC.js').then((m) => ({ default: m.TableRenderer })));
|
|
2266
2266
|
var SlidesRenderer = lazy(() => import('./SlidesRenderer-4QWZVWWD.js').then((m) => ({ default: m.SlidesRenderer })));
|
|
2267
|
-
var FileRenderer = lazy(() => import('./FileRenderer-
|
|
2267
|
+
var FileRenderer = lazy(() => import('./FileRenderer-TZSZVVLY.js').then((m) => ({ default: m.FileRenderer })));
|
|
2268
2268
|
var builtinRenderers = {
|
|
2269
2269
|
html: HtmlRenderer,
|
|
2270
2270
|
document: DocumentRenderer,
|
package/dist/styles.css
CHANGED
|
@@ -1309,6 +1309,7 @@
|
|
|
1309
1309
|
}
|
|
1310
1310
|
.cv-docx__picked { color: var(--cv-accent); }
|
|
1311
1311
|
.cv-docx__fonts { color: var(--cv-warn, #b45309); }
|
|
1312
|
+
.cv-docx__redrawn { color: var(--cv-warn, #b45309); }
|
|
1312
1313
|
|
|
1313
1314
|
/* Tablet / narrow desktop: tighten paddings, let toolbars wrap. */
|
|
1314
1315
|
@media (max-width: 900px) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@braincrew-lab/langchain-canvas",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.6",
|
|
4
4
|
"description": "A live canvas for LangChain agents — stream documents, charts, and rich artifacts into a React panel.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Brain Crew (https://github.com/braincrew-lab)",
|