2009년 5월 29일 금요일

haskell, happstack 에서 Text.Html 통해서 한글 출력

  마이너 언어를 배울때 가장 골때리는게 한글문제다. 역시나 haskell 도
  마찬가지라 한글이 엮이면 좀 난감해 지는데 뭐 포터블한 한글파일명
  처리는 바라지도 않지만 그래도 리눅스상에서 한글을 뿌리는건
  가능해야겠지. 어쨌거나 기본 모듈인 Html.Text 로 간단히 한글을
  포함하는 html 을 만들어 보고 이놈을 Happstack 을 통해서 뿌려봤다.

  먼저 Text.Html 은 html 을 뽑아낼 함수덩어리들을 유지하다가
  renderHtml 등으로 실행을 하면 String 타입의 html 을 돌려주는 놈이라고
  보면 된다. haskell 의 String 타입은 아주 엿같다고 생각하기 때문에
  이런 동작이 그다지 맘에 들진 않지만.. 뭐 어쨌거나 String 으로만
  뽑아주게 되어있다.

  Happstack 은.. 뭐 결국 응답으로 쓸수있는 타입이 ToMessage 란
  타입클래스의 인스턴스여야 하는데 결론적으로 toMessage 라는 함수에
  의해서 ByteString 으로 변환후 이걸 브라우저에 뿌려준다고 보면
  되겠다.

  마침 Html 이 ToMessage 의 인스턴스로 잡혀있어서 따로 렌더를 부르지
  않고 바로 Html 을 리턴해주면 알아서 적절히 풀어주게 되어있는데
  문제는! 이 인스턴스 구현 소스를 보면 알지만 renderHtml 한 결과물인
  String 을 Data.ByteString.Lazy.Char8.pack 을 통해서 바이트스트링으로
  바꾼다는거다. Char8 타입이 어떻게 돌지는 모르겠다만 유니코드를
  담고있는데 8 이란꼬릴 달고있는 타입을 적용했다는거 자체가 뭔가
  안좋다는게 느껴진다.

import qualified Data.ByteString.Char8 as B
import qualified Data.ByteString.Lazy.Char8 as L

instance ToMessage Html where
toContentType _ = B.pack "text/html"
toMessage = L.pack . renderHtml

  마침 얼마전에 봐둔 utf8-string 이란 패키지가 있었고 그쪽 문서를
  둘러보니 Data.ByteString.Lazy.UTF8 이란 모듈이 보였다.. 흠. 이런식의
  모듈간의 호환성을 이용한 라이브러리 구성은 정말 익숙해지질
  않는군.. 어쨌거나 저놈을 이용해서 바이트스트링으로 바꿔주니 한글이 잘
  보이더라.

import Happstack.Server
import Text.Html
import qualified Data.ByteString.Char8 as B
import qualified Data.ByteString.Lazy.UTF8 as U

main = simpleHTTP conf handler
conf = Conf 8080 Nothing
handler = return f

hello = header << thetitle << "안녕"
+++ body << "세상"

f = U.fromString $ renderHtml hello

instance ToMessage U.ByteString where
toContentType _ = B.pack "text/html"
toMessage = id

  음.. 사실 ToMessage Html 인스턴스를 유니코드먹인걸로 덮어쓰고
  싶었는데 방법을 잘 모르겠네. 기존 인스턴스를 무시하고 새인스턴스를
  정의한다거나 하는건 안되나? newtype 으로 새 타입을 만들어주는 삽질을
  해줘야 하는건가? import 시 적절히 저놈만 제외해줄수는 있나? 흠.






 

댓글 없음: