C++ ときどき ごはん、わりとてぃーぶれいく☆

USAGI.NETWORKのなかのひとのブログ。主にC++。

CleverCSS-hs と Hakyll と ごめんなさい><

CleverCSS-hs

↑これは素晴らしい・w・b

CSSの人間が記述する為に作られた訳では無い様に感じるとてもだるいシンタックスから開放してくれる素敵なプリプロセッサです。

CSSの何がだるいかと言うと、

  • ブラケットによるブロック記法を要求される
  • 定義のネストが無い
  • 変数とか使えない

とか特に不満はそこらへん。複雑なネスト構文無いのにブラケット強いられるとか、内容もシンボルも同じ事何度も書く事を強いられるとかモウネ・w・;

そんな訳でCSSって、一般プログラムの世界で言えばそれはC++の様な高級言語ではなく、アセンブラーの様なものだと思う。策定中のCSS3でも特にこうしたシンタックス周りの改善は盛り込まれていない様に思えるし。議論は勿論されているのだろうけれど。

そういうわけで、特にそれを専門としたCSS職人ではない普通の人間ならばこれを手書きしたいとは思わないはずで、

  • 定義のシンタックスをネストしたい
  • 変数とか式とか使いたい

くらいは思う。そこで冒頭で紹介した CleverCSS-hs なるCSSプリプロセッサが輝くわけです(・∀・) 元は Python らしいけどうちは haskell 版しか使ってないのでこっちで紹介。

導入

HackageDB にあるので cab るだけ。

% cab install clevercss

コマンドラインから - 先ずはとりあえずお試し的な

CleverCSS 用のコードファイルを標準入力で投げつけると標準出力に処理結果が出てくる。

hoge.clevercss とか書く
*:
  font ->
    family: 'schoolbell', cursive

body:
  width: 640px
  margin: auto

.vh-list:
  list-style ->
    type: none
  padding ->
    left: 16px
  ul, li:
    padding ->
      left: 0
  li:
    ul:
      li:
        display: inline
        margin ->
          right: 4px
        padding ->
          left: 4px
          right: 4px
        border ->
          radius: 8px
        background ->
          color: hsla(0, 0%, 95%, 0.70)
  a:hover:
    border ->
      radius: 8px
    background ->
      color: hsla(0, 0%, 85%, 0.90)
clevercss コマンドで処理する
% clevercss < hoge.clevercss > hoge.css
hoge.css とかできてる
* {
    font-family: "schoolbell", cursive;
}

body {
    width: 640px;
    margin: auto;
}

.vh-list ul, .vh-list li {
    padding-left: 0;
}

.vh-list li ul li {
    display: inline;
    margin-right: 4px;
    padding-left: 4px;
    padding-right: 4px;
    border-radius: 8px;
    background-color: hsla 0, 0%, 95%, 0.7;
}

.vh-list li ul {
}

.vh-list li {
}

.vh-list a:hover {
    border-radius: 8px;
    background-color: hsla 0, 0%, 85%, 0.9;
}

.vh-list {
    list-style-type: none;
    padding-left: 16px;
}

「わぁい、クレバー!うさぎ、クレバー大好きっ!」

Haskellモジュールとして - Hakyll といっしょ

さて、どっちらかって言うとこちらの使い方が私にとっては本題・w・

今回は謎のシバンをスルーしてくれるGHCアンドキュメントぽい実装とか使うのもアレゲなので、素直に hakyll.lhs とかLHS(Literate Haskell) の TeX モードで!

#!/usr/bin/runhaskell
\begin{code}
{-# LANGUAGE OverloadedStrings #-}
import Control.Arrow ((>>>))
import Control.Arrow ((>>^))
import Hakyll
import Text.CSS.CleverCSS
import System.IO.Unsafe

main = hakyll $ do
  
  match "favicon.ico" $ do
    route   idRoute
    compile copyFileCompiler
  
  match "images/" $ do
    route   idRoute
    compile copyFileCompiler
  
  match "css/*.css" $ do
    route   idRoute
    compile compressCssCompiler
  
  match "css/*.clevercss" $ do
    route   $ setExtension "css"
    compile $ getResourceString
      >>^ cleverCSSFilter
      >>^ compressCss
  
  match "templates/*" $ compile templateCompiler
  
  match "*.markdown" $ do
    route   $ setExtension "html"
    compile $ pageCompiler
      >>> applyTemplateCompiler "templates/default.html"
      >>> relativizeUrlsCompiler

cleverCSSFilter :: String -> String
cleverCSSFilter i =
  case (unsafePerformIO $ cleverCSSConvert [] i []) of
    Right r -> r

\end{code}

ごめんなさい><ごめんなさい><ごめんなさい><ごめんなさい><ごめんなさい><ごめんなさい><ごめんなさい><ごめんなさい><ごめんなさい><ごめんなさい><ごめんなさい><ごめんなさい><ごめんなさい><ごめんなさい><ごめんなさい><ごめんなさい><ごめんなさい><ごめんなさい><ごめんなさい><ごめんなさい><ごめんなさい><ごめんなさい><ごめんなさい><ごめんなさい><ごめんなさい><ごめんなさい><ごめんなさい><ごめんなさい><ごめんなさい><ごめんなさい><

CleverCSS-hs がなんだか根深く IO な実装になっている様で、クレバーに String -> String に使える様にはなってない…様に私には見えたので、unsafePerformIOの目的外使用甚だしくはありますが Hakyll の処理、プレビュー等でこれによる問題は起こらない「だろう」と思い使ってしまいました。

unsafePerformIO を使わずに CleverCSSConvert をよりコンパクトかつクレバーに Hakyll へ組み込む知恵などあればお寄せ頂ければ幸いです。

ごめんなさい><