@udx/md2html 1.3.1 → 1.4.0
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/package.json +1 -1
- package/static/chapter-navigation.css +40 -15
- package/static/scripts.js +52 -95
- package/static/styles.css +47 -56
package/package.json
CHANGED
|
@@ -16,16 +16,16 @@
|
|
|
16
16
|
/* Floating navigation styles - clean and minimal */
|
|
17
17
|
.chapter-navigation {
|
|
18
18
|
position: fixed;
|
|
19
|
-
top:
|
|
20
|
-
|
|
21
|
-
left: 20px;
|
|
19
|
+
top: 0;
|
|
20
|
+
left: 0;
|
|
22
21
|
width: var(--chapter-nav-width);
|
|
23
|
-
|
|
22
|
+
height: 100vh;
|
|
24
23
|
overflow-y: auto;
|
|
25
|
-
background-color:
|
|
26
|
-
padding:
|
|
24
|
+
background-color: #fff;
|
|
25
|
+
padding: 40px 20px 60px 20px;
|
|
27
26
|
z-index: 100;
|
|
28
|
-
scrollbar-width:
|
|
27
|
+
scrollbar-width: thin; /* Show thin scrollbar for Firefox */
|
|
28
|
+
scrollbar-color: rgba(0, 0, 0, 0.2) transparent;
|
|
29
29
|
transition: transform 0.3s ease;
|
|
30
30
|
border: 0 none transparent !important;
|
|
31
31
|
box-shadow: none !important;
|
|
@@ -34,9 +34,18 @@
|
|
|
34
34
|
-moz-box-shadow: none !important;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
/*
|
|
37
|
+
/* Show thin scrollbar for Chrome, Safari and Opera */
|
|
38
38
|
.chapter-navigation::-webkit-scrollbar {
|
|
39
|
-
|
|
39
|
+
width: 4px;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.chapter-navigation::-webkit-scrollbar-track {
|
|
43
|
+
background: transparent;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.chapter-navigation::-webkit-scrollbar-thumb {
|
|
47
|
+
background-color: rgba(0, 0, 0, 0.2);
|
|
48
|
+
border-radius: 2px;
|
|
40
49
|
}
|
|
41
50
|
|
|
42
51
|
.chapter-nav-list {
|
|
@@ -181,14 +190,22 @@
|
|
|
181
190
|
}
|
|
182
191
|
|
|
183
192
|
/* Add padding to the content to prevent floating nav from overlapping */
|
|
193
|
+
/* Content is centered in the remaining space to the right of the sidebar */
|
|
184
194
|
.chapter-content {
|
|
185
|
-
|
|
195
|
+
/* Leave space for sidebar on the left - push content further right */
|
|
196
|
+
margin-left: calc(var(--chapter-nav-width) + 120px);
|
|
197
|
+
/* Add margin on the right for balance */
|
|
198
|
+
margin-right: 80px;
|
|
199
|
+
/* Remove padding-left since we're using margin */
|
|
200
|
+
padding-left: 0;
|
|
201
|
+
padding-right: 0;
|
|
186
202
|
}
|
|
187
203
|
|
|
188
204
|
/* Responsive adjustments */
|
|
189
205
|
@media (max-width: 1024px) {
|
|
190
206
|
.chapter-content {
|
|
191
|
-
|
|
207
|
+
margin-left: calc(var(--chapter-nav-width) + 60px);
|
|
208
|
+
margin-right: 40px;
|
|
192
209
|
}
|
|
193
210
|
}
|
|
194
211
|
|
|
@@ -202,12 +219,14 @@
|
|
|
202
219
|
}
|
|
203
220
|
|
|
204
221
|
.chapter-content {
|
|
205
|
-
|
|
206
|
-
|
|
222
|
+
margin-left: 20px;
|
|
223
|
+
margin-right: 20px;
|
|
224
|
+
padding-left: 0;
|
|
225
|
+
padding-right: 0;
|
|
207
226
|
}
|
|
208
227
|
}
|
|
209
228
|
|
|
210
|
-
/* Hide nav when printing */
|
|
229
|
+
/* Hide nav when printing - let browser print dialog control all margins */
|
|
211
230
|
@media print {
|
|
212
231
|
.chapter-navigation,
|
|
213
232
|
.mobile-chapter-nav {
|
|
@@ -215,6 +234,12 @@
|
|
|
215
234
|
}
|
|
216
235
|
|
|
217
236
|
.chapter-content {
|
|
218
|
-
padding
|
|
237
|
+
/* Remove all margins and padding so browser print dialog controls page margins */
|
|
238
|
+
margin-left: 0 !important;
|
|
239
|
+
margin-right: 0 !important;
|
|
240
|
+
padding-left: 0 !important;
|
|
241
|
+
padding-right: 0 !important;
|
|
242
|
+
max-width: 100% !important;
|
|
243
|
+
width: 100% !important;
|
|
219
244
|
}
|
|
220
245
|
}
|
package/static/scripts.js
CHANGED
|
@@ -44,90 +44,16 @@ document.addEventListener('DOMContentLoaded', (event) => {
|
|
|
44
44
|
}
|
|
45
45
|
});
|
|
46
46
|
|
|
47
|
-
//
|
|
47
|
+
// Table enhancement - add responsive wrapper and basic styling
|
|
48
|
+
// Note: We do NOT set inline styles for table-layout or width to avoid conflicts with CSS
|
|
48
49
|
document.querySelectorAll('table').forEach(table => {
|
|
49
|
-
// Use auto layout for smart column sizing
|
|
50
|
-
table.style.tableLayout = 'auto';
|
|
51
|
-
table.style.width = 'auto';
|
|
52
|
-
table.style.maxWidth = '100%';
|
|
53
|
-
table.classList.add('auto-size');
|
|
54
|
-
|
|
55
50
|
// Add responsive wrapper if not already wrapped
|
|
56
51
|
if (table.parentElement.tagName !== 'DIV' || !table.parentElement.classList.contains('table-responsive')) {
|
|
57
52
|
const wrapper = document.createElement('div');
|
|
58
|
-
wrapper.className = 'table-responsive
|
|
59
|
-
wrapper.style.maxWidth = '100%';
|
|
53
|
+
wrapper.className = 'table-responsive';
|
|
60
54
|
table.parentNode.insertBefore(wrapper, table);
|
|
61
55
|
wrapper.appendChild(table);
|
|
62
56
|
}
|
|
63
|
-
|
|
64
|
-
// Analyze columns and apply smart sizing
|
|
65
|
-
const rows = table.querySelectorAll('tr');
|
|
66
|
-
if (rows.length > 0) {
|
|
67
|
-
const headerCells = table.querySelectorAll('th');
|
|
68
|
-
const numCols = headerCells.length || (rows[0] ? rows[0].querySelectorAll('td').length : 0);
|
|
69
|
-
|
|
70
|
-
// Analyze each column's content
|
|
71
|
-
for (let colIdx = 0; colIdx < numCols; colIdx++) {
|
|
72
|
-
let isNumeric = true;
|
|
73
|
-
let isCurrency = true;
|
|
74
|
-
let isCompact = true;
|
|
75
|
-
let maxLength = 0;
|
|
76
|
-
|
|
77
|
-
rows.forEach(row => {
|
|
78
|
-
const cells = row.querySelectorAll('th, td');
|
|
79
|
-
if (cells[colIdx]) {
|
|
80
|
-
const text = cells[colIdx].textContent.trim();
|
|
81
|
-
maxLength = Math.max(maxLength, text.length);
|
|
82
|
-
|
|
83
|
-
// Check if numeric (including decimals and commas)
|
|
84
|
-
if (!/^[\d,.\-\s]+$/.test(text) && text !== '') {
|
|
85
|
-
isNumeric = false;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// Check if currency (starts with $ or ends with .00)
|
|
89
|
-
if (!/^\$?[\d,]+\.?\d*$/.test(text) && text !== '') {
|
|
90
|
-
isCurrency = false;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// Compact if short content (less than 15 chars)
|
|
94
|
-
if (text.length > 15) {
|
|
95
|
-
isCompact = false;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
// Apply column classes based on analysis
|
|
101
|
-
rows.forEach(row => {
|
|
102
|
-
const cells = row.querySelectorAll('th, td');
|
|
103
|
-
if (cells[colIdx]) {
|
|
104
|
-
if (isCurrency && maxLength <= 15) {
|
|
105
|
-
cells[colIdx].classList.add('col-currency');
|
|
106
|
-
} else if (isNumeric && maxLength <= 10) {
|
|
107
|
-
cells[colIdx].classList.add('col-numeric');
|
|
108
|
-
} else if (isCompact && maxLength <= 10) {
|
|
109
|
-
cells[colIdx].classList.add('col-compact');
|
|
110
|
-
} else {
|
|
111
|
-
cells[colIdx].classList.add('col-text');
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// Add proper classes and styles to table headers
|
|
119
|
-
table.querySelectorAll('th').forEach(th => {
|
|
120
|
-
th.classList.add('bg-gray-50');
|
|
121
|
-
th.classList.add('font-semibold');
|
|
122
|
-
th.style.padding = '0.5rem 0.75rem';
|
|
123
|
-
th.style.borderBottom = '2px solid #e5e7eb';
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
// Add proper classes and styles to table cells
|
|
127
|
-
table.querySelectorAll('td').forEach(td => {
|
|
128
|
-
td.style.padding = '0.5rem 0.75rem';
|
|
129
|
-
td.style.borderBottom = '1px solid #e5e7eb';
|
|
130
|
-
});
|
|
131
57
|
});
|
|
132
58
|
|
|
133
59
|
// Remove any blue highlights
|
|
@@ -227,10 +153,11 @@ document.addEventListener('DOMContentLoaded', (event) => {
|
|
|
227
153
|
|
|
228
154
|
window.updateActiveChapter = () => {
|
|
229
155
|
try {
|
|
230
|
-
//
|
|
231
|
-
const
|
|
156
|
+
// Target H2 and H3 headings for navigation
|
|
157
|
+
const allHeadings = Array.from(document.querySelectorAll('h2, h3'));
|
|
158
|
+
const h2Headings = Array.from(document.querySelectorAll('h2'));
|
|
232
159
|
|
|
233
|
-
if (!
|
|
160
|
+
if (!allHeadings.length || !chapterNavItems.length) return;
|
|
234
161
|
|
|
235
162
|
// Calculate which heading is most visible in the viewport
|
|
236
163
|
const viewportHeight = window.innerHeight;
|
|
@@ -239,7 +166,7 @@ document.addEventListener('DOMContentLoaded', (event) => {
|
|
|
239
166
|
let bestVisibleHeading = null;
|
|
240
167
|
let bestVisibleScore = -1;
|
|
241
168
|
|
|
242
|
-
|
|
169
|
+
allHeadings.forEach(heading => {
|
|
243
170
|
if (!heading) return;
|
|
244
171
|
|
|
245
172
|
const rect = heading.getBoundingClientRect();
|
|
@@ -261,10 +188,29 @@ document.addEventListener('DOMContentLoaded', (event) => {
|
|
|
261
188
|
}
|
|
262
189
|
});
|
|
263
190
|
|
|
191
|
+
// Find the parent H2 for the current heading (if it's an H3)
|
|
192
|
+
const findParentH2 = (heading) => {
|
|
193
|
+
if (!heading || heading.tagName === 'H2') return heading;
|
|
194
|
+
|
|
195
|
+
// Walk backwards through all headings to find the parent H2
|
|
196
|
+
const headingIndex = allHeadings.indexOf(heading);
|
|
197
|
+
for (let i = headingIndex - 1; i >= 0; i--) {
|
|
198
|
+
if (allHeadings[i].tagName === 'H2') {
|
|
199
|
+
return allHeadings[i];
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return null;
|
|
203
|
+
};
|
|
204
|
+
|
|
264
205
|
if (bestVisibleHeading) {
|
|
265
206
|
const headingId = bestVisibleHeading.getAttribute('id');
|
|
266
207
|
const headingText = bestVisibleHeading.textContent.trim();
|
|
267
208
|
|
|
209
|
+
// Get parent H2 if current heading is H3
|
|
210
|
+
const parentH2 = findParentH2(bestVisibleHeading);
|
|
211
|
+
const parentH2Text = parentH2 ? parentH2.textContent.trim() : null;
|
|
212
|
+
const parentH2Id = parentH2 ? parentH2.getAttribute('id') : null;
|
|
213
|
+
|
|
268
214
|
chapterNavItems.forEach(item => {
|
|
269
215
|
if (!item) return;
|
|
270
216
|
|
|
@@ -272,22 +218,30 @@ document.addEventListener('DOMContentLoaded', (event) => {
|
|
|
272
218
|
if (!navLink) return;
|
|
273
219
|
|
|
274
220
|
const itemText = navLink.textContent.trim();
|
|
275
|
-
const
|
|
221
|
+
const itemId = item.getAttribute('data-chapter-id');
|
|
222
|
+
|
|
223
|
+
// Check if this nav item matches the current heading OR its parent H2
|
|
224
|
+
const isCurrentHeading = itemText === headingText || itemId === headingId;
|
|
225
|
+
const isParentSection = parentH2 && (itemText === parentH2Text || itemId === parentH2Id);
|
|
226
|
+
const isActive = isCurrentHeading || isParentSection;
|
|
276
227
|
|
|
277
228
|
if (isActive) {
|
|
278
229
|
item.classList.add('active');
|
|
279
230
|
|
|
280
|
-
|
|
281
|
-
if (
|
|
282
|
-
const
|
|
283
|
-
|
|
284
|
-
|
|
231
|
+
// Only scroll to and update text for the most specific (current) heading
|
|
232
|
+
if (isCurrentHeading) {
|
|
233
|
+
const navContainer = document.querySelector('.chapter-navigation');
|
|
234
|
+
if (navContainer) {
|
|
235
|
+
const itemOffset = item.offsetTop;
|
|
236
|
+
const navHeight = navContainer.offsetHeight;
|
|
237
|
+
const itemHeight = item.offsetHeight;
|
|
238
|
+
|
|
239
|
+
navContainer.scrollTop = itemOffset - (navHeight / 2) + (itemHeight / 2);
|
|
240
|
+
}
|
|
285
241
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
if (currentChapterText) {
|
|
290
|
-
currentChapterText.textContent = itemText;
|
|
242
|
+
if (currentChapterText) {
|
|
243
|
+
currentChapterText.textContent = itemText;
|
|
244
|
+
}
|
|
291
245
|
}
|
|
292
246
|
} else {
|
|
293
247
|
item.classList.remove('active');
|
|
@@ -302,7 +256,10 @@ document.addEventListener('DOMContentLoaded', (event) => {
|
|
|
302
256
|
if (!link) return;
|
|
303
257
|
|
|
304
258
|
const itemText = link.textContent.trim();
|
|
305
|
-
const
|
|
259
|
+
const itemId = item.getAttribute('data-chapter-id');
|
|
260
|
+
const isCurrentHeading = itemText === headingText || itemId === headingId;
|
|
261
|
+
const isParentSection = parentH2 && (itemText === parentH2Text || itemId === parentH2Id);
|
|
262
|
+
const isActive = isCurrentHeading || isParentSection;
|
|
306
263
|
|
|
307
264
|
if (isActive) {
|
|
308
265
|
item.classList.add('active');
|
|
@@ -310,8 +267,8 @@ document.addEventListener('DOMContentLoaded', (event) => {
|
|
|
310
267
|
item.classList.remove('active');
|
|
311
268
|
}
|
|
312
269
|
});
|
|
313
|
-
} else if (
|
|
314
|
-
const firstHeading =
|
|
270
|
+
} else if (h2Headings.length > 0) {
|
|
271
|
+
const firstHeading = h2Headings[0];
|
|
315
272
|
const firstHeadingText = firstHeading.textContent.trim();
|
|
316
273
|
|
|
317
274
|
chapterNavItems.forEach(item => {
|
package/static/styles.css
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
@media print {
|
|
2
|
+
/* Remove all margins so browser print dialog controls page margins */
|
|
3
|
+
html, body {
|
|
4
|
+
margin: 0 !important;
|
|
5
|
+
padding: 0 !important;
|
|
6
|
+
}
|
|
7
|
+
|
|
2
8
|
pre, pre code {
|
|
3
9
|
white-space: pre-wrap !important;
|
|
4
10
|
overflow-x: hidden !important;
|
|
@@ -27,11 +33,15 @@
|
|
|
27
33
|
.content-container {
|
|
28
34
|
max-width: 100% !important;
|
|
29
35
|
width: 100% !important;
|
|
36
|
+
margin: 0 !important;
|
|
37
|
+
padding: 0 !important;
|
|
30
38
|
}
|
|
31
39
|
|
|
32
|
-
article {
|
|
40
|
+
article, main, section {
|
|
33
41
|
width: 100% !important;
|
|
34
42
|
max-width: 100% !important;
|
|
43
|
+
margin: 0 !important;
|
|
44
|
+
padding: 0 !important;
|
|
35
45
|
}
|
|
36
46
|
}
|
|
37
47
|
|
|
@@ -182,42 +192,41 @@ blockquote + p {
|
|
|
182
192
|
margin-top: 2em;
|
|
183
193
|
}
|
|
184
194
|
|
|
185
|
-
/* Enhanced table styling
|
|
195
|
+
/* Enhanced table styling - use auto layout for natural column sizing */
|
|
186
196
|
.prose table,
|
|
187
197
|
table.w-full,
|
|
188
198
|
article table,
|
|
189
199
|
div table,
|
|
190
200
|
.table-responsive table {
|
|
191
|
-
width: 100
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
table-layout: fixed !important;
|
|
197
|
-
display: table !important;
|
|
201
|
+
width: 100%;
|
|
202
|
+
margin: 2em 0;
|
|
203
|
+
border-collapse: collapse;
|
|
204
|
+
table-layout: auto;
|
|
205
|
+
display: table;
|
|
198
206
|
}
|
|
199
207
|
|
|
200
208
|
/* Table wrapper to handle overflow properly */
|
|
201
209
|
.table-responsive,
|
|
202
210
|
div.overflow-x-auto {
|
|
203
|
-
width: 100
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
display: block !important;
|
|
211
|
+
width: 100%;
|
|
212
|
+
max-width: 100%;
|
|
213
|
+
overflow-x: auto;
|
|
214
|
+
margin: 2em 0;
|
|
215
|
+
display: block;
|
|
209
216
|
}
|
|
210
217
|
|
|
211
218
|
.prose table th, .prose table td {
|
|
212
|
-
padding: 0.75em 1em
|
|
213
|
-
border: 1px solid rgba(0, 0, 0, 0.1)
|
|
214
|
-
text-align: left
|
|
215
|
-
vertical-align: top
|
|
219
|
+
padding: 0.75em 1em;
|
|
220
|
+
border: 1px solid rgba(0, 0, 0, 0.1);
|
|
221
|
+
text-align: left;
|
|
222
|
+
vertical-align: top;
|
|
223
|
+
word-wrap: break-word;
|
|
224
|
+
overflow-wrap: break-word;
|
|
216
225
|
}
|
|
217
226
|
|
|
218
227
|
.prose table th {
|
|
219
|
-
font-weight: 600
|
|
220
|
-
background-color: rgba(0, 0, 0, 0.05)
|
|
228
|
+
font-weight: 600;
|
|
229
|
+
background-color: rgba(0, 0, 0, 0.05);
|
|
221
230
|
}
|
|
222
231
|
|
|
223
232
|
/* Grid-based tables for special formatting needs */
|
|
@@ -709,48 +718,30 @@ main > svg,
|
|
|
709
718
|
}
|
|
710
719
|
|
|
711
720
|
/* ============================================
|
|
712
|
-
|
|
721
|
+
TABLE STYLING
|
|
713
722
|
============================================ */
|
|
714
723
|
|
|
715
|
-
/*
|
|
716
|
-
table
|
|
724
|
+
/* Tables use auto layout to fit content naturally */
|
|
725
|
+
table {
|
|
717
726
|
table-layout: auto;
|
|
718
|
-
width:
|
|
719
|
-
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
/* Compact columns for short content (numbers, codes) */
|
|
723
|
-
table .col-compact {
|
|
724
|
-
width: 1%;
|
|
725
|
-
white-space: nowrap;
|
|
726
|
-
}
|
|
727
|
-
|
|
728
|
-
/* Numeric columns - right aligned, compact */
|
|
729
|
-
table .col-numeric {
|
|
730
|
-
width: 1%;
|
|
731
|
-
white-space: nowrap;
|
|
732
|
-
text-align: right;
|
|
733
|
-
font-variant-numeric: tabular-nums;
|
|
734
|
-
}
|
|
735
|
-
|
|
736
|
-
/* Currency columns */
|
|
737
|
-
table .col-currency {
|
|
738
|
-
width: 1%;
|
|
739
|
-
white-space: nowrap;
|
|
740
|
-
text-align: right;
|
|
741
|
-
font-variant-numeric: tabular-nums;
|
|
727
|
+
width: 100%;
|
|
728
|
+
border-collapse: collapse;
|
|
742
729
|
}
|
|
743
730
|
|
|
744
|
-
/*
|
|
745
|
-
table
|
|
746
|
-
|
|
731
|
+
/* Ensure table cells don't overlap */
|
|
732
|
+
table th,
|
|
733
|
+
table td {
|
|
734
|
+
padding: 0.75em 1em;
|
|
735
|
+
border: 1px solid rgba(0, 0, 0, 0.1);
|
|
736
|
+
text-align: left;
|
|
737
|
+
vertical-align: top;
|
|
738
|
+
word-wrap: break-word;
|
|
739
|
+
overflow-wrap: break-word;
|
|
747
740
|
}
|
|
748
741
|
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
max-width: 100%;
|
|
753
|
-
overflow-x: auto;
|
|
742
|
+
table th {
|
|
743
|
+
font-weight: 600;
|
|
744
|
+
background-color: rgba(0, 0, 0, 0.05);
|
|
754
745
|
}
|
|
755
746
|
|
|
756
747
|
/* Print table sizing */
|