BLOG main image
분류 전체보기 (16)
emacs (10)
lisp (6)
1,378 Visitors up to today!
Today 2 hit, Yesterday 1 hit
daisy rss
tistory 티스토리 가입하기!
2009/06/15 13:06
설정을 따로 하지 않는 다면, Emacs 는 2벌식으로 동작합니다. 그래서 .emacs 에

 (setq default-korean-keyboard "3")


같이 추가 해 줌으로써 모든 곳에서 삼벌식 390 을 사용할 수가 있습니다.
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback Address :: http://emacsos.tistory.com/trackback/17 관련글 쓰기
Name
Password
Homepage
Secret
2009/01/15 15:39
우분투를 사용하면서 이맥스에 TrueType 폰트를 적용해 보고 싶은 욕망이 생겼습니다. 기반
인프라가 다 나와 있는 상태라 전혀 부담이 없이 설치 하실 수가 있습니다.

1. 먼저 TrueType 폰트를 지원하는 이맥스 버젼이 필요합니다.

이맥스 22버젼 까지는 TrueType 폰트를 지원 안합니다. 그래서 현재 개발중인 23 버젼을 깔아야
하지요.

sudo apt-get install emacs-snapshot


하면 최근 개발중인 emacs 23 버젼을 설치합니다.

2. 영문 폰트 설정하기

~/.Xresources 파일을 만들고 그 것을 열어서

Emacs.font: Monospace-10


이라가 적어주고 파일을 닫은 후

xrdb -merge ~/.Xresources


해주면 적용이 됩니다.  여기까지 해주면 영문은 정말 이쁘게 보일 테지만 한글은 영 아니게
보입니다.  한글 폰트도 따로 설정을 해줘야 합니다.

3. 한글 폰트 설정하기

참조 : http://4ipperz.com/81

set-fontset-font "fontset-default" '(#x1100 . #xffdc)  '("Malgun Gothic" . "unicode-bmp")) ;;; 유니코드 한글영역...Malgun Gothic에다가 원하는폰트를 적는다
(set-fontset-font "fontset-default" '(#xe0bc . #xf66e)  '("New Gulim" . "unicode-bmp")) ;;;유니코드 사용자 영역
(set-fontset-font "fontset-default" 'kana '("Meiryo" . "unicode-bmp"))
(set-fontset-font "fontset-default" 'han '("Microsoft YaHei"
. "unicode-bmp"))


이런식으로 .emacs 파일에 써주면 한글 설정이 됩니다.  안되는 분들은 '맑은 고딕' 폰트가
없어서 입니다. 저 폰트는 윈도에서 배포하는 폰트입니다. 당연히 상용이니 재주것 구하시면
됩니다. (비스타에는 무조건 깔려있음)

4. 그러면 맑은 고딕을 우분투에 설치하는 법을 알아보기로 하지요.

참조 : http://zodiac12k.egloos.com/1828667

sudo cp malgun.ttf /usr/share/fonts/truetype


맑은 고딕 폰트를 폰트 폴더에 복사해 넣습니다.

sudo fc-cache -f -v


폰트 정보를 갱신해 넣습니다.

단순히 이와 같이만 해주면 폰트가 등록됐습니다. 이제 emacs 를 띄워보면
알맞게 폰트들이 설정되어 있는 것을 확인이 가능합니다.


-- 깔끔하게 다듬기 --

여기까지 해도 한글 폰트가 뭔가 아쉬워 보일 것입니다. 다른 이유는 아니고 한국어 폰트의
크기가 10~22 일때 기본적으로 Auto Hint 와 Anti-Alias 가 꺼지도록 설정되어 있다는
것입니다. 대체 왜????

그래서 그 부분을 수정해보기로 하지요.

/etc/fonts/conf.d/29-language-selector-ko-kr.conf 파일을 열어보시면

