chalknotes 0.0.27 → 0.0.28
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/src/lib/getPostBySlug.js +83 -48
package/package.json
CHANGED
package/src/lib/getPostBySlug.js
CHANGED
@@ -53,36 +53,36 @@ const getPostBySlug = async (slug) => {
|
|
53
53
|
function processBlock(block) {
|
54
54
|
switch (block.type) {
|
55
55
|
case "paragraph":
|
56
|
-
return processRichText(block.paragraph.rich_text, "p", "mb-
|
56
|
+
return processRichText(block.paragraph.rich_text, "p", "mb-6 leading-relaxed text-gray-700");
|
57
57
|
|
58
58
|
case "heading_1":
|
59
|
-
return processRichText(block.heading_1.rich_text, "h1", "text-3xl font-bold mb-6");
|
59
|
+
return processRichText(block.heading_1.rich_text, "h1", "text-3xl font-bold mb-6 mt-8 text-gray-900 border-b border-gray-200 pb-2");
|
60
60
|
|
61
61
|
case "heading_2":
|
62
|
-
return processRichText(block.heading_2.rich_text, "h2", "text-2xl font-
|
62
|
+
return processRichText(block.heading_2.rich_text, "h2", "text-2xl font-semibold mb-4 mt-6 text-gray-900");
|
63
63
|
|
64
64
|
case "heading_3":
|
65
|
-
return processRichText(block.heading_3.rich_text, "h3", "text-xl font-
|
65
|
+
return processRichText(block.heading_3.rich_text, "h3", "text-xl font-medium mb-3 mt-5 text-gray-900");
|
66
66
|
|
67
67
|
case "bulleted_list_item":
|
68
|
-
return processRichText(block.bulleted_list_item.rich_text, "li", "mb-2");
|
68
|
+
return processRichText(block.bulleted_list_item.rich_text, "li", "mb-2 ml-4");
|
69
69
|
|
70
70
|
case "numbered_list_item":
|
71
|
-
return processRichText(block.numbered_list_item.rich_text, "li", "mb-2");
|
71
|
+
return processRichText(block.numbered_list_item.rich_text, "li", "mb-2 ml-4");
|
72
72
|
|
73
73
|
case "quote":
|
74
|
-
return processRichText(block.quote.rich_text, "blockquote", "border-l-4 border-
|
74
|
+
return processRichText(block.quote.rich_text, "blockquote", "border-l-4 border-blue-500 pl-6 italic text-gray-600 mb-6 bg-blue-50 py-4 rounded-r-lg");
|
75
75
|
|
76
76
|
case "code":
|
77
77
|
const codeContent = block.code.rich_text.map(text => text.plain_text).join("");
|
78
78
|
const language = block.code.language || 'text';
|
79
|
-
return `<pre class="bg-gray-100 p-4 rounded-lg overflow-x-auto mb-
|
79
|
+
return `<pre class="bg-gray-900 text-gray-100 p-4 rounded-lg overflow-x-auto mb-6 text-sm"><code class="language-${language}">${escapeHtml(codeContent)}</code></pre>`;
|
80
80
|
|
81
81
|
case "image":
|
82
82
|
return processImage(block.image);
|
83
83
|
|
84
84
|
case "divider":
|
85
|
-
return '<hr class="my-8 border-gray-
|
85
|
+
return '<hr class="my-8 border-gray-200" />';
|
86
86
|
|
87
87
|
case "callout":
|
88
88
|
return processCallout(block.callout);
|
@@ -91,18 +91,18 @@ function processBlock(block) {
|
|
91
91
|
return processToggle(block.toggle);
|
92
92
|
|
93
93
|
case "table_of_contents":
|
94
|
-
return '<div class="bg-blue-50 border border-blue-200 rounded-lg p-4 mb-
|
94
|
+
return '<div class="bg-blue-50 border border-blue-200 rounded-lg p-4 mb-6"><p class="text-blue-800 font-medium">📋 Table of Contents</p><p class="text-blue-600 text-sm">(Generated automatically)</p></div>';
|
95
95
|
|
96
96
|
case "bookmark":
|
97
97
|
return processBookmark(block.bookmark);
|
98
98
|
|
99
99
|
case "equation":
|
100
|
-
return `<div class="bg-gray-50 p-4 rounded-lg mb-
|
100
|
+
return `<div class="bg-gray-50 p-4 rounded-lg mb-6 text-center border border-gray-200"><p class="text-gray-600 mb-2">📐 Mathematical equation</p><p class="font-mono text-sm bg-white p-2 rounded border">${block.equation.expression}</p></div>`;
|
101
101
|
|
102
102
|
default:
|
103
103
|
// For unsupported blocks, try to extract plain text
|
104
104
|
if (block[block.type]?.rich_text) {
|
105
|
-
return processRichText(block[block.type].rich_text, "p", "mb-4 text-gray-500");
|
105
|
+
return processRichText(block[block.type].rich_text, "p", "mb-4 text-gray-500 italic");
|
106
106
|
}
|
107
107
|
return "";
|
108
108
|
}
|
@@ -118,23 +118,58 @@ function processImage(image) {
|
|
118
118
|
const caption = image.caption?.map(text => text.plain_text).join("") || "";
|
119
119
|
const altText = caption || "Image";
|
120
120
|
|
121
|
-
// Get image size
|
121
|
+
// Get image size from Notion properties
|
122
122
|
let sizeClass = "w-full"; // Default full width
|
123
|
-
let
|
123
|
+
let maxWidthClass = "max-w-full";
|
124
124
|
|
125
|
-
//
|
126
|
-
|
127
|
-
|
125
|
+
// Check if image has size information
|
126
|
+
if (image.width && image.height) {
|
127
|
+
// Calculate aspect ratio and apply appropriate sizing
|
128
|
+
const aspectRatio = image.width / image.height;
|
129
|
+
|
130
|
+
if (aspectRatio > 2) {
|
131
|
+
// Wide images
|
132
|
+
sizeClass = "w-full";
|
133
|
+
maxWidthClass = "max-w-4xl";
|
134
|
+
} else if (aspectRatio < 0.5) {
|
135
|
+
// Tall images
|
136
|
+
sizeClass = "w-full";
|
137
|
+
maxWidthClass = "max-w-2xl";
|
138
|
+
} else {
|
139
|
+
// Square-ish images
|
140
|
+
sizeClass = "w-full";
|
141
|
+
maxWidthClass = "max-w-3xl";
|
142
|
+
}
|
143
|
+
}
|
144
|
+
|
145
|
+
// Check for Notion's size property (if available)
|
146
|
+
if (image.size) {
|
147
|
+
switch (image.size) {
|
148
|
+
case 'small':
|
149
|
+
maxWidthClass = "max-w-md";
|
150
|
+
break;
|
151
|
+
case 'medium':
|
152
|
+
maxWidthClass = "max-w-2xl";
|
153
|
+
break;
|
154
|
+
case 'large':
|
155
|
+
maxWidthClass = "max-w-4xl";
|
156
|
+
break;
|
157
|
+
default:
|
158
|
+
maxWidthClass = "max-w-full";
|
159
|
+
}
|
160
|
+
}
|
161
|
+
|
162
|
+
const responsiveClasses = `${sizeClass} ${maxWidthClass} h-auto rounded-lg shadow-sm`;
|
128
163
|
|
129
164
|
return `
|
130
|
-
<figure class="my-
|
165
|
+
<figure class="my-6 text-center">
|
131
166
|
<img
|
132
167
|
src="${imageUrl}"
|
133
168
|
alt="${escapeHtml(altText)}"
|
134
|
-
class="${
|
169
|
+
class="${responsiveClasses}"
|
135
170
|
loading="lazy"
|
136
171
|
/>
|
137
|
-
${caption ? `<figcaption class="text-center text-gray-
|
172
|
+
${caption ? `<figcaption class="text-center text-gray-500 mt-3 text-sm italic">${escapeHtml(caption)}</figcaption>` : ''}
|
138
173
|
</figure>
|
139
174
|
`.trim();
|
140
175
|
}
|
@@ -162,35 +197,15 @@ function processCallout(callout) {
|
|
162
197
|
const colorClass = colorClasses[bgColor] || colorClasses.blue;
|
163
198
|
|
164
199
|
return `
|
165
|
-
<div class="${colorClass} border-l-4 p-4 my-
|
200
|
+
<div class="${colorClass} border-l-4 p-4 my-6 rounded-r-lg shadow-sm">
|
166
201
|
<div class="flex items-start">
|
167
|
-
<span class="mr-3 text-
|
168
|
-
<div class="flex-1">${content}</div>
|
202
|
+
<span class="mr-3 text-xl flex-shrink-0">${icon}</span>
|
203
|
+
<div class="flex-1 leading-relaxed">${content}</div>
|
169
204
|
</div>
|
170
205
|
</div>
|
171
206
|
`.trim();
|
172
207
|
}
|
173
208
|
|
174
|
-
/**
|
175
|
-
* Process toggle block
|
176
|
-
* @param {Object} toggle - Notion toggle block
|
177
|
-
* @returns {string} HTML string
|
178
|
-
*/
|
179
|
-
function processToggle(toggle) {
|
180
|
-
const content = processRichText(toggle.rich_text, "div", "");
|
181
|
-
return `
|
182
|
-
<details class="my-4">
|
183
|
-
<summary class="cursor-pointer font-medium text-gray-700 hover:text-gray-900">
|
184
|
-
${content}
|
185
|
-
</summary>
|
186
|
-
<div class="mt-2 pl-4 border-l-2 border-gray-200">
|
187
|
-
<!-- Toggle content would go here if Notion API provided it -->
|
188
|
-
<p class="text-gray-600 text-sm">Toggle content not available in current API</p>
|
189
|
-
</div>
|
190
|
-
</details>
|
191
|
-
`.trim();
|
192
|
-
}
|
193
|
-
|
194
209
|
/**
|
195
210
|
* Process bookmark block
|
196
211
|
* @param {Object} bookmark - Notion bookmark block
|
@@ -201,14 +216,14 @@ function processBookmark(bookmark) {
|
|
201
216
|
const title = bookmark.caption?.[0]?.plain_text || "Bookmark";
|
202
217
|
|
203
218
|
return `
|
204
|
-
<div class="my-
|
205
|
-
<a href="${url}" target="_blank" rel="noopener noreferrer" class="block border border-gray-200 rounded-lg p-4 hover:border-gray-300 transition-
|
219
|
+
<div class="my-6">
|
220
|
+
<a href="${url}" target="_blank" rel="noopener noreferrer" class="block border border-gray-200 rounded-lg p-4 hover:border-gray-300 hover:shadow-md transition-all duration-200">
|
206
221
|
<div class="flex items-center">
|
207
|
-
<div class="flex-1">
|
208
|
-
<p class="font-medium text-gray-900">${escapeHtml(title)}</p>
|
222
|
+
<div class="flex-1 min-w-0">
|
223
|
+
<p class="font-medium text-gray-900 truncate">${escapeHtml(title)}</p>
|
209
224
|
<p class="text-sm text-gray-500 truncate">${url}</p>
|
210
225
|
</div>
|
211
|
-
<svg class="w-5 h-5 text-gray-400 ml-
|
226
|
+
<svg class="w-5 h-5 text-gray-400 ml-3 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
212
227
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"></path>
|
213
228
|
</svg>
|
214
229
|
</div>
|
@@ -217,6 +232,26 @@ function processBookmark(bookmark) {
|
|
217
232
|
`.trim();
|
218
233
|
}
|
219
234
|
|
235
|
+
/**
|
236
|
+
* Process toggle block
|
237
|
+
* @param {Object} toggle - Notion toggle block
|
238
|
+
* @returns {string} HTML string
|
239
|
+
*/
|
240
|
+
function processToggle(toggle) {
|
241
|
+
const content = processRichText(toggle.rich_text, "div", "");
|
242
|
+
return `
|
243
|
+
<details class="my-4">
|
244
|
+
<summary class="cursor-pointer font-medium text-gray-700 hover:text-gray-900">
|
245
|
+
${content}
|
246
|
+
</summary>
|
247
|
+
<div class="mt-2 pl-4 border-l-2 border-gray-200">
|
248
|
+
<!-- Toggle content would go here if Notion API provided it -->
|
249
|
+
<p class="text-gray-600 text-sm">Toggle content not available in current API</p>
|
250
|
+
</div>
|
251
|
+
</details>
|
252
|
+
`.trim();
|
253
|
+
}
|
254
|
+
|
220
255
|
/**
|
221
256
|
* Process rich text and apply formatting
|
222
257
|
* @param {Array} richText - Array of rich text objects
|