레이블이 한글인 게시물을 표시합니다. 모든 게시물 표시
레이블이 한글인 게시물을 표시합니다. 모든 게시물 표시

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 시 적절히 저놈만 제외해줄수는 있나? 흠.