카테고리 보관물: 컴퓨터

std::nothrow

Reference : http://www.cprogramming.com/tips/tip/cincrement-new-does-not-return-0-on-failure

C++ new는 할당실패시 bad_alloc exception을 던진다.
매번 try-catch 하기 귀찮으니까, malloc()처럼 오류상황에서 0을 리턴하게 만들고 싶은 경우, 다음과 같이 고친다.

#include <new>
...
type_t *ptr = new (std::nothrow) type_t[size];
...

SVN to git 이전하기, 윈도우 환경을 기준으로.

Reference: http://john.albin.net/git/convert-subversion-to-git

한동안 개발에 SVN을 사용하다가, 최근들어 git을 사용하면서 옮겨가게 되었다.

SVN 대비 git 장점.

1. 저장소(의 완전한 복사본)가 로컬에 있어서 네트워크 접속이 필요없고 속도가 빠르다.
로컬에서 작업 끝나면? 브랜치 정리하고 로컬->서버로 밀어넣던지(push), 아니면 서버에서 로컬 데이터를 당겨가도록 요구(pull request)할 수도 있다.

2. 저장소 사본을 내가 들고 있으므로 브랜치 작업이 자유롭다. 그냥 브랜치 따서 쓰면 된다. 로컬 저장소는 온전히 내 소유이기 때문.
반면 SVN은 서버에 커밋권한이 없으면 브랜치 따는게 불가능하다. 물론 로컬 저장소를 만들면 되지만… 서버와 동기화가 귀찮아진다.

3. 브랜치 사이에 merge 관리가 쉽다.
SVN에서는 내가 어디에서 어디까지 merge했는지가 명확하지 않지만(기록은 된다), git에서는 어느 커밋과 어느 커밋을 merge했는지 명확하게 기록이 남는다.
애당초 git 구조상 merge 이력이 남을 수밖에 없다. 굳이 안 남길 수도 있지만, 다른 사람 – 내지는 두 달 후의 자신에게서 욕을 좀 먹을 것이다.

그 외에도 개념이나 장단점은 다른데에도 자료가 많이 있으니까 넘어가기로 하고.
여하튼 이번 포스팅에서는 SVN으로 구성된 저장소를 git으로 마이그레이션 하는 방법을 소개한다. 윈도우 환경을 기준으로.

굳이 마이그레이션을 강조하는 이유는, 절차를 완료한 후에는 SVN 저장소를 더이상 사용하지 않고 git으로 버전관리를 할 것이기 때문.
git-svn은 SVN을 리모트 서버로, 로컬에서는 git을 사용하는 것을 전제로 만들어져 있지만, 이중 뻘짓은 사양하기로 하자.

이 글을 읽는 사람이 SVN, git의 사용법은 알고있다고 가정하겠다. 윈도우 콘솔 명령어도.

1. 마이그레이션 할 SVN 저장소를 준비한다.

작업도중 IDPW를 지정할 수는 있지만, 가능하다면 Everyone에게 읽기권한은 주는 것이 좋겠다.

2. SVN 저장소의 Log를 보면서, committers list를 준비한다.

링크된 글에서는 SVN 작업사본에서 쉘 스크립트 명령어를 이용해서 committer list를 뽑아낸 모양이지만, 윈도우에서는 못 써먹는다.
나는 그냥 손으로 만들었다. 서버 committer가 10명이 채 안돼기 때문에 굳이 쉘 스크립트 짤 필요도 없었고.

committer list는 일반 텍스트 파일로 저장되며, 다음과 같은 형태를 가진다. 파일이름은 편의상 svn_authors.txt 로 저장하자.

[SVN USERNAME] = [GIT USERNAME] <[email protected]>
committer001 = John Doe <[email protected]>
committer002 = Jane Doe <[email protected]>

3. SourceTree를 설치한다.

http://www.sourcetreeapp.com/

git이 리눅스 커널 개발을 위하여 설계된 물건인지라, 윈도우 환경에서 git쓰기는 꽤나 지저분하다.
애당초 이건 모든 (리눅스를 기반으로 개발된) 오픈소스 어플리케이션의 문제이기도 하지만.

여튼 윈도우에서 git을 편하게 사용하려면 프론트엔드를 써야 하는데, 그나마 현 시점에서 안정적이고 깔끔한게 SourceTree인 것 같다.
그래프 방식으로 branch history를 쭉 보여주는데 이만한 툴이 없는 듯. 굳이 윈도우에서 GUI환경을 포기할 이유가 있을까.
(GitHub 클라이언트는 History View가 안 나오는거같다.)

git 라이브러리는 SourceTree 내장으로 설치하면 된다. 18. Nov. 2013 현재 git 버전은 1.8.3 이고 이 글도 해당 버전을 기준으로 설명한다.
SourceTree 설치가 완료되면 툴박스에서 Terminal 버튼을 눌러 git 터미널을 열고, 작업할 수 있는 임시폴더로 이동한다. MinGW 환경으로 실행될거다 아마.

4. git-svn으로 SVN 저장소를 git 저장소로 변환

명령어는 다음과 같다.

git svn clone http://svn_server/project_name/ –no-metadata -A svn_authors.txt -T trunk -b branches -t tags ./temp

옵션을 풀어 설명하자면 다음과 같다.

git svn clone : SVN 서버에서 복제해서 git 저장소를 생성한다. 밑에서 설명하겠지만 clone = init + fetch 이다.
http://svn_server/project_name/ : 프로젝트 최상위 폴더. 통상적으로 이 밑에 trunk, branches, tags 폴더가 위치한다.
–no-metadata : git-SVN 연동을 위한 메타데이터를 생성하지 않는다. 마이그레이션을 목적으로 하므로 메타데이터를 생략하는 것.
-A svn_authors.txt : 3번에서 만든 committers list
-T trunk -b branches -t tags : 트렁크, 브랜치, 태그 폴더명. 참고로 위에 표시된 것과 같은 표준 사양인 경우 –stdlayout 으로 대체 가능.
./temp : git 저장소가 만들어질 폴더이름

5. 인내심을 가지고 기다린다.

변환 과정은 짤없이 하나의 리비전을 체크아웃 -> git으로 커밋 과정을 반복하는 것이므로 시간이 꽤 걸린다.
리비전이 1천 단위를 넘어간다면 2~3시간 이상 걸릴 수도 있다. r50 정도 되는 저장소를 변환하는데 2분 정도 걸린 것 같다.

