Almirah 0.2.3 → 0.2.5
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 +21 -2
- data/lib/almirah/doc_items/controlled_paragraph.rb +100 -79
- data/lib/almirah/doc_items/controlled_table.rb +180 -137
- data/lib/almirah/doc_items/controlled_table_row.rb +3 -3
- data/lib/almirah/doc_items/doc_item.rb +16 -14
- data/lib/almirah/doc_items/frontmatter.rb +9 -0
- data/lib/almirah/doc_items/markdown_list.rb +3 -5
- data/lib/almirah/doc_items/markdown_table.rb +2 -4
- data/lib/almirah/doc_items/paragraph.rb +18 -20
- data/lib/almirah/doc_parser.rb +77 -29
- data/lib/almirah/doc_types/base_document.rb +56 -61
- data/lib/almirah/doc_types/coverage.rb +65 -63
- data/lib/almirah/doc_types/index.rb +168 -156
- data/lib/almirah/doc_types/persistent_document.rb +14 -17
- data/lib/almirah/doc_types/traceability.rb +6 -2
- data/lib/almirah/dom/doc_section.rb +21 -24
- data/lib/almirah/dom/document.rb +72 -57
- data/lib/almirah/project.rb +240 -277
- data/lib/almirah/project_template.rb +298 -0
- data/lib/almirah/search/specifications_db.rb +66 -70
- data/lib/almirah/templates/page.html +3 -3
- data/lib/almirah/templates/scripts/main.js +34 -0
- data/lib/almirah.rb +32 -23
- metadata +27 -5
@@ -1,161 +1,173 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base_document'
|
4
|
+
|
5
|
+
class Index < BaseDocument # rubocop:disable Metrics/ClassLength,Style/Documentation
|
6
|
+
attr_accessor :project
|
7
|
+
|
8
|
+
def initialize(project)
|
9
|
+
super()
|
10
|
+
@project = project
|
11
|
+
@title = 'Document Index'
|
12
|
+
@id = 'index'
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_console
|
16
|
+
puts "\e[36mIndex: #{@id}\e[0m"
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_html(output_file_path) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
|
20
|
+
html_rows = []
|
21
|
+
|
22
|
+
html_rows.append('')
|
23
|
+
s = "<h1>#{@title}</h1>\n"
|
24
|
+
|
25
|
+
# Specifications
|
26
|
+
s = "<h2>Specifications</h2>\n"
|
27
|
+
s += "<table class=\"controlled\">\n"
|
28
|
+
s += "\t<thead>\n"
|
29
|
+
s += "\t\t<th title=\"Document title\">Title</th>\n"
|
30
|
+
s += "\t\t<th title=\"Number of Controlled Paragraphs\">Items</th>\n"
|
31
|
+
s += "\t\t<th title=\"Number of Controlled Paragraphs with up-links\">Items<br>w/ Up-links</th>\n"
|
32
|
+
s += "\t\t<th title=\"Number of references from other documents\">Items<br>w/ Down-links</th>\n"
|
33
|
+
s += "\t\t<th title=\"Number of Controlled Paragraphs mentioned in Test Cases\">Covered <br>by Tests</th>\n"
|
34
|
+
s += "\t\t<th title=\"Number of Controlled Paragraphs that have the same ID\">Duplicated<br>IDs</th>\n"
|
35
|
+
s += "\t\t<th title=\"Number of Controlled Paragraphs that link to non-existing items\">Wrong<br>links</th>\n"
|
36
|
+
s += "\t\t<th title=\"Number of 'TODO:' blocks in document\">TODOs</th>\n"
|
37
|
+
s += "\t\t<th title=\"The last Controlled Paragraph sequence number (ID) used in the document\">Last Used<br>ID</th>\n"
|
38
|
+
s += "</thead>\n"
|
39
|
+
html_rows.append s
|
40
|
+
|
41
|
+
sorted_items = @project.specifications.sort_by(&:id)
|
42
|
+
|
43
|
+
sorted_items.each do |doc| # rubocop:disable Metrics/BlockLength
|
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\"><i class=\"fa fa-file-text-o\" style='background-color: ##{doc.color};'> </i> #{doc.title}</a></td>\n"
|
46
|
+
s += "\t\t<td class=\"item_id\" style='width: 7%;'>#{doc.controlled_items.length}</td>\n"
|
47
|
+
s += "\t\t<td class=\"item_id\" style='width: 7%;'>#{doc.items_with_uplinks_number}</td>\n"
|
48
|
+
s += "\t\t<td class=\"item_id\" style='width: 7%;'>#{doc.items_with_downlinks_number}</td>\n"
|
49
|
+
s += "\t\t<td class=\"item_id\" style='width: 7%;'>#{doc.items_with_coverage_number}</td>\n"
|
50
|
+
|
51
|
+
if doc.duplicated_ids_number.positive?
|
52
|
+
s += "\t\t<td class=\"item_id\" style='width: 7%; background-color: #fcc;'>"
|
53
|
+
s += "<div id=\"DL_#{doc.id}\" style=\"display: block;\">"
|
54
|
+
s += "<a href=\"#\" onclick=\"downlink_OnClick(this.parentElement); return false;\" class=\"external\" title=\"Number of Controlled Paragraphs that have the same ID\">#{doc.duplicated_ids_number}</a>"
|
55
|
+
s += '</div>'
|
56
|
+
s += "<div id=\"DLS_#{doc.id}\" style=\"display: none;\">"
|
57
|
+
doc.duplicates_list.each do |lnk|
|
58
|
+
s += "\t\t\t<a href=\"./specifications/#{doc.id}/#{doc.id}.html##{lnk.id}\" class=\"external\" title=\"Controlled Paragraph with duplicated ID\">#{lnk.id}</a>\n<br>"
|
59
|
+
end
|
60
|
+
s += '</div>'
|
61
|
+
s += "</td>\n"
|
62
|
+
else
|
63
|
+
s += "\t\t<td class=\"item_id\" style='width: 7%;'>#{doc.duplicated_ids_number}</td>\n"
|
64
|
+
end
|
65
|
+
|
66
|
+
if !doc.wrong_links_hash.empty?
|
67
|
+
s += "\t\t<td class=\"item_id\" style='width: 7%; background-color: #fcc;'>"
|
68
|
+
s += "<div id=\"DL_#{doc.id}wl\" style=\"display: block;\">"
|
69
|
+
s += "<a href=\"#\" onclick=\"downlink_OnClick(this.parentElement); return false;\" class=\"external\" title=\"Number of Controlled Paragraphs that link to non-existing items\">#{doc.wrong_links_hash.length}</a>"
|
70
|
+
s += '</div>'
|
71
|
+
s += "<div id=\"DLS_#{doc.id}wl\" style=\"display: none;\">"
|
72
|
+
doc.wrong_links_hash.each do |wrong_lnk, item|
|
73
|
+
s += "\t\t\t<a href=\"./specifications/#{doc.id}/#{doc.id}.html##{item.id}\" class=\"external\" title=\"Controlled Paragraphs that link to non-existing items\">#{wrong_lnk}</a>\n<br>"
|
74
|
+
end
|
75
|
+
s += '</div>'
|
76
|
+
s += "</td>\n"
|
77
|
+
else
|
78
|
+
s += "\t\t<td class=\"item_id\" style='width: 7%;'>#{doc.wrong_links_hash.length}</td>\n"
|
79
|
+
end
|
80
|
+
|
81
|
+
color = if !doc.todo_blocks.empty?
|
82
|
+
'background-color: #fcc;'
|
83
|
+
else
|
84
|
+
''
|
85
|
+
end
|
86
|
+
s += "\t\t<td class=\"item_id\" style='width: 7%; #{color}'>#{doc.todo_blocks.length}</td>\n"
|
87
|
+
s += "\t\t<td class=\"item_id\" style='width: 7%;'>#{doc.last_used_id}</td>\n"
|
88
|
+
s += "</tr>\n"
|
89
|
+
html_rows.append s
|
12
90
|
end
|
13
|
-
|
14
|
-
|
15
|
-
|
91
|
+
html_rows.append "</table>\n"
|
92
|
+
|
93
|
+
# Traceability Matrices
|
94
|
+
s = "<h2>Traceability Matrices</h2>\n"
|
95
|
+
s += "<table class=\"controlled\">\n"
|
96
|
+
s += "\t<thead>\n"
|
97
|
+
s += "\t\t<th title=\"Traceability Matrix Title\">Title</th>\n"
|
98
|
+
s += "\t\t<th title=\"The ratio of Controlled Paragraphs mentioned in other documents and not-mentioned ones\">Coverage</th>\n"
|
99
|
+
s += "\t\t<th title=\"Document, that contains Cotroled Paragraphs to be referenced in Bottom document(s)\">Top Document</th>\n"
|
100
|
+
s += "\t\t<th title=\"Document(s), that contains references to Controlled Paragraphs from the Top Document\">Bottom Document</th>\n"
|
101
|
+
s += "</thead>\n"
|
102
|
+
html_rows.append s
|
103
|
+
|
104
|
+
sorted_items = @project.traceability_matrices.sort_by(&:id)
|
105
|
+
# buble-up design inputs
|
106
|
+
design_inputs = []
|
107
|
+
others = []
|
108
|
+
sorted_items.each do |doc|
|
109
|
+
if doc.bottom_doc
|
110
|
+
others.append doc
|
111
|
+
else
|
112
|
+
design_inputs.append doc
|
113
|
+
end
|
16
114
|
end
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
s = "
|
27
|
-
|
28
|
-
s += "\t<
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
s += "<div id=\"DL_#{doc.id}wl\" style=\"display: block;\">"
|
69
|
-
s += "<a href=\"#\" onclick=\"downlink_OnClick(this.parentElement); return false;\" class=\"external\" title=\"Number of Controlled Paragraphs that link to non-existing items\">#{doc.wrong_links_hash.length.to_s}</a>"
|
70
|
-
s += "</div>"
|
71
|
-
s += "<div id=\"DLS_#{doc.id}wl\" style=\"display: none;\">"
|
72
|
-
doc.wrong_links_hash.each do |wrong_lnk, item|
|
73
|
-
s += "\t\t\t<a href=\"./specifications/#{doc.id}/#{doc.id}.html##{item.id}\" class=\"external\" title=\"Controlled Paragraphs that link to non-existing items\">#{wrong_lnk}</a>\n<br>"
|
74
|
-
end
|
75
|
-
s += "</div>"
|
76
|
-
s += "</td>\n"
|
77
|
-
else
|
78
|
-
s += "\t\t<td class=\"item_id\" style='width: 7%;'>#{doc.wrong_links_hash.length.to_s}</td>\n"
|
79
|
-
end
|
80
|
-
|
81
|
-
if doc.todo_blocks.length >0
|
82
|
-
color = "background-color: #fcc;"
|
83
|
-
else
|
84
|
-
color = ""
|
85
|
-
end
|
86
|
-
s += "\t\t<td class=\"item_id\" style='width: 7%; #{color}'>#{doc.todo_blocks.length.to_s}</td>\n"
|
87
|
-
s += "\t\t<td class=\"item_id\" style='width: 7%;'>#{doc.last_used_id.to_s}</td>\n"
|
88
|
-
s += "</tr>\n"
|
89
|
-
html_rows.append s
|
90
|
-
end
|
91
|
-
html_rows.append "</table>\n"
|
92
|
-
|
93
|
-
# Traceability Matrices
|
94
|
-
s = "<h2>Traceability Matrices</h2>\n"
|
95
|
-
s += "<table class=\"controlled\">\n"
|
96
|
-
s += "\t<thead>\n"
|
97
|
-
s += "\t\t<th title=\"Traceability Matrix Title\">Title</th>\n"
|
98
|
-
s += "\t\t<th title=\"The ratio of Controlled Paragraphs mentioned in other documents and not-mentioned ones\">Coverage</th>\n"
|
99
|
-
s += "\t\t<th title=\"Document, that contains Cotroled Paragraphs to be referenced in Bottom document(s)\">Top Document</th>\n"
|
100
|
-
s += "\t\t<th title=\"Document(s), that contains references to Controlled Paragraphs from the Top Document\">Bottom Document</th>\n"
|
101
|
-
s += "</thead>\n"
|
115
|
+
sorted_items = design_inputs + others
|
116
|
+
|
117
|
+
sorted_items.each do |doc|
|
118
|
+
s = "\t<tr>\n"
|
119
|
+
coverage = doc.traced_items.length.to_f / doc.top_doc.controlled_items.length * 100.0
|
120
|
+
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"
|
121
|
+
s += "\t\t<td class=\"item_id\" style='width: 7%;'>#{'%.2f' % coverage}%</td>\n"
|
122
|
+
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"
|
123
|
+
if doc.bottom_doc
|
124
|
+
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"
|
125
|
+
else
|
126
|
+
s += "\t\t<td class=\"item_text\" style='width: 25%; padding: 5px;'><i class=\"fa fa-circle-o\"'> </i> All References</td>\n"
|
127
|
+
end
|
128
|
+
s += "</tr>\n"
|
129
|
+
html_rows.append s
|
130
|
+
end
|
131
|
+
html_rows.append "</table>\n"
|
132
|
+
|
133
|
+
# Coverage Matrices
|
134
|
+
unless @project.coverage_matrices.empty?
|
135
|
+
s = "<h2>Coverage Matrices</h2>\n"
|
136
|
+
s += "<table class=\"controlled\">\n"
|
137
|
+
s += "\t<thead>\n"
|
138
|
+
s += "\t\t<th>Title</th>\n"
|
139
|
+
s += "\t\t<th title=\"The ratio of Controlled Paragraphs mentioned in test protocols and total number of Controlled Paragraphs\">Coverage</th>\n"
|
140
|
+
s += "\t\t<th title=\"Numbers of passed and failed test steps\">Test Results</th>\n"
|
141
|
+
s += "\t\t<th>Specification Covered</th>\n"
|
142
|
+
s += "</thead>\n"
|
143
|
+
html_rows.append s
|
144
|
+
|
145
|
+
sorted_items = @project.coverage_matrices.sort_by(&:id)
|
146
|
+
|
147
|
+
sorted_items.each do |doc|
|
148
|
+
s = "\t<tr>\n"
|
149
|
+
coverage = doc.covered_items.length.to_f / doc.top_doc.controlled_items.length * 100.0
|
150
|
+
|
151
|
+
test_step_color = if doc.failed_steps_number.positive?
|
152
|
+
'background-color: #fcc;'
|
153
|
+
elsif !doc.failed_steps_number.positive? && doc.passed_steps_number.positive?
|
154
|
+
'background-color: #cfc;'
|
155
|
+
else
|
156
|
+
'background-color: #ffffee;'
|
157
|
+
end
|
158
|
+
|
159
|
+
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"
|
160
|
+
s += "\t\t<td class=\"item_id\" style='width: 7%;'>#{'%.2f' % coverage}%</td>\n" # rubocop:disable Style/FormatString
|
161
|
+
s += "\t\t<td class=\"item_id\" style='width: 7%; #{test_step_color}' title='pass/fail'> #{doc.passed_steps_number}/#{doc.failed_steps_number} </td>\n"
|
162
|
+
s += "\t\t<td class=\"item_text\" style='width: 25%; padding: 5px;'>\
|
163
|
+
<i class=\"fa fa-file-text-o\" style='background-color: ##{doc.top_doc.color};'> </i>\
|
164
|
+
#{doc.top_doc.title}</td>\n"
|
165
|
+
s += "</tr>\n"
|
102
166
|
html_rows.append s
|
103
|
-
|
104
|
-
|
105
|
-
# buble-up design inputs
|
106
|
-
design_inputs = []
|
107
|
-
others = []
|
108
|
-
sorted_items.each do |doc|
|
109
|
-
if doc.bottom_doc
|
110
|
-
others.append doc
|
111
|
-
else
|
112
|
-
design_inputs.append doc
|
113
|
-
end
|
114
|
-
end
|
115
|
-
sorted_items = design_inputs + others
|
116
|
-
|
117
|
-
sorted_items.each do |doc|
|
118
|
-
s = "\t<tr>\n"
|
119
|
-
coverage = doc.traced_items.length.to_f / doc.top_doc.controlled_items.length.to_f * 100.0
|
120
|
-
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"
|
121
|
-
s += "\t\t<td class=\"item_id\" style='width: 7%;'>#{'%.2f' % coverage}%</td>\n"
|
122
|
-
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"
|
123
|
-
if doc.bottom_doc
|
124
|
-
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"
|
125
|
-
else
|
126
|
-
s += "\t\t<td class=\"item_text\" style='width: 25%; padding: 5px;'><i class=\"fa fa-circle-o\"'> </i> All References</td>\n"
|
127
|
-
end
|
128
|
-
s += "</tr>\n"
|
129
|
-
html_rows.append s
|
130
|
-
end
|
131
|
-
html_rows.append "</table>\n"
|
132
|
-
|
133
|
-
# Coverage Matrices
|
134
|
-
if @project.coverage_matrices.length > 0
|
135
|
-
s = "<h2>Coverage Matrices</h2>\n"
|
136
|
-
s += "<table class=\"controlled\">\n"
|
137
|
-
s += "\t<thead>\n"
|
138
|
-
s += "\t\t<th>Title</th>\n"
|
139
|
-
s += "\t\t<th>Specification Covered</th>\n"
|
140
|
-
s += "</thead>\n"
|
141
|
-
html_rows.append s
|
142
|
-
|
143
|
-
sorted_items = @project.coverage_matrices.sort_by { |w| w.id }
|
144
|
-
|
145
|
-
sorted_items.each do |doc|
|
146
|
-
s = "\t<tr>\n"
|
147
|
-
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"
|
148
|
-
s += "\t\t<td class=\"item_text\" style='width: 25%; padding: 5px;'>#{doc.top_doc.title}</td>\n"
|
149
|
-
s += "</tr>\n"
|
150
|
-
html_rows.append s
|
151
|
-
end
|
152
|
-
html_rows.append "</table>\n"
|
153
|
-
end
|
154
|
-
|
155
|
-
self.save_html_to_file(html_rows, nil, output_file_path)
|
156
|
-
|
167
|
+
end
|
168
|
+
html_rows.append "</table>\n"
|
157
169
|
end
|
158
170
|
|
159
|
-
|
160
|
-
|
161
|
-
end
|
171
|
+
save_html_to_file(html_rows, nil, output_file_path)
|
172
|
+
end
|
173
|
+
end
|
@@ -1,20 +1,17 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require_relative 'base_document'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
attr_accessor :controlled_items
|
8
|
-
attr_accessor :headings
|
9
|
-
attr_accessor :up_link_docs
|
5
|
+
class PersistentDocument < BaseDocument # rubocop:disable Style/Documentation
|
6
|
+
attr_accessor :path, :items, :controlled_items, :headings, :up_link_docs, :frontmatter
|
10
7
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
8
|
+
def initialize(fele_path)
|
9
|
+
super()
|
10
|
+
@path = fele_path
|
11
|
+
@items = []
|
12
|
+
@controlled_items = []
|
13
|
+
@headings = []
|
14
|
+
@up_link_docs = {}
|
15
|
+
@frontmatter = nil
|
16
|
+
end
|
17
|
+
end
|
@@ -8,11 +8,15 @@ class Traceability < BaseDocument
|
|
8
8
|
attr_accessor :is_agregated
|
9
9
|
attr_accessor :traced_items
|
10
10
|
|
11
|
-
def initialize(top_doc, bottom_doc
|
11
|
+
def initialize(top_doc, bottom_doc)
|
12
12
|
super()
|
13
13
|
@top_doc = top_doc
|
14
14
|
@bottom_doc = bottom_doc
|
15
|
-
@is_agregated =
|
15
|
+
@is_agregated = if bottom_doc
|
16
|
+
false
|
17
|
+
else
|
18
|
+
true
|
19
|
+
end
|
16
20
|
@traced_items = {}
|
17
21
|
|
18
22
|
if @is_agregated
|
@@ -1,28 +1,25 @@
|
|
1
1
|
class DocSection
|
2
|
+
attr_accessor :sections, :heading, :parent_section
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
4
|
+
def initialize(heading)
|
5
|
+
@sections = []
|
6
|
+
@heading = heading
|
7
|
+
@parent_section = nil
|
8
|
+
end
|
6
9
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
10
|
+
def to_html # rubocop:disable Metrics/MethodLength
|
11
|
+
s = ''
|
12
|
+
s += "\t<li onclick=\"nav_toggle_expand_list(this, event)\">" \
|
13
|
+
'<span class="fa-li"><i class="fa fa-minus-square-o"> </i></span>'
|
14
|
+
s += "<a href=\"##{@heading.anchor_id}\">#{@heading.get_section_info}</a>\n"
|
15
|
+
unless @sections.empty?
|
16
|
+
s += "\t\t<ul class=\"fa-ul\">\n"
|
17
|
+
@sections.each do |sub_section|
|
18
|
+
s += sub_section.to_html
|
19
|
+
end
|
20
|
+
s += "\t\t</ul>\n"
|
11
21
|
end
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
s += "<a href=\"\#" + @heading.anchor_id.to_s + "\">" + @heading.get_section_info + "</a>\n"
|
17
|
-
if @sections.length >0
|
18
|
-
s += "\t\t<ul class=\"fa-ul\">\n"
|
19
|
-
@sections.each do |sub_section|
|
20
|
-
s += sub_section.to_html()
|
21
|
-
end
|
22
|
-
s += "\t\t</ul>\n"
|
23
|
-
end
|
24
|
-
s += "</li>\n"
|
25
|
-
return s
|
26
|
-
end
|
27
|
-
|
28
|
-
end
|
22
|
+
s += "</li>\n"
|
23
|
+
s
|
24
|
+
end
|
25
|
+
end
|
data/lib/almirah/dom/document.rb
CHANGED
@@ -1,63 +1,78 @@
|
|
1
|
-
require_relative
|
1
|
+
require_relative 'doc_section'
|
2
2
|
|
3
3
|
class Document
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
s = DocSection.new(h)
|
29
|
-
@@sections_stack[-2].sections.append(s)
|
30
|
-
@@sections_stack[-1] = s
|
31
|
-
|
32
|
-
elsif h.level > @@sections_stack[-1].heading.level
|
33
|
-
|
34
|
-
s = DocSection.new(h)
|
35
|
-
@@sections_stack[-1].sections.append(s)
|
36
|
-
@@sections_stack.push s
|
37
|
-
|
38
|
-
else
|
39
|
-
while h.level < @@sections_stack[-1].heading.level
|
40
|
-
@@sections_stack.pop
|
41
|
-
end
|
42
|
-
|
43
|
-
s = DocSection.new(h)
|
44
|
-
@@sections_stack[-2].sections.append(s)
|
45
|
-
@@sections_stack[-1] = s
|
46
|
-
end
|
4
|
+
attr_accessor :root_section
|
5
|
+
|
6
|
+
def initialize(headings_list)
|
7
|
+
@root_section = nil
|
8
|
+
|
9
|
+
build_sections_tree(headings_list)
|
10
|
+
end
|
11
|
+
|
12
|
+
def build_sections_tree(headings_list)
|
13
|
+
sections_stack = []
|
14
|
+
headings_list.each do |h|
|
15
|
+
if @root_section.nil?
|
16
|
+
|
17
|
+
s = DocSection.new(h)
|
18
|
+
s.parent_section = nil
|
19
|
+
@root_section = s
|
20
|
+
sections_stack.push s
|
21
|
+
# one more artificial section copy if root is not a Document Title (level 0)
|
22
|
+
if h.level.positive?
|
23
|
+
a = DocSection.new(h)
|
24
|
+
a.parent_section = @root_section
|
25
|
+
@root_section.sections.append(a)
|
26
|
+
sections_stack.push a
|
47
27
|
end
|
48
|
-
end
|
49
28
|
|
50
|
-
|
51
|
-
|
52
|
-
s
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
29
|
+
elsif sections_stack[-1].heading.level == h.level
|
30
|
+
|
31
|
+
s = DocSection.new(h)
|
32
|
+
s.parent_section = sections_stack[-1].parent_section
|
33
|
+
sections_stack[-1].parent_section.sections.append(s)
|
34
|
+
sections_stack[-1] = s
|
35
|
+
# for search engine
|
36
|
+
s.heading.parent_heading = s.parent_section.heading
|
37
|
+
|
38
|
+
elsif h.level > sections_stack[-1].heading.level
|
39
|
+
|
40
|
+
s = DocSection.new(h)
|
41
|
+
s.parent_section = sections_stack[-1]
|
42
|
+
sections_stack[-1].sections.append(s)
|
43
|
+
sections_stack.push s
|
44
|
+
# for search engine
|
45
|
+
s.heading.parent_heading = s.parent_section.heading
|
46
|
+
|
47
|
+
else
|
48
|
+
sections_stack.pop while h.level < sections_stack[-1].heading.level
|
49
|
+
sections_stack.push @root_section if sections_stack.empty?
|
50
|
+
s = DocSection.new(h)
|
51
|
+
if h.level == sections_stack[-1].heading.level
|
52
|
+
s.parent_section = sections_stack[-1].parent_section
|
53
|
+
sections_stack[-1].parent_section.sections.append(s)
|
54
|
+
else
|
55
|
+
s.parent_section = sections_stack[-1]
|
56
|
+
sections_stack[-1].sections.append(s)
|
59
57
|
end
|
60
|
-
|
61
|
-
|
58
|
+
sections_stack[-1] = s
|
59
|
+
# for search engine
|
60
|
+
s.heading.parent_heading = s.parent_section.heading
|
61
|
+
end
|
62
62
|
end
|
63
|
-
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def section_tree_to_html
|
66
|
+
s = ''
|
67
|
+
s += "<a href=\"##{@root_section.heading.anchor_id}\">#{@root_section.heading.get_section_info}</a>\n"
|
68
|
+
unless @root_section.sections.empty?
|
69
|
+
s += "\t<ul class=\"fa-ul\" style=\"margin-top: 2px;\">\n"
|
70
|
+
@root_section.sections.each do |sub_section|
|
71
|
+
s += sub_section.to_html
|
72
|
+
end
|
73
|
+
s += "\t</ul>\n"
|
74
|
+
end
|
75
|
+
|
76
|
+
s
|
77
|
+
end
|
78
|
+
end
|