docgen-utils 1.0.12 → 1.0.13
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/dist/bundle.js +3189 -1238
- package/dist/bundle.min.js +101 -99
- package/dist/cli.js +2653 -1117
- package/dist/packages/cli/commands/export-docs.d.ts.map +1 -1
- package/dist/packages/cli/commands/export-docs.js +131 -2
- package/dist/packages/cli/commands/export-docs.js.map +1 -1
- package/dist/packages/cli/commands/export-slides.d.ts.map +1 -1
- package/dist/packages/cli/commands/export-slides.js +25 -1
- package/dist/packages/cli/commands/export-slides.js.map +1 -1
- package/dist/packages/docs/common.d.ts +10 -0
- package/dist/packages/docs/common.d.ts.map +1 -1
- package/dist/packages/docs/common.js.map +1 -1
- package/dist/packages/docs/convert.d.ts.map +1 -1
- package/dist/packages/docs/convert.js +246 -218
- package/dist/packages/docs/convert.js.map +1 -1
- package/dist/packages/docs/create-document.d.ts.map +1 -1
- package/dist/packages/docs/create-document.js +43 -3
- package/dist/packages/docs/create-document.js.map +1 -1
- package/dist/packages/docs/export.d.ts +9 -8
- package/dist/packages/docs/export.d.ts.map +1 -1
- package/dist/packages/docs/export.js +23 -36
- package/dist/packages/docs/export.js.map +1 -1
- package/dist/packages/docs/parse-colors.d.ts +37 -0
- package/dist/packages/docs/parse-colors.d.ts.map +1 -0
- package/dist/packages/docs/parse-colors.js +507 -0
- package/dist/packages/docs/parse-colors.js.map +1 -0
- package/dist/packages/docs/parse-css.d.ts +98 -0
- package/dist/packages/docs/parse-css.d.ts.map +1 -0
- package/dist/packages/docs/parse-css.js +1592 -0
- package/dist/packages/docs/parse-css.js.map +1 -0
- package/dist/packages/docs/parse-helpers.d.ts +45 -0
- package/dist/packages/docs/parse-helpers.d.ts.map +1 -0
- package/dist/packages/docs/parse-helpers.js +214 -0
- package/dist/packages/docs/parse-helpers.js.map +1 -0
- package/dist/packages/docs/parse-inline.d.ts +41 -0
- package/dist/packages/docs/parse-inline.d.ts.map +1 -0
- package/dist/packages/docs/parse-inline.js +473 -0
- package/dist/packages/docs/parse-inline.js.map +1 -0
- package/dist/packages/docs/parse-layout.d.ts +57 -0
- package/dist/packages/docs/parse-layout.d.ts.map +1 -0
- package/dist/packages/docs/parse-layout.js +295 -0
- package/dist/packages/docs/parse-layout.js.map +1 -0
- package/dist/packages/docs/parse-special.d.ts +51 -0
- package/dist/packages/docs/parse-special.d.ts.map +1 -0
- package/dist/packages/docs/parse-special.js +251 -0
- package/dist/packages/docs/parse-special.js.map +1 -0
- package/dist/packages/docs/parse-units.d.ts +68 -0
- package/dist/packages/docs/parse-units.d.ts.map +1 -0
- package/dist/packages/docs/parse-units.js +275 -0
- package/dist/packages/docs/parse-units.js.map +1 -0
- package/dist/packages/docs/parse.d.ts.map +1 -1
- package/dist/packages/docs/parse.js +957 -2800
- package/dist/packages/docs/parse.js.map +1 -1
- package/dist/packages/slides/common.d.ts +7 -0
- package/dist/packages/slides/common.d.ts.map +1 -1
- package/dist/packages/slides/convert.d.ts.map +1 -1
- package/dist/packages/slides/convert.js +92 -7
- package/dist/packages/slides/convert.js.map +1 -1
- package/dist/packages/slides/parse.d.ts.map +1 -1
- package/dist/packages/slides/parse.js +723 -40
- package/dist/packages/slides/parse.js.map +1 -1
- package/dist/packages/slides/transform.d.ts.map +1 -1
- package/dist/packages/slides/transform.js +12 -7
- package/dist/packages/slides/transform.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
import { getElementStyles } from "./parse-css";
|
|
2
|
+
export function isGridOrFlexContainer(element, cssContext) {
|
|
3
|
+
const styles = getElementStyles(element, cssContext);
|
|
4
|
+
return styles.display === "grid" || styles.display === "flex";
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* GENERALIZED: Check if an element is a horizontal flex container.
|
|
8
|
+
* A horizontal flex container has display: flex with flex-direction: row (or unset, since row is default).
|
|
9
|
+
* This is used to detect containers where flex items should be visually separated
|
|
10
|
+
* with a separator character (like " • ") to represent the CSS gap.
|
|
11
|
+
*
|
|
12
|
+
* @param element - The element to check
|
|
13
|
+
* @param cssContext - CSS context for style resolution
|
|
14
|
+
* @returns true if this is a horizontal flex container, false otherwise
|
|
15
|
+
*/
|
|
16
|
+
export function isHorizontalFlexContainer(element, cssContext) {
|
|
17
|
+
const styles = getElementStyles(element, cssContext);
|
|
18
|
+
// Must be a flex container
|
|
19
|
+
if (styles.display !== "flex") {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
// Check flex-direction - horizontal if "row" or "row-reverse" or not set (default is row)
|
|
23
|
+
// Vertical (column) containers should NOT have separators between items
|
|
24
|
+
const direction = styles.flexDirection?.toLowerCase();
|
|
25
|
+
if (direction === "column" || direction === "column-reverse") {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
// Also check inline styles for flex-direction override
|
|
29
|
+
const inlineStyle = element.getAttribute("style") || "";
|
|
30
|
+
const directionMatch = inlineStyle.match(/flex-direction\s*:\s*([^;]+)/i);
|
|
31
|
+
if (directionMatch) {
|
|
32
|
+
const inlineDirection = directionMatch[1].trim().toLowerCase();
|
|
33
|
+
if (inlineDirection === "column" || inlineDirection === "column-reverse") {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Check if an SVG element is purely decorative (background pattern, decoration, etc).
|
|
41
|
+
* Decorative SVGs should NOT be converted to chart placeholders.
|
|
42
|
+
*
|
|
43
|
+
* Detection criteria (style-based, not class-name-based per skill rules):
|
|
44
|
+
* 1. Fixed/absolute positioning (background elements)
|
|
45
|
+
* 2. Very low opacity (< 0.5)
|
|
46
|
+
* 3. Contains only pattern definitions (<defs>, <pattern>, <linearGradient>)
|
|
47
|
+
* 4. Is a background overlay (pointer-events: none)
|
|
48
|
+
* 5. Very small viewBox (icons < 50x50)
|
|
49
|
+
*/
|
|
50
|
+
export function isDecorativeSvg(svgElement, parentElement, cssContext) {
|
|
51
|
+
// Check parent container styles
|
|
52
|
+
const parentStyles = getElementStyles(parentElement, cssContext);
|
|
53
|
+
const parentInlineStyle = parentElement.getAttribute("style") || "";
|
|
54
|
+
// Check SVG's own styles
|
|
55
|
+
const svgInlineStyle = svgElement.getAttribute("style") || "";
|
|
56
|
+
// 1. Check for fixed/absolute positioning (typically background elements)
|
|
57
|
+
const positionMatch = parentInlineStyle.match(/position\s*:\s*(fixed|absolute)/i) ||
|
|
58
|
+
svgInlineStyle.match(/position\s*:\s*(fixed|absolute)/i);
|
|
59
|
+
if (positionMatch) {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
// 2. Check for low opacity (decorative overlays)
|
|
63
|
+
const parentOpacityMatch = parentInlineStyle.match(/opacity\s*:\s*([0-9.]+)/i);
|
|
64
|
+
const svgOpacityMatch = svgInlineStyle.match(/opacity\s*:\s*([0-9.]+)/i);
|
|
65
|
+
const opacityAttr = svgElement.getAttribute("opacity");
|
|
66
|
+
const opacity = parseFloat(parentOpacityMatch?.[1] || svgOpacityMatch?.[1] || opacityAttr || "1");
|
|
67
|
+
if (opacity < 0.5) {
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
// 3. Check for pointer-events: none (non-interactive background)
|
|
71
|
+
if (parentInlineStyle.includes("pointer-events: none") ||
|
|
72
|
+
svgInlineStyle.includes("pointer-events: none") ||
|
|
73
|
+
parentStyles.display === "none") {
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
// 4. Check if SVG contains only definitions (patterns, gradients) - no actual shapes
|
|
77
|
+
const hasOnlyDefs = svgElement.children.length > 0 &&
|
|
78
|
+
Array.from(svgElement.children).every((child) => ["defs", "style", "title", "desc"].includes(child.tagName.toLowerCase()));
|
|
79
|
+
if (hasOnlyDefs) {
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
// 5. Check for very small viewBox (likely an icon, not a chart)
|
|
83
|
+
// Charts must be at least 100x50 to match export.ts isChartSvg()
|
|
84
|
+
const viewBox = svgElement.getAttribute("viewBox");
|
|
85
|
+
if (viewBox) {
|
|
86
|
+
const parts = viewBox.split(/\s+/).map(Number);
|
|
87
|
+
if (parts.length >= 4) {
|
|
88
|
+
const width = parts[2] || 0;
|
|
89
|
+
const height = parts[3] || 0;
|
|
90
|
+
// Charts must be at least 100x50 - anything smaller is decorative
|
|
91
|
+
if (width > 0 && height > 0 && (width < 100 || height < 50)) {
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
// No viewBox - check width/height attributes
|
|
98
|
+
const widthAttr = svgElement.getAttribute("width");
|
|
99
|
+
const heightAttr = svgElement.getAttribute("height");
|
|
100
|
+
if (widthAttr && heightAttr) {
|
|
101
|
+
const width = parseFloat(widthAttr) || 0;
|
|
102
|
+
const height = parseFloat(heightAttr) || 0;
|
|
103
|
+
// Charts must be at least 100x50
|
|
104
|
+
if (width > 0 && height > 0 && (width < 100 || height < 50)) {
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// 6. Check if SVG is purely a pattern/gradient container
|
|
110
|
+
// These typically have <rect> with fill="url(#pattern)" or only <circle>/<path> with very low complexity
|
|
111
|
+
const shapes = svgElement.querySelectorAll("rect, circle, ellipse, path, polygon, polyline, line");
|
|
112
|
+
if (shapes.length > 0) {
|
|
113
|
+
// Count shapes that use pattern/gradient fills (decorative)
|
|
114
|
+
let decorativeShapeCount = 0;
|
|
115
|
+
for (const shape of shapes) {
|
|
116
|
+
const fill = shape.getAttribute("fill") || "";
|
|
117
|
+
const stroke = shape.getAttribute("stroke") || "";
|
|
118
|
+
if (fill.includes("url(#") || stroke.includes("url(#")) {
|
|
119
|
+
decorativeShapeCount++;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// If all shapes use pattern/gradient fills, it's likely decorative
|
|
123
|
+
if (decorativeShapeCount === shapes.length && shapes.length <= 5) {
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// 7. Check if this appears to be a progress circle (small circular skills indicator)
|
|
128
|
+
// These have circle elements with stroke-dasharray for progress
|
|
129
|
+
const circles = svgElement.querySelectorAll("circle");
|
|
130
|
+
if (circles.length > 0 && circles.length <= 2) {
|
|
131
|
+
const hasStrokeDasharray = Array.from(circles).some((c) => c.getAttribute("stroke-dasharray"));
|
|
132
|
+
if (hasStrokeDasharray) {
|
|
133
|
+
// This is a progress indicator, not a chart - treat as decorative for now
|
|
134
|
+
// In the future, we could extract the percentage
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// 8. Check if parent is a centered flex container (typical hero image pattern)
|
|
139
|
+
// Hero images typically have: display: flex; align-items: center; justify-content: center
|
|
140
|
+
// These contain illustrative SVGs which should be included as images, not filtered
|
|
141
|
+
// We no longer filter these - they are legitimate content images
|
|
142
|
+
// (Previously we filtered centered flex containers, but hero images should be included)
|
|
143
|
+
// 9. SVGs with sufficient size should be included as images
|
|
144
|
+
// We only filter out truly decorative elements (icons, patterns, progress circles)
|
|
145
|
+
// Large SVGs (illustrations, charts, diagrams) should all be included
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Check if an element is a two-column CSS grid layout.
|
|
150
|
+
* Detects patterns like: display: grid; grid-template-columns: Xpx 1fr
|
|
151
|
+
* Returns the sidebar width percentage if it's a two-column layout, undefined otherwise.
|
|
152
|
+
*/
|
|
153
|
+
export function isTwoColumnGridLayout(element, cssContext) {
|
|
154
|
+
const styles = getElementStyles(element, cssContext);
|
|
155
|
+
// Must be a grid container
|
|
156
|
+
if (styles.display !== "grid") {
|
|
157
|
+
return undefined;
|
|
158
|
+
}
|
|
159
|
+
// Check for two-column pattern (e.g., "280px 1fr", "300px auto", "25% 75%")
|
|
160
|
+
const gridCols = styles.gridTemplateColumns;
|
|
161
|
+
if (!gridCols) {
|
|
162
|
+
return undefined;
|
|
163
|
+
}
|
|
164
|
+
// Parse grid-template-columns to detect two-column sidebar layout
|
|
165
|
+
// Common patterns:
|
|
166
|
+
// - "280px 1fr" (fixed sidebar + fluid main)
|
|
167
|
+
// - "300px auto" (fixed sidebar + auto main)
|
|
168
|
+
// - "25% 1fr" (percentage sidebar + fluid main)
|
|
169
|
+
const parts = gridCols.trim().split(/\s+/);
|
|
170
|
+
if (parts.length !== 2) {
|
|
171
|
+
return undefined;
|
|
172
|
+
}
|
|
173
|
+
const [first, second] = parts;
|
|
174
|
+
// Check if first column is a fixed width or small percentage (sidebar)
|
|
175
|
+
// and second column is flexible (1fr, auto, or larger percentage)
|
|
176
|
+
const firstIsSidebar = (first.endsWith("px") && parseInt(first, 10) <= 400) ||
|
|
177
|
+
(first.endsWith("%") && parseFloat(first) <= 35);
|
|
178
|
+
const secondIsMain = second === "1fr" ||
|
|
179
|
+
second === "auto" ||
|
|
180
|
+
(second.endsWith("%") && parseFloat(second) >= 50) ||
|
|
181
|
+
(second.endsWith("fr") && parseFloat(second) >= 1);
|
|
182
|
+
if (firstIsSidebar && secondIsMain) {
|
|
183
|
+
// Calculate sidebar width percentage
|
|
184
|
+
if (first.endsWith("px")) {
|
|
185
|
+
// Assume ~1100px total width for typical documents
|
|
186
|
+
const pxWidth = parseInt(first, 10);
|
|
187
|
+
return Math.round((pxWidth / 1100) * 100);
|
|
188
|
+
}
|
|
189
|
+
else if (first.endsWith("%")) {
|
|
190
|
+
return parseFloat(first);
|
|
191
|
+
}
|
|
192
|
+
return 25; // Default 25% for other cases
|
|
193
|
+
}
|
|
194
|
+
return undefined;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Find the sidebar and main content elements in a two-column grid container.
|
|
198
|
+
* Returns the first two direct children as [sidebar, main] or undefined.
|
|
199
|
+
*/
|
|
200
|
+
export function findTwoColumnChildren(container) {
|
|
201
|
+
const children = Array.from(container.children).filter((child) => child.nodeType === Node.ELEMENT_NODE);
|
|
202
|
+
if (children.length < 2) {
|
|
203
|
+
return undefined;
|
|
204
|
+
}
|
|
205
|
+
// First child is sidebar (aside, div, etc.), second is main content
|
|
206
|
+
return [children[0], children[1]];
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* GENERALIZED: Detect if an element is a flex container with equal-width columns.
|
|
210
|
+
* This handles layouts like:
|
|
211
|
+
* display: flex; with children having flex: 1 (equal width)
|
|
212
|
+
*
|
|
213
|
+
* Returns the column children if detected, undefined otherwise.
|
|
214
|
+
* Each child will become a column in a DOCX table.
|
|
215
|
+
*/
|
|
216
|
+
export function detectFlexEqualColumns(element, cssContext) {
|
|
217
|
+
const styles = getElementStyles(element, cssContext);
|
|
218
|
+
// Must be a flex container
|
|
219
|
+
if (styles.display !== "flex") {
|
|
220
|
+
return undefined;
|
|
221
|
+
}
|
|
222
|
+
// Get direct children
|
|
223
|
+
const children = Array.from(element.children).filter((child) => child.nodeType === Node.ELEMENT_NODE);
|
|
224
|
+
// Need at least 2 children for multi-column layout
|
|
225
|
+
if (children.length < 2 || children.length > 12) {
|
|
226
|
+
return undefined;
|
|
227
|
+
}
|
|
228
|
+
// Check if children have flex: 1 or similar equal-width pattern
|
|
229
|
+
// Also check inline styles since class-based flex: 1 is common
|
|
230
|
+
let hasEqualFlexChildren = true;
|
|
231
|
+
for (const child of children) {
|
|
232
|
+
const childStyles = getElementStyles(child, cssContext);
|
|
233
|
+
const inlineStyle = child.getAttribute("style") || "";
|
|
234
|
+
// Check for flex: 1 in CSS or inline styles
|
|
235
|
+
const hasFlex1 = childStyles.flex === "1" ||
|
|
236
|
+
inlineStyle.includes("flex:") ||
|
|
237
|
+
inlineStyle.includes("flex: 1");
|
|
238
|
+
// Also detect if class has flex: 1 (we can't directly read this, but
|
|
239
|
+
// children in a flex container with no explicit width typically share space)
|
|
240
|
+
// For now, assume if parent is flex and has 2+ children, they share space
|
|
241
|
+
// If any child has explicit width that's not equal, skip
|
|
242
|
+
// (We're being permissive here - assuming equal columns if parent is flex)
|
|
243
|
+
}
|
|
244
|
+
// Return children as columns if this looks like an equal-column flex layout
|
|
245
|
+
return children;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Detect if an element uses CSS Grid with equal-width columns.
|
|
249
|
+
* Patterns:
|
|
250
|
+
* display: grid; grid-template-columns: 1fr 1fr
|
|
251
|
+
* display: grid; grid-template-columns: repeat(2, 1fr)
|
|
252
|
+
* display: grid; grid-template-columns: repeat(3, 1fr)
|
|
253
|
+
*
|
|
254
|
+
* Returns the column children if detected, undefined otherwise.
|
|
255
|
+
* Only matches equal-width patterns (all 1fr), not sidebar patterns (280px 1fr).
|
|
256
|
+
*/
|
|
257
|
+
export function detectGridEqualColumns(element, cssContext) {
|
|
258
|
+
const styles = getElementStyles(element, cssContext);
|
|
259
|
+
// Must be a grid container
|
|
260
|
+
if (styles.display !== "grid") {
|
|
261
|
+
// Also check inline styles for grid
|
|
262
|
+
const inlineStyle = element.getAttribute("style") || "";
|
|
263
|
+
if (!inlineStyle.includes("display") || !inlineStyle.includes("grid")) {
|
|
264
|
+
return undefined;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
// Check grid-template-columns
|
|
268
|
+
const gridCols = styles.gridTemplateColumns || "";
|
|
269
|
+
const inlineStyle = element.getAttribute("style") || "";
|
|
270
|
+
// Extract grid-template-columns from inline style if not in CSS context
|
|
271
|
+
let colValue = gridCols;
|
|
272
|
+
if (!colValue) {
|
|
273
|
+
const colMatch = inlineStyle.match(/grid-template-columns:\s*([^;]+)/);
|
|
274
|
+
if (colMatch) {
|
|
275
|
+
colValue = colMatch[1].trim();
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
if (!colValue)
|
|
279
|
+
return undefined;
|
|
280
|
+
// Check if it's an equal-width pattern
|
|
281
|
+
// "1fr 1fr", "1fr 1fr 1fr", "repeat(2, 1fr)", "repeat(3, 1fr)"
|
|
282
|
+
const repeatMatch = colValue.match(/repeat\(\s*(\d+)\s*,\s*1fr\s*\)/);
|
|
283
|
+
const frOnlyMatch = colValue.match(/^(\s*1fr\s*)+$/);
|
|
284
|
+
if (!repeatMatch && !frOnlyMatch) {
|
|
285
|
+
return undefined;
|
|
286
|
+
}
|
|
287
|
+
// Get direct children
|
|
288
|
+
const children = Array.from(element.children).filter((child) => child.nodeType === Node.ELEMENT_NODE);
|
|
289
|
+
// Need at least 2 children for multi-column layout
|
|
290
|
+
if (children.length < 2 || children.length > 12) {
|
|
291
|
+
return undefined;
|
|
292
|
+
}
|
|
293
|
+
return children;
|
|
294
|
+
}
|
|
295
|
+
//# sourceMappingURL=parse-layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-layout.js","sourceRoot":"","sources":["../../../packages/docs/parse-layout.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { CssContext } from "./parse-css";
|
|
2
|
+
export interface TimelineItem {
|
|
3
|
+
date: string;
|
|
4
|
+
title?: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
isCurrent: boolean;
|
|
7
|
+
accentColor?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Detect if an element is a "skill item" by its structure.
|
|
11
|
+
* Pattern: The element has a direct child that contains exactly 2 text elements (name + percentage).
|
|
12
|
+
* The element should have exactly 1-2 direct children (header + optional progress bar).
|
|
13
|
+
*
|
|
14
|
+
* Returns { name, percentage } if detected, undefined otherwise.
|
|
15
|
+
*/
|
|
16
|
+
export declare function detectSkillItem(element: Element): {
|
|
17
|
+
name: string;
|
|
18
|
+
percentage: string;
|
|
19
|
+
} | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* Detect if an element is a "language item" with proficiency dots/indicators.
|
|
22
|
+
* Pattern: container with text (language name) and a child with multiple small indicators.
|
|
23
|
+
*
|
|
24
|
+
* Returns { name, filledCount, totalCount } if detected, undefined otherwise.
|
|
25
|
+
*/
|
|
26
|
+
export declare function detectLanguageItem(element: Element, cssContext: CssContext): {
|
|
27
|
+
name: string;
|
|
28
|
+
filledCount: number;
|
|
29
|
+
totalCount: number;
|
|
30
|
+
} | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Detect if an element is a progress bar container.
|
|
33
|
+
* Patterns:
|
|
34
|
+
* 1. Div containing a child with a width percentage in inline style (progress-bar fill)
|
|
35
|
+
* 2. Div with .progress, .progress-bar, .goal-progress class
|
|
36
|
+
*
|
|
37
|
+
* Returns { percentage, label? } if detected, undefined otherwise.
|
|
38
|
+
*/
|
|
39
|
+
export declare function detectProgressBar(element: Element, cssContext: CssContext): {
|
|
40
|
+
percentage: number;
|
|
41
|
+
label?: string;
|
|
42
|
+
} | undefined;
|
|
43
|
+
/**
|
|
44
|
+
* Detect if an element is a timeline container.
|
|
45
|
+
* Pattern: div with class "timeline" or containing children with class "timeline-item".
|
|
46
|
+
* Also detects horizontal timelines and milestone lists.
|
|
47
|
+
*
|
|
48
|
+
* Returns array of TimelineItem if detected, undefined otherwise.
|
|
49
|
+
*/
|
|
50
|
+
export declare function detectTimeline(element: Element, cssContext: CssContext): TimelineItem[] | undefined;
|
|
51
|
+
//# sourceMappingURL=parse-special.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-special.d.ts","sourceRoot":"","sources":["../../../packages/docs/parse-special.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAK9C,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAiClG;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAoElJ;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAqD9H;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,GAAG,YAAY,EAAE,GAAG,SAAS,CAwFnG"}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import { getElementStyles } from "./parse-css";
|
|
2
|
+
import { extractHexColor } from "./parse-colors";
|
|
3
|
+
import { getTextContent } from "./parse-helpers";
|
|
4
|
+
/**
|
|
5
|
+
* Detect if an element is a "skill item" by its structure.
|
|
6
|
+
* Pattern: The element has a direct child that contains exactly 2 text elements (name + percentage).
|
|
7
|
+
* The element should have exactly 1-2 direct children (header + optional progress bar).
|
|
8
|
+
*
|
|
9
|
+
* Returns { name, percentage } if detected, undefined otherwise.
|
|
10
|
+
*/
|
|
11
|
+
export function detectSkillItem(element) {
|
|
12
|
+
const children = Array.from(element.children);
|
|
13
|
+
// Skill items typically have 1-2 direct children:
|
|
14
|
+
// - A header div with name + percentage
|
|
15
|
+
// - Optionally a progress bar container
|
|
16
|
+
if (children.length === 0 || children.length > 3)
|
|
17
|
+
return undefined;
|
|
18
|
+
// Look for the header child that contains name + percentage
|
|
19
|
+
for (const child of children) {
|
|
20
|
+
// Skip if this child has too many children (not a header)
|
|
21
|
+
if (child.children.length !== 2)
|
|
22
|
+
continue;
|
|
23
|
+
const directChildren = Array.from(child.children).filter((c) => c.children.length === 0 && c.textContent?.trim());
|
|
24
|
+
// Must have exactly 2 leaf text elements
|
|
25
|
+
if (directChildren.length !== 2)
|
|
26
|
+
continue;
|
|
27
|
+
const text1 = directChildren[0].textContent?.trim() || "";
|
|
28
|
+
const text2 = directChildren[1].textContent?.trim() || "";
|
|
29
|
+
// Check if one is a percentage (number followed by %)
|
|
30
|
+
if (text2.match(/^\d+%$/)) {
|
|
31
|
+
return { name: text1, percentage: text2 };
|
|
32
|
+
}
|
|
33
|
+
if (text1.match(/^\d+%$/)) {
|
|
34
|
+
return { name: text2, percentage: text1 };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Detect if an element is a "language item" with proficiency dots/indicators.
|
|
41
|
+
* Pattern: container with text (language name) and a child with multiple small indicators.
|
|
42
|
+
*
|
|
43
|
+
* Returns { name, filledCount, totalCount } if detected, undefined otherwise.
|
|
44
|
+
*/
|
|
45
|
+
export function detectLanguageItem(element, cssContext) {
|
|
46
|
+
const children = Array.from(element.children);
|
|
47
|
+
if (children.length < 2)
|
|
48
|
+
return undefined;
|
|
49
|
+
let languageName = "";
|
|
50
|
+
let filledCount = 0;
|
|
51
|
+
let totalCount = 0;
|
|
52
|
+
for (const child of children) {
|
|
53
|
+
const childTagName = child.tagName.toLowerCase();
|
|
54
|
+
// GENERALIZED: Skip headings - they're not language names
|
|
55
|
+
// This prevents title-block patterns (h1 + metadata div) from being detected
|
|
56
|
+
if (childTagName.match(/^h[1-6]$/)) {
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
// Check if this is a text element (language name)
|
|
60
|
+
// Must be a simple span or similar inline element, not a complex structure
|
|
61
|
+
if (child.children.length === 0 && child.textContent?.trim()) {
|
|
62
|
+
const text = child.textContent.trim();
|
|
63
|
+
// GENERALIZED: Language names are typically short (1-3 words)
|
|
64
|
+
// Skip if the text is too long (like a title or paragraph)
|
|
65
|
+
if (text.length > 50 || text.split(/\s+/).length > 5) {
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
languageName = text;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
// Check if this is a container with multiple similar small children (dots/indicators)
|
|
72
|
+
const indicators = Array.from(child.children);
|
|
73
|
+
if (indicators.length >= 3 && indicators.length <= 10) {
|
|
74
|
+
// Check if they look like indicators (similar structure)
|
|
75
|
+
const allSpans = indicators.every((ind) => ind.tagName.toLowerCase() === "span");
|
|
76
|
+
if (allSpans) {
|
|
77
|
+
totalCount = indicators.length;
|
|
78
|
+
// Count "filled" indicators by checking for background color or specific styling
|
|
79
|
+
for (const indicator of indicators) {
|
|
80
|
+
const styles = getElementStyles(indicator, cssContext);
|
|
81
|
+
const bgColor = styles.backgroundColor;
|
|
82
|
+
// A "filled" indicator typically has a non-white/non-transparent background
|
|
83
|
+
// or has more than just border styling
|
|
84
|
+
if (bgColor && bgColor !== "transparent" && bgColor !== "inherit") {
|
|
85
|
+
const hexBg = extractHexColor(bgColor);
|
|
86
|
+
// Check if it's a "filled" color (not white/very light)
|
|
87
|
+
if (hexBg && hexBg !== "FFFFFF" && !hexBg.startsWith("FF")) {
|
|
88
|
+
filledCount++;
|
|
89
|
+
}
|
|
90
|
+
else if (hexBg) {
|
|
91
|
+
// Light color means filled if rgba has low opacity
|
|
92
|
+
// For now, count any background as potentially filled
|
|
93
|
+
// We'll need to be smarter about this
|
|
94
|
+
const alpha = bgColor.match(/rgba.*,\s*([0-9.]+)\s*\)/)?.[1];
|
|
95
|
+
if (!alpha || parseFloat(alpha) > 0.15) {
|
|
96
|
+
filledCount++;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (languageName && totalCount > 0) {
|
|
105
|
+
return { name: languageName, filledCount, totalCount };
|
|
106
|
+
}
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Detect if an element is a progress bar container.
|
|
111
|
+
* Patterns:
|
|
112
|
+
* 1. Div containing a child with a width percentage in inline style (progress-bar fill)
|
|
113
|
+
* 2. Div with .progress, .progress-bar, .goal-progress class
|
|
114
|
+
*
|
|
115
|
+
* Returns { percentage, label? } if detected, undefined otherwise.
|
|
116
|
+
*/
|
|
117
|
+
export function detectProgressBar(element, cssContext) {
|
|
118
|
+
const children = Array.from(element.children);
|
|
119
|
+
if (children.length === 0 || children.length > 4)
|
|
120
|
+
return undefined;
|
|
121
|
+
// Check if this is a progress bar wrapper (has a child with width% inline style)
|
|
122
|
+
for (const child of children) {
|
|
123
|
+
const childEl = child;
|
|
124
|
+
const inlineStyle = childEl.getAttribute("style") || "";
|
|
125
|
+
const className = childEl.getAttribute("class") || "";
|
|
126
|
+
// Pattern 1: Child with width percentage in inline style and background color
|
|
127
|
+
// e.g., <div class="progress-bar" style="width: 65%; background-color: ...">
|
|
128
|
+
const widthMatch = inlineStyle.match(/width:\s*(\d+(?:\.\d+)?)%/);
|
|
129
|
+
if (widthMatch) {
|
|
130
|
+
const childStyles = getElementStyles(childEl, cssContext);
|
|
131
|
+
const hasBgColor = childStyles.backgroundColor &&
|
|
132
|
+
childStyles.backgroundColor !== "transparent" &&
|
|
133
|
+
childStyles.backgroundColor !== "inherit";
|
|
134
|
+
const hasProgressClass = className.match(/progress|bar|fill|gauge/i);
|
|
135
|
+
if (hasBgColor || hasProgressClass) {
|
|
136
|
+
const percentage = Math.round(parseFloat(widthMatch[1]));
|
|
137
|
+
// Look for a label in sibling elements or parent's siblings
|
|
138
|
+
let label;
|
|
139
|
+
const parentEl = element.parentElement;
|
|
140
|
+
if (parentEl) {
|
|
141
|
+
for (const sibling of parentEl.children) {
|
|
142
|
+
if (sibling !== element) {
|
|
143
|
+
const text = getTextContent(sibling).trim();
|
|
144
|
+
if (text && text.length < 100) {
|
|
145
|
+
label = text;
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return { percentage, label };
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// Pattern 2: Child has a progress-related class but no width — check its children
|
|
155
|
+
if (className.match(/progress/i) && childEl.children.length > 0) {
|
|
156
|
+
for (const grandchild of childEl.children) {
|
|
157
|
+
const gcStyle = grandchild.getAttribute("style") || "";
|
|
158
|
+
const gcWidthMatch = gcStyle.match(/width:\s*(\d+(?:\.\d+)?)%/);
|
|
159
|
+
if (gcWidthMatch) {
|
|
160
|
+
return { percentage: Math.round(parseFloat(gcWidthMatch[1])) };
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return undefined;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Detect if an element is a timeline container.
|
|
169
|
+
* Pattern: div with class "timeline" or containing children with class "timeline-item".
|
|
170
|
+
* Also detects horizontal timelines and milestone lists.
|
|
171
|
+
*
|
|
172
|
+
* Returns array of TimelineItem if detected, undefined otherwise.
|
|
173
|
+
*/
|
|
174
|
+
export function detectTimeline(element, cssContext) {
|
|
175
|
+
const className = element.getAttribute("class") || "";
|
|
176
|
+
const children = Array.from(element.children);
|
|
177
|
+
// Direct timeline container
|
|
178
|
+
const isTimeline = className.match(/\btimeline\b/i);
|
|
179
|
+
// Or a wrapper that contains a timeline child
|
|
180
|
+
let timelineEl = null;
|
|
181
|
+
if (isTimeline) {
|
|
182
|
+
timelineEl = element;
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
// Check direct children for a timeline element
|
|
186
|
+
for (const child of children) {
|
|
187
|
+
const childClass = child.getAttribute("class") || "";
|
|
188
|
+
if (childClass.match(/\btimeline\b/i)) {
|
|
189
|
+
timelineEl = child;
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
if (!timelineEl)
|
|
195
|
+
return undefined;
|
|
196
|
+
// Extract accent color from CSS context (timeline-date color)
|
|
197
|
+
let accentColor;
|
|
198
|
+
const dateEl = timelineEl.querySelector(".timeline-date, .timeline-h-date");
|
|
199
|
+
if (dateEl) {
|
|
200
|
+
const dateStyles = getElementStyles(dateEl, cssContext);
|
|
201
|
+
if (dateStyles.color) {
|
|
202
|
+
accentColor = extractHexColor(dateStyles.color);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
const items = [];
|
|
206
|
+
// Pattern 1: Vertical timeline with .timeline-item children
|
|
207
|
+
const timelineItems = timelineEl.querySelectorAll(".timeline-item");
|
|
208
|
+
if (timelineItems.length > 0) {
|
|
209
|
+
for (const item of timelineItems) {
|
|
210
|
+
const itemEl = item;
|
|
211
|
+
const itemClass = itemEl.getAttribute("class") || "";
|
|
212
|
+
const isCurrent = itemClass.includes("current");
|
|
213
|
+
const dateEl = itemEl.querySelector(".timeline-date");
|
|
214
|
+
const date = dateEl ? getTextContent(dateEl).trim() : "";
|
|
215
|
+
const contentEl = itemEl.querySelector(".timeline-content");
|
|
216
|
+
let title;
|
|
217
|
+
let description;
|
|
218
|
+
if (contentEl) {
|
|
219
|
+
const h5 = contentEl.querySelector("h5, h4, h3, strong");
|
|
220
|
+
if (h5)
|
|
221
|
+
title = getTextContent(h5).trim();
|
|
222
|
+
const p = contentEl.querySelector("p");
|
|
223
|
+
if (p)
|
|
224
|
+
description = getTextContent(p).trim();
|
|
225
|
+
}
|
|
226
|
+
if (date || title) {
|
|
227
|
+
items.push({ date: date || "", title, description, isCurrent, accentColor });
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return items.length > 0 ? items : undefined;
|
|
231
|
+
}
|
|
232
|
+
// Pattern 2: Horizontal timeline with .timeline-h-item children
|
|
233
|
+
const hItems = timelineEl.querySelectorAll(".timeline-h-item");
|
|
234
|
+
if (hItems.length > 0) {
|
|
235
|
+
for (const item of hItems) {
|
|
236
|
+
const itemEl = item;
|
|
237
|
+
const itemClass = itemEl.getAttribute("class") || "";
|
|
238
|
+
const isCurrent = itemClass.includes("current");
|
|
239
|
+
const dateEl = itemEl.querySelector(".timeline-h-date");
|
|
240
|
+
const labelEl = itemEl.querySelector(".timeline-h-label");
|
|
241
|
+
const date = dateEl ? getTextContent(dateEl).trim() : "";
|
|
242
|
+
const title = labelEl ? getTextContent(labelEl).trim() : undefined;
|
|
243
|
+
if (date || title) {
|
|
244
|
+
items.push({ date: date || "", title, isCurrent, accentColor });
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return items.length > 0 ? items : undefined;
|
|
248
|
+
}
|
|
249
|
+
return undefined;
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=parse-special.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-special.js","sourceRoot":"","sources":["../../../packages/docs/parse-special.ts"],"names":[],"mappings":"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"}
|