@mintlify/common 1.0.598 → 1.0.600

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.
@@ -1,6 +1,130 @@
1
1
  import { u } from 'unist-builder';
2
2
  import { visit } from 'unist-util-visit';
3
3
  import { createMdxJsxAttribute } from '../../lib/remark-utils.js';
4
+ const extractTextContent = (node) => {
5
+ let text = '';
6
+ for (const child of node.children) {
7
+ if (child.type === 'text') {
8
+ text += child.value;
9
+ }
10
+ else if (child.type === 'element') {
11
+ text += extractTextContent(child);
12
+ }
13
+ }
14
+ return text;
15
+ };
16
+ const PROCESS_NUMERIC_CELLS_THRESHOLD = 0.8;
17
+ const UNITS = '(GiB|MiB|KiB|TiB|PiB|EiB|ZiB|' + // Storage (binary prefixes - IEC)
18
+ 'GB|MB|KB|TB|PB|EB|ZB|' + // Storage (decimal prefixes)
19
+ 'ms|μs|µs|ns|s|m|h|min|' + // Time
20
+ 'km|cm|mm|' + // Distance
21
+ 'kg|g|mg|t|' + // Weight
22
+ 'Hz|kHz|MHz|GHz|THz|' + // Frequency
23
+ '%|' + // Percent
24
+ 'px|em|rem|pt|' + // CSS
25
+ '°C|°F|°K|K|' + // Temperature
26
+ 'Mbps|Gbps|kbps|' + // Network speed
27
+ 'W|kW|mW|MW|GW|' + // Power (Watts)
28
+ 'V|kV|mV|' + // Voltage
29
+ 'A|mA|kA|' + // Current (Ampere)
30
+ 'Wh|kWh|mWh|' + // Energy
31
+ 'Pa|kPa|MPa|bar|psi|atm|' + // Pressure
32
+ 'L|ml|m³|gal|' + // Volume
33
+ 'lm|cd|lx|nits|' + // Luminosity
34
+ 'dB|dBm|' + // Sound
35
+ 'rpm|' + // Rotation
36
+ 'bpm|' + // Heart rate
37
+ 'fps|' + // Frame rate
38
+ 'Bq|Gy|Sv|rad|' + // Radiation
39
+ 'mph|km\\/h|m\\/s|kt|' + // Speed
40
+ 'ft²|m²|ha|ac|' + // Area
41
+ 'mol\\/L|M|ppm|kg\\/m³|g\\/L|' + // Concentration and density
42
+ 'bit|byte|ch|MP|dpi|ppi|' + // Digital
43
+ 'oz|cup|cups|tbsp|tsp|' + // Cooking (includes plural)
44
+ 'AU|ly|pc|' + // Astronomical
45
+ 'mmHg|' + // Medical
46
+ 'mAh|' + // Battery
47
+ 'in|ft|yd' + // Imperial
48
+ ')';
49
+ const isNumberWithUnit = (text) => {
50
+ // support fractions (1/2), decimals (1.5), and ranges (5-10)
51
+ const numberWithUnit = `[+-]?\\d+[\\d\\s.,/]*\\s*${UNITS}`;
52
+ const pattern = new RegExp(`^${numberWithUnit}(-${numberWithUnit})?$`, 'i');
53
+ return pattern.test(text);
54
+ };
55
+ // "0xFF", "0x100", "0b1111", "0o777"
56
+ const isProgrammerNotation = (text) => {
57
+ // hexadecimal: 0x or 0X followed by hex digits
58
+ if (/^0x[0-9a-f]+$/i.test(text)) {
59
+ return true;
60
+ }
61
+ // binary: 0b or 0B followed by binary digits
62
+ if (/^0b[01]+$/i.test(text)) {
63
+ return true;
64
+ }
65
+ // octal: 0o or 0O followed by octal digits
66
+ if (/^0o[0-7]+$/i.test(text)) {
67
+ return true;
68
+ }
69
+ return false;
70
+ };
71
+ // "1.0.0", "v2.5.1", "v1", "2.0.0-beta", "3.0.0-rc1", "1.2.3-dev", "1.0.0-alpha"
72
+ const isVersionNumber = (text) => {
73
+ // starts with 'v' followed by numbers and dots: v1, v2.5, v10.5.2
74
+ if (/^v\d+(\.\d+)*(-[\w.]+)?$/i.test(text)) {
75
+ return true;
76
+ }
77
+ // version with dots and optional suffix: 1.0.0, 2.0.0-beta, 1.2.3-rc1
78
+ if (/^\d+\.\d+(\.\d+)?(-[\w.]+)?$/.test(text)) {
79
+ return true;
80
+ }
81
+ return false;
82
+ };
83
+ // "#FFFFFF", "#000", "rgb(255,0,0)", "hsl(0,100%,50%)", "cmyk(0,100,100,0)"
84
+ const isColorValue = (text) => {
85
+ // hex colors: #FFF, #FFFFFF, #FF0000
86
+ if (/^#[0-9a-f]{3,8}$/i.test(text)) {
87
+ return true;
88
+ }
89
+ // functional notation: rgb(), rgba(), hsl(), hsla(), cmyk()
90
+ if (/^(rgb|rgba|hsl|hsla|cmyk)\s*\([\d\s,.%]+\)$/i.test(text)) {
91
+ return true;
92
+ }
93
+ return false;
94
+ };
95
+ // "1st", "2nd", "3rd", "95th", "21st"
96
+ const isOrdinalNumber = (text) => {
97
+ return /^\d+(st|nd|rd|th)$/i.test(text);
98
+ };
99
+ const hasHighNumericRatio = (text) => {
100
+ var _a;
101
+ // only include: digits, spaces, basic punctuation, currency
102
+ // explicitly exclude: math symbols, Greek letters, super/subscripts (to avoid matching formulas)
103
+ const numericChars = ((_a = text.match(/[\d\s.,+\-/%$€£¥°:()]/gi)) === null || _a === void 0 ? void 0 : _a.length) || 0;
104
+ const ratio = numericChars / text.length;
105
+ return ratio >= PROCESS_NUMERIC_CELLS_THRESHOLD;
106
+ };
107
+ const isPrimarilyNumeric = (text) => {
108
+ const trimmed = text.trim();
109
+ if (trimmed.length === 0)
110
+ return false;
111
+ return (isNumberWithUnit(trimmed) ||
112
+ isProgrammerNotation(trimmed) ||
113
+ isOrdinalNumber(trimmed) ||
114
+ isVersionNumber(trimmed) ||
115
+ isColorValue(trimmed) ||
116
+ hasHighNumericRatio(trimmed));
117
+ };
118
+ const processTableCells = (node) => {
119
+ visit(node, 'element', (cellNode) => {
120
+ if (cellNode.tagName === 'td') {
121
+ const textContent = extractTextContent(cellNode);
122
+ if (isPrimarilyNumeric(textContent)) {
123
+ cellNode.properties['data-numeric'] = 'true';
124
+ }
125
+ }
126
+ });
127
+ };
4
128
  export const rehypeTable = () => {
5
129
  return (tree) => {
6
130
  visit(tree, 'element', (node, index, parent) => {
@@ -10,10 +134,18 @@ export const rehypeTable = () => {
10
134
  const attributeName = key === 'class' ? 'className' : key;
11
135
  return createMdxJsxAttribute(attributeName, attributeValue);
12
136
  });
137
+ // filter out whitespace-only text nodes to prevent hydration errors
138
+ const filteredChildren = node.children.filter((child) => {
139
+ if (child.type === 'text' && /^\s*$/.test(child.value)) {
140
+ return false;
141
+ }
142
+ return true;
143
+ });
144
+ processTableCells(node);
13
145
  const tableComponent = u('mdxJsxFlowElement', {
14
146
  name: 'Table',
15
147
  attributes,
16
- }, node.children);
148
+ }, filteredChildren);
17
149
  parent.children.splice(index, 1, tableComponent);
18
150
  }
19
151
  });