@autoblogwriter/sdk 3.0.4 → 3.0.6

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/dist/react.js CHANGED
@@ -6,7 +6,11 @@ function escapeHtml(value) {
6
6
  function renderInline(input) {
7
7
  let output = escapeHtml(input);
8
8
  output = output.replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>");
9
+ output = output.replace(/__(.+?)__/g, "<strong>$1</strong>");
9
10
  output = output.replace(/\*(.+?)\*/g, "<em>$1</em>");
11
+ output = output.replace(/(?<!\w)_(.+?)_(?!\w)/g, "<em>$1</em>");
12
+ output = output.replace(/~~(.+?)~~/g, "<s>$1</s>");
13
+ output = output.replace(/\+\+(.+?)\+\+/g, "<u>$1</u>");
10
14
  output = output.replace(/`([^`]+)`/g, (_, code) => `<code>${code}</code>`);
11
15
  output = output.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, (_, alt, src) => {
12
16
  const safeSrc = escapeHtml(src);
@@ -21,14 +25,97 @@ function renderInline(input) {
21
25
  return output;
22
26
  }
23
27
  function replaceCodeBlocks(markdown, blocks) {
24
- return markdown.replace(/```([\s\S]*?)```/g, (_, code) => {
25
- const index = blocks.push(`<pre><code>${escapeHtml(code.trim())}</code></pre>`) - 1;
28
+ return markdown.replace(/```(\w*)\n?([\s\S]*?)```/g, (_, lang, code) => {
29
+ const langAttr = lang ? ` class="language-${escapeHtml(lang)}"` : "";
30
+ const index = blocks.push(`<pre><code${langAttr}>${escapeHtml(code.trim())}</code></pre>`) - 1;
26
31
  return `${CODE_BLOCK_TOKEN}${index}__`;
27
32
  });
28
33
  }
29
34
  function restoreCodeBlocks(html, blocks) {
30
35
  return html.replace(/__AUTOBLOGWRITER_CODE_BLOCK_(\d+)__/g, (_, rawIndex) => blocks[Number(rawIndex)] ?? "");
31
36
  }
37
+ function isUnorderedListItem(line) {
38
+ return /^[\t ]*[-*+] /.test(line);
39
+ }
40
+ function isOrderedListItem(line) {
41
+ return /^[\t ]*\d+\. /.test(line);
42
+ }
43
+ function getListItemContent(line) {
44
+ return line.replace(/^[\t ]*(?:[-*+]|\d+\.) /, "");
45
+ }
46
+ function getIndentLevel(line) {
47
+ const match = line.match(/^([\t ]*)/);
48
+ if (!match) return 0;
49
+ const indent = match[1];
50
+ return indent.replace(/\t/g, " ").length;
51
+ }
52
+ function parseListItems(lines, baseIndent) {
53
+ const items = [];
54
+ let i = 0;
55
+ while (i < lines.length) {
56
+ const indent = getIndentLevel(lines[i]);
57
+ if (indent > baseIndent && items.length > 0) {
58
+ const nestedLines = [];
59
+ while (i < lines.length && getIndentLevel(lines[i]) > baseIndent) {
60
+ nestedLines.push(lines[i]);
61
+ i++;
62
+ }
63
+ items[items.length - 1].children = parseListItems(nestedLines, baseIndent + 2);
64
+ } else {
65
+ items.push({ content: getListItemContent(lines[i]), children: [] });
66
+ i++;
67
+ }
68
+ }
69
+ return items;
70
+ }
71
+ function renderListItems(items, tag) {
72
+ const lis = items.map((item) => {
73
+ let li = `<li>${renderInline(item.content)}`;
74
+ if (item.children.length > 0) {
75
+ li += renderListItems(item.children, tag);
76
+ }
77
+ li += "</li>";
78
+ return li;
79
+ });
80
+ return `<${tag}>${lis.join("")}</${tag}>`;
81
+ }
82
+ function renderBlock(block) {
83
+ const headingMatch = block.match(/^(#{1,6})\s+(.*)$/);
84
+ if (headingMatch) {
85
+ const level = headingMatch[1].length;
86
+ const content = renderInline(headingMatch[2]);
87
+ return `<h${level}>${content}</h${level}>`;
88
+ }
89
+ if (/^(?:---+|\*\*\*+|___+)$/.test(block.trim())) {
90
+ return "<hr />";
91
+ }
92
+ const imageMatch = block.match(/^!\[([^\]]*)\]\(([^)]+)\)$/);
93
+ if (imageMatch) {
94
+ const safeSrc = escapeHtml(imageMatch[2]);
95
+ const safeAlt = escapeHtml(imageMatch[1]);
96
+ return `<img src="${safeSrc}" alt="${safeAlt}" />`;
97
+ }
98
+ const lines = block.split("\n");
99
+ if (lines.every((l) => l.startsWith("> ") || l === ">")) {
100
+ const inner = lines.map((l) => l.replace(/^>\s?/, "")).join("\n");
101
+ const innerHtml = inner.split(/\n{2,}/).map((b) => b.trim()).filter(Boolean).map(renderBlock).join("\n");
102
+ return `<blockquote>${innerHtml}</blockquote>`;
103
+ }
104
+ if (lines.every((l) => isUnorderedListItem(l))) {
105
+ const items = parseListItems(lines, 0);
106
+ return renderListItems(items, "ul");
107
+ }
108
+ if (lines.every((l) => isOrderedListItem(l))) {
109
+ const items = parseListItems(lines, 0);
110
+ return renderListItems(items, "ol");
111
+ }
112
+ if (lines.length > 0 && (isUnorderedListItem(lines[0]) || isOrderedListItem(lines[0]))) {
113
+ const isOrdered = isOrderedListItem(lines[0]);
114
+ const items = parseListItems(lines, 0);
115
+ return renderListItems(items, isOrdered ? "ol" : "ul");
116
+ }
117
+ return `<p>${renderInline(block)}</p>`;
118
+ }
32
119
  function renderMarkdownToHtml(markdown) {
33
120
  if (!markdown) {
34
121
  return "";
@@ -37,22 +124,61 @@ function renderMarkdownToHtml(markdown) {
37
124
  const withoutCode = replaceCodeBlocks(markdown, codeBlocks);
38
125
  const normalized = withoutCode.replace(/\r\n/g, "\n");
39
126
  const withHeadingBreaks = normalized.replace(/\n(#{1,6}\s)/g, "\n\n$1").replace(/(#{1,6}\s[^\n]+)\n(?!#|\n)/g, "$1\n\n");
40
- const blocks = withHeadingBreaks.split(/\n{2,}/).map((block) => block.trim()).filter(Boolean);
41
- const htmlBlocks = blocks.map((block) => {
42
- const headingMatch = block.match(/^(#{1,6})\s+(.*)$/);
43
- if (headingMatch) {
44
- const level = headingMatch[1].length;
45
- const content = renderInline(headingMatch[2]);
46
- return `<h${level}>${content}</h${level}>`;
127
+ const rawBlocks = [];
128
+ let currentBlock = [];
129
+ const flushBlock = () => {
130
+ if (currentBlock.length > 0) {
131
+ rawBlocks.push(currentBlock.join("\n").trim());
132
+ currentBlock = [];
133
+ }
134
+ };
135
+ const inputLines = withHeadingBreaks.split("\n");
136
+ let i = 0;
137
+ while (i < inputLines.length) {
138
+ const line = inputLines[i];
139
+ const trimmed = line.trim();
140
+ if (trimmed === "") {
141
+ const prevIsListOrQuote = currentBlock.length > 0 && (isUnorderedListItem(currentBlock[0]) || isOrderedListItem(currentBlock[0]) || currentBlock[0].startsWith("> "));
142
+ if (prevIsListOrQuote) {
143
+ let nextIdx = i + 1;
144
+ while (nextIdx < inputLines.length && inputLines[nextIdx].trim() === "") nextIdx++;
145
+ if (nextIdx < inputLines.length) {
146
+ const nextTrimmed = inputLines[nextIdx].trim();
147
+ const continues = isUnorderedListItem(currentBlock[0]) && isUnorderedListItem(nextTrimmed) || isOrderedListItem(currentBlock[0]) && isOrderedListItem(nextTrimmed) || currentBlock[0].startsWith("> ") && (nextTrimmed.startsWith("> ") || nextTrimmed === ">");
148
+ if (continues) {
149
+ i++;
150
+ continue;
151
+ }
152
+ }
153
+ }
154
+ flushBlock();
155
+ i++;
156
+ continue;
47
157
  }
48
- const imageMatch = block.match(/^!\[([^\]]*)\]\(([^)]+)\)$/);
49
- if (imageMatch) {
50
- const safeSrc = escapeHtml(imageMatch[2]);
51
- const safeAlt = escapeHtml(imageMatch[1]);
52
- return `<img src="${safeSrc}" alt="${safeAlt}" />`;
158
+ if (isUnorderedListItem(trimmed) || isOrderedListItem(trimmed)) {
159
+ if (currentBlock.length > 0 && !isUnorderedListItem(currentBlock[0]) && !isOrderedListItem(currentBlock[0])) {
160
+ flushBlock();
161
+ }
162
+ currentBlock.push(trimmed);
163
+ i++;
164
+ continue;
53
165
  }
54
- return `<p>${renderInline(block)}</p>`;
55
- });
166
+ if (trimmed.startsWith("> ") || trimmed === ">") {
167
+ if (currentBlock.length > 0 && !currentBlock[0].startsWith("> ") && currentBlock[0] !== ">") {
168
+ flushBlock();
169
+ }
170
+ currentBlock.push(trimmed);
171
+ i++;
172
+ continue;
173
+ }
174
+ if (currentBlock.length > 0 && (isUnorderedListItem(currentBlock[0]) || isOrderedListItem(currentBlock[0]) || currentBlock[0].startsWith("> "))) {
175
+ flushBlock();
176
+ }
177
+ currentBlock.push(line);
178
+ i++;
179
+ }
180
+ flushBlock();
181
+ const htmlBlocks = rawBlocks.filter(Boolean).map(renderBlock);
56
182
  const html = htmlBlocks.join("\n");
57
183
  return restoreCodeBlocks(html, codeBlocks);
58
184
  }
package/dist/react.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/render.ts","../src/react/Markdown.tsx","../src/react/BlogPost.tsx","../src/react/BlogPostList.tsx"],"sourcesContent":["const CODE_BLOCK_TOKEN = \"__AUTOBLOGWRITER_CODE_BLOCK_\";\n\nfunction escapeHtml(value: string): string {\n return value\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\n}\n\nfunction renderInline(input: string): string {\n let output = escapeHtml(input);\n output = output.replace(/\\*\\*(.+?)\\*\\*/g, \"<strong>$1</strong>\");\n output = output.replace(/\\*(.+?)\\*/g, \"<em>$1</em>\");\n output = output.replace(/`([^`]+)`/g, (_, code) => `<code>${code}</code>`);\n output = output.replace(/!\\[([^\\]]*)\\]\\(([^)]+)\\)/g, (_, alt, src) => {\n const safeSrc = escapeHtml(src);\n const safeAlt = escapeHtml(alt);\n return `<img src=\"${safeSrc}\" alt=\"${safeAlt}\" />`;\n });\n output = output.replace(/\\[(.+?)\\]\\((.+?)\\)/g, (_, label, href) => {\n const safeHref = escapeHtml(href);\n return `<a href=\"${safeHref}\" target=\"_blank\" rel=\"noreferrer\">${label}</a>`;\n });\n output = output.replace(/\\n/g, \"<br />\");\n return output;\n}\n\nfunction replaceCodeBlocks(markdown: string, blocks: string[]): string {\n return markdown.replace(/```([\\s\\S]*?)```/g, (_, code) => {\n const index = blocks.push(`<pre><code>${escapeHtml(code.trim())}</code></pre>`) - 1;\n return `${CODE_BLOCK_TOKEN}${index}__`;\n });\n}\n\nfunction restoreCodeBlocks(html: string, blocks: string[]): string {\n return html.replace(/__AUTOBLOGWRITER_CODE_BLOCK_(\\d+)__/g, (_, rawIndex) => blocks[Number(rawIndex)] ?? \"\");\n}\n\nexport function renderMarkdownToHtml(markdown: string): string {\n if (!markdown) {\n return \"\";\n }\n\n const codeBlocks: string[] = [];\n const withoutCode = replaceCodeBlocks(markdown, codeBlocks);\n const normalized = withoutCode.replace(/\\r\\n/g, \"\\n\");\n // Insert blank lines around heading lines so they become separate blocks\n const withHeadingBreaks = normalized\n .replace(/\\n(#{1,6}\\s)/g, \"\\n\\n$1\")\n .replace(/(#{1,6}\\s[^\\n]+)\\n(?!#|\\n)/g, \"$1\\n\\n\");\n const blocks = withHeadingBreaks\n .split(/\\n{2,}/)\n .map((block) => block.trim())\n .filter(Boolean);\n\n const htmlBlocks = blocks.map((block) => {\n const headingMatch = block.match(/^(#{1,6})\\s+(.*)$/);\n if (headingMatch) {\n const level = headingMatch[1].length;\n const content = renderInline(headingMatch[2]);\n return `<h${level}>${content}</h${level}>`;\n }\n\n // Check if block is a standalone image\n const imageMatch = block.match(/^!\\[([^\\]]*)\\]\\(([^)]+)\\)$/);\n if (imageMatch) {\n const safeSrc = escapeHtml(imageMatch[2]);\n const safeAlt = escapeHtml(imageMatch[1]);\n return `<img src=\"${safeSrc}\" alt=\"${safeAlt}\" />`;\n }\n\n return `<p>${renderInline(block)}</p>`;\n });\n\n const html = htmlBlocks.join(\"\\n\");\n return restoreCodeBlocks(html, codeBlocks);\n}\n","import { renderMarkdownToHtml } from \"../render\";\n\nexport interface MarkdownProps {\n source?: string | null;\n className?: string;\n}\n\nexport function Markdown({ source, className = \"ba-markdown\" }: MarkdownProps) {\n if (!source) {\n return null;\n }\n\n return (\n <div\n className={className}\n dangerouslySetInnerHTML={{ __html: renderMarkdownToHtml(source) }}\n />\n );\n}\n","import type { BlogPost as BlogPostType } from \"../types\";\nimport { Markdown } from \"./Markdown\";\n\nexport interface BlogPostProps {\n post: BlogPostType;\n showTitle?: boolean;\n showDate?: boolean;\n className?: string;\n renderContent?: (content: string) => React.ReactNode;\n}\n\nfunction formatDate(dateStr: string): string {\n return new Date(dateStr).toLocaleDateString(undefined, {\n year: \"numeric\",\n month: \"long\",\n day: \"numeric\",\n });\n}\n\nexport function BlogPost({\n post,\n showTitle = true,\n showDate = true,\n className = \"ba-post\",\n renderContent,\n}: BlogPostProps) {\n const readingTime = post.metadata?.readingTimeMinutes;\n const dateStr = post.publishedAt ?? post.updatedAt;\n\n return (\n <article className={className}>\n {showTitle && <h1 className=\"ba-post-title\">{post.title}</h1>}\n {post.categories && post.categories.length > 0 && (\n <div className=\"ba-post-categories\" aria-label=\"Categories\">\n {post.categories.map((category) => (\n <span key={category} className=\"ba-category-chip\">\n {category}\n </span>\n ))}\n </div>\n )}\n {(showDate || readingTime) && (\n <p className=\"ba-post-meta\">\n {showDate && (\n <time dateTime={dateStr}>{formatDate(dateStr)}</time>\n )}\n {showDate && readingTime && <span className=\"ba-post-meta-sep\"> · </span>}\n {readingTime && (\n <span className=\"ba-post-reading-time\">{readingTime} min read</span>\n )}\n </p>\n )}\n {renderContent ? renderContent(post.content) : <Markdown source={post.content} />}\n </article>\n );\n}\n","import type { BlogPost } from \"../types\";\nimport { Markdown } from \"./Markdown\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype LinkComponent = React.ComponentType<any>;\n\nexport interface BlogPostListProps {\n posts: BlogPost[];\n title?: string;\n routePrefix?: string;\n linkComponent?: LinkComponent;\n className?: string;\n renderCard?: (post: BlogPost, href: string) => React.ReactNode;\n}\n\nfunction DefaultLink({\n href,\n className,\n children,\n}: {\n href: string;\n className?: string;\n children: React.ReactNode;\n}) {\n return (\n <a href={href} className={className}>\n {children}\n </a>\n );\n}\n\nfunction formatDate(dateStr: string): string {\n return new Date(dateStr).toLocaleDateString(undefined, {\n year: \"numeric\",\n month: \"long\",\n day: \"numeric\",\n });\n}\n\nexport function BlogPostList({\n posts,\n title = \"Latest posts\",\n routePrefix = \"/blog\",\n linkComponent,\n className = \"ba-listing\",\n renderCard,\n}: BlogPostListProps) {\n const Link = linkComponent ?? DefaultLink;\n const prefix = routePrefix.replace(/\\/$/, \"\");\n\n return (\n <section className={className}>\n {title && <h1 className=\"ba-listing-title\">{title}</h1>}\n <div className=\"ba-posts\">\n {posts.map((post) => {\n const href = `${prefix}/${post.slug}`;\n\n if (renderCard) {\n return <div key={post.id}>{renderCard(post, href)}</div>;\n }\n\n const dateStr = post.publishedAt ?? post.updatedAt;\n\n return (\n <article key={post.id} className=\"ba-post-card\">\n {post.categories && post.categories.length > 0 && (\n <div className=\"ba-post-card-categories\" aria-label=\"Categories\">\n {post.categories.map((category) => (\n <span key={category} className=\"ba-category-chip\">\n {category}\n </span>\n ))}\n </div>\n )}\n <h2 className=\"ba-post-card-title\">\n <Link href={href} className=\"ba-post-card-link\">\n {post.title}\n </Link>\n </h2>\n <p className=\"ba-post-card-meta\">\n <time dateTime={dateStr}>{formatDate(dateStr)}</time>\n </p>\n <div className=\"ba-post-card-excerpt\">\n <Markdown source={post.excerpt ?? post.content.slice(0, 180)} />\n </div>\n </article>\n );\n })}\n </div>\n </section>\n );\n}\n"],"mappings":"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","names":["jsx","jsx","jsxs","formatDate"]}
1
+ {"version":3,"sources":["../src/render.ts","../src/react/Markdown.tsx","../src/react/BlogPost.tsx","../src/react/BlogPostList.tsx"],"sourcesContent":["const CODE_BLOCK_TOKEN = \"__AUTOBLOGWRITER_CODE_BLOCK_\";\n\nfunction escapeHtml(value: string): string {\n return value\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\n}\n\nfunction renderInline(input: string): string {\n let output = escapeHtml(input);\n // bold\n output = output.replace(/\\*\\*(.+?)\\*\\*/g, \"<strong>$1</strong>\");\n output = output.replace(/__(.+?)__/g, \"<strong>$1</strong>\");\n // italic\n output = output.replace(/\\*(.+?)\\*/g, \"<em>$1</em>\");\n output = output.replace(/(?<!\\w)_(.+?)_(?!\\w)/g, \"<em>$1</em>\");\n // strikethrough\n output = output.replace(/~~(.+?)~~/g, \"<s>$1</s>\");\n // underline (non-standard but common: ++text++)\n output = output.replace(/\\+\\+(.+?)\\+\\+/g, \"<u>$1</u>\");\n // inline code\n output = output.replace(/`([^`]+)`/g, (_, code) => `<code>${code}</code>`);\n // images (before links)\n output = output.replace(/!\\[([^\\]]*)\\]\\(([^)]+)\\)/g, (_, alt, src) => {\n const safeSrc = escapeHtml(src);\n const safeAlt = escapeHtml(alt);\n return `<img src=\"${safeSrc}\" alt=\"${safeAlt}\" />`;\n });\n // links\n output = output.replace(/\\[(.+?)\\]\\((.+?)\\)/g, (_, label, href) => {\n const safeHref = escapeHtml(href);\n return `<a href=\"${safeHref}\" target=\"_blank\" rel=\"noreferrer\">${label}</a>`;\n });\n // line breaks\n output = output.replace(/\\n/g, \"<br />\");\n return output;\n}\n\nfunction replaceCodeBlocks(markdown: string, blocks: string[]): string {\n return markdown.replace(/```(\\w*)\\n?([\\s\\S]*?)```/g, (_, lang, code) => {\n const langAttr = lang ? ` class=\"language-${escapeHtml(lang)}\"` : \"\";\n const index = blocks.push(`<pre><code${langAttr}>${escapeHtml(code.trim())}</code></pre>`) - 1;\n return `${CODE_BLOCK_TOKEN}${index}__`;\n });\n}\n\nfunction restoreCodeBlocks(html: string, blocks: string[]): string {\n return html.replace(/__AUTOBLOGWRITER_CODE_BLOCK_(\\d+)__/g, (_, rawIndex) => blocks[Number(rawIndex)] ?? \"\");\n}\n\nfunction isUnorderedListItem(line: string): boolean {\n return /^[\\t ]*[-*+] /.test(line);\n}\n\nfunction isOrderedListItem(line: string): boolean {\n return /^[\\t ]*\\d+\\. /.test(line);\n}\n\nfunction getListItemContent(line: string): string {\n return line.replace(/^[\\t ]*(?:[-*+]|\\d+\\.) /, \"\");\n}\n\nfunction getIndentLevel(line: string): number {\n const match = line.match(/^([\\t ]*)/);\n if (!match) return 0;\n const indent = match[1];\n // Count tabs as 2 spaces worth\n return indent.replace(/\\t/g, \" \").length;\n}\n\ninterface ListItem {\n content: string;\n children: ListItem[];\n}\n\nfunction parseListItems(lines: string[], baseIndent: number): ListItem[] {\n const items: ListItem[] = [];\n let i = 0;\n\n while (i < lines.length) {\n const indent = getIndentLevel(lines[i]);\n if (indent > baseIndent && items.length > 0) {\n // Nested: collect all lines at this deeper level\n const nestedLines: string[] = [];\n while (i < lines.length && getIndentLevel(lines[i]) > baseIndent) {\n nestedLines.push(lines[i]);\n i++;\n }\n items[items.length - 1].children = parseListItems(nestedLines, baseIndent + 2);\n } else {\n items.push({ content: getListItemContent(lines[i]), children: [] });\n i++;\n }\n }\n\n return items;\n}\n\nfunction renderListItems(items: ListItem[], tag: \"ul\" | \"ol\"): string {\n const lis = items.map((item) => {\n let li = `<li>${renderInline(item.content)}`;\n if (item.children.length > 0) {\n li += renderListItems(item.children, tag);\n }\n li += \"</li>\";\n return li;\n });\n return `<${tag}>${lis.join(\"\")}</${tag}>`;\n}\n\nfunction renderBlock(block: string): string {\n // Heading\n const headingMatch = block.match(/^(#{1,6})\\s+(.*)$/);\n if (headingMatch) {\n const level = headingMatch[1].length;\n const content = renderInline(headingMatch[2]);\n return `<h${level}>${content}</h${level}>`;\n }\n\n // Horizontal rule\n if (/^(?:---+|\\*\\*\\*+|___+)$/.test(block.trim())) {\n return \"<hr />\";\n }\n\n // Standalone image\n const imageMatch = block.match(/^!\\[([^\\]]*)\\]\\(([^)]+)\\)$/);\n if (imageMatch) {\n const safeSrc = escapeHtml(imageMatch[2]);\n const safeAlt = escapeHtml(imageMatch[1]);\n return `<img src=\"${safeSrc}\" alt=\"${safeAlt}\" />`;\n }\n\n // Blockquote\n const lines = block.split(\"\\n\");\n if (lines.every((l) => l.startsWith(\"> \") || l === \">\")) {\n const inner = lines.map((l) => l.replace(/^>\\s?/, \"\")).join(\"\\n\");\n // Recursively render blockquote content\n const innerHtml = inner\n .split(/\\n{2,}/)\n .map((b) => b.trim())\n .filter(Boolean)\n .map(renderBlock)\n .join(\"\\n\");\n return `<blockquote>${innerHtml}</blockquote>`;\n }\n\n // Unordered list\n if (lines.every((l) => isUnorderedListItem(l))) {\n const items = parseListItems(lines, 0);\n return renderListItems(items, \"ul\");\n }\n\n // Ordered list\n if (lines.every((l) => isOrderedListItem(l))) {\n const items = parseListItems(lines, 0);\n return renderListItems(items, \"ol\");\n }\n\n // Mixed list lines or lines starting with list markers — try to detect\n if (lines.length > 0 && (isUnorderedListItem(lines[0]) || isOrderedListItem(lines[0]))) {\n const isOrdered = isOrderedListItem(lines[0]);\n const items = parseListItems(lines, 0);\n return renderListItems(items, isOrdered ? \"ol\" : \"ul\");\n }\n\n // Default: paragraph\n return `<p>${renderInline(block)}</p>`;\n}\n\nexport function renderMarkdownToHtml(markdown: string): string {\n if (!markdown) {\n return \"\";\n }\n\n const codeBlocks: string[] = [];\n const withoutCode = replaceCodeBlocks(markdown, codeBlocks);\n const normalized = withoutCode.replace(/\\r\\n/g, \"\\n\");\n\n // Insert blank lines around heading lines so they become separate blocks\n const withHeadingBreaks = normalized\n .replace(/\\n(#{1,6}\\s)/g, \"\\n\\n$1\")\n .replace(/(#{1,6}\\s[^\\n]+)\\n(?!#|\\n)/g, \"$1\\n\\n\");\n\n // Split into blocks but keep list items and blockquotes grouped\n const rawBlocks: string[] = [];\n let currentBlock: string[] = [];\n\n const flushBlock = () => {\n if (currentBlock.length > 0) {\n rawBlocks.push(currentBlock.join(\"\\n\").trim());\n currentBlock = [];\n }\n };\n\n const inputLines = withHeadingBreaks.split(\"\\n\");\n let i = 0;\n\n while (i < inputLines.length) {\n const line = inputLines[i];\n const trimmed = line.trim();\n\n // Empty line: flush current block\n if (trimmed === \"\") {\n // But if we're in a list or blockquote, keep going if next line continues it\n const prevIsListOrQuote =\n currentBlock.length > 0 &&\n (isUnorderedListItem(currentBlock[0]) ||\n isOrderedListItem(currentBlock[0]) ||\n currentBlock[0].startsWith(\"> \"));\n\n if (prevIsListOrQuote) {\n // Check if the next non-empty line continues the same structure\n let nextIdx = i + 1;\n while (nextIdx < inputLines.length && inputLines[nextIdx].trim() === \"\") nextIdx++;\n if (nextIdx < inputLines.length) {\n const nextTrimmed = inputLines[nextIdx].trim();\n const continues =\n (isUnorderedListItem(currentBlock[0]) && isUnorderedListItem(nextTrimmed)) ||\n (isOrderedListItem(currentBlock[0]) && isOrderedListItem(nextTrimmed)) ||\n (currentBlock[0].startsWith(\"> \") && (nextTrimmed.startsWith(\"> \") || nextTrimmed === \">\"));\n if (continues) {\n i++;\n continue;\n }\n }\n }\n flushBlock();\n i++;\n continue;\n }\n\n // List items: group together\n if (isUnorderedListItem(trimmed) || isOrderedListItem(trimmed)) {\n // If current block is not a list, flush first\n if (\n currentBlock.length > 0 &&\n !isUnorderedListItem(currentBlock[0]) &&\n !isOrderedListItem(currentBlock[0])\n ) {\n flushBlock();\n }\n currentBlock.push(trimmed);\n i++;\n continue;\n }\n\n // Blockquote lines: group together\n if (trimmed.startsWith(\"> \") || trimmed === \">\") {\n if (currentBlock.length > 0 && !currentBlock[0].startsWith(\"> \") && currentBlock[0] !== \">\") {\n flushBlock();\n }\n currentBlock.push(trimmed);\n i++;\n continue;\n }\n\n // Regular line\n if (\n currentBlock.length > 0 &&\n (isUnorderedListItem(currentBlock[0]) ||\n isOrderedListItem(currentBlock[0]) ||\n currentBlock[0].startsWith(\"> \"))\n ) {\n flushBlock();\n }\n currentBlock.push(line);\n i++;\n }\n flushBlock();\n\n const htmlBlocks = rawBlocks.filter(Boolean).map(renderBlock);\n const html = htmlBlocks.join(\"\\n\");\n return restoreCodeBlocks(html, codeBlocks);\n}\n","import { renderMarkdownToHtml } from \"../render\";\n\nexport interface MarkdownProps {\n source?: string | null;\n className?: string;\n}\n\nexport function Markdown({ source, className = \"ba-markdown\" }: MarkdownProps) {\n if (!source) {\n return null;\n }\n\n return (\n <div\n className={className}\n dangerouslySetInnerHTML={{ __html: renderMarkdownToHtml(source) }}\n />\n );\n}\n","import type { BlogPost as BlogPostType } from \"../types\";\nimport { Markdown } from \"./Markdown\";\n\nexport interface BlogPostProps {\n post: BlogPostType;\n showTitle?: boolean;\n showDate?: boolean;\n className?: string;\n renderContent?: (content: string) => React.ReactNode;\n}\n\nfunction formatDate(dateStr: string): string {\n return new Date(dateStr).toLocaleDateString(undefined, {\n year: \"numeric\",\n month: \"long\",\n day: \"numeric\",\n });\n}\n\nexport function BlogPost({\n post,\n showTitle = true,\n showDate = true,\n className = \"ba-post\",\n renderContent,\n}: BlogPostProps) {\n const readingTime = post.metadata?.readingTimeMinutes;\n const dateStr = post.publishedAt ?? post.updatedAt;\n\n return (\n <article className={className}>\n {showTitle && <h1 className=\"ba-post-title\">{post.title}</h1>}\n {post.categories && post.categories.length > 0 && (\n <div className=\"ba-post-categories\" aria-label=\"Categories\">\n {post.categories.map((category) => (\n <span key={category} className=\"ba-category-chip\">\n {category}\n </span>\n ))}\n </div>\n )}\n {(showDate || readingTime) && (\n <p className=\"ba-post-meta\">\n {showDate && (\n <time dateTime={dateStr}>{formatDate(dateStr)}</time>\n )}\n {showDate && readingTime && <span className=\"ba-post-meta-sep\"> · </span>}\n {readingTime && (\n <span className=\"ba-post-reading-time\">{readingTime} min read</span>\n )}\n </p>\n )}\n {renderContent ? renderContent(post.content) : <Markdown source={post.content} />}\n </article>\n );\n}\n","import type { BlogPost } from \"../types\";\nimport { Markdown } from \"./Markdown\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype LinkComponent = React.ComponentType<any>;\n\nexport interface BlogPostListProps {\n posts: BlogPost[];\n title?: string;\n routePrefix?: string;\n linkComponent?: LinkComponent;\n className?: string;\n renderCard?: (post: BlogPost, href: string) => React.ReactNode;\n}\n\nfunction DefaultLink({\n href,\n className,\n children,\n}: {\n href: string;\n className?: string;\n children: React.ReactNode;\n}) {\n return (\n <a href={href} className={className}>\n {children}\n </a>\n );\n}\n\nfunction formatDate(dateStr: string): string {\n return new Date(dateStr).toLocaleDateString(undefined, {\n year: \"numeric\",\n month: \"long\",\n day: \"numeric\",\n });\n}\n\nexport function BlogPostList({\n posts,\n title = \"Latest posts\",\n routePrefix = \"/blog\",\n linkComponent,\n className = \"ba-listing\",\n renderCard,\n}: BlogPostListProps) {\n const Link = linkComponent ?? DefaultLink;\n const prefix = routePrefix.replace(/\\/$/, \"\");\n\n return (\n <section className={className}>\n {title && <h1 className=\"ba-listing-title\">{title}</h1>}\n <div className=\"ba-posts\">\n {posts.map((post) => {\n const href = `${prefix}/${post.slug}`;\n\n if (renderCard) {\n return <div key={post.id}>{renderCard(post, href)}</div>;\n }\n\n const dateStr = post.publishedAt ?? post.updatedAt;\n\n return (\n <article key={post.id} className=\"ba-post-card\">\n {post.categories && post.categories.length > 0 && (\n <div className=\"ba-post-card-categories\" aria-label=\"Categories\">\n {post.categories.map((category) => (\n <span key={category} className=\"ba-category-chip\">\n {category}\n </span>\n ))}\n </div>\n )}\n <h2 className=\"ba-post-card-title\">\n <Link href={href} className=\"ba-post-card-link\">\n {post.title}\n </Link>\n </h2>\n <p className=\"ba-post-card-meta\">\n <time dateTime={dateStr}>{formatDate(dateStr)}</time>\n </p>\n <div className=\"ba-post-card-excerpt\">\n <Markdown source={post.excerpt ?? post.content.slice(0, 180)} />\n </div>\n </article>\n );\n })}\n </div>\n </section>\n );\n}\n"],"mappings":"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","names":["jsx","jsx","jsxs","formatDate"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autoblogwriter/sdk",
3
- "version": "3.0.4",
3
+ "version": "3.0.6",
4
4
  "description": "Official AutoBlogWriter SDK for fetching posts, building sitemaps, rendering helpers, and revalidation utilities.",
5
5
  "license": "MIT",
6
6
  "type": "module",