<!-- Turn off antialias and autohint for Korean fonts depending on pixelsize -->
<match target="font">
        <test name="lang" compare="contains">
                <string>ko</string>
        </test>
        <test name="pixelsize" compare="more">
                <int>10</int>
        </test>
        <test name="pixelsize" compare="less">
                <int>22</int>
        </test>
        <edit name="antialias" mode="assign">
                <bool>false</bool>
        </edit>
        <edit name="autohint" mode="assign">
                <bool>false</bool>
        </edit>
        <edit name="hintstyle" mode="assign">
                <const>hintmedium</const>
        </edit>
</match>



false 인 부분을 true 로 변경해 주고 저장하고 그놈을 다시 시작하시면 됩니다.(우분투 8.10 기준)

크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback Address :: http://emacsos.tistory.com/trackback/16 관련글 쓰기
Name
Password
Homepage
Secret
2008/11/20 16:09

웹 프로그래밍은 대대로 귀찮은 일의 반복 , 귀찮은 개발환경 세팅 등이 언제나 피곤하게
만들었습니다. 그래서 대체로 시스템 프로그래머들은 은근히 웹쪽을 차별하는 발언을 많이
하곤 합니다(저 또한 그랬습니다...) 그렇지만 역시 웹의 세계는 무궁무진하기 때문에
안 익힐 수 없는 영역이지요.

리습은 또한 개발환경 세팅이야 그리 쉽다고는 할 수 없지만 , 반복적인 일은 정말
환상적으로 줄여주는 막강한 능력을 가지고 있습니다. 그렇기 때문에 초 단기간에 웹
프로그래밍을 할 수 있을 뿐만 아니라 기존의 소스들을 변경하기가 아주 쉽고도
빠릅니다. 리습 자체가 상향식 (bottom - up) 프로그래밍이 가능하기 때문에 그를
이용해서 만드는 웹 서비스 조차도 '상향식' 이 됩니다. 이 것 또한 정말 미친듯한
강점입니다.

자 이전 아티클에서 계속적으로 개발 환경 세팅에 관한 이야기가 끝났으니까 빠르게 웹
프로그래밍을 해보기로 하지요.

참조한 사이트는 http://www.adampetersen.se/articles/lispweb.htm 입니다. 기본을
참조하는 사이트와 같게 만들고 하나씩 변경해 나가는 쪽으로 진행해 볼까 합니다. 예제
그대로 하기에는 일단 우리가 있는 곳이 한국이기도 하고 생각하는 바가 조금은 다르기
때문이겠지요.

emacs 를 실행시키고 새로운 파일 하나를 열도록 하지요. 'C-xC-f' 명령으로 새롭게
파일이름을 적어주면 버퍼창이 하나 생성되고 입력한 파일이름과 연결시켜줍니다. (가장
기본적인 파일 오픈입니다)

처음에 필요한 패키지 로딩이 필요하겠군요. 저번에 설명 드렸던 'eval-when 을 이용한 패키지
로딩'을 적용해 보기로 하겠습니다.

