윤익희: 개인위키 빌더
윤익희 공식사이트 . English

아이디어

윤익희의 다음 버전을 개발하면서 생각나는 아이디어를 정리한다.

1   템플릿으로 페이지 생성

구현완료: $preprocess_text 루틴을 u.cfg 안에 정의하는 방식

템플릿을 지정해서 페이지를 생성할 수 있게 하자.

2   페이지 소스를 저장하기 전에 변경

페이지 소스를 저장하기 바로 전에 소스를 조작할 수 있게 하자.

3   페이지 소스 안에서 다운로드 가능한 파일 만들기

---를 이용해서 생성한 <pre> 블럭을 다운로드 가능한 파일로 만들자.

4   섹션에디트

구현완료: 메인 파일을 파싱하는 도중 헤더를 만나면 줄번호를 이용해서 시작줄부터 몇줄 편집하라는 식으로 구현했다. 꼭 섹션이 아니라도 부분편집이 가능하다. 하지만 복잡한 방법으로 헤더를 출력할 경우 문제가 생길 수 있다. 그리고 파일의 처음부터 부분편집 마지막줄까지 파싱을 하기 때문에 시작줄 이전의 명령들도 그대로 적용된다.

한 섹션만 에디트할 수 있게 하자. #regex가 존재할 경우 문서의 처음부터 섹션까지 파싱한 다음 해당 섹션만 출력해야 한다.

5   풋노트

풋노트를 구현하자. 텍스트를 모아서 원하는 위치에 출력하는 방법을 고려해 보자. 예를 들어 ((footnotes.a 노트))라고 하면 footnotes라는 변수에 a라는 id의 노트를 생성한다. 나중에 ((footnotes))를 입력해서 footnotes에 모은 노트를 출력한다. ((a 노트))라고만 입력하면 내부변수에 모은 후 문서의 마지막에 출력하자. 이 경우 (())와 같이 입력해서 위치를 바꿀 수도 있겠다.

6   여러개의 파일 업로드

두 개 이상의 파일을 한 번에 업로드할 수 있게 하자.

7   쓰레기통

삭제한 페이지의 파일들을 바로 지워버리지 않고 쓰레기통으로 옮긴다. .trash 또는 .deleted라는 폴더로 옮기자.

8   커맨드라인

커맨드라인에서 html의 생성이 가능하게 만들어서 txt 파일을 직접 수정할 수 있게 하자. 웹에서 실행할 경우 필요한 환경변수가 없어서 이 기능은 구현하지 않기로 했다.

9   자료구조

현재는 각 페이지마다 .html, .txt, .txt.v 파일들과 업로드된 파일이 있을 경우 같은 이름의 디렉토리를 만들고 페이지/파일이름 이런 식으로 링크를 하고 있다. 링크를 걸 때는 http://hostname/page.html 처럼 .html을 입력해야 된다. .htaccess를 이용해서 .html을 제거한 http://hostname/page처럼 링크를 걸 수는 있지만 디렉토리 하이어아키를 고려하면 페이지의 디렉토리를 가리키기 때문에 그 페이지 안에서 다시 페이지/파일이름 식의 링크는 위계상 말이 안 된다.

페이지마다 디렉토리를 만들고 점으로 시작하는 숨겨진 파일 .txt, .txt.v에 자료를 저장하고 index.html 파일을 만들어서 http://hostname/page 링크를 지원하고 그 안에서는 파일이름 식의 링크를 걸 수도 있겠다. 이 경우 문제는 다른 페이지를 링크 걸 때 ../페이지 또는 /페이지 식의 링크를 걸어야 한다. 페이지.html 또는 페이지 보다 안 좋은가? ../페이지는 몰라도 /페이지는 괜찮아 보인다. 문제는 페이지 내에서 업로드된 파일로의 링크와 다른 페이지로의 링크를 구분할 방법이 필요하게 된다.

업로드된 파일을 별도의 디렉토리를 만들어 저장하지 않고 그냥 루트에 저장할 경우 다른 페이지에서 같은 이름의 파일을 업로드할 경우 문제가 생긴다.