폴더구조가 이상하게 꼬여있지 않고 브랜치/태그를 svn copy로 정확하게 만들었다면 그럭저럭 잘 인식해서 브랜치를 만들어 준다.
브랜치 병합 또한, svn-props에 merge 정보가 기록되어 있다면 이를 반영해서 merge commit을 생성해 준다.
정보가 없으면? git에서 merge commit으로 기록은 안 된다. 뭐 트렁크에 병합된건 사실이니까 git에서도 데이터는 남겠지만 추적이 안 될 뿐이다.

변환 도중 알 수 없는 committer가 발견되면 그 시점에서 변환이 중단된다. committer list를 업데이트해야 한다.
겪어보지는 않았지만(말했다시피 서버에 커미터가 10명이 채 안된다), 중단된 시점 이후로는 git svn fetch 명령어로 이어서 작업이 가능할거다.

6. 브랜치/태그 정리

시간이 흘러 작업이 완료되면, SVN 저장소는 git 저장소로 변환된 것이며 더 이상 SVN 저장소는 필요가 없다.
이제 SourceTree로 마이그레이션 된 git 저장소를 열어보자. SVN trunk에 해당하는 git master 브랜치가 체크아웃 되어 있을 것이다.

문제는 브랜치, 그리고 태그. 우선 브랜치부터 해결하자.
git 저장소로 변환되긴 했지만, SVN 브랜치는 기본적으로 로컬에 체크아웃 되어 있지 않다. 따라서 수동으로 한 번씩 체크아웃을 해 줘야 한다.

그 다음은 태그. SVN에서는 브랜치나 태그나 원리만 놓고보면 그냥 svn copy 명령을 수행한 것일 뿐이다. 단지 특수한 폴더에 넣어둔 것일 뿐.
따라서 각각의 SVN 태그도 git 입장에서 보자면 그냥 하나의 (delta가 없는) 브랜치 커밋으로 취급될 뿐이다. 물론 브랜치 이름 대신 태그가 달려있지만.
이를 깔끔하게 정리해준다. 필요한 커밋에 git 태그를 달아주고, 불필요하게 생성된 SVN 태그용 브랜치를 삭제한다.

7. 저장소 재복사

이렇게 정리한 저장소는 아직 SVN 관련 옵션이 남아있어서 지저분할 수 있다.
그냥 써도 좋지만 좀 더 깔끔하게 쓰고 싶은 경우, 아니면 다시 서버에 올리려는 경우는 저장소를 다시 복사해야 한다.

작업 자체는 간단하다. SourceTree 툴박스에서 Clone 을 선택하고, Source Path에 마이그레이션 된 git 저장소 폴더를 지정하면 된다.
Clone 작업이 완료되면 이제 SVN 이력이 깨끗하게 정리된 git 로컬 저장소를 얻게 된다.

뻘짓1. 특정 revision 무시하기

변환을 하다보면, SVN에서 특정 revision을 무시해야 하는 경우가 생긴다. 보통은 잘못된 커밋을 reverse-merge한 경우로, 여러 개의 커밋이 상쇄되어 없던게 되는 경우.

예를 들어

예를 들어 SVN에서 브랜치를 삭제하고 다시 생성한 경우. 아직 git에서 인식을 못한다.

브랜치 생성을 r21에서 해야 하는데 r20에서 잘못 한 경우를 생각해 보자. 그래서 브랜치를 지우고(r23), 올바르게 다시 생성했다(r24).
그냥 r21을 merge하면 되지 않아? 라고 생각할 수도 있겠지만, 커밋로그를 바꿀 수도 없는 노릇이니까 그냥 넘어가자.

이런 경우, 사용자가 의도하는 git history는 다음과 같을 것이다.

근데 정작 git svn으로 변환해 보면, 브랜치 삭제를 제대로 인식 못하고 다음 그림과 같은 결과물이 나오게 된다.

불필요한 r22가 생성된 것도 있고 r24가 merge로 취급되어 히스토리가 복잡하게 꼬이게 된다. 트래킹 되니까 merge에는 문제없잖아-라고 생각하면 뭐 할 말은 없겠다만.

접기

여하튼, 위와 같은 경우도 있고 그 외에 다양한 사유로 특정 revision을 git으로 보내고 싶지 않은 경우가 발생한다.

아쉽지만, 아직 git-svn 명령줄에서 “SVN의 특정 revision을 제외하고 fetch하는” 옵션은 없다. 반대로 말하자면, “SVN의 특정 revision만 fetch하는” 옵션은 있다.
위의 예시를 들자면, r22, r23을 삭제해야 하는 경우인데 그렇다면 BASE:r21, 그리고 r24:HEAD를 fetch하면 되는 것.

5번 과정에서 명령어에 옵션이 추가된다.

git svn clone (blahblah) -t tags -r BASE:21 ./temp
git svn fetch -r 24:HEAD

명령이 둘로 나뉘고, 옵션이 하나 추가되었다.

git svn fetch: 정확하게는 이 명령어가 svn으로부터 데이터를 가져오도록 하는 명령이다. clone = init + fetch 인 축약 명령.
-r START:END : START에서 END까지의 리비전만 가져오도록 제한하는 옵션. START와 END의 리비전을 포함한다.

즉, 두 번에 걸쳐서 데이터를 가져오게 하는 것.
첫 번째 명령에서 BASE~r21까지의 리비전을 가져오고, fetch로 r24~HEAD 리비전을 가져옴으로써 불필요한 r22, r23을 생략하게 된다.

필요한 경우 더 잘게 쪼개서 여러 개의 불필요한 리비전을 생략할 수도 있다. 응용은 직접. 물론 신중하게 잘 사용해야 한다.
잘못 사용하는 경우 커밋 순서나 브랜치가 꼬이게 되며, 최악의 경우 git 저장소를 삭제하고 처음부터 다시 작업해야 할 수도 있다.

뻘짓 2. SVN 저장소 구조가 이상한 경우

Reference : http://www.jeremyjohnstone.com/blog/2010-01-14-using-git-svn-with-non-standard-subversion-repository-layouts.html

보통 SVN 저장소는 안정화 배포버전인 trunk, 문제 해결이나 개발용 사본인 branches, 과거의 특정 버전을 손쉽게 찾아보기 위한 tags 로 구성된다.
형상관리가 10년이 넘도록 사용되면서 그 효율성을 인정받아서 자연스럽게 굳어진 형태이지만, 꼭 저장소가 이렇게 구성되라는 법은 없다.
(SVN 저장소는 저런거를 따로 관리해 주지 않고 그냥 통째로 형상을 기억한다.)

프로젝트 여러 개가 저장소를 공유하는 경우

프로젝트 여러 개가 저장소를 공유하는 경우가 대표적인데, 보통은 저장소 루트에 프로젝트 폴더를 생성하고 그 밑에 stdlayout을 생성하게 된다.
그러니까 아래같은 경우. 이 때는 그냥 full 주소를 쓰면 된다. –prefix=PROJECTxx/ 옵션을 써도 되지만, 이 경우 마지막 백슬래시를 꼭 붙여줘야 한다.
git으로 마이그레이션 후, commonlib를 서브프로젝트로 등록하는 것은 이 글의 범위를 벗어나므로 생략하도록 한다.

/PROJECTxx/trunk
/PROJECTxx/branches
/PROJECTxx/tags

/PROJECTyy/trunk
/PROJECTyy/branches
/PROJECTyy/tags

/commonlib/trunk
/commonlib/branches
/commonlib/tags

접기

문제는 저장소가 저런 stdlyaout을 벗어나는 경우.

잘못된 레이아웃의 예시

링크 건 참조사이트는 이런 구조 때문에 엿을 먹었다고 한다.

trunk/PROJECTxx
trunk/PROJECTyy
trunk/commonlib

branches/PROJECTxx
branches/PROJECTyy
branches/commonlib

tags/PROJECTxx
tags/PROJECTyy
tags/commonlib

그 외에 내가 겪은 케이스는, 막 SVN 도입당시에 생성된 repo라서 아예 stdlayout 구조 없이 썼던 프로젝트가 있다.
따로 trunk/branches/tags를 구분하지 않고 마일스톤 달성시점마다 새롭게 브랜치를 따고, 기존 브랜치는 개발 중단하는 식으로 사용한 것.

/PROJECT
/PROJECT_rev2
/PROJECT_rev3

접기

여하튼 이런 경우는 git에서 브랜치를 파악하지 못하므로, 사용자가 직접 브랜치를 명명해 줘야 한다. 우선 git-svn 저장소부터 만들자.

git svn init http://svn_server/project_name/ –no-metadata -T PROJECT ./temp

이렇게 하면 ./temp 폴더에 비어 있는 git 저장소가 만들어진다. 이제 ./temp/.git/config 파일을 텍스트 편집기로 연다.

(생략)
[svn-remote “svn”]
noMetadata = 1
url = http://svn_server/project_name
fetch = PROJECT:refs/remotes/trunk

fetch 뒤쪽에 다른 브랜치 경로들을 추가해준다.

(생략)
[svn-remote “svn”]
noMetadata = 1
url = http://svn_server/project_name
fetch = PROJECT:refs/remotes/trunk
fetch = PROJECT_REV2:refs/remotes/rev2
fetch = PROJECT_REV3:refs/remotes/rev3

이렇게 하면 각각의 SVN branches가 git branches로 온전히 인식된다. 이제 fetch하면 된다.

git svn fetch -A svn_authors.txt

뻘짓 3. 비어 있는 commit 제거하기

