Almirah 0.2.3 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,20 +1,22 @@
1
- require_relative "text_line"
1
+ # frozen_string_literal: true
2
2
 
3
- class DocItem < TextLine
4
- attr_accessor :parent_doc
5
- attr_accessor :parent_heading
6
-
7
- @parent_doc = nil
8
- @parent_heading = nil
9
-
10
- @@html_table_render_in_progress = false
11
-
12
- def get_url
13
- ''
14
- end
15
- end
3
+ require_relative 'text_line'
16
4
 
5
+ class DocItem < TextLine # rubocop:disable Style/Documentation
6
+ attr_accessor :parent_doc, :parent_heading
17
7
 
8
+ @parent_doc = nil
9
+ @parent_heading = nil
18
10
 
11
+ @@html_table_render_in_progress = false # rubocop:disable Style/ClassVars
19
12
 
13
+ def initialize(doc)
14
+ super()
15
+ @parent_doc = doc
16
+ @parent_heading = doc.headings[-1]
17
+ end
20
18
 
19
+ def get_url
20
+ ''
21
+ end
22
+ end
@@ -0,0 +1,9 @@
1
+ require 'yaml'
2
+
3
+ class Frontmatter
4
+ attr_accessor :parameters
5
+
6
+ def initialize(yaml_text_line)
7
+ @parameters = YAML.safe_load(yaml_text_line)
8
+ end
9
+ end
@@ -8,9 +8,7 @@ class MarkdownList < DocItem
8
8
  @@lists_stack = []
9
9
 
10
10
  def initialize(doc, is_ordered)
11
- super()
12
- @parent_doc = doc
13
- @parent_heading = doc.headings[-1]
11
+ super(doc)
14
12
 
15
13
  @rows = []
16
14
  @is_ordered = is_ordered
@@ -21,7 +19,7 @@ class MarkdownList < DocItem
21
19
  @@lists_stack.push(self)
22
20
  end
23
21
 
24
- def addRow(raw_text)
22
+ def add_row(raw_text)
25
23
  pos = calculate_text_position(raw_text)
26
24
  row = raw_text[pos..-1]
27
25
 
@@ -44,7 +42,7 @@ class MarkdownList < DocItem
44
42
  prev_lists_stack_item.rows[-1] = nested_list
45
43
  end
46
44
 
47
- nested_list.addRow(raw_text)
45
+ nested_list.add_row(raw_text)
48
46
 
49
47
  elsif pos < @@lists_stack[-1].indent_position
50
48
 
@@ -6,9 +6,7 @@ class MarkdownTable < DocItem
6
6
  attr_accessor :column_names, :rows, :heading_row, :is_separator_detected
7
7
 
8
8
  def initialize(doc, heading_row)
9
- super()
10
- @parent_doc = doc
11
- @parent_heading = doc.headings[-1]
9
+ super(doc)
12
10
  @heading_row = heading_row
13
11
 
14
12
  res = /^[|](.*[|])/.match(heading_row)
@@ -21,7 +19,7 @@ class MarkdownTable < DocItem
21
19
  @is_separator_detected = false
22
20
  end
23
21
 
24
- def addRow(row)
22
+ def add_row(row)
25
23
  columns = row.split('|')
26
24
  @rows.append(columns.map!(&:strip))
27
25
  true
@@ -1,27 +1,25 @@
1
- require_relative "doc_item"
1
+ require_relative 'doc_item'
2
2
 
3
3
  class Paragraph < DocItem
4
+ attr_accessor :text
4
5
 
5
- attr_accessor :text
6
+ def initialize(doc, text)
7
+ super(doc)
8
+ @text = text.strip
9
+ end
6
10
 
7
- def initialize(doc, text)
8
- @parent_doc = doc
9
- @parent_heading = doc.headings[-1]
10
- @text = text
11
- end
11
+ def getTextWithoutSpaces
12
+ @text.split.join('-').downcase
13
+ end
12
14
 
13
- def getTextWithoutSpaces
14
- return @text.split.join('-').downcase
15
+ def to_html
16
+ s = ''
17
+ if @@html_table_render_in_progress
18
+ s += '</table>'
19
+ @@html_table_render_in_progress = false
15
20
  end
