Almirah 0.1.9 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,334 @@
1
+ require_relative 'doc_items/text_line'
2
+ require_relative 'doc_items/doc_item'
3
+ require_relative 'doc_items/heading'
4
+ require_relative 'doc_items/paragraph'
5
+ require_relative 'doc_items/blockquote'
6
+ require_relative 'doc_items/code_block'
7
+ require_relative 'doc_items/todo_block'
8
+ require_relative 'doc_items/controlled_paragraph'
9
+ require_relative 'doc_items/markdown_table'
10
+ require_relative 'doc_items/controlled_table'
11
+ require_relative 'doc_items/image'
12
+ require_relative 'doc_items/markdown_list'
13
+ require_relative 'doc_items/doc_footer'
14
+
15
+ class DocParser
16
+ def self.parse(doc, text_lines)
17
+ temp_md_table = nil
18
+ temp_md_list = nil
19
+ temp_code_block = nil
20
+ # restart section numbering for each new document
21
+ Heading.reset_global_section_number
22
+
23
+ text_lines.each do |s|
24
+ if s.lstrip != ''
25
+ if res = /^(\#{1,})\s(.*)/.match(s) # Heading
26
+
27
+ if temp_md_table
28
+ doc.items.append temp_md_table
29
+ temp_md_table = nil
30
+ end
31
+ if temp_md_list
32
+ doc.items.append temp_md_list
33
+ temp_md_list = nil
34
+ end
35
+
36
+ level = res[1].length
37
+ value = res[2]
38
+
39
+ if level == 1 && doc.title == ''
40
+ doc.title = value
41
+ end
42
+
43
+ item = Heading.new(doc, value, level)
44
+ doc.items.append(item)
45
+ doc.headings.append(item)
46
+
47
+ elsif res = /^%\s(.*)/.match(s) # Pandoc Document Title
48
+
49
+ title = res[1]
50
+
51
+ if doc.title == ''
52
+ doc.title = title
53
+ end
54
+
55
+ item = Heading.new(doc, title, 0)
56
+ doc.items.append(item)
57
+ doc.headings.append(item)
58
+
59
+ elsif res = /^\[(\S*)\]\s+(.*)/.match(s) # Controlled Paragraph
60
+
61
+ if temp_md_table
62
+ doc.items.append temp_md_table
63
+ temp_md_table = nil
64
+ end
65
+ if temp_md_list
66
+ doc.items.append temp_md_list
67
+ temp_md_list = nil
68
+ end
69
+
70
+ id = res[1].upcase
71
+ text = res[2]
72
+ up_links = nil
73
+
74
+ # check if it contains the uplink (one or many)
75
+ # TODO: check this regular expression
76
+ first_pos = text.length # for trailing commas
77
+ tmp = text.scan(/(>\[(?>[^\[\]]|\g<0>)*\])/) # >[SRS-001], >[SYS-002]
78
+ if tmp.length > 0
79
+ up_links = []
80
+ tmp.each do |ul|
81
+ lnk = ul[0]
82
+ # do not add links for the self document
83
+ doc_id = /([a-zA-Z]+)-\d+/.match(lnk) # SRS
84
+ if (doc_id) and (doc_id[1].downcase != doc.id.downcase)
85
+ up_links << lnk.upcase
86
+ end
87
+ # try to find the real end of text
88
+ pos = text.index(lnk)
89
+ first_pos = pos if pos < first_pos
90
+ # remove uplink from text
91
+ text = text.split(lnk, 1).join('')
92
+ end
93
+ # remove trailing commas and spaces
94
+ if text.length > first_pos
95
+ first_pos -= 1
96
+ text = text[0..first_pos].strip
97
+ end
98
+ end
99
+
100
+ # since we already know id and text
101
+ item = ControlledParagraph.new(doc, text, id)
102
+
103
+ if up_links
104
+ up_links.uniq! #remove duplicates
105
+ doc.items_with_uplinks_number += 1 # for statistics
106
+ up_links.each do |ul|
107
+ next unless tmp = />\[(\S*)\]$/.match(ul) # >[SRS-001]
108
+
109
+ up_link_id = tmp[1]
110
+
111
+ item.up_link_ids = [] unless item.up_link_ids
112
+
113
+ item.up_link_ids.append(up_link_id)
114
+
115
+ if tmp = /^([a-zA-Z]+)-\d+/.match(up_link_id) # SRS
116
+ doc.up_link_docs[tmp[1].downcase.to_s] = tmp[1].downcase # multiple documents could be up-linked
117
+ end
118
+ end
119
+ end
120
+
121
+ doc.items.append(item)
122
+ # for statistics
123
+ if doc.dictionary.has_key?(id.to_s)
124
+ doc.duplicated_ids_number += 1
125
+ doc.duplicates_list.append(item)
126
+ else
127
+ doc.dictionary[id.to_s] = item # for fast search
128
+ end
129
+ doc.controlled_items.append(item) # for fast search
130
+
131
+ # for statistics
132
+ n = /\d+/.match(id)[0].to_i
133
+ if n > doc.last_used_id_number
134
+ doc.last_used_id = id
135
+ doc.last_used_id_number = n
136
+ end
137
+
138
+ elsif res = /^!\[(.*)\]\((.*)\)/.match(s) # Image
139
+
140
+ if temp_md_table
141
+ doc.items.append temp_md_table
142
+ temp_md_table = nil
143
+ end
144
+ if temp_md_list
145
+ doc.items.append temp_md_list
146
+ temp_md_list = nil
147
+ end
148
+
149
+ img_text = res[1]
150
+ img_path = res[2]
151
+
152
+ item = Image.new(img_text, img_path)
153
+ item.parent_doc = doc
154
+ item.parent_heading = doc.headings[-1]
155
+
156
+ doc.items.append(item)
157
+
158
+ elsif res = /^(\*\s+)(.*)/.match(s) # check if unordered list start
159
+
160
+ if temp_md_table
161
+ doc.items.append temp_md_table
162
+ temp_md_table = nil
163
+ end
164
+
165
+ row = res[2]
166
+
167
+ if temp_md_list
168
+ temp_md_list.addRow(s)
169
+ else
170
+ item = MarkdownList.new(doc, false)
171
+ item.addRow(s)
172
+ temp_md_list = item
173
+ end
174
+
175
+ elsif res = /^\d[.]\s(.*)/.match(s) # check if ordered list start
176
+
177
+ if temp_md_table
178
+ doc.items.append temp_md_table
179
+ temp_md_table = nil
180
+ end
181
+
182
+ row = res[1]
183
+
184
+ if temp_md_list
185
+ temp_md_list.addRow(s)
186
+ else
187
+ item = MarkdownList.new(doc, true)
188
+ item.addRow(s)
189
+ temp_md_list = item
190
+ end
191
+
192
+ elsif s[0] == '|' # check if table
193
+
194
+ if temp_md_list
195
+ doc.items.append temp_md_list
196
+ temp_md_list = nil
197
+ end
198
+
199
+ if res = /^[|](-{3,})[|]/.match(s) # check if it is a separator first
200
+
201
+ if temp_md_table
202
+ # separator is found after heading - just skip it
203
+ else
204
+ # separator out of table scope consider it just as a regular paragraph
205
+ item = Paragraph.new(s)
206
+ item.parent_doc = doc
207
+ item.parent_heading = doc.headings[-1]
208
+ doc.items.append(item)
209
+ end
210
+
211
+ elsif res = /^[|](.*[|])/.match(s) # check if it looks as a table
212
+
213
+ row = res[1]
214
+
215
+ if temp_md_table
216
+ # check if it is a controlled table
217
+ unless temp_md_table.addRow(row)
218
+ temp_md_table = ControlledTable.new(temp_md_table, doc)
219
+ temp_md_table.parent_doc = doc
220
+ temp_md_table.addRow(row)
221
+ end
222
+ else
223
+ # start table from heading
224
+ temp_md_table = MarkdownTable.new(row)
225
+ temp_md_table.parent_doc = doc
226
+ end
227
+ end
228
+
229
+ elsif res = /^>(.*)/.match(s) # check if blockquote
230
+
231
+ if temp_md_table
232
+ doc.items.append temp_md_table
233
+ temp_md_table = nil
234
+ end
235
+ if temp_md_list
236
+ doc.items.append temp_md_list
237
+ temp_md_list = nil
238
+ end
239
+
240
+ item = Blockquote.new(res[1])
241
+ item.parent_doc = doc
242
+ item.parent_heading = doc.headings[-1]
243
+ doc.items.append(item)
244
+
245
+ elsif res = /^```(\w*)/.match(s) # check if code block
246
+
247
+ if temp_md_table
248
+ doc.items.append temp_md_table
249
+ temp_md_table = nil
250
+ end
251
+ if temp_md_list
252
+ doc.items.append temp_md_list
253
+ temp_md_list = nil
254
+ end
255
+
256
+ suggested_format = ''
257
+ suggested_format = res[1] if res.length == 2
258
+
259
+ if temp_code_block
260
+ # close already opened block
261
+ doc.items.append(temp_code_block)
262
+ temp_code_block = nil
263
+ else
264
+ # start code block
265
+ temp_code_block = CodeBlock.new(suggested_format)
266
+ temp_code_block.parent_doc = doc
267
+ end
268
+
269
+ elsif res = /^TODO:(.*)/.match(s) # check if TODO block
270
+
271
+ if temp_md_table
272
+ doc.items.append temp_md_table
273
+ temp_md_table = nil
274
+ end
275
+ if temp_md_list
276
+ doc.items.append temp_md_list
277
+ temp_md_list = nil
278
+ end
279
+
280
+ text = '**TODO**: ' + res[1]
281
+
282
+ item = TodoBlock.new(text)
283
+ item.parent_doc = doc
284
+ item.parent_heading = doc.headings[-1]
285
+ doc.items.append(item)
286
+ doc.todo_blocks.append(item)
287
+
288
+ else # Reqular Paragraph
289
+ if temp_md_table
290
+ doc.items.append temp_md_table
291
+ temp_md_table = nil
292
+ end
293
+ if temp_md_list
294
+ if MarkdownList.unordered_list_item?(s) || MarkdownList.ordered_list_item?(s)
295
+ temp_md_list.addRow(s)
296
+ next
297
+ else
298
+ doc.items.append temp_md_list
299
+ temp_md_list = nil
300
+ end
301
+ end
302
+ if temp_code_block
303
+ temp_code_block.code_lines.append(s)
304
+ else
305
+ item = Paragraph.new(s)
306
+ item.parent_doc = doc
307
+ item.parent_heading = doc.headings[-1]
308
+ doc.items.append(item)
309
+ end
310
+ end
311
+ elsif temp_md_list
312
+ doc.items.append temp_md_list
313
+ temp_md_list = nil # lists are separated by emty line from each other
314
+ end
315
+ end
316
+ # Finalize non-closed elements
317
+ if temp_md_table
318
+ doc.items.append temp_md_table
319
+ temp_md_table = nil
320
+ end
321
+ if temp_md_list
322
+ doc.items.append temp_md_list
323
+ temp_md_list = nil
324
+ end
325
+ if temp_code_block
326
+ doc.items.append temp_code_block
327
+ temp_code_block = nil
328
+ end
329
+ # Add footer to close opened tables if any
330
+ item = DocFooter.new
331
+ item.parent_doc = doc
332
+ doc.items.append(item)
333
+ end
334
+ end
@@ -1,16 +1,11 @@
1
1
 
2
2
  class BaseDocument
3
3
 
4
- attr_accessor :path
5
- attr_accessor :items
6
- attr_accessor :headings
7
4
  attr_accessor :title
8
5
  attr_accessor :id
9
6
  attr_accessor :dom
10
7
 
11
- def initialize(fele_path)
12
-
13
- @path = fele_path
8
+ def initialize()
14
9
  @items = Array.new
15
10
  @headings = Array.new
16
11
  @title = ""
@@ -44,6 +39,27 @@ class BaseDocument
44
39
  end
45
40
  elsif s.include?('{{DOCUMENT_TITLE}}')
46
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 + ")"
47
63
  else
48
64
  file.puts s
49
65
  end
@@ -4,16 +4,12 @@ class Coverage < BaseDocument
4
4
 
5
5
  attr_accessor :top_doc
6
6
  attr_accessor :bottom_doc
7
- attr_accessor :items
8
7
 
9
8
  def initialize(top_doc)
10
-
9
+ super()
11
10
  @top_doc = top_doc
12
11
  @bottom_doc = bottom_doc
13
12
 
14
- @items = Array.new
15
- @headings = Array.new
16
-
17
13
  @id = top_doc.id + "-" + "tests"
18
14
  @title = "Coverage Matrix: " + @id
19
15
  end
@@ -2,13 +2,11 @@ require_relative "base_document"
2
2
 
3
3
  class Index < BaseDocument
4
4
 
5
- attr_accessor :items
6
5
  attr_accessor :project
7
6
 
8
7
  def initialize(project)
9
- @items = Array.new
8
+ super()
10
9
  @project = project
11
-
12
10
  @title = "Document Index"
13
11
  @id = "index"
14
12
  end
@@ -0,0 +1,20 @@
1
+ require_relative "base_document"
2
+
3
+ class PersistentDocument < BaseDocument
4
+
5
+ attr_accessor :path
6
+ attr_accessor :items
7
+ attr_accessor :controlled_items
8
+ attr_accessor :headings
9
+ attr_accessor :up_link_docs
10
+
11
+ def initialize(fele_path)
12
+ super()
13
+ @path = fele_path
14
+ @items = []
15
+ @controlled_items = []
16
+ @headings = []
17
+ @up_link_docs = {}
18
+ end
19
+
20
+ end
@@ -1,22 +1,10 @@
1
- require_relative "base_document"
1
+ require_relative "persistent_document"
2
2
 
3
- class Protocol < BaseDocument
4
-
5
- attr_accessor :up_link_doc_id
6
- #attr_accessor :dictionary
7
- attr_accessor :controlled_items
3
+ class Protocol < PersistentDocument
8
4
 
9
5
  def initialize(fele_path)
10
-
11
- @path = fele_path
12
- @title = ""
13
- @items = Array.new
14
- @headings = Array.new
15
- @controlled_items = Array.new
16
- #@dictionary = Hash.new
17
-
6
+ super
18
7
  @id = File.basename(fele_path, File.extname(fele_path)).downcase
19
- @up_link_doc_id = Hash.new
20
8
  end
21
9
 
22
10
  def to_html(nav_pane, output_file_path)
@@ -1,10 +1,8 @@
1
- require_relative "base_document"
1
+ require_relative "persistent_document"
2
2
 
3
- class Specification < BaseDocument
3
+ class Specification < PersistentDocument
4
4
 
5
- attr_accessor :up_link_doc_id
6
5
  attr_accessor :dictionary
7
- attr_accessor :controlled_items
8
6
  attr_accessor :todo_blocks
9
7
  attr_accessor :wrong_links_hash
10
8
 
@@ -18,12 +16,7 @@ class Specification < BaseDocument
18
16
  attr_accessor :color
19
17
 
20
18
  def initialize(fele_path)
21
-
22
- @path = fele_path
23
- @title = ""
24
- @items = Array.new
25
- @headings = Array.new
26
- @controlled_items = Array.new
19
+ super
27
20
  @dictionary = Hash.new
28
21
  @duplicates_list = Array.new
29
22
  @todo_blocks = Array.new
@@ -39,7 +32,6 @@ class Specification < BaseDocument
39
32
  @color = 'bbb'
40
33
 
41
34
  @id = File.basename(fele_path, File.extname(fele_path)).downcase
42
- @up_link_doc_id = Hash.new
43
35
  end
44
36
 
45
37
  def to_console
@@ -9,15 +9,12 @@ class Traceability < BaseDocument
9
9
  attr_accessor :traced_items
10
10
 
11
11
  def initialize(top_doc, bottom_doc, is_agregated)
12
-
12
+ super()
13
13
  @top_doc = top_doc
14
14
  @bottom_doc = bottom_doc
15
15
  @is_agregated = is_agregated
16
16
  @traced_items = {}
17
17
 
18
- @items = Array.new
19
- @headings = Array.new
20
-
21
18
  if @is_agregated
22
19
  @id = top_doc.id + "-all"
23
20
  else
@@ -49,7 +49,7 @@ class Document
49
49
 
50
50
  def section_tree_to_html
51
51
  s = ''
52
- s += "<a href=\"\#" + @root_section.heading.anchor_id.to_s + "\">" + @root_section.heading.text + "</a>\n"
52
+ s += "<a href=\"\#" + @root_section.heading.anchor_id.to_s + "\">" + @root_section.heading.get_section_info + "</a>\n"
53
53
  if @root_section.sections.length >0
54
54
  s += "\t<ul class=\"fa-ul\" style=\"margin-top: 2px;\">\n"
55
55
  @root_section.sections.each do |sub_section|