�빫�� ����� ���

Archive for the ‘lisp’ Category.

Clojure Web library hiccup(예전 compojure)


Programming clojure 책에는 compojure에 있는 html 함수들을 사용하는 예제들을 보여줍니다. 막상 해보니깐 안되더군요. 언제인지는 모르겠지만 hiccup이라는 라이브러리로 떨어져 나왔더군요.

Hiccup is a library for representing HTML in Clojure. It uses vectors to represent tags, and maps to represent a tag’s attributes.

hiccup의 readme 파일에 있는 내용입니다.(살짝 바뻐서, 대충 써야겠네요.) 예제소스를 보면 금방 알 수 있을 겁니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
 
(ns hello-www.core
  (:use compojure.core
    hiccup.core
    ring.adapter.jetty)
  (:require [compojure.route :as route]))
 
(defroutes example
  (GET "/hello" [] 
    (html
			 [:head
			  [:body
			   [:h1 "Hello World Wide Web!"]]]))
  (GET "/" [] "<h1>root</h1>")
  (GET "/sample" []
    (html
      [:head
       [:title "html sample by hiccup lib, clojure"]
       ]
      [:body
       [:p [:a {:href "http://defree.co.kr"} "Samuel's blog"]]
       [:p [:b "b tag"]]
       [:p [:dd "dd tag"]]
       [:p 
        [:div "form in a div tag"
         [:form {:name "form1"}
          [:p 
           [:input {:type "text" :name "text_input" :value "this is a text input tag."}]
           [:input {:type "password" :name "password_input" :value "this is a password input tag."}]
           [:input {:type "button" :name "button_input" :value "this is a button input tag."}]
           [:input {:type "submit" :name "submit_input" :value "this is a submit input tag."}]
           ]
          [:p 
           [:input {:type "radio" :name "text_input" :value "1" :selected "true"} "radio No.1"]
           [:input {:type "radio" :name "text_input" :value "2" :selected "false"} "radio No.2"]
           [:select {:name "select"}
            [:option {:value "code1" :selected "true"} "select 1"]
            [:option {:value "code2"} "select 2"]]
           [:textarea {:value "textarea"}]]]]]
       [:h1 "h1"]
       [:h2 "h1"]
       [:h3 "h2"]
       [:h4 "h3"]
       [:h5 "h4"]
       [:h6 "h5"]]))
  (route/not-found "Page not found"))
 
(run-jetty example {:port 8080})

꽤 쉽죠? 그리고 당연히 project.clj에 hiccup을 명시해 두어야겠죠.

1
2
3
4
5
6
7
8
(defproject hello-www "0.0.1-SNAPSHOT"
  :description "FIXME: write"
  :dependencies [[org.clojure/clojure "1.2.0"]
                   [org.clojure/clojure-contrib "1.2.0"]
                   [compojure "0.4.0"]
                   [ring/ring-jetty-adapter "0.2.3"]
                   [lein-eclipse "1.0.0"]
                   [hiccup "0.2.6"]])

마음이 급해져서 설명을 어떻게 할 지 생각나질 않는군요. -_-;;

Windows 에서 Clojure Web 개발 환경설정(leiningen, Compojure, Eclipse REPL)


일하다가 지루해져서(화장실에 책 들고 볼일보다가..) Clojure 책을 구경하고 있었습니다.(열심히 읽은게 아니라 말 그대로 구경) 생각해보니깐, 프로그래밍 언어를 익히는 데 가장 좋은 방법은 프로그램을 계속 만드는 것인데, 요새 제 일도 그렇고 해서 웹으로 만들어야겠다 하는 생각이 들더군요. Programming Clojure 책 후반부에 Compojure 라이브러리가 딱 1챕터 나옵니다. 그런데 버전이 올라가면서 조금씩 바뀌었나보군요. 환경설정하는데 한참 걸렸습니다. ~_~

준비물은 eclipse 3.4 이상, J2SDK 1.6 이상입니다.

