Almirah 0.0.8 → 0.0.9

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1841cdb6a5d88bcbe36d8ed926fd8f659e9a630d58763ead2b78e8b7f17281dd
4
- data.tar.gz: 13b91603331fe68ff13f4b1917806551f94f11d98084ce773a1e247abb4b1abb
3
+ metadata.gz: 9e500204a8575e500989c7d86e4db4dff7a6247b14d3768904620be7a3cef356
4
+ data.tar.gz: a12d76101a33fc1938c0c42d361f84ae9a8c796684becd1567e154e67f345cad
5
5
  SHA512:
6
- metadata.gz: ed609c1862a9f33b46c2379ae8f08904c30a00767939418e28600267ccc449aa88b7bcf96efc661c1c3d39d9a720a12491c01eed4c0c30034623f342a47d5d70
7
- data.tar.gz: e5c91e4efbd5d96d915ad2228b22982391ccc91eae8afc545dc8c1fd1a8f077a690d9da988e47794df470eda560e7f6a0a99ec7a173d33660c0cc532de1c5e97
6
+ metadata.gz: eff42c3d45f0be71488484ce864740c5363e9169450d32469b9044136ea47af2989b32c4cb526c176c4d4721e60be0c5f484db8ed2245285eb042187a9c5df57
7
+ data.tar.gz: 2e5c4887b584428a71db8cbd33d244242c90df9b7b02aca8804f72f97fb017dfebc4aa8ff2ae52f924ae9895f7ac1b075cac2407ba84888db55cd36d97984344
@@ -124,7 +124,7 @@ class DocFabric
124
124
 
125
125
  doc.items.append(item)
126
126
 
127
- elsif res = /^(\*\s?)+(.*)/.match(s) #check if bullet list
127
+ elsif res = /^(\*\s?)(.*)/.match(s) #check if unordered list start
128
128
 
129
129
  if tempMdTable
130
130
  doc.items.append tempMdTable
@@ -136,7 +136,26 @@ class DocFabric
136
136
  if tempMdList
137
137
  tempMdList.addRow(row)
138
138
  else
139
- item = MarkdownList.new(row)
139
+ item = MarkdownList.new(false)
140
+ item.addRow(s)
141
+ item.parent_doc = doc
142
+ tempMdList = item
143
+ end
144
+
145
+ elsif res = /^\d[.]\s(.*)/.match(s) #check if ordered list start
146
+
147
+ if tempMdTable
148
+ doc.items.append tempMdTable
149
+ tempMdTable = nil
150
+ end
151
+
152
+ row = res[1]
153
+
154
+ if tempMdList
155
+ tempMdList.addRow(row)
156
+ else
157
+ item = MarkdownList.new(true)
158
+ item.addRow(s)
140
159
  item.parent_doc = doc
141
160
  tempMdList = item
142
161
  end
@@ -198,14 +217,24 @@ class DocFabric
198
217
  tempMdTable = nil
199
218
  end
200
219
  if tempMdList
201
- doc.items.append tempMdList
202
- tempMdList = nil
220
+ if MarkdownList.unordered_list_item?(s) || MarkdownList.ordered_list_item?(s)
221
+ tempMdList.addRow(s)
222
+ next
223
+ else
224
+ doc.items.append tempMdList
225
+ tempMdList = nil
226
+ end
203
227
  end
204
228
 
205
229
  item = Paragraph.new(s)
206
230
  item.parent_doc = doc
207
231
  doc.items.append(item)
208
232
  end
233
+ else
234
+ if tempMdList # lists are separated by emty line from each other
235
+ doc.items.append tempMdList
236
+ tempMdList = nil
237
+ end
209
238
  end
210
239
  end
211
240
  # Finalize non-closed elements
@@ -10,12 +10,13 @@ class Blockquote < DocItem
10
10
 
11
11
  def to_html
12
12
  s = ''
13
+ f_text = format_string(@text)
13
14
  if @@htmlTableRenderInProgress
14
15
  s += "</table>\n"
15
16
  @@htmlTableRenderInProgress = false
16
17
  end
17
18
 
18
- s += "<div class=\"blockquote\"><p>#{@text}</div>\n"
19
+ s += "<div class=\"blockquote\"><p>#{f_text}</div>\n"
19
20
  return s