16
21
 
17
- def to_html
18
- s = ''
19
- if @@html_table_render_in_progress
20
- s += "</table>"
21
- @@html_table_render_in_progress = false
22
- end
23
-
24
- s += "<p>" + format_string(@text)
25
- return s
26
- end
27
- end
22
+ s += "<p>#{format_string(@text)}"
23
+ s
24
+ end
25
+ end
@@ -11,15 +11,53 @@ require_relative 'doc_items/controlled_table'
11
11
  require_relative 'doc_items/image'
12
12
  require_relative 'doc_items/markdown_list'
13
13
  require_relative 'doc_items/doc_footer'
14
+ require_relative 'doc_items/frontmatter'
15
+
16
+ class DocParser # rubocop:disable Metrics/ClassLength,Style/Documentation
17
+ def self.try_to_extract_frontmatter(doc, text_lines) # rubocop:disable Metrics/MethodLength
18
+ lines_to_remove = 0
19
+ frontmatter_lines = ''
20
+ if /^(-{3,})/.match(text_lines[0])
21
+ frontmatter_started = false
22
+ text_lines.each do |s|
23
+ lines_to_remove += 1
24
+ if /^(-{3,})/.match(s)
25
+ if frontmatter_started
26
+ doc.frontmatter = Frontmatter.new(frontmatter_lines)
27
+ frontmatter_started = false
28
+ break
29
+ else
30
+ frontmatter_started = true
31
+ end
32
+ elsif frontmatter_started
33
+ frontmatter_lines += s
34
+ end
35
+ end
36
+ end
37
+ text_lines.shift(lines_to_remove)
38
+ text_lines
39
+ end
14
40
 
15
- class DocParser
16
41
  def self.parse(doc, text_lines)
17
42
  temp_md_table = nil
18
43
  temp_md_list = nil
19
44
  temp_code_block = nil
20
45
  # restart section numbering for each new document
21
46
  Heading.reset_global_section_number
22
-
47
+ # try to get frontmatter first
48
+ text_lines = try_to_extract_frontmatter(doc, text_lines)
49
+ # There is no document without heading
50
+ title = "#{doc.id}.md"
51
+ item = Heading.new(doc, title, 0)
52
+ doc.items.append(item)
53
+ doc.headings.append(item)
54
+ doc.title = title
55
+ # replace dummy title with extracted from frontmatter
56
+ if doc.frontmatter && (doc.frontmatter.parameters.key? 'title')
57
+ doc.title = doc.frontmatter.parameters['title']
58
+ doc.headings[0].text = doc.frontmatter.parameters['title']
59
+ end
60
+ # main loop
23
61
  text_lines.each do |s|
24
62
  if s.lstrip != ''
