diff --git a/resources/help/B02/00_설명서.md b/A05_EduDetail/guide/B02/00_설명서.md similarity index 100% rename from resources/help/B02/00_설명서.md rename to A05_EduDetail/guide/B02/00_설명서.md diff --git a/resources/help/B03/00_설명서.md b/A05_EduDetail/guide/B03/00_설명서.md similarity index 100% rename from resources/help/B03/00_설명서.md rename to A05_EduDetail/guide/B03/00_설명서.md diff --git a/resources/help/B03/10_필요한_파일.md b/A05_EduDetail/guide/B03/10_필요한_파일.md similarity index 100% rename from resources/help/B03/10_필요한_파일.md rename to A05_EduDetail/guide/B03/10_필요한_파일.md diff --git a/resources/help/B03/20_고르는_방법.md b/A05_EduDetail/guide/B03/20_고르는_방법.md similarity index 100% rename from resources/help/B03/20_고르는_방법.md rename to A05_EduDetail/guide/B03/20_고르는_방법.md diff --git a/resources/help/B03/30_알아_둘_것.md b/A05_EduDetail/guide/B03/30_알아_둘_것.md similarity index 100% rename from resources/help/B03/30_알아_둘_것.md rename to A05_EduDetail/guide/B03/30_알아_둘_것.md diff --git a/resources/help/B04/00_설명서.md b/A05_EduDetail/guide/B04/00_설명서.md similarity index 100% rename from resources/help/B04/00_설명서.md rename to A05_EduDetail/guide/B04/00_설명서.md diff --git a/resources/help/B05/00_설명서.md b/A05_EduDetail/guide/B05/00_설명서.md similarity index 100% rename from resources/help/B05/00_설명서.md rename to A05_EduDetail/guide/B05/00_설명서.md diff --git a/resources/help/B05/구조물_BOX암거.md b/A05_EduDetail/guide/B05/구조물_BOX암거.md similarity index 100% rename from resources/help/B05/구조물_BOX암거.md rename to A05_EduDetail/guide/B05/구조물_BOX암거.md diff --git a/resources/help/B05/구조물_기슭막이.md b/A05_EduDetail/guide/B05/구조물_기슭막이.md similarity index 100% rename from resources/help/B05/구조물_기슭막이.md rename to A05_EduDetail/guide/B05/구조물_기슭막이.md diff --git a/resources/help/B05/구조물_돌쌓기(메).md b/A05_EduDetail/guide/B05/구조물_돌쌓기(메).md similarity index 100% rename from resources/help/B05/구조물_돌쌓기(메).md rename to A05_EduDetail/guide/B05/구조물_돌쌓기(메).md diff --git a/resources/help/B05/구조물_돌쌓기(찰).md b/A05_EduDetail/guide/B05/구조물_돌쌓기(찰).md similarity index 100% rename from resources/help/B05/구조물_돌쌓기(찰).md rename to A05_EduDetail/guide/B05/구조물_돌쌓기(찰).md diff --git a/resources/help/B05/구조물_물넘이포장.md b/A05_EduDetail/guide/B05/구조물_물넘이포장.md similarity index 100% rename from resources/help/B05/구조물_물넘이포장.md rename to A05_EduDetail/guide/B05/구조물_물넘이포장.md diff --git a/resources/help/B05/구조물_배관.md b/A05_EduDetail/guide/B05/구조물_배관.md similarity index 100% rename from resources/help/B05/구조물_배관.md rename to A05_EduDetail/guide/B05/구조물_배관.md diff --git a/resources/help/B05/구조물_비탈면 녹화.md b/A05_EduDetail/guide/B05/구조물_비탈면 녹화.md similarity index 100% rename from resources/help/B05/구조물_비탈면 녹화.md rename to A05_EduDetail/guide/B05/구조물_비탈면 녹화.md diff --git a/resources/help/B05/구조물_세월교.md b/A05_EduDetail/guide/B05/구조물_세월교.md similarity index 100% rename from resources/help/B05/구조물_세월교.md rename to A05_EduDetail/guide/B05/구조물_세월교.md diff --git a/resources/help/B05/구조물_옹벽.md b/A05_EduDetail/guide/B05/구조물_옹벽.md similarity index 100% rename from resources/help/B05/구조물_옹벽.md rename to A05_EduDetail/guide/B05/구조물_옹벽.md diff --git a/resources/help/B05/구조물_측구(옆도랑).md b/A05_EduDetail/guide/B05/구조물_측구(옆도랑).md similarity index 100% rename from resources/help/B05/구조물_측구(옆도랑).md rename to A05_EduDetail/guide/B05/구조물_측구(옆도랑).md diff --git a/resources/help/B05/구조물_큰돌쌓기.md b/A05_EduDetail/guide/B05/구조물_큰돌쌓기.md similarity index 100% rename from resources/help/B05/구조물_큰돌쌓기.md rename to A05_EduDetail/guide/B05/구조물_큰돌쌓기.md diff --git a/resources/help/B05/구조물_흙막이.md b/A05_EduDetail/guide/B05/구조물_흙막이.md similarity index 100% rename from resources/help/B05/구조물_흙막이.md rename to A05_EduDetail/guide/B05/구조물_흙막이.md diff --git a/resources/help/B06/00_설명서.md b/A05_EduDetail/guide/B06/00_설명서.md similarity index 100% rename from resources/help/B06/00_설명서.md rename to A05_EduDetail/guide/B06/00_설명서.md diff --git a/resources/help/B06/표준_횡단면.md b/A05_EduDetail/guide/B06/표준_횡단면.md similarity index 100% rename from resources/help/B06/표준_횡단면.md rename to A05_EduDetail/guide/B06/표준_횡단면.md diff --git a/resources/help/B07/00_설명서.md b/A05_EduDetail/guide/B07/00_설명서.md similarity index 100% rename from resources/help/B07/00_설명서.md rename to A05_EduDetail/guide/B07/00_설명서.md diff --git a/resources/help/B08/00_설명서.md b/A05_EduDetail/guide/B08/00_설명서.md similarity index 100% rename from resources/help/B08/00_설명서.md rename to A05_EduDetail/guide/B08/00_설명서.md diff --git a/resources/help/B09/00_설명서.md b/A05_EduDetail/guide/B09/00_설명서.md similarity index 100% rename from resources/help/B09/00_설명서.md rename to A05_EduDetail/guide/B09/00_설명서.md diff --git a/resources/help/D01/00_설명서.md b/A05_EduDetail/guide/D01/00_설명서.md similarity index 100% rename from resources/help/D01/00_설명서.md rename to A05_EduDetail/guide/D01/00_설명서.md diff --git a/resources/help/D01/10_칸_뜻.md b/A05_EduDetail/guide/D01/10_칸_뜻.md similarity index 100% rename from resources/help/D01/10_칸_뜻.md rename to A05_EduDetail/guide/D01/10_칸_뜻.md diff --git a/resources/help/D02/00_설명서.md b/A05_EduDetail/guide/D02/00_설명서.md similarity index 100% rename from resources/help/D02/00_설명서.md rename to A05_EduDetail/guide/D02/00_설명서.md diff --git a/resources/help/D02/10_칸_뜻.md b/A05_EduDetail/guide/D02/10_칸_뜻.md similarity index 100% rename from resources/help/D02/10_칸_뜻.md rename to A05_EduDetail/guide/D02/10_칸_뜻.md diff --git a/resources/help/D02/20_쓰인_방법과_근거.md b/A05_EduDetail/guide/D02/20_쓰인_방법과_근거.md similarity index 100% rename from resources/help/D02/20_쓰인_방법과_근거.md rename to A05_EduDetail/guide/D02/20_쓰인_방법과_근거.md diff --git a/resources/help/D03/00_설명서.md b/A05_EduDetail/guide/D03/00_설명서.md similarity index 100% rename from resources/help/D03/00_설명서.md rename to A05_EduDetail/guide/D03/00_설명서.md diff --git a/resources/help/D03/20_쓰인_방법과_근거.md b/A05_EduDetail/guide/D03/20_쓰인_방법과_근거.md similarity index 100% rename from resources/help/D03/20_쓰인_방법과_근거.md rename to A05_EduDetail/guide/D03/20_쓰인_방법과_근거.md diff --git a/resources/help/D03/30_사용자_확정_전_값.md b/A05_EduDetail/guide/D03/30_사용자_확정_전_값.md similarity index 100% rename from resources/help/D03/30_사용자_확정_전_값.md rename to A05_EduDetail/guide/D03/30_사용자_확정_전_값.md diff --git a/resources/help/D04/00_설명서.md b/A05_EduDetail/guide/D04/00_설명서.md similarity index 100% rename from resources/help/D04/00_설명서.md rename to A05_EduDetail/guide/D04/00_설명서.md diff --git a/resources/help/D04/10_내보내기_파일_구성.md b/A05_EduDetail/guide/D04/10_내보내기_파일_구성.md similarity index 100% rename from resources/help/D04/10_내보내기_파일_구성.md rename to A05_EduDetail/guide/D04/10_내보내기_파일_구성.md diff --git a/resources/help/D04/30_사용자_확정_전_값.md b/A05_EduDetail/guide/D04/30_사용자_확정_전_값.md similarity index 100% rename from resources/help/D04/30_사용자_확정_전_값.md rename to A05_EduDetail/guide/D04/30_사용자_확정_전_값.md diff --git a/resources/help/E01/00_설명서.md b/A05_EduDetail/guide/E01/00_설명서.md similarity index 100% rename from resources/help/E01/00_설명서.md rename to A05_EduDetail/guide/E01/00_설명서.md diff --git a/resources/help/E02/00_설명서.md b/A05_EduDetail/guide/E02/00_설명서.md similarity index 100% rename from resources/help/E02/00_설명서.md rename to A05_EduDetail/guide/E02/00_설명서.md diff --git a/resources/help/E02/10_칸_뜻.md b/A05_EduDetail/guide/E02/10_칸_뜻.md similarity index 100% rename from resources/help/E02/10_칸_뜻.md rename to A05_EduDetail/guide/E02/10_칸_뜻.md diff --git a/resources/help/E02/20_쓰인_방법과_근거.md b/A05_EduDetail/guide/E02/20_쓰인_방법과_근거.md similarity index 100% rename from resources/help/E02/20_쓰인_방법과_근거.md rename to A05_EduDetail/guide/E02/20_쓰인_방법과_근거.md diff --git a/resources/help/E02/30_사용자_확정_전_값.md b/A05_EduDetail/guide/E02/30_사용자_확정_전_값.md similarity index 100% rename from resources/help/E02/30_사용자_확정_전_값.md rename to A05_EduDetail/guide/E02/30_사용자_확정_전_값.md diff --git a/resources/help/E03/00_설명서.md b/A05_EduDetail/guide/E03/00_설명서.md similarity index 100% rename from resources/help/E03/00_설명서.md rename to A05_EduDetail/guide/E03/00_설명서.md diff --git a/resources/help/E03/10_칸_뜻.md b/A05_EduDetail/guide/E03/10_칸_뜻.md similarity index 100% rename from resources/help/E03/10_칸_뜻.md rename to A05_EduDetail/guide/E03/10_칸_뜻.md diff --git a/resources/help/E03/20_쓰인_방법과_근거.md b/A05_EduDetail/guide/E03/20_쓰인_방법과_근거.md similarity index 100% rename from resources/help/E03/20_쓰인_방법과_근거.md rename to A05_EduDetail/guide/E03/20_쓰인_방법과_근거.md diff --git a/resources/help/E04/00_설명서.md b/A05_EduDetail/guide/E04/00_설명서.md similarity index 100% rename from resources/help/E04/00_설명서.md rename to A05_EduDetail/guide/E04/00_설명서.md diff --git a/resources/help/E04/10_칸_뜻.md b/A05_EduDetail/guide/E04/10_칸_뜻.md similarity index 100% rename from resources/help/E04/10_칸_뜻.md rename to A05_EduDetail/guide/E04/10_칸_뜻.md diff --git a/resources/help/E04/20_쓰인_방법과_근거.md b/A05_EduDetail/guide/E04/20_쓰인_방법과_근거.md similarity index 100% rename from resources/help/E04/20_쓰인_방법과_근거.md rename to A05_EduDetail/guide/E04/20_쓰인_방법과_근거.md diff --git a/resources/help/E04/30_사용자_확정_전_값.md b/A05_EduDetail/guide/E04/30_사용자_확정_전_값.md similarity index 100% rename from resources/help/E04/30_사용자_확정_전_값.md rename to A05_EduDetail/guide/E04/30_사용자_확정_전_값.md diff --git a/resources/help/E05/00_설명서.md b/A05_EduDetail/guide/E05/00_설명서.md similarity index 100% rename from resources/help/E05/00_설명서.md rename to A05_EduDetail/guide/E05/00_설명서.md diff --git a/resources/help/E05/10_시트_구성.md b/A05_EduDetail/guide/E05/10_시트_구성.md similarity index 100% rename from resources/help/E05/10_시트_구성.md rename to A05_EduDetail/guide/E05/10_시트_구성.md diff --git a/resources/help/E06/00_설명서.md b/A05_EduDetail/guide/E06/00_설명서.md similarity index 100% rename from resources/help/E06/00_설명서.md rename to A05_EduDetail/guide/E06/00_설명서.md diff --git a/resources/help/E06/10_칸_뜻.md b/A05_EduDetail/guide/E06/10_칸_뜻.md similarity index 100% rename from resources/help/E06/10_칸_뜻.md rename to A05_EduDetail/guide/E06/10_칸_뜻.md diff --git a/resources/help/E06/20_쓰인_방법과_근거.md b/A05_EduDetail/guide/E06/20_쓰인_방법과_근거.md similarity index 100% rename from resources/help/E06/20_쓰인_방법과_근거.md rename to A05_EduDetail/guide/E06/20_쓰인_방법과_근거.md diff --git a/resources/help/E07/00_설명서.md b/A05_EduDetail/guide/E07/00_설명서.md similarity index 100% rename from resources/help/E07/00_설명서.md rename to A05_EduDetail/guide/E07/00_설명서.md diff --git a/resources/help/E07/10_칸_뜻.md b/A05_EduDetail/guide/E07/10_칸_뜻.md similarity index 100% rename from resources/help/E07/10_칸_뜻.md rename to A05_EduDetail/guide/E07/10_칸_뜻.md diff --git a/resources/help/E07/20_쓰인_방법과_근거.md b/A05_EduDetail/guide/E07/20_쓰인_방법과_근거.md similarity index 100% rename from resources/help/E07/20_쓰인_방법과_근거.md rename to A05_EduDetail/guide/E07/20_쓰인_방법과_근거.md diff --git a/resources/help/E07/30_사용자_확정_전_값.md b/A05_EduDetail/guide/E07/30_사용자_확정_전_값.md similarity index 100% rename from resources/help/E07/30_사용자_확정_전_값.md rename to A05_EduDetail/guide/E07/30_사용자_확정_전_값.md diff --git a/B03_FileInput/B03_FileInput_UI_Guide.ts b/B03_FileInput/B03_FileInput_UI_Guide.ts index 062f21290..4977f577f 100644 --- a/B03_FileInput/B03_FileInput_UI_Guide.ts +++ b/B03_FileInput/B03_FileInput_UI_Guide.ts @@ -2,7 +2,7 @@ * B03_FileInput_UI_Guide.ts * 파일 입력 좌측 패널 (2026-09-03 사용자 지시). * - * 안내 글(필요한 파일 · 고르는 방법 · 알아 둘 것)은 [?] 설명서 `resources/help/B03/*.md` 로 + * 안내 글(필요한 파일 · 고르는 방법 · 알아 둘 것)은 [?] 설명서 `A05_EduDetail/guide/B03/*.md` 로 * 옮김(54-2). 패널에는 현황 배너와 아래 단추 줄([?] 자리)만 남김. * ========================================================================== */ diff --git a/common_util/common_util_help_router.py b/common_util/common_util_help_router.py index 6960521b7..20571c3f7 100644 --- a/common_util/common_util_help_router.py +++ b/common_util/common_util_help_router.py @@ -1,20 +1,30 @@ -"""[?] 설명서 글(54-2) — `resources/help/<페이지>/*.md` 를 부를 때마다 읽어 줌. +"""[?] 사용자 가이드(54-2 · 538) — `A05_EduDetail/guide/<페이지>/*.md` 를 부를 때마다 읽어 줌. 사용자가 메모장으로 파일을 고치면 화면 고침 없이 다음에 열 때 바뀐 글이 보임. 파일 이름 순서 = 모달 왼쪽 차례 순서 · 제목 = 첫 `# ` 줄(없으면 파일 이름). +`_` 로 시작하는 파일 · 그림은 항목 아님. +판(version) = 파일 sha256 앞 16자 · 페이지 제목 = `00_설명서` 의 제목. """ from __future__ import annotations +import hashlib import re from pathlib import Path +from typing import Any -from fastapi import APIRouter, HTTPException +from fastapi import APIRouter, Depends, HTTPException + +from common_util.common_util_auth import verify_session router = APIRouter(prefix="/api/help", tags=["help"]) -HELP_ROOT = Path(__file__).resolve().parent.parent / "resources" / "help" -PAGE_RE = re.compile(r"^(B0[2-9]|D0[1-4]|E0[1-7])$") +HELP_ROOT = Path(__file__).resolve().parent.parent / "A05_EduDetail" / "guide" +PAGE_RE = re.compile(r"^[BDE]\d{2}$") + + +def file_version(blob: bytes) -> str: + return hashlib.sha256(blob).hexdigest()[:16] def read_help(page: str, root: Path = HELP_ROOT) -> list[dict[str, str]]: @@ -23,12 +33,45 @@ def read_help(page: str, root: Path = HELP_ROOT) -> list[dict[str, str]]: folder = root / page items = [] for path in sorted(folder.glob("*.md")) if folder.is_dir() else []: - text = path.read_text(encoding="utf-8-sig") + if path.name.startswith("_"): + continue + blob = path.read_bytes() + text = blob.decode("utf-8-sig") head = next((line[2:].strip() for line in text.splitlines() if line.startswith("# ")), "") - items.append({"key": path.stem, "title": head or path.stem, "text": text}) + items.append( + { + "key": path.stem, + "title": head or path.stem, + "text": text, + "version": file_version(blob), + } + ) return items +def read_guide(root: Path = HELP_ROOT) -> list[dict[str, Any]]: + """모든 페이지 — 폴더 이름 순 · 글 없는 폴더는 뺌.""" + pages = [] + for folder in sorted(p for p in root.iterdir() if p.is_dir() and PAGE_RE.match(p.name)): + items = read_help(folder.name, root) + if not items: + continue + manual = next((i for i in items if i["key"] == "00_설명서"), None) + pages.append( + { + "page": folder.name, + "title": manual["title"] if manual else folder.name, + "items": items, + } + ) + return pages + + +@router.get("") +async def get_guide(session: dict[str, Any] = Depends(verify_session)) -> dict[str, Any]: + return {"pages": read_guide(), "admin": session.get("role") == "SYSTEM_ADMIN"} + + @router.get("/{page}") async def get_help(page: str) -> dict[str, list[dict[str, str]]]: return {"items": read_help(page)} diff --git a/resources/tester/test_54_2_help_files.py b/resources/tester/test_54_2_help_files.py index b5ae4fc75..0580109bc 100644 --- a/resources/tester/test_54_2_help_files.py +++ b/resources/tester/test_54_2_help_files.py @@ -1,23 +1,34 @@ -"""54-2 [?] 설명서 — 서버가 resources/help/<페이지>/*.md 를 부를 때마다 읽음(고치면 바로 바뀜).""" +"""54-2 · 538 [?] 가이드 — 서버가 A05_EduDetail/guide/<페이지>/*.md 를 부를 때마다 읽음. -import re +글 내용 검사(명사형 · 길이)는 두지 않음 — 관리자가 화면에서 고친 글이 시험을 빨갛게 안 하게. +""" + +import shutil import tempfile from pathlib import Path import pytest from fastapi import HTTPException -from common_util.common_util_help_router import HELP_ROOT, read_help +from common_util.common_util_help_router import HELP_ROOT, file_version, read_guide, read_help + + +@pytest.fixture +def tmp_path(): # 기본 pytest 임시 폴더가 이 PC 에서 막힘 — 직접 만듦 + path = Path(tempfile.mkdtemp()) + yield path + shutil.rmtree(path, ignore_errors=True) def test_every_page_has_manual_first(): - for n in range(2, 10): - items = read_help(f"B0{n}") - assert items and items[0]["key"] == "00_설명서" + for page in [f"B0{n}" for n in range(2, 10)] + [f"D0{n}" for n in range(1, 5)]: + items = read_help(page) + assert items and items[0]["key"] == "00_설명서", page + for n in range(1, 8): + assert read_help(f"E0{n}")[0]["key"] == "00_설명서" -def test_title_order_and_live_edit(): - tmp_path = Path(tempfile.mkdtemp()) +def test_title_order_and_live_edit(tmp_path): page = tmp_path / "B05" page.mkdir() (page / "10_배관.md").write_text("# 배관\n\n본문", encoding="utf-8") @@ -29,30 +40,49 @@ def test_title_order_and_live_edit(): assert "고친 글" in read_help("B05", tmp_path)[1]["text"] -@pytest.mark.parametrize("page", ["B01", "B10", "../B05", "b05", "D05", "E08", "C01"]) +def test_version_is_file_hash_and_changes(tmp_path): + page = tmp_path / "B05" + page.mkdir() + path = page / "00_설명서.md" + path.write_text("# 종단\n", encoding="utf-8") + first = read_help("B05", tmp_path)[0]["version"] + assert first == file_version(path.read_bytes()) and len(first) == 16 + path.write_text("# 종단\n고침\n", encoding="utf-8") + assert read_help("B05", tmp_path)[0]["version"] != first + + +def test_guide_pages_order_title_and_skips(tmp_path): + for name in ["E02", "B05", "B01", "b03", "X01", "B5", "_B04", "D01"]: + (tmp_path / name).mkdir() + (tmp_path / "B05" / "00_설명서.md").write_text("# 종단 설계\n", encoding="utf-8") + (tmp_path / "B05" / "_scenes.md").write_text("# 장면\n", encoding="utf-8") + (tmp_path / "B05" / "그림.webp").write_bytes(b"x") + (tmp_path / "B01" / "00_설명서.md").write_text("# 대시보드\n", encoding="utf-8") + (tmp_path / "E02" / "10_칸_뜻.md").write_text("# 칸\n", encoding="utf-8") + for name in ["b03", "X01", "B5", "_B04"]: + (tmp_path / name / "00_설명서.md").write_text("# 나쁨\n", encoding="utf-8") + pages = read_guide(tmp_path) + assert [p["page"] for p in pages] == ["B01", "B05", "E02"] # D01 = 글 없음 · 나쁜 폴더 뺌 + assert [p["title"] for p in pages] == ["대시보드", "종단 설계", "E02"] + assert [i["key"] for i in pages[1]["items"]] == ["00_설명서"] # `_` 파일 · 그림은 항목 아님 + + +def test_real_guide_reads_all_pages(): + pages = {p["page"] for p in read_guide()} + assert {"B02", "B05", "B06", "D01", "E02", "E07"} <= pages + + +@pytest.mark.parametrize("page", ["../B05", "b05", "B5", "C01", "B05/..", "..", "B100"]) def test_bad_page_refused(page): with pytest.raises(HTTPException): read_help(page) -def test_529_1_D_E_pages_open_empty(tmp_path): - assert read_help("D02", tmp_path) == [] and read_help("E07", tmp_path) == [] +def test_missing_page_opens_empty(tmp_path): + assert read_help("D02", tmp_path) == [] and read_help("B10", tmp_path) == [] -def test_root_is_repo_resources(): - assert HELP_ROOT.parts[-2:] == ("resources", "help") - - -@pytest.mark.parametrize( - "page", ["D01", "D02", "D03", "D04", "E01", "E02", "E03", "E04", "E05", "E06", "E07"] -) -def test_d_e_pages_have_manual(page): - items = read_help(page) - assert items and items[0]["key"] == "00_설명서" - assert len(items[0]["text"]) > 400 - for item in items: # 명사형 종결 — 합쇼체 · 해요체 · 한다체 금지 - for line in item["text"].splitlines(): - assert not re.search(r"(합니다|습니다|해요|세요|한다|된다|있다|없다)[.!]?\s*$", line), ( - page, - line, - ) +def test_root_is_a05_guide(): + assert HELP_ROOT.parts[-2:] == ("A05_EduDetail", "guide") + assert HELP_ROOT.is_dir() + assert not (Path(HELP_ROOT).parents[1] / "resources" / "help").exists() diff --git a/resources/tester/ui_checks/54-2_도움말.js b/resources/tester/ui_checks/54-2_도움말.js index f3592c5b0..508dd1e6e 100644 --- a/resources/tester/ui_checks/54-2_도움말.js +++ b/resources/tester/ui_checks/54-2_도움말.js @@ -4,7 +4,7 @@ * 부르는 법: orca eval --expression "$(cat 이 파일)" (async 식 · JSON 글을 돌려줌) · 1분 넘으면 끊기므로 * `window.__help542 = ["b02-proj-register", …];` 를 앞에 붙여 네 화면씩 두 번 * 쓰는 것: 없음(주소 이동 · 누르기 · 모달 닫기 · 끝나면 처음 주소로) - * 파일 고침 반영: 셸이 `resources/help/B04/99_임시.md` 를 만들고(글 A) 부름 → 글 B 로 고치고 다시 부름 → + * 파일 고침 반영: 셸이 `A05_EduDetail/guide/B04/99_임시.md` 를 만들고(글 A) 부름 → 글 B 로 고치고 다시 부름 → * `temp` 가 A → B 로 바뀌면 통과 · 뒤에 파일 지움(없으면 temp = null) * 기대 수치: * - pages 8 · 줄마다 btn = 1 · first = true(묶음 맨 왼쪽) · inLeft = true(B02 는 아래 단추 줄) · diff --git a/ui_template/ui_template_help.ts b/ui_template/ui_template_help.ts index 002d0cb36..a337d1271 100644 --- a/ui_template/ui_template_help.ts +++ b/ui_template/ui_template_help.ts @@ -1,7 +1,7 @@ /* ============================================================================= * ui_template_help.ts * [?] 설명서(54-2) — 좌측 패널 아래 단추 묶음 맨 왼쪽 단추 + 모달(왼쪽 차례 · 오른쪽 글). B02~B09 공용. - * 글 = `resources/help/<페이지>/*.md` — 서버가 열 때마다 읽음(파일만 고치면 다음에 열 때 바뀜). + * 글 = `A05_EduDetail/guide/<페이지>/*.md` — 서버가 열 때마다 읽음(파일만 고치면 다음에 열 때 바뀜). * 페이지 = 주소(#/b05-…)의 B0N · 먼저 여는 항목 = 좌측 패널에서 보이는 `[data-help-topic]` 중 마지막 * (지금 연 상자 · 구조물 종류) · 없으면 첫 파일(00_설명서). * 단추 자리 = `.ui-sidebar-actions` 안 `[data-help-row]`(없으면 그 줄 자신)의 맨 앞.