20
21
  end
21
22
  end
@@ -22,9 +22,10 @@ class ControlledParagraph < Paragraph
22
22
  s += "\t<thead> <th>#</th> <th>Text</th> <th>UL</th> <th>DL</th> <th>COV</th> </thead>\n"
23
23
  @@htmlTableRenderInProgress = true
24
24
  end
25
+ f_text = format_string(@text)
25
26
  s += "\t<tr>\n"
26
27
  s += "\t\t<td class=\"item_id\"> <a name=\"#{@id}\" id=\"#{@id}\" href=\"##{@id}\">#{@id}</a></td>\n"
27
- s += "\t\t<td class=\"item_text\">#{@text}</td>\n"
28
+ s += "\t\t<td class=\"item_text\">#{f_text}</td>\n"
28
29
 
29
30
  if @up_link
30
31
  if tmp = /^([a-zA-Z]+)[-]\d+/.match(@up_link)
@@ -1,7 +1,7 @@
1
1
  require_relative "controlled_table_row"
2
+ require_relative "text_line"
2
3
 
3
-
4
- class ControlledTableColumn
4
+ class ControlledTableColumn < TextLine
5
5
 
6
6
  attr_accessor :text
7
7
 
@@ -10,7 +10,8 @@ class ControlledTableColumn
10
10
  end
11
11
 
12
12
  def to_html
13
- "\t\t<td>#{@text}</td>\n\r"
13
+ f_text = format_string(@text)
14
+ "\t\t<td>#{f_text}</td>\n\r"
14
15
  end
15
16
  end
16
17
 
@@ -41,12 +42,13 @@ end
41
42
  class TestStepResultColumn < ControlledTableColumn
42
43
 
43
44
  def to_html
45
+ f_text = format_string(@text)
44
46
  if @text.downcase == "pass"
45
- "\t\t<td style=\"background-color: #cfc;\">#{@text}</td>\n\r"
47
+ "\t\t<td style=\"background-color: #cfc;\">#{f_text}</td>\n\r"
46
48
  elsif @text.downcase == "fail"
47
- "\t\t<td style=\"background-color: #fcc;\">#{@text}</td>\n\r"
49
+ "\t\t<td style=\"background-color: #fcc;\">#{f_text}</td>\n\r"
48
50
  else
49
- "\t\t<td>#{@text}</td>\n\r"
51
+ "\t\t<td>#{f_text}</td>\n\r"
50
52
  end
51
53
  end
52
54
  end
@@ -1,4 +1,6 @@
1
- class DocItem
1
+ require_relative "text_line"
2
+
3
+ class DocItem < TextLine
2
4
  attr_accessor :parent_doc
3
5
 
4
6
  @parent_doc = nil
@@ -8,7 +8,7 @@ class Heading < Paragraph
8
8
  def initialize(text, level)
9
9
  @text = text
10
10
  @level = level
11
- @anchor_id = self.getTextWithoutSpaces()
11
+ @anchor_id = getTextWithoutSpaces()
12
12
  end
13
13
 
14
14
  def to_html
@@ -3,14 +3,107 @@ require_relative "doc_item"
3
3
  class MarkdownList < DocItem
4
4
 
5
5
  attr_accessor :rows
6
+ attr_accessor :text
7
+ attr_accessor :is_ordered
8
+ attr_accessor :indent_position
9
+ attr_accessor :current_nesting_level
6
10
 
7
- def initialize(first_row)
11
+ @@lists_stack = Array.new
12
+
13
+ def initialize(is_ordered)
8
14
  @rows = Array.new
