fix-md-tables 1.1.1 → 1.1.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/README.md +3 -3
- package/lib/index.mjs +43 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@ Renders misaligned:
|
|
|
27
27
|
Add ideographic spaces (U+3000) to cells with fewer emoji. Ideographic spaces also display as 2 columns, compensating for the width difference:
|
|
28
28
|
|
|
29
29
|
```markdown
|
|
30
|
-
| Status | Description | Comments
|
|
30
|
+
| Status | Description | Comments |
|
|
31
31
|
| -------- | -------------- | ---------- |
|
|
32
32
|
| ✅ | ✅ Complete | ❌ |
|
|
33
33
|
| 🚧 | 🚧 In Progress | ⚠️ |
|
|
@@ -134,9 +134,9 @@ Main function to fix table alignment in markdown content.
|
|
|
134
134
|
|
|
135
135
|
Count emoji characters in a string.
|
|
136
136
|
|
|
137
|
-
### `
|
|
137
|
+
### `normalizeIdeographicSpaces(str: string): string`
|
|
138
138
|
|
|
139
|
-
|
|
139
|
+
Replace all ideographic spaces with 2 regular spaces (same visual width).
|
|
140
140
|
|
|
141
141
|
### `processTable(tableRows: string[]): string[]`
|
|
142
142
|
|
package/lib/index.mjs
CHANGED
|
@@ -28,9 +28,9 @@ export function countEmoji(str) {
|
|
|
28
28
|
return (str.match(EMOJI_REGEX) || []).length;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
/**
|
|
32
|
-
export function
|
|
33
|
-
return str.replaceAll("\u3000", "");
|
|
31
|
+
/** Replace all ideographic spaces with 2 regular spaces (same visual width) */
|
|
32
|
+
export function normalizeIdeographicSpaces(str) {
|
|
33
|
+
return str.replaceAll("\u3000", " ");
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
/** Check if a line is a markdown table separator */
|
|
@@ -78,8 +78,11 @@ export function compensateSeparatorCell(cell, compensation) {
|
|
|
78
78
|
// Remove 2 dashes per ideographic space (both are 2 cols visually)
|
|
79
79
|
const dashesToRemove = compensation * 2;
|
|
80
80
|
const newDashes = dashes.length > dashesToRemove ? dashes.slice(0, -dashesToRemove) : dashes;
|
|
81
|
+
// Also remove trailing spaces to maintain column width
|
|
82
|
+
const spacesToRemove = compensation * 2;
|
|
83
|
+
const newTrailingSpace = trailingSpace.length > spacesToRemove ? trailingSpace.slice(spacesToRemove) : "";
|
|
81
84
|
|
|
82
|
-
return leadingSpace + leftColon + newDashes + IDEOGRAPHIC_SPACE.repeat(compensation) + rightColon +
|
|
85
|
+
return leadingSpace + leftColon + newDashes + IDEOGRAPHIC_SPACE.repeat(compensation) + rightColon + newTrailingSpace;
|
|
83
86
|
}
|
|
84
87
|
|
|
85
88
|
/** Split cell into [leadingSpace, content, trailingSpace] without regex (ReDoS-safe) */
|
|
@@ -124,25 +127,53 @@ export function buildTableRow(cells) {
|
|
|
124
127
|
return "|" + cells.join("|") + "|";
|
|
125
128
|
}
|
|
126
129
|
|
|
130
|
+
/** Count ideographic spaces in a string */
|
|
131
|
+
export function countIdeographicSpaces(str) {
|
|
132
|
+
return (str.match(/\u3000/g) || []).length;
|
|
133
|
+
}
|
|
134
|
+
|
|
127
135
|
/** Process a complete table, applying emoji compensation to all rows */
|
|
128
136
|
export function processTable(tableRows) {
|
|
129
|
-
//
|
|
130
|
-
const
|
|
131
|
-
|
|
137
|
+
// Parse original rows to count existing ideographic spaces
|
|
138
|
+
const originalParsedRows = tableRows.map(parseTableRow);
|
|
139
|
+
|
|
140
|
+
// Normalize for emoji counting (but we'll use original cells when adequate)
|
|
141
|
+
const cleanedRows = tableRows.map(normalizeIdeographicSpaces);
|
|
142
|
+
const cleanedParsedRows = cleanedRows.map(parseTableRow);
|
|
132
143
|
|
|
133
144
|
// Check if table has any emoji
|
|
134
145
|
const hasEmoji = cleanedRows.some((row) => countEmoji(row) > 0);
|
|
135
|
-
if (!hasEmoji ||
|
|
146
|
+
if (!hasEmoji || cleanedParsedRows.length < 2) {
|
|
136
147
|
return cleanedRows;
|
|
137
148
|
}
|
|
138
149
|
|
|
139
|
-
const numCols = Math.max(...
|
|
140
|
-
const maxEmojiPerCol = calculateMaxEmojiPerColumn(
|
|
150
|
+
const numCols = Math.max(...cleanedParsedRows.map((r) => r.length));
|
|
151
|
+
const maxEmojiPerCol = calculateMaxEmojiPerColumn(cleanedParsedRows, numCols);
|
|
141
152
|
|
|
142
153
|
// Rebuild all rows with compensation
|
|
143
|
-
return
|
|
154
|
+
return originalParsedRows.map((originalRow, rowIdx) => {
|
|
155
|
+
const cleanedRow = cleanedParsedRows[rowIdx];
|
|
144
156
|
const isSeparatorRow = rowIdx === 1;
|
|
145
|
-
|
|
157
|
+
|
|
158
|
+
const processedCells = originalRow.map((originalCell, col) => {
|
|
159
|
+
const cleanedCell = cleanedRow[col];
|
|
160
|
+
const existingCompensation = countIdeographicSpaces(originalCell);
|
|
161
|
+
const maxEmoji = maxEmojiPerCol[col] || 0;
|
|
162
|
+
const cellEmoji = countEmoji(cleanedCell);
|
|
163
|
+
const neededCompensation = maxEmoji - cellEmoji;
|
|
164
|
+
|
|
165
|
+
// If existing compensation is adequate, keep original cell
|
|
166
|
+
if (existingCompensation >= neededCompensation) {
|
|
167
|
+
return originalCell;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Need more compensation - use normalized cell and add what's needed
|
|
171
|
+
const additionalCompensation = neededCompensation - existingCompensation;
|
|
172
|
+
return isSeparatorRow
|
|
173
|
+
? compensateSeparatorCell(cleanedCell, additionalCompensation)
|
|
174
|
+
: compensateRegularCell(cleanedCell, additionalCompensation);
|
|
175
|
+
});
|
|
176
|
+
|
|
146
177
|
return buildTableRow(processedCells);
|
|
147
178
|
});
|
|
148
179
|
}
|