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.
- checksums.yaml +4 -4
- data/lib/almirah/doc_fabric.rb +3 -327
- data/lib/almirah/doc_items/controlled_paragraph.rb +3 -1
- data/lib/almirah/doc_items/controlled_table.rb +1 -1
- data/lib/almirah/doc_items/doc_item.rb +4 -0
- data/lib/almirah/doc_items/heading.rb +18 -2
- data/lib/almirah/doc_items/markdown_list.rb +5 -2
- data/lib/almirah/doc_parser.rb +334 -0
- data/lib/almirah/doc_types/base_document.rb +22 -6
- data/lib/almirah/doc_types/coverage.rb +1 -5
- data/lib/almirah/doc_types/index.rb +1 -3
- data/lib/almirah/doc_types/persistent_document.rb +20 -0
- data/lib/almirah/doc_types/protocol.rb +3 -15
- data/lib/almirah/doc_types/specification.rb +3 -11
- data/lib/almirah/doc_types/traceability.rb +1 -4
- data/lib/almirah/dom/document.rb +1 -1
- data/lib/almirah/project.rb +58 -47
- data/lib/almirah/project_configuration.rb +42 -0
- data/lib/almirah/search/specifications_db.rb +66 -0
- data/lib/almirah/templates/css/main.css +298 -0
- data/lib/almirah/templates/css/search.css +40 -0
- data/lib/almirah/templates/page.html +7 -357
- data/lib/almirah/templates/scripts/main.js +61 -0
- data/lib/almirah/templates/scripts/orama_search.js +136 -0
- data/lib/almirah.rb +3 -1
- metadata +10 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: da8737eaa32966b6559639becfd0737c25394340b1f32cc682a1063a78205190
|
4
|
+
data.tar.gz: 40914f94ceda02630a170c04965d65a83a5073db6d5aa32eb678caaf2823ee96
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a3f545f59badec9c749b0b9104eb9a2ae7737bd47f2c36a1c5d2b743df8a6931654500b798b6309b3a96368b926d64e8dd52f4faae4fd83affe453a861cbad9e
|
7
|
+
data.tar.gz: eeb982a3da8bbba0dadf6832fc9491d334e31b06aaf8749921e8a4bb0dc6fa9b94a8a249b05c883f3a288b242550be46342a9bccdec11b809910caaa5644930c
|
data/lib/almirah/doc_fabric.rb
CHANGED
@@ -1,20 +1,7 @@
|
|
1
1
|
require_relative 'doc_types/base_document'
|
2
2
|
require_relative 'doc_types/specification'
|
3
3
|
require_relative 'doc_types/protocol'
|
4
|
-
require_relative '
|
5
|
-
require_relative 'doc_items/doc_item'
|
6
|
-
require_relative 'doc_items/heading'
|
7
|
-
require_relative 'doc_items/paragraph'
|
8
|
-
require_relative 'doc_items/blockquote'
|
9
|
-
require_relative 'doc_items/code_block'
|
10
|
-
require_relative 'doc_items/todo_block'
|
11
|
-
require_relative 'doc_items/controlled_paragraph'
|
12
|
-
require_relative 'doc_items/markdown_table'
|
13
|
-
require_relative 'doc_items/controlled_table'
|
14
|
-
require_relative 'doc_items/image'
|
15
|
-
require_relative 'doc_items/markdown_list'
|
16
|
-
require_relative 'doc_items/doc_footer'
|
17
|
-
|
4
|
+
require_relative 'doc_parser'
|
18
5
|
require_relative 'dom/document'
|
19
6
|
|
20
7
|
class DocFabric
|
@@ -45,326 +32,15 @@ class DocFabric
|
|
45
32
|
end
|
46
33
|
|
47
34
|
def self.parse_document(doc)
|
48
|
-
temp_md_table = nil
|
49
|
-
temp_md_list = nil
|
50
|
-
temp_code_block = nil
|
51
35
|
|
52
36
|
file = File.open(doc.path)
|
53
37
|
file_lines = file.readlines
|
54
38
|
file.close
|
55
39
|
|
56
|
-
|
57
|
-
if s.lstrip != ''
|
58
|
-
if res = /^(\#{1,})\s(.*)/.match(s) # Heading
|
59
|
-
|
60
|
-
if temp_md_table
|
61
|
-
doc.items.append temp_md_table
|
62
|
-
temp_md_table = nil
|
63
|
-
end
|
64
|
-
if temp_md_list
|
65
|
-
doc.items.append temp_md_list
|
66
|
-
temp_md_list = nil
|
67
|
-
end
|
68
|
-
|
69
|
-
level = res[1].length
|
70
|
-
value = res[2]
|
71
|
-
|
72
|
-
if level == 1 && doc.title == ''
|
73
|
-
doc.title = value
|
74
|
-
level = 0 # Doc Title is a Root
|
75
|
-
Heading.reset_global_section_number
|
76
|
-
end
|
77
|
-
|
78
|
-
item = Heading.new(value, level)
|
79
|
-
item.parent_doc = doc
|
80
|
-
doc.items.append(item)
|
81
|
-
doc.headings.append(item)
|
82
|
-
|
83
|
-
elsif res = /^%\s(.*)/.match(s) # Pandoc Document Title
|
84
|
-
|
85
|
-
title = res[1]
|
86
|
-
|
87
|
-
if doc.title == ''
|
88
|
-
doc.title = title
|
89
|
-
Heading.reset_global_section_number
|
90
|
-
end
|
91
|
-
|
92
|
-
item = Heading.new(title, 0)
|
93
|
-
item.parent_doc = doc
|
94
|
-
doc.items.append(item)
|
95
|
-
doc.headings.append(item)
|
96
|
-
|
97
|
-
Heading.reset_global_section_number # Pandoc Document Title is not a section, so it shall not be taken into account in numbering
|
98
|
-
|
99
|
-
elsif res = /^\[(\S*)\]\s+(.*)/.match(s) # Controlled Paragraph
|
100
|
-
|
101
|
-
if temp_md_table
|
102
|
-
doc.items.append temp_md_table
|
103
|
-
temp_md_table = nil
|
104
|
-
end
|
105
|
-
if temp_md_list
|
106
|
-
doc.items.append temp_md_list
|
107
|
-
temp_md_list = nil
|
108
|
-
end
|
109
|
-
|
110
|
-
id = res[1]
|
111
|
-
text = res[2]
|
112
|
-
up_links = nil
|
113
|
-
|
114
|
-
# check if it contains the uplink (one or many)
|
115
|
-
# TODO: check this regular expression
|
116
|
-
first_pos = text.length # for trailing commas
|
117
|
-
tmp = text.scan(/(>\[(?>[^\[\]]|\g<0>)*\])/) # >[SRS-001], >[SYS-002]
|
118
|
-
if tmp.length > 0
|
119
|
-
up_links = []
|
120
|
-
tmp.each do |ul|
|
121
|
-
up_links.append(ul[0])
|
122
|
-
# try to find the real end of text
|
123
|
-
pos = text.index(ul[0])
|
124
|
-
first_pos = pos if pos < first_pos
|
125
|
-
# remove uplink from text
|
126
|
-
text = text.split(ul[0]).join('')
|
127
|
-
end
|
128
|
-
# remove trailing commas and spaces
|
129
|
-
if text.length > first_pos
|
130
|
-
first_pos -= 1
|
131
|
-
text = text[0..first_pos].strip
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
# since we already know id and text
|
136
|
-
item = ControlledParagraph.new(text, id)
|
137
|
-
|
138
|
-
if up_links
|
139
|
-
doc.items_with_uplinks_number += 1 # for statistics
|
140
|
-
up_links.each do |ul|
|
141
|
-
next unless tmp = />\[(\S*)\]$/.match(ul) # >[SRS-001]
|
142
|
-
|
143
|
-
up_link_id = tmp[1]
|
144
|
-
|
145
|
-
item.up_link_ids = [] unless item.up_link_ids
|
146
|
-
|
147
|
-
item.up_link_ids.append(up_link_id)
|
148
|
-
|
149
|
-
if tmp = /^([a-zA-Z]+)-\d+/.match(up_link_id) # SRS
|
150
|
-
doc.up_link_doc_id[tmp[1].downcase.to_s] = tmp[1].downcase # multiple documents could be up-linked
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
item.parent_doc = doc
|
156
|
-
item.parent_heading = doc.headings[-1]
|
157
|
-
|
158
|
-
doc.items.append(item)
|
159
|
-
# for statistics
|
160
|
-
if doc.dictionary.has_key?(id.to_s)
|
161
|
-
doc.duplicated_ids_number += 1
|
162
|
-
doc.duplicates_list.append(item)
|
163
|
-
else
|
164
|
-
doc.dictionary[id.to_s] = item # for fast search
|
165
|
-
end
|
166
|
-
doc.controlled_items.append(item) # for fast search
|
167
|
-
|
168
|
-
# for statistics
|
169
|
-
n = /\d+/.match(id)[0].to_i
|
170
|
-
if n > doc.last_used_id_number
|
171
|
-
doc.last_used_id = id
|
172
|
-
doc.last_used_id_number = n
|
173
|
-
end
|
174
|
-
|
175
|
-
elsif res = /^!\[(.*)\]\((.*)\)/.match(s) # Image
|
176
|
-
|
177
|
-
if temp_md_table
|
178
|
-
doc.items.append temp_md_table
|
179
|
-
temp_md_table = nil
|
180
|
-
end
|
181
|
-
if temp_md_list
|
182
|
-
doc.items.append temp_md_list
|
183
|
-
temp_md_list = nil
|
184
|
-
end
|
185
|
-
|
186
|
-
img_text = res[1]
|
187
|
-
img_path = res[2]
|
188
|
-
|
189
|
-
item = Image.new(img_text, img_path)
|
190
|
-
item.parent_doc = doc
|
191
|
-
|
192
|
-
doc.items.append(item)
|
193
|
-
|
194
|
-
elsif res = /^(\*\s+)(.*)/.match(s) # check if unordered list start
|
40
|
+
DocParser.parse(doc, file_lines)
|
195
41
|
|
196
|
-
if temp_md_table
|
197
|
-
doc.items.append temp_md_table
|
198
|
-
temp_md_table = nil
|
199
|
-
end
|
200
|
-
|
201
|
-
row = res[2]
|
202
|
-
|
203
|
-
if temp_md_list
|
204
|
-
temp_md_list.addRow(s)
|
205
|
-
else
|
206
|
-
item = MarkdownList.new(false)
|
207
|
-
item.addRow(s)
|
208
|
-
item.parent_doc = doc
|
209
|
-
temp_md_list = item
|
210
|
-
end
|
211
|
-
|
212
|
-
elsif res = /^\d[.]\s(.*)/.match(s) # check if ordered list start
|
213
|
-
|
214
|
-
if temp_md_table
|
215
|
-
doc.items.append temp_md_table
|
216
|
-
temp_md_table = nil
|
217
|
-
end
|
218
|
-
|
219
|
-
row = res[1]
|
220
|
-
|
221
|
-
if temp_md_list
|
222
|
-
temp_md_list.addRow(s)
|
223
|
-
else
|
224
|
-
item = MarkdownList.new(true)
|
225
|
-
item.addRow(s)
|
226
|
-
item.parent_doc = doc
|
227
|
-
temp_md_list = item
|
228
|
-
end
|
229
|
-
|
230
|
-
elsif s[0] == '|' # check if table
|
231
|
-
|
232
|
-
if temp_md_list
|
233
|
-
doc.items.append temp_md_list
|
234
|
-
temp_md_list = nil
|
235
|
-
end
|
236
|
-
|
237
|
-
if res = /^[|](-{3,})[|]/.match(s) # check if it is a separator first
|
238
|
-
|
239
|
-
if temp_md_table
|
240
|
-
# separator is found after heading - just skip it
|
241
|
-
else
|
242
|
-
# separator out of table scope consider it just as a regular paragraph
|
243
|
-
item = Paragraph.new(s)
|
244
|
-
item.parent_doc = doc
|
245
|
-
doc.items.append(item)
|
246
|
-
end
|
247
|
-
|
248
|
-
elsif res = /^[|](.*[|])/.match(s) # check if it looks as a table
|
249
|
-
|
250
|
-
row = res[1]
|
251
|
-
|
252
|
-
if temp_md_table
|
253
|
-
# check if it is a controlled table
|
254
|
-
unless temp_md_table.addRow(row)
|
255
|
-
temp_md_table = ControlledTable.new(temp_md_table, doc)
|
256
|
-
temp_md_table.parent_doc = doc
|
257
|
-
temp_md_table.addRow(row)
|
258
|
-
end
|
259
|
-
else
|
260
|
-
# start table from heading
|
261
|
-
temp_md_table = MarkdownTable.new(row)
|
262
|
-
temp_md_table.parent_doc = doc
|
263
|
-
end
|
264
|
-
end
|
265
|
-
|
266
|
-
elsif res = /^>(.*)/.match(s) # check if blockquote
|
267
|
-
|
268
|
-
if temp_md_table
|
269
|
-
doc.items.append temp_md_table
|
270
|
-
temp_md_table = nil
|
271
|
-
end
|
272
|
-
if temp_md_list
|
273
|
-
doc.items.append temp_md_list
|
274
|
-
temp_md_list = nil
|
275
|
-
end
|
276
|
-
|
277
|
-
item = Blockquote.new(res[1])
|
278
|
-
item.parent_doc = doc
|
279
|
-
doc.items.append(item)
|
280
|
-
|
281
|
-
elsif res = /^```(\w*)/.match(s) # check if code block
|
282
|
-
|
283
|
-
if temp_md_table
|
284
|
-
doc.items.append temp_md_table
|
285
|
-
temp_md_table = nil
|
286
|
-
end
|
287
|
-
if temp_md_list
|
288
|
-
doc.items.append temp_md_list
|
289
|
-
temp_md_list = nil
|
290
|
-
end
|
291
|
-
|
292
|
-
suggested_format = ''
|
293
|
-
suggested_format = res[1] if res.length == 2
|
294
|
-
|
295
|
-
if temp_code_block
|
296
|
-
# close already opened block
|
297
|
-
doc.items.append(temp_code_block)
|
298
|
-
temp_code_block = nil
|
299
|
-
else
|
300
|
-
# start code block
|
301
|
-
temp_code_block = CodeBlock.new(suggested_format)
|
302
|
-
temp_code_block.parent_doc = doc
|
303
|
-
end
|
304
|
-
|
305
|
-
elsif res = /^TODO:(.*)/.match(s) # check if TODO block
|
306
|
-
|
307
|
-
if temp_md_table
|
308
|
-
doc.items.append temp_md_table
|
309
|
-
temp_md_table = nil
|
310
|
-
end
|
311
|
-
if temp_md_list
|
312
|
-
doc.items.append temp_md_list
|
313
|
-
temp_md_list = nil
|
314
|
-
end
|
315
|
-
|
316
|
-
text = '**TODO**: ' + res[1]
|
317
|
-
|
318
|
-
item = TodoBlock.new(text)
|
319
|
-
item.parent_doc = doc
|
320
|
-
doc.items.append(item)
|
321
|
-
doc.todo_blocks.append(item)
|
322
|
-
|
323
|
-
else # Reqular Paragraph
|
324
|
-
if temp_md_table
|
325
|
-
doc.items.append temp_md_table
|
326
|
-
temp_md_table = nil
|
327
|
-
end
|
328
|
-
if temp_md_list
|
329
|
-
if MarkdownList.unordered_list_item?(s) || MarkdownList.ordered_list_item?(s)
|
330
|
-
temp_md_list.addRow(s)
|
331
|
-
next
|
332
|
-
else
|
333
|
-
doc.items.append temp_md_list
|
334
|
-
temp_md_list = nil
|
335
|
-
end
|
336
|
-
end
|
337
|
-
if temp_code_block
|
338
|
-
temp_code_block.code_lines.append(s)
|
339
|
-
else
|
340
|
-
item = Paragraph.new(s)
|
341
|
-
item.parent_doc = doc
|
342
|
-
doc.items.append(item)
|
343
|
-
end
|
344
|
-
end
|
345
|
-
elsif temp_md_list
|
346
|
-
doc.items.append temp_md_list
|
347
|
-
temp_md_list = nil # lists are separated by emty line from each other
|
348
|
-
end
|
349
|
-
end
|
350
|
-
# Finalize non-closed elements
|
351
|
-
if temp_md_table
|
352
|
-
doc.items.append temp_md_table
|
353
|
-
temp_md_table = nil
|
354
|
-
end
|
355
|
-
if temp_md_list
|
356
|
-
doc.items.append temp_md_list
|
357
|
-
temp_md_list = nil
|
358
|
-
end
|
359
|
-
if temp_code_block
|
360
|
-
doc.items.append temp_code_block
|
361
|
-
temp_code_block = nil
|
362
|
-
end
|
363
|
-
# Add footer to close opened tables if any
|
364
|
-
item = DocFooter.new
|
365
|
-
item.parent_doc = doc
|
366
|
-
doc.items.append(item)
|
367
42
|
# Build dom
|
368
43
|
doc.dom = Document.new(doc.headings) if doc.is_a?(Specification)
|
44
|
+
|
369
45
|
end
|
370
46
|
end
|
@@ -7,7 +7,9 @@ class ControlledParagraph < Paragraph
|
|
7
7
|
attr_accessor :down_links
|
8
8
|
attr_accessor :coverage_links
|
9
9
|
|
10
|
-
def initialize(text, id)
|
10
|
+
def initialize(doc, text, id)
|
11
|
+
@parent_doc = doc
|
12
|
+
@parent_heading = doc.headings[-1]
|
11
13
|
@text = text.strip
|
12
14
|
@id = id
|
13
15
|
@up_link_ids = nil
|
@@ -129,7 +129,7 @@ class ControlledTable < DocItem
|
|
129
129
|
# save uplink key but do not rewrite
|
130
130
|
if col.up_link_doc_id != nil
|
131
131
|
|
132
|
-
@parent_doc.
|
132
|
+
@parent_doc.up_link_docs[ col.up_link_doc_id.to_s ] = col.up_link_doc_id
|
133
133
|
|
134
134
|
# save reference to the test step
|
135
135
|
new_row.up_link = col.up_link
|
@@ -8,7 +8,8 @@ class Heading < Paragraph
|
|
8
8
|
|
9
9
|
@@global_section_number = ""
|
10
10
|
|
11
|
-
def initialize(text, level)
|
11
|
+
def initialize(doc, text, level)
|
12
|
+
@parent_doc = doc
|
12
13
|
@text = text
|
13
14
|
@level = level
|
14
15
|
|
@@ -51,7 +52,11 @@ class Heading < Paragraph
|
|
51
52
|
end
|
52
53
|
|
53
54
|
def get_section_info
|
54
|
-
|
55
|
+
if level == 0 # Doc Title
|
56
|
+
s = @text
|
57
|
+
else
|
58
|
+
s = @section_number + " " + @text
|
59
|
+
end
|
55
60
|
end
|
56
61
|
|
57
62
|
def get_anchor_text()
|
@@ -76,6 +81,17 @@ class Heading < Paragraph
|
|
76
81
|
return s
|
77
82
|
end
|
78
83
|
|
84
|
+
def get_html_link
|
85
|
+
if (@parent_doc.instance_of? Specification)
|
86
|
+
heading_text = get_section_info()
|
87
|
+
s = "<a href= class=\"external\">#{heading_text}</a>"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def get_url
|
92
|
+
"./specifications/#{parent_doc.id}/#{parent_doc.id}.html\##{@anchor_id}"
|
93
|
+
end
|
94
|
+
|
79
95
|
def self.reset_global_section_number
|
80
96
|
@@global_section_number = ""
|
81
97
|
end
|
@@ -10,7 +10,10 @@ class MarkdownList < DocItem
|
|
10
10
|
|
11
11
|
@@lists_stack = Array.new
|
12
12
|
|
13
|
-
def initialize(is_ordered)
|
13
|
+
def initialize(doc, is_ordered)
|
14
|
+
@parent_doc = doc
|
15
|
+
@parent_heading = doc.headings[-1]
|
16
|
+
|
14
17
|
@rows = Array.new
|
15
18
|
@is_ordered = is_ordered
|
16
19
|
@current_nesting_level = 0
|
@@ -30,7 +33,7 @@ class MarkdownList < DocItem
|
|
30
33
|
|
31
34
|
prev_lists_stack_item = @@lists_stack[-1]
|
32
35
|
# the following line pushes new list to the lists_stack in the constructor!
|
33
|
-
nested_list = MarkdownList.new( MarkdownList.ordered_list_item?(raw_text) )
|
36
|
+
nested_list = MarkdownList.new( @parent_doc, MarkdownList.ordered_list_item?(raw_text) )
|
34
37
|
nested_list.current_nesting_level = @current_nesting_level + 1
|
35
38
|
nested_list.indent_position = pos
|
36
39
|
|