25
63
  if res = /^(\#{1,})\s(.*)/.match(s) # Heading
@@ -33,10 +71,6 @@ class DocParser
33
71
  level = res[1].length
34
72
  value = res[2]
35
73
 
36
- if level == 1 && doc.title == ''
37
- doc.title = value
38
- end
39
-
40
74
  item = Heading.new(doc, value, level)
41
75
  doc.items.append(item)
42
76
  doc.headings.append(item)
@@ -45,13 +79,9 @@ class DocParser
45
79
 
46
80
  title = res[1]
47
81
 
48
- if doc.title == ''
49
- doc.title = title
50
- end
51
-
52
- item = Heading.new(doc, title, 0)
53
- doc.items.append(item)
54
- doc.headings.append(item)
82
+ # Rewrite
83
+ doc.title = title
84
+ doc.headings[0].text = title
55
85
 
56
86
  elsif res = /^\[(\S*)\]\s+(.*)/.match(s) # Controlled Paragraph
57
87
 
@@ -72,12 +102,10 @@ class DocParser
72
102
  if tmp.length > 0
73
103
  up_links = []
74
104
  tmp.each do |ul|
75
- lnk = ul[0]
105
+ lnk = ul[0]
76
106
  # do not add links for the self document
77
107
  doc_id = /([a-zA-Z]+)-\d+/.match(lnk) # SRS
78
- if (doc_id) and (doc_id[1].downcase != doc.id.downcase)
79
- up_links << lnk.upcase
80
- end
108
+ up_links << lnk.upcase if doc_id and (doc_id[1].downcase != doc.id.downcase)
81
109
  # try to find the real end of text
82
110
  pos = text.index(lnk)
83
111
  first_pos = pos if pos < first_pos
@@ -95,7 +123,7 @@ class DocParser
95
123
  item = ControlledParagraph.new(doc, text, id)
96
124
 
97
125
  if up_links
98
- up_links.uniq! #remove duplicates
126
+ up_links.uniq! # remove duplicates
99
127
  doc.items_with_uplinks_number += 1 # for statistics
100
128
  up_links.each do |ul|
101
129
  next unless tmp = />\[(\S*)\]$/.match(ul) # >[SRS-001]
@@ -146,36 +174,54 @@ class DocParser
146
174
 
147
175
  doc.items.append(item)
148
176
 
149
- elsif res = /^(\*\s+)(.*)/.match(s) # check if unordered list start
177
+ elsif res = /^(\*\s+)(.*)/.match(s) # check if unordered list start
178
+
179
+ if doc.title == ''
180
+ # dummy section if root is not a Document Title (level 0)
181
+ title = "#{doc.id}.md"
182
+ item = Heading.new(doc, title, 0)
183
+ doc.items.append(item)
184
+ doc.headings.append(item)
185
+ doc.title = title
186
+ end
150
187
 
151
188
  temp_md_table = process_temp_table(doc, temp_md_table)
152
189
 
153
190
  row = res[2]
154
191
 
155
192
  if temp_md_list
156
- temp_md_list.addRow(s)
193
+ temp_md_list.add_row(s)
157
194
  else
158
195
  item = MarkdownList.new(doc, false)
159
- item.addRow(s)
196
+ item.add_row(s)
160
197
  temp_md_list = item
161
198
  end
162
199
 
163
- elsif res = /^\d[.]\s(.*)/.match(s) # check if ordered list start
200
+ elsif res = /^\d[.]\s(.*)/.match(s) # check if ordered list start
164
201
 
165
202
  temp_md_table = process_temp_table(doc, temp_md_table)
166
203
 
167
204
  row = res[1]
168
205
 
169
206
  if temp_md_list
170
- temp_md_list.addRow(s)
207
+ temp_md_list.add_row(s)
171
208
  else
172
209
  item = MarkdownList.new(doc, true)
173
- item.addRow(s)
210
+ item.add_row(s)
174
211
  temp_md_list = item
175
212
  end
176
213
 
177
214
  elsif s[0] == '|' # check if table
178
215
 
216
+ if doc.title == ''
217
+ # dummy section if root is not a Document Title (level 0)
218
+ title = "#{doc.id}.md"
219
+ item = Heading.new(doc, title, 0)
220
+ doc.items.append(item)
221
+ doc.headings.append(item)
222
+ doc.title = title
223
+ end
224
+
179
225
  if temp_md_list
180
226
  doc.items.append temp_md_list
181
227
  temp_md_list = nil
@@ -184,8 +230,8 @@ class DocParser
184
230
  if res = /^[|](-{3,})[|]/.match(s) # check if it is a separator first
185
231
 
186
232
  if temp_md_table
187
- # separator is found after heading
188
- temp_md_table.is_separator_detected = true
233
+ # separator is found after heading
234
+ temp_md_table.is_separator_detected = true
189
235
  else
190
236
  # separator out of table scope consider it just as a regular paragraph
191
237
  item = Paragraph.new(doc, s)
@@ -208,7 +254,7 @@ class DocParser
208
254
  temp_md_table = ControlledTable.new(doc, temp_md_table)
209
255
  end
210
256
  end
211
- temp_md_table.addRow(row)
257
+ temp_md_table.add_row(row)
212
258
  else
213
259
  # replece table heading with regular paragraph
214
260
  item = Paragraph.new(doc, temp_md_table.heading_row)
@@ -257,6 +303,7 @@ class DocParser
257
303
  # start code block
258
304
  temp_code_block = CodeBlock.new(suggested_format)
259
305
  temp_code_block.parent_doc = doc
306
+ temp_code_block.parent_heading = doc.headings[-1]
260
307
  end
261
308
 
262
309
  elsif res = /^TODO:(.*)/.match(s) # check if TODO block
@@ -276,10 +323,11 @@ class DocParser
276
323
  doc.todo_blocks.append(item)
277
324
 
278
325
  else # Reqular Paragraph
326
+
279
327
  temp_md_table = process_temp_table(doc, temp_md_table)
280
328
  if temp_md_list
281
329
  if MarkdownList.unordered_list_item?(s) || MarkdownList.ordered_list_item?(s)
282
- temp_md_list.addRow(s)
330
+ temp_md_list.add_row(s)
283
331
  next
284
332
  else
285
333
  doc.items.append temp_md_list
@@ -314,7 +362,7 @@ class DocParser
314
362
  doc.items.append(item)
315
363
  end
316
364
 
317
- def self.process_temp_table(doc, temp_md_table) # rubocop:disable Metrics/MethodLength
365
+ def self.process_temp_table(doc, temp_md_table)
318
366
  if temp_md_table
319
367
  if temp_md_table.is_separator_detected
320
368
  doc.items.append temp_md_table
@@ -1,69 +1,64 @@
1
+ # frozen_string_literal: true
1
2
 
2
- class BaseDocument
3
+ class BaseDocument # rubocop:disable Style/Documentation
4
+ attr_accessor :title, :id, :dom, :headings
3
5
 
4
- attr_accessor :title
5
- attr_accessor :id
6
- attr_accessor :dom
6
+ def initialize
7
+ @items = []
8
+ @headings = []
9
+ @title = ''
10
+ @id = ''
11
+ @dom = nil
12
+ end
7
13
 
8
- def initialize()
9
- @items = Array.new
10
- @headings = Array.new
11
- @title = ""
12
- @id = ""
13
- @dom = nil
14
- end
15
-
16
- def save_html_to_file html_rows, nav_pane, output_file_path
17
-
18
- gem_root = File.expand_path './../../..', File.dirname(__FILE__)
19
- template_file = gem_root + "/lib/almirah/templates/page.html"
14
+ def save_html_to_file(html_rows, nav_pane, output_file_path) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
15
+ gem_root = File.expand_path './../../..', File.dirname(__FILE__)
16
+ template_file = "#{gem_root}/lib/almirah/templates/page.html"
20
17
 
21
- file = File.open( template_file )
22
- file_data = file.readlines
23
- file.close
18
+ file = File.open(template_file)
19
+ file_data = file.readlines
20
+ file.close
24
21
 
25
- if @id == 'index'
26
- output_file_path += "#{@id}.html"
27
- else
28
- output_file_path += "#{@id}/#{@id}.html"
22
+ output_file_path += if @id == 'index'
23
+ "#{@id}.html"
24
+ else
25
+ "#{@id}/#{@id}.html"
26
+ end
27
+ file = File.open(output_file_path, 'w')
28
+ file_data.each do |s| # rubocop:disable Metrics/BlockLength
29
+ if s.include?('{{CONTENT}}')
30
+ html_rows.each do |r|
31
+ file.puts r
29
32
  end
30
- file = File.open( output_file_path, "w" )
31
- file_data.each do |s|
32
- if s.include?('{{CONTENT}}')
33
- html_rows.each do |r|
34
- file.puts r
35
- end
36
- elsif s.include?('{{NAV_PANE}}')
37
- if nav_pane
38
- file.puts nav_pane.to_html
39
- end
40
- elsif s.include?('{{DOCUMENT_TITLE}}')
41
- file.puts s.gsub! '{{DOCUMENT_TITLE}}', @title
42
- elsif s.include?('{{STYLES_AND_SCRIPTS}}')
43
- if @id == 'index'
44
- file.puts '<script type="module" src="./scripts/orama_search.js"></script>'
45
- file.puts '<link rel="stylesheet" href="./css/search.css">'
46
- file.puts '<link rel="stylesheet" href="./css/main.css">'
47
- file.puts '<script src="./scripts/main.js"></script>'
48
- elsif self.instance_of? Specification
49
- file.puts '<link rel="stylesheet" href="../../css/main.css">'
50
- file.puts '<script src="../../scripts/main.js"></script>'
51
- elsif self.instance_of? Traceability
52
- file.puts '<link rel="stylesheet" href="../../css/main.css">'
53
- file.puts '<script src="../../scripts/main.js"></script>'
54
- elsif self.instance_of? Coverage
55
- file.puts '<link rel="stylesheet" href="../../css/main.css">'
56
- file.puts '<script src="../../scripts/main.js"></script>'
57
- elsif self.instance_of? Protocol
58
- file.puts '<link rel="stylesheet" href="../../../css/main.css">'
59
- file.puts '<script src="../../../scripts/main.js"></script>'
60
- end
61
- elsif s.include?('{{GEM_VERSION}}')
62
- file.puts "(" + Gem.loaded_specs['Almirah'].version.version + ")"
63
- else
64
- file.puts s
65
- end
33
+ elsif s.include?('{{NAV_PANE}}')
34
+ file.puts nav_pane.to_html if nav_pane
35
+ elsif s.include?('{{DOCUMENT_TITLE}}')
36
+ file.puts s.gsub! '{{DOCUMENT_TITLE}}', @title
37
+ elsif s.include?('{{STYLES_AND_SCRIPTS}}')
38
+ if @id == 'index'
39
+ file.puts '<script type="module" src="./scripts/orama_search.js"></script>'
40
+ file.puts '<link rel="stylesheet" href="./css/search.css">'
41
+ file.puts '<link rel="stylesheet" href="./css/main.css">'
42
+ file.puts '<script src="./scripts/main.js"></script>'
43
+ elsif instance_of? Specification
44
+ file.puts '<link rel="stylesheet" href="../../css/main.css">'
45
+ file.puts '<script src="../../scripts/main.js"></script>'
46
+ elsif instance_of? Traceability
47
+ file.puts '<link rel="stylesheet" href="../../css/main.css">'
48
+ file.puts '<script src="../../scripts/main.js"></script>'
49
+ elsif instance_of? Coverage
50
+ file.puts '<link rel="stylesheet" href="../../css/main.css">'
51
+ file.puts '<script src="../../scripts/main.js"></script>'
52
+ elsif instance_of? Protocol
53
+ file.puts '<link rel="stylesheet" href="../../../css/main.css">'
54
+ file.puts '<script src="../../../scripts/main.js"></script>'
66
55
  end
67
- file.close
56
+ elsif s.include?('{{GEM_VERSION}}')
57
+ file.puts "(#{Gem.loaded_specs['Almirah'].version.version})"
58
+ else
59
+ file.puts s
60
+ end
68
61
  end
69
- end
62
+ file.close
63
+ end
64
+ end
@@ -1,78 +1,80 @@
1
- require_relative "base_document"
1
+ require_relative 'base_document'
2
2
 
3
3
  class Coverage < BaseDocument
4
+ attr_accessor :top_doc, :bottom_doc, :covered_items, :passed_steps_number, :failed_steps_number
4
5
 
5
- attr_accessor :top_doc
6
- attr_accessor :bottom_doc
6
+ def initialize(top_doc)
7
+ super()
8
+ @top_doc = top_doc
9
+ @bottom_doc = nil
7
10
 
8
- def initialize(top_doc)
9
- super()
10
- @top_doc = top_doc
11
- @bottom_doc = bottom_doc
11
+ @id = top_doc.id + '-' + 'tests'
12
+ @title = 'Coverage Matrix: ' + @id
13
+ @covered_items = {}
14
+ @passed_steps_number = 0
15
+ @failed_steps_number = 0
16
+ end
12
17
 
13
- @id = top_doc.id + "-" + "tests"
14
- @title = "Coverage Matrix: " + @id
15
- end
16
-
17
- def to_console
18
- puts "\e[35m" + "Traceability: " + @id + "\e[0m"
19
- end
18
+ def to_console
19
+ puts "\e[35m" + 'Traceability: ' + @id + "\e[0m"
20
+ end
20
21
 
21
- def to_html(nav_pane, output_file_path)
22
+ def to_html(nav_pane, output_file_path)
23
+ html_rows = []
22
24
 
23
- html_rows = Array.new
25
+ html_rows.append('')
26
+ s = "<h1>#{@title}</h1>\n"
27
+ s += "<table class=\"controlled\">\n"
28
+ 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"
29
+ html_rows.append s
24
30
 
25
- html_rows.append('')
26
- s = "<h1>#{@title}</h1>\n"
27
- s += "<table class=\"controlled\">\n"
28
- 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"
29
- html_rows.append s
31
+ sorted_items = @top_doc.controlled_items.sort_by { |w| w.id }
30
32
 
31
- sorted_items = @top_doc.controlled_items.sort_by { |w| w.id }
33
+ sorted_items.each do |top_item|
34
+ row = render_table_row top_item
35
+ html_rows.append row
36
+ end
37
+ html_rows.append "</table>\n"
32
38
 
33
- sorted_items.each do |top_item|
34
- row = render_table_row top_item
35
- html_rows.append row
36
- end
37
- html_rows.append "</table>\n"
39
+ save_html_to_file(html_rows, nav_pane, output_file_path)
40
+ end
38
41
 
39
- self.save_html_to_file(html_rows, nav_pane, output_file_path)
40
-
41
- end
42
+ def render_table_row(top_item)
43
+ s = ''
44
+ if top_item.coverage_links
45
+ id_color = if top_item.coverage_links.length > 1
46
+ '' # "style='background-color: #fff8c5;'" # disabled for now
47
+ else
48
+ ''
49
+ end
50
+ top_item.coverage_links.each do |bottom_item|
51
+ s += "\t<tr>\n"
52
+ 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"
53
+ s += "\t\t<td class=\"item_text\" style='width: 42%;'>#{top_item.text}</td>\n"
42
54
 
43
- def render_table_row(top_item)
44
- s = ""
45
- if top_item.coverage_links
46
- if top_item.coverage_links.length > 1
47
- id_color = "" # "style='background-color: #fff8c5;'" # disabled for now
48
- else
49
- id_color = ""
50
- end
51
- top_item.coverage_links.each do |bottom_item|
52
- s += "\t<tr>\n"
53
- 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"
54
- s += "\t\t<td class=\"item_text\" style='width: 42%;'>#{top_item.text}</td>\n"
55
-
56
- if bottom_item.columns[-2].text.downcase == "pass"
57
- test_step_color = "style='background-color: #cfc;'"
58
- elsif bottom_item.columns[-2].text.downcase == "fail"
59
- test_step_color = "style='background-color: #fcc;'"
60
- else
61
- test_step_color = ""
62
- end
55
+ test_step_color = if bottom_item.columns[-2].text.downcase == 'pass'
56
+ @passed_steps_number += 1
57
+ "style='background-color: #cfc;'"
58
+ elsif bottom_item.columns[-2].text.downcase == 'fail'
59
+ @failed_steps_number += 1
60
+ "style='background-color: #fcc;'"
61
+ else
62
+ ''
63
+ end
63
64
 
64
- 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"
65
- s += "\t\t<td class=\"item_text\" style='width: 42%;'>#{bottom_item.columns[1].text}</td>\n"
66
- s += "\t</tr>\n"
67
- end
68
- else
69
- s += "\t<tr>\n"
70
- 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"
71
- s += "\t\t<td class=\"item_text\" style='width: 42%;'>#{top_item.text}</td>\n"
72
- s += "\t\t<td class=\"item_id\"></td>\n"
73
- s += "\t\t<td class=\"item_text\" style='width: 42%;'></td>\n"
74
- s += "\t</tr>\n"
75
- end
76
- return s
65
+ 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"
66
+ s += "\t\t<td class=\"item_text\" style='width: 42%;'>#{bottom_item.columns[1].text}</td>\n"
67
+ s += "\t</tr>\n"
68
+ @covered_items[top_item.id.to_s.downcase] = top_item
69
+ end
70
+ else
71
+ s += "\t<tr>\n"
72
+ 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"
73
+ s += "\t\t<td class=\"item_text\" style='width: 42%;'>#{top_item.text}</td>\n"
74
+ s += "\t\t<td class=\"item_id\"></td>\n"
75
+ s += "\t\t<td class=\"item_text\" style='width: 42%;'></td>\n"
76
+ s += "\t</tr>\n"
77
77
  end
78
+ s
79
+ end
78
80
  end