1. counterclockwise 설치하기
쉬워요. counterclockwise 홈페이지에서 플러그인을 이클립스에 복사해 넣으면 땡입니다. 설치하고 나면 이클립스에 클로져 지원이 생기죠.

이클립스에서 클로져 지원


이렇게 말이죠

2. leiningen 설치
leiningen은 클로져 프로젝트 도구입니다. 프로젝트를 생성하고, 의존성을 관리하고, 빌드 등을 지원하는 툴이죠.(아겔님 블로그 참조)

    설치방법

  • github의 leiningen 저장소에 보면 릴리즈된 leiningen 패키지를 찾을 수 있습니다.(요즘은 1.3.0이군요.) 다운로드 받아서 적당한 위치에 옮겨넣습니다.(전 d:\src\leiningen 에 넣었습니다.)
  • 그리고 실행 스크립트인 lein.bat 파일을 leiningen의 readme 페이지에서 찾을 수 있습니다. installation 부분에 있어요. 그것도 leiningen.jar 디렉토리에 같이 넣어둡니다. 필요하시면 path를 걸어두시는 것도 좋죠.
  • 나중에 보니깐 lein.bat나 lein.sh 만 있으면 self-install 명령으로 설치가 가능한거였더군요. -_-;; leiningen jar를 다운받지 않아도 그냥 “lein self-install” 명령으로 알아서 다운받네요. 흠흠
  • 전 처음에 lein.sh만 있는 줄 알고 그거 보고 스크립트를 윈도우용으로 작성해야겠구나 싶어서 스크립트 코드를 한참동안 읽었더랬습니다. readme 파일도 읽어봐야겠다 생각이 들어서 읽다가 발견한 lein.bat.. 하.. 참. ~_~

3. leiningen만 있으면 사실 거의 다 된겁니다. 프로젝트를 생성하고 이클립스 연동을 해 보죠.

lein new hello-www

이렇게 하면 leiningen 디렉토리 하위에 hello-www 디렉토리와 프로젝트를 위한 스켈레톤이 생성됩니다. 이클립스에서 편하게 Compojure 개발을 하려면 몇가지 더 추가하여야 합니다. hello-www 디렉토리를 보면 project.clj 파일이 있습니다. 에디터 등으로 열어서 다음과 같이 바꿔줍니다.

1
2
3
4
5
6
7
(defproject hello-www "0.0.1-SNAPSHOT"
  :description "FIXME: write"
  :dependencies [[org.clojure/clojure "1.2.0"]
                   [org.clojure/clojure-contrib "1.2.0"]
                   [compojure "0.4.0"]
                   [ring/ring-jetty-adapter "0.2.3"]
                   [lein-eclipse "1.0.0"]])

compojure 지원, jetty 지원, eclipse 지원을 추가한거죠.(아겔님 블로그 참조, lein-eclipse 홈페이지 참조) 그 다음에 해당 프로젝트 디렉토리에서 “lein deps” 명령을 사용합니다.

cd hello-www
..\lein.bat deps

