Almirah 0.1.8 → 0.2.0
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 +6 -0
- data/lib/almirah/doc_items/doc_item.rb +4 -0
- data/lib/almirah/doc_items/heading.rb +11 -0
- data/lib/almirah/doc_types/base_document.rb +21 -0
- data/lib/almirah/project.rb +54 -43
- data/lib/almirah/project_configuration.rb +42 -0
- data/lib/almirah/search/specifications_db.rb +37 -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 +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 239bc6813a8ad20ae8cf8a99d5a36968acf8679965c123ace4f981082f08813f
|
4
|
+
data.tar.gz: bfe821957ccd6adebf87f21052fe1b3cb8bdffe3761c68be8dfb9bd619fc9605
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e633985b182351caa581c6dc8e0133b78a98bd56ade57f8ab152d1bf8442e161775d4c7a161a8421c32e272edab1d9798fe5d5157ba558c6b267d5a503e25fa2
|
7
|
+
data.tar.gz: 72cfef9d334a4522b9fa3dea553ace439299a62dae4ba79dba7db5b284164f33d41280ecea602945068e01ce183ceac4591e408026400ec2bbbbc31ec3648c64
|
data/lib/almirah/doc_fabric.rb
CHANGED
@@ -188,6 +188,7 @@ class DocFabric
|
|
188
188
|
|
189
189
|
item = Image.new(img_text, img_path)
|
190
190
|
item.parent_doc = doc
|
191
|
+
item.parent_heading = doc.headings[-1]
|
191
192
|
|
192
193
|
doc.items.append(item)
|
193
194
|
|
@@ -224,6 +225,7 @@ class DocFabric
|
|
224
225
|
item = MarkdownList.new(true)
|
225
226
|
item.addRow(s)
|
226
227
|
item.parent_doc = doc
|
228
|
+
item.parent_heading = doc.headings[-1]
|
227
229
|
temp_md_list = item
|
228
230
|
end
|
229
231
|
|
@@ -242,6 +244,7 @@ class DocFabric
|
|
242
244
|
# separator out of table scope consider it just as a regular paragraph
|
243
245
|
item = Paragraph.new(s)
|
244
246
|
item.parent_doc = doc
|
247
|
+
item.parent_heading = doc.headings[-1]
|
245
248
|
doc.items.append(item)
|
246
249
|
end
|
247
250
|
|
@@ -276,6 +279,7 @@ class DocFabric
|
|
276
279
|
|
277
280
|
item = Blockquote.new(res[1])
|
278
281
|
item.parent_doc = doc
|
282
|
+
item.parent_heading = doc.headings[-1]
|
279
283
|
doc.items.append(item)
|
280
284
|
|
281
285
|
elsif res = /^```(\w*)/.match(s) # check if code block
|
@@ -317,6 +321,7 @@ class DocFabric
|
|
317
321
|
|
318
322
|
item = TodoBlock.new(text)
|
319
323
|
item.parent_doc = doc
|
324
|
+
item.parent_heading = doc.headings[-1]
|
320
325
|
doc.items.append(item)
|
321
326
|
doc.todo_blocks.append(item)
|
322
327
|
|
@@ -339,6 +344,7 @@ class DocFabric
|
|
339
344
|
else
|
340
345
|
item = Paragraph.new(s)
|
341
346
|
item.parent_doc = doc
|
347
|
+
item.parent_heading = doc.headings[-1]
|
342
348
|
doc.items.append(item)
|
343
349
|
end
|
344
350
|
end
|
@@ -76,6 +76,17 @@ class Heading < Paragraph
|
|
76
76
|
return s
|
77
77
|
end
|
78
78
|
|
79
|
+
def get_html_link
|
80
|
+
if (@parent_doc.instance_of? Specification)
|
81
|
+
heading_text = get_section_info()
|
82
|
+
s = "<a href= class=\"external\">#{heading_text}</a>"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def get_url
|
87
|
+
"./specifications/#{parent_doc.id}/#{parent_doc.id}.html\##{@anchor_id}"
|
88
|
+
end
|
89
|
+
|
79
90
|
def self.reset_global_section_number
|
80
91
|
@@global_section_number = ""
|
81
92
|
end
|
@@ -44,6 +44,27 @@ class BaseDocument
|
|
44
44
|
end
|
45
45
|
elsif s.include?('{{DOCUMENT_TITLE}}')
|
46
46
|
file.puts s.gsub! '{{DOCUMENT_TITLE}}', @title
|
47
|
+
elsif s.include?('{{STYLES_AND_SCRIPTS}}')
|
48
|
+
if @id == 'index'
|
49
|
+
file.puts '<script type="module" src="./scripts/orama_search.js"></script>'
|
50
|
+
file.puts '<link rel="stylesheet" href="./css/search.css">'
|
51
|
+
file.puts '<link rel="stylesheet" href="./css/main.css">'
|
52
|
+
file.puts '<script src="./scripts/main.js"></script>'
|
53
|
+
elsif self.instance_of? Specification
|
54
|
+
file.puts '<link rel="stylesheet" href="../../css/main.css">'
|
55
|
+
file.puts '<script src="../../scripts/main.js"></script>'
|
56
|
+
elsif self.instance_of? Traceability
|
57
|
+
file.puts '<link rel="stylesheet" href="../../css/main.css">'
|
58
|
+
file.puts '<script src="../../scripts/main.js"></script>'
|
59
|
+
elsif self.instance_of? Coverage
|
60
|
+
file.puts '<link rel="stylesheet" href="../../css/main.css">'
|
61
|
+
file.puts '<script src="../../scripts/main.js"></script>'
|
62
|
+
elsif self.instance_of? Protocol
|
63
|
+
file.puts '<link rel="stylesheet" href="../../../css/main.css">'
|
64
|
+
file.puts '<script src="../../../scripts/main.js"></script>'
|
65
|
+
end
|
66
|
+
elsif s.include?('{{GEM_VERSION}}')
|
67
|
+
file.puts "(" + Gem.loaded_specs['Almirah'].version.version + ")"
|
47
68
|
else
|
48
69
|
file.puts s
|
49
70
|
end
|
data/lib/almirah/project.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'fileutils'
|
2
|
-
require 'YAML'
|
3
2
|
require_relative "doc_fabric"
|
4
3
|
require_relative "navigation_pane"
|
5
4
|
require_relative "doc_types/traceability"
|
6
5
|
require_relative "doc_types/coverage"
|
7
6
|
require_relative "doc_types/index"
|
7
|
+
require_relative "search/specifications_db"
|
8
8
|
|
9
9
|
class Project
|
10
10
|
|
@@ -12,14 +12,13 @@ class Project
|
|
12
12
|
attr_accessor :protocols
|
13
13
|
attr_accessor :traceability_matrices
|
14
14
|
attr_accessor :coverage_matrices
|
15
|
-
attr_accessor :project_root_directory
|
16
15
|
attr_accessor :specifications_dictionary
|
17
16
|
attr_accessor :index
|
18
17
|
attr_accessor :project
|
19
|
-
attr_accessor :
|
18
|
+
attr_accessor :configuration
|
20
19
|
|
21
|
-
def initialize(
|
22
|
-
@
|
20
|
+
def initialize(configuration)
|
21
|
+
@configuration = configuration
|
23
22
|
@specifications = Array.new
|
24
23
|
@protocols = Array.new
|
25
24
|
@traceability_matrices = Array.new
|
@@ -27,19 +26,22 @@ class Project
|
|
27
26
|
@specifications_dictionary = Hash.new
|
28
27
|
@index = nil
|
29
28
|
@project = self
|
30
|
-
@
|
31
|
-
|
32
|
-
FileUtils.remove_dir(@project_root_directory + "/build", true)
|
29
|
+
FileUtils.remove_dir(@configuration.project_root_directory + "/build", true)
|
30
|
+
copy_resources
|
33
31
|
end
|
34
32
|
|
35
|
-
def
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
33
|
+
def copy_resources
|
34
|
+
# scripts
|
35
|
+
gem_root = File.expand_path './../..', File.dirname(__FILE__)
|
36
|
+
src_folder = gem_root + "/lib/almirah/templates/scripts"
|
37
|
+
dst_folder = @configuration.project_root_directory + "/build/scripts"
|
38
|
+
FileUtils.mkdir_p(dst_folder)
|
39
|
+
FileUtils.copy_entry( src_folder, dst_folder )
|
40
|
+
# css
|
41
|
+
src_folder = gem_root + "/lib/almirah/templates/css"
|
42
|
+
dst_folder = @configuration.project_root_directory + "/build/css"
|
43
|
+
FileUtils.mkdir_p(dst_folder)
|
44
|
+
FileUtils.copy_entry( src_folder, dst_folder )
|
43
45
|
end
|
44
46
|
|
45
47
|
def specifications_and_protocols
|
@@ -55,6 +57,7 @@ class Project
|
|
55
57
|
render_all_specifications(@coverage_matrices)
|
56
58
|
render_all_protocols
|
57
59
|
render_index
|
60
|
+
create_search_data
|
58
61
|
end
|
59
62
|
|
60
63
|
def specifications_and_results( test_run )
|
@@ -70,6 +73,7 @@ class Project
|
|
70
73
|
render_all_specifications(@coverage_matrices)
|
71
74
|
render_all_protocols
|
72
75
|
render_index
|
76
|
+
create_search_data
|
73
77
|
end
|
74
78
|
|
75
79
|
def transform( file_extension )
|
@@ -78,10 +82,10 @@ class Project
|
|
78
82
|
|
79
83
|
def transform_all_specifications( file_extension )
|
80
84
|
|
81
|
-
path = @project_root_directory
|
85
|
+
path = @configuration.project_root_directory
|
82
86
|
|
83
87
|
# find all specifications
|
84
|
-
Dir.glob( "#{
|
88
|
+
Dir.glob( "#{path}/specifications/**/*.md" ).each do |f|
|
85
89
|
puts f
|
86
90
|
# make a copy with another extention to preserve the content
|
87
91
|
f_directory = File.dirname(f)
|
@@ -93,12 +97,13 @@ class Project
|
|
93
97
|
end
|
94
98
|
|
95
99
|
def parse_all_specifications
|
100
|
+
path = @configuration.project_root_directory
|
96
101
|
# do a lasy pass first to get the list of documents id
|
97
|
-
Dir.glob( "#{
|
102
|
+
Dir.glob( "#{path}/specifications/**/*.md" ).each do |f|
|
98
103
|
DocFabric.add_lazy_doc_id(f)
|
99
104
|
end
|
100
105
|
# parse documents in the second pass
|
101
|
-
Dir.glob( "#{
|
106
|
+
Dir.glob( "#{path}/specifications/**/*.md" ).each do |f|
|
102
107
|
doc = DocFabric.create_specification(f)
|
103
108
|
@specifications.append(doc)
|
104
109
|
@specifications_dictionary[doc.id.to_s.downcase] = doc
|
@@ -106,7 +111,8 @@ class Project
|
|
106
111
|
end
|
107
112
|
|
108
113
|
def parse_all_protocols
|
109
|
-
|
114
|
+
path = @configuration.project_root_directory
|
115
|
+
Dir.glob( "#{path}/tests/protocols/**/*.md" ).each do |f|
|
110
116
|
puts "Prot: " + f
|
111
117
|
doc = DocFabric.create_protocol(f)
|
112
118
|
@protocols.append(doc)
|
@@ -114,7 +120,8 @@ class Project
|
|
114
120
|
end
|
115
121
|
|
116
122
|
def parse_test_run( test_run )
|
117
|
-
|
123
|
+
path = @configuration.project_root_directory
|
124
|
+
Dir.glob( "#{path}/tests/runs/#{test_run}/**/*.md" ).each do |f|
|
118
125
|
puts "Run: " + f
|
119
126
|
doc = DocFabric.create_protocol(f)
|
120
127
|
@protocols.append(doc)
|
@@ -128,14 +135,12 @@ class Project
|
|
128
135
|
# puts "Link: #{c[0].id} - #{c[1].id}"
|
129
136
|
end
|
130
137
|
# separatelly create design inputs treceability
|
131
|
-
|
132
|
-
@
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
@traceability_matrices.append trx
|
138
|
-
end
|
138
|
+
@configuration.get_design_inputs.each do |i|
|
139
|
+
if @specifications_dictionary.has_key? i.to_s.downcase
|
140
|
+
document = @specifications_dictionary[i.to_s.downcase]
|
141
|
+
if document
|
142
|
+
trx = Traceability.new document, nil, true
|
143
|
+
@traceability_matrices.append trx
|
139
144
|
end
|
140
145
|
end
|
141
146
|
end
|
@@ -253,16 +258,16 @@ class Project
|
|
253
258
|
|
254
259
|
def render_all_specifications(spec_list)
|
255
260
|
|
256
|
-
|
261
|
+
path = @configuration.project_root_directory
|
257
262
|
|
258
|
-
FileUtils.mkdir_p(
|
263
|
+
FileUtils.mkdir_p(path + "/build/specifications")
|
259
264
|
|
260
265
|
spec_list.each do |doc|
|
261
266
|
|
262
267
|
doc.to_console
|
263
268
|
|
264
|
-
img_src_dir =
|
265
|
-
img_dst_dir =
|
269
|
+
img_src_dir = path + "/specifications/" + doc.id + "/img"
|
270
|
+
img_dst_dir = path + "/build/specifications/" + doc.id + "/img"
|
266
271
|
|
267
272
|
FileUtils.mkdir_p(img_dst_dir)
|
268
273
|
|
@@ -272,7 +277,7 @@ class Project
|
|
272
277
|
|
273
278
|
# create a sidebar first
|
274
279
|
nav_pane = NavigationPane.new(doc)
|
275
|
-
doc.to_html( nav_pane, "#{
|
280
|
+
doc.to_html( nav_pane, "#{path}/build/specifications/" )
|
276
281
|
end
|
277
282
|
end
|
278
283
|
|
@@ -281,15 +286,14 @@ class Project
|
|
281
286
|
# create a sidebar first
|
282
287
|
# nav_pane = NavigationPane.new(@specifications)
|
283
288
|
|
284
|
-
|
289
|
+
path = @configuration.project_root_directory
|
285
290
|
|
286
|
-
|
287
|
-
FileUtils.mkdir_p(pass + "/build/tests/protocols")
|
291
|
+
FileUtils.mkdir_p(path + "/build/tests/protocols")
|
288
292
|
|
289
293
|
@protocols.each do |doc|
|
290
294
|
|
291
|
-
img_src_dir =
|
292
|
-
img_dst_dir =
|
295
|
+
img_src_dir = path + "/tests/protocols/" + doc.id + "/img"
|
296
|
+
img_dst_dir = path + "/build/tests/protocols/" + doc.id + "/img"
|
293
297
|
|
294
298
|
FileUtils.mkdir_p(img_dst_dir)
|
295
299
|
|
@@ -297,17 +301,24 @@ class Project
|
|
297
301
|
FileUtils.copy_entry( img_src_dir, img_dst_dir )
|
298
302
|
end
|
299
303
|
|
300
|
-
doc.to_html( nil, "#{
|
304
|
+
doc.to_html( nil, "#{path}/build/tests/protocols/" )
|
301
305
|
end
|
302
306
|
end
|
303
307
|
|
304
|
-
def render_index
|
308
|
+
def render_index
|
305
309
|
|
306
|
-
path = @project_root_directory
|
310
|
+
path = @configuration.project_root_directory
|
307
311
|
|
308
312
|
doc = @index
|
309
313
|
doc.to_console
|
310
314
|
|
311
315
|
doc.to_html("#{path}/build/")
|
312
316
|
end
|
317
|
+
|
318
|
+
def create_search_data
|
319
|
+
db = SpecificationsDb.new @specifications
|
320
|
+
data_path = @configuration.project_root_directory + "/build/data"
|
321
|
+
FileUtils.mkdir_p(data_path)
|
322
|
+
db.save(data_path)
|
323
|
+
end
|
313
324
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
class ProjectConfiguration
|
4
|
+
|
5
|
+
attr_accessor :project_root_directory
|
6
|
+
attr_accessor :parameters
|
7
|
+
|
8
|
+
def initialize(path)
|
9
|
+
@project_root_directory = path
|
10
|
+
@parameters = {}
|
11
|
+
load_project_file()
|
12
|
+
end
|
13
|
+
|
14
|
+
def load_project_file
|
15
|
+
begin
|
16
|
+
@parameters = YAML.load_file(@project_root_directory + '/project.yml')
|
17
|
+
rescue Psych::SyntaxError => e
|
18
|
+
puts "YAML syntax error: #{e.message}"
|
19
|
+
rescue Errno::ENOENT
|
20
|
+
puts "Project file not found: project.yml"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def get_design_inputs
|
25
|
+
if (@parameters.key? 'specifications') and (@parameters['specifications'].key? 'input')
|
26
|
+
return @parameters['specifications']['input']
|
27
|
+
end
|
28
|
+
return []
|
29
|
+
end
|
30
|
+
|
31
|
+
def is_spec_db_shall_be_created
|
32
|
+
if (@parameters.key? 'output')
|
33
|
+
@parameters['output'].each do |p|
|
34
|
+
if p == 'specifications_db'
|
35
|
+
return true
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
return false
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'json'
|
2
|
+
# Prepare JSON database file for further indexing by other tools
|
3
|
+
class SpecificationsDb
|
4
|
+
|
5
|
+
attr_accessor :specifications
|
6
|
+
attr_accessor :data
|
7
|
+
|
8
|
+
def initialize(spec_list)
|
9
|
+
@specifications = spec_list
|
10
|
+
@data = []
|
11
|
+
create_data
|
12
|
+
end
|
13
|
+
|
14
|
+
def create_data
|
15
|
+
@specifications.each do |sp|
|
16
|
+
sp.items.each do |i|
|
17
|
+
if (i.instance_of? Paragraph) or (i.instance_of? ControlledParagraph)
|
18
|
+
e = {"document" => i.parent_doc.title, \
|
19
|
+
"doc_color" => i.parent_doc.color, \
|
20
|
+
"text" => i.text, \
|
21
|
+
"heading_url" => i.parent_heading.get_url(), \
|
22
|
+
"heading_text" => i.parent_heading.get_section_info()
|
23
|
+
}
|
24
|
+
@data.append e
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def save(path)
|
31
|
+
json = JSON.generate(@data)
|
32
|
+
|
33
|
+
file = File.open( path + "/specifications_db.json", "w" )
|
34
|
+
file.puts json
|
35
|
+
file.close
|
36
|
+
end
|
37
|
+
end
|