Hierarchical CSS Converter
Home >> Note >> Hierarchical CSS Converter

階層的CSSコンバータ

CSSの記述テクニック 階層宣言コーディング より.エントリ自体は,エイプリルフールネタなのですが,意外と便利そうな記述方法でしたので, 通常のCSSへのコンバータを記述してみました.

階層的CSSクラス

以下が,階層的CSSを解析するためのクラスのプロトタイプ宣言です(名前空間は,clx).

  template <
      class CharT,
      class Traits = std::char_traits<CharT>
  >
  class basic_hcss {
  public:
      typedef CharT char_type;
      typedef unsigned int size_type;
      typedef std::basic_string<CharT, Traits> string_type;
      typedef std::vector<string_type> selector_list;
      typedef cssdecl<CharT, Traits> declaration_type;
      typedef std::vector<string_type> declaration_list;
      
      basic_hcss();
      
      template <class InputIterator>
      explicit basic_hcss(InputIterator first, InputIterator last,
          const std::locale& loc = std::locale());
      explicit basic_hcss(const char_type* filename,
          const std::locale& loc = std::locale());
      explicit basic_hcss(const string_type& filename,
          const std::locale& loc = std::locale());
      
      template <class InputIterator>
      basic_hcss& assign(InputIterator first, InputIterator last,
          const std::locale& loc = std::locale());
      basic_hcss& assign(const char_type* filename,
          const std::locale& loc = std::locale());        
      basic_hcss& assign(const string_type& filename,
          const std::locale& loc = std::locale());
      
      size_type size() const;
      const string_type& selector(size_type i) const;
      const declaration_list& declarations(size_type i) const;
  };
  
  typedef basic_hcss<char> hcss;

コンストラクタ,またはassign()メソッドに,ファイル名,または入力ストリームバッファの イテレータ(istreambuf_iterator<char>)を指定すると階層的CSSの解析を行い, 結果を配列(vector)に格納します.解析結果にアクセスするためのメソッドは, selector()およびdeclarations()で,それぞれ添え字に対応するセレクタおよび宣言リストを返します. declarations()で返されるのは配列(vector)なので,さらにat()メソッドや[]演算子などを用いて それぞれの宣言にアクセスします.

例外処理

現在の実装では,以下の場合に例外をthrowします.

例外クラスのプロトタイプ宣言は,以下の通りです.

  class css_syntax_error : public std::runtime_error {
  public:
      typedef unsigned int size_type;
      typedef char char_type;
      typedef std::string string_type;
      
      explicit css_syntax_error(size_type n, const string_type& what_arg);
      size_type line();
  };

css_syntax_errorの例外オブジェクトをcatchした場合,line()メソッドで例外を検知した行数を 取得することができます.

制限事項

制限,その他注意事項としては,以下の通りです.

サンプルプログラム

最後に,このクラスを使用した簡単なコンバータのプログラム例を書いてみました.

  #include <cstdlib>
  #include <iostream>
  #include "hcss.h"
  
  int main(int argc, char* argv[]) {
      if (argc < 2) {
          std::cerr << "usage hcssconv filename" << std::endl;
          std::exit(-1);
      }
      
      try {
          clx::hcss hc;
          hc.assign(argv[1]);
          
          // print
          for (size_t i = 0; i < hc.size(); i++) {
              if (hc.declarations(i).empty()) continue;
              std::cout << hc.selector(i) << " {" << std::endl;
              for (size_t j = 0; j < hc.declarations(i).size(); j++) {
                  std::cout << "  " << hc.declarations(i).at(j).property << ": "
                      << hc.declarations(i).at(j).value << ';' << std::endl;
              }
              std::cout << '}' << std::endl;
              std::cout << std::endl;
          }
      }
      catch (clx::css_syntax_error& e) {
          std::cerr << argv[1] << ':' << e.line()
              << ": error: " << e.what() << std::endl;
          std::exit(-1);
      }
      catch (std::runtime_error& e) {
          std::cerr << e.what() << std::endl;
          std::exit(-1);
      }
      
      return 0;
  }

このプログラムは引数としてファイル名を渡すと,そのファイル中に記述されている階層的CSS を解析し,結果を標準出力へ出力します.以下のサンプルで試してみます.尚,現在のところ, コンパイルはgccでのみ確認しています.

  body {
    p.caution {
      color: red;
      font-weight: bold;
    }
  
    div.entry {
      background-color: #eee;
      p.caution {
        border: 1px solid green;
        margin: 1em;
      }
    }
  }

実行結果は以下の通りです.

  p.caution {
    color: red;
    font-weight: bold;
  }
  
  div.entry {
    background-color: #eee;
  }
  
  div.entry p.caution {
    border: 1px solid green;
    margin: 1em;
  }

なかなか面白いかもしれません.hcss_20070427.tar.gz