9
- @rows.append(first_row)
15
+ @is_ordered = is_ordered
16
+ @current_nesting_level = 0
17
+ @indent_position = 0
18
+ @text = ''
19
+
20
+ @@lists_stack.push(self)
21
+ end
22
+
23
+ def addRow(raw_text)
24
+ puts raw_text
25
+ pos = calculate_text_position(raw_text)
26
+ row = raw_text[pos..-1]
27
+
28
+ pos = calculate_indent_position(raw_text)
29
+
30
+ if pos > @@lists_stack[-1].indent_position
31
+
32
+ prev_lists_stack_item = @@lists_stack[-1]
33
+ # the following line pushes new list to the lists_stack in the constructor!
34
+ nested_list = MarkdownList.new( MarkdownList.ordered_list_item?(raw_text) )
35
+ nested_list.current_nesting_level = @current_nesting_level + 1
36
+ nested_list.indent_position = pos
37
+
38
+ prev_row = prev_lists_stack_item.rows[-1]
39
+ if prev_row.is_a?(MarkdownList)
40
+ #cannot be there
41
+ else
42
+ nested_list.text = prev_row
43
+ puts "Length: " + prev_lists_stack_item.rows.length.to_s
44
+ prev_lists_stack_item.rows[-1] = nested_list
45
+ end
46
+
47
+ nested_list.addRow(raw_text)
48
+
49
+ elsif pos < @@lists_stack[-1].indent_position
50
+
51
+ @@lists_stack.pop
52
+ @@lists_stack[-1].rows.append(row)
53
+
54
+ else
55
+ @@lists_stack[-1].rows.append(row)
56
+
57
+ end
58
+ end
59
+
60
+ def calculate_indent_position(s)
61
+ pos = 0
62
+ s.each_char do |c|
63
+ if non_blank?(c)
64
+ break
65
+ end
66
+ pos += 1
67
+ end
68
+ return pos
69
+ end
70
+ def calculate_text_position(s)
71
+ pos = 0
72
+ s.each_char do |c|
73
+ if letter?(c)
74
+ break
75
+ end
76
+ pos += 1
77
+ end
78
+ return pos
79
+ end
80
+
81
+ def letter?(c)
82
+ c.match?(/[[:alpha:]]/)
83
+ end
84
+
85
+ def numeric?(c)
86
+ c.match?(/[[:digit:]]/)
10
87
  end
11
88
 
12
- def addRow(row)
13
- @rows.append(row)
89
+ def non_blank?(c)
90
+ c.match?(/[[:graph:]]/)
91
+ end
92
+
93
+ def self.unordered_list_item?(raw_text)
94
+
95
+ if res = /(\*\s?)(.*)/.match(raw_text)
96
+ return true
97
+ end
98
+ return false
99
+ end
100
+
101
+ def self.ordered_list_item?(raw_text)
102
+
103
+ if res = /\d[.]\s(.*)/.match(raw_text)
104
+ return true
105
+ end
106
+ return false
14
107
  end
15
108
 
16
109
  def to_html
@@ -20,11 +113,29 @@ class MarkdownList < DocItem
20
113
  @@htmlTableRenderInProgress = false
21
114
  end
22
115
 
23
- s += "<ul>\n"
116
+ if @is_ordered
117
+ s += "<ol>\n"
118
+ else
119
+ s += "<ul>\n"
120
+ end
121
+
24
122
  @rows.each do |r|
25
- s += "\t<li>#{r}</li>\n"
123
+ if r.is_a?(MarkdownList)
124
+ f_text = format_string(r.text)
125
+ s += "\t<li>#{f_text}\n"
126
+ s += r.to_html()
127
+ s += "</li>\n"
128
+ else
129
+ f_text = format_string(r)
130
+ s += "\t<li>#{f_text}</li>\n"
131
+ end
26
132
  end
27
- s += "</ul>\n"
133
+
134
+ if @is_ordered
135
+ s += "</ol>\n"
136
+ else
137
+ s += "</ul>\n"
138
+ end
28
139
 
29
140
  return s
30
141
  end
@@ -44,7 +44,8 @@ class MarkdownTable < DocItem
44
44
  if col.to_i > 0 && col.to_i.to_s == col # autoalign cells with numbers
45
45
  s += "\t\t<td style=\"text-align: center;\">#{col}</td>\n"
46
46
  else
47
- s += "\t\t<td>#{col}</td>\n"
47
+ f_text = format_string(col)
48
+ s += "\t\t<td>#{f_text}</td>\n"
48
49
  end
49
50
  end
50
51
  s += "\t</tr>\n"
@@ -9,7 +9,7 @@ class Paragraph < DocItem
9
9
  end
10
10
 
11
11
  def getTextWithoutSpaces
12
- return @text.split.join('-')
12
+ return @text.split.join('-').downcase
13
13
  end