그러면 “Copying 15 files to D:\src\lein\hello-www\lib” 와 같이 파일 몇 개를 복사했다고 알려줍니다. 필요한 jar 등을 가져온거죠.(다운로드 받을 수도 있습니다. 복사할 파일이 없으면 말이죠. 그리고 빌드 한번 해봐야죠.

..\lein.bat install

빌드는 maven을 이용하는 것 같습니다. pom.xml을 생성하거든요.(아직 정확히는 모르겠다는.. -_-;;)

Created D:\src\lein\hello-www/hello-www-0.0.1-SNAPSHOT.jar
Wrote pom.xml
[INFO] Installing D:\src\lein\hello-www\hello-www-0.0.1-SNAPSHOT.jar to C:\Docum
ents and Settings\LG\.m2\repository\hello-www\hello-www\0.0.1-SNAPSHOT\hello-www
-0.0.1-SNAPSHOT.jar

이렇게 말이죠.
이번엔 이클립스 지원을 추가해야죠.

..\lein eclipse

.classpath 파일과 .project 파일이 생성됩니다. 그럼 이클립스에서 import 하면 되죠. import->Existing Projects into Workspace 선택한 후 생성된 프로젝트(d:\src\leiningen\hello-www)를 선택하면 됩니다.

4. 생성된 프로젝트에 클로져 지원을 추가해줍니다.(프로젝트 오른쪽 클릭 -> “enable/disable clojure language support”) 그러면 Run As 메뉴에 “New Clojure project’s JVM, with a REPL”이 추가되어 있어요. 이제 이클립스에서 REPL을 사용할 수 있게 됬습니다.

5. 한번 코드를 동작시켜봐야죠? src/hello-www/core.clj 파일을 다음과 같이 수정하시거나 REPL에 바로 작성하셔도 됩니다.

1
2
3
4
5
6
7
8
9
10
(ns hello-www.core
  (:use compojure.core
        ring.adapter.jetty)
  (:require [compojure.route :as route]))
 
(defroutes example
  (GET "/" [] "<h1>Hello World Wide Web!</h1>")
  (route/not-found "Page not found"))
 
(run-jetty example {:port 8080})

요러면 http://localhost:8080 에서 “Hello World Wide Web!” 라는 글자를 볼 수 있을 겁니다.

6. 클로져 코딩하며 놀기~~

저 스스로도 잊어버리지 않으려고 적어놨습니다만… 썩 간단하지가 않군요. -_-

Emacs 단축키 리스트


발췌 : http://www.cs.rutgers.edu/LCSR-Computing/some-docs/emacs-chart.html

Lisp 프로그래밍하려면 역시 emacs를 써야 하나봅니다. 이것저것 삽질하다가 결국 emacs와 친해지려고 노력해야겠다 싶더군요.

 

Emacs Command Summary

Emacs command summary, Thu Jul 25.

C-SP     set-mark-command		 C-q      quoted-insert
C-a      beginning-of-line		 C-r      isearch-backward
C-b      backward-char			 C-s      isearch-forward
C-c      exit-recursive-edit		 C-t      transpose-chars
C-d      delete-char			 C-u      universal-argument
C-e      end-of-line			 C-v      scroll-up
C-f      forward-char			 C-w      kill-region
C-h      help-command			 C-x      Control-X-prefix
TAB      indent-for-tab-command		 C-y      yank
LFD      newline-and-indent		 C-z      suspend-emacs
C-k      kill-line			 ESC      ESC-prefix
C-l      recenter			 C-]      abort-recursive-edit
RET      newline			 C-_      undo
C-n      next-line			 SPC .. ~        self-insert-command
C-o      open-line			 DEL      delete-backward-char
C-p      previous-line

C-h v    describe-variable		 C-h d    describe-function
C-h w    where-is			 C-h k    describe-key
C-h t    help-with-tutorial		 C-h c    describe-key-briefly
C-h s    describe-syntax		 C-h b    describe-bindings
C-h n    view-emacs-news		 C-h a    command-apropos
C-h C-n  view-emacs-news		 C-h C-d  describe-distribution
C-h m    describe-mode			 C-h C-c  describe-copying
C-h l    view-lossage			 C-h ?    help-for-help
C-h i    info				 C-h C-h  help-for-help
C-h f    describe-function

