1 # $Id: factory.rb,v 1.15 2012/04/17 02:22:15 machan Exp $
2
3 require 'tmdoc/tmstd'
4 require 'tmdoc/tmstd/cache'
5 require 'tmdoc/tmstd/docbook/leaf'
6 require 'tmdoc/tmstd/docbook/node'
7
8
9 module TmStd
10
11 module DocBook
12
13 module Facade
14
15 class CacheDomain < Lsm::Product::Abstract
16 attr_reader :name, :attrs
17
18
19 def initialize(name = nil, attrs = {})
20 Assertion.opt_kind_of name, String
21 Assertion.kind_of attrs, Hash
22
23 Assertion.assert(
24 !(name.nil?) || !(attrs.empty?),
25 "name: %s, attrs: %s", name.to_s, attrs.inspect
26 )
27
28 @name = name
29 @attrs = attrs
30
31 @name.freeze
32 for key, val in @attrs
33 key.freeze
34 val.freeze
35 end
36 @attrs.freeze
37 end
38
39
40 def to_s
41 str = format("%s%s",
42 if self.name.nil? then '-' else self.name end,
43
44 if self.attrs.empty?
45 ''
46 else
47 format(" {%s}",
48 self.attrs.map { |key, val|
49 format "%s: %s", key.to_s, val.to_s
50 }.join(', ')
51 )
52 end
53 )
54
55 Assertion.kind_of str, String
56 end
57
58
59 def hash
60 h = self.to_s.hash
61
62 Assertion.kind_of h, Integer
63 end
64
65
66 def eql?(other)
67 Assertion.kind_of other, CacheDomain
68
69 result = (
70 self.name == other.name
71 ) && (
72 self.attrs.length == other.attrs.length
73 ) && (
74 self.attrs.all? { |key, val| val == other.attrs[key] }
75 )
76
77 Assertion.boolean result
78 end
79 end
80
81
82
83 class CacheEntry < Cache::AbstractEntry
84 LSM_DOMAIN_CLASS = CacheDomain
85 LSM_RANGE_CLASS = Abstraction::LeafElement
86 end
87
88
89
90 class CacheManager < Cache::AbstractManager
91 LSM_RANGE_CLASS = CacheEntry
92
93
94 INIT_CACHE = [
95 [:title, Leaf::Title::Element],
96 [:pub_date, Leaf::PubDate::Element],
97 [:primary, Leaf::Primary::Element],
98 [:secondary, Leaf::Secondary::Element],
99 [:tertiary, Leaf::Tertiary::Element],
100 [:literal, Leaf::Literal::Element],
101 [:constant, Leaf::Constant::Element],
102 [:var_name, Leaf::VarName::Element],
103 [:class_name, Leaf::ClassName::Element],
104 [:function, Leaf::Function::Element],
105 [:file_name, Leaf::FileName::Element],
106
107 [:index, Leaf::Index::Element],
108 [:anchor, Leaf::Anchor::Element],
109 [:column_spec, Leaf::ColSpec::Element]
110 ].inject({}) { |result, spec|
111 Assertion.tuple_of spec, [Symbol, Class]
112 member, elem_class = spec
113 Assertion.subclass_of elem_class, Abstraction::LeafElement
114
115 result.merge(
116 member => CacheEntry.new { |hash, dom|
117 Assertion.kind_of dom, CacheDomain
118
119 dom.freeze
120 hash[dom] = if dom.name.nil?
121 elem_class.new dom.attrs
122 elsif dom.attrs.empty?
123 elem_class.new dom.name
124 else
125 elem_class.new dom.name, dom.attrs
126 end
127 }
128 )
129 }
130
131
132 def initialize
133 super INIT_CACHE
134 end
135 end
136
137
138
139 module_function
140
141 def reset_cache!
142 @@text_cache = Hash.new { |hash, str|
143 Assertion.kind_of str, String
144
145 str.freeze
146 hash[str] = Leaf::Text::Element.new str
147 }
148 @@raw_text_cache = Hash.new { |hash, str|
149 Assertion.kind_of str, String
150
151 str.freeze
152 hash[str] = Leaf::RawText::Element.new str
153 }
154 @@cache_manager = CacheManager.new
155
156 nil
157 end
158
159
160
161 #####################################
162 ######## Leaf Elements ########
163 #####################################
164
165 def include(name, suffix)
166 Assertion.kind_of name, String
167 Assertion.kind_of suffix, String
168
169 Leaf::Include::Element.new name, suffix
170 end
171
172
173 def text(str)
174 Assertion.kind_of str, String
175
176 elem = @@text_cache[str]
177
178 Assertion.kind_of elem, Leaf::Text::Element
179 end
180
181
182 def raw_text(str)
183 Assertion.kind_of str, String
184
185 elem = @@raw_text_cache[str]
186
187 Assertion.kind_of elem, Leaf::RawText::Element
188 end
189
190
191 def title(name, attrs = {})
192 Assertion.kind_of name, String
193 Assertion.kind_of attrs, Hash
194
195 elem = @@cache_manager.title.at CacheDomain.new(name, attrs)
196
197 Assertion.kind_of elem, Leaf::Title::Element
198 end
199
200
201 def pub_date(name, attrs = {})
202 Assertion.kind_of name, String
203 Assertion.kind_of attrs, Hash
204
205 elem = @@cache_manager.pub_date.at CacheDomain.new(name, attrs)
206
207 Assertion.kind_of elem, Leaf::PubDate::Element
208 end
209
210
211 def primary(name, attrs = {})
212 Assertion.kind_of name, String
213 Assertion.kind_of attrs, Hash
214
215 elem = @@cache_manager.primary.at CacheDomain.new(name, attrs)
216
217 Assertion.kind_of elem, Leaf::Primary::Element
218 end
219
220
221 def secondary(name, attrs = {})
222 Assertion.kind_of name, String
223 Assertion.kind_of attrs, Hash
224
225 elem = @@cache_manager.secondary.at CacheDomain.new(name, attrs)
226
227 Assertion.kind_of elem, Leaf::Secondary::Element
228 end
229
230
231 def tertiary(name, attrs = {})
232 Assertion.kind_of name, String
233 Assertion.kind_of attrs, Hash
234
235 elem = @@cache_manager.tertiary.at CacheDomain.new(name, attrs)
236
237 Assertion.kind_of elem, Leaf::Tertiary::Element
238 end
239
240
241 def literal(name, attrs = {})
242 Assertion.kind_of name, String
243 Assertion.kind_of attrs, Hash
244
245 elem = @@cache_manager.literal.at CacheDomain.new(name, attrs)
246
247 Assertion.kind_of elem, Leaf::Literal::Element
248 end
249
250
251 def constant(name, attrs = {})
252 Assertion.kind_of name, String
253 Assertion.kind_of attrs, Hash
254
255 elem = @@cache_manager.constant.at CacheDomain.new(name, attrs)
256
257 Assertion.kind_of elem, Leaf::Constant::Element
258 end
259
260
261 def var_name(name, attrs = {})
262 Assertion.kind_of name, String
263 Assertion.kind_of attrs, Hash
264
265 elem = @@cache_manager.var_name.at CacheDomain.new(name, attrs)
266
267 Assertion.kind_of elem, Leaf::VarName::Element
268 end
269
270
271 def class_name(name, attrs = {})
272 Assertion.kind_of name, String
273 Assertion.kind_of attrs, Hash
274
275 elem = @@cache_manager.class_name.at CacheDomain.new(name, attrs)
276
277 Assertion.kind_of elem, Leaf::ClassName::Element
278 end
279
280
281 def function(name, attrs = {})
282 Assertion.kind_of name, String
283 Assertion.kind_of attrs, Hash
284
285 elem = @@cache_manager.function.at CacheDomain.new(name, attrs)
286
287 Assertion.kind_of elem, Leaf::Function::Element
288 end
289
290
291 def file_name(name, attrs = {})
292 Assertion.kind_of name, String
293 Assertion.kind_of attrs, Hash
294
295 elem = @@cache_manager.file_name.at CacheDomain.new(name, attrs)
296
297 Assertion.kind_of elem, Leaf::FileName::Element
298 end
299
300
301 def index(attrs = {})
302 Assertion.kind_of attrs, Hash
303
304 elem = @@cache_manager.index.at CacheDomain.new(nil, attrs)
305
306 Assertion.kind_of elem, Leaf::Index::Element
307 end
308
309
310 def anchor(attrs = {})
311 Assertion.kind_of attrs, Hash
312
313 elem = @@cache_manager.anchor.at CacheDomain.new(nil, attrs)
314
315 Assertion.kind_of elem, Leaf::Anchor::Element
316 end
317
318
319 def column_spec(attrs = {})
320 Assertion.kind_of attrs, Hash
321
322 elem = @@cache_manager.column_spec.at CacheDomain.new(nil, attrs)
323
324 Assertion.kind_of elem, Leaf::ColSpec::Element
325 end
326
327
328
329 #####################################
330 ######## Node Elements ########
331 #####################################
332
333 def book(attrs = {}, &block)
334 Assertion.kind_of attrs, Hash
335
336 Node::Book::Element.new attrs, &block
337 end
338
339
340 def book_info(attrs = {}, &block)
341 Assertion.kind_of attrs, Hash
342
343 Node::BookInfo::Element.new attrs, &block
344 end
345
346
347 def chapter(attrs = {}, &block)
348 Assertion.kind_of attrs, Hash
349
350 Node::Chapter::Element.new attrs, &block
351 end
352
353
354 def chapter_info(attrs = {}, &block)
355 Assertion.kind_of attrs, Hash
356
357 Node::ChapterInfo::Element.new attrs, &block
358 end
359
360
361 def section(attrs = {}, &block)
362 Assertion.kind_of attrs, Hash
363
364 Node::Section::Element.new attrs, &block
365 end
366
367
368 def section_info(attrs = {}, &block)
369 Assertion.kind_of attrs, Hash
370
371 Node::SectionInfo::Element.new attrs, &block
372 end
373
374
375 def index_term(attrs = {}, &block)
376 Assertion.kind_of attrs, Hash
377
378 Node::IndexTerm::Element.new attrs, &block
379 end
380
381
382 def para(attrs = {}, &block)
383 Assertion.kind_of attrs, Hash
384
385 Node::Para::Element.new attrs, &block
386 end
387
388
389 def program_listing(attrs = {}, &block)
390 Assertion.kind_of attrs, Hash
391
392 Node::ProgramListing::Element.new attrs, &block
393 end
394
395
396 def itemized_list(attrs = {}, &block)
397 Assertion.kind_of attrs, Hash
398
399 Node::ItemizedList::Element.new attrs, &block
400 end
401
402
403 def list_item(attrs = {}, &block)
404 Assertion.kind_of attrs, Hash
405
406 Node::ListItem::Element.new attrs, &block
407 end
408
409
410 def simple_list(attrs = {}, &block)
411 Assertion.kind_of attrs, Hash
412
413 Assertion.kind_of attrs, Hash
414
415 Node::SimpleList::Element.new attrs, &block
416 end
417
418
419 def member(attrs = {}, &block)
420 Assertion.kind_of attrs, Hash
421
422 Node::Member::Element.new attrs, &block
423 end
424
425
426 def variable_list(attrs = {}, &block)
427 Assertion.kind_of attrs, Hash
428
429 Node::VariableList::Element.new attrs, &block
430 end
431
432
433 def var_list_entry(attrs = {}, &block)
434 Assertion.kind_of attrs, Hash
435
436 Node::VarListEntry::Element.new attrs, &block
437 end
438
439
440 def term(attrs = {}, &block)
441 Assertion.kind_of attrs, Hash
442
443 Node::Term::Element.new attrs, &block
444 end
445
446
447 def informal_table(attrs = {}, &block)
448 Assertion.kind_of attrs, Hash
449
450 Node::InformalTable::Element.new attrs, &block
451 end
452
453
454 def table_group(attrs = {}, &block)
455 Assertion.kind_of attrs, Hash
456
457 Node::TGroup::Element.new attrs, &block
458 end
459
460
461 def table_body(attrs = {}, &block)
462 Node::TBody::Element.new attrs, &block
463 end
464
465
466 def row(attrs = {}, &block)
467 Assertion.kind_of attrs, Hash
468
469 Node::Row::Element.new attrs, &block
470 end
471
472
473 def entry(attrs = {}, &block)
474 Assertion.kind_of attrs, Hash
475
476 Node::Entry::Element.new attrs, &block
477 end
478
479
480 def entry_table(attrs = {}, &block)
481 Assertion.kind_of attrs, Hash
482
483 Node::EntryTbl::Element.new attrs, &block
484 end
485
486
487 def link(attrs = {}, &block)
488 Assertion.kind_of attrs, Hash
489
490 Node::Link::Element.new attrs, &block
491 end
492
493
494
495 module Extension
496
497 module_function
498
499 def informal_table(aligns, attrs = {}, &block)
500 Assertion.kind_of aligns, String
501 Assertion.kind_of attrs, Hash
502
503 cols = aligns.length
504 Assertion.assert cols >= 1
505
506 Facade.informal_table(attrs) {
507 [
508 Facade.table_group(:cols => cols) {
509 __transform_table_contents__(aligns, &block)
510 }
511 ]
512 }
513 end
514
515
516 def entry_table(aligns, &block)
517 Assertion.kind_of aligns, String
518
519 cols = aligns.length
520 Assertion.assert cols >= 1
521
522 Facade.entry_table(:cols => cols) {
523 __transform_table_contents__(aligns, &block)
524 }
525 end
526
527
528 def __transform_table_contents__(aligns, &block)
529 Assertion.kind_of aligns, String
530
531 aligns.scan(/./).map { |align_char|
532 Assertion.kind_of align_char, String
533
534 align_val = {
535 'c' => 'center',
536 'C' => 'char',
537 'j' => 'justify',
538 'l' => 'left',
539 'r' => 'right'
540 }[align_char]
541 Assertion.kind_of align_val, String
542
543 Facade.column_spec(:align => align_val)
544 } + [
545 Facade.table_body(&block)
546 ]
547 end
548 end
549
550 end
551
552
553
554 Facade.reset_cache!
555
556 end # TmStd::DocBook
557
558 end # TmStd