Almirah 0.1.9 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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|