C-x C-a  add-mode-abbrev		 C-x 5    split-window-horizontally
C-x C-b  list-buffers			 C-x ;    set-comment-column
C-x C-c  save-buffers-kill-emacs	 C-x <    scroll-left
C-x C-d  list-directory			 C-x =    what-cursor-position
C-x C-e  eval-last-sexp			 C-x >    scroll-right
C-x C-f  find-file			 C-x [    backward-page
C-x C-h  inverse-add-mode-abbrev	 C-x ]    forward-page
C-x TAB  indent-rigidly			 C-x ^    enlarge-window
C-x C-l  downcase-region		 C-x `    next-error
C-x C-n  set-goal-column		 C-x a    append-to-buffer
C-x C-o  delete-blank-lines		 C-x b    switch-to-buffer
C-x C-p  mark-page			 C-x d    dired
C-x C-q  toggle-read-only		 C-x e    call-last-kbd-macro
C-x C-r  find-file-read-only		 C-x f    set-fill-column
C-x C-s  save-buffer			 C-x g    insert-register
C-x C-t  transpose-lines		 C-x h    mark-whole-buffer
C-x C-u  upcase-region			 C-x i    insert-file
C-x C-v  find-alternate-file		 C-x j    register-to-dot
C-x C-w  write-file			 C-x k    kill-buffer
C-x C-x  exchange-dot-and-mark		 C-x l    count-lines-page
C-x C-z  suspend-emacs			 C-x m    mail
C-x ESC  repeat-complex-command		 C-x n    narrow-to-region
C-x $    set-selective-display		 C-x o    other-window
C-x (    start-kbd-macro		 C-x p    narrow-to-page
C-x )    end-kbd-macro			 C-x q    kbd-macro-query
C-x +    add-global-abbrev		 C-x r    copy-rectangle-to-register
C-x -    inverse-add-global-abbrev	 C-x s    save-some-buffers
C-x .    set-fill-prefix		 C-x u    advertised-undo
C-x /    dot-to-register		 C-x w    widen
C-x 0    delete-window			 C-x x    copy-to-register
C-x 1    delete-other-windows		 C-x {    shrink-window-horizontally
C-x 2    split-window-vertically	 C-x }    enlarge-window-horizontally
C-x 4    ctl-x-4-prefix			 C-x DEL  backward-kill-sentence

ESC C-SP mark-sexp			 ESC =    count-lines-region
ESC C-a  beginning-of-defun		 ESC >    end-of-buffer
ESC C-b  backward-sexp			 ESC @    mark-word
ESC C-c  exit-recursive-edit		 ESC O    ??
ESC C-d  down-list			 ESC [    backward-paragraph
ESC C-e  end-of-defun			 ESC \    delete-horizontal-space
ESC C-f  forward-sexp			 ESC ]    forward-paragraph
ESC C-h  mark-defun			 ESC ^    delete-indentation
ESC LFD  indent-new-comment-line	 ESC a    backward-sentence
ESC C-k  kill-sexp			 ESC b    backward-word
ESC C-n  forward-list			 ESC c    capitalize-word
ESC C-o  split-line			 ESC d    kill-word
ESC C-p  backward-list			 ESC e    forward-sentence
ESC C-s  isearch-forward-regexp		 ESC f    forward-word
ESC C-t  transpose-sexps		 ESC g    fill-region
ESC C-u  backward-up-list		 ESC h    mark-paragraph
ESC C-v  scroll-other-window		 ESC i    tab-to-tab-stop
ESC C-w  append-next-kill		 ESC j    indent-new-comment-line
ESC ESC  ??				 ESC k    kill-sentence
ESC C-\  indent-region			 ESC l    downcase-word
ESC SPC  just-one-space			 ESC m    back-to-indentation
ESC !    shell-command			 ESC q    fill-paragraph
ESC $    spell-word			 ESC r    move-to-window-line
ESC %    query-replace			 ESC t    transpose-words
ESC '    abbrev-prefix-mark		 ESC u    upcase-word
ESC (    insert-parentheses		 ESC v    scroll-down
ESC )    move-past-close-and-reindent	 ESC w    copy-region-as-kill
ESC ,    tags-loop-continue		 ESC x    execute-extended-command
ESC -    negative-argument		 ESC y    yank-pop
ESC .    find-tag			 ESC z    zap-to-char
ESC 0 .. ESC 9  digit-argument		 ESC |    shell-command-on-region
ESC ;    indent-for-comment		 ESC ~    not-modified
ESC <    beginning-of-buffer		 ESC DEL  backward-kill-word

C-x 4 C-f       find-file-other-window	 C-x 4 d  dired-other-window
C-x 4 .  find-tag-other-window		 C-x 4 f  find-file-other-window
C-x 4 b  pop-to-buffer			 C-x 4 m  mail-other-window