Show HN: Simple org-mode 웹 어댑터

발행: (2026년 2월 17일 오전 01:19 GMT+9)
7 분 소요

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를 추출합니다.
  • 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 파일 탐색.
  • 현재 노트를 강조 표시하는 사이드바 노트 목록.
  • 제목/경로 검색 필터.
  • 노트 섞기.
  • 역링크 수 기준 정렬 (내림차순).
  • 생성일 기준 정렬 (오름차순). 타임스탬프가 없는 노트는 타임스탬프가 있는 노트보다 오래된 것으로 간주됩니다.
  • 현재 노트로 이동 버튼.
  • 오른쪽 사이드바에 현재 노트를 링크하는 노트 목록 표시.
  • 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를 로드하는 것에 의존합니다.
0 조회
Back to Blog

관련 글

더 보기 »