@san-siva/blogkit-md 0.1.2 → 0.2.1

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 CHANGED
@@ -123,7 +123,7 @@ description: A short description shown below the title
123
123
  | Image | `![alt](url)` |
124
124
  | Ordered list | `1. item` |
125
125
  | Unordered list | `- item` |
126
- | Table | GFM table syntax |
126
+ | Table | `\| col \| col \|` — headers and rows only |
127
127
  | Code block | ` ```lang ` |
128
128
  | Mermaid diagram | ` ```mermaid ` |
129
129
  | Thematic break | `---` |
@@ -259,13 +259,13 @@ Result content.
259
259
 
260
260
  ### Callouts
261
261
 
262
- Blockquotes are rendered as styled callout banners. The callout type is controlled by a prefix on the first word of the quote:
262
+ Blockquotes are rendered as styled callout banners. The callout type is controlled by a prefix on the first word of the quote.
263
263
 
264
- | Syntax | Callout Type | Example |
265
- | :-------- | :----------- | :--------------------------- |
266
- | `> text` | Info | `> This is an info callout.` |
267
- | `> ~text` | Warning | `> ~This is a warning.` |
268
- | `> !text` | Error | `> !This is an error.` |
264
+ > This is an info callout. Use `> text` for general information.
265
+
266
+ > ~This is a warning callout. Use `> ~text` to flag caution.
267
+
268
+ > !This is an error callout. Use `> !text` for errors or destructive actions.
269
269
 
270
270
  The prefix character is stripped from the rendered output — only the callout style changes.
271
271
 
@@ -1,11 +1,10 @@
1
1
  import { readFile } from 'node:fs/promises';
2
2
  import path from 'node:path';
3
3
 
4
- import '@/utils/devReloadTrigger';
5
- import type { Frontmatter } from '@/utils/parseMarkdown';
6
- import { parseMarkdown } from '@/utils/parseMarkdown';
7
- import type { RenderedMarkdown } from '@/utils/renderMarkdown';
8
- import { renderMarkdownAst } from '@/utils/renderMarkdown';
4
+ import type { Frontmatter } from '../utils/parseMarkdown';
5
+ import { parseMarkdown } from '../utils/parseMarkdown';
6
+ import type { RenderedMarkdown } from '../utils/renderMarkdown';
7
+ import { renderMarkdownAst } from '../utils/renderMarkdown';
9
8
 
10
9
  type MarkdownFileResult =
11
10
  | { success: true; rendered: RenderedMarkdown; frontmatter: Frontmatter }