이런 저런 문제점들을 생각했을 때 지금의 자료구조가 가장 적당한 것 같다. 조금 더 잘 하자면 .txt와 .txt.v 파일들을 .meta 쯤 되는 디렉토리에 모으는 정도가 되겠다.

일단 자료구조는 그대로 두자.

10   parse_line의 모듈화

구현완료

현재 parse_line에 문법을 추가하기 위해서는 전체를 복사한 다음 적당한 위치에 구현을 해야 한다. 이를 해결할 방법이 필요하다.

11   """와 ---를 모아서 처리하기

구현완료

현재는 텍스트를 마칠 때 닫지 않아도 자동으로 닫아 주는데 그러지 말고 닫지 않으면 일반텍스트로 출력? 다른 code block, syntax block, child block은? 후자 블럭은 닫지 않으면 사라진다. 일관성을 유지하자.

모든 블럭을 자동으로 닫게 구현했다.

12   비문법

구현완료

"""+를 ---+와 비슷하게 사용해서 문법이 적용되지 않는 블럭을 구현하자.

13   섹션, 플로트 번호매기기

구현완료

현재 자바스크립트로 구현되어 있는 섹션, 플로트 번호매기기를 스크립트로 구현하자. 자바스크립트를 지원하지 않는 브라우저 지원.

14   버전파일

구현완료

버전파일을 버전 1부터 쓰도록 하자.

15   사용자 정보를 AJAX로 읽기

구현완료

정적인 HTML 파일 안에 자바스크립트를 이용해서 동적인 부분을 구현하자.

16   비밀번호

구현완료

처음 새로운 사용자를 추가하거나 비밀번호를 잊어 버렸을 경우 비밀번호를 초기화할 수 있는 일시적인 링크를 이메일로 보낸다. 사용자는 이 링크를 이용해서 비밀번호를 다시 지정할 수 있다.

17   세션파일

구현완료

패스워드 해시를 쿠키에 저장하는 대신 세션 아이디를 저장하고 서버에 .sessions 파일을 만들어 세션 아이디를 관리한다.

18   버전파일

구현완료

새로운 버전파일에는 사용자 ID와 수정시각을 저장하자.

19   사용자관리

구현완료

사용자 추가시 관리자인지 일반유저인지를 지정하게 하고 이메일을 추가하자.

20   통제된 사이트

구현완료

$SECURED_SITE=1을 설정하고 다음의 .htaccess 파일을 생성하면 전체사이트의 페이지들을 u.cgi가 처리하게 된다. HTML 파일을 서비스하는 대신 u.cgi가 HTML 파일을 출력해서 보여 주게 되며 로그인한 사용자만 접근 가능하다.

.htaccess

RewriteEngine On
RewriteBase /

RewriteRule ^$ u.cgi [R,L]
RewriteRule ^([^/]*)\.html$ u.cgi/$1 [R,L]
RewriteRule ^(u\.cgi/.*)\.html$ $1 [R,L]

21   위키권한

구현완료

#!wiki를 통한 위키

  • 읽기 공개: 로그인 없이 읽기가능 (기본설정)
  • 읽기 비공개: 로그인 후에만 읽기가능
    • 쓰기 공개: 로그인 없이 쓰기는 가능하나 읽기가 불가능하다. 쓴 후에 읽을 수가 없다. 비공개적으로 피드백을 주는 용도로 사용 가능하지 않을까?
    • 쓰기 비공개: 읽기와 쓰기 모두 비공개
      • 비위키페이지 읽기 공개: $SECURED_SITE, .htaccess를 통해 구현완료
      • 비위키페이지 읽기 비공개
  • 쓰기 공개: 로그인 없이 쓰기가능 (기본설정)
  • 쓰기 비공개: 로그인 후에만 쓰기가능

$SECURED_SITE와 .htaccess를 이용해서 통제된 사이트를 만들면 읽기 쓰기 모두 비공개로 운영이 가능하다. 괄호 안은 비관리자인 사용자의 통제단계. 비위키페이지의 쓰기는 무조건 관리자만 가능하다.

