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. - 1. 環境構築と基本思想 -
  2. -
  3. - 2. 基本構文とデータ型 -
  4. -
  5. - 3. リスト、タプル、辞書、セット -
  6. -
  7. - 4. 制御構文と関数 -
  8. -
  9. - 5. モジュールとパッケージ -
  10. -
  11. - 6. オブジェクト指向プログラミング -
  12. -
  13. - 7. ファイルの入出力とコンテキストマネージャ -
  14. -
  15. - 8. 例外処理 -
  16. -
  17. - 9. ジェネレータとデコレータ -
  18. + +
      + {pages.map((page) => ( +
    1. + {page.title} + {page.id === docs_id && !isLoading &&( +
        + {splitmdcontent + .slice(1) + .map((section, idx) => ( +
      • + {section.title} +
      • + ))} +
      + )} + +
    2. + ))}
); } + 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": {