Show HN: Simple org-mode 웹 어댑터
Source: Hacker News
Org Web Adapter
Org 파일을 탐색하고 편집하기 위한 가벼운 로컬 웹 앱입니다.
이 앱은 단일 Python 서버(main.py)와 하나의 HTML 템플릿(templates/index.html), 하나의 스타일시트(static/style.css)로 구현되었습니다. 노트 디렉터리에서 .org 파일을 스캔하고 세 개의 패널 UI를 렌더링합니다.
⚠️ 인증이나 암호화가 제공되지 않으니, 신뢰할 수 있는 네트워크에서만 이 서비스를 실행하십시오. ⚠️
스크린샷
데스크톱
모바일
사용법
- 노트 디렉터리를
notes에 심볼릭 링크합니다. - 원하는 경우
config.yaml에서 바인드 주소와 포트를 편집합니다. - 서버를 실행합니다:
python3 main.py
작동 방식
main.py가 HTTP 서버를 시작합니다.- 각 페이지 요청(
GET /) 시, 노트 디렉터리에서.org파일을 다시 스캔합니다. - 링크/백링크를 해석하고 HTML 조각을 생성합니다.
- 조각들은
templates/index.html의 플레이스홀더에 삽입됩니다:{{NAV_ITEMS}}{{MAIN_CONTENT}}{{BACKLINKS}}
templates/index.html에 있는 브라우저 JavaScript가 클라이언트 측 상호작용(검색, 셔플, 정렬, 현재 항목으로 이동, 테마 전환)을 처리합니다.
Server‑side components (main.py)
File discovery and parsing
scan_org_files(...)는.org파일을 재귀적으로 찾습니다.#+TITLE:에서 제목을,:ID:에서 ID를 추출합니다.
Org link/backlink handling
resolve_link_target(...)는file:...와id:...링크를 지원합니다.find_backlinks(...)는 선택된 노트에 연결된 노트를 계산합니다.build_backlink_counts(...)는 정렬을 위해 백링크 총수를 계산합니다.
Rendering
render_org_to_html(...)는 헤딩(*,**, …)과 단락을 간단한 HTML로 변환합니다.render_line_with_links(...)는 텍스트 내 Org 링크를 해석 가능한 경우 클릭 가능한 앱 링크로 변환합니다.truncate_label(...)는 사이드바 레이블을 32자 이하로…로 잘라냅니다.
Editing
POST /edit은 선택된.org파일을 업데이트하고 상태 플래그와 함께 다시 리다이렉트합니다.
Static files
serve_static(...)는 경로 탐색 방지 보호와 함께static/아래 파일을 제공합니다.
프론트엔드 컴포넌트
templates/index.html
- 기본 레이아웃 마크업.
- 사이드바 컨트롤.
- 필터링, 정렬 및 네비게이션 링크 섞기를 위한 작은 JavaScript 컨트롤러.
- 인라인
$...$렌더링을 위한 MathJax 초기화.
static/style.css
- 데스크톱 3열 그리드와 모바일 스택 레이아웃.
- 노트 리스트와 백링크를 위한 독립 스크롤 영역.
- 모바일 노트 리스트 제한 (스크롤하기 전 약 5개의 노트가 보임).
구성
시작 구성은 기본적으로 config.yaml에서 읽어옵니다.
bind_addr: 바인드할 호스트/IP.bind_port: TCP 포트 (1..65535).
config.yaml가 없을 경우, 기본값은 127.0.0.1:8000입니다.
CLI 플래그 --host와 --port는 구성 값을 덮어쓰며, --config /path/to/config.yaml를 사용하면 다른 파일을 지정할 수 있습니다.
유용한 실행 명령
python3 main.py --dir notes
python3 main.py --host 127.0.0.1 --port 9000
python3 main.py --config ./config.yaml
python3 main.py --no-browser
Features
Note browsing
- 재귀적인
.org파일 탐색. - 현재 노트를 강조 표시하는 사이드바 노트 목록.
- 제목/경로 검색 필터.
Sidebar ordering controls
- 노트 섞기.
- 역링크 수 기준 정렬 (내림차순).
- 생성일 기준 정렬 (오름차순). 타임스탬프가 없는 노트는 타임스탬프가 있는 노트보다 오래된 것으로 간주됩니다.
- 현재 노트로 이동 버튼.
Backlinks
- 오른쪽 사이드바에 현재 노트를 링크하는 노트 목록 표시.
file:및id:링크 해석 모두 지원.
Editing
- 선택한 노트에 대해 미리보기/편집 전환.
- 브라우저에서 디스크로 변경 사항 저장.
- 저장 성공 또는 오류에 대한 인라인 상태 메시지.
Math rendering
$...$구분자를 사용한 MathJax를 통한 인라인 수식 렌더링.
UI behavior
- 라이트/다크 테마 토글 (
localStorage에 지속). - 데스크톱: 독립적인 스크롤 가능한 사이드바.
- 모바일: 자체 스크롤 영역을 가진 노트 목록 제한.
- 사이드바 텍스트는 줄임표와 전체 텍스트 툴팁으로 잘라 표시.
프로젝트 레이아웃
main.py: 서버, 파싱, 렌더링, 라우팅.templates/index.html: 페이지 템플릿 + UI 동작 JavaScript.static/style.css: 스타일링 및 반응형 레이아웃.config.yaml: 바인드 설정.notes/: 노트 디렉터리 (심볼릭 링크일 수 있음).old_notes/: 대체 로컬 노트 스냅샷.
Limitations
- 전체 Org 파서가 아니며, 렌더링은 의도적으로 단순합니다.
- 노트는 각 요청 시마다 다시 스캔됩니다(단순하고 최신이지만, 방대한 노트 집합에 최적화되어 있지는 않습니다).
- 수학 렌더링은 CDN에서 MathJax를 로드하는 것에 의존합니다.