읽기 공개읽기 비공개
쓰기 공개(1) 기본설정(2) 쓰기는 공개적으로 가능하나 읽을 수는 없다. 비공개 피드백 용도?
쓰기 비공개(3) 로그인한 사용자만 쓸 수 있으나 아무나 읽을 수 있다.(4) 비위키페이지 읽기 공개, (5) 비위키페이지 읽기 비공개
  • (1): 기본설정
  • (2): 필요할까? 말이 되나?
  • (3): $WIKI_EDIT_REQUIRES_LOGIN (WERL)
  • (4): $WIKI_READ_REQUIRES_LOGIN (WRRL)
  • (5): 위키와 비위키페이지의 쓰기권한은 편집화면을 열 때 어차피 파일을 읽어 들이기 때문에 괜찮지만 읽기권한까지 제한하려면 HTML을 출력하기 전 소스파일의 첫번째 줄을 읽은 후 공개여부를 결정해야 한다. Diff의 경우는 소스파일을 읽기 때문에 괜찮지만 search의 경우 단순히 HTML 파일의 검색에 그치지 않고 소스파일을 읽어서 검색여부를 결정하는 단계가 필요하다.
WRRL=0WRRL=1
WERL=0(1)(2)
WERL=1(3)(4,5)

로그인 하지 않은 사용자에게 위키와 비위키페이지의 읽기권한을 다르게 하는 것은 쉽지 않아 보인다. 우선 유니키의 주목적이 정적인 HTML 파일을 생성해 놓고 바로 웹서버를 통해서 서비스하는 것이기 때문에 페이지의 성격에 따라서 HTML 파일을 바로 보여주거나 유니키 스크립트가 처리하게 하는 것은 웹서버의 몫이다. 하지만 아파치의 경우 파일의 내용에 따라서 RewriteRule을 다르게 적용할 수 있지는 않아 보인다. 그 결과 로그인 안 한 사용자가 위키/비위키페이지 모두 볼 수 있거나 모두 볼 수 없거나만 가능하다. 즉 (1)과 (3)은 모두 비위키페이지까지 공개를 해야 한다. 다시 말하면 $WIKI_READ_REQUIRES_LOGIN과 $NONWIKI_READ_REQUIRES_LOGIN 두 가지 설정이 필요없으며 $READ_REQUIRES_LOGIN으로도 충분하다.

쓰기권한의 경우 비위키페이지는 관리자만 쓰기권한이 있기 때문에 설정이 따로 필요없지만 위키페이지는 $WIKI_EDIT_REQUIRES_LOGIN이 필요하다.

지금 구현된 $SECURED_SITE는 $READ_REQUIRES_LOGIN과 $WIKI_EDIT_REQUIRES_LOGIN의 조합으로 구현이 가능하기 때문에 새로운 설정으로 대체가 가능하다.

RRL=0RRL=1
WERL=0(1)(2)
WERL=1(3)(4,5)

이제 (5)를 구현하기 위해서 $READ_REQUIRES_LOGIN=2를 설정하면 로그인한 사용자는 위키페이지만 읽을 수 있고 비위키페이지는 읽을 수 없다.

최종권한표

RRL=0RRL=1RRL=2
WERL=0(1)(2)(6) 관리자만 비위키 읽기
WERL=1(3)(4)(5) 관리자만 비위키 읽기

22   문법

22.1   헤더라인

구현완료

현재

= 1 제목
 = 1.1 제목

본문이다.

  = 1.1.1 제목

본문이 헤더보다 앞에 있어서 헤더를 찾기 힘들고 헤더가 두드러지지 않는다.

도쿠위키

=== 제목 ===
이건 어떤가?

단점은 오른쪽의 매칭되는 부분도 타이핑하거나 복사해야 한다. 레벨을 바꿀 때도 일이 조금 더 많다. 보기에는 더 좋은 것 같다. 만약 이 방식을 택한다면 =이 더 많은 헤더가 눈에 더 잘 띄기는 한다.

= 1 제목
== 1.1 제목

본문이다.

=== 1.1.1 제목

