1 # $Id: link.rb,v 1.15 2012/01/24 03:46:19 machan Exp $
2
3 require 'tmdoc/tmstd'
4 require 'tmdoc/tmstd/cache'
5 require 'tmdoc/tmstd/docbook'
6 require 'tmdoc/constant'
7 require 'tmdoc/model/document'
8 require 'tmdoc/transformer/localizable-string'
9
10
11 module TmDoc
12
13 module Transformer::DocumentIntoDocBook
14
15 module Link
16
17 module CacheDomain
18
19 class Abstract < TmStd::Lsm::Product::Abstract
20 attr_reader :link_id, :content
21
22
23 def initialize(link_id, content)
24 ASSERT.kind_of link_id, String
25 ASSERT.kind_of content, String
26
27 @link_id = link_id
28 @content = content
29
30 @link_id.freeze
31 @content.freeze
32 end
33
34
35 def to_s
36 str = format("%s %s", self.link_id, self.content)
37
38 ASSERT.kind_of str, String
39 end
40
41
42 def hash
43 h = self.to_s.hash
44
45 ASSERT.kind_of h, Integer
46 end
47
48
49 def eql?(other)
50 ASSERT.kind_of other, Abstract
51
52 result = self.link_id == other.link_id &&
53 self.content == other.content
54
55 ASSERT.boolean result
56 end
57 end
58
59
60
61 class Text < Abstract; end
62
63
64
65 class Name < Abstract
66 alias name content
67 end
68
69
70
71 class Property < Name
72 attr_reader :uniq_num, :max_uniq_num
73
74
75 def initialize(link_id, name, uniq_num, max_uniq_num)
76 ASSERT.kind_of link_id, String
77 ASSERT.kind_of name, String
78 ASSERT.kind_of uniq_num, Integer
79 ASSERT.kind_of max_uniq_num, Integer
80
81 super(link_id, name)
82
83 @uniq_num = uniq_num
84 @max_uniq_num = max_uniq_num
85
86 @uniq_num.freeze
87 @max_uniq_num.freeze
88 end
89
90
91 def to_s
92 str = format "%s %d %d", super, self.uniq_num, self.max_uniq_num
93
94 ASSERT.kind_of str, String
95 end
96
97
98 def eql?(other)
99 ASSERT.kind_of other, Property
100
101 result = super &&
102 self.uniq_num == other.uniq_num &&
103 self.max_uniq_num == other.max_uniq_num
104
105 ASSERT.boolean result
106 end
107 end
108
109
110
111 class File < Name
112 attr_reader :show_code
113
114
115 def initialize(link_id, name, show_code)
116 ASSERT.kind_of link_id, String
117 ASSERT.kind_of name, String
118 ASSERT.boolean show_code
119
120 super(link_id, name)
121
122 @show_code = show_code
123
124 @show_code.freeze
125 end
126
127
128 def to_s
129 str = format("%s %s",
130 super, if self.show_code then 'T' else 'F' end
131 )
132
133 ASSERT.kind_of str, String
134 end
135
136
137 def eql?(other)
138 ASSERT.kind_of other, File
139
140 result = super && self.show_code == other.show_code
141
142 ASSERT.boolean result
143 end
144 end
145
146
147
148 class Line < File
149 attr_reader :line_num
150
151 alias file_name name
152
153
154 def initialize(line_num, link_id, name, show_code)
155 ASSERT.kind_of line_num, Integer
156 ASSERT.kind_of link_id, String
157 ASSERT.kind_of name, String
158 ASSERT.boolean show_code
159
160 super(link_id, name, show_code)
161
162 @line_num = line_num
163
164 @line_num.freeze
165 end
166
167
168 def to_s
169 str = format("%s %d", super, self.line_num)
170
171 ASSERT.kind_of str, String
172 end
173
174
175 def eql?(other)
176 ASSERT.kind_of other, Line
177
178 result = super && self.line_num == other.line_num
179
180 ASSERT.boolean result
181 end
182 end
183
184 end
185
186
187
188 module CacheEntry
189
190 class Abstract < TmStd::Cache::AbstractEntry
191 LSM_DOMAIN_CLASS = CacheDomain::Abstract
192 LSM_RANGE_CLASS = TmStd::DocBook::Node::Link::Element
193 end
194
195
196
197 class Text < Abstract
198 LSM_DOMAIN_CLASS = CacheDomain::Text
199 end
200
201
202
203 class Name < Abstract
204 LSM_DOMAIN_CLASS = CacheDomain::Name
205 end
206
207
208
209 class Property < Abstract
210 LSM_DOMAIN_CLASS = CacheDomain::Name
211 end
212
213
214
215 class File < Abstract
216 LSM_DOMAIN_CLASS = CacheDomain::File
217 end
218
219
220
221 class Line < Abstract
222 LSM_DOMAIN_CLASS = CacheDomain::Line
223 end
224
225 end
226
227
228
229 class CacheManager < TmStd::Cache::AbstractManager
230 LSM_RANGE_CLASS = CacheEntry::Abstract
231
232 INIT_CACHE = {
233 :text_entry => CacheEntry::Text.new { |hash, dom|
234 ASSERT.kind_of dom, CacheDomain::Text
235
236 dom.freeze
237 hash[dom] = DBOOK.link(:linkend => dom.link_id) {
238 [ DBOOK.text(dom.content) ]
239 }
240 },
241 :file_entry => CacheEntry::File.new { |hash, dom|
242 ASSERT.kind_of dom, CacheDomain::File
243
244 dom.freeze
245 hash[dom] =
246 if dom.show_code
247 DBOOK.link(:linkend => dom.link_id) {
248 [ DBOOK.file_name(dom.name) ]
249 }
250 else
251 DBOOK.file_name(dom.name)
252 end
253 },
254 :line_entry => CacheEntry::Line.new { |hash, dom|
255 ASSERT.kind_of dom, CacheDomain::Line
256
257 db_line_num = DBOOK.text format("#%d", dom.line_num)
258
259 dom.freeze
260 hash[dom] =
261 if dom.show_code
262 DBOOK.link(
263 :linkend => Id.transform_line(
264 dom.file_name, dom.line_num
265 )
266 ) { [ db_line_num ] }
267 else
268 db_line_num
269 end
270 },
271 :module_entry => CacheEntry::Name.new { |hash, dom|
272 ASSERT.kind_of dom, CacheDomain::Name
273
274 dom.freeze
275 hash[dom] = DBOOK.link(:linkend => dom.link_id) {
276 [ DBOOK.class_name(dom.name) ]
277 }
278 },
279 :constant_entry => CacheEntry::Name.new { |hash, dom|
280 ASSERT.kind_of dom, CacheDomain::Name
281
282 dom.freeze
283 hash[dom] = DBOOK.link(:linkend => dom.link_id) {
284 [ DBOOK.constant(dom.name) ]
285 }
286 },
287 :alias_entry => CacheEntry::Property.new { |hash, dom|
288 ASSERT.kind_of dom, CacheDomain::Property
289
290 dom.freeze
291 hash[dom] = DBOOK.link(:linkend => dom.link_id) {
292 [ DBOOK.var_name(dom.name) ] +
293 Link.transform_uniq_num(
294 dom.uniq_num, dom.max_uniq_num
295 )
296 }
297 },
298 :attribute_entry => CacheEntry::Property.new { |hash, dom|
299 ASSERT.kind_of dom, CacheDomain::Property
300
301 dom.freeze
302 hash[dom] = DBOOK.link(:linkend => dom.link_id) {
303 [ DBOOK.var_name(dom.name) ] +
304 Link.transform_uniq_num(
305 dom.uniq_num, dom.max_uniq_num
306 )
307 }
308 },
309 :method_entry => CacheEntry::Property.new { |hash, dom|
310 ASSERT.kind_of dom, CacheDomain::Property
311
312 dom.freeze
313 hash[dom] = DBOOK.link(:linkend => dom.link_id) {
314 [ DBOOK.function(dom.name) ] +
315 Link.transform_uniq_num(
316 dom.uniq_num, dom.max_uniq_num
317 )
318 }
319 }
320 }
321
322
323 def initialize
324 super INIT_CACHE
325 end
326 end
327
328
329
330
331 module_function
332
333 def reset_cache!
334 @@cache_manager = CacheManager.new
335
336 nil
337 end
338
339
340
341 def transform_text(link_id, text)
342 ASSERT.kind_of link_id, String
343 ASSERT.kind_of text, String
344
345 db_link = @@cache_manager.text_entry.at(
346 CacheDomain::Text.new(link_id, text)
347 )
348
349 ASSERT.kind_of db_link, TmStd::DocBook::Node::Link::Element
350 end
351
352
353
354 def transform_lines(md_links_to_line, show_code)
355 ASSERT.kind_of md_links_to_line, MDL::SeqOfLine
356 ASSERT.boolean show_code
357
358 num_of_lines = md_links_to_line.length
359 ASSERT.assert num_of_lines >= 1
360
361 db_link =
362 if num_of_lines == 1
363 Link.transform_line(md_links_to_line.first, show_code)
364 else
365 DBOOK.simple_list(:type => 'inline') {
366 md_links_to_line.map { |md_link_to_line|
367 DBOOK.member {
368 [
369 Link.transform_line(
370 md_link_to_line, show_code
371 )
372 ]
373 }
374 }
375 }
376 end
377
378 ASSERT.kind_of db_link, TmStd::DocBook::Abstraction::Element
379 end
380
381
382 def transform_line(md_link_to_line, show_code = true)
383 ASSERT.kind_of md_link_to_line, MDL::Line
384 ASSERT.boolean show_code
385
386 file_name = md_link_to_line.file_name
387
388 db_link = @@cache_manager.line_entry.at(
389 CacheDomain::Line.new(
390 md_link_to_line.line_num,
391 Id.transform_file(file_name),
392 file_name,
393 show_code
394 )
395 )
396
397 ASSERT.kind_of db_link, TmStd::DocBook::Abstraction::Element
398 end
399
400
401 def transform_file(md_link_to_file, show_code)
402 ASSERT.kind_of md_link_to_file, MDL::File
403 ASSERT.boolean show_code
404
405 name = md_link_to_file.name
406
407 db_link = @@cache_manager.file_entry.at(
408 CacheDomain::File.new(
409 Id.transform_file(name),
410 name,
411 show_code
412 )
413 )
414
415 ASSERT.kind_of db_link, TmStd::DocBook::Node::Link::Element
416 end
417
418
419
420 def transform_link_to_module(md_link_to_module)
421 ASSERT.kind_of md_link_to_module, MDL::Module
422
423 above_path = md_link_to_module.above_path
424 name = md_link_to_module.name
425 display_name = Link.display_name_of_module(
426 md_link_to_module, name
427 )
428
429 db_link = Link.transform_module(
430 Id.transform_module(above_path, name),
431 (above_path << display_name).join('::')
432 )
433
434 ASSERT.kind_of db_link, TmStd::DocBook::Node::Link::Element
435 end
436
437
438 def transform_module(link_id, name)
439 ASSERT.kind_of link_id, String
440 ASSERT.kind_of name, String
441
442 db_link = @@cache_manager.module_entry.at(
443 CacheDomain::Name.new(link_id, name)
444 )
445
446 ASSERT.kind_of db_link, TmStd::DocBook::Node::Link::Element
447 end
448
449
450 def transform_constant(link_id, name)
451 ASSERT.kind_of link_id, String
452 ASSERT.kind_of name, String
453
454 db_link = @@cache_manager.constant_entry.at(
455 CacheDomain::Name.new(link_id, name)
456 )
457
458 ASSERT.kind_of db_link, TmStd::DocBook::Node::Link::Element
459 end
460
461
462 def transform_alias(link_id, name, uniq_num, max_uniq_num)
463 ASSERT.kind_of link_id, String
464 ASSERT.kind_of name, String
465 ASSERT.kind_of uniq_num, Integer
466 ASSERT.kind_of max_uniq_num, Integer
467
468 db_link = @@cache_manager.alias_entry.at(
469 CacheDomain::Property.new(
470 link_id, name, uniq_num, max_uniq_num
471 )
472 )
473
474 ASSERT.kind_of db_link, TmStd::DocBook::Node::Link::Element
475 end
476
477
478 def transform_attribute(link_id, name, uniq_num, max_uniq_num)
479 ASSERT.kind_of link_id, String
480 ASSERT.kind_of name, String
481 ASSERT.kind_of uniq_num, Integer
482 ASSERT.kind_of max_uniq_num, Integer
483
484 db_link = @@cache_manager.attribute_entry.at(
485 CacheDomain::Property.new(
486 link_id, name, uniq_num, max_uniq_num
487 )
488 )
489
490 ASSERT.kind_of db_link, TmStd::DocBook::Node::Link::Element
491 end
492
493
494 def transform_method(link_id, name, uniq_num, max_uniq_num)
495 ASSERT.kind_of link_id, String
496 ASSERT.kind_of name, String
497 ASSERT.kind_of uniq_num, Integer
498 ASSERT.kind_of max_uniq_num, Integer
499
500 db_link = @@cache_manager.method_entry.at(
501 CacheDomain::Property.new(
502 link_id, name, uniq_num, max_uniq_num
503 )
504 )
505
506 ASSERT.kind_of db_link, TmStd::DocBook::Node::Link::Element
507 end
508
509
510
511 def transform_uniq_num(uniq_num, max_uniq_num)
512 ASSERT.kind_of uniq_num, Integer
513 ASSERT.kind_of max_uniq_num, Integer
514
515 str_uniq_num = Module.transform_uniq_num(uniq_num, max_uniq_num)
516
517 uniq_num = if str_uniq_num
518 [ DBOOK.text(' ' + str_uniq_num) ]
519 else
520 []
521 end
522
523 ASSERT.kind_of uniq_num, Array
524 end
525
526
527 def display_name_of_module(md_link_to_module, opt_name)
528 ASSERT.kind_of md_link_to_module, MDL::Module
529 ASSERT.kind_of opt_name, String
530
531 display_name =
532 case md_link_to_module
533 when MDL::ToplevelModule
534 TLS::TOPLEVEL_MODULE
535 when MDL::BuiltinModule
536 TLS::BUILTIN_MODULE
537 when MDL::UnknownModule
538 TLS::UNKNOWN_MODULE
539 when MDL::UnknownClass
540 TLS::UNKNOWN_CLASS
541 else
542 opt_name
543 end
544
545 ASSERT.kind_of display_name, String
546 end
547 end
548
549
550
551 Link.reset_cache!
552
553 end # TmDoc::Transformer::DocumentIntoDocBook
554
555 end # TmDoc