diff --git a/app/[docs_id]/page.tsx b/app/[docs_id]/page.tsx
index cd09acd..9cb12dc 100644
--- a/app/[docs_id]/page.tsx
+++ b/app/[docs_id]/page.tsx
@@ -41,7 +41,9 @@ export default async function Page({
return (
{splitMdContent.map((section, index) => (
-
+
+
+
))}
);
diff --git a/app/[docs_id]/splitMarkdown.ts b/app/[docs_id]/splitMarkdown.ts
index 104e2e2..21dbbbf 100644
--- a/app/[docs_id]/splitMarkdown.ts
+++ b/app/[docs_id]/splitMarkdown.ts
@@ -1,5 +1,3 @@
-"use server";
-
import { unified } from "unified";
import remarkParse from "remark-parse";
import remarkGfm from "remark-gfm";
@@ -13,9 +11,9 @@ export interface MarkdownSection {
* Markdownコンテンツを見出しごとに分割し、
* 見出しのレベルとタイトル、内容を含むオブジェクトの配列を返す。
*/
-export async function splitMarkdown(
+export function splitMarkdown(
content: string
-): Promise {
+): MarkdownSection[] {
const tree = unified().use(remarkParse).use(remarkGfm).parse(content);
// console.log(tree.children.map(({ type, position }) => ({ type, position: JSON.stringify(position) })));
const headingNodes = tree.children.filter((node) => node.type === "heading");
diff --git a/app/sidebar.tsx b/app/sidebar.tsx
index eda32e1..21b7730 100644
--- a/app/sidebar.tsx
+++ b/app/sidebar.tsx
@@ -1,6 +1,37 @@
+"use client";
import Link from "next/link";
+import { usePathname } from "next/navigation";
+import useSWR, { Fetcher } from 'swr'
+import { splitMarkdown } from "./[docs_id]/splitMarkdown";
+
+const fetcher: Fetcher = (url) => fetch(url).then((r) => r.text())
export function Sidebar() {
+ const pathname = usePathname();
+ const docs_id = pathname.replace(/^\//, "");
+ const { data, error, isLoading } = useSWR(
+ `/docs/${docs_id}.md`,
+ fetcher
+ )
+
+ const pages = [
+ { id: "python-1", title: "1. 環境構築と基本思想" },
+ { id: "python-2", title: "2. 基本構文とデータ型" },
+ { id: "python-3", title: "3. リスト、タプル、辞書、セット" },
+ { id: "python-4", title: "4. 制御構文と関数" },
+ { id: "python-5", title: "5. モジュールとパッケージ" },
+ { id: "python-6", title: "6. オブジェクト指向プログラミング" },
+ { id: "python-7", title: "7. ファイルの入出力とコンテキストマネージャ" },
+ { id: "python-8", title: "8. 例外処理" },
+ { id: "python-9", title: "9. ジェネレータとデコレータ" },
+ ];
+
+ if (error) console.error("Sidebar fetch error:", error)
+
+
+
+
+ const splitmdcontent = splitMarkdown(data ?? "")
return (
{/* todo: 背景色ほんとにこれでいい? */}
@@ -8,35 +39,27 @@ export function Sidebar() {
{/* サイドバーが常時表示されている場合のみ */}
Navbar Title
-
- -
- 1. 環境構築と基本思想
-
- -
- 2. 基本構文とデータ型
-
- -
- 3. リスト、タプル、辞書、セット
-
- -
- 4. 制御構文と関数
-
- -
- 5. モジュールとパッケージ
-
- -
- 6. オブジェクト指向プログラミング
-
- -
- 7. ファイルの入出力とコンテキストマネージャ
-
- -
- 8. 例外処理
-
- -
- 9. ジェネレータとデコレータ
-
+
+
+ {pages.map((page) => (
+ -
+ {page.title}
+ {page.id === docs_id && !isLoading &&(
+
+ {splitmdcontent
+ .slice(1)
+ .map((section, idx) => (
+ -
+ {section.title}
+
+ ))}
+
+ )}
+
+
+ ))}
);
}
+
diff --git a/app/terminal/python/pyodide.tsx b/app/terminal/python/pyodide.tsx
index bfaf16d..1fb34b7 100644
--- a/app/terminal/python/pyodide.tsx
+++ b/app/terminal/python/pyodide.tsx
@@ -289,7 +289,7 @@ export function PyodideProvider({ children }: { children: ReactNode }) {
return output;
});
},
- [files]
+ [files, writeFile]
);
/**
diff --git a/package-lock.json b/package-lock.json
index b34b94e..af61fd9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -25,6 +25,7 @@
"react-markdown": "^10.1.0",
"react-syntax-highlighter": "^15.6.1",
"remark-gfm": "^4.0.1",
+ "swr": "^2.3.6",
"zod": "^4.0.17"
},
"devDependencies": {
@@ -19328,6 +19329,19 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/swr": {
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/swr/-/swr-2.3.6.tgz",
+ "integrity": "sha512-wfHRmHWk/isGNMwlLGlZX5Gzz/uTgo0o2IRuTMcf4CPuPFJZlq0rDaKUx+ozB5nBOReNV1kiOyzMfj+MBMikLw==",
+ "license": "MIT",
+ "dependencies": {
+ "dequal": "^2.0.3",
+ "use-sync-external-store": "^1.4.0"
+ },
+ "peerDependencies": {
+ "react": "^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
"node_modules/tailwindcss": {
"version": "4.1.11",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.11.tgz",
@@ -19837,6 +19851,15 @@
"integrity": "sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw==",
"license": "MIT"
},
+ "node_modules/use-sync-external-store": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz",
+ "integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
"node_modules/utils-merge": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
diff --git a/package.json b/package.json
index 6ad4485..7c60a9c 100644
--- a/package.json
+++ b/package.json
@@ -31,6 +31,7 @@
"react-markdown": "^10.1.0",
"react-syntax-highlighter": "^15.6.1",
"remark-gfm": "^4.0.1",
+ "swr": "^2.3.6",
"zod": "^4.0.17"
},
"devDependencies": {