=심볼을 연속적으로 써서 본문과 어울리고 헤더를 찾기 쉽다. 다른 위키처럼 오른쪽에도 =심볼을 넣지 않은 이유는 타이핑을 줄이기 위해서이다.

새버전 2

=== 1 제목
== 1.1 제목
= 1.1.1 제목

도쿠위키 스타일로 =심볼 개수를 바꾼다. 이 방법은 헤더라인의 레벨을 추가할 경우 페이지소스를 바꿔야 하는 단점이 있어서 안 좋은 것 같다.

22.2   글자체

구현완료

현재

``굵은 글씨``
''기운 글씨''
``''굵고 기운 글씨''``
""타자체""
**굵은 글씨**
//기운 글씨//
**//굵고 기운 글씨//**
''타자체''
!!형광펜!!

도쿠위키 문법으로 더 눈에 잘 띄고 더 직관적인 것으로 판단된다.

22.3   리스트

구현완료

현재

- 하나
- 둘
 - 둘의 하나
  - 둘 하나의 하나

리스트 안에 문단
-
본문

새버전

- 하나
- 둘
 - 둘의 하나
  - 둘 하나의 하나
    리스트 안에 같은 문장
    ...
    같은 리스트
본문

22.4   링크

구현완료

현재

[page. 페이지] 또는 [page.]

페이지 파일명에 공백을 허용하지 않고 [와 ]를 한번씩 만 사용해서 [, ]를 링크 이외에 자주 사용할 수 있는 환경에서 불편함이 크다. 또한 페이지명 뒤에 점을 찍어야 했다. 이는 디렉토리 지정시 점을 찍지 않기 위함이다.

새버전

[[page name|페이지]] 또는 [[page name]]

페이지 파일명에 공백을 허용하고 [와 ]를 두번 겹쳐 쓴다. 디렉토리 지정시 directory/와 같이 /를 붙여서 해결한다.

23   페이지 이름

구현완료

페이지 이름에서 공백을 포기하면 위의 링크에서 |의 사용을 피할 수 있다. 페이지 이름을 도쿠위키처럼 모두 소문자로 하고 공백을 포함한 특수문자는 언더스코어로 바꾸는 것도 좋은 생각인 것 같다. 대소문자를 모두 지원해 봤자 페이지 작명시 고민만 더 할 뿐이다. 한편, 선택의 관점에서 보면 모두 지원하게 한 다음 사용자가 선택할 수 있게 하는 것도 한 방법이다.

http://geni.isnew.info에서 uniqki 사이트를 운용하면서 가장 불편했던 점은 페이지 이름을 모두 소문자로 일치했기 때문에 내용 중에 대문자로 쓸 일이 있을 경우 페이지명과는 별도로 새 이름을 늘 지정해야만 했던 점이다. 이를 해결하는 방법은 두 가지이다. 대문자로 쓸 단어는 페이지명도 대문자로 하거나 모든 페이지명을 소문자로 강제변환하는 방법이 있다. 전자의 경우 일반명사 사용시 불편한 점이 있을 것이다. 예를 들어 computer와 Computer. 후자의 경우는 사용자의 대소문자 결정권을 박탈하게 된다. 이것이 문제가 될까? 페이지명을 GRASS, grass, Grass와 같이 다양한 대소문자의 조합으로 만들 필요가 있을까?

현재로서는 가장 확장성이 높은 파서를 구현하는 것보다 내가 쓰기에 가장 편한 파서를 구현하는 쪽이 더 합리적인 것 같다. 그런 다음 기본 파서를 바꿀 수 있게 하는 매카니즘을 구현하는게 옳은 방법인 것 같다.

24   설치

구현완료

현재는 설치를 통해서 u.cgi에서 텔플릿파일, 컨피그 파일등을 생성한 후에야 사용할 수 있다. 이를 바꿔서 커스터마이징이 필요없을 경우 설치를 하지 않고서 u.cgi 파일 하나만으로도 사용 가능하게 만들자.

커스터마이즈하고 싶은 부분만 설치할 수 있게 구현했다.