Almirah 0.1.7 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e9e49efacc05e9b7d14bb1aa9acd2797de76395eb7c21ae40242b6319e59a55b
4
- data.tar.gz: 6cdba1580e4c9501de9c3e8cf2d1e009a127014a67d0c0fe79d142bb1d8ac662
3
+ metadata.gz: 43cc55174ff93a8d851853fde51988ed8d331803f2fea4a421d2892dc7712d69
4
+ data.tar.gz: 74cac6c8e6fc5503dbc4eb35424c31f87d90247d150d4ac9ff2338e804174570
5
5
  SHA512:
6
- metadata.gz: 62705f4cd221a3964cb579309a09dadcda38688f1df974f026e4957dc3d2380089c690a2b95b7395ec1cdd64eeebb8fdb7ac94f869fb3e348814fba795aec1f6
7
- data.tar.gz: 53aa6e81cbe3b3156107e3a71fc3c95e9bc8920dfe1615a43d0a9f2de6f0d04fe4325368b9f5563b2833b7f9dfa1a76186a4df18ec223e8a140ccabae18c6dbd
6
+ metadata.gz: 644ae40f9e92eeab516faaffa88d25ad451e6384831a64294e3f2b180fed1535e164d00c031d1d9f13fabb66fef12b338d82add7e20051486f1850dd990fe377
7
+ data.tar.gz: ffc11811a9f06697f3a93079d39179fb7789d2d227e1ba3d594f51157178829505a0245bf979771ce61c4b50981fd6eed8774c6fc638e6e32404bbfef0f55236
@@ -1,377 +1,370 @@
1
- #
2
- require_relative "doc_types/base_document"
3
- require_relative "doc_types/specification"
4
- require_relative "doc_types/protocol"
5
- #
6
- require_relative "doc_items/text_line"
7
- require_relative "doc_items/doc_item"
8
- require_relative "doc_items/heading"
9
- require_relative "doc_items/paragraph"
10
- require_relative "doc_items/blockquote"
11
- require_relative "doc_items/code_block"
12
- require_relative "doc_items/todo_block"
13
- require_relative "doc_items/controlled_paragraph"
14
- require_relative "doc_items/markdown_table"
15
- require_relative "doc_items/controlled_table"
16
- require_relative "doc_items/image"
17
- require_relative "doc_items/markdown_list"
18
- require_relative "doc_items/doc_footer"
19
-
20
- require_relative "dom/document"
1
+ require_relative 'doc_types/base_document'
2
+ require_relative 'doc_types/specification'
3
+ require_relative 'doc_types/protocol'
4
+ require_relative 'doc_items/text_line'
5
+ require_relative 'doc_items/doc_item'
6
+ require_relative 'doc_items/heading'
7
+ require_relative 'doc_items/paragraph'
8
+ require_relative 'doc_items/blockquote'
9
+ require_relative 'doc_items/code_block'
10
+ require_relative 'doc_items/todo_block'
11
+ require_relative 'doc_items/controlled_paragraph'
12
+ require_relative 'doc_items/markdown_table'
13
+ require_relative 'doc_items/controlled_table'
14
+ require_relative 'doc_items/image'
15
+ require_relative 'doc_items/markdown_list'
16
+ require_relative 'doc_items/doc_footer'
17
+
18
+ require_relative 'dom/document'
21
19
 
22
20
  class DocFabric
21
+ @@color_index = 0
22
+ @@spec_colors = %w[cff4d2 fbeee6 ffcad4 bce6ff e4dfd9 f9e07f cbe54e d3e7ee eab595 86e3c3
23
+ ffdca2 ffffff ffdd94 d0e6a5 ffb284 f3dbcf c9bbc8 c6c09c]
23
24
 
24
- def self.add_lazy_doc_id(path)
25
- if res = /(\w+)[.]md$/.match(path)
26
- TextLine.add_lazy_doc_id(res[1])
27
- end
25
+ def self.add_lazy_doc_id(path)
26
+ if res = /(\w+)[.]md$/.match(path)
27
+ TextLine.add_lazy_doc_id(res[1])
28
28
  end
