chalknotes 0.0.27 → 0.0.29
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 +86 -54
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-7 text-gray-700 text-lg");
|
57
57
|
|
58
58
|
case "heading_1":
|
59
|
-
return processRichText(block.heading_1.rich_text, "h1", "text-
|
59
|
+
return processRichText(block.heading_1.rich_text, "h1", "text-4xl font-bold mb-8 mt-12 text-gray-900 border-b-2 border-gray-200 pb-4");
|
60
60
|
|
61
61
|
case "heading_2":
|
62
|
-
return processRichText(block.heading_2.rich_text, "h2", "text-
|
62
|
+
return processRichText(block.heading_2.rich_text, "h2", "text-3xl font-semibold mb-6 mt-10 text-gray-900");
|
63
63
|
|
64
64
|
case "heading_3":
|
65
|
-
return processRichText(block.heading_3.rich_text, "h3", "text-
|
65
|
+
return processRichText(block.heading_3.rich_text, "h3", "text-2xl font-medium mb-4 mt-8 text-gray-900");
|
66
66
|
|
67
67
|
case "bulleted_list_item":
|
68
|
-
return processRichText(block.bulleted_list_item.rich_text, "li", "mb-
|
68
|
+
return processRichText(block.bulleted_list_item.rich_text, "li", "mb-3 ml-6 leading-7 text-gray-700");
|
69
69
|
|
70
70
|
case "numbered_list_item":
|
71
|
-
return processRichText(block.numbered_list_item.rich_text, "li", "mb-
|
71
|
+
return processRichText(block.numbered_list_item.rich_text, "li", "mb-3 ml-6 leading-7 text-gray-700");
|
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-8 italic text-gray-600 mb-8 bg-blue-50 py-6 rounded-r-lg text-lg leading-7");
|
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-
|
79
|
+
return `<pre class="bg-gray-900 text-gray-100 p-6 rounded-lg overflow-x-auto mb-8 text-sm leading-6 shadow-lg"><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-
|
85
|
+
return '<hr class="my-12 border-gray-300" />';
|
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-
|
94
|
+
return '<div class="bg-blue-50 border border-blue-200 rounded-lg p-6 mb-8 shadow-sm"><p class="text-blue-800 font-medium text-lg">📋 Table of Contents</p><p class="text-blue-600 text-sm mt-1">(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-
|
100
|
+
return `<div class="bg-gray-50 p-6 rounded-lg mb-8 text-center border border-gray-200 shadow-sm"><p class="text-gray-600 mb-3 font-medium">📐 Mathematical equation</p><p class="font-mono text-sm bg-white p-4 rounded border shadow-sm">${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-
|
105
|
+
return processRichText(block[block.type].rich_text, "p", "mb-6 text-gray-500 italic text-lg");
|
106
106
|
}
|
107
107
|
return "";
|
108
108
|
}
|
@@ -118,23 +118,55 @@ function processImage(image) {
|
|
118
118
|
const caption = image.caption?.map(text => text.plain_text).join("") || "";
|
119
119
|
const altText = caption || "Image";
|
120
120
|
|
121
|
-
//
|
122
|
-
let
|
123
|
-
let alignmentClass = "text-center";
|
121
|
+
// Check for Notion's size property in the block itself
|
122
|
+
let maxWidthClass = "max-w-full";
|
123
|
+
let alignmentClass = "text-center";
|
124
124
|
|
125
|
-
//
|
126
|
-
|
127
|
-
|
125
|
+
// Try to get size from block properties (Notion API structure)
|
126
|
+
if (image.size) {
|
127
|
+
switch (image.size) {
|
128
|
+
case 'small':
|
129
|
+
maxWidthClass = "max-w-sm";
|
130
|
+
break;
|
131
|
+
case 'medium':
|
132
|
+
maxWidthClass = "max-w-lg";
|
133
|
+
break;
|
134
|
+
case 'large':
|
135
|
+
maxWidthClass = "max-w-2xl";
|
136
|
+
break;
|
137
|
+
default:
|
138
|
+
maxWidthClass = "max-w-full";
|
139
|
+
}
|
140
|
+
}
|
141
|
+
|
142
|
+
// Check for alignment in block properties
|
143
|
+
if (image.alignment) {
|
144
|
+
switch (image.alignment) {
|
145
|
+
case 'left':
|
146
|
+
alignmentClass = "text-left";
|
147
|
+
break;
|
148
|
+
case 'center':
|
149
|
+
alignmentClass = "text-center";
|
150
|
+
break;
|
151
|
+
case 'right':
|
152
|
+
alignmentClass = "text-right";
|
153
|
+
break;
|
154
|
+
default:
|
155
|
+
alignmentClass = "text-center";
|
156
|
+
}
|
157
|
+
}
|
158
|
+
|
159
|
+
const responsiveClasses = `w-full ${maxWidthClass} h-auto rounded-lg shadow-sm`;
|
128
160
|
|
129
161
|
return `
|
130
162
|
<figure class="my-8 ${alignmentClass}">
|
131
163
|
<img
|
132
164
|
src="${imageUrl}"
|
133
165
|
alt="${escapeHtml(altText)}"
|
134
|
-
class="${
|
166
|
+
class="${responsiveClasses}"
|
135
167
|
loading="lazy"
|
136
168
|
/>
|
137
|
-
${caption ? `<figcaption class="text-
|
169
|
+
${caption ? `<figcaption class="text-gray-500 mt-3 text-sm italic">${escapeHtml(caption)}</figcaption>` : ''}
|
138
170
|
</figure>
|
139
171
|
`.trim();
|
140
172
|
}
|
@@ -162,35 +194,15 @@ function processCallout(callout) {
|
|
162
194
|
const colorClass = colorClasses[bgColor] || colorClasses.blue;
|
163
195
|
|
164
196
|
return `
|
165
|
-
<div class="${colorClass} border-l-4 p-
|
197
|
+
<div class="${colorClass} border-l-4 p-6 my-8 rounded-r-lg shadow-sm">
|
166
198
|
<div class="flex items-start">
|
167
|
-
<span class="mr-
|
168
|
-
<div class="flex-1">${content}</div>
|
199
|
+
<span class="mr-4 text-2xl flex-shrink-0">${icon}</span>
|
200
|
+
<div class="flex-1 leading-7 text-lg">${content}</div>
|
169
201
|
</div>
|
170
202
|
</div>
|
171
203
|
`.trim();
|
172
204
|
}
|
173
205
|
|
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
206
|
/**
|
195
207
|
* Process bookmark block
|
196
208
|
* @param {Object} bookmark - Notion bookmark block
|
@@ -201,14 +213,14 @@ function processBookmark(bookmark) {
|
|
201
213
|
const title = bookmark.caption?.[0]?.plain_text || "Bookmark";
|
202
214
|
|
203
215
|
return `
|
204
|
-
<div class="my-
|
205
|
-
<a href="${url}" target="_blank" rel="noopener noreferrer" class="block border border-gray-200 rounded-lg p-
|
216
|
+
<div class="my-8">
|
217
|
+
<a href="${url}" target="_blank" rel="noopener noreferrer" class="block border border-gray-200 rounded-lg p-6 hover:border-gray-300 hover:shadow-lg transition-all duration-200 bg-white">
|
206
218
|
<div class="flex items-center">
|
207
|
-
<div class="flex-1">
|
208
|
-
<p class="font-
|
209
|
-
<p class="text-sm text-gray-500 truncate">${url}</p>
|
219
|
+
<div class="flex-1 min-w-0">
|
220
|
+
<p class="font-semibold text-gray-900 truncate text-lg">${escapeHtml(title)}</p>
|
221
|
+
<p class="text-sm text-gray-500 truncate mt-1">${url}</p>
|
210
222
|
</div>
|
211
|
-
<svg class="w-
|
223
|
+
<svg class="w-6 h-6 text-gray-400 ml-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
212
224
|
<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
225
|
</svg>
|
214
226
|
</div>
|
@@ -217,6 +229,26 @@ function processBookmark(bookmark) {
|
|
217
229
|
`.trim();
|
218
230
|
}
|
219
231
|
|
232
|
+
/**
|
233
|
+
* Process toggle block
|
234
|
+
* @param {Object} toggle - Notion toggle block
|
235
|
+
* @returns {string} HTML string
|
236
|
+
*/
|
237
|
+
function processToggle(toggle) {
|
238
|
+
const content = processRichText(toggle.rich_text, "div", "");
|
239
|
+
return `
|
240
|
+
<details class="my-6">
|
241
|
+
<summary class="cursor-pointer font-semibold text-gray-700 hover:text-gray-900 text-lg leading-7">
|
242
|
+
${content}
|
243
|
+
</summary>
|
244
|
+
<div class="mt-4 pl-6 border-l-2 border-gray-200">
|
245
|
+
<!-- Toggle content would go here if Notion API provided it -->
|
246
|
+
<p class="text-gray-600 text-base italic">Toggle content not available in current API</p>
|
247
|
+
</div>
|
248
|
+
</details>
|
249
|
+
`.trim();
|
250
|
+
}
|
251
|
+
|
220
252
|
/**
|
221
253
|
* Process rich text and apply formatting
|
222
254
|
* @param {Array} richText - Array of rich text objects
|
@@ -231,13 +263,13 @@ function processRichText(richText, tag, className) {
|
|
231
263
|
let result = text.plain_text;
|
232
264
|
|
233
265
|
// Apply annotations
|
234
|
-
if (text.annotations.bold) result = `<strong>${result}</strong>`;
|
235
|
-
if (text.annotations.italic) result = `<em>${result}</em>`;
|
236
|
-
if (text.annotations.strikethrough) result = `<del>${result}</del>`;
|
237
|
-
if (text.annotations.code) result = `<code class="bg-gray-100 px-
|
266
|
+
if (text.annotations.bold) result = `<strong class="font-bold">${result}</strong>`;
|
267
|
+
if (text.annotations.italic) result = `<em class="italic">${result}</em>`;
|
268
|
+
if (text.annotations.strikethrough) result = `<del class="line-through">${result}</del>`;
|
269
|
+
if (text.annotations.code) result = `<code class="bg-gray-100 px-2 py-1 rounded text-sm font-mono text-gray-800">${result}</code>`;
|
238
270
|
|
239
271
|
// Apply links
|
240
|
-
if (text.href) result = `<a href="${text.href}" class="text-blue-600 hover:text-blue-800 underline" target="_blank" rel="noopener noreferrer">${result}</a>`;
|
272
|
+
if (text.href) result = `<a href="${text.href}" class="text-blue-600 hover:text-blue-800 underline font-medium" target="_blank" rel="noopener noreferrer">${result}</a>`;
|
241
273
|
|
242
274
|
return result;
|
243
275
|
}).join("");
|