1 # $Id: source.rb,v 1.11 2012/04/17 02:49:40 machan Exp $
2
3 require 'tmdoc/tmstd'
4 require 'tmdoc/tmstd/docbook'
5 require 'tmdoc/constant'
6 require 'tmdoc/model/document'
7 require 'tmdoc/transformer/document-into-docbook/node'
8 require 'tmdoc/transformer/localizable-string'
9
10
11 module TmDoc
12
13 module Transformer::DocumentIntoDocBook
14
15 module Source
16 def self.read_file(dir_name, file_name, env)
17 ASSERT.kind_of dir_name, String
18 ASSERT.kind_of file_name, String
19 ASSERT.kind_of env, ENV::Environment
20
21 expand_file_path = Reader.check_file(dir_name, file_name, env)
22 return nil unless expand_file_path
23
24 lines = nil
25 begin
26 lines = IO.readlines(expand_file_path)
27 rescue SystemCallError => exception
28 LOG::Error.log(
29 "System call error in reading file\n" + "\t%s (%s)",
30 exception.to_s, exception.class.to_s
31 )
32 CMD.test_sensitive_level env, LOG::Error
33 rescue IOError => exception
34 LOG::Error.log "I/O error: '%s'", expand_file_path
35 CMD.test_sensitive_level env, LOG::Error
36 end
37 return nil unless lines
38
39 LSM::SeqOfString.new lines
40 end
41
42
43
44 module_function
45
46 def transform_sources(
47 md_sources, env, title, id, source_dir_name, tab_width, show_code
48 )
49 ASSERT.kind_of md_sources, MDS::SeqOfSource
50 ASSERT.kind_of env, ENV::Environment
51 ASSERT.kind_of title, String
52 ASSERT.kind_of id, String
53 ASSERT.kind_of source_dir_name, String
54 ASSERT.kind_of tab_width, Integer
55 ASSERT.boolean show_code
56
57 return nil if md_sources.empty?
58
59 mb_documents = MBD::SeqOfDocument.new(
60 md_sources.map { |md_source|
61 ASSERT.kind_of md_source, MDS::Source
62
63 LOG::Progress.log("\t\t%s", md_source.name)
64
65 transform(
66 md_source, env, source_dir_name, tab_width, show_code
67 )
68 }.compact
69 )
70 return nil if mb_documents.empty?
71
72 MBD::Node.new(
73 id,
74 DBOOK.chapter(:id => id) {
75 [
76 DBOOK.chapter_info {
77 [ DBOOK.title(title) ]
78 }
79 ] + mb_documents.map { |mb_document|
80 ASSERT.kind_of mb_document, MBD::Leaf
81
82 DBOOK.include(mb_document.name, OUTPUT_FILE_SUFFIX)
83 }
84 },
85 mb_documents
86 )
87 end
88
89
90 def transform(md_file, env, source_dir_name, tab_width, show_code)
91 ASSERT.kind_of md_file, MDS::Source
92 ASSERT.kind_of env, ENV::Environment
93 ASSERT.kind_of source_dir_name, String
94 ASSERT.kind_of tab_width, Integer
95 ASSERT.boolean show_code
96
97 name = md_file.name
98 title = TLS::DIV_FILE + ': ' + name
99 id = Id.transform_file(name)
100
101
102 mb_code =
103 if show_code
104 lines = Source.read_file(source_dir_name, name, env)
105
106 if lines && (! lines.empty?)
107 transform_code(
108 lines,
109 env,
110 TLS::DIV_CODE,
111 id + Id::SEP + Id::DIV_NAME_OF_CODE,
112 name,
113 md_file.map_of_line_num_to_links,
114 tab_width
115 )
116 else
117 nil
118 end
119 else
120 nil
121 end
122
123 MBD::Leaf.new(
124 id,
125
126 DBOOK.section(:id => id) {
127 [
128 DBOOK.section_info {
129 [ DBOOK.title(title) ]
130 },
131
132 transform_overview(id, md_file, show_code),
133
134 mb_code
135 ].compact
136 }
137 )
138 end
139
140
141 def transform_overview(file_id, md_file, show_code)
142 ASSERT.kind_of file_id, String
143 ASSERT.kind_of md_file, MDS::Source
144 ASSERT.boolean show_code
145
146 contents = [
147 if md_file.a_module_structure
148 Node.transform_logical_structure(
149 md_file.a_module_structure,
150 TLS::DIV_M_STRUCTURE,
151 Id.transform_module_section(
152 file_id, Id::DIV_NAME_OF_M_STRUCTURE
153 ),
154 Id::DIV_NAME_OF_M_STRUCTURE,
155 :show_type_label => true,
156 :show_line_num_in_infobox => true,
157 :show_code => show_code
158 )
159 else
160 nil
161 end,
162
163 if md_file.a_class_hierarchy
164 Node.transform_logical_structure(
165 md_file.a_class_hierarchy,
166 TLS::DIV_C_HIERARCHY,
167 Id.transform_module_section(
168 file_id, Id::DIV_NAME_OF_C_HIERARCHY
169 ),
170 Id::DIV_NAME_OF_C_HIERARCHY,
171 :show_above_link => true,
172 :show_code => show_code
173 )
174 else
175 nil
176 end
177 ].compact
178 return nil if contents.empty?
179
180 DBOOK.section {
181 [
182 DBOOK.section_info {
183 [ DBOOK.title(TLS::DIV_OVERVIEW) ]
184 }
185 ] + contents
186 }
187 end
188
189
190 LINE_NUM_WIDTH = 4
191
192 def transform_code(
193 lines,
194 env,
195 title,
196 id,
197 file_name,
198 map_of_line_num_to_links,
199 tab_width
200 )
201 ASSERT.kind_of lines, LSM::SeqOfString
202 ASSERT.kind_of env, ENV::Environment
203 ASSERT.kind_of title, String
204 ASSERT.kind_of id, String
205 ASSERT.kind_of file_name, String
206 ASSERT.kind_of(
207 map_of_line_num_to_links, MDL::MapOfLineNumToLinks
208 )
209 ASSERT.kind_of tab_width, Integer
210
211 contents = lines.map_with_index { |line, index|
212 formating_line = line.chop.split(
213 /\t/
214 ).inject('') { |result, elem|
215 n = (result.length + tab_width) % tab_width
216 tab_stop = ' ' * (tab_width - n)
217
218 result + tab_stop + elem
219 }
220 formated_line =
221 if formating_line.length >= tab_width
222 formating_line[
223 (tab_width - 1) .. (formating_line.length - 1)
224 ]
225 else
226 formating_line
227 end
228
229 line_num = index + 1
230 links = map_of_line_num_to_links.at line_num
231
232 if links && links.length >= 1
233 md_link = links.first
234 link_id =
235 case md_link
236 when MDL::Module
237 Id.transform_module(
238 md_link.above_path, md_link.name
239 )
240 when MDL::Property
241 module_id = Id.transform_module(
242 *md_link.module_path.pop
243 )
244
245 Id.transform_property(
246 module_id, md_link.name, md_link.uniq_num
247 )
248 else
249 ASSERT.abort(
250 "Unknown md_link: %s", md_link.to_s
251 )
252 end
253
254 line_num_str = line_num.to_s
255 line_num_width = line_num_str.length
256
257 [
258 if line_num_width < LINE_NUM_WIDTH
259 DBOOK.text(
260 ' ' * (LINE_NUM_WIDTH - line_num_width)
261 )
262 else
263 nil
264 end,
265
266 DBOOK.anchor(
267 :id => Id.transform_line(file_name, line_num)
268 ),
269
270 Link.transform_text(link_id, line_num_str),
271
272 DBOOK.text(format(" %s\n", formated_line))
273 ].compact
274 else
275 DBOOK.text(format("%4d %s\n", line_num, formated_line))
276 end
277 }.flatten
278
279 DBOOK.section(:id => id) {
280 [
281 DBOOK.section_info { [ DBOOK.title(title) ] },
282
283 DBOOK.program_listing { contents }
284 ]
285 }
286 end
287 end
288
289 end # TmDoc::Transformer::DocumentIntoDocBook
290
291 end # TmDoc