Almirah 0.1.6 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/almirah/doc_fabric.rb +359 -366
- data/lib/almirah/doc_items/text_line.rb +243 -113
- data/lib/almirah/doc_types/index.rb +21 -3
- data/lib/almirah/doc_types/specification.rb +3 -0
- data/lib/almirah/doc_types/traceability.rb +26 -10
- data/lib/almirah/dom/doc_section.rb +1 -1
- data/lib/almirah/project.rb +27 -3
- data/lib/almirah/templates/page.html +1 -1
- data/lib/almirah.rb +4 -17
- metadata +2 -2
@@ -1,139 +1,270 @@
|
|
1
|
-
class
|
1
|
+
class TextLineToken
|
2
|
+
attr_accessor :value
|
3
|
+
def initialize()
|
4
|
+
@value = ""
|
5
|
+
end
|
6
|
+
end
|
2
7
|
|
3
|
-
|
8
|
+
class ItalicToken < TextLineToken
|
9
|
+
attr_accessor :value
|
10
|
+
def initialize()
|
11
|
+
@value = "*"
|
12
|
+
end
|
13
|
+
end
|
4
14
|
|
5
|
-
|
6
|
-
|
7
|
-
|
15
|
+
class BoldToken < TextLineToken
|
16
|
+
attr_accessor :value
|
17
|
+
def initialize()
|
18
|
+
@value = "**"
|
8
19
|
end
|
20
|
+
end
|
9
21
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
link_text = ''
|
17
|
-
link_url = ''
|
18
|
-
str.each_char do |c|
|
19
|
-
if c == '*'
|
20
|
-
if state == 'default'
|
21
|
-
prev_state, state = change_state(c, state, 'first_asterisk_detected')
|
22
|
-
|
23
|
-
elsif state == 'first_asterisk_detected'
|
24
|
-
prev_state, state = change_state(c, state, 'second_asterisk_detected')
|
25
|
-
|
26
|
-
elsif state == 'second_asterisk_detected'
|
27
|
-
prev_state, state = change_state(c, state, 'third_asterisk_detected')
|
28
|
-
|
29
|
-
elsif state == 'second_asterisk_detected'
|
30
|
-
prev_state, state = change_state(c, state, 'third_asterisk_detected')
|
31
|
-
|
32
|
-
elsif state == 'italic_started'
|
33
|
-
prev_state, state = change_state(c, state, 'default')
|
34
|
-
result += italic(stack)
|
35
|
-
|
36
|
-
elsif state == 'bold_started'
|
37
|
-
prev_state, state = change_state(c, state, 'first_asterisk_after_bold_detected')
|
38
|
-
|
39
|
-
elsif state == 'first_asterisk_after_bold_detected'
|
40
|
-
prev_state, state = change_state(c, state, 'default')
|
41
|
-
result += bold(stack)
|
42
|
-
|
43
|
-
elsif state == 'bold_and_italic_started'
|
44
|
-
prev_state, state = change_state(c, state, 'first_asterisk_after_bold_and_italic_detected')
|
45
|
-
|
46
|
-
elsif state == 'first_asterisk_after_bold_and_italic_detected'
|
47
|
-
prev_state, state = change_state(c, state, 'second_asterisk_after_bold_and_italic_detected')
|
48
|
-
|
49
|
-
elsif state == 'second_asterisk_after_bold_and_italic_detected'
|
50
|
-
prev_state, state = change_state(c, state, 'default')
|
51
|
-
result += bold_and_italic(stack)
|
22
|
+
class BoldAndItalicToken < TextLineToken
|
23
|
+
attr_accessor :value
|
24
|
+
def initialize()
|
25
|
+
@value = "***"
|
26
|
+
end
|
27
|
+
end
|
52
28
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
end
|
60
|
-
elsif c == ']'
|
61
|
-
if state == 'square_bracket_left_detected'
|
62
|
-
prev_state, state = change_state(c, state, 'default')
|
63
|
-
result += '[]'
|
29
|
+
class ParentheseLeft < TextLineToken
|
30
|
+
attr_accessor :value
|
31
|
+
def initialize()
|
32
|
+
@value = "("
|
33
|
+
end
|
34
|
+
end
|
64
35
|
|
65
|
-
|
66
|
-
|
67
|
-
|
36
|
+
class ParentheseRight < TextLineToken
|
37
|
+
attr_accessor :value
|
38
|
+
def initialize()
|
39
|
+
@value = ")"
|
40
|
+
end
|
41
|
+
end
|
68
42
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
43
|
+
class SquareBracketLeft < TextLineToken
|
44
|
+
attr_accessor :value
|
45
|
+
def initialize()
|
46
|
+
@value = "["
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class SquareBracketRight < TextLineToken
|
51
|
+
attr_accessor :value
|
52
|
+
def initialize()
|
53
|
+
@value = "]"
|
54
|
+
end
|
55
|
+
end
|
81
56
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
57
|
+
class SquareBracketRightAndParentheseLeft < TextLineToken
|
58
|
+
attr_accessor :value
|
59
|
+
def initialize()
|
60
|
+
@value = "]("
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
class TextLineParser
|
65
|
+
attr_accessor :supported_tokens
|
66
|
+
|
67
|
+
def initialize()
|
68
|
+
@supported_tokens = Array.new
|
69
|
+
@supported_tokens.append(BoldAndItalicToken.new)
|
70
|
+
@supported_tokens.append(BoldToken.new)
|
71
|
+
@supported_tokens.append(ItalicToken.new)
|
72
|
+
@supported_tokens.append(SquareBracketRightAndParentheseLeft.new)
|
73
|
+
@supported_tokens.append(ParentheseLeft.new)
|
74
|
+
@supported_tokens.append(ParentheseRight.new)
|
75
|
+
@supported_tokens.append(SquareBracketLeft.new)
|
76
|
+
@supported_tokens.append(SquareBracketRight.new)
|
77
|
+
@supported_tokens.append(TextLineToken.new)
|
78
|
+
end
|
86
79
|
|
80
|
+
def tokenize(str)
|
81
|
+
result = Array.new
|
82
|
+
sl = str.length
|
83
|
+
si = 0
|
84
|
+
while si < sl
|
85
|
+
@supported_tokens.each do |t|
|
86
|
+
tl = t.value.length
|
87
|
+
if tl != 0 # literal is the last supported token in the list
|
88
|
+
projected_end_position = si+tl-1
|
89
|
+
if projected_end_position > sl
|
90
|
+
next
|
91
|
+
end
|
92
|
+
buf = str[si..projected_end_position]
|
93
|
+
if buf == t.value
|
94
|
+
result.append(t)
|
95
|
+
si = projected_end_position +1
|
96
|
+
break
|
97
|
+
end
|
87
98
|
else
|
88
|
-
result
|
99
|
+
if (result.length > 0) and (result[-1].instance_of? TextLineToken)
|
100
|
+
literal = result[-1]
|
101
|
+
literal.value += str[si]
|
102
|
+
else
|
103
|
+
literal = TextLineToken.new
|
104
|
+
literal.value = str[si]
|
105
|
+
result.append(literal)
|
106
|
+
end
|
107
|
+
si += 1
|
89
108
|
end
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
prev_state, state = change_state(c, state, 'italic_started')
|
96
|
-
stack = ''
|
109
|
+
end
|
110
|
+
end
|
111
|
+
return result
|
112
|
+
end
|
113
|
+
end
|
97
114
|
|
98
|
-
|
99
|
-
prev_state, state = change_state(c, state, 'bold_started')
|
100
|
-
stack = ''
|
115
|
+
class TextLineBuilderContext
|
101
116
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
elsif state == 'first_asterisk_after_bold_detected'
|
107
|
-
prev_state, state = change_state(c, state, 'bold_started')
|
117
|
+
def italic(str)
|
118
|
+
return str
|
119
|
+
end
|
108
120
|
|
109
|
-
|
110
|
-
|
121
|
+
def bold(str)
|
122
|
+
return str
|
123
|
+
end
|
111
124
|
|
112
|
-
|
113
|
-
|
125
|
+
def bold_and_italic(str)
|
126
|
+
return str
|
127
|
+
end
|
114
128
|
|
115
|
-
|
116
|
-
|
117
|
-
|
129
|
+
def link(link_text, link_url)
|
130
|
+
return link_url
|
131
|
+
end
|
132
|
+
end
|
118
133
|
|
119
|
-
|
120
|
-
|
121
|
-
result += stack + c
|
122
|
-
c = ''
|
134
|
+
class TextLineBuilder
|
135
|
+
attr_accessor :builder_context
|
123
136
|
|
124
|
-
|
125
|
-
|
126
|
-
|
137
|
+
def initialize(builder_context)
|
138
|
+
@builder_context = builder_context
|
139
|
+
end
|
127
140
|
|
128
|
-
|
129
|
-
|
130
|
-
|
141
|
+
def restore(token_list)
|
142
|
+
result = ""
|
143
|
+
if token_list == nil
|
144
|
+
return ""
|
145
|
+
end
|
146
|
+
sub_list_url_text = nil
|
147
|
+
sub_list_url_address = nil
|
148
|
+
tl = token_list.length
|
149
|
+
ti = 0
|
150
|
+
while ti < tl
|
151
|
+
case token_list[ti].class.name
|
152
|
+
when "ItalicToken"
|
153
|
+
is_found = false
|
154
|
+
ti_starting_position = ti
|
155
|
+
# try to find closing part
|
156
|
+
tii = ti + 1
|
157
|
+
while tii < tl
|
158
|
+
if token_list[tii].instance_of? ItalicToken
|
159
|
+
sub_list = token_list[(ti+1)..(tii-1)]
|
160
|
+
result += @builder_context.italic(restore(sub_list))
|
161
|
+
ti = tii +1
|
162
|
+
is_found = true
|
163
|
+
break
|
164
|
+
end
|
165
|
+
tii += 1
|
166
|
+
end
|
167
|
+
unless is_found
|
168
|
+
result += "*"
|
169
|
+
ti = ti_starting_position + 1
|
170
|
+
end
|
171
|
+
when "BoldToken"
|
172
|
+
is_found = false
|
173
|
+
ti_starting_position = ti
|
174
|
+
# try to find closing part
|
175
|
+
tii = ti + 1
|
176
|
+
while tii < tl
|
177
|
+
if token_list[tii].instance_of? BoldToken
|
178
|
+
sub_list = token_list[(ti+1)..(tii-1)]
|
179
|
+
result += @builder_context.bold(restore(sub_list))
|
180
|
+
ti = tii +1
|
181
|
+
is_found = true
|
182
|
+
break
|
183
|
+
end
|
184
|
+
tii += 1
|
185
|
+
end
|
186
|
+
unless is_found
|
187
|
+
result += "**"
|
188
|
+
ti = ti_starting_position + 1
|
189
|
+
end
|
190
|
+
when "BoldAndItalicToken"
|
191
|
+
is_found = false
|
192
|
+
ti_starting_position = ti
|
193
|
+
# try to find closing part
|
194
|
+
tii = ti + 1
|
195
|
+
while tii < tl
|
196
|
+
if token_list[tii].instance_of? BoldAndItalicToken
|
197
|
+
sub_list = token_list[(ti+1)..(tii-1)]
|
198
|
+
result += @builder_context.bold_and_italic(restore(sub_list))
|
199
|
+
ti = tii +1
|
200
|
+
is_found = true
|
201
|
+
break
|
202
|
+
end
|
203
|
+
tii += 1
|
204
|
+
end
|
205
|
+
unless is_found
|
206
|
+
result += "***"
|
207
|
+
ti = ti_starting_position + 1
|
131
208
|
end
|
209
|
+
when "SquareBracketLeft"
|
210
|
+
# try to find closing part
|
211
|
+
is_found = false
|
212
|
+
tii = ti + 1
|
213
|
+
ti_starting_position = ti
|
214
|
+
while tii < tl
|
215
|
+
case token_list[tii].class.name
|
216
|
+
when "SquareBracketRightAndParentheseLeft"
|
217
|
+
sub_list_url_text = token_list[(ti+1)..(tii-1)]
|
218
|
+
ti = tii +1
|
219
|
+
tiii = ti
|
220
|
+
while tiii < tl
|
221
|
+
case token_list[tiii].class.name
|
222
|
+
when "ParentheseRight"
|
223
|
+
sub_list_url_address = token_list[(tii+1)..(tiii-1)]
|
224
|
+
ti = tiii +1
|
225
|
+
is_found = true
|
226
|
+
break
|
227
|
+
end
|
228
|
+
tiii += 1
|
229
|
+
end
|
230
|
+
break
|
231
|
+
when "SquareBracketRight"
|
232
|
+
break
|
233
|
+
end
|
234
|
+
tii += 1
|
235
|
+
end
|
236
|
+
if is_found
|
237
|
+
result += @builder_context.link(restore(sub_list_url_text), restore(sub_list_url_address))
|
238
|
+
else
|
239
|
+
result += "["
|
240
|
+
ti = ti_starting_position + 1
|
241
|
+
end
|
242
|
+
|
243
|
+
when "TextLineToken", "ParentheseLeft", "ParentheseRight", "SquareBracketLeft", "SquareBracketRight"
|
244
|
+
result += token_list[ti].value
|
245
|
+
ti += 1
|
246
|
+
else
|
247
|
+
ti += 1
|
132
248
|
end
|
133
|
-
prev_c = c
|
134
249
|
end
|
135
250
|
return result
|
136
251
|
end
|
252
|
+
end
|
253
|
+
|
254
|
+
class TextLine < TextLineBuilderContext
|
255
|
+
|
256
|
+
@@lazy_doc_id_dict = Hash.new
|
257
|
+
|
258
|
+
def self.add_lazy_doc_id(id)
|
259
|
+
doc_id = id.to_s.downcase
|
260
|
+
@@lazy_doc_id_dict[doc_id] = doc_id
|
261
|
+
end
|
262
|
+
|
263
|
+
def format_string(str)
|
264
|
+
tlp = TextLineParser.new
|
265
|
+
tlb = TextLineBuilder.new(self)
|
266
|
+
tlb.restore(tlp.tokenize(str))
|
267
|
+
end
|
137
268
|
|
138
269
|
def change_state(c, cur_state, new_state)
|
139
270
|
# puts "[#{c}] Transition: #{cur_state} --> #{new_state}"
|
@@ -153,7 +284,6 @@ class TextLine
|
|
153
284
|
end
|
154
285
|
|
155
286
|
def link(link_text, link_url)
|
156
|
-
|
157
287
|
# define default result first
|
158
288
|
result = "<a target=\"_blank\" rel=\"noopener\" href=\"#{link_url}\" class=\"external\">#{link_text}</a>"
|
159
289
|
|
@@ -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\"
|
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> #{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=\"
|
111
|
-
s += "\t\t<td class=\"item_text\" style='width: 25%; padding: 5px;'
|
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> #{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> #{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> All 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
|
-
|
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
|
-
|
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\"
|
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
|
@@ -12,7 +12,7 @@ class DocSection
|
|
12
12
|
|
13
13
|
def to_html
|
14
14
|
s = ''
|
15
|
-
s += "\t<li><span class=\"fa-li\"><i class=\"fa fa-
|
15
|
+
s += "\t<li><span class=\"fa-li\"><i class=\"fa fa-sticky-note-o\"> </i></span>"
|
16
16
|
s += "<a href=\"\#" + @heading.anchor_id.to_s + "\">" + @heading.get_section_info + "</a>\n"
|
17
17
|
if @sections.length >0
|
18
18
|
s += "\t\t<ul class=\"fa-ul\">\n"
|
data/lib/almirah/project.rb
CHANGED
@@ -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 :
|
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
|
-
@
|
30
|
+
@project_configuration = {}
|
31
|
+
load_project_file()
|
32
|
+
FileUtils.remove_dir(@project_root_directory + "/build", true)
|
33
|
+
end
|
30
34
|
|
31
|
-
|
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]
|
10
|
+
a.results( options[:results] )
|
11
11
|
else
|
12
|
-
a.default(
|
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
|
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(
|
56
|
-
@project.on_server = on_server
|
43
|
+
def default()
|
57
44
|
@project.specifications_and_protocols
|
58
45
|
end
|
59
46
|
|