File: tmstd/docbook/abstraction.rb

Overview
Module Structure
Class Hierarchy
Code

Overview

Module Structure

  module: <Toplevel Module>
  module: TmStd#7
  module: DocBook#9
  module: Abstraction#11
has properties
constant: EMPTY_SEQ_OF_CONTENT #133
  class: Element#13
inherits from
  Abstract ( TmStd::Lsm::Product )
has properties
attribute: attr_id [R] #14
attribute: attr_class [R] #14
method: initialize / 1 #16
method: to_xml / 4 #39
method: parse_attributes / 2 #60
method: common_attributes #92
method: attributes / 1 #99
method: contents_to_xml #117
  class: Content#125
inherits from
  KindOf ( TmStd::Lsm::Sum )
  class: SeqOfContent#129
inherits from
  Abstract ( TmStd::Lsm::Collection::Sequence )
has properties
constant: LSM_ELEMENT_CLASS #130
  class: LeafElement#137
inherits from
  Element ( TmStd::DocBook::Abstraction )
  class: NodeElement#141
includes
  Enumerable ( Builtin-Module )
inherits from
  Element ( TmStd::DocBook::Abstraction )
has properties
attribute: contents [R] #144
method: initialize / 4 #147
method: each / 1 #176
method: contents_to_xml #185
  class: Division#199
inherits from
  NodeElement ( TmStd::DocBook::Abstraction )
has properties
constant: DOC_TYPE #200
method: to_xml / 2 #204
  class: Info#240
  class: List#244
  class: Row#248
  class: Entry#252
  class: Name#256
inherits from
  LeafElement ( TmStd::DocBook::Abstraction )
has properties
method: initialize / 2 #257
method: to_xml / 1 #267