29
+ end
30
+
31
+ def self.create_specification(path)
32
+ color = @@spec_colors[@@color_index]
33
+ @@color_index += 1
34
+ @@color_index = 0 if @@color_index >= @@spec_colors.length
35
+ doc = Specification.new path
36
+ DocFabric.parse_document doc
37
+ doc.color = color
38
+ doc
39
+ end
40
+
41
+ def self.create_protocol(path)
42
+ doc = Protocol.new path
43
+ DocFabric.parse_document doc
44
+ doc
45
+ end
46
+
47
+ def self.parse_document(doc)
48
+ temp_md_table = nil
49
+ temp_md_list = nil
50
+ temp_code_block = nil
51
+
52
+ file = File.open(doc.path)
53
+ file_lines = file.readlines
54
+ file.close
55
+
56
+ file_lines.each do |s|
57
+ if s.lstrip != ''
58
+ if res = /^(\#{1,})\s(.*)/.match(s) # Heading
59
+
60
+ if temp_md_table
61
+ doc.items.append temp_md_table
62
+ temp_md_table = nil
63
+ end
64
+ if temp_md_list
65
+ doc.items.append temp_md_list
66
+ temp_md_list = nil
67
+ end
68
+
69
+ level = res[1].length
70
+ value = res[2]
71
+
72
+ if level == 1 && doc.title == ''
73
+ doc.title = value
74
+ level = 0 # Doc Title is a Root
75
+ Heading.reset_global_section_number
76
+ end
77
+
78
+ item = Heading.new(value, level)
79
+ item.parent_doc = doc
80
+ doc.items.append(item)
81
+ doc.headings.append(item)
82
+
83
+ elsif res = /^%\s(.*)/.match(s) # Pandoc Document Title
84
+
85
+ title = res[1]
86
+
87
+ if doc.title == ''
88
+ doc.title = title
89
+ Heading.reset_global_section_number
90
+ end
91
+
92
+ item = Heading.new(title, 0)
93
+ item.parent_doc = doc
94
+ doc.items.append(item)
95
+ doc.headings.append(item)
96
+
97
+ Heading.reset_global_section_number # Pandoc Document Title is not a section, so it shall not be taken into account in numbering
98
+
99
+ elsif res = /^\[(\S*)\]\s+(.*)/.match(s) # Controlled Paragraph
100
+
101
+ if temp_md_table
102
+ doc.items.append temp_md_table
103
+ temp_md_table = nil
104
+ end
105
+ if temp_md_list
106
+ doc.items.append temp_md_list
107
+ temp_md_list = nil
108
+ end
109
+
110
+ id = res[1]
111
+ text = res[2]
112
+ up_links = nil
113
+
114
+ # check if it contains the uplink (one or many)
115
+ # TODO: check this regular expression
116
+ first_pos = text.length # for trailing commas
117
+ tmp = text.scan(/(>\[(?>[^\[\]]|\g<0>)*\])/) # >[SRS-001], >[SYS-002]
118
+ if tmp.length > 0
119
+ up_links = []
120
+ tmp.each do |ul|
121
+ up_links.append(ul[0])
122
+ # try to find the real end of text
123
+ pos = text.index(ul[0])
124
+ first_pos = pos if pos < first_pos
125
+ # remove uplink from text
126
+ text = text.split(ul[0]).join('')
127
+ end
128
+ # remove trailing commas and spaces
129
+ if text.length > first_pos
130
+ first_pos -= 1
131
+ text = text[0..first_pos].strip
132
+ end
133
+ end
29
134
 
30
- def self.create_specification(path)
31
- doc = Specification.new path
32
- DocFabric.parse_document doc
33
- return doc
34
- end
135
+ # since we already know id and text
136
+ item = ControlledParagraph.new(text, id)
35
137
 
36
- def self.create_protocol(path)
37
- doc = Protocol.new path
38
- DocFabric.parse_document doc
39
- return doc
40
- end
138
+ if up_links
139
+ doc.items_with_uplinks_number += 1 # for statistics
140
+ up_links.each do |ul|
141
+ next unless tmp = />\[(\S*)\]$/.match(ul) # >[SRS-001]
142
+
143
+ up_link_id = tmp[1]
41
144
 
42
- def self.parse_document(doc)
43
-
44
- tempMdTable = nil
45
- tempMdList = nil
46
- tempCodeBlock = nil
47
-
48
- file = File.open( doc.path )
49
- file_lines = file.readlines
50
- file.close
51
-
52
- file_lines.each do |s|
53
- if s.lstrip != ""
54
- if res = /^([#]{1,})\s(.*)/.match(s) # Heading
55
-
56
- if tempMdTable
57
- doc.items.append tempMdTable
58
- tempMdTable = nil
59
- end
60
- if tempMdList
61
- doc.items.append tempMdList
62
- tempMdList = nil
63
- end
64
-
65
- level = res[1].length
66
- value = res[2]
67
-
68
- if level == 1 && doc.title == ""
69
- doc.title = value
70
- level = 0 # Doc Title is a Root
71
- Heading.reset_global_section_number()
72
- end
73
-
74
- item = Heading.new(value, level)
75
- item.parent_doc = doc
76
- doc.items.append(item)
77
- doc.headings.append(item)
78
-
79
- elsif res = /^\%\s(.*)/.match(s) # Pandoc Document Title
80
-
81
- title = res[1]
82
-
83
- if doc.title == ""
84
- doc.title = title
85
- Heading.reset_global_section_number()
86
- end
87
-
88
- item = Heading.new(title, 0)
89
- item.parent_doc = doc
90
- doc.items.append(item)
91
- doc.headings.append(item)
92
-
93
- Heading.reset_global_section_number() # Pandoc Document Title is not a section, so it shall not be taken into account in numbering
94
-
95
- elsif res = /^\[(\S*)\]\s+(.*)/.match(s) # Controlled Paragraph
96
-
97
- if tempMdTable
98
- doc.items.append tempMdTable
99
- tempMdTable = nil
100
- end
101
- if tempMdList
102
- doc.items.append tempMdList
103
- tempMdList = nil
104
- end
105
-
106
- id = res[1]
107
- text = res[2]
108
- up_links = nil
109
-
110
- #check if it contains the uplink (one or many)
111
- #TODO: check this regular expression
112
- first_pos = text.length # for trailing commas
113
- tmp = text.scan( /(>\[(?>[^\[\]]|\g<0>)*\])/ ) # >[SRS-001], >[SYS-002]
114
- if tmp.length >0
115
- up_links = Array.new
116
- tmp.each do |ul|
117
- up_links.append(ul[0])
118
- # try to find the real end of text
119
- pos = text.index(ul[0])
120
- if pos < first_pos
121
- first_pos = pos
122
- end
123
- # remove uplink from text
124
- text = text.split(ul[0]).join("")
125
- end
126
- # remove trailing commas and spaces
127
- if text.length > first_pos
128
- first_pos -= 1
129
- text = text[0..first_pos].strip
130
- end
131
- end
132
-
133
- # since we already know id and text
134
- item = ControlledParagraph.new( text, id )
135
-
136
- if up_links
137
- doc.items_with_uplinks_number += 1 #for statistics
138
- up_links.each do |ul|
139
- if tmp = />\[(\S*)\]$/.match(ul) # >[SRS-001]
140
- up_link_id = tmp[1]
141
-
142
- unless item.up_link_ids
143
- item.up_link_ids = Array.new
144
- end
145
-
146
- item.up_link_ids.append(up_link_id)
147
-
148
- if tmp = /^([a-zA-Z]+)[-]\d+/.match(up_link_id) # SRS
149
- doc.up_link_doc_id[ tmp[1].downcase.to_s ] = tmp[1].downcase # multiple documents could be up-linked
150
- end
151
- end
152
- end
153
- end
154
-
155
-
156
- item.parent_doc = doc
157
- item.parent_heading = doc.headings[-1]
158
-
159
- doc.items.append(item)
160
- #for statistics
161
- if doc.dictionary.has_key?( id.to_s )
162
- doc.duplicated_ids_number += 1
163
- doc.duplicates_list.append(item)
164
- else
165
- doc.dictionary[ id.to_s ] = item #for fast search
166
- end
167
- doc.controlled_items.append(item) #for fast search
168
-
169
- #for statistics
170
- n = /\d+/.match(id)[0].to_i
171
- if n > doc.last_used_id_number
172
- doc.last_used_id = id
173
- doc.last_used_id_number = n
174
- end
175
-
176
- elsif res = /^[!]\[(.*)\]\((.*)\)/.match(s) # Image
177
-
178
- if tempMdTable
179
- doc.items.append tempMdTable
180
- tempMdTable = nil
181
- end
182
- if tempMdList
183
- doc.items.append tempMdList
184
- tempMdList = nil
185
- end
186
-
187
- img_text = res[1]
188
- img_path = res[2]
189
-
190
- item = Image.new( img_text, img_path )
191
- item.parent_doc = doc
192
-
193
- doc.items.append(item)
194
-
195
- elsif res = /^(\*\s+)(.*)/.match(s) #check if unordered list start
196
-
197
- if tempMdTable
198
- doc.items.append tempMdTable
199
- tempMdTable = nil
200
- end
201
-
202
- row = res[2]
203
-
204
- if tempMdList
205
- tempMdList.addRow(s)
206
- else
207
- item = MarkdownList.new(false)
208
- item.addRow(s)
209
- item.parent_doc = doc
210
- tempMdList = item
211
- end
212
-
213
- elsif res = /^\d[.]\s(.*)/.match(s) #check if ordered list start
214
-
215
- if tempMdTable
216
- doc.items.append tempMdTable
217
- tempMdTable = nil
218
- end
219
-
220
- row = res[1]
221
-
222
- if tempMdList
223
- tempMdList.addRow(s)
224
- else
225
- item = MarkdownList.new(true)
226
- item.addRow(s)
227
- item.parent_doc = doc
228
- tempMdList = item
229
- end
230
-
231
- elsif s[0] == '|' #check if table
232
-
233
- if tempMdList
234
- doc.items.append tempMdList
235
- tempMdList = nil
236
- end
237
-
238
- if res = /^[|](-{3,})[|]/.match(s) #check if it is a separator first
239
-
240
- if tempMdTable
241
- #separator is found after heading - just skip it
242
- else
243
- #separator out of table scope consider it just as a regular paragraph
244
- item = Paragraph.new(s)
245
- item.parent_doc = doc
246
- doc.items.append(item)
247
- end
248
-
249
- elsif res = /^[|](.*[|])/.match(s) #check if it looks as a table
250
-
251
- row = res[1]
252
-
253
- if tempMdTable
254
- # check if it is a controlled table
255
- unless tempMdTable.addRow(row)
256
- tempMdTable = ControlledTable.new(tempMdTable, doc)
257
- tempMdTable.parent_doc = doc
258
- tempMdTable.addRow(row)
259
- end
260
- else
261
- #start table from heading
262
- tempMdTable = MarkdownTable.new(row)
263
- tempMdTable.parent_doc = doc
264
- end
265
- end
266
-
267
- elsif res = /^[>](.*)/.match(s) #check if blockquote
268
-
269
- if tempMdTable
270
- doc.items.append tempMdTable
271
- tempMdTable = nil
272
- end
273
- if tempMdList
274
- doc.items.append tempMdList
275
- tempMdList = nil
276
- end
277
-
278
- item = Blockquote.new(res[1])
279
- item.parent_doc = doc
280
- doc.items.append(item)
281
-
282
- elsif res = /^```(\w*)/.match(s) #check if code block
283
-
284
- if tempMdTable
285
- doc.items.append tempMdTable
286
- tempMdTable = nil
287
- end
288
- if tempMdList
289
- doc.items.append tempMdList
290
- tempMdList = nil
291
- end
292
-
293
- suggested_format = ""
294
- if res.length == 2
295
- suggested_format = res[1]
296
- end
297
-
298
- if tempCodeBlock
299
- # close already opened block
300
- doc.items.append(tempCodeBlock)
301
- tempCodeBlock = nil
302
- else
303
- #start code block
304
- tempCodeBlock = CodeBlock.new(suggested_format)
305
- tempCodeBlock.parent_doc = doc
306
- end
307
-
308
- elsif res = /^TODO\:(.*)/.match(s) #check if TODO block
309
-
310
- if tempMdTable
311
- doc.items.append tempMdTable
312
- tempMdTable = nil
313
- end
314
- if tempMdList
315
- doc.items.append tempMdList
316
- tempMdList = nil
317
- end
318
-
319
- text = "**TODO**: " + res[1]
320
-
321
- item = TodoBlock.new(text)
322
- item.parent_doc = doc
323
- doc.items.append(item)
324
- doc.todo_blocks.append(item)
325
-
326
- else # Reqular Paragraph
327
- if tempMdTable
328
- doc.items.append tempMdTable
329
- tempMdTable = nil
330
- end
331
- if tempMdList
332
- if MarkdownList.unordered_list_item?(s) || MarkdownList.ordered_list_item?(s)
333
- tempMdList.addRow(s)
334
- next
335
- else
336
- doc.items.append tempMdList
337
- tempMdList = nil
338
- end
339
- end
340
- if tempCodeBlock
341
- tempCodeBlock.code_lines.append(s)
342
- else
343
- item = Paragraph.new(s)
344
- item.parent_doc = doc
345
- doc.items.append(item)
346
- end
347
- end
145
+ item.up_link_ids = [] unless item.up_link_ids
146
+
147
+ item.up_link_ids.append(up_link_id)
148
+
149
+ if tmp = /^([a-zA-Z]+)-\d+/.match(up_link_id) # SRS
150
+ doc.up_link_doc_id[tmp[1].downcase.to_s] = tmp[1].downcase # multiple documents could be up-linked
151
+ end
152
+ end
153
+ end
154
+
155
+ item.parent_doc = doc
156
+ item.parent_heading = doc.headings[-1]
157
+
158
+ doc.items.append(item)
159
+ # for statistics
160
+ if doc.dictionary.has_key?(id.to_s)
161
+ doc.duplicated_ids_number += 1
162
+ doc.duplicates_list.append(item)
163
+ else
164
+ doc.dictionary[id.to_s] = item # for fast search
165
+ end
166
+ doc.controlled_items.append(item) # for fast search
167
+
168
+ # for statistics
169
+ n = /\d+/.match(id)[0].to_i
170
+ if n > doc.last_used_id_number
171
+ doc.last_used_id = id
172
+ doc.last_used_id_number = n
173
+ end
174
+
175
+ elsif res = /^!\[(.*)\]\((.*)\)/.match(s) # Image
176
+
177
+ if temp_md_table
178
+ doc.items.append temp_md_table
179
+ temp_md_table = nil
180
+ end
181
+ if temp_md_list
182
+ doc.items.append temp_md_list
183
+ temp_md_list = nil
184
+ end
185
+
186
+ img_text = res[1]
187
+ img_path = res[2]
188
+
189
+ item = Image.new(img_text, img_path)
190
+ item.parent_doc = doc
191
+
192
+ doc.items.append(item)
193
+
194
+ elsif res = /^(\*\s+)(.*)/.match(s) # check if unordered list start
195
+
196
+ if temp_md_table
197
+ doc.items.append temp_md_table
198
+ temp_md_table = nil
199
+ end
200
+
201
+ row = res[2]
202
+
203
+ if temp_md_list
204
+ temp_md_list.addRow(s)
205
+ else
206
+ item = MarkdownList.new(false)
207
+ item.addRow(s)
208
+ item.parent_doc = doc
209
+ temp_md_list = item
210
+ end
211
+
212
+ elsif res = /^\d[.]\s(.*)/.match(s) # check if ordered list start
213
+
214
+ if temp_md_table
215
+ doc.items.append temp_md_table
216
+ temp_md_table = nil
217
+ end
218
+
219
+ row = res[1]
220
+
221
+ if temp_md_list
222
+ temp_md_list.addRow(s)
223
+ else
224
+ item = MarkdownList.new(true)
225
+ item.addRow(s)
226
+ item.parent_doc = doc
227
+ temp_md_list = item
228
+ end
229
+
230
+ elsif s[0] == '|' # check if table
231
+
232
+ if temp_md_list
233
+ doc.items.append temp_md_list
234
+ temp_md_list = nil
235
+ end
236
+
237
+ if res = /^[|](-{3,})[|]/.match(s) # check if it is a separator first
238
+
239
+ if temp_md_table
240
+ # separator is found after heading - just skip it
348
241
  else
349
- if tempMdList # lists are separated by emty line from each other
350
- doc.items.append tempMdList
351
- tempMdList = nil
352
- end
242
+ # separator out of table scope consider it just as a regular paragraph
243
+ item = Paragraph.new(s)
244
+ item.parent_doc = doc
245
+ doc.items.append(item)
353
246
  end
247
+
248
+ elsif res = /^[|](.*[|])/.match(s) # check if it looks as a table
249
+
250
+ row = res[1]
251
+
252
+ if temp_md_table
253
+ # check if it is a controlled table
254
+ unless temp_md_table.addRow(row)
255
+ temp_md_table = ControlledTable.new(temp_md_table, doc)
256
+ temp_md_table.parent_doc = doc
257
+ temp_md_table.addRow(row)
258
+ end
259
+ else
260
+ # start table from heading
261
+ temp_md_table = MarkdownTable.new(row)
262
+ temp_md_table.parent_doc = doc
263
+ end
264
+ end
265
+
266
+ elsif res = /^>(.*)/.match(s) # check if blockquote
267
+
268
+ if temp_md_table
269
+ doc.items.append temp_md_table
270
+ temp_md_table = nil
271
+ end
272
+ if temp_md_list
273
+ doc.items.append temp_md_list
274
+ temp_md_list = nil
275
+ end
276
+
277
+ item = Blockquote.new(res[1])
278
+ item.parent_doc = doc
279
+ doc.items.append(item)
280
+
281
+ elsif res = /^```(\w*)/.match(s) # check if code block
282
+
283
+ if temp_md_table
284
+ doc.items.append temp_md_table
285
+ temp_md_table = nil
286
+ end
287
+ if temp_md_list
288
+ doc.items.append temp_md_list
289
+ temp_md_list = nil
290
+ end
291
+
292
+ suggested_format = ''
293
+ suggested_format = res[1] if res.length == 2
294
+
295
+ if temp_code_block
296
+ # close already opened block
297
+ doc.items.append(temp_code_block)
298
+ temp_code_block = nil
299
+ else
300
+ # start code block
301
+ temp_code_block = CodeBlock.new(suggested_format)
302
+ temp_code_block.parent_doc = doc
303
+ end
304
+
305
+ elsif res = /^TODO:(.*)/.match(s) # check if TODO block
306
+
307
+ if temp_md_table
308
+ doc.items.append temp_md_table
309
+ temp_md_table = nil
310
+ end
311
+ if temp_md_list
312
+ doc.items.append temp_md_list
313
+ temp_md_list = nil
314
+ end
315
+
316
+ text = '**TODO**: ' + res[1]
317
+
318
+ item = TodoBlock.new(text)
319
+ item.parent_doc = doc
320
+ doc.items.append(item)
321
+ doc.todo_blocks.append(item)
322
+
323
+ else # Reqular Paragraph
324
+ if temp_md_table
325
+ doc.items.append temp_md_table
326
+ temp_md_table = nil
327
+ end
328
+ if temp_md_list
329
+ if MarkdownList.unordered_list_item?(s) || MarkdownList.ordered_list_item?(s)
330
+ temp_md_list.addRow(s)
331
+ next
332
+ else
333
+ doc.items.append temp_md_list
334
+ temp_md_list = nil
335
+ end
336
+ end
337
+ if temp_code_block
338
+ temp_code_block.code_lines.append(s)
339
+ else
340
+ item = Paragraph.new(s)
341
+ item.parent_doc = doc
342
+ doc.items.append(item)
343
+ end
354
344
  end
355
- # Finalize non-closed elements
356
- if tempMdTable
357
- doc.items.append tempMdTable
358
- tempMdTable = nil
359
- end
360
- if tempMdList
361
- doc.items.append tempMdList
362
- tempMdList = nil
363
- end
364
- if tempCodeBlock
365
- doc.items.append tempCodeBlock
366
- tempCodeBlock = nil
367
- end
368
- # Add footer to close opened tables if any
369
- item = DocFooter.new
370
- item.parent_doc = doc
371
- doc.items.append(item)
372
- # Build dom
373
- if doc.is_a?(Specification)
374
- doc.dom = Document.new(doc.headings)
375
- end
345
+ elsif temp_md_list
346
+ doc.items.append temp_md_list
347
+ temp_md_list = nil # lists are separated by emty line from each other
348
+ end
349
+ end
350
+ # Finalize non-closed elements
351
+ if temp_md_table
352
+ doc.items.append temp_md_table
353
+ temp_md_table = nil
354
+ end
355
+ if temp_md_list
356
+ doc.items.append temp_md_list
357
+ temp_md_list = nil
358
+ end
359
+ if temp_code_block
360
+ doc.items.append temp_code_block
361
+ temp_code_block = nil
376
362
  end
377
- end
363
+ # Add footer to close opened tables if any
364
+ item = DocFooter.new
365
+ item.parent_doc = doc
366
+ doc.items.append(item)
367
+ # Build dom
368
+ doc.dom = Document.new(doc.headings) if doc.is_a?(Specification)
369
+ end
370
+ end
@@ -44,7 +44,7 @@ class Index < BaseDocument
44
44
 
45
45
  sorted_items.each do |doc|
46
46
  s = "\t<tr>\n"
47
- s += "\t\t<td class=\"item_text\" style='padding: 5px;'><a href=\"./specifications/#{doc.id}/#{doc.id}.html\" class=\"external\">#{doc.title}</a></td>\n"
47
+ s += "\t\t<td class=\"item_text\" style='padding: 5px;'><a href=\"./specifications/#{doc.id}/#{doc.id}.html\" class=\"external\"><i class=\"fa fa-file-text-o\" style='background-color: ##{doc.color};'> </i>&nbsp#{doc.title}</a></td>\n"
48
48
  s += "\t\t<td class=\"item_id\" style='width: 7%;'>#{doc.controlled_items.length.to_s}</td>\n"
49
49
  s += "\t\t<td class=\"item_id\" style='width: 7%;'>#{doc.items_with_uplinks_number.to_s}</td>\n"
50
50
  s += "\t\t<td class=\"item_id\" style='width: 7%;'>#{doc.items_with_downlinks_number.to_s}</td>\n"
@@ -97,18 +97,36 @@ class Index < BaseDocument
97
97
  s += "<table class=\"controlled\">\n"
98
98
  s += "\t<thead>\n"
99
99
  s += "\t\t<th>Title</th>\n"
100
+ s += "\t\t<th>Coverage</th>\n"
100
101
  s += "\t\t<th>Top Document</th>\n"
101
102
  s += "\t\t<th>Bottom Document</th>\n"
102
103
  s += "</thead>\n"
103
104
  html_rows.append s
104
105
 
105
106
  sorted_items = @project.traceability_matrices.sort_by { |w| w.id }
107
+ # buble-up design inputs
108
+ design_inputs = []
109
+ others = []
110
+ sorted_items.each do |doc|
111
+ if doc.bottom_doc
112
+ others.append doc
113
+ else
114
+ design_inputs.append doc
115
+ end
116
+ end
117
+ sorted_items = design_inputs + others
106
118
 
107
119
  sorted_items.each do |doc|
108
120
  s = "\t<tr>\n"
121
+ coverage = doc.traced_items.length.to_f / doc.top_doc.controlled_items.length.to_f * 100.0
109
122
  s += "\t\t<td class=\"item_text\" style='padding: 5px;'><a href=\"./specifications/#{doc.id}/#{doc.id}.html\" class=\"external\">#{doc.title}</a></td>\n"
110
- s += "\t\t<td class=\"item_text\" style='width: 25%; padding: 5px;'>#{doc.top_doc.title}</td>\n"
111
- s += "\t\t<td class=\"item_text\" style='width: 25%; padding: 5px;'>#{doc.bottom_doc.title}</td>\n"
123
+ s += "\t\t<td class=\"item_id\" style='width: 7%;'>#{'%.2f' % coverage}%</td>\n"
124
+ s += "\t\t<td class=\"item_text\" style='width: 25%; padding: 5px;'><i class=\"fa fa-file-text-o\" style='background-color: ##{doc.top_doc.color};'> </i>&nbsp#{doc.top_doc.title}</td>\n"
125
+ if doc.bottom_doc
126
+ s += "\t\t<td class=\"item_text\" style='width: 25%; padding: 5px;'><i class=\"fa fa-file-text-o\" style='background-color: ##{doc.bottom_doc.color};'> </i>&nbsp#{doc.bottom_doc.title}</td>\n"
127
+ else
128
+ s += "\t\t<td class=\"item_text\" style='width: 25%; padding: 5px;'><i class=\"fa fa-circle-o\"'> </i>&nbspAll References</td>\n"
129
+ end
112
130
  s += "</tr>\n"
113
131
  html_rows.append s
114
132
  end
@@ -15,6 +15,7 @@ class Specification < BaseDocument
15
15
  attr_accessor :duplicates_list
16
16
  attr_accessor :last_used_id
17
17
  attr_accessor :last_used_id_number
18
+ attr_accessor :color
18
19
 
19
20
  def initialize(fele_path)
20
21
 
@@ -35,6 +36,8 @@ class Specification < BaseDocument
35
36
  @last_used_id = ""
36
37
  @last_used_id_number = 0
37
38
 
39
+ @color = 'bbb'
40
+
38
41
  @id = File.basename(fele_path, File.extname(fele_path)).downcase
39
42
  @up_link_doc_id = Hash.new
40
43
  end
@@ -6,12 +6,14 @@ class Traceability < BaseDocument
6
6
  attr_accessor :bottom_doc
7
7
  attr_accessor :items
8
8
  attr_accessor :is_agregated
9
+ attr_accessor :traced_items
9
10
 
10
11
  def initialize(top_doc, bottom_doc, is_agregated)
11
12
 
12
13
  @top_doc = top_doc
13
14
  @bottom_doc = bottom_doc
14
15
  @is_agregated = is_agregated
16
+ @traced_items = {}
15
17
 
16
18
  @items = Array.new
17
19
  @headings = Array.new
@@ -37,7 +39,11 @@ class Traceability < BaseDocument
37
39
  s = "<h1>#{@title}</h1>\n"
38
40
  s += "<table class=\"controlled\">\n"
39
41
  s += "\t<thead> <th>#</th> <th style='font-weight: bold;'>#{@top_doc.title}</th> "
40
- s += "<th>#</th> <th style='font-weight: bold;'>#{@bottom_doc.title}</th> "
42
+ if @bottom_doc
43
+ s += "<th>#</th> <th style='font-weight: bold;'>#{@bottom_doc.title}</th> "
44
+ else
45
+ s += "<th>#</th> <th style='font-weight: bold;'>All References</th> "
46
+ end
41
47
  s += "<th style='font-weight: bold;'>Document Section</th>"
42
48
  s += "</thead>\n"
43
49
  html_rows.append s
@@ -57,27 +63,36 @@ class Traceability < BaseDocument
57
63
  def render_table_row(top_item)
58
64
  s = ""
59
65
  top_f_text = top_item.format_string( top_item.text )
60
-
66
+ id_color = ""
67
+
61
68
  if top_item.down_links
62
69
 
63
70
  if @is_agregated
64
-
65
- if top_item.down_links.length > 1
66
- id_color = "style='background-color: #fff8c5;'"
67
- else
68
- id_color = ""
69
- end
71
+
72
+ top_item_rendered = false
70
73
 
71
74
  top_item.down_links.each do |bottom_item|
75
+ id_color = "style='background-color: ##{bottom_item.parent_doc.color};'"
72
76
  bottom_f_text = bottom_item.format_string( bottom_item.text )
73
77
  document_section = bottom_item.parent_heading.get_section_info
74
78
  s += "\t<tr>\n"
75
- s += "\t\t<td class=\"item_id\" #{id_color}><a href=\"./../#{top_item.parent_doc.id}/#{top_item.parent_doc.id}.html##{top_item.id}\" class=\"external\">#{top_item.id}</a></td>\n"
79
+ s += "\t\t<td class=\"item_id\"><a href=\"./../#{top_item.parent_doc.id}/#{top_item.parent_doc.id}.html##{top_item.id}\" class=\"external\">#{top_item.id}</a></td>\n"
76
80
  s += "\t\t<td class=\"item_text\" style='width: 34%;'>#{top_f_text}</td>\n"
77
- s += "\t\t<td class=\"item_id\"><a href=\"./../#{bottom_item.parent_doc.id}/#{bottom_item.parent_doc.id}.html##{bottom_item.id}\" class=\"external\">#{bottom_item.id}</a></td>\n"
81
+ s += "\t\t<td class=\"item_id\" #{id_color}><a href=\"./../#{bottom_item.parent_doc.id}/#{bottom_item.parent_doc.id}.html##{bottom_item.id}\" class=\"external\">#{bottom_item.id}</a></td>\n"
78
82
  s += "\t\t<td class=\"item_text\" style='width: 34%;'>#{bottom_f_text}</td>\n"
79
83
  s += "\t\t<td class=\"item_text\" style='width: 16%;'>#{document_section}</td>\n"
80
84
  s += "\t</tr>\n"
85
+ top_item_rendered = true
86
+ @traced_items[top_item.id.to_s.downcase] = top_item
87
+ end
88
+ unless top_item_rendered
89
+ s += "\t<tr>\n"
90
+ s += "\t\t<td class=\"item_id\"><a href=\"./../#{top_item.parent_doc.id}/#{top_item.parent_doc.id}.html##{top_item.id}\" class=\"external\">#{top_item.id}</a></td>\n"
91
+ s += "\t\t<td class=\"item_text\" style='width: 34%;'>#{top_f_text}</td>\n"
92
+ s += "\t\t<td class=\"item_id\"></td>\n"
93
+ s += "\t\t<td class=\"item_text\" style='width: 34%;'></td>\n"
94
+ s += "\t\t<td class=\"item_text\" style='width: 16%;'></td>\n"
95
+ s += "\t</tr>\n"
81
96
  end
82
97
 
83
98
  else
@@ -99,6 +114,7 @@ class Traceability < BaseDocument
99
114
  s += "\t\t<td class=\"item_text\" style='width: 16%;'>#{document_section}</td>\n"
100
115
  s += "\t</tr>\n"
101
116
  top_item_rendered = true
117
+ @traced_items[top_item.id.to_s.downcase] = top_item
102
118
  end
103
119
  end
104
120
  unless top_item_rendered
@@ -1,4 +1,5 @@
1
1
  require 'fileutils'
2
+ require 'YAML'
2
3
  require_relative "doc_fabric"
3
4
  require_relative "navigation_pane"
4
5
  require_relative "doc_types/traceability"
@@ -15,7 +16,7 @@ class Project
15
16
  attr_accessor :specifications_dictionary
16
17
  attr_accessor :index
17
18
  attr_accessor :project
18
- attr_accessor :on_server
19
+ attr_accessor :project_configuration
19
20
 
20
21
  def initialize(path)
21
22
  @project_root_directory = path
@@ -26,9 +27,19 @@ class Project
26
27
  @specifications_dictionary = Hash.new
27
28
  @index = nil
28
29
  @project = self
29
- @on_server = false
30
+ @project_configuration = {}
31
+ load_project_file()
32
+ FileUtils.remove_dir(@project_root_directory + "/build", true)
33
+ end
30
34
 
31
- FileUtils.remove_dir(@project_root_directory + "/build", true)
35
+ def load_project_file
36
+ begin
37
+ @project_configuration = YAML.load_file(@project_root_directory + '/project.yml')
38
+ rescue Psych::SyntaxError => e
39
+ puts "YAML syntax error: #{e.message}"
40
+ rescue Errno::ENOENT
41
+ puts "Project file not found: project.yml"
42
+ end
32
43
  end
33
44
 
34
45
  def specifications_and_protocols
@@ -90,6 +101,7 @@ class Project
90
101
  Dir.glob( "#{@project_root_directory}/specifications/**/*.md" ).each do |f|
91
102
  doc = DocFabric.create_specification(f)
92
103
  @specifications.append(doc)
104
+ @specifications_dictionary[doc.id.to_s.downcase] = doc
93
105
  end
94
106
  end
95
107
 
@@ -115,6 +127,18 @@ class Project
115
127
  link_two_specifications(c[0], c[1])
116
128
  # puts "Link: #{c[0].id} - #{c[1].id}"
117
129
  end
130
+ # separatelly create design inputs treceability
131
+ if (@project_configuration.key? 'specifications') and (@project_configuration['specifications'].key? 'input')
132
+ @project_configuration['specifications']['input'].each do |i|
133
+ if @specifications_dictionary.has_key? i.to_s.downcase
134
+ document = @specifications_dictionary[i.to_s.downcase]
135
+ if document
136
+ trx = Traceability.new document, nil, true
137
+ @traceability_matrices.append trx
138
+ end
139
+ end
140
+ end
141
+ end
118
142
  end
119
143
 
120
144
  def link_all_protocols
@@ -378,7 +378,7 @@ function modal_close_OnClick(clicked){
378
378
  </div><!-- content -->
379
379
  </div><!-- main -->
380
380
  <div id="footer">
381
- Powered by <a target="_blank" rel="noopener" href="https://www.almirah.site/">Almirah Framework</a>
381
+ Powered by <a target="_blank" rel="noopener" href="https://www.almirah.site/">Almirah Framework (0.1.8)</a>
382
382
  </div><!-- footer -->
383
383
  <!-- The modal window for image zoom -->
384
384
  <div id="image_modal_div" class="modal">
data/lib/almirah.rb CHANGED
@@ -7,9 +7,9 @@ class CLI < Thor
7
7
  def please(project_folder)
8
8
  a = Almirah.new project_folder
9
9
  if options[:results]
10
- a.results( options[:results], false )
10
+ a.results( options[:results] )
11
11
  else
12
- a.default(false)
12
+ a.default()
13
13
  end
14
14
  end
15
15
 
@@ -18,17 +18,6 @@ class CLI < Thor
18
18
  a = Almirah.new project_folder
19
19
  a.transform "docx"
20
20
  end
21
-
22
- option :results
23
- desc "server <project_folder>", "say <project_folder>"
24
- def server(project_folder)
25
- a = Almirah.new project_folder
26
- if options[:results]
27
- a.results( options[:results], true )
28
- else
29
- a.default(true)
30
- end
31
- end
32
21
  end
33
22
 
34
23
  class Almirah
@@ -43,8 +32,7 @@ class Almirah
43
32
  File.expand_path './..', File.dirname(__FILE__)
44
33
  end
45
34
 
46
- def results( test_run, on_server )
47
- @project.on_server = on_server
35
+ def results( test_run )
48
36
  @project.specifications_and_results test_run
49
37
  end
50
38
 
@@ -52,8 +40,7 @@ class Almirah
52
40
  @project.transform file_extension
53
41
  end
54
42
 
55
- def default(on_server)
56
- @project.on_server = on_server
43
+ def default()
57
44
  @project.specifications_and_protocols
58
45
  end
59
46
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: Almirah
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.1.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oleksandr Ivanov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-05-13 00:00:00.000000000 Z
11
+ date: 2024-05-19 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: The software part of the Almirah framework
14
14
  email: oleksandr.ivanov.development@gmail.com