(eval-when (:compile-toplevel :load-toplevel :execute)
  (require 'hunchentoot)
  (require 'parenscript)
  (require 'cl-who)
)

이렇게 소스 상단에 적어주면 컴파일 , 로딩, 실행할때 저 패키지들을 로딩해 줍니다.
그러면 새로운 패키지를 정의해 줄 필요가 있군요.

(defpackage :pollpoll
  (:use :cl :cl-who :hunchentoot :parenscript))

이는 c++ 이나 c# 에서의 namespace 와 같은 것이라고 이해하시면 아주 편하고 빠르게
이해가 됩니다. pollpoll 을 아래 나열된 패키지들의 영역에 두겠다는 뜻(상속한다고
생각하시면 편합니다) 이지요.

서버 변수를 하나 생성하기로 하지요. 이것은 나중에 repl (해석기) 에서 서버를 중단 시킬때
편합니다.

(defvar *web-server* nil)
;; web server 를 포트 8001 로 해서 띄운다.
(setf *web-server* (start-server :port 8001))

웹 서버를 하나 생성하고 그 인스턴스를 *web-server* 에 저장합니다. 이제는 투표
항목을 만들어 보기로 하지요. 클래스로 만들어 줄 수가 있습니다.

(defclass game ()
  ((name :reader name
         :initarg :name)
   (contents :reader contents
             :initarg :contents)
   (votes :accessor votes
          :initform 0)))

항목에 관한 이름, 내용 , 득표수로 이루어 져 있습니다. 그러면 연관된 메서드 한개
선언해 볼까요? 투표를 하면 득표수가 한개 올라야 겠지요?

(defmethod vote-for (user-selected-game)
  (incf (votes user-selected-game)))

어떻게 이런 것이 가능할 지 궁금해 하실까 미리 말씀 드리지만 INCF 는 값을 하나
증가시키는 함수입니다. user-selected-game 은 위에 언급된 game 의 인스턴스
구요. votes 는 game 에 대한 accessor 함수 입니다. 즉 votes 변수에 접근해서 그 값을
하나 증가시키는 일을 하라는 것이지요. 단지 득표 + 1 인데 좀 어렵게 설명된 감이
있군요. ㅎㅎ

; 게임들이 저장될 리스트
(defvar *games* '())

게임이 저장될 리스트 입니다. 초기화에 주목하면 리스트 변수기 때문에 '() 값으로
초기화 해줬습니다. 다음은 게임 내용중에서 이름으로 검색하는 함수 입니다.

(defun game-from-name (pname)
  (find pname *games* :test #'string-equal
        :key #'name))

FIND 가 쓰여졌군요. pname 인자를 받아서 *games* game 인스턴스에서 찾아 내는 일을
합니다. 어떤 방법으로 찾는 가 하는 것이 바로 :test 입니다. 그 방법에 관한 설명은
#'string-equal 이지요. #' 는 함수에 관한 포인터 같은 개념이라고 제가 예전
아티클에서 설명한 적이 있을 것입니다. 방법은 알았으니 대상은 무엇일까요? 바로 :key
뒤에 나오는 것입니다. #'name 이 되겠네요.

다시 풀어서 설명을 하자면 위에 나온 내용은 *games* 안에 있는 각각의 game
인스턴스들에 대해서 name 이라는 함수를 적용하면 (name 이 reader 속성 이니까) 저장된
name 이 리턴됩니다. 이 리턴된 name 과 주어진 pname 과 값이 같은건지 string-equal
비교하는 것입니다. 찾아지면 그 게임 인스턴스가 리턴 되고 없으면 NIL 이 리턴되겠지요.

이걸 응용해서 같은 게임이 저장되어 있는지 찾아보는 함수를 제작할 수 있겠군요.

; 같은 이름이 저장되어 있는지 비교
(defun game-stored? (game-name)
  (game-from-name game-name))

그냥 wrapping 정도 입니다. 이 함수까지 만들었 다면 바로 항목(game) 을 추가하는 함수로
가보기로 하지요.

; 새로 추가합니다. 게임을. 일단 같은 것이 있는지 비교해야 겠지요.
(defun add-game (name contents)
  (unless (game-stored? name)
    (push (make-instance 'game :name name :contents contents) *games* )))

같은 이름의 항목이 있는지 조사해서 없다면 투표의 인스턴스를 만들어서 리스트에
추가한다.

이제 *games* 안에 들어 있는 게임을 정렬해서 뿌려 주는 부분을 보기로 하지요. 득표수에
따라서 정렬을 하니까 나중에 결과물 보여주기로 할때 편하겠지요?

(defun games ()
       (sort (copy-list *games*) #'> :key #'votes))

SORT 는 리스트 자체를 변경시키니 copy-list 를 이용해서 복사한 결과를 가지고 소팅을
합니다. game 인스턴스에서 정렬의 기준이 되는 값은 accessor votes 를 통한 득표수
이고 정렬 방식은 > 라고 쓰여져 있군요.

이제 중요한 웹 관련 소스들을 훑어 보기로 하지요. 다음 매크로는 url 과 함수를
매칭시켜서 디스패처에 등록시키는 매크로입니다.

(defmacro define-url-fn ((name) &body body)
  `(progn
     (defun ,name ()
       ,@body)
     (push (create-prefix-dispatcher ,(format nil "/~(~a~).htm" name) ',name) *dispatch-table*)))

매크로는 모든 메타프로그래밍의 아버지격입니다. 따라서 요즘 나오는 최신 언어 스펙이
리습에서 태동되었다고 해도 과언이 아니지요. 그런 최신 경향인 만큼 강력합니다. 이
함수는 매크로를 이용해서 쓰고 있는데, 두개의 문장을 하나의 문장으로 합치기 위해서
progn 을 쓰고 있습니다.

` 연산자와 ' 연산자의 차이점에 대해서는 잘 아시나요? 실제로 예를 들어보이죠.

CL-USER> `(1 2 3)
(1 2 3)
CL-USER> '(1 2 3)
(1 2 3)

연산자 뒤에 나오는 값을 그대로 리턴하는 것은 두 연산자가 같습니다. (실제로 '
리스트를 파라미터로 넘길때 많이 쓰지요) 하지만 ` 만의 특징은 , 연산자와 함께 쓰여질
때 입니다.

CL-USER> `(1 2 (+ 1 2))
(1 2 (+ 1 2))
CL-USER> `(1 2 , (+ 1 2))
(1 2 3)

차이가 극명하지요? , 뒤의 표현식은 계산된 형태로 반환이 됩니다.  여기까지가
매크로의 가장 기본적인 설명입니다. 다시 소스를 보면 전형적인 ` , 의 콤보로
이루어져 있습니다. 또 하나 눈여겨 볼 것은 &body @ 의 콤보 입니다.

(defmacro define-url-fn ((name) &body body)
  `(progn
     (defun ,name ()
       ,@body)
     (push (create-prefix-dispatcher ,(format nil "/~(~a~).htm" name) ',name) *dispatch-table*)))

이는 처음에 파라미터를 넘겨줄때 &body 를 써서 주어진 값을 리스트 형태로 만들어서
파라미터로 넘겨주고 @ 연산자를 써서 다시 리스트를 일반 원소의 나열로 쪼갭니다. 이런
점을 염두에 두고 이 함수를 설명하자면 주어진 '이름''함수 몸통' 에 해당하는 것으로
함수를 만들고 그 함수를 디스패쳐에 등록하는 매크로를 만들어 줍니다.

다음은 또 다른 중요한 매크로를 보기로 하지요. 이것은 기본적인 웹페이지의 반복되는
부분을 처리할 수 있게 해주는 매크로 입니다. 역시 `, 의 콤보와 &body @
콤보를 염두에 두시면서 바라보면 좋습니다.

;;; 페이지를 구성하는 요소들로 이루어진 기본적인 페이지 작성하는 함수
;;; body 부분만 추가해 주면 웹 페이지 완성

(defmacro standard-page ((&key title) &body body)
  `(with-html-output-to-string (*standard-output* nil :prologue t :indent t)
     (:html :xmlns "http://www.w3.org/1999/xhtml"  :xml\:lang "en" :lang "en"
       (:head
         (:meta :http-equiv "Content-Type" :content "text/html;charset=utf-8")
         (:title ,title)
         (:link :type "text/css" :rel "stylesheet" :href "/vote.css"))
           (:body
             (:div :id "header" ; Start all pages with our header.
               (:img :src "/logo.jpg" :alt "다스베이더" :class "logo")
               (:span :class "strapline" "님의 비교 비교"))
             ,@body))))

with-html-output-to-string 함수는 cl-who 의 함수인 데 리습 함수형식으로 쓰여진
내용들을 html 용 마크업 언어 형태로 변환 해주는 함수입니다.

자 이제 준비가 끝났으니 실제로 이제 까지 만들어 진 것을 토대로 페이지를 한번 만들어
보기로 하지요. (defin-url-fn ) 함수를 이용합니다.

(define-url-fn (mains)
    (standard-page (:title "소녀시대")
                   (:p "어리다고 놀리지 말아요")))

혹시나 해서 말씀드리지만 전 소녀시대를 좋아하지는 않습니다. -ㅅ- 걍 떠오른게
이거라서.. 자 이제 소스를 저장하시고 C-cC-k 를 눌러보기로 하지요.

웹브라우저를 열고  http://localhost:8001/mains.htm 을 입력하면 화면에 아무것도
디스플레이 되지 않습니다. hunchentoot 현재 다루고 있는 문서의 인코딩을 짐작 못하기
때문에 발생하는 현상
입니다. 기본이 '서유럽 기반' 이기 때문에 그러니

(setf hunchentoot:*hunchentoot-default-external-format* :UTF-8)

(setf *web-server* (start-server :port 8001))

웹 서버를 실행하기 전에 위와 같은 값을 입력해준다. 기본 문서 형태를 utf-8 으로 설정해
주는 함수다. 바꾸고 (웹 서버가 떠 있으면 웹서버를 죽이고) 다시 실행 ㄱㄱ



뭔가가 출력되긴 했지만 알아보기 힘들지요? 왼쪽 상단의 커다란 네모는 이미지를 출력
시키기로 했지만 실제로 이미지 위치를 디스패쳐에 안넣어 줬기 때문에 이미지가 없는
것으로 나오는 것이고 그건 그렇다고 해도 글자가 깨지는 군요.

고치는 방법을 알려드리지요. 화면에 대고 마우스 오른쪽 버튼을 클릭하시면 뜨는
메뉴중에 '인코딩' 을 선택하시면 '서유럽'으로 되어 있는 것을 'UTF-8' 으로 바꾸어
주시면 원하고자 하는 바가 제대로 나옵니다. 앞으로 문서가 깨질 때마다 이와 같은
방법으로 하시면 됩니다.

..... 당연히 그러면 안되겠지요? ㅎㅎ
이는 글 자체는 utf-8 으로 출력됐지만 그 html 자체가 '서유럽 기반' 으로 인식되는
데서 생기는 오류 입니다. 이 또한 간단하게 해결이 가능합니다.

(setf hunchentoot:*default-content-type* "text/html; charset=utf-8")

이를 위에서 추가해준 곳에 더해줍니다. html 자체 즉, 그 내용을 utf-8 으로 정하라고
하는 세팅입니다.

이제 이미지를 올리는 방법을 알아보기로 하지요. 소스파일이 있는 곳을 웹 서버는
루트로 인식합니다. 따라서 다음과 같이 추가해 줍니다.

(push (create-static-file-dispatcher-and-handler "/logo.jpg" "./img/logo.jpg") *dispatch-table*)

설명을 하자면 create-static-file-dispatcher-and-handler 이 함수(매크로?)는 정적으로
존재하는 파일 구성원들을 처리하는 디스패처입니다. 사진이나 아니면 순수한 html 파일
, 그리고 css 들을 처리합니다. logo.jpg 의 요청이 오면 ./img/logo.jpg 를 넘겨주라는
이야기 입니다.

코드를 추가 해줬으면 정말 소스가 있는 디렉토리 밑에 img 디렉토리를 생성하고 그 곳에
적당한 jpg 파일을 이름을 logo.jpg 로 바꿔서 저장합니다. 그리고 다시 떠 있는
웹서버가 있다면 죽이고 로딩을 하면



짠!! 이렇게 완성 됐습니다.  여기까지 소요된 라인수는 리습이라 옆으로 길게 쓰는
함수들 형태가 아닌데 도 불구하고 커멘트 포함해서 84 라인입니다!!! (그중에 대부분은
아직 쓰지도 않는 함수들이지요!!) 이 어찌나 효율적인지 감동입니다 +ㅂ+

놀랍지 않습니까? 이것은 시작입니다. 물론 루비온 레일즈처럼 최적화된 웹 프레임웍이
있으면 좋지만 이제 시작하는 분들은(나 같은 경우군요 ㅎㅎ) 지금부터 기본부터 충분히
익히실 필요가 있습니다.

다음부터는 이를 바탕으로 해서 기존의 것을 고쳐가면서 원하는 형태의 사이트로 다듬어
가기로 하지요.

크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback Address :: http://emacsos.tistory.com/trackback/15 관련글 쓰기
Name
Password
Homepage
Secret
prev"" #1 #2 #3 #4 #5 ... #6 next