@@ -15,14 +14,12 @@ export const readMarkdownFile = async (
15
14
  filePath: string | undefined
16
15
  ): Promise<MarkdownFileResult> => {
17
16
  if (!filePath) {
18
- return {
19
- success: false,
20
- error:
21
- 'MARKDOWN_FILE env variable is required. Usage: MARKDOWN_FILE=data/test.md npm run dev',
22
- };
17
+ return { success: false, error: 'No file path provided.' };
23
18
  }
24
19
 
25
- const absolutePath = path.join(process.cwd(), filePath);
20
+ const absolutePath = path.isAbsolute(filePath)
21
+ ? filePath
22
+ : path.join(process.cwd(), filePath);
26
23
 
27
24
  let content: string;
28
25
  try {
package/index.ts CHANGED
@@ -1 +1,3 @@
1
1
  export { default as BlogPost } from './components/BlogPost';
2
+ export { readMarkdownFile } from './hooks/readMarkdownFile';
3
+ export { MarkdownSections } from './utils/renderMarkdown';
package/package.json CHANGED
@@ -1,15 +1,12 @@
1
1
  {
2
2
  "name": "@san-siva/blogkit-md",
3
- "version": "0.1.2",
3
+ "version": "0.2.1",
4
4
  "description": "Converts markdown files into JSX blog posts for Blogkit",
5
5
  "main": "index.ts",
6
6
  "exports": {
7
7
  ".": "./index.ts"
8
8
  },
9
9
  "scripts": {
10
- "dev": "tsx scripts/dev.ts",
11
- "build": "MARKDOWN_FILE=data/test.md next build",
12
- "start": "next start",
13
10
  "test": "vitest run",
14
11
  "lint": "eslint . --config eslint.config.ts",
15
12
  "fix": "eslint . --config eslint.config.ts --fix"
@@ -50,7 +47,6 @@
50
47
  "eslint-plugin-unicorn": "^62.0.0",
51
48
  "jiti": "^2.0.0",
52
49
  "prettier": "^3.0.0",
53
- "tsx": "^4.0.0",
54
50
  "typescript": "^5.0.0",
55
51
  "typescript-eslint": "^8.0.0",
56
52
  "vitest": "^4.1.0"
@@ -25,7 +25,7 @@
25
25
  },
26
26
  "..": {
27
27
  "name": "@san-siva/blogkit-md",
28
- "version": "0.1.1",
28
+ "version": "0.1.2",
29
29
  "dependencies": {
30
30
  "@san-siva/blogkit": "^1.1.20",
31
31
  "@san-siva/stylekit": "^1.0.8",
package/app/layout.tsx DELETED
@@ -1,44 +0,0 @@
1
- import type { Metadata } from 'next';
2
- import { JetBrains_Mono, Montserrat, Rubik } from 'next/font/google';
3
-
4
- import '@san-siva/stylekit/styles/globals.scss';
5
- import '@san-siva/blogkit/styles.css';
6
- import styles from '@san-siva/stylekit/styles/index.module.scss';
7
-
8
- const montserrat = Montserrat({
9
- subsets: ['latin'] as const,
10
- weight: ['400', '500', '600', '700', '800'] as const,
11
- style: ['normal', 'italic'] as const,
12
- variable: '--font-montserrat',
13
- });
14
-
15
- const rubik = Rubik({
16
- subsets: ['latin'] as const,
17
- weight: ['300', '400', '500', '600', '700', '800', '900'] as const,
18
- style: ['normal', 'italic'] as const,
19
- variable: '--font-rubik',
20
- });
21
-
22
- const jetbrainsMono = JetBrains_Mono({
23
- subsets: ['latin'] as const,
24
- weight: ['400', '500', '600', '700'] as const,
25
- style: ['normal', 'italic'] as const,
26
- variable: '--font-jetbrains-mono',
27
- });
28
-
29
- export const metadata: Metadata = {
30
- title: 'Blogkit MD',
31
- description: 'Markdown to JSX blog post renderer',
32
- };
33
-
34
- const RootLayout = ({ children }: { children: React.ReactNode }) => (
35
- <html lang="en">
36
- <body
37
- className={`${montserrat.variable} ${rubik.variable} ${jetbrainsMono.variable}`}
38
- >
39
- <div className={`${styles.page}`}>{children}</div>
40
- </body>
41
- </html>
42
- );
43
-
44
- export default RootLayout;
package/app/page.tsx DELETED
@@ -1,32 +0,0 @@
1
- import { Blog, BlogHeader, Callout } from '@san-siva/blogkit';
2
-
3
- import { readMarkdownFile } from '@/hooks/readMarkdownFile';
4
- import { MarkdownSections } from '@/utils/renderMarkdown';
5
-
6
- const Page = async () => {
7
- const result = await readMarkdownFile(process.env.MARKDOWN_FILE);
8
-
9
- if (!result.success) {
10
- return (
11
- <Blog>
12
- <Callout type="warning">{result.error}</Callout>
13
- </Blog>
14
- );
15
- }
16
-
17
- const { rendered, frontmatter } = result;
18
-
19
- return (
20
- <Blog>
21
- {frontmatter.title && (
22
- <BlogHeader
23
- title={[frontmatter.title]}
24
- desc={frontmatter.description ? [frontmatter.description] : []}
25
- />
26
- )}
27
- <MarkdownSections rendered={rendered} />
28
- </Blog>
29
- );
30
- };
31
-
32
- export default Page;
package/next.config.ts DELETED
@@ -1,5 +0,0 @@
1
- import type { NextConfig } from 'next';
2
-
3
- const nextConfig: NextConfig = {};
4
-
5
- export default nextConfig;
package/scripts/dev.ts DELETED
@@ -1,50 +0,0 @@
1
- import { exec, spawn } from 'node:child_process';
2
- import { stat, writeFileSync } from 'node:fs';
3
- import path from 'node:path';
4
-
5
- const fileArgument = process.argv.find(argument => argument.startsWith('--file='));
6
- const markdownFile = fileArgument ? fileArgument.replace('--file=', '') : 'data/test.md';
7
-
8
- const markdownPath = path.join(process.cwd(), markdownFile);
9
- const triggerPath = path.join(process.cwd(), 'utils/devReloadTrigger.ts');
10
-
11
- // Write on startup so fresh clones have the file before Next.js compiles.
12
- writeFileSync(triggerPath, `export const reloadTrigger = '${Date.now()}';\n`);
13
-
14
- let lastMtime: number | null = null;
15
-
16
- const checkMarkdownFile = () => {
17
- stat(markdownPath, (error, stats) => {
18
- if (error) return;
19
- const { mtimeMs } = stats;
20
- if (lastMtime !== null && mtimeMs !== lastMtime) {
21
- writeFileSync(triggerPath, `export const reloadTrigger = '${mtimeMs}';\n`);
22
- }
23
- lastMtime = mtimeMs;
24
- });
25
- };
26
-
27
- setInterval(checkMarkdownFile, 500);
28
- checkMarkdownFile();
29
-
30
- const child = spawn('next', ['dev'], {
31
- env: { ...process.env, MARKDOWN_FILE: markdownFile },
32
- stdio: ['inherit', 'pipe', 'inherit'],
33
- });
34
-
35
- let browserOpened = false;
36
-
37
- child.stdout?.on('data', (chunk: Buffer) => {
38
- process.stdout.write(chunk);
39
- if (!browserOpened) {
40
- const match = chunk.toString().match(/http:\/\/localhost:\d+/);
41
- if (match) {
42
- browserOpened = true;
43
- exec(`open ${match[0]}`);
44
- }
45
- }
46
- });
47
-
48
- child.on('exit', code => {
49
- process.exit(code ?? 0);
50
- });