SVN에서 브랜치나 태그를 따는 커밋은 파일 구성에는 변화가 없는 커밋이다. (다시 말하지만, SVN에서 브랜치, 태그는 단순한 cheap copy일 뿐이다.)
git으로 변환된 커밋로그를 보면, (아마도 create branch for issue #nnnn 따위의) 커밋 메시지는 남아있지만 정작 파일 변경점은 전혀 없는 커밋이 존재하게 된다.

물론 이것도 지울 수 있다. git이 재미있는 점이 과거 커밋도 강제로 수정 가능하다는 점.
각각의 커밋이 독자적으로 완벽한 하나의 형상으로 존재하며, 커밋간의 관계를 포인터로만 구성하기 때문에 이런 뻘짓이 가능하다.

저장소에서 터미널을 열고 다음 명령을 수행하면 파일 변경점이 없는 커밋을 찾아서 몽땅 삭제해 준다.
단, 부모 커밋이 딱 하나인 경우에만 삭제 가능하다. 부모가 둘 이상인 merge 커밋이나 0개인 Initial 커밋은 삭제 안 된다.

git filter-branch –prune-empty — –all

git filter-branch: 브랜치에 필터를 적용한다.
–prune-empty : 빈 커밋을 잘라낸다. (prune 뜻이 가지치기 한다는 뜻임)
— –all : 모든 커밋에 적용하도록 한다. 이거 안 쓰면 다른 브랜치에는 변경사항이 적용 안 되므로 커밋 그래프가 아주 형이상학적으로 바뀌게 된다.

사실 이런 “과거 커밋을 건드는” 명령은 잘못 쓰면 저장소 망가뜨리기 일쑤다. 거의 모든 커밋의 SHA-1 해시가 바뀌므로 히스토리가 꼬이거나 할 가능성이 높다.
특히 태그같은 경우는 거의 전부 새로 작업해 줘야 할거다. 어짜피 SVN 태그를 옮겨오려면 git에서 새로 만들어야 하긴 하지만.

아, SHA-1 해시가 모두 바뀐다고 하였다. 따라서 다른사람하고 공유를 시작한 저장소에서는 절대 쓰지 마라.

옛날 댓글 틀린정보

뭐 이런 댓글이 달렸다. 본문과는 전혀 상관없는 글이라서 지금은 삭제한 상태지만.

2년도 더 된 옛날 댓글이라 어디에 달았는지 기억도 가물가물하고 한데, 내용만 보면 아마 내가 쓴게 맞긴 한 모양이다.
근데 저거 반쯤은 뻘소리고 -_- 수업시간에 교수님이 잡담 비슷하게 한 내용으로 기억하는데 왜 저렇게 싸지르고 다닌거지?

프레임레이트 줄인건 음성 캐리어 쪽에서 간섭 때문이라고 한다. 덕분에 1000/1001 이라는 아주 지랄맞은 factor를 곱해줬는데…
이게 디지털 쪽 넘어와서는 매우 성가신 것으로 작용하게 되었다. 그래서 요즘은 다시 30 또는 60프레임으로 올리려고 한다나 뭐라나.

근데 본문과는 전혀 상관없는 옛날 댓글을 그대로 복붙해서 돌아오는걸 보면 기분이 묘하다.
방명록에 주소만 걸어주는게 더 나을번 봤는데.

썬더버드 기본 정렬방식 변경

SRC: Change the default sorting order in Thunderbird

썬더버드에서 메일함의 기본 정렬방식은 “수신한 날짜, 오름차순” 정렬이다.
오름차순 정렬인 탓에 오래된 메일이 목록 맨 위에 있고, 새 메일은 맨 밑으로 들어가게 된다.

모든 폴더를 돌아가면서 일일이 손으로 설정하기 귀찮으니까, 썬더버드 설치하자마자 기본값을 바꿔주면 된다. 요즘 다 IMAP 쓰니까 뭐…

1. 도구 -> 설정, 그리고 아래 그림을 따라간다.

썬더버드 설정창

2. 고급 기능 사용 동의를 누른다.

3. 검색 창에 mailnews.default 를 입력한다. 썬더버드 17.0 기준으로 6개 항목이 뜨게 된다.

about:config

4. mailnews.default_sort_order, mailnews.default_sort_type 값을 적당히 바꿔준다.

입력 가능한 값은 다음과 같다.

mailnews.default_sort_order
1 = Ascending (오름차순: 오래된 것이 가장 위)
2 = Descending (내림차순: 오래된 것이 가장 아래)

mailnews.default_sort_type
17(0x11) = None
18(0x12) = Date
19(0x13) = Subject
20(0x14) = Author
21(0x15) = ID
22(0x16) = Thread
23(0x17) = Priority
24(0x18) = Status
25(0x19) = Size
26(0x1A) = Flagged
27(0x1B) = Unread
28(0x1C) = Recipient
29(0x1D) = Location
30(0x1E) = Label
31(0x1F) = Junk Status
32(0x20) = Attachments
33(0x21) = Account
34(0x22) = Custom
35(0x23) = Received

맥 OS X 설치파일 다운로드 방법

윈도우는 설치파일을 iso 표준 이미지로 배포하지만, 맥은 전용 설치프로그램을 통하여 배포한다. 맥OS의 실제 설치파일은 설치프로그램 내부에 installESD.dmg 파일로 저장되며, 복구 모드에서 온라인으로 다운로드가 가능하므로 대부분의 경우는 굳이 설치파일을 다운로드 받아서 DVD나 플래시메모리에 저장할 필요는 없다.

반면 재설치를 자주 하거나 인터넷 연결이 원활하지 않은 곳이라면, 설치 때마다 매 번 다운로드 받아야 하니 여간 불편한 것이 아니다. 4.7GB 정도로 국내에서 인터넷 접속이 원활한 곳에서도 한 번 받는데 1시간 정도 걸린다. installESD를 가지고 있다면, 이런 경우에 대비하여 설치 미디어를 제작할 수 있다. 앱스토어를 통해 이전 버전에서 맥OS를 업그레이드한 경우, 설치프로그램 컨텐츠를 뒤지면 손쉽게 installESD를 추출해 낼 수 있지만, 맥 OS가 사전 탑재된 맥을 구매하는 경우(내가 이 경우)는 마땅히 구할 수 있는 방법이 없는데, 꽤 간단하게 다운로드할 수 있는 방법을 소개한 글이 있어서 옮겨 적는다.

원문 : http://hints.macworld.com/article.php?story=20110831105634716

0. 준비물
– 16GB 이상의 USB 메모리 스틱 또는 외장 하드디스크. 내용물이 모두 삭제되므로 미리 백업해 둔다.
– 리커버리 파티션이 온전히 남아있는 맥 시스템.

1. 터미널을 열고, 파티션 구조를 확인한다. 아마 다음과 유사하게 뜰 것이다.

$ diskutil list
/dev/disk0
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *121.3 GB   disk0
   1:                        EFI                         209.7 MB   disk0s1
   2:                  Apple_HFS Mac OS X                120.5 GB   disk0s2
   3:                 Apple_Boot Recovery HD             650.0 MB   disk0s3

2. 복구 파티션(‘Recovery HD’)의 식별자(IDENTIFIER)를 확인한다. 위 같은 상황에서는 disk0s3
복구 파티션이 없다면? 그냥 포기하고 인터넷 복구로 재설치해라. 복구 파티션 복구하는 방법(?)은 인터넷 복구밖에 없다.
복구 파티션을 마운트한다. [IDENTIFIER] 를 위에서 확인한 식별자로 교체해야 한다.

$ diskutil mount readOnly /dev/[IDENTIFIER]
Volume Recovery HD on /dev/[IDENTIFIER] mounted

3. 복구 파티션의 내용물은 파인더에서는 볼 수 없다. 터미널에서 계속 작업을 수행한다.
복구 파티션에 포함된 설치 프로그램 이미지를 마운트한다.

$ hdiutil attach "/Volumes/Recovery HD/com.apple.recovery.boot/BaseSystem.dmg"
Driver Descriptor Map (DDM : 0) 체크섬 처리 중...
--- 중략 ---
/dev/disk1           Apple_partition_scheme
/dev/disk1s1         Apple_partition_map
/dev/disk1s2         Apple_Driver_ATAPI
/dev/disk1s3         Apple_HFS                       /Volumes/Mac OS X Base System

4. 자동으로 파인더가 실행된다. 실행되지 않으면 직접 열고, 마운트된 “Mac OS X Base System” 볼륨으로 접근한다.
반가운 아이콘 – “Mac OS X Lion 설치” 가 보일 것이다. 아직 실행하지는 말 것. USB를 초기화해야 한다.

5. 잠시 파인더를 접어두고, USB를 꽂고 디스크 유틸리티를 실행한다.
USB를 선택하고 지우기 – 포맷 Mac OS 확장(저널링) 을 선택한 후 지우기를 실행하여 EFI 포맷으로 초기화한다.
모든 데이터가 삭제되니 중요한 내용물은 미리 백업해 두도록 한다.

6. 다시 파인더로 돌아가서, Lion 설치를 시작한다.
쭉 넘어가되, 설치 디스크를 선택하는 곳에서는 “모두 보이기”를 선택하고 USB 디스크를 선택한다.
요구하는 경우 관리자 비밀번호나 애플계정 로그인을 진행하면 다운로드가 시작된다.

7. 자동저장 지원 안 되는 어플리케이션을 실행해 둔다. 재부팅 방지용이라고 하는데, 본문에서 보험삼아 해 두라고 하니 해 두자.
예를 들면 TextWrangler 를 띄워두고 새 문서를 만든 다음 아무 문자나 쳐 두는 식(저장은 하지 말고). 다만 별 효과 없었다는 댓글이 있다.

다운로드 도중에 USB를 들여다보면 “Mac OS X Install Data” 라는 폴더가 있을거다. 열어보면 installESD.dmg.partial 파일을 볼 수 있다.
설치 프로그램에서 command-L 을 눌러 로그창을 띄우고, 로그레벨을 모든 로그로 바꾸면 자세한 다운로드 진행상황을 확인할 수 있다.

9. 다운로드 완료될 때까지 기다린다. 특별한게 없으면 한시간 정도 걸린다. 위에서 말한 설치 데이터 폴더를 파인더로 띄워두자.
다운로드가 완료되고서도 1~2분 더 기다리면 시스템 재시작한다는 경고가 뜨며 30초를 대기하게 된다. 이 때 파인더를 보면 installESD.dmg 파일이 생성된 것을 확인할 수 있다.
30초가 지나서 시스템 재부팅되기 전에 설치 프로그램을 강제 종료한다. command-option-escape 를 눌러서 강제 종료해야 한다.
(command-Q를 이용하면 설치 취소되며 다운받은 파일이 모조리 삭제된다 -_-)

10. 온전한 installESD.dmg 파일을 구했다. 나머지는 just your own work.

맥북에어에서 윈도우 세팅.

맥북에어를 산게 2011년 9월 일이다. 그동안 다양한 이유로 사용을 거의 하지 않았다. 나갈때나 잠깐 들고나가는 정도로…

이번에 1월말 해외출장을 가게 되면서, 기왕 가는거 사무용 세팅이나 하자 해서 윈도우로 밀어버렸다.
부트캠프로 듀얼부트를 하는 레벨이 아니고, 아예 맥OS를 삭제하고 윈도우만 설치했다는 이야기.

절차는 의외로 간단하다.

1. 맥에서 부트캠프 지원 툴로 부트용 USB를 생성하고 부트캠프 파티션을 생성한다. 윈도우7 ISO이미지와 8GB 이상의 USB 메모리스틱이 필요하다.
2. 정상적으로 부트캠프 지원을 통하여 윈도우7을 설치한다. 부트 기본값을 윈도우7로 설정해 준다. 지워질 파티션이므로 업데이트 할 필요 없다.
3. 시스템을 재시작한다. command+R을 누르고 있으면 인터넷 복구 모드로 진입한다. 약 10분정도 걸린다.
4. 파티션 툴로 맥북에어 스토리지를 초기화한다. 이 때 DOS 파티션(FAT)로 포맷하고, 절차가 종료되면 시스템 전원을 완전히 끈다.
5. 아까 만든 USB 메모리스틱을 꽂고, option을 누른 상태로 전원을 켠다. 부트 장비에 메모리 스틱만 보일거다.
6. 메모리스틱으로 부트, 윈도우를 다시 설치한다.
7. 절차 끝. 부트로더에서 윈도우 파티션만 보이면 정상 설치된 것이다.

부트캠프 지원으로 USB메모리스틱만 만들고, 바로 3번으로 넘어가도 될 것 같은데 해보진 않았다. 참고만 할 것.

다시 맥으로 돌아가려면 command+R을 이용하여 인터넷 복구 모드로 진입한 후 맥OS를 재설치하면 된다.

안경잡이 정리

나중에 깔끔하게 정리해야 함

1. 디옵터(Diopter)
– 렌즈의 굴절률 즉 빛이 꺾이는 정도를 나타내는 단위. 초점거리(Focal Length)의 역수이며 SI단위는 1/m 이며 흔히 D 또는 dpt 단위를 사용한다.
– 음의 값을 가지면 오목렌즈(볼록거울), 양의 값을 가지면 볼록렌즈(오목거울). 이는 “빛의 진행방향”을 기준으로 초점(허초점)이 어디에 맺히느냐를 +/-로 나타낸 것이다.
– 초점거리가 크면 렌즈가 빛을 굴절시키는 정도가 작다는 이야기이며, 디옵터의 절대값 또한 작아진다. 즉, 디옵터의 절대값은 굴절률을 나타낸다.
– 얇은 렌즈 모델에서 렌즈 여러개를 가까이 위치하여 중첩시키면 전체 시스템의 디옵터 값은 개별 렌즈의 디옵터 값의 합으로 근사할 수 있다.

2. 사람의 눈
– 사람의 눈은 초점거리가 변하는 볼록렌즈로 모델링이 가능하다. 즉 디옵터는 양수가 된다.
– 사람 눈은 근육을 조정하여 수정체의 두께 즉 굴절률을 조절한다. 수정체가 두꺼워지면 굴절률도 커지고, 수정체가 얇아지면 굴절률도 작아진다.
– 사람 눈에서 이야기하는 디옵터 값은, 망막에 상이 정확하게 맺힐 때의 물체와 수정체 사이의 거리의 역수로 정의하는 것 같다. (정확하지는 않음)
– 따라서 0D면 무한히 먼 거리에 있는 물체가 선명하게 상이 맺히는 것 즉 수정체가 최대로 얇아진 상태이다.

3. 노안
– 광학적으로 신생아의 수정체를 볼록렌즈로 평가하면 최소 0D에서 최대 +60D 까지 조정 가능하며, 25세에 약 +10D, 45세에 약 +3D, 50세에 약 +1D 정도가 된다고 한다.
25세를 기준으로 1/10D = 0.1m 보다 멀리 있는 물체를 선명하게 볼 수 있다. 이보다 가까이 있는 물체는 굴절률이 부족해서 선명한 상을 얻을 수 없다.
45세를 기준으로 1/3D = 0.33m 보다 멀리 있는 물체를 선명하게 볼 수 있다. 보통 책을 30cm 정도 떨어져서 읽는 탓에, 40대 중반이 되면 독서가 어려워진다.
50세를 기준으로 1/1D = 1m 보다 멀리 있는 물체를 선명하게 볼 수 있다.
60세를 기준으로 디옵터는 0에 수렴한다. 즉 매우 멀리 있는 물체만 선명하게 볼 수 있지만 너무 작아서 안 보인다.
– 그렇다면 나이로 인한 노안은 어떻게 해결할 수 있을까? 수정체에서 모자라는 디옵터 값을 안경 등을 이용하여 더해 주면 된다.
– 양의 디옵터 값이 필요하므로 볼록렌즈 즉 돋보기 안경을 쓰면 선명하게 볼 수 있다. 대신 시야가 좁아지는 문제가 있다.

3. 근시, 원시
– 수정체가 조정가능한 D값의 범위는 한계가 있다. 아무리 해봐도 D값은 양의 값을 갖게 된다는 것.

– 그렇다면 근시는 어떤 경우일까? 어떠한 이유로 망막 즉 상이 맺히는 지점이 뒤쪽으로 이동한 경우다.
– 이 경우 수정체에서는 빛을 정상보다 덜 꺾어줘야, 즉 정상보다 더 작은 디옵터 값을 취해야 망막에 상이 정확하게 맺히고 시야가 선명하게 보인다.
– 멀리 있는 물체를 볼 때에는 수정체가 음의 디옵터를 취해야 하는 경우가 생긴다. 근데 이건 불가능.
– 따라서 멀리 있는 물체는 안 보이게 된다. 망막이 뒤로 이동할 수록 이 범위가 점점 늘어난다.

– 그럼 어떻게 보정할까? 수정체에서 남는 디옵터 값을 빼 줘야 한다. 즉 오목렌즈를 착용하면 된다.
– 이 때 오목렌즈를 얼마나 센 걸 착용해야 하는지가 안과에서 사용하는 디옵터 단위가 된다.
– 예를 들어 안과에서 측정결과 SPH = -3.00D 가 나왔다고 하면…
1. 이 사람은 근시이며, -3.00D 짜리 오목렌즈로 보정해야 한다.
2. 이 사람은 대략 1/3D = 0.33m 보다 멀리 있는 것은 수정체가 아무리 얇아져도 초점을 맞출 수 없다. 즉 흐리게 보인다.

– 원시는 반대 케이스. 어떠한 이유로 망막이 앞쪽으로 이동한 경우다.
– 수정체에서 빛을 정상보다 더 꺾어줘야 하는데, 수정체가 두꺼워지는데 한계가 있다.
– 따라서 멀리 있는것은 잘 보이는데, 가까이 있는 것은 안 보인다. 모자라는 만큼 볼록렌즈로 보정해 줘야 한다.
– 예를 들어 안과에서 측정 결과 SPH = +2.00D 가 나왔다고 하면…
1. 이 사람은 원시이며, +2.00D 짜리 볼록렌즈로 보정해야 한다.
2. 이 사람은 대략 1/2D = 0.5m 보다 멀리 떨어져야 물체를 선명하게 볼 수 있다. 이보다 가까이 있으면 선명한 상을 못 얻는다.

– 참고로 망막까지의 거리와 수정체의 D값의 범위는 상대적인 개념이다.

학교 이메일을 구글 지메일로 이전하다.

최근 이메일 서비스를 보면 대부분 1GB 이상의 큰 스토리지를 제공한다. 티스토리가 입주해 있는 다음은 기본 10GB에서 이벤트 참여에 따라 100GB 이상 제공하며, 구글 지메일은 10GB 이상, 네이버 메일도 기본 5GB를 제공하고 있다.

그런데 학교 이메일 서비스는 꼴랑 50MB를 제공한다. 아무래도 학교가 대형 메일 서비스를 따라갈 수 없는건 그렇다 하지만, Quota가 이렇게 작아서야 뭘 할 수가 없다. 보고서 좀 큰거 한 두 건 받으면 50MB는 우습게 차버리니까. 덕분에 회사와 연락 차질이 빚어져서 좀 곤란한 상황을 겪기도 했다. 회사에서 보내온 미팅 취소메일이 씹히면서 괜히 가지 않아도 출장을 나가게 된 것.

그 외에도 이래저래 불편한 점이 많았던 터라, 이참에 학교 이메일은 껍데기만 남겨두고 지메일로 모든 메일 데이터를 이전하기로 했다. 작업은 크게 두 단계로 나뉘어지는데, 하나는 지금까지 누적된 이메일 데이터를 구글로 이전하는 작업이고, 다른 하나는 지메일을 통해서 이메일 수발신이 가능하도록 하는 작업이다.

다행히 지메일로 데이터 이전작업은 그리 어렵지 않다. 지메일이 IMAP을 지원하면서, 아웃룩에서 계정 추가 후 끌어다 놓는 작업만으로 메일 데이터를 지메일로 올릴 수 있기 때문이다. 다만, 4년간 약 3900통 2GB 정도 되는 데이터를 모두 옮기는데 이틀이 걸렸다. 아웃룩과 지메일이 잘 안 맞는건지 수백여 개의 메일을 한 번에 모두 올리려 시도하면 접속이 끊어지면서 작업이 중단되는 탓에, 50개씩 끊어서 올린 탓이 크지만.

여하튼, 그 다음은 지메일을 통하여 학교 메일을 수발신할 수 있어야 한다. 수신 작업은 간단하다. 학교 메일이 POP3을 지원하므로(아웃룩을 쓸 수 있어야 하니까 당연한 거지만) 자동 포워딩 설정도 되니까 설정만 잡아주면 된다. 어느 쪽이 나은지는 좀 더 써 보고 생각해 봐야 할 것 같지만…

문제는 발신 작업. 일단 지메일 웹에서는 다른 이름으로 발송할 수 있도록 보내기 계정 설정을 지원한다. 발송도 학교 서버를 경유해서 발송하므로, 받는 사람 입장에서는 내가 지메일에서 보내는지 아니면 진짜 학교메일을 쓰는건지 구분하기 어렵다. 헤더 뜯어보면 나오니까 불가능한건 아니지만 굳이 알 필요도 없는거고… 문제는 클라이언트 인데, 다행히 썬더버드도 보내기 계정을 별도로 설정할 수 있다.

하여 사흘동안 삽질해서 이메일 데이터를 모두 구글로 이전하였다. 이제 컴퓨터가 뻑나더라도 이메일 데이터 백업할 필요는 없어졌다.

신용카드 결제, 환불, 해외마켓

그러니까 이게 꽤 민감한 문제다.

요즘 애플 앱스토어니 안드로이드 마켓이니 해서 해외 결제가 심심찮게 발생하는 편이다. 실물구매야 말할 것도 없고.
그런데, 이 과정에서 아무래도 모를 이유로 돈이 묶인다거나, 결제가 두 번 된다거나 하는 문제(?)가 발생한다.
실제로 앱스토어나 마켓에서 댓글을 보면 두 번(심지어는 여러 번) 결제되었으니 환불해 달라는 코멘트도 많이 달린다.
(물론 처리는 안 된다. 구글이나 애플에 메일을 보내야지, 코멘트만 단다고 누가 처리해 주겠나.)

더하여, 체크카드가 해외신판을 제한적으로 지원하게 되면서, 돈이 묶인다거나 하는 문제로 고생하는 경우도 많이 발생하고 있다.
특히나 체크카드는 신용카드와 달리 직접적으로 통장잔고에 영향을 미치는 터라 문제가 더욱 커진다.

여튼, 카드의 결제 흐름을 알아두면 왜 결제가 두 번 된 것처럼 보이는지, 언제쯤 내 돈이 풀릴지 대충 짐작할 수 있으며
여기에서 그 내용을 소개하고자 한다.

1. “신용판매”?
흔히 카드거래를 “신용판매”라고 한다.
이 말이 좀 애매한데, 죽 풀어쓰자면 대충 다음과 같은 의미이다.

구매자의 신용을 바탕으로, 신용제공자(=카드사)가 판매자에게 판매대금을 선지급하고 추후 구매자에게 이를 환수하는 판매방식

즉, 구매자의 신용=지불능력을 입증해야 하므로, 일정한 수입이 있는 사람 내지는 통장잔고가 많은 사람(보통 3개월 평잔 150만원 선), 최근 3개월 평균 체크카드 실적이 150만원 이상으로 지불능력을 입증하면 신용카드가 나오게 된다. 아니면 가족의 신용을 빌리거나.

2. 신용카드 구매과정

신용카드 거래과정을 도식적으로 나타내면 위 그림과 같다.

구매자가 카드결제 요청하면
→ 판매자는 카드사에 “이 사람이 신뢰할만 하여 신용거래를 해도 되는지” 카드사에 승인 요청한다.
흔히 카드단말기를 이용하지만, 사용이 여의치 않으면 전화승인이나 특별승인(거래후승인) 을 사용하기도 한다.
만약 이 사람이 카드를 너무 많이 사용하거나 해서 한도부족이면 승인거절되며 거래가 안 된다.
→ 신용한도가 남아있다면 거래승인이 나며, 이 시점에서 구매자의 신용카드 한도가 감소한다.
거래승인시, 구매자-판매자-카드사가 거래에 합의했음을 알리는 일종의 계약서가 발급되는데 이를 “카드전표”(Sales slip)이라고 한다.
보통 물품인도일 기준으로 카드전표가 발급된다.
→ 거래시점으로부터 일정기간 이후, 판매자는 카드전표를 카드사(or 은행)에 제출하고 대금 지급을 청구해야 하는데 이를 전표매입이라고 한다.
카드단말기를 이용한 전자매출의 경우, 대체로 거래즉시~24시간 이내에 전자적으로 전표매입이 이루어진다.(전표제출 안 해도 됨)
전화승인 등은 3일에서 7일 간격으로(판매자 귀차니즘 레벨에 따라 달라짐) 일괄적으로 전표매입이 이루어진다.
→ 전표매입이 이루어지면 카드사는 이 거래가 정당한 것인지 확인하고, 판매자에게 거래대금 지급한다.
→ 전표매입으로 판매대금을 지급한 카드사는, 결제기일에 맞추어 구매자에게 카드대금 청구한다.
즉, 대금청구는 전표매입일 기준이다. 승인시점과 매입시점이 크게 차이나면 결제가 한 달 밀리기도 한다.
→ 퍼가요~♥ ㅅㅂ…

즉, 물품인도는 카드승인 시점에 받지만 대금납부는 결제기일에 이루어지므로 당장 돈이 없어도 한도만 있다면 지를 수 있는 것.
특히 돈을 주고받기 어려운 해외결제시에도, 결제승인 등은 전자적으로 이루어지므로 원활하게 거래가 가능하게 된다.

더하여, 반드시 승인금액과 전표매입금액이 같아야 할 필요는 없다. (흔히 가승인이라고 한다.)
이게 좀 머리아픈데, 보통 가맹점에선 이런 경우가 없기 때문. 보통은 무인주유소나 호텔, 해외결제 같이 특수한 경우에만 허용된다.
물론 이 경우 카드대금 결제는 청구금액 기준으로 이루어진다.

3. 체크카드의 경우는?

체크카드는 “통장잔고를 담보로” 하여 신용판매를 하게 된다. 즉, 통장잔고가 없으면 신용제공도 안 되고 거래승인이 안 난다는 것.
기본적인 절차는 카드결제와 같지만, 몇 가지 차이가 발생한다.

1. 승인요청시 통장잔고를 기준으로 승인여부를 판단한다. 잔고가 있으면 승인이 나고 없으면 안 난다.
2. 구매자에게 신용(=지불능력)이 없으니 승인 시점에서 통장 잔고를 바로 빼 간다. 결제일까지 안 기다린다.
3. 돈 거래가 바로바로 이루어져야 한다. 하여, 전표매입이 바로 이루어지는 전자매출만 허용되는 경우가 많다.

4. 카드결제 취소하는 경우는?

이게 좀 복잡해지는데, 전표매입 이전과 이후에 따라 그 처리과정이 달라진다.

1. 전표매입 이전

전표매입 이전에는 아직 돈이 오가지 아니하였다. 따라서 승인만 취소하면 간단하게 거래가 취소된다.
판매자는 승인취소요청을 하면 되고, 승인취소와 동시에 구매자의 신용한도도 복원된다. 체크카드의 경우 바로 거래금액이 재입금된다.

2. 전표매입 이후

이게 좀 지저분하다. 전표매입이 되면 좋던싫던 카드사는 돈을 줘야 하고, 판매자는 돈을 받아야 한다.
하여, 전표매입이후 거래를 취소하게 되면 취소거래를 내야 한다. 취소거래 이후 판매자가 해당 전표를 매입(+동시에 돈도 반환)해야 카드사에서 환불절차가 이루어질 수 있다. (물론, 보통은 다음번 전표매입금액과 상계하여 처리하긴 한다.)

신용카드야 한도 가지고 장난치니까, 정산기간 내에만 취소전표 매입이 이루어지면 구매자 돈이 묶이는 문제는 없다.
문제는 체크카드. 위에서 설명했다시피, 체크카드는 승인직후 돈이 빠져나간다. 그런데 전표매입이후 이를 취소하면 전표매입~대금입금~취소거래~취소승인까지 최소 2~3일은 걸리고, 해당 기간에는 꼼짝없이 돈이 카드사에 묶이게 되는 것이다. 하여 체크카드 거래는 거래다음날부터 취소시 환불까지 최소 3일 이상 걸리게 된다. 거래시스템이 구리니 어쩔 수 없다.

5. 해외결제는?

기본적으로 해외결제도 거래방식은 같다. 전표매입 등이 국제카드사(VISA, MASTER 등등…)를 통하여 이루어지는게 다르지만, 그건 카드사 뒷단에서 일어나는 일이니 신경꺼도 좋다.
다만 전표가 국제적으로 날아다니다 보니 승인으로부터 전표매입까지 열흘 이상, 최장 30일이 걸릴 수도 있다. 개인이야 상관없지만, 결제내역을 정산해야 하는 법인카드의 경우 문제가 될 수 있으니 가급적 사용을 자제하는게 좋을지도 모르겠다.

6. 체크카드 해외결제?

위에서 말했다시피, 체크카드는 전표매입이 바로 이루어져야 하고, 해외결제는 전표매입이 오래 걸린다. 하여 초기에는 체크카드 해외결제는 거의 요원한 것처럼 받아들여졌다.

허나, 해외결제 수요가 워낙 많아졌기에 시스템을 좀 우회하는 방식으로 체크카드 해외결제를 지원하게 되었다. 크게 두 가지 방식이 있는데, 직접지불(Direct Pay)과 지급정지후 정산(Holding-and-Pay) 방식이다.

1. 직접지불
전표매입까지 안 기다리고, 승인시점에 승인금액만큼 바로 돈을 빼 간다. 즉, 국내거래하고 똑같이 취급해 버린다.
전표매입 이후 발생할 수 있는 환차익/환차손은 카드사가 떠안는 방식. 가승인의 경우 일단 많이 청구하고 나중에 차이만큼 돌려준다.
카드 호환성(?)이 좋지만 아무래도 위험한 방식이며, 특히 거래취소때 돈이 붕 떠버릴 가능성이 있다.

2. 지급정지 후 정산
승인시점에 승인금액+α만큼 출금정지를 건다. 이후 카드결제처럼 결제일에 정산하는 방식.
진일보한 방식으로, 신용카드결제 과정과 유사한 방식. 다만 지급정지만 걸릴 뿐 통장잔고는 남아 있으니 사용자가 세심하게 체크해야 한다.

7. 앱스토어 두 번 결제됐어요!

이게 굉장히 지저분한 케이스다. 만약 승인을 내고 전표매입을 고의로 하지 않으면 어떻게 될까?

판매자는 가승인을 냄으로써 이 사람의 신용을 확인할 수 있다.
비단 카드결제가 아니더라도, “이 카드가 실제 유효하다”는 정보가 필요한 경우에도 가승인을 발생시킬 수 있는 것이다.
보통 이런 경우 묶이는 한도를 최소화하기 위해 1달러만 가승인하는 경우가 많다.

보통, 승인으로부터 한 달간 전표매입이 이루어지지 않으면 해당 승인건은 취소되고 한도복원된다.
신용카드야 한도만 묶이고 돈은 안 나가니 상관없지만, 체크카드는 좀 문제가 심각하다.
1달러 가승인시 수수료 등등 해서 1200원 정도가 묶이는데, 이 돈이 한 달동안 카드사(직접지불) 내지는 계좌에 지급정지로 묶이는 것.
하여 불만사항이 굉장히 많다. 맨 위에 알아본 “결제 두 번 됐어요!” 하는 케이스들은 99% 이런 케이스다.

근데, 돈이 묶인다 뿐이지 결론적으로는 기다리면 환불 된다. 다만 그 기간이 한 달 정도로 굉장히 오래 걸려서 문제일 뿐이지.

참고로, 국내에서도 한때 고속버스 예매 등에서 가승인을 활용하였다. 현재는 신용카드를 이용한 본인확인 시스템이 구축되어 폐기되었지만.

티스토리에 Syntax Highlighter 설치하기.

Syntax Highlighter이 뭐냐면… 그냥 소스코드 예쁘게 뿌려주는거다. 이 글에서도 자주 쓰이니 알아서 판단하시고.

일단 티스토리는 Syntax Highlighter를 제공하지 않는다. 플러그인을 마음대로 설치할 수도 없으니 물건너간 줄 알았으나…
찾아보니까 된다 카더라 ‘ㅅ’ 그러니까 스킨 뜯어고치면 된다.

소스 홈페이지 : http://alexgorbatchev.com/SyntaxHighlighter/ (오픈소스로 공개중이다. 감사하도록.)

1. 설치방법

설정 – 스킨 – HTML/CSS 편집 들어간 후, </body>와 </html> 사이에 다음 내용을 추가해 준다.

<link rel='stylesheet' type='text/css' href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' />
<link rel='stylesheet' type='text/css' href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css' />
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCpp.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPhp.js' type='text/javascript'></script>
<script type="text/javascript">
SyntaxHighlighter.all();
</script>

설치끝. 진짜로. 이게 전부다.

2. 사용방법

우선 편집기에서 소스를 쭉 작성한다. < 를 &lt; 로 작성해야 하는데, 이건 티스토리 편집기에서 자동으로 치환해 준다.
그리고 HTML 모드에서 위아래를 <pre> – </pre> 태그로 묶어주는데, 코드 종류에 따라 태그 클래스를 미묘하게 바꿔줘야 한다.

CPP 코드 : <pre class="brush: cpp"> - </pre>
HTML : <pre class="brush: html"> - </pre>
PHP : <pre class="brush: php"> - </pre>

이런 식.

정확하게는 위에서 추가해 준 브러시 타입만 사용할 수 있다. 저 위 소스 잘 보면 shBrush___.js 를 삽입하는걸 볼 수 있는데 이 부분.
다른쪽(Ruby라거나…) 쓰는 블로그라면 알아서 홈페이지 뒤져서 바꿔주면 되겠다.
(설마 코드 다루는 블로그 주인장이 저 정도 응용력도 없진 않겠지…)

파이어폭스 사용시, 코드 뒤에 <br /> 붙는건 지워줘야 한다. 아니면 아래처럼 소스에 한 줄 추가해주면 알아서 삭제하고 파싱해 준다.

<script type="text/javascript">
SyntaxHighlighter.config.stripBrs = true;
SyntaxHighlighter.all();
</script>

3. 그리고

코드 유지보수하는게 Alex Gorbatchev란 사람인데, 월 트래픽이 80GB가 넘게 발생하고 덕분에 월 40달러씩 돈내고 있다고 무지하게 투덜거리고 있다.
PayPal 쓰는 사람이라면 맥주 한 잔쯤 사 주는게 어떠한가.