14
14
 
15
15
  def to_html
@@ -19,7 +19,7 @@ class Paragraph < DocItem
19
19
  @@htmlTableRenderInProgress = false
20
20
  end
21
21
 
22
- s += "<p>#{@text}"
22
+ s += "<p>" + format_string(@text)
23
23
  return s
24
24
  end
25
25
  end
@@ -0,0 +1,169 @@
1
+ class TextLine
2
+
3
+ def format_string(str)
4
+ state = 'default'
5
+ prev_state = 'default'
6
+ result = ''
7
+ stack = ''
8
+ prev_c = ''
9
+ link_text = ''
10
+ link_url = ''
11
+ str.each_char do |c|
12
+ if c == '*'
13
+ if state == 'default'
14
+ prev_state = state
15
+ state = 'first_asterisk_detected'
16
+
17
+ elsif state == 'first_asterisk_detected'
18
+ prev_state = state
19
+ state = 'second_asterisk_detected'
20
+
21
+ elsif state == 'second_asterisk_detected'
22
+ prev_state = state
23
+ state = 'third_asterisk_detected'
24
+
25
+ elsif state == 'second_asterisk_detected'
26
+ prev_state = state
27
+ state = 'third_asterisk_detected'
28
+
29
+ elsif state == 'italic_started'
30
+ prev_state = state
31
+ state = 'default'
32
+ result += italic(stack)
33
+
34
+ elsif state == 'bold_started'
35
+ prev_state = state
36
+ state = 'first_asterisk_after_bold_detected'
37
+
38
+ elsif state == 'first_asterisk_after_bold_detected'
39
+ prev_state = state
40
+ state = 'default'
41
+ result += bold(stack)
42
+
43
+ elsif state == 'bold_and_italic_started'
44
+ prev_state = state
45
+ state = 'first_asterisk_after_bold_and_italic_detected'
46
+
47
+ elsif state == 'first_asterisk_after_bold_and_italic_detected'
48
+ prev_state = state
49
+ state = 'second_asterisk_after_bold_and_italic_detected'
50
+
51
+ elsif state == 'second_asterisk_after_bold_and_italic_detected'
52
+ prev_state = state
53
+ state = 'default'
54
+ result += bold_and_italic(stack)
55
+
56
+ else
57
+ end
58
+ elsif c == '['
59
+ if state == 'default'
60
+ prev_state = state
61
+ state = 'square_bracket_left_detected'
62
+ else
63
+ end
64
+ elsif c == ']'
65
+ if state == 'square_bracket_left_detected'
66
+ prev_state = state
67
+ state = 'default'
68
+ result += '[]'
69
+
70
+ elsif state == 'link_text_started'
71
+ prev_state = state
72
+ state = 'square_bracket_right_detected'
73
+ link_text = stack
74
+
75
+ else
76
+ end
77
+ elsif c == '('
78
+ if state == 'square_bracket_right_detected'
79
+ prev_state = state
80
+ state = 'brace_left_detected'
81
+ else
82
+ end
83
+ elsif c == ')'
84
+ if state == 'brace_left_detected'
85
+ prev_state = state
86
+ state = 'default'
87
+ result += '()'
88
+
89
+ elsif state == 'link_url_started'
90
+ prev_state = state
91
+ state = 'default'
92
+ link_url = stack
93
+ result += link(link_text, link_url)
94
+
95
+ else
96
+ end
97
+ else
98
+ if state == 'default'
99
+ result += c
100
+ else
101
+ if state == 'first_asterisk_detected'
102
+ prev_state = state
103
+ state = 'italic_started'
104
+ stack = ''
105
+
106
+ elsif state == 'second_asterisk_detected'
107
+ prev_state = state
108
+ state = 'bold_started'
109
+ stack = ''
110
+
111
+ elsif state == 'third_asterisk_detected'
112
+ prev_state = state
113
+ state = 'bold_and_italic_started'
114
+ stack = ''
115
+
116
+ elsif state == 'first_asterisk_after_bold_detected'
117
+ prev_state = state
118
+ state = 'bold_started'
119
+
120
+ elsif state == 'first_asterisk_after_bold_and_italic_detected'
121
+ prev_state = state
122
+ state = 'bold_and_italic_started'
123
+
124
+ elsif state == 'second_asterisk_after_bold_and_italic_detected'
125
+ prev_state = state
126
+ state = 'bold_and_italic_started'
127
+
128
+ elsif state == 'square_bracket_left_detected'
129
+ prev_state = state
130
+ state = 'link_text_started'
131
+ stack = ''
132
+
133
+ elsif state == 'square_bracket_right_detected'
134
+ prev_state = state
135
+ state = 'default'
136
+ result += stack + c
137
+ c = ''
138
+
139
+ elsif state == 'brace_left_detected'
140
+ prev_state = state
141
+ state = 'link_url_started'
142
+ stack = ''
143
+
144
+ else
145
+ end
146
+ stack += c
147
+ end
148
+ end
149
+ prev_c = c
150
+ end
151
+ return result
152
+ end
153
+
154
+ def italic(str)
155
+ "<i>#{str}</i>"
156
+ end
157
+
158
+ def bold(str)
159
+ "<b>#{str}</b>"
160
+ end
161
+
162
+ def bold_and_italic(str)
163
+ "<b><i>#{str}</i></b>"
164
+ end
165
+
166
+ def link(link_text, link_url)
167
+ "<a href=\"#{link_url}\" class=\"external\">#{link_text}</a>"
168
+ end
169
+ end
@@ -67,6 +67,7 @@ class Specification < BaseDocument
67
67
 
