Almirah 0.0.7 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/almirah/doc_fabric.rb +55 -5
- data/lib/almirah/doc_items/blockquote.rb +2 -1
- data/lib/almirah/doc_items/controlled_paragraph.rb +5 -4
- data/lib/almirah/doc_items/controlled_table.rb +14 -9
- data/lib/almirah/doc_items/doc_item.rb +7 -1
- data/lib/almirah/doc_items/heading.rb +1 -1
- data/lib/almirah/doc_items/markdown_list.rb +118 -7
- data/lib/almirah/doc_items/markdown_table.rb +2 -1
- data/lib/almirah/doc_items/paragraph.rb +2 -2
- data/lib/almirah/doc_items/text_line.rb +169 -0
- data/lib/almirah/doc_types/base_document.rb +27 -0
- data/lib/almirah/doc_types/coverage.rb +82 -0
- data/lib/almirah/doc_types/protocol.rb +15 -0
- data/lib/almirah/doc_types/specification.rb +81 -0
- data/lib/almirah/doc_types/traceability.rb +73 -0
- data/lib/almirah/project.rb +17 -15
- data/lib/almirah/templates/page.html +7 -0
- data/lib/almirah.rb +4 -4
- metadata +7 -5
- data/lib/almirah/html_render.rb +0 -54
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9e500204a8575e500989c7d86e4db4dff7a6247b14d3768904620be7a3cef356
|
4
|
+
data.tar.gz: a12d76101a33fc1938c0c42d361f84ae9a8c796684becd1567e154e67f345cad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eff42c3d45f0be71488484ce864740c5363e9169450d32469b9044136ea47af2989b32c4cb526c176c4d4721e60be0c5f484db8ed2245285eb042187a9c5df57
|
7
|
+
data.tar.gz: 2e5c4887b584428a71db8cbd33d244242c90df9b7b02aca8804f72f97fb017dfebc4aa8ff2ae52f924ae9895f7ac1b075cac2407ba84888db55cd36d97984344
|
data/lib/almirah/doc_fabric.rb
CHANGED
@@ -52,6 +52,7 @@ class DocFabric
|
|
52
52
|
level = res[1].length
|
53
53
|
value = res[2]
|
54
54
|
item = Heading.new(value, level)
|
55
|
+
item.parent_doc = doc
|
55
56
|
doc.items.append(item)
|
56
57
|
doc.headings.append(item)
|
57
58
|
|
@@ -85,12 +86,25 @@ class DocFabric
|
|
85
86
|
end
|
86
87
|
|
87
88
|
item = ControlledParagraph.new( text, id )
|
88
|
-
item.
|
89
|
+
item.parent_doc = doc
|
90
|
+
if up_link
|
91
|
+
item.up_link = up_link
|
92
|
+
doc.items_with_uplinks_number += 1 #for statistics
|
93
|
+
end
|
89
94
|
|
90
95
|
doc.items.append(item)
|
91
96
|
doc.dictionary[ id.to_s ] = item #for fast search
|
92
97
|
doc.controlled_items.append(item) #for fast search
|
93
98
|
|
99
|
+
#for statistics
|
100
|
+
n = /\d+/.match(id)[0].to_i
|
101
|
+
if n == doc.last_used_id_number
|
102
|
+
doc.duplicated_ids_number += 1
|
103
|
+
elsif n > doc.last_used_id_number
|
104
|
+
doc.last_used_id = id
|
105
|
+
doc.last_used_id_number = n
|
106
|
+
end
|
107
|
+
|
94
108
|
elsif res = /^[!]\[(.*)\]\((.*)\)/.match(s) # Image
|
95
109
|
|
96
110
|
if tempMdTable
|
@@ -106,10 +120,11 @@ class DocFabric
|
|
106
120
|
img_path = res[2]
|
107
121
|
|
108
122
|
item = Image.new( img_text, img_path )
|
123
|
+
item.parent_doc = doc
|
109
124
|
|
110
125
|
doc.items.append(item)
|
111
126
|
|
112
|
-
elsif res = /^(\*\s?)
|
127
|
+
elsif res = /^(\*\s?)(.*)/.match(s) #check if unordered list start
|
113
128
|
|
114
129
|
if tempMdTable
|
115
130
|
doc.items.append tempMdTable
|
@@ -121,7 +136,27 @@ class DocFabric
|
|
121
136
|
if tempMdList
|
122
137
|
tempMdList.addRow(row)
|
123
138
|
else
|
124
|
-
item = MarkdownList.new(
|
139
|
+
item = MarkdownList.new(false)
|
140
|
+
item.addRow(s)
|
141
|
+
item.parent_doc = doc
|
142
|
+
tempMdList = item
|
143
|
+
end
|
144
|
+
|
145
|
+
elsif res = /^\d[.]\s(.*)/.match(s) #check if ordered list start
|
146
|
+
|
147
|
+
if tempMdTable
|
148
|
+
doc.items.append tempMdTable
|
149
|
+
tempMdTable = nil
|
150
|
+
end
|
151
|
+
|
152
|
+
row = res[1]
|
153
|
+
|
154
|
+
if tempMdList
|
155
|
+
tempMdList.addRow(row)
|
156
|
+
else
|
157
|
+
item = MarkdownList.new(true)
|
158
|
+
item.addRow(s)
|
159
|
+
item.parent_doc = doc
|
125
160
|
tempMdList = item
|
126
161
|
end
|
127
162
|
|
@@ -139,6 +174,7 @@ class DocFabric
|
|
139
174
|
else
|
140
175
|
#separator out of table scope consider it just as a regular paragraph
|
141
176
|
item = Paragraph.new(s)
|
177
|
+
item.parent_doc = doc
|
142
178
|
doc.items.append(item)
|
143
179
|
end
|
144
180
|
|
@@ -150,11 +186,13 @@ class DocFabric
|
|
150
186
|
# check if it is a controlled table
|
151
187
|
unless tempMdTable.addRow(row)
|
152
188
|
tempMdTable = ControlledTable.new(tempMdTable, doc)
|
189
|
+
tempMdTable.parent_doc = doc
|
153
190
|
tempMdTable.addRow(row)
|
154
191
|
end
|
155
192
|
else
|
156
193
|
#start table from heading
|
157
194
|
tempMdTable = MarkdownTable.new(row)
|
195
|
+
tempMdTable.parent_doc = doc
|
158
196
|
end
|
159
197
|
end
|
160
198
|
|
@@ -170,6 +208,7 @@ class DocFabric
|
|
170
208
|
end
|
171
209
|
|
172
210
|
item = Blockquote.new(res[1])
|
211
|
+
item.parent_doc = doc
|
173
212
|
doc.items.append(item)
|
174
213
|
|
175
214
|
else # Reqular Paragraph
|
@@ -178,13 +217,24 @@ class DocFabric
|
|
178
217
|
tempMdTable = nil
|
179
218
|
end
|
180
219
|
if tempMdList
|
181
|
-
|
182
|
-
|
220
|
+
if MarkdownList.unordered_list_item?(s) || MarkdownList.ordered_list_item?(s)
|
221
|
+
tempMdList.addRow(s)
|
222
|
+
next
|
223
|
+
else
|
224
|
+
doc.items.append tempMdList
|
225
|
+
tempMdList = nil
|
226
|
+
end
|
183
227
|
end
|
184
228
|
|
185
229
|
item = Paragraph.new(s)
|
230
|
+
item.parent_doc = doc
|
186
231
|
doc.items.append(item)
|
187
232
|
end
|
233
|
+
else
|
234
|
+
if tempMdList # lists are separated by emty line from each other
|
235
|
+
doc.items.append tempMdList
|
236
|
+
tempMdList = nil
|
237
|
+
end
|
188
238
|
end
|
189
239
|
end
|
190
240
|
# Finalize non-closed elements
|
@@ -10,12 +10,13 @@ class Blockquote < DocItem
|
|
10
10
|
|
11
11
|
def to_html
|
12
12
|
s = ''
|
13
|
+
f_text = format_string(@text)
|
13
14
|
if @@htmlTableRenderInProgress
|
14
15
|
s += "</table>\n"
|
15
16
|
@@htmlTableRenderInProgress = false
|
16
17
|
end
|
17
18
|
|
18
|
-
s += "<div class=\"blockquote\"><p>#{
|
19
|
+
s += "<div class=\"blockquote\"><p>#{f_text}</div>\n"
|
19
20
|
return s
|
20
21
|
end
|
21
22
|
end
|
@@ -8,7 +8,7 @@ class ControlledParagraph < Paragraph
|
|
8
8
|
attr_accessor :coverage_links
|
9
9
|
|
10
10
|
def initialize(text, id)
|
11
|
-
@text = text
|
11
|
+
@text = text.strip
|
12
12
|
@id = id
|
13
13
|
@up_link = nil
|
14
14
|
@down_links = nil
|
@@ -22,15 +22,16 @@ class ControlledParagraph < Paragraph
|
|
22
22
|
s += "\t<thead> <th>#</th> <th>Text</th> <th>UL</th> <th>DL</th> <th>COV</th> </thead>\n"
|
23
23
|
@@htmlTableRenderInProgress = true
|
24
24
|
end
|
25
|
+
f_text = format_string(@text)
|
25
26
|
s += "\t<tr>\n"
|
26
|
-
s += "\t\t<td class=\"item_id\"> <a name=\"#{@id}\"
|
27
|
-
s += "\t\t<td class=\"item_text\">#{
|
27
|
+
s += "\t\t<td class=\"item_id\"> <a name=\"#{@id}\" id=\"#{@id}\" href=\"##{@id}\">#{@id}</a></td>\n"
|
28
|
+
s += "\t\t<td class=\"item_text\">#{f_text}</td>\n"
|
28
29
|
|
29
30
|
if @up_link
|
30
31
|
if tmp = /^([a-zA-Z]+)[-]\d+/.match(@up_link)
|
31
32
|
up_link_doc_name = tmp[1].downcase
|
32
33
|
end
|
33
|
-
s += "\t\t<td class=\"item_id\"><a href=\"./../#{up_link_doc_name}/#{up_link_doc_name}.html\" class=\"external\">#{@up_link}</a></td>\n"
|
34
|
+
s += "\t\t<td class=\"item_id\"><a href=\"./../#{up_link_doc_name}/#{up_link_doc_name}.html##{@up_link}\" class=\"external\">#{@up_link}</a></td>\n"
|
34
35
|
else
|
35
36
|
s += "\t\t<td class=\"item_id\"></td>\n"
|
36
37
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require_relative "controlled_table_row"
|
2
|
+
require_relative "text_line"
|
2
3
|
|
3
|
-
|
4
|
-
class ControlledTableColumn
|
4
|
+
class ControlledTableColumn < TextLine
|
5
5
|
|
6
6
|
attr_accessor :text
|
7
7
|
|
@@ -10,7 +10,8 @@ class ControlledTableColumn
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def to_html
|
13
|
-
|
13
|
+
f_text = format_string(@text)
|
14
|
+
"\t\t<td>#{f_text}</td>\n\r"
|
14
15
|
end
|
15
16
|
end
|
16
17
|
|
@@ -23,15 +24,17 @@ end
|
|
23
24
|
class TestStepNumberColumn < ControlledTableColumn
|
24
25
|
|
25
26
|
attr_accessor :step_number
|
27
|
+
attr_accessor :row_id
|
26
28
|
|
27
29
|
def initialize(text)
|
28
30
|
text = text.strip
|
29
31
|
@step_number = text.to_i
|
30
32
|
@text = text
|
33
|
+
@row_id = ""
|
31
34
|
end
|
32
35
|
|
33
36
|
def to_html
|
34
|
-
"\t\t<td style=\"text-align: center;\">#{@text}</td>\n\r"
|
37
|
+
"\t\t<td style=\"text-align: center;\"><a name=\"#{@row_id}\" id=\"#{@row_id}\" href=\"##{@row_id}\">#{@text}</a></td>\n\r"
|
35
38
|
end
|
36
39
|
end
|
37
40
|
|
@@ -39,12 +42,13 @@ end
|
|
39
42
|
class TestStepResultColumn < ControlledTableColumn
|
40
43
|
|
41
44
|
def to_html
|
45
|
+
f_text = format_string(@text)
|
42
46
|
if @text.downcase == "pass"
|
43
|
-
"\t\t<td style=\"background-color: #cfc;\">#{
|
47
|
+
"\t\t<td style=\"background-color: #cfc;\">#{f_text}</td>\n\r"
|
44
48
|
elsif @text.downcase == "fail"
|
45
|
-
"\t\t<td style=\"background-color: #fcc;\">#{
|
49
|
+
"\t\t<td style=\"background-color: #fcc;\">#{f_text}</td>\n\r"
|
46
50
|
else
|
47
|
-
"\t\t<td>#{
|
51
|
+
"\t\t<td>#{f_text}</td>\n\r"
|
48
52
|
end
|
49
53
|
end
|
50
54
|
end
|
@@ -70,7 +74,7 @@ class TestStepReferenceColumn < ControlledTableColumn
|
|
70
74
|
|
71
75
|
def to_html
|
72
76
|
if @up_link
|
73
|
-
"\t\t<td class=\"item_id\"><a href=\"./../../../specifications/#{@up_link_doc_id}/#{@up_link_doc_id}.html\" class=\"external\">#{@up_link}</a></td>\n\r"
|
77
|
+
"\t\t<td class=\"item_id\"><a href=\"./../../../specifications/#{@up_link_doc_id}/#{@up_link_doc_id}.html##{@up_link}\" class=\"external\">#{@up_link}</a></td>\n\r"
|
74
78
|
else
|
75
79
|
"\t\t<td style=\"text-align: center;\"></td>\n\r"
|
76
80
|
end
|
@@ -83,7 +87,6 @@ class ControlledTable < DocItem
|
|
83
87
|
|
84
88
|
attr_accessor :column_names
|
85
89
|
attr_accessor :rows
|
86
|
-
attr_accessor :parent_doc
|
87
90
|
|
88
91
|
def initialize(markdown_table, parent_doc)
|
89
92
|
@parent_doc = parent_doc
|
@@ -108,6 +111,7 @@ class ControlledTable < DocItem
|
|
108
111
|
def format_columns(columns)
|
109
112
|
|
110
113
|
new_row = ControlledTableRow.new
|
114
|
+
new_row.parent_doc = @parent_doc
|
111
115
|
|
112
116
|
columns.each_with_index do | element, index |
|
113
117
|
|
@@ -116,6 +120,7 @@ class ControlledTable < DocItem
|
|
116
120
|
col = TestStepNumberColumn.new element
|
117
121
|
new_row.columns.append col
|
118
122
|
new_row.id = @parent_doc.id + '.' + col.text
|
123
|
+
col.row_id = new_row.id
|
119
124
|
|
120
125
|
elsif index + 1 == columns.length # it is expected that a link is placed to the last column only
|
121
126
|
|
@@ -3,14 +3,107 @@ require_relative "doc_item"
|
|
3
3
|
class MarkdownList < DocItem
|
4
4
|
|
5
5
|
attr_accessor :rows
|
6
|
+
attr_accessor :text
|
7
|
+
attr_accessor :is_ordered
|
8
|
+
attr_accessor :indent_position
|
9
|
+
attr_accessor :current_nesting_level
|
6
10
|
|
7
|
-
|
11
|
+
@@lists_stack = Array.new
|
12
|
+
|
13
|
+
def initialize(is_ordered)
|
8
14
|
@rows = Array.new
|
9
|
-
@
|
15
|
+
@is_ordered = is_ordered
|
16
|
+
@current_nesting_level = 0
|
17
|
+
@indent_position = 0
|
18
|
+
@text = ''
|
19
|
+
|
20
|
+
@@lists_stack.push(self)
|
21
|
+
end
|
22
|
+
|
23
|
+
def addRow(raw_text)
|
24
|
+
puts raw_text
|
25
|
+
pos = calculate_text_position(raw_text)
|
26
|
+
row = raw_text[pos..-1]
|
27
|
+
|
28
|
+
pos = calculate_indent_position(raw_text)
|
29
|
+
|
30
|
+
if pos > @@lists_stack[-1].indent_position
|
31
|
+
|
32
|
+
prev_lists_stack_item = @@lists_stack[-1]
|
33
|
+
# the following line pushes new list to the lists_stack in the constructor!
|
34
|
+
nested_list = MarkdownList.new( MarkdownList.ordered_list_item?(raw_text) )
|
35
|
+
nested_list.current_nesting_level = @current_nesting_level + 1
|
36
|
+
nested_list.indent_position = pos
|
37
|
+
|
38
|
+
prev_row = prev_lists_stack_item.rows[-1]
|
39
|
+
if prev_row.is_a?(MarkdownList)
|
40
|
+
#cannot be there
|
41
|
+
else
|
42
|
+
nested_list.text = prev_row
|
43
|
+
puts "Length: " + prev_lists_stack_item.rows.length.to_s
|
44
|
+
prev_lists_stack_item.rows[-1] = nested_list
|
45
|
+
end
|
46
|
+
|
47
|
+
nested_list.addRow(raw_text)
|
48
|
+
|
49
|
+
elsif pos < @@lists_stack[-1].indent_position
|
50
|
+
|
51
|
+
@@lists_stack.pop
|
52
|
+
@@lists_stack[-1].rows.append(row)
|
53
|
+
|
54
|
+
else
|
55
|
+
@@lists_stack[-1].rows.append(row)
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def calculate_indent_position(s)
|
61
|
+
pos = 0
|
62
|
+
s.each_char do |c|
|
63
|
+
if non_blank?(c)
|
64
|
+
break
|
65
|
+
end
|
66
|
+
pos += 1
|
67
|
+
end
|
68
|
+
return pos
|
69
|
+
end
|
70
|
+
def calculate_text_position(s)
|
71
|
+
pos = 0
|
72
|
+
s.each_char do |c|
|
73
|
+
if letter?(c)
|
74
|
+
break
|
75
|
+
end
|
76
|
+
pos += 1
|
77
|
+
end
|
78
|
+
return pos
|
79
|
+
end
|
80
|
+
|
81
|
+
def letter?(c)
|
82
|
+
c.match?(/[[:alpha:]]/)
|
83
|
+
end
|
84
|
+
|
85
|
+
def numeric?(c)
|
86
|
+
c.match?(/[[:digit:]]/)
|
10
87
|
end
|
11
88
|
|
12
|
-
def
|
13
|
-
|
89
|
+
def non_blank?(c)
|
90
|
+
c.match?(/[[:graph:]]/)
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.unordered_list_item?(raw_text)
|
94
|
+
|
95
|
+
if res = /(\*\s?)(.*)/.match(raw_text)
|
96
|
+
return true
|
97
|
+
end
|
98
|
+
return false
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.ordered_list_item?(raw_text)
|
102
|
+
|
103
|
+
if res = /\d[.]\s(.*)/.match(raw_text)
|
104
|
+
return true
|
105
|
+
end
|
106
|
+
return false
|
14
107
|
end
|
15
108
|
|
16
109
|
def to_html
|
@@ -20,11 +113,29 @@ class MarkdownList < DocItem
|
|
20
113
|
@@htmlTableRenderInProgress = false
|
21
114
|
end
|
22
115
|
|
23
|
-
|
116
|
+
if @is_ordered
|
117
|
+
s += "<ol>\n"
|
118
|
+
else
|
119
|
+
s += "<ul>\n"
|
120
|
+
end
|
121
|
+
|
24
122
|
@rows.each do |r|
|
25
|
-
|
123
|
+
if r.is_a?(MarkdownList)
|
124
|
+
f_text = format_string(r.text)
|
125
|
+
s += "\t<li>#{f_text}\n"
|
126
|
+
s += r.to_html()
|
127
|
+
s += "</li>\n"
|
128
|
+
else
|
129
|
+
f_text = format_string(r)
|
130
|
+
s += "\t<li>#{f_text}</li>\n"
|
131
|
+
end
|
26
132
|
end
|
27
|
-
|
133
|
+
|
134
|
+
if @is_ordered
|
135
|
+
s += "</ol>\n"
|
136
|
+
else
|
137
|
+
s += "</ul>\n"
|
138
|
+
end
|
28
139
|
|
29
140
|
return s
|
30
141
|
end
|
@@ -44,7 +44,8 @@ class MarkdownTable < DocItem
|
|
44
44
|
if col.to_i > 0 && col.to_i.to_s == col # autoalign cells with numbers
|
45
45
|
s += "\t\t<td style=\"text-align: center;\">#{col}</td>\n"
|
46
46
|
else
|
47
|
-
|
47
|
+
f_text = format_string(col)
|
48
|
+
s += "\t\t<td>#{f_text}</td>\n"
|
48
49
|
end
|
49
50
|
end
|
50
51
|
s += "\t</tr>\n"
|
@@ -9,7 +9,7 @@ class Paragraph < DocItem
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def getTextWithoutSpaces
|
12
|
-
return @text.split.join('-')
|
12
|
+
return @text.split.join('-').downcase
|
13
13
|
end
|
14
14
|
|
15
15
|
def to_html
|
@@ -19,7 +19,7 @@ class Paragraph < DocItem
|
|
19
19
|
@@htmlTableRenderInProgress = false
|
20
20
|
end
|
21
21
|
|
22
|
-
s += "<p
|
22
|
+
s += "<p>" + format_string(@text)
|
23
23
|
return s
|
24
24
|
end
|
25
25
|
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
class TextLine
|
2
|
+
|
3
|
+
def format_string(str)
|
4
|
+
state = 'default'
|
5
|
+
prev_state = 'default'
|
6
|
+
result = ''
|
7
|
+
stack = ''
|
8
|
+
prev_c = ''
|
9
|
+
link_text = ''
|
10
|
+
link_url = ''
|
11
|
+
str.each_char do |c|
|
12
|
+
if c == '*'
|
13
|
+
if state == 'default'
|
14
|
+
prev_state = state
|
15
|
+
state = 'first_asterisk_detected'
|
16
|
+
|
17
|
+
elsif state == 'first_asterisk_detected'
|
18
|
+
prev_state = state
|
19
|
+
state = 'second_asterisk_detected'
|
20
|
+
|
21
|
+
elsif state == 'second_asterisk_detected'
|
22
|
+
prev_state = state
|
23
|
+
state = 'third_asterisk_detected'
|
24
|
+
|
25
|
+
elsif state == 'second_asterisk_detected'
|
26
|
+
prev_state = state
|
27
|
+
state = 'third_asterisk_detected'
|
28
|
+
|
29
|
+
elsif state == 'italic_started'
|
30
|
+
prev_state = state
|
31
|
+
state = 'default'
|
32
|
+
result += italic(stack)
|
33
|
+
|
34
|
+
elsif state == 'bold_started'
|
35
|
+
prev_state = state
|
36
|
+
state = 'first_asterisk_after_bold_detected'
|
37
|
+
|
38
|
+
elsif state == 'first_asterisk_after_bold_detected'
|
39
|
+
prev_state = state
|
40
|
+
state = 'default'
|
41
|
+
result += bold(stack)
|
42
|
+
|
43
|
+
elsif state == 'bold_and_italic_started'
|
44
|
+
prev_state = state
|
45
|
+
state = 'first_asterisk_after_bold_and_italic_detected'
|
46
|
+
|
47
|
+
elsif state == 'first_asterisk_after_bold_and_italic_detected'
|
48
|
+
prev_state = state
|
49
|
+
state = 'second_asterisk_after_bold_and_italic_detected'
|
50
|
+
|
51
|
+
elsif state == 'second_asterisk_after_bold_and_italic_detected'
|
52
|
+
prev_state = state
|
53
|
+
state = 'default'
|
54
|
+
result += bold_and_italic(stack)
|
55
|
+
|
56
|
+
else
|
57
|
+
end
|
58
|
+
elsif c == '['
|
59
|
+
if state == 'default'
|
60
|
+
prev_state = state
|
61
|
+
state = 'square_bracket_left_detected'
|
62
|
+
else
|
63
|
+
end
|
64
|
+
elsif c == ']'
|
65
|
+
if state == 'square_bracket_left_detected'
|
66
|
+
prev_state = state
|
67
|
+
state = 'default'
|
68
|
+
result += '[]'
|
69
|
+
|
70
|
+
elsif state == 'link_text_started'
|
71
|
+
prev_state = state
|
72
|
+
state = 'square_bracket_right_detected'
|
73
|
+
link_text = stack
|
74
|
+
|
75
|
+
else
|
76
|
+
end
|
77
|
+
elsif c == '('
|
78
|
+
if state == 'square_bracket_right_detected'
|
79
|
+
prev_state = state
|
80
|
+
state = 'brace_left_detected'
|
81
|
+
else
|
82
|
+
end
|
83
|
+
elsif c == ')'
|
84
|
+
if state == 'brace_left_detected'
|
85
|
+
prev_state = state
|
86
|
+
state = 'default'
|
87
|
+
result += '()'
|
88
|
+
|
89
|
+
elsif state == 'link_url_started'
|
90
|
+
prev_state = state
|
91
|
+
state = 'default'
|
92
|
+
link_url = stack
|
93
|
+
result += link(link_text, link_url)
|
94
|
+
|
95
|
+
else
|
96
|
+
end
|
97
|
+
else
|
98
|
+
if state == 'default'
|
99
|
+
result += c
|
100
|
+
else
|
101
|
+
if state == 'first_asterisk_detected'
|
102
|
+
prev_state = state
|
103
|
+
state = 'italic_started'
|
104
|
+
stack = ''
|
105
|
+
|
106
|
+
elsif state == 'second_asterisk_detected'
|
107
|
+
prev_state = state
|
108
|
+
state = 'bold_started'
|
109
|
+
stack = ''
|
110
|
+
|
111
|
+
elsif state == 'third_asterisk_detected'
|
112
|
+
prev_state = state
|
113
|
+
state = 'bold_and_italic_started'
|
114
|
+
stack = ''
|
115
|
+
|
116
|
+
elsif state == 'first_asterisk_after_bold_detected'
|
117
|
+
prev_state = state
|
118
|
+
state = 'bold_started'
|
119
|
+
|
120
|
+
elsif state == 'first_asterisk_after_bold_and_italic_detected'
|
121
|
+
prev_state = state
|
122
|
+
state = 'bold_and_italic_started'
|
123
|
+
|
124
|
+
elsif state == 'second_asterisk_after_bold_and_italic_detected'
|
125
|
+
prev_state = state
|
126
|
+
state = 'bold_and_italic_started'
|
127
|
+
|
128
|
+
elsif state == 'square_bracket_left_detected'
|
129
|
+
prev_state = state
|
130
|
+
state = 'link_text_started'
|
131
|
+
stack = ''
|
132
|
+
|
133
|
+
elsif state == 'square_bracket_right_detected'
|
134
|
+
prev_state = state
|
135
|
+
state = 'default'
|
136
|
+
result += stack + c
|
137
|
+
c = ''
|
138
|
+
|
139
|
+
elsif state == 'brace_left_detected'
|
140
|
+
prev_state = state
|
141
|
+
state = 'link_url_started'
|
142
|
+
stack = ''
|
143
|
+
|
144
|
+
else
|
145
|
+
end
|
146
|
+
stack += c
|
147
|
+
end
|
148
|
+
end
|
149
|
+
prev_c = c
|
150
|
+
end
|
151
|
+
return result
|
152
|
+
end
|
153
|
+
|
154
|
+
def italic(str)
|
155
|
+
"<i>#{str}</i>"
|
156
|
+
end
|
157
|
+
|
158
|
+
def bold(str)
|
159
|
+
"<b>#{str}</b>"
|
160
|
+
end
|
161
|
+
|
162
|
+
def bold_and_italic(str)
|
163
|
+
"<b><i>#{str}</i></b>"
|
164
|
+
end
|
165
|
+
|
166
|
+
def link(link_text, link_url)
|
167
|
+
"<a href=\"#{link_url}\" class=\"external\">#{link_text}</a>"
|
168
|
+
end
|
169
|
+
end
|
@@ -15,4 +15,31 @@ class BaseDocument
|
|
15
15
|
@title = ""
|
16
16
|
@id = ""
|
17
17
|
end
|
18
|
+
|
19
|
+
def save_html_to_file html_rows, nav_pane, output_file_path
|
20
|
+
|
21
|
+
gem_root = File.expand_path './../../..', File.dirname(__FILE__)
|
22
|
+
template_file = gem_root + "/lib/almirah/templates/page.html"
|
23
|
+
|
24
|
+
file = File.open( template_file )
|
25
|
+
file_data = file.readlines
|
26
|
+
file.close
|
27
|
+
|
28
|
+
output_file_path += "#{@id}/#{@id}.html"
|
29
|
+
file = File.open( output_file_path, "w" )
|
30
|
+
file_data.each do |s|
|
31
|
+
if s.include?('{{CONTENT}}')
|
32
|
+
html_rows.each do |r|
|
33
|
+
file.puts r
|
34
|
+
end
|
35
|
+
elsif s.include?('{{NAV_PANE}}')
|
36
|
+
if nav_pane
|
37
|
+
file.puts nav_pane.to_html
|
38
|
+
end
|
39
|
+
else
|
40
|
+
file.puts s
|
41
|
+
end
|
42
|
+
end
|
43
|
+
file.close
|
44
|
+
end
|
18
45
|
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require_relative "base_document"
|
2
|
+
|
3
|
+
class Coverage < BaseDocument
|
4
|
+
|
5
|
+
attr_accessor :top_doc
|
6
|
+
attr_accessor :bottom_doc
|
7
|
+
attr_accessor :items
|
8
|
+
|
9
|
+
def initialize(top_doc)
|
10
|
+
|
11
|
+
@top_doc = top_doc
|
12
|
+
@bottom_doc = bottom_doc
|
13
|
+
|
14
|
+
@items = Array.new
|
15
|
+
@headings = Array.new
|
16
|
+
|
17
|
+
@id = top_doc.id + "-" + "tests"
|
18
|
+
@title = "Coverage Matrix: " + @id
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_console
|
22
|
+
puts "\e[35m" + "Traceability: " + @id + "\e[0m"
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_html(nav_pane, output_file_path)
|
26
|
+
|
27
|
+
html_rows = Array.new
|
28
|
+
|
29
|
+
html_rows.append('')
|
30
|
+
s = "<h1>#{@title}</h1>\n"
|
31
|
+
s += "<table class=\"controlled\">\n"
|
32
|
+
s += "\t<thead> <th>#</th> <th style='font-weight: bold;'>#{@top_doc.title}</th> <th>#</th> <th style='font-weight: bold;'>Test CaseId.StepId</th> </thead>\n"
|
33
|
+
html_rows.append s
|
34
|
+
|
35
|
+
sorted_items = @top_doc.controlled_items.sort_by { |w| w.id }
|
36
|
+
|
37
|
+
sorted_items.each do |top_item|
|
38
|
+
row = render_table_row top_item
|
39
|
+
html_rows.append row
|
40
|
+
end
|
41
|
+
html_rows.append "</table>\n"
|
42
|
+
|
43
|
+
self.save_html_to_file(html_rows, nav_pane, output_file_path)
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
def render_table_row(top_item)
|
48
|
+
s = ""
|
49
|
+
if top_item.coverage_links
|
50
|
+
if top_item.coverage_links.length > 1
|
51
|
+
id_color = "" # "style='background-color: #fff8c5;'" # disabled for now
|
52
|
+
else
|
53
|
+
id_color = ""
|
54
|
+
end
|
55
|
+
top_item.coverage_links.each do |bottom_item|
|
56
|
+
s += "\t<tr>\n"
|
57
|
+
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"
|
58
|
+
s += "\t\t<td class=\"item_text\" style='width: 42%;'>#{top_item.text}</td>\n"
|
59
|
+
|
60
|
+
if bottom_item.columns[-2].text.downcase == "pass"
|
61
|
+
test_step_color = "style='background-color: #cfc;'"
|
62
|
+
elsif bottom_item.columns[-2].text.downcase == "fail"
|
63
|
+
test_step_color = "style='background-color: #fcc;'"
|
64
|
+
else
|
65
|
+
test_step_color = ""
|
66
|
+
end
|
67
|
+
|
68
|
+
s += "\t\t<td class=\"item_id\" #{test_step_color}><a href=\"./../../tests/protocols/#{bottom_item.parent_doc.id}/#{bottom_item.parent_doc.id}.html##{bottom_item.id}\" class=\"external\">#{bottom_item.id}</a></td>\n"
|
69
|
+
s += "\t\t<td class=\"item_text\" style='width: 42%;'>#{bottom_item.columns[1].text}</td>\n"
|
70
|
+
s += "\t</tr>\n"
|
71
|
+
end
|
72
|
+
else
|
73
|
+
s += "\t<tr>\n"
|
74
|
+
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"
|
75
|
+
s += "\t\t<td class=\"item_text\" style='width: 42%;'>#{top_item.text}</td>\n"
|
76
|
+
s += "\t\t<td class=\"item_id\"></td>\n"
|
77
|
+
s += "\t\t<td class=\"item_text\" style='width: 42%;'></td>\n"
|
78
|
+
s += "\t</tr>\n"
|
79
|
+
end
|
80
|
+
return s
|
81
|
+
end
|
82
|
+
end
|
@@ -19,4 +19,19 @@ class Protocol < BaseDocument
|
|
19
19
|
@up_link_doc_id = ""
|
20
20
|
end
|
21
21
|
|
22
|
+
def to_html(nav_pane, output_file_path)
|
23
|
+
|
24
|
+
html_rows = Array.new
|
25
|
+
|
26
|
+
html_rows.append('')
|
27
|
+
|
28
|
+
@items.each do |item|
|
29
|
+
a = item.to_html
|
30
|
+
html_rows.append a
|
31
|
+
end
|
32
|
+
|
33
|
+
self.save_html_to_file(html_rows, nav_pane, output_file_path)
|
34
|
+
|
35
|
+
end
|
36
|
+
|
22
37
|
end
|
@@ -6,6 +6,13 @@ class Specification < BaseDocument
|
|
6
6
|
attr_accessor :dictionary
|
7
7
|
attr_accessor :controlled_items
|
8
8
|
|
9
|
+
attr_accessor :items_with_uplinks_number
|
10
|
+
attr_accessor :items_with_downlinks_number
|
11
|
+
attr_accessor :items_with_coverage_number
|
12
|
+
attr_accessor :duplicated_ids_number
|
13
|
+
attr_accessor :last_used_id
|
14
|
+
attr_accessor :last_used_id_number
|
15
|
+
|
9
16
|
def initialize(fele_path)
|
10
17
|
|
11
18
|
@path = fele_path
|
@@ -15,8 +22,82 @@ class Specification < BaseDocument
|
|
15
22
|
@controlled_items = Array.new
|
16
23
|
@dictionary = Hash.new
|
17
24
|
|
25
|
+
@items_with_uplinks_number = 0
|
26
|
+
@items_with_downlinks_number = 0
|
27
|
+
@items_with_coverage_number = 0
|
28
|
+
@duplicated_ids_number = 0
|
29
|
+
@last_used_id = ""
|
30
|
+
@last_used_id_number = 0
|
31
|
+
|
18
32
|
@id = File.basename(fele_path, File.extname(fele_path)).downcase
|
19
33
|
@up_link_doc_id = ""
|
20
34
|
end
|
21
35
|
|
36
|
+
def to_console
|
37
|
+
puts ""
|
38
|
+
puts "\e[33m" + "Specification: " + @title + "\e[0m"
|
39
|
+
puts "-" * 53
|
40
|
+
puts "| Number of Controlled Items | %10d |" % @controlled_items.length
|
41
|
+
puts "| Number of Items w/ Up-links | %10d |" % @items_with_uplinks_number
|
42
|
+
puts "| Number of Items w/ Down-links | %10d |" % @items_with_downlinks_number
|
43
|
+
|
44
|
+
# coverage
|
45
|
+
if (@controlled_items.length > 0) && (@controlled_items.length == @items_with_coverage_number)
|
46
|
+
puts "| Number of Items w/ Test Coverage |\e[1m\e[32m %10d \e[0m|" % @items_with_coverage_number
|
47
|
+
else
|
48
|
+
puts "| Number of Items w/ Test Coverage | %10d |" % @items_with_coverage_number
|
49
|
+
end
|
50
|
+
|
51
|
+
# duplicates
|
52
|
+
if @duplicated_ids_number >0
|
53
|
+
puts "| Duplicated Item Ids found |\e[1m\e[31m %10d \e[0m|" % @duplicated_ids_number
|
54
|
+
else
|
55
|
+
puts "| Duplicated Item Ids found | %10d |" % @duplicated_ids_number
|
56
|
+
end
|
57
|
+
|
58
|
+
puts "| Last used Item Id |\e[1m\e[37m %10s \e[0m|" % @last_used_id
|
59
|
+
puts "-" * 53
|
60
|
+
end
|
61
|
+
|
62
|
+
def to_html(nav_pane, output_file_path)
|
63
|
+
|
64
|
+
html_rows = Array.new
|
65
|
+
|
66
|
+
html_rows.append('')
|
67
|
+
|
68
|
+
@items.each do |item|
|
69
|
+
a = item.to_html
|
70
|
+
a = adjust_internal_links(a, nav_pane.specifications)
|
71
|
+
html_rows.append a
|
72
|
+
end
|
73
|
+
|
74
|
+
self.save_html_to_file(html_rows, nav_pane, output_file_path)
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
def adjust_internal_links(line, specifications)
|
79
|
+
# check if there are internal links to md files and replace them
|
80
|
+
if tmp = /<a\shref="(.*)"\sclass="external">.*<\/a>/.match(line)
|
81
|
+
if res = /(\w*)[.]md/.match(tmp[1])
|
82
|
+
id = res[1].downcase
|
83
|
+
res = /(\w*)[.]md(#.*)/.match(tmp[1])
|
84
|
+
|
85
|
+
specifications.each do |spec|
|
86
|
+
if spec.id.downcase == id
|
87
|
+
if res && res.length > 2
|
88
|
+
anchor = res[2]
|
89
|
+
line.sub!(/<a\shref="(.*)"\sclass="external">/,
|
90
|
+
"<a href=\".\\..\\#{id}\\#{id}.html#{anchor}\" class=\"external\">")
|
91
|
+
else
|
92
|
+
line.sub!(/<a\shref="(.*)"\sclass="external">/,
|
93
|
+
"<a href=\".\\..\\#{id}\\#{id}.html\" class=\"external\">")
|
94
|
+
end
|
95
|
+
break
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
return line
|
101
|
+
end
|
102
|
+
|
22
103
|
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require_relative "base_document"
|
2
|
+
|
3
|
+
class Traceability < BaseDocument
|
4
|
+
|
5
|
+
attr_accessor :top_doc
|
6
|
+
attr_accessor :bottom_doc
|
7
|
+
attr_accessor :items
|
8
|
+
|
9
|
+
def initialize(top_doc, bottom_doc)
|
10
|
+
|
11
|
+
@top_doc = top_doc
|
12
|
+
@bottom_doc = bottom_doc
|
13
|
+
|
14
|
+
@items = Array.new
|
15
|
+
@headings = Array.new
|
16
|
+
|
17
|
+
@id = top_doc.id + "-" + bottom_doc.id
|
18
|
+
@title = "Traceability Matrix: " + @id
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_console
|
22
|
+
puts "\e[35m" + "Traceability: " + @id + "\e[0m"
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_html(nav_pane, output_file_path)
|
26
|
+
|
27
|
+
html_rows = Array.new
|
28
|
+
|
29
|
+
html_rows.append('')
|
30
|
+
s = "<h1>#{@title}</h1>\n"
|
31
|
+
s += "<table class=\"controlled\">\n"
|
32
|
+
s += "\t<thead> <th>#</th> <th style='font-weight: bold;'>#{@top_doc.title}</th> <th>#</th> <th style='font-weight: bold;'>#{@bottom_doc.title}</th> </thead>\n"
|
33
|
+
html_rows.append s
|
34
|
+
|
35
|
+
sorted_items = @top_doc.controlled_items.sort_by { |w| w.id }
|
36
|
+
|
37
|
+
sorted_items.each do |top_item|
|
38
|
+
row = render_table_row top_item
|
39
|
+
html_rows.append row
|
40
|
+
end
|
41
|
+
html_rows.append "</table>\n"
|
42
|
+
|
43
|
+
self.save_html_to_file(html_rows, nav_pane, output_file_path)
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
def render_table_row(top_item)
|
48
|
+
s = ""
|
49
|
+
if top_item.down_links
|
50
|
+
if top_item.down_links.length > 1
|
51
|
+
id_color = "style='background-color: #fff8c5;'"
|
52
|
+
else
|
53
|
+
id_color = ""
|
54
|
+
end
|
55
|
+
top_item.down_links.each do |bottom_item|
|
56
|
+
s += "\t<tr>\n"
|
57
|
+
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"
|
58
|
+
s += "\t\t<td class=\"item_text\" style='width: 42%;'>#{top_item.text}</td>\n"
|
59
|
+
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"
|
60
|
+
s += "\t\t<td class=\"item_text\" style='width: 42%;'>#{bottom_item.text}</td>\n"
|
61
|
+
s += "\t</tr>\n"
|
62
|
+
end
|
63
|
+
else
|
64
|
+
s += "\t<tr>\n"
|
65
|
+
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"
|
66
|
+
s += "\t\t<td class=\"item_text\" style='width: 42%;'>#{top_item.text}</td>\n"
|
67
|
+
s += "\t\t<td class=\"item_id\"></td>\n"
|
68
|
+
s += "\t\t<td class=\"item_text\" style='width: 42%;'></td>\n"
|
69
|
+
s += "\t</tr>\n"
|
70
|
+
end
|
71
|
+
return s
|
72
|
+
end
|
73
|
+
end
|
data/lib/almirah/project.rb
CHANGED
@@ -1,20 +1,20 @@
|
|
1
|
+
require 'fileutils'
|
1
2
|
require_relative "doc_fabric"
|
2
|
-
require_relative "html_render"
|
3
3
|
require_relative "navigation_pane"
|
4
|
+
require_relative "doc_types/traceability"
|
5
|
+
require_relative "doc_types/coverage"
|
4
6
|
|
5
7
|
class Project
|
6
8
|
|
7
9
|
attr_accessor :specifications
|
8
10
|
attr_accessor :protocols
|
9
11
|
attr_accessor :project_root_directory
|
10
|
-
attr_accessor :gem_root
|
11
12
|
attr_accessor :specifications_dictionary
|
12
13
|
|
13
|
-
def initialize(path
|
14
|
+
def initialize(path)
|
14
15
|
@project_root_directory = path
|
15
16
|
@specifications = Array.new
|
16
17
|
@protocols = Array.new
|
17
|
-
@gem_root = gem_root
|
18
18
|
@specifications_dictionary = Hash.new
|
19
19
|
|
20
20
|
FileUtils.remove_dir(@project_root_directory + "/build", true)
|
@@ -102,14 +102,14 @@ class Project
|
|
102
102
|
|
103
103
|
unless topItem.down_links
|
104
104
|
topItem.down_links = Array.new
|
105
|
+
top_document.items_with_downlinks_number += 1 # for statistics
|
105
106
|
end
|
106
107
|
topItem.down_links.append(item)
|
107
|
-
|
108
|
-
#if tmp = /^([a-zA-Z]+)[-]\d+/.match(item.id)
|
109
|
-
# top_document.downlinkKey = tmp[1].upcase
|
110
|
-
#end
|
111
108
|
end
|
112
109
|
end
|
110
|
+
# create treceability document
|
111
|
+
trx = Traceability.new top_document, bottom_document
|
112
|
+
@specifications.append trx
|
113
113
|
end
|
114
114
|
|
115
115
|
def link_protocol_to_spec(protocol, specification)
|
@@ -125,10 +125,14 @@ class Project
|
|
125
125
|
|
126
126
|
unless topItem.coverage_links
|
127
127
|
topItem.coverage_links = Array.new
|
128
|
+
top_document.items_with_coverage_number += 1 # for statistics
|
128
129
|
end
|
129
130
|
topItem.coverage_links.append(item)
|
130
131
|
end
|
131
132
|
end
|
133
|
+
# create coverage document
|
134
|
+
trx = Coverage.new top_document
|
135
|
+
@specifications.append trx
|
132
136
|
end
|
133
137
|
|
134
138
|
def render_all_specifications
|
@@ -142,6 +146,8 @@ class Project
|
|
142
146
|
|
143
147
|
@specifications.each do |doc|
|
144
148
|
|
149
|
+
doc.to_console
|
150
|
+
|
145
151
|
img_src_dir = pass + "/specifications/" + doc.id + "/img"
|
146
152
|
img_dst_dir = pass + "/build/specifications/" + doc.id + "/img"
|
147
153
|
|
@@ -151,16 +157,14 @@ class Project
|
|
151
157
|
FileUtils.copy_entry( img_src_dir, img_dst_dir )
|
152
158
|
end
|
153
159
|
|
154
|
-
|
155
|
-
@gem_root + "/lib/almirah/templates/page.html",
|
156
|
-
"#{pass}/build/specifications/#{doc.id}/#{doc.id}.html" )
|
160
|
+
doc.to_html( nav_pane, "#{pass}/build/specifications/" )
|
157
161
|
end
|
158
162
|
end
|
159
163
|
|
160
164
|
def render_all_protocols
|
161
165
|
|
162
166
|
# create a sidebar first
|
163
|
-
|
167
|
+
nav_pane = NavigationPane.new(@specifications)
|
164
168
|
|
165
169
|
pass = @project_root_directory
|
166
170
|
|
@@ -178,9 +182,7 @@ class Project
|
|
178
182
|
FileUtils.copy_entry( img_src_dir, img_dst_dir )
|
179
183
|
end
|
180
184
|
|
181
|
-
|
182
|
-
@gem_root + "/lib/almirah/templates/page.html",
|
183
|
-
"#{pass}/build/tests/protocols/#{doc.id}/#{doc.id}.html" )
|
185
|
+
doc.to_html( nav_pane, "#{pass}/build/tests/protocols/" )
|
184
186
|
end
|
185
187
|
end
|
186
188
|
end
|
@@ -126,6 +126,13 @@
|
|
126
126
|
a, a:link, a:visited {
|
127
127
|
color: #169;
|
128
128
|
text-decoration: none;
|
129
|
+
display: inline-block;
|
130
|
+
}
|
131
|
+
a:active {
|
132
|
+
color: #555;
|
133
|
+
background-color:#deb887;
|
134
|
+
text-decoration: none;
|
135
|
+
display: inline-block;
|
129
136
|
}
|
130
137
|
div.blockquote {
|
131
138
|
display: block;
|
data/lib/almirah.rb
CHANGED
@@ -18,11 +18,11 @@ class Almirah
|
|
18
18
|
|
19
19
|
attr_accessor :project
|
20
20
|
|
21
|
-
def initialize
|
22
|
-
@project = Project.new project_folder
|
21
|
+
def initialize(project_folder)
|
22
|
+
@project = Project.new project_folder
|
23
23
|
end
|
24
24
|
|
25
|
-
def getGemRoot
|
25
|
+
def getGemRoot()
|
26
26
|
File.expand_path './..', File.dirname(__FILE__)
|
27
27
|
end
|
28
28
|
|
@@ -30,7 +30,7 @@ class Almirah
|
|
30
30
|
@project.specifications_and_results test_run
|
31
31
|
end
|
32
32
|
|
33
|
-
def default
|
33
|
+
def default()
|
34
34
|
@project.specifications_and_protocols
|
35
35
|
end
|
36
36
|
|
metadata
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: Almirah
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.9
|
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-
|
11
|
+
date: 2024-03-03 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
|
-
description: The software part of the Almirah
|
13
|
+
description: The software part of the Almirah framework
|
14
14
|
email: oleksandr.ivanov.development@gmail.com
|
15
15
|
executables:
|
16
16
|
- almirah
|
@@ -30,10 +30,12 @@ files:
|
|
30
30
|
- lib/almirah/doc_items/markdown_list.rb
|
31
31
|
- lib/almirah/doc_items/markdown_table.rb
|
32
32
|
- lib/almirah/doc_items/paragraph.rb
|
33
|
+
- lib/almirah/doc_items/text_line.rb
|
33
34
|
- lib/almirah/doc_types/base_document.rb
|
35
|
+
- lib/almirah/doc_types/coverage.rb
|
34
36
|
- lib/almirah/doc_types/protocol.rb
|
35
37
|
- lib/almirah/doc_types/specification.rb
|
36
|
-
- lib/almirah/
|
38
|
+
- lib/almirah/doc_types/traceability.rb
|
37
39
|
- lib/almirah/navigation_pane.rb
|
38
40
|
- lib/almirah/project.rb
|
39
41
|
- lib/almirah/templates/page.html
|
@@ -56,7 +58,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
56
58
|
- !ruby/object:Gem::Version
|
57
59
|
version: '0'
|
58
60
|
requirements: []
|
59
|
-
rubygems_version: 3.
|
61
|
+
rubygems_version: 3.5.6
|
60
62
|
signing_key:
|
61
63
|
specification_version: 4
|
62
64
|
summary: Almirah
|
data/lib/almirah/html_render.rb
DELETED
@@ -1,54 +0,0 @@
|
|
1
|
-
|
2
|
-
class HtmlRender
|
3
|
-
|
4
|
-
attr_accessor :template
|
5
|
-
attr_accessor :htmlRows
|
6
|
-
attr_accessor :outputFile
|
7
|
-
attr_accessor :document
|
8
|
-
attr_accessor :nav_pane
|
9
|
-
|
10
|
-
def initialize(document, nav_pane, template, outputFile)
|
11
|
-
|
12
|
-
@template = template
|
13
|
-
@outputFile = outputFile
|
14
|
-
@htmlRows = Array.new
|
15
|
-
@document = document
|
16
|
-
@nav_pane = nav_pane
|
17
|
-
|
18
|
-
self.render()
|
19
|
-
self.saveRenderToFile()
|
20
|
-
end
|
21
|
-
|
22
|
-
def render()
|
23
|
-
self.htmlRows.append('')
|
24
|
-
|
25
|
-
self.document.items.each do |item|
|
26
|
-
a = item.to_html
|
27
|
-
self.htmlRows.append a
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def saveRenderToFile()
|
32
|
-
|
33
|
-
file = File.open( self.template )
|
34
|
-
file_data = file.readlines
|
35
|
-
file.close
|
36
|
-
|
37
|
-
file = File.open( self.outputFile, "w" )
|
38
|
-
file_data.each do |s|
|
39
|
-
if s.include?('{{CONTENT}}')
|
40
|
-
self.htmlRows.each do |r|
|
41
|
-
file.puts r
|
42
|
-
end
|
43
|
-
elsif s.include?('{{NAV_PANE}}')
|
44
|
-
if @nav_pane
|
45
|
-
file.puts self.nav_pane.to_html
|
46
|
-
end
|
47
|
-
else
|
48
|
-
file.puts s
|
49
|
-
end
|
50
|
-
end
|
51
|
-
file.close
|
52
|
-
end
|
53
|
-
|
54
|
-
end
|