Almirah 0.0.8 → 0.1.0
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 +54 -7
- data/lib/almirah/doc_items/blockquote.rb +2 -1
- data/lib/almirah/doc_items/controlled_paragraph.rb +8 -3
- data/lib/almirah/doc_items/controlled_table.rb +11 -9
- data/lib/almirah/doc_items/doc_item.rb +3 -1
- data/lib/almirah/doc_items/heading.rb +1 -1
- data/lib/almirah/doc_items/image.rb +1 -1
- data/lib/almirah/doc_items/markdown_list.rb +125 -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 +183 -0
- data/lib/almirah/doc_types/base_document.rb +5 -1
- data/lib/almirah/doc_types/index.rb +107 -0
- data/lib/almirah/doc_types/protocol.rb +1 -1
- data/lib/almirah/doc_types/specification.rb +27 -1
- data/lib/almirah/doc_types/traceability.rb +46 -14
- data/lib/almirah/project.rb +75 -19
- data/lib/almirah/templates/page.html +3 -2
- data/lib/almirah.rb +11 -1
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4bc6867a502188fb11b4632e9ab695d6fda2af0d1bfef94d3976d069acfb409f
|
4
|
+
data.tar.gz: 7d993b275d67bf0fa9cc6f40bfb3c43c2d16f6bb8cab5b76135866b5d81b59b9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '087e3aa7b1792ef031d42945fa29d05e5d2231b3e6b83177bfd529e3e7de646a24ac091a0be6e175575c814f87154641aad2036aa9ea7bd8f9247e6e50bd5aca'
|
7
|
+
data.tar.gz: 223acb70d369cdb753635b67b424815cee057ce0309d379a9547ec7769aa9ec78385a178a4862b859444cdd0a187e37c9eaf9771860a2756f1dfea68439133d5
|
data/lib/almirah/doc_fabric.rb
CHANGED
@@ -3,6 +3,7 @@ require_relative "doc_types/base_document"
|
|
3
3
|
require_relative "doc_types/specification"
|
4
4
|
require_relative "doc_types/protocol"
|
5
5
|
#
|
6
|
+
require_relative "doc_items/text_line"
|
6
7
|
require_relative "doc_items/doc_item"
|
7
8
|
require_relative "doc_items/heading"
|
8
9
|
require_relative "doc_items/paragraph"
|
@@ -15,6 +16,12 @@ require_relative "doc_items/markdown_list"
|
|
15
16
|
|
16
17
|
class DocFabric
|
17
18
|
|
19
|
+
def self.add_lazy_doc_id(path)
|
20
|
+
if res = /(\w+)[.]md$/.match(path)
|
21
|
+
TextLine.add_lazy_doc_id(res[1])
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
18
25
|
def self.create_specification(path)
|
19
26
|
doc = Specification.new path
|
20
27
|
DocFabric.parse_document doc
|
@@ -59,7 +66,18 @@ class DocFabric
|
|
59
66
|
if level == 1 && doc.title == ""
|
60
67
|
doc.title = value
|
61
68
|
end
|
62
|
-
|
69
|
+
elsif res = /^\%\s(.*)/.match(s) # Pandoc Document Title
|
70
|
+
|
71
|
+
title = res[1]
|
72
|
+
item = Heading.new(title, 1)
|
73
|
+
item.parent_doc = doc
|
74
|
+
doc.items.append(item)
|
75
|
+
doc.headings.append(item)
|
76
|
+
|
77
|
+
if doc.title == ""
|
78
|
+
doc.title = title
|
79
|
+
end
|
80
|
+
|
63
81
|
elsif res = /^\[(\S*)\]\s+(.*)/.match(s) # Controlled Paragraph
|
64
82
|
|
65
83
|
if tempMdTable
|
@@ -81,7 +99,7 @@ class DocFabric
|
|
81
99
|
up_link = tmp[2]
|
82
100
|
|
83
101
|
if tmp = /^([a-zA-Z]+)[-]\d+/.match(up_link) # SRS
|
84
|
-
doc.up_link_doc_id = tmp[1].downcase
|
102
|
+
doc.up_link_doc_id[ tmp[1].downcase.to_s ] = tmp[1].downcase # multiple documents could be up-linked
|
85
103
|
end
|
86
104
|
end
|
87
105
|
|
@@ -124,7 +142,7 @@ class DocFabric
|
|
124
142
|
|
125
143
|
doc.items.append(item)
|
126
144
|
|
127
|
-
elsif res = /^(\*\s?)
|
145
|
+
elsif res = /^(\*\s?)(.*)/.match(s) #check if unordered list start
|
128
146
|
|
129
147
|
if tempMdTable
|
130
148
|
doc.items.append tempMdTable
|
@@ -134,9 +152,28 @@ class DocFabric
|
|
134
152
|
row = res[2]
|
135
153
|
|
136
154
|
if tempMdList
|
137
|
-
tempMdList.addRow(
|
155
|
+
tempMdList.addRow(s)
|
138
156
|
else
|
139
|
-
item = MarkdownList.new(
|
157
|
+
item = MarkdownList.new(false)
|
158
|
+
item.addRow(s)
|
159
|
+
item.parent_doc = doc
|
160
|
+
tempMdList = item
|
161
|
+
end
|
162
|
+
|
163
|
+
elsif res = /^\d[.]\s(.*)/.match(s) #check if ordered list start
|
164
|
+
|
165
|
+
if tempMdTable
|
166
|
+
doc.items.append tempMdTable
|
167
|
+
tempMdTable = nil
|
168
|
+
end
|
169
|
+
|
170
|
+
row = res[1]
|
171
|
+
|
172
|
+
if tempMdList
|
173
|
+
tempMdList.addRow(s)
|
174
|
+
else
|
175
|
+
item = MarkdownList.new(true)
|
176
|
+
item.addRow(s)
|
140
177
|
item.parent_doc = doc
|
141
178
|
tempMdList = item
|
142
179
|
end
|
@@ -198,14 +235,24 @@ class DocFabric
|
|
198
235
|
tempMdTable = nil
|
199
236
|
end
|
200
237
|
if tempMdList
|
201
|
-
|
202
|
-
|
238
|
+
if MarkdownList.unordered_list_item?(s) || MarkdownList.ordered_list_item?(s)
|
239
|
+
tempMdList.addRow(s)
|
240
|
+
next
|
241
|
+
else
|
242
|
+
doc.items.append tempMdList
|
243
|
+
tempMdList = nil
|
244
|
+
end
|
203
245
|
end
|
204
246
|
|
205
247
|
item = Paragraph.new(s)
|
206
248
|
item.parent_doc = doc
|
207
249
|
doc.items.append(item)
|
208
250
|
end
|
251
|
+
else
|
252
|
+
if tempMdList # lists are separated by emty line from each other
|
253
|
+
doc.items.append tempMdList
|
254
|
+
tempMdList = nil
|
255
|
+
end
|
209
256
|
end
|
210
257
|
end
|
211
258
|
# 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
|
@@ -19,12 +19,13 @@ class ControlledParagraph < Paragraph
|
|
19
19
|
s = ''
|
20
20
|
unless @@htmlTableRenderInProgress
|
21
21
|
s += "<table class=\"controlled\">\n"
|
22
|
-
s += "\t<thead> <th>#</th> <th
|
22
|
+
s += "\t<thead> <th>#</th> <th></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
27
|
s += "\t\t<td class=\"item_id\"> <a name=\"#{@id}\" id=\"#{@id}\" href=\"##{@id}\">#{@id}</a></td>\n"
|
27
|
-
s += "\t\t<td class=\"item_text\">#{
|
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)
|
@@ -39,7 +40,11 @@ class ControlledParagraph < Paragraph
|
|
39
40
|
if tmp = /^([a-zA-Z]+)[-]\d+/.match(@down_links[0].id) # guessing that all the links refer to one document
|
40
41
|
down_link_doc_name = tmp[1].downcase
|
41
42
|
end
|
42
|
-
|
43
|
+
if @down_links.length == 1
|
44
|
+
s += "\t\t<td class=\"item_id\"><a href=\"./../#{down_link_doc_name}/#{down_link_doc_name}.html##{@down_links[0].id}\" class=\"external\">#{@down_links[0].id}</a></td>\n"
|
45
|
+
else
|
46
|
+
s += "\t\t<td class=\"item_id\"><a href=\"./../#{down_link_doc_name}/#{down_link_doc_name}.html\" class=\"external\">#{@down_links.length}</a></td>\n"
|
47
|
+
end
|
43
48
|
else
|
44
49
|
s += "\t\t<td class=\"item_id\"></td>\n"
|
45
50
|
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
|
|
@@ -41,12 +42,13 @@ end
|
|
41
42
|
class TestStepResultColumn < ControlledTableColumn
|
42
43
|
|
43
44
|
def to_html
|
45
|
+
f_text = format_string(@text)
|
44
46
|
if @text.downcase == "pass"
|
45
|
-
"\t\t<td style=\"background-color: #cfc;\">#{
|
47
|
+
"\t\t<td style=\"background-color: #cfc;\">#{f_text}</td>\n\r"
|
46
48
|
elsif @text.downcase == "fail"
|
47
|
-
"\t\t<td style=\"background-color: #fcc;\">#{
|
49
|
+
"\t\t<td style=\"background-color: #fcc;\">#{f_text}</td>\n\r"
|
48
50
|
else
|
49
|
-
"\t\t<td>#{
|
51
|
+
"\t\t<td>#{f_text}</td>\n\r"
|
50
52
|
end
|
51
53
|
end
|
52
54
|
end
|
@@ -126,9 +128,9 @@ class ControlledTable < DocItem
|
|
126
128
|
new_row.columns.append col
|
127
129
|
# save uplink key but do not rewrite
|
128
130
|
if col.up_link_doc_id != nil
|
129
|
-
|
130
|
-
|
131
|
-
|
131
|
+
|
132
|
+
@parent_doc.up_link_doc_id[ col.up_link_doc_id.to_s ] = col.up_link_doc_id
|
133
|
+
|
132
134
|
# save reference to the test step
|
133
135
|
new_row.up_link = col.up_link
|
134
136
|
@parent_doc.controlled_items.append new_row
|
@@ -3,14 +3,113 @@ 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
|
+
pos = calculate_text_position(raw_text)
|
25
|
+
row = raw_text[pos..-1]
|
26
|
+
|
27
|
+
pos = calculate_indent_position(raw_text)
|
28
|
+
|
29
|
+
if pos > @@lists_stack[-1].indent_position
|
30
|
+
|
31
|
+
prev_lists_stack_item = @@lists_stack[-1]
|
32
|
+
# the following line pushes new list to the lists_stack in the constructor!
|
33
|
+
nested_list = MarkdownList.new( MarkdownList.ordered_list_item?(raw_text) )
|
34
|
+
nested_list.current_nesting_level = @current_nesting_level + 1
|
35
|
+
nested_list.indent_position = pos
|
36
|
+
|
37
|
+
prev_row = prev_lists_stack_item.rows[-1]
|
38
|
+
if prev_row.is_a?(MarkdownList)
|
39
|
+
#cannot be there
|
40
|
+
else
|
41
|
+
nested_list.text = prev_row
|
42
|
+
#puts "Length: " + prev_lists_stack_item.rows.length.to_s
|
43
|
+
prev_lists_stack_item.rows[-1] = nested_list
|
44
|
+
end
|
45
|
+
|
46
|
+
nested_list.addRow(raw_text)
|
47
|
+
|
48
|
+
elsif pos < @@lists_stack[-1].indent_position
|
49
|
+
|
50
|
+
@@lists_stack.pop
|
51
|
+
@@lists_stack[-1].rows.append(row)
|
52
|
+
|
53
|
+
else
|
54
|
+
@@lists_stack[-1].rows.append(row)
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def calculate_indent_position(s)
|
60
|
+
s.downcase
|
61
|
+
pos = 0
|
62
|
+
s.each_char do |c|
|
63
|
+
if c != ' ' && c != '\t'
|
64
|
+
break
|
65
|
+
end
|
66
|
+
pos += 1
|
67
|
+
end
|
68
|
+
return pos
|
69
|
+
end
|
70
|
+
def calculate_text_position(s)
|
71
|
+
s.downcase
|
72
|
+
pos = 0
|
73
|
+
space_detected = false
|
74
|
+
s.each_char do |c|
|
75
|
+
if space_detected
|
76
|
+
if c != ' ' && c != '\t' && c != '*' && c != '.' && !numeric?(c)
|
77
|
+
break
|
78
|
+
end
|
79
|
+
elsif c == ' ' || c == '\t'
|
80
|
+
space_detected = true
|
81
|
+
end
|
82
|
+
pos += 1
|
83
|
+
end
|
84
|
+
return pos
|
85
|
+
end
|
86
|
+
|
87
|
+
def letter?(c)
|
88
|
+
c.match?(/[[:alpha:]]/)
|
89
|
+
end
|
90
|
+
|
91
|
+
def numeric?(c)
|
92
|
+
c.match?(/[[:digit:]]/)
|
10
93
|
end
|
11
94
|
|
12
|
-
def
|
13
|
-
|
95
|
+
def non_blank?(c)
|
96
|
+
c.match?(/[[:graph:]]/)
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.unordered_list_item?(raw_text)
|
100
|
+
|
101
|
+
if res = /(\*\s?)(.*)/.match(raw_text)
|
102
|
+
return true
|
103
|
+
end
|
104
|
+
return false
|
105
|
+
end
|
106
|
+
|
107
|
+
def self.ordered_list_item?(raw_text)
|
108
|
+
|
109
|
+
if res = /\d[.]\s(.*)/.match(raw_text)
|
110
|
+
return true
|
111
|
+
end
|
112
|
+
return false
|
14
113
|
end
|
15
114
|
|
16
115
|
def to_html
|
@@ -20,11 +119,30 @@ class MarkdownList < DocItem
|
|
20
119
|
@@htmlTableRenderInProgress = false
|
21
120
|
end
|
22
121
|
|
23
|
-
|
122
|
+
if @is_ordered
|
123
|
+
s += "<ol>\n"
|
124
|
+
else
|
125
|
+
s += "<ul>\n"
|
126
|
+
end
|
127
|
+
|
24
128
|
@rows.each do |r|
|
25
|
-
|
129
|
+
if r.is_a?(MarkdownList)
|
130
|
+
f_text = format_string(r.text)
|
131
|
+
s += "\t<li>#{f_text}\n"
|
132
|
+
s += r.to_html()
|
133
|
+
s += "</li>\n"
|
134
|
+
else
|
135
|
+
f_text = format_string(r)
|
136
|
+
#puts f_text
|
137
|
+
s += "\t<li>#{f_text}</li>\n"
|
138
|
+
end
|
26
139
|
end
|
27
|
-
|
140
|
+
|
141
|
+
if @is_ordered
|
142
|
+
s += "</ol>\n"
|
143
|
+
else
|
144
|
+
s += "</ul>\n"
|
145
|
+
end
|
28
146
|
|
29
147
|
return s
|
30
148
|
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,183 @@
|
|
1
|
+
class TextLine
|
2
|
+
|
3
|
+
@@lazy_doc_id_dict = Hash.new
|
4
|
+
|
5
|
+
def self.add_lazy_doc_id(id)
|
6
|
+
doc_id = id.to_s.downcase
|
7
|
+
@@lazy_doc_id_dict[doc_id] = doc_id
|
8
|
+
end
|
9
|
+
|
10
|
+
def format_string(str)
|
11
|
+
state = 'default'
|
12
|
+
prev_state = 'default'
|
13
|
+
result = ''
|
14
|
+
stack = ''
|
15
|
+
prev_c = ''
|
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)
|
52
|
+
|
53
|
+
else
|
54
|
+
end
|
55
|
+
elsif c == '['
|
56
|
+
if state == 'default'
|
57
|
+
prev_state, state = change_state(c, state, 'square_bracket_left_detected')
|
58
|
+
else
|
59
|
+
end
|
60
|
+
elsif c == ']'
|
61
|
+
if state == 'square_bracket_left_detected'
|
62
|
+
prev_state, state = change_state(c, state, 'default')
|
63
|
+
result += '[]'
|
64
|
+
|
65
|
+
elsif state == 'link_text_started'
|
66
|
+
prev_state, state = change_state(c, state, 'square_bracket_right_detected')
|
67
|
+
link_text = stack
|
68
|
+
|
69
|
+
else
|
70
|
+
end
|
71
|
+
elsif c == '('
|
72
|
+
if state == 'square_bracket_right_detected'
|
73
|
+
prev_state, state = change_state(c, state, 'brace_left_detected')
|
74
|
+
else
|
75
|
+
result += c
|
76
|
+
end
|
77
|
+
elsif c == ')'
|
78
|
+
if state == 'brace_left_detected'
|
79
|
+
prev_state, state = change_state(c, state, 'default')
|
80
|
+
result += '()'
|
81
|
+
|
82
|
+
elsif state == 'link_url_started'
|
83
|
+
prev_state, state = change_state(c, state, 'default')
|
84
|
+
link_url = stack
|
85
|
+
result += link(link_text, link_url)
|
86
|
+
|
87
|
+
else
|
88
|
+
result += c
|
89
|
+
end
|
90
|
+
else
|
91
|
+
if state == 'default'
|
92
|
+
result += c
|
93
|
+
else
|
94
|
+
if state == 'first_asterisk_detected'
|
95
|
+
prev_state, state = change_state(c, state, 'italic_started')
|
96
|
+
stack = ''
|
97
|
+
|
98
|
+
elsif state == 'second_asterisk_detected'
|
99
|
+
prev_state, state = change_state(c, state, 'bold_started')
|
100
|
+
stack = ''
|
101
|
+
|
102
|
+
elsif state == 'third_asterisk_detected'
|
103
|
+
prev_state, state = change_state(c, state, 'bold_and_italic_started')
|
104
|
+
stack = ''
|
105
|
+
|
106
|
+
elsif state == 'first_asterisk_after_bold_detected'
|
107
|
+
prev_state, state = change_state(c, state, 'bold_started')
|
108
|
+
|
109
|
+
elsif state == 'first_asterisk_after_bold_and_italic_detected'
|
110
|
+
prev_state, state = change_state(c, state, 'bold_and_italic_started')
|
111
|
+
|
112
|
+
elsif state == 'second_asterisk_after_bold_and_italic_detected'
|
113
|
+
prev_state, state = change_state(c, state, 'bold_and_italic_started')
|
114
|
+
|
115
|
+
elsif state == 'square_bracket_left_detected'
|
116
|
+
prev_state, state = change_state(c, state, 'link_text_started')
|
117
|
+
stack = ''
|
118
|
+
|
119
|
+
elsif state == 'square_bracket_right_detected'
|
120
|
+
prev_state, state = change_state(c, state, 'default')
|
121
|
+
result += stack + c
|
122
|
+
c = ''
|
123
|
+
|
124
|
+
elsif state == 'brace_left_detected'
|
125
|
+
prev_state, state = change_state(c, state, 'link_url_started')
|
126
|
+
stack = ''
|
127
|
+
|
128
|
+
else
|
129
|
+
end
|
130
|
+
stack += c
|
131
|
+
end
|
132
|
+
end
|
133
|
+
prev_c = c
|
134
|
+
end
|
135
|
+
return result
|
136
|
+
end
|
137
|
+
|
138
|
+
def change_state(c, cur_state, new_state)
|
139
|
+
# puts "[#{c}] Transition: #{cur_state} --> #{new_state}"
|
140
|
+
return cur_state, new_state
|
141
|
+
end
|
142
|
+
|
143
|
+
def italic(str)
|
144
|
+
"<i>#{str}</i>"
|
145
|
+
end
|
146
|
+
|
147
|
+
def bold(str)
|
148
|
+
"<b>#{str}</b>"
|
149
|
+
end
|
150
|
+
|
151
|
+
def bold_and_italic(str)
|
152
|
+
"<b><i>#{str}</i></b>"
|
153
|
+
end
|
154
|
+
|
155
|
+
def link(link_text, link_url)
|
156
|
+
|
157
|
+
# define default result first
|
158
|
+
result = "<a href=\"#{link_url}\" class=\"external\">#{link_text}</a>"
|
159
|
+
|
160
|
+
lazy_doc_id, anchor = nil, nil
|
161
|
+
|
162
|
+
if res = /(\w+)[.]md$/.match(link_url) #link
|
163
|
+
lazy_doc_id = res[1].to_s.downcase
|
164
|
+
|
165
|
+
elsif res = /(\w*)[.]md(#.*)$/.match(link_url) # link with anchor
|
166
|
+
if res && res.length > 2
|
167
|
+
lazy_doc_id = res[1]
|
168
|
+
anchor = res[2]
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
if lazy_doc_id
|
173
|
+
if @@lazy_doc_id_dict.has_key?(lazy_doc_id)
|
174
|
+
if anchor
|
175
|
+
result = "<a href=\".\\..\\#{lazy_doc_id}\\#{lazy_doc_id}.html#{anchor}\" class=\"external\">#{link_text}</a>"
|
176
|
+
else
|
177
|
+
result = "<a href=\".\\..\\#{lazy_doc_id}\\#{lazy_doc_id}.html\" class=\"external\">#{link_text}</a>"
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
return result
|
182
|
+
end
|
183
|
+
end
|
@@ -25,7 +25,11 @@ class BaseDocument
|
|
25
25
|
file_data = file.readlines
|
26
26
|
file.close
|
27
27
|
|
28
|
-
|
28
|
+
if @id == 'index'
|
29
|
+
output_file_path += "#{@id}.html"
|
30
|
+
else
|
31
|
+
output_file_path += "#{@id}/#{@id}.html"
|
32
|
+
end
|
29
33
|
file = File.open( output_file_path, "w" )
|
30
34
|
file_data.each do |s|
|
31
35
|
if s.include?('{{CONTENT}}')
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require_relative "base_document"
|
2
|
+
|
3
|
+
class Index < BaseDocument
|
4
|
+
|
5
|
+
attr_accessor :items
|
6
|
+
attr_accessor :project
|
7
|
+
|
8
|
+
def initialize(project)
|
9
|
+
@items = Array.new
|
10
|
+
@project = project
|
11
|
+
|
12
|
+
@title = "Document Index"
|
13
|
+
@id = "index"
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_console
|
17
|
+
puts "\e[36m" + "Index: " + @id + "\e[0m"
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_html(output_file_path)
|
21
|
+
|
22
|
+
html_rows = Array.new
|
23
|
+
|
24
|
+
html_rows.append('')
|
25
|
+
s = "<h1>#{@title}</h1>\n"
|
26
|
+
|
27
|
+
# Specifications
|
28
|
+
s = "<h2>Specifications</h2>\n"
|
29
|
+
s += "<table class=\"controlled\">\n"
|
30
|
+
s += "\t<thead>\n"
|
31
|
+
s += "\t\t<th>Title</th>\n"
|
32
|
+
s += "\t\t<th>Items</th>\n"
|
33
|
+
s += "\t\t<th>Items<br>w/ Uplinks</th>\n"
|
34
|
+
s += "\t\t<th>Items<br>w/ Downlinks</th>\n"
|
35
|
+
s += "\t\t<th>Covered<br>by Tests</th>\n"
|
36
|
+
s += "\t\t<th>Duplicated<br>ids</th>\n"
|
37
|
+
s += "\t\t<th>Last Used<br>id</th>\n"
|
38
|
+
s += "</thead>\n"
|
39
|
+
html_rows.append s
|
40
|
+
|
41
|
+
sorted_items = @project.specifications.sort_by { |w| w.id }
|
42
|
+
|
43
|
+
sorted_items.each do |doc|
|
44
|
+
s = "\t<tr>\n"
|
45
|
+
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"
|
46
|
+
s += "\t\t<td class=\"item_id\" style='width: 7%;'>#{doc.controlled_items.length.to_s}</td>\n"
|
47
|
+
s += "\t\t<td class=\"item_id\" style='width: 7%;'>#{doc.items_with_uplinks_number.to_s}</td>\n"
|
48
|
+
s += "\t\t<td class=\"item_id\" style='width: 7%;'>#{doc.items_with_downlinks_number.to_s}</td>\n"
|
49
|
+
s += "\t\t<td class=\"item_id\" style='width: 7%;'>#{doc.items_with_coverage_number.to_s}</td>\n"
|
50
|
+
s += "\t\t<td class=\"item_id\" style='width: 7%;'>#{doc.duplicated_ids_number.to_s}</td>\n"
|
51
|
+
s += "\t\t<td class=\"item_id\" style='width: 7%;'>#{doc.last_used_id.to_s}</td>\n"
|
52
|
+
s += "</tr>\n"
|
53
|
+
html_rows.append s
|
54
|
+
end
|
55
|
+
html_rows.append "</table>\n"
|
56
|
+
|
57
|
+
# Traceability Matrices
|
58
|
+
s = "<h2>Traceability Matrices</h2>\n"
|
59
|
+
s += "<table class=\"controlled\">\n"
|
60
|
+
s += "\t<thead>\n"
|
61
|
+
s += "\t\t<th>Title</th>\n"
|
62
|
+
s += "\t\t<th>Top Document</th>\n"
|
63
|
+
s += "\t\t<th>Bottom Document</th>\n"
|
64
|
+
s += "</thead>\n"
|
65
|
+
html_rows.append s
|
66
|
+
|
67
|
+
sorted_items = @project.traceability_matrices.sort_by { |w| w.id }
|
68
|
+
|
69
|
+
sorted_items.each do |doc|
|
70
|
+
s = "\t<tr>\n"
|
71
|
+
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"
|
72
|
+
s += "\t\t<td class=\"item_text\" style='width: 25%; padding: 5px;'>#{doc.top_doc.title}</td>\n"
|
73
|
+
s += "\t\t<td class=\"item_text\" style='width: 25%; padding: 5px;'>#{doc.bottom_doc.title}</td>\n"
|
74
|
+
s += "</tr>\n"
|
75
|
+
html_rows.append s
|
76
|
+
end
|
77
|
+
html_rows.append "</table>\n"
|
78
|
+
|
79
|
+
# Coverage Matrices
|
80
|
+
if @project.coverage_matrices.length > 0
|
81
|
+
s = "<h2>Coverage Matrices</h2>\n"
|
82
|
+
s += "<table class=\"controlled\">\n"
|
83
|
+
s += "\t<thead>\n"
|
84
|
+
s += "\t\t<th>Title</th>\n"
|
85
|
+
s += "\t\t<th>Specification Covered</th>\n"
|
86
|
+
s += "</thead>\n"
|
87
|
+
html_rows.append s
|
88
|
+
|
89
|
+
sorted_items = @project.coverage_matrices.sort_by { |w| w.id }
|
90
|
+
|
91
|
+
sorted_items.each do |doc|
|
92
|
+
s = "\t<tr>\n"
|
93
|
+
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"
|
94
|
+
s += "\t\t<td class=\"item_text\" style='width: 25%; padding: 5px;'>#{doc.top_doc.title}</td>\n"
|
95
|
+
s += "</tr>\n"
|
96
|
+
html_rows.append s
|
97
|
+
end
|
98
|
+
html_rows.append "</table>\n"
|
99
|
+
end
|
100
|
+
|
101
|
+
self.save_html_to_file(html_rows, nil, output_file_path)
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
|
107
|
+
end
|
@@ -30,7 +30,7 @@ class Specification < BaseDocument
|
|
30
30
|
@last_used_id_number = 0
|
31
31
|
|
32
32
|
@id = File.basename(fele_path, File.extname(fele_path)).downcase
|
33
|
-
@up_link_doc_id =
|
33
|
+
@up_link_doc_id = Hash.new
|
34
34
|
end
|
35
35
|
|
36
36
|
def to_console
|
@@ -67,6 +67,7 @@ class Specification < BaseDocument
|
|
67
67
|
|
68
68
|
@items.each do |item|
|
69
69
|
a = item.to_html
|
70
|
+
#a = adjust_internal_links(a, nav_pane.specifications)
|
70
71
|
html_rows.append a
|
71
72
|
end
|
72
73
|
|
@@ -74,4 +75,29 @@ class Specification < BaseDocument
|
|
74
75
|
|
75
76
|
end
|
76
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
|
+
|
77
103
|
end
|
@@ -5,16 +5,23 @@ class Traceability < BaseDocument
|
|
5
5
|
attr_accessor :top_doc
|
6
6
|
attr_accessor :bottom_doc
|
7
7
|
attr_accessor :items
|
8
|
+
attr_accessor :is_agregated
|
8
9
|
|
9
|
-
def initialize(top_doc, bottom_doc)
|
10
|
+
def initialize(top_doc, bottom_doc, is_agregated)
|
10
11
|
|
11
12
|
@top_doc = top_doc
|
12
13
|
@bottom_doc = bottom_doc
|
14
|
+
@is_agregated = is_agregated
|
13
15
|
|
14
16
|
@items = Array.new
|
15
17
|
@headings = Array.new
|
16
18
|
|
17
|
-
@
|
19
|
+
if @is_agregated
|
20
|
+
@id = top_doc.id + "-all"
|
21
|
+
else
|
22
|
+
@id = top_doc.id + "-" + bottom_doc.id
|
23
|
+
end
|
24
|
+
|
18
25
|
@title = "Traceability Matrix: " + @id
|
19
26
|
end
|
20
27
|
|
@@ -46,24 +53,49 @@ class Traceability < BaseDocument
|
|
46
53
|
|
47
54
|
def render_table_row(top_item)
|
48
55
|
s = ""
|
56
|
+
top_f_text = top_item.format_string( top_item.text )
|
57
|
+
|
49
58
|
if top_item.down_links
|
50
|
-
|
51
|
-
|
59
|
+
|
60
|
+
if @is_agregated
|
61
|
+
|
62
|
+
if top_item.down_links.length > 1
|
63
|
+
id_color = "style='background-color: #fff8c5;'"
|
64
|
+
else
|
65
|
+
id_color = ""
|
66
|
+
end
|
67
|
+
|
68
|
+
top_item.down_links.each do |bottom_item|
|
69
|
+
bottom_f_text = bottom_item.format_string( bottom_item.text )
|
70
|
+
s += "\t<tr>\n"
|
71
|
+
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"
|
72
|
+
s += "\t\t<td class=\"item_text\" style='width: 42%;'>#{top_f_text}</td>\n"
|
73
|
+
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"
|
74
|
+
s += "\t\t<td class=\"item_text\" style='width: 42%;'>#{bottom_f_text}</td>\n"
|
75
|
+
s += "\t</tr>\n"
|
76
|
+
end
|
77
|
+
|
52
78
|
else
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
79
|
+
top_item.down_links.each do |bottom_item|
|
80
|
+
|
81
|
+
id_color = ""
|
82
|
+
|
83
|
+
if bottom_item.parent_doc.id == @bottom_doc.id
|
84
|
+
|
85
|
+
bottom_f_text = bottom_item.format_string( bottom_item.text )
|
86
|
+
s += "\t<tr>\n"
|
87
|
+
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"
|
88
|
+
s += "\t\t<td class=\"item_text\" style='width: 42%;'>#{top_f_text}</td>\n"
|
89
|
+
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"
|
90
|
+
s += "\t\t<td class=\"item_text\" style='width: 42%;'>#{bottom_f_text}</td>\n"
|
91
|
+
s += "\t</tr>\n"
|
92
|
+
end
|
93
|
+
end
|
62
94
|
end
|
63
95
|
else
|
64
96
|
s += "\t<tr>\n"
|
65
97
|
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%;'>#{
|
98
|
+
s += "\t\t<td class=\"item_text\" style='width: 42%;'>#{top_f_text}</td>\n"
|
67
99
|
s += "\t\t<td class=\"item_id\"></td>\n"
|
68
100
|
s += "\t\t<td class=\"item_text\" style='width: 42%;'></td>\n"
|
69
101
|
s += "\t</tr>\n"
|
data/lib/almirah/project.rb
CHANGED
@@ -1,21 +1,31 @@
|
|
1
|
+
require 'fileutils'
|
1
2
|
require_relative "doc_fabric"
|
2
3
|
require_relative "navigation_pane"
|
3
4
|
require_relative "doc_types/traceability"
|
4
5
|
require_relative "doc_types/coverage"
|
6
|
+
require_relative "doc_types/index"
|
5
7
|
|
6
8
|
class Project
|
7
9
|
|
8
10
|
attr_accessor :specifications
|
9
11
|
attr_accessor :protocols
|
12
|
+
attr_accessor :traceability_matrices
|
13
|
+
attr_accessor :coverage_matrices
|
10
14
|
attr_accessor :project_root_directory
|
11
15
|
attr_accessor :specifications_dictionary
|
16
|
+
attr_accessor :index
|
17
|
+
attr_accessor :project
|
12
18
|
|
13
19
|
def initialize(path)
|
14
20
|
@project_root_directory = path
|
15
21
|
@specifications = Array.new
|
16
22
|
@protocols = Array.new
|
23
|
+
@traceability_matrices = Array.new
|
24
|
+
@coverage_matrices = Array.new
|
17
25
|
@specifications_dictionary = Hash.new
|
18
|
-
|
26
|
+
@index = nil
|
27
|
+
@project = self
|
28
|
+
|
19
29
|
FileUtils.remove_dir(@project_root_directory + "/build", true)
|
20
30
|
end
|
21
31
|
|
@@ -25,8 +35,12 @@ class Project
|
|
25
35
|
parse_all_protocols
|
26
36
|
link_all_specifications
|
27
37
|
link_all_protocols
|
28
|
-
|
38
|
+
create_index
|
39
|
+
render_all_specifications(@specifications)
|
40
|
+
render_all_specifications(@traceability_matrices)
|
41
|
+
render_all_specifications(@coverage_matrices)
|
29
42
|
render_all_protocols
|
43
|
+
render_index
|
30
44
|
end
|
31
45
|
|
32
46
|
def specifications_and_results( test_run )
|
@@ -35,13 +49,41 @@ class Project
|
|
35
49
|
parse_test_run test_run
|
36
50
|
link_all_specifications
|
37
51
|
link_all_protocols
|
38
|
-
|
52
|
+
create_index
|
53
|
+
render_all_specifications(@specifications)
|
54
|
+
render_all_specifications(@traceability_matrices)
|
55
|
+
render_all_specifications(@coverage_matrices)
|
39
56
|
render_all_protocols
|
57
|
+
render_index
|
58
|
+
end
|
59
|
+
|
60
|
+
def transform( file_extension )
|
61
|
+
transform_all_specifications file_extension
|
62
|
+
end
|
63
|
+
|
64
|
+
def transform_all_specifications( file_extension )
|
65
|
+
|
66
|
+
path = @project_root_directory
|
67
|
+
|
68
|
+
# find all specifications
|
69
|
+
Dir.glob( "#{@project_root_directory}/specifications/**/*.md" ).each do |f|
|
70
|
+
puts f
|
71
|
+
# make a copy with another extention to preserve the content
|
72
|
+
f_directory = File.dirname(f)
|
73
|
+
f_name = File.basename(f, File.extname(f)).downcase + "._md"
|
74
|
+
FileUtils.copy_file( f, "#{f_directory}/#{f_name}")
|
75
|
+
# transform the original one
|
76
|
+
# but do nothing for now - TODO
|
77
|
+
end
|
40
78
|
end
|
41
79
|
|
42
|
-
def parse_all_specifications
|
80
|
+
def parse_all_specifications
|
81
|
+
# do a lasy pass first to get the list of documents id
|
82
|
+
Dir.glob( "#{@project_root_directory}/specifications/**/*.md" ).each do |f|
|
83
|
+
DocFabric.add_lazy_doc_id(f)
|
84
|
+
end
|
85
|
+
# parse documents in the second pass
|
43
86
|
Dir.glob( "#{@project_root_directory}/specifications/**/*.md" ).each do |f|
|
44
|
-
puts "Spec: " + f
|
45
87
|
doc = DocFabric.create_specification(f)
|
46
88
|
@specifications.append(doc)
|
47
89
|
end
|
@@ -67,13 +109,14 @@ class Project
|
|
67
109
|
combList = @specifications.combination(2)
|
68
110
|
combList.each do |c|
|
69
111
|
link_two_specifications(c[0], c[1])
|
112
|
+
# puts "Link: #{c[0].id} - #{c[1].id}"
|
70
113
|
end
|
71
114
|
end
|
72
115
|
|
73
116
|
def link_all_protocols
|
74
117
|
@protocols.each do |p|
|
75
118
|
@specifications.each do |s|
|
76
|
-
if s.id
|
119
|
+
if p.up_link_doc_id.has_key?(s.id.to_s)
|
77
120
|
link_protocol_to_spec(p,s)
|
78
121
|
end
|
79
122
|
end
|
@@ -82,17 +125,16 @@ class Project
|
|
82
125
|
|
83
126
|
def link_two_specifications(doc_A, doc_B)
|
84
127
|
|
85
|
-
if doc_A.id
|
128
|
+
if doc_B.up_link_doc_id.has_key?(doc_A.id.to_s)
|
86
129
|
top_document = doc_A
|
87
130
|
bottom_document = doc_B
|
88
|
-
elsif doc_B.id
|
131
|
+
elsif doc_A.up_link_doc_id.has_key?(doc_B.id.to_s)
|
89
132
|
top_document = doc_B
|
90
133
|
bottom_document = doc_A
|
91
134
|
else
|
92
|
-
puts "No Links"
|
93
135
|
return # no links
|
94
136
|
end
|
95
|
-
|
137
|
+
#puts "Link: #{doc_A.id} - #{doc_B.id}"
|
96
138
|
bottom_document.controlled_items.each do |item|
|
97
139
|
|
98
140
|
if top_document.dictionary.has_key?(item.up_link.to_s)
|
@@ -107,8 +149,8 @@ class Project
|
|
107
149
|
end
|
108
150
|
end
|
109
151
|
# create treceability document
|
110
|
-
trx = Traceability.new top_document, bottom_document
|
111
|
-
@
|
152
|
+
trx = Traceability.new top_document, bottom_document, false
|
153
|
+
@traceability_matrices.append trx
|
112
154
|
end
|
113
155
|
|
114
156
|
def link_protocol_to_spec(protocol, specification)
|
@@ -131,19 +173,23 @@ class Project
|
|
131
173
|
end
|
132
174
|
# create coverage document
|
133
175
|
trx = Coverage.new top_document
|
134
|
-
@
|
176
|
+
@coverage_matrices.append trx
|
177
|
+
end
|
178
|
+
|
179
|
+
def create_index
|
180
|
+
@index = Index.new( @project )
|
135
181
|
end
|
136
182
|
|
137
|
-
def render_all_specifications
|
183
|
+
def render_all_specifications(spec_list)
|
138
184
|
|
139
185
|
# create a sidebar first
|
140
|
-
nav_pane = NavigationPane.new(@specifications)
|
186
|
+
# nav_pane = NavigationPane.new(@specifications)
|
141
187
|
|
142
188
|
pass = @project_root_directory
|
143
189
|
|
144
190
|
FileUtils.mkdir_p(pass + "/build/specifications")
|
145
191
|
|
146
|
-
|
192
|
+
spec_list.each do |doc|
|
147
193
|
|
148
194
|
doc.to_console
|
149
195
|
|
@@ -156,14 +202,14 @@ class Project
|
|
156
202
|
FileUtils.copy_entry( img_src_dir, img_dst_dir )
|
157
203
|
end
|
158
204
|
|
159
|
-
doc.to_html(
|
205
|
+
doc.to_html( nil, "#{pass}/build/specifications/" )
|
160
206
|
end
|
161
207
|
end
|
162
208
|
|
163
209
|
def render_all_protocols
|
164
210
|
|
165
211
|
# create a sidebar first
|
166
|
-
nav_pane = NavigationPane.new(@specifications)
|
212
|
+
# nav_pane = NavigationPane.new(@specifications)
|
167
213
|
|
168
214
|
pass = @project_root_directory
|
169
215
|
|
@@ -181,7 +227,17 @@ class Project
|
|
181
227
|
FileUtils.copy_entry( img_src_dir, img_dst_dir )
|
182
228
|
end
|
183
229
|
|
184
|
-
doc.to_html(
|
230
|
+
doc.to_html( nil, "#{pass}/build/tests/protocols/" )
|
185
231
|
end
|
186
232
|
end
|
233
|
+
|
234
|
+
def render_index
|
235
|
+
|
236
|
+
path = @project_root_directory
|
237
|
+
|
238
|
+
doc = @index
|
239
|
+
doc.to_console
|
240
|
+
|
241
|
+
doc.to_html("#{path}/build/")
|
242
|
+
end
|
187
243
|
end
|
@@ -93,6 +93,7 @@
|
|
93
93
|
border: 1px solid #bbb;
|
94
94
|
}
|
95
95
|
table.controlled td {
|
96
|
+
padding: 4px;
|
96
97
|
text-align:center;
|
97
98
|
vertical-align:middle;
|
98
99
|
padding-right:10px;
|
@@ -197,8 +198,8 @@ function closeNav() {
|
|
197
198
|
</head>
|
198
199
|
<body>
|
199
200
|
<div id="top_nav">
|
200
|
-
<a href="
|
201
|
-
|
201
|
+
<a href="./../../index.html"><span><i class="fa fa-home" aria-hidden="true"></i></span> Home</a>
|
202
|
+
<!--a href="javascript:void(0)"> About</a-->
|
202
203
|
</div>
|
203
204
|
<div id="main">
|
204
205
|
<div id="nav_pane">
|
data/lib/almirah.rb
CHANGED
@@ -2,8 +2,8 @@ require "thor"
|
|
2
2
|
require_relative "almirah/project"
|
3
3
|
|
4
4
|
class CLI < Thor
|
5
|
-
desc "please <project_folder>", "say <project_folder>"
|
6
5
|
option :results
|
6
|
+
desc "please <project_folder>", "say <project_folder>"
|
7
7
|
def please(project_folder)
|
8
8
|
a = Almirah.new project_folder
|
9
9
|
if options[:results]
|
@@ -12,6 +12,12 @@ class CLI < Thor
|
|
12
12
|
a.default
|
13
13
|
end
|
14
14
|
end
|
15
|
+
|
16
|
+
desc "transform <project_folder>", "say <project_folder>"
|
17
|
+
def transform(project_folder)
|
18
|
+
a = Almirah.new project_folder
|
19
|
+
a.transform "docx"
|
20
|
+
end
|
15
21
|
end
|
16
22
|
|
17
23
|
class Almirah
|
@@ -30,6 +36,10 @@ class Almirah
|
|
30
36
|
@project.specifications_and_results test_run
|
31
37
|
end
|
32
38
|
|
39
|
+
def transform( file_extension )
|
40
|
+
@project.transform file_extension
|
41
|
+
end
|
42
|
+
|
33
43
|
def default()
|
34
44
|
@project.specifications_and_protocols
|
35
45
|
end
|
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.1.0
|
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-09 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,8 +30,10 @@ 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
|
34
35
|
- lib/almirah/doc_types/coverage.rb
|
36
|
+
- lib/almirah/doc_types/index.rb
|
35
37
|
- lib/almirah/doc_types/protocol.rb
|
36
38
|
- lib/almirah/doc_types/specification.rb
|
37
39
|
- lib/almirah/doc_types/traceability.rb
|
@@ -57,7 +59,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
57
59
|
- !ruby/object:Gem::Version
|
58
60
|
version: '0'
|
59
61
|
requirements: []
|
60
|
-
rubygems_version: 3.
|
62
|
+
rubygems_version: 3.5.6
|
61
63
|
signing_key:
|
62
64
|
specification_version: 4
|
63
65
|
summary: Almirah
|