68
68
  @items.each do |item|
69
69
  a = item.to_html
70
+ a = adjust_internal_links(a, nav_pane.specifications)
70
71
  html_rows.append a
71
72
  end
72
73
 
@@ -74,4 +75,29 @@ class Specification < BaseDocument
74
75
 
75
76
  end
76
77
 
78
+ def adjust_internal_links(line, specifications)
79
+ # check if there are internal links to md files and replace them
80
+ if tmp = /<a\shref="(.*)"\sclass="external">.*<\/a>/.match(line)
81
+ if res = /(\w*)[.]md/.match(tmp[1])
82
+ id = res[1].downcase
83
+ res = /(\w*)[.]md(#.*)/.match(tmp[1])
84
+
85
+ specifications.each do |spec|
86
+ if spec.id.downcase == id
87
+ if res && res.length > 2
88
+ anchor = res[2]
89
+ line.sub!(/<a\shref="(.*)"\sclass="external">/,
90
+ "<a href=\".\\..\\#{id}\\#{id}.html#{anchor}\" class=\"external\">")
91
+ else
92
+ line.sub!(/<a\shref="(.*)"\sclass="external">/,
93
+ "<a href=\".\\..\\#{id}\\#{id}.html\" class=\"external\">")
94
+ end
95
+ break
96
+ end
97
+ end
98
+ end
99
+ end
100
+ return line
101
+ end
102
+
77
103
  end
@@ -1,3 +1,4 @@
1
+ require 'fileutils'
1
2
  require_relative "doc_fabric"
2
3
  require_relative "navigation_pane"
3
4
  require_relative "doc_types/traceability"
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: Almirah
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oleksandr Ivanov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-02-17 00:00:00.000000000 Z
11
+ date: 2024-03-03 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: The software part of the Almirah system
13
+ description: The software part of the Almirah framework
14
14
  email: oleksandr.ivanov.development@gmail.com
15
15
  executables:
16
16
  - almirah
@@ -30,6 +30,7 @@ files:
30
30
  - lib/almirah/doc_items/markdown_list.rb
31
31
  - lib/almirah/doc_items/markdown_table.rb
32
32
  - lib/almirah/doc_items/paragraph.rb
33
+ - lib/almirah/doc_items/text_line.rb
33
34
  - lib/almirah/doc_types/base_document.rb
34
35
  - lib/almirah/doc_types/coverage.rb
35
36
  - lib/almirah/doc_types/protocol.rb
@@ -57,7 +58,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
57
58
  - !ruby/object:Gem::Version
58
59
  version: '0'
59
60
  requirements: []
60
- rubygems_version: 3.1.6
61
+ rubygems_version: 3.5.6
61
62
  signing_key:
62
63
  specification_version: 4
63
64
  summary: Almirah