Code

   1  # $Id: abstraction.rb,v 1.3 2012/04/17 02:49:40 machan Exp $
   2 
   3  require 'tmdoc/tmstd'
   4  require 'tmdoc/tmstd/xml'
   5 
   6 
   7  module TmStd
   8 
   9  module DocBook
  10 
  11  module Abstraction
  12 
  13  class Element < TmStd::Lsm::Product::Abstract
  14      attr_reader :attr_id, :attr_class
  15 
  16      def initialize(common_attrs = {})
  17          Assertion.kind_of common_attrs, Hash
  18 
  19          @attr_id = @attr_class = nil
  20          for key, val in common_attrs
  21              Assertion.kind_of key,  Symbol
  22 
  23              case key
  24              when :id
  25                  Assertion.kind_of val,  String, "Key: #{key}"
  26 
  27                  @attr_id = val
  28              when :class
  29                  Assertion.kind_of val,  String
  30 
  31                  @attr_class = val
  32              else
  33                  Assertion.abort "Unknown attribute key: '%s'", key
  34              end
  35          end
  36      end
  37 
  38 
  39      def to_xml(tag, specific_attrs = {}, opts = {}, &block)
  40          Assertion.kind_of tag,              Symbol
  41          Assertion.kind_of specific_attrs,   Hash
  42          Assertion.kind_of opts,             Hash
  43 
  44          attrs = common_attributes.merge(specific_attrs)
  45 
  46          Xml::Element.new(tag, attrs, opts) {
  47              xml_contents =  if block
  48                                  block.call
  49                              else
  50                                  contents_to_xml
  51                              end
  52 
  53              Assertion.kind_of xml_contents, Array
  54          }
  55      end
  56 
  57 
  58  private
  59 
  60      def parse_attributes(attrs = {}, attr_defs = {})
  61          Assertion.kind_of attrs,        Hash
  62          Assertion.kind_of attr_defs,    Hash
  63 
  64          result_attrs = attrs.inject({}) { |result, pair|
  65              Assertion.tuple_of  pair,   [Symbol, Object]
  66              key, val = pair
  67 
  68              attr_def = attr_defs[key]
  69              if attr_def
  70                  Assertion.tuple_of(
  71                      attr_def, [Class, Proc],
  72                      "Type declaration error on the attribute: '%s'", key
  73                  )
  74 
  75                  class_of_val, func = attr_def
  76                  Assertion.kind_of(val, class_of_val,
  77                      "Value type error on the attribute: '%s'", key
  78                  )
  79 
  80                  func.call val
  81 
  82                  result
  83              else
  84                  result.merge key => val
  85              end
  86          }
  87 
  88          Assertion.kind_of result_attrs, Hash
  89      end
  90 
  91 
  92      def common_attributes
  93          common_attrs = attributes :id => @attr_id, :class => @attr_class
  94 
  95          Assertion.kind_of common_attrs, Hash
  96      end
  97 
  98 
  99      def attributes(source_attrs = {})
 100          Assertion.kind_of source_attrs, Hash
 101 
 102          target_attrs = source_attrs.reject { |key, val|
 103              Assertion.kind_of key,  Symbol
 104 
 105              val.nil?
 106          }.inject({}) { |hash_of_attr, pair|
 107              Assertion.tuple_of pair, [Symbol, String]
 108              key, string = pair
 109 
 110              hash_of_attr.merge key => string
 111          }
 112 
 113          Assertion.kind_of target_attrs, Hash
 114      end
 115 
 116 
 117      def contents_to_xml
 118          []
 119      end
 120  end
 121 
 122 
 123 
 124 
 125  class Content < Lsm::Sum::KindOf; end
 126 
 127 
 128 
 129  class SeqOfContent < TmStd::Lsm::Collection::Sequence::Abstract
 130      LSM_ELEMENT_CLASS = Abstraction::Content
 131  end
 132 
 133  EMPTY_SEQ_OF_CONTENT = SeqOfContent.new
 134 
 135 
 136 
 137  class LeafElement < Element; end
 138 
 139 
 140 
 141  class NodeElement < Element
 142      include     Enumerable
 143 
 144      attr_reader :contents
 145 
 146 
 147      def initialize(contents_class, content_class, attrs = {}, &block)
 148          Assertion.subclass_of   contents_class, SeqOfContent
 149          Assertion.subclass_of   content_class,  Content
 150          Assertion.kind_of       attrs,          Hash
 151 
 152          super attrs
 153 
 154          @contents =
 155              if block
 156                  elements = block.call
 157                  Assertion.kind_of elements, Array
 158 
 159                  unless elements.empty?
 160                      contents_class.new(
 161                          elements.map { |elem|
 162                              Assertion.kind_of elem, Element
 163 
 164                              content_class.new(elem)
 165                          }
 166                      )
 167                  else
 168                      EMPTY_SEQ_OF_CONTENT
 169                  end
 170              else
 171                  EMPTY_SEQ_OF_CONTENT
 172              end
 173      end
 174 
 175 
 176      def each(&block)
 177          self.contents.each(&block)
 178 
 179          nil
 180      end
 181 
 182 
 183  private
 184 
 185      def contents_to_xml
 186          xml_contents = self.map { |content|
 187              xml_content = content.lsm_member.to_xml
 188              Assertion.kind_of xml_content, Xml::Abstraction::Unit
 189 
 190              xml_content
 191          }
 192 
 193          Assertion.kind_of xml_contents, Array
 194      end
 195  end
 196 
 197 
 198 
 199  class Division < NodeElement
 200      DOC_TYPE =
 201          '<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"' +
 202          ' "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">'
 203 
 204      def to_xml(tag, opts = {})
 205          Assertion.kind_of tag,          Symbol
 206          Assertion.kind_of opts,         Hash
 207 
 208 
 209          is_document = false
 210          for key, val in opts
 211              Assertion.kind_of key, Symbol
 212 
 213              case key
 214              when :is_document
 215                  Assertion.boolean val
 216 
 217                  is_document = val
 218              else
 219                  Assertion.abort "Unknown option: %s", key
 220              end
 221          end
 222 
 223          xml_elem =
 224              if is_document
 225                  Xml::Document.new(tag, DOC_TYPE, common_attributes) {
 226                      contents_to_xml
 227                  }
 228              else
 229                  Xml::Element.new(tag, common_attributes) {
 230                      contents_to_xml
 231                  }
 232              end
 233 
 234          Assertion.kind_of xml_elem, Xml::Element
 235      end
 236  end
 237 
 238 
 239 
 240  class Info < NodeElement; end
 241 
 242 
 243 
 244  class List < NodeElement; end
 245 
 246 
 247 
 248  class Row < NodeElement; end
 249 
 250 
 251 
 252  class Entry < NodeElement; end
 253 
 254 
 255 
 256  class Name < LeafElement
 257      def initialize(name, common_attrs = {})
 258          Assertion.kind_of name,         String
 259          Assertion.kind_of common_attrs, Hash
 260 
 261          super common_attrs
 262 
 263          @name = name
 264      end
 265 
 266 
 267      def to_xml(tag)
 268          Assertion.kind_of tag,  Symbol
 269 
 270          super(tag) { [ Xml::Text.new(@name) ] }
 271      end
 272  end
 273 
 274  end # TmStd::DocBook::Abstraction
 275 
 276  end # TmStd::DocBook
 277 
 278  end # TmStd