Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
9923326
Initial plan
Copilot Feb 22, 2026
b39ae29
Restructure public/docs/ into per-language directory format with inde…
Copilot Feb 22, 2026
f50b611
cppの全セクションにslug設定
na-trium-144 Feb 22, 2026
11e6fc0
一部のセクション構成と見出しを修正
na-trium-144 Feb 22, 2026
155e833
jsの全セクションにslug作成、js-replのidを削除
na-trium-144 Feb 22, 2026
c6713d7
update readme
na-trium-144 Feb 22, 2026
9e63553
pythonの全セクションにslug作成、python-replのidを削除
na-trium-144 Feb 23, 2026
eb5a049
rubyの全セクションにslug作成、ruby-replのidを削除
na-trium-144 Feb 23, 2026
712e7fe
なんかslug変なやつがあった
na-trium-144 Feb 23, 2026
93de093
Rename typescript and rust section files to N1-N2-slug.md format
Copilot Feb 23, 2026
1c39ee8
セクション分けに失敗しているものを修正
na-trium-144 Feb 23, 2026
0d7ee22
Add sections.yml script and new [lang]/[pageId] route
Copilot Feb 24, 2026
d16e95f
Use js-yaml for YAML parsing in page route and generateSections script
Copilot Feb 24, 2026
cf428cd
Add sections.yml to .gitignore and remove committed files
Copilot Feb 24, 2026
e50a9f9
Replace pagesList.ts with reading from public/docs/{lang}/index.yml
Copilot Feb 24, 2026
dd34b4b
Remove content from MarkdownSection, use rawContent directly in pageC…
Copilot Feb 24, 2026
2270cd1
Generate languages.yml at build time, remove hardcoded LANGUAGE_IDS f…
Copilot Feb 24, 2026
4dc38c3
Remove sectionId from DynamicMarkdownSection, use section.id directly
Copilot Feb 24, 2026
cdac6cb
Use section id instead of array index for element id and sidebar link…
Copilot Feb 24, 2026
5612905
Fix build: correct import paths in app/[lang]/[pageId]/page.tsx
Copilot Feb 24, 2026
c3b0b34
古いmdを削除
na-trium-144 Feb 24, 2026
ab9643f
refactor
na-trium-144 Feb 24, 2026
2594cc7
雑にターミナルidを追加
na-trium-144 Feb 24, 2026
faa9782
目次の折返しを修正
na-trium-144 Feb 24, 2026
9fa2c0a
descriptionがないのを修正
na-trium-144 Feb 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
/.open-next
/cloudflare-env.d.ts

# generated docs section file lists (regenerated by npm run generateSections)
/public/docs/**/sections.yml

# generated languages list (regenerated by npm run generateLanguages)
/public/docs/languages.yml

# dependencies
/node_modules
/.pnp
Expand Down
45 changes: 43 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,49 @@ npm run lint
現在は本番環境(my-code.utcode.net)はCoolifyでデプロイしています。
Cloudflare Worker のビルドログとステータス表示が見れますが、そちらは使っていません。

## ベースとなるドキュメントの作り方
## ドキュメント

* ドキュメントはセクション(見出し)ごとにわけ、 public/docs/言語id/ページid/並び替え用連番-セクション名.md に置く。
* ページはディレクトリの名前によらず 言語id/index.yml に書かれている順で表示される。
* セクションはセクションIDによらずファイル名順で表示される。
* 各セクションのfrontmatter (各ページ最初のセクション(-intro.md)を除く)
```yml
id: 一意なセクションID。ファイル名・ディレクトリ名と一致していなくても良い。バックエンドがこのセクションIDで識別するので、一度コミットしたら変更不可(ファイル名は何度変えても良い)
title: セクションタイトルと同じものをmd記法を使わずに書いた文字列
level: セクションの見出しレベル(2〜6が使用可)
```
* コード例はそれが配置されているセクションの内容と関連するようにする。
````md
## 制御構文
### if
if文の説明…
### switch
switch文の説明…

ifとswitch共通の注意事項... → ## 制御構文 に移す
```
ifとswitchを使ったコード例… → 2つのコード例に分割する
(分割が難しい(かつ説明が短い)場合は、1つのセクションで全部説明してコード例を載せるのでもよい)
```
````
* コード例や注意事項などを不必要に独立したセクションにするのは避ける
````md
## hoge
hogeの説明…
### hogeの使用場面 →この見出しいらない
**hogeの使用場面** はok
- 説明
- 説明
### hogeの使用例 →この見出しいらない
```
hogeを使ったコード例…
```
````
* REPLのコード例は1セクションに最大1つまで。
* コードエディターとコード実行ブロックはいくつでも置けます。
* ページ0以外の各ページの最後はレベル2見出し「この章のまとめ」と、レベル3見出し「練習問題n」を置く

### ベースとなるドキュメントの作り方

- web版の ~~Gemini2.5Pro~~ Gemini3Pro を用いる。
- 以下のプロンプトで章立てを考えさせる
Expand Down Expand Up @@ -107,7 +149,6 @@ Cloudflare Worker のビルドログとステータス表示が見れますが
Hello
```
````
- 練習問題の見出しは「この章のまとめ」の直下のレベル3見出しで、 `### 練習問題n` または `### 練習問題n: タイトル` とする
- 練習問題のファイル名は不都合がなければ `practice(章番号)_(問題番号).拡張子` で統一。空でもよいのでファイルコードブロックとexecコードブロックを置く
- 1章にはたぶん練習問題要らない。

Expand Down
90 changes: 0 additions & 90 deletions app/[docs_id]/page.tsx

This file was deleted.

47 changes: 0 additions & 47 deletions app/[docs_id]/splitMarkdown.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { useState, FormEvent, useEffect } from "react";
// } from "../actions/questionExample";
// import { getLanguageName } from "../pagesList";
import { DynamicMarkdownSection } from "./pageContent";
import { useEmbedContext } from "../terminal/embedContext";
import { useEmbedContext } from "@/terminal/embedContext";
import { useChatHistoryContext } from "./chatHistory";
import { askAI } from "@/actions/chatActions";

Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import Markdown, { Components, ExtraProps } from "react-markdown";
import remarkGfm from "remark-gfm";
import removeComments from "remark-remove-comments";
import remarkCjkFriendly from "remark-cjk-friendly";
import { EditorComponent, getAceLang } from "../terminal/editor";
import { ExecFile } from "../terminal/exec";
import { EditorComponent, getAceLang } from "@/terminal/editor";
import { ExecFile } from "@/terminal/exec";
import { JSX, ReactNode } from "react";
import { getRuntimeLang } from "@/terminal/runtime";
import { ReplTerminal } from "@/terminal/repl";
Expand Down Expand Up @@ -64,6 +64,8 @@ export function Heading({
children: ReactNode;
}) {
switch (level) {
case 0:
return null;
case 1:
return <h1 className="text-2xl font-bold my-4">{children}</h1>;
case 2:
Expand Down
63 changes: 63 additions & 0 deletions app/[lang]/[pageId]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { Metadata } from "next";
import { notFound } from "next/navigation";
import { PageContent } from "./pageContent";
import { ChatHistoryProvider } from "./chatHistory";
import { getChatFromCache, initContext } from "@/lib/chatHistory";
import { getMarkdownSections, getPagesList } from "@/lib/docs";

export async function generateMetadata({
params,
}: {
params: Promise<{ lang: string; pageId: string }>;
}): Promise<Metadata> {
const { lang, pageId } = await params;
const pagesList = await getPagesList();
const langEntry = pagesList.find((l) => l.id === lang);
const pageEntry = langEntry?.pages.find((p) => p.slug === pageId);
if (!langEntry || !pageEntry) notFound();

const sections = await getMarkdownSections(lang, pageId);
const description = sections[0].rawContent;

return {
title: `${langEntry!.name}-${pageEntry.index}. ${pageEntry.title}`,
description,
};
}

export default async function Page({
params,
}: {
params: Promise<{ lang: string; pageId: string }>;
}) {
const { lang, pageId } = await params;
const pagesList = await getPagesList();
const langEntry = pagesList.find((l) => l.id === lang);
const pageEntry = langEntry?.pages.find((p) => p.slug === pageId);
if (!langEntry || !pageEntry) notFound();

const docsId = `${lang}/${pageId}`;
const sections = await getMarkdownSections(lang, pageId);

// AI用のドキュメント全文(rawContentを結合)
const documentContent = sections.map((s) => s.rawContent).join("\n");

const context = await initContext();
const initialChatHistories = await getChatFromCache(docsId, context);

return (
<ChatHistoryProvider
initialChatHistories={initialChatHistories}
docs_id={docsId}
>
<PageContent
documentContent={documentContent}
splitMdContent={sections}
pageEntry={pageEntry}
docs_id={docsId}
lang={lang}
pageId={pageId}
/>
</ChatHistoryProvider>
);
}
Loading