class HTMLBuilder

HTMLドキュメントを文法に正しく沿って構築するためのクラス。 拡張ライブラリによらずRubyだけで書かれているので処理系によらず動作する。s 簡明実用のため、DOM操作の機能はない。 Fileに対するプレーンテキストの出力のように必要な順で tagputsを呼べば HTMLが作られる。

Constants

BLOCKY_ELEMS

読みやすさのため、タグ名がこの正規表現にマッチする場合、開きタグの前と閉じタグの後に改行が挿入される。

VOID_ELEMS

HTMLでは一部のタグは内容を持つことが許されず、閉じタグを記載してはならないこととされている。 VOID_ELEMSはこのようなタグ名にマッチする正規表現である。 /A(area|base|br|col|embed|hr|img|input|link|meta|param|source|track|wbr)z/

Public Class Methods

good_name?(str) click to toggle source

引数strが要素・属性の名前として適切な文字列の場合に真を返す。 さしあたり字種をチェックしているだけである。

# File lib/html_builder.rb, line 30
def good_name? str
  /\A[0-9A-Za-z][-0-9A-Za-z]*\z/ === str
end
new(title) click to toggle source

HTMLドキュメントの構築を始める。引数 titleが(要すれば文字エスケープをした上で)title要素に設定される。このtitle要素のほかhead要素の一部は最初にタグを出力するまで変更可能である( header 参照).

# File lib/html_builder.rb, line 51
def initialize title
  @buf = ['<!DOCTYPE html>']
  # @head holds the content of <head> tag until _start_body is called.
  # _start_body clears it to indicate <head> can no longer be modified.
  @head = {
    :lang => 'ja',
    :title => title,
    :buf => []
  }
  # @stack is list of nested tags
  @stack = []
end
xmlattr(str) click to toggle source

引数 str を文字列化し、XML文書の属性値に 使えるようにメタキャラクタを実体参照に 置換した結果(String)を返す。 先頭・末尾がダブルクォートとなることに注意。

# File lib/html_builder.rb, line 24
def xmlattr str
  str.to_s.encode(Encoding::UTF_8, :xml => :attr)
end
xmltext(str) click to toggle source

引数 str を文字列化し、XML文書のテキストノードに 使えるようにメタキャラクタを実体参照に 置換した結果(String)を返す。

# File lib/html_builder.rb, line 16
def xmltext str
  str.to_s.encode(Encoding::UTF_8, :xml => :text)
end

Public Instance Methods

<<(str)
Alias for: puts
close_all_tags() click to toggle source

すべての開きっぱなしのタグを閉じる。 実は to_swrite の中で呼び出されるので、自分で呼び出す必要はあまりない。

# File lib/html_builder.rb, line 179
def close_all_tags
  while ! @stack.empty?
    close_tag
  end
end
close_tag(name = nil) click to toggle source

直近に tag で開いたタグを閉じる。 この文法を使わず、 tag にはすべてブロックを与えてタグを自動的に閉じることをおすすめする。

name

閉じたいタグ名。直近に開いたタグと一致しない場合例外となる。

次の例外が生じうる。

RuntimeError

すべてのタグが閉じられているのに close_tag が呼ばれた。

ArgumentError

引数 name が直近に開いたタグと不一致。なにか間違えている。

# File lib/html_builder.rb, line 143
def close_tag name = nil
  raise RuntimeError 'already closed HTML' if @stack.empty?
  sname = @stack.pop
  if name
    raise ArgumentError "<#{sname}> ... </#{name}>" if name != sname
  end
  @buf.push('</', sname, ">")
  _newline if BLOCKY_ELEMS === sname
end
header('lang', [String] lang) → self click to toggle source
header('title', [String] title) → self
header('base', 'href'=>url) → self
header('meta', 'http-equiv'=>fieldname, 'content'=>content) → self
header('link', 'rel'=>relation, 'href'=>url) → self
header('script', 'src'=>url) → self
header('script', 'text'=>text) → self
header('style', 'text'=>text) → self

引数itemの値に応じて各種メタ情報を設定する。 tag または puts より前に呼ばねばならない。

lang

HTMLドキュメントの言語を指定する。 デフォルトは日本語。英語ならば 'en' とする。 その他は en.wikipedia.org/wiki/List_of_ISO_639-1_codes をみてほしい。

title

ページの表題を指定する。コンストラクタ new で指定した表題を変更する。

text

<script> 及び <style> タグの内容。

例外

ArgumentError

未知のitemが指定された場合に発生する。

RuntimeError

既に tag 又は puts が呼ばれたためメタ情報を変更不可。

# File lib/html_builder.rb, line 88
def header item, attrs = {}
  raise RuntimeError "Can't modify frozen <head>" if @head.empty?
  case item
  when 'lang'
    @head[:lang] = attrs.to_s
  when 'title'
    @head[:title] = attrs.to_s
  when 'base', 'meta', 'link', 'isindex', 'script', 'style'
    @head[:buf].push [item, attrs]
  else
    raise ArgumentError "Unknown item #{item} for <head>"
  end
  self
end
puts(str) click to toggle source

引数 str を文字列化してテキストノードとして出力する。 不等号などメタキャラクタは ::xmltext で処理されるので、表示したいように出力すればよい。

# File lib/html_builder.rb, line 128
def puts str
  _start_body
  @buf.push HTMLBuilder.xmltext(str)
  self
end
Also aliased as: <<
table(cols, opts = {}) { |self| ... } click to toggle source

表組みに決まって用いられるタグ構造に従って tag を呼び出す。 複雑なマークアップ(スタイルシートのクラス指定など)を伴う表は、自力で tag を組み合わせて書いてほしい。

cols

列名を指定する配列。

opts

オプション。

次のオプションが実装されている。

'caption'

指定するとキャプションとして出力される。

ブロックでは <tbody> タグの中身(つまり必要数の <tr> タグ)を記載することが期待される。

# File lib/html_builder.rb, line 162
def table cols, opts = {}
  tag('table') {
    tag('thead') {
      tag('caption') { puts(opts[:caption]) } if opts[:caption]
      tag('tr') {
        cols.each {|colname|
          tag('th') { self.puts(colname) }
        }
      }
    }
    tag('tbody') { yield self }
  }
end
tag(name, attr=>{}) {|self| ... } → self click to toggle source
tag(name, attr=>{}) → self

名前 name のHTMLタグを出力する。 ブロックを与えた場合、ブロック内で tag 又は puts を呼んだ結果は タグ内に作られ、閉じタグが自動的に作られる。 ブロックを与えない場合は close_tag 又は close_all_tags によって タグを閉じなければならない。 ただし、名前が VOID_ELEMS にあたる場合はHTML文法でタグ内容が 禁止されているので、 tag により開き閉じタグが出力され、閉じる必要はない。

# File lib/html_builder.rb, line 115
def tag name, attrs = {}
  _start_body
  if block_given?
    _tag(name, attrs) { yield self }
  else
    _tag(name, attrs)
  end
  self
end
to_s() click to toggle source

HTMLドキュメントを構築して文字列(String)として返す。 この場合、文字列のエンコーディングを確定させてファイルに書き出すのはプログラマーの責任である。

# File lib/html_builder.rb, line 197
def to_s
  close_all_tags
  @buf.flatten.join
end
write(output=$stdout) click to toggle source

HTMLドキュメントを構築して output の指すファイルに書き出す。

# File lib/html_builder.rb, line 187
def write output=$stdout
  close_all_tags
  output.set_encoding(Encoding::UTF_8)
  @buf.each {|str| output << str }
  self
end