coradoc 1.1.3 → 1.1.4

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: 4f515fbc05baa87f58f84a59737c9818603c6e9f0fc8835cdeb9bd6be9eb39e4
4
- data.tar.gz: ce51ff395a3dfb4bf77c37f6b54fe745a14a7262911df50479088d43392d4927
3
+ metadata.gz: e528645f0bdb38f707239ed1862dc74944dc7eba4149cf9f1243458e98591edb
4
+ data.tar.gz: 268acd80823a507d3a86e83bfeaef55a8145819822aac9903f0bc96cee29d55c
5
5
  SHA512:
6
- metadata.gz: 3269512745aea59b9780e5df2d872af7c3f19851666868335bc4876a534e50c64df410c5257a335324e9a9e0ad573dacf00058752ee00fd4b830f2f150cadeb2
7
- data.tar.gz: 00e4122ec5e234e8e7e54d3e5769e03df15ad0f9851059576dadde7de58c0e2dd87f3c18ab14283574347bda6c95536cf31ee3ce6c202ea8b4c3f0da96f3f399
6
+ metadata.gz: 624f718300d0877f0d610a3fbf953b324d5bfd6a73c68de30db69ddc75b45e1b396eeb5bdfdcfc7d0ecac2d50c8301d7011f118a2d23d4ac02d11c2e54e92e6a
7
+ data.tar.gz: 849b5851b2ca0b37313d8f7c743defbc168f698284c694c0a467536dbffd9cc10f5ec263fd2c28e1f287a926c6acbe3756c8753f6f3ae303dc61fc9678981ff1
@@ -61,12 +61,13 @@ module Coradoc
61
61
 
62
62
  def type_hash
63
63
  @type_hash ||= {
64
- "____" => :quote,
65
- "****" => :side,
66
- "----" => :source,
67
64
  "====" => :example,
68
65
  "...." => :literal,
66
+ "--" => :open,
69
67
  "++++" => :pass,
68
+ "____" => :quote,
69
+ "****" => :side,
70
+ "----" => :source,
70
71
  }
71
72
  end
72
73
  end
@@ -15,7 +15,7 @@ module Coradoc
15
15
  end
16
16
 
17
17
  def to_adoc
18
- "\n\n#{gen_anchor}#{gen_title}#{gen_delimiter}\n" << gen_lines << "\n#{gen_delimiter}\n\n"
18
+ "\n\n#{gen_anchor}#{gen_title}#{gen_attributes}#{gen_delimiter}\n" << gen_lines << "\n#{gen_delimiter}\n\n"
19
19
  end
20
20
  end
21
21
  end
@@ -0,0 +1,21 @@
1
+ module Coradoc
2
+ module Element
3
+ module Block
4
+ class Listing < Core
5
+ def initialize(_title, options = {})
6
+ @id = options.fetch(:id, nil)
7
+ @anchor = @id.nil? ? nil : Inline::Anchor.new(@id)
8
+ @lang = options.fetch(:lang, "")
9
+ @attributes = options.fetch(:attributes, AttributeList.new)
10
+ @lines = options.fetch(:lines, [])
11
+ @delimiter_char = "-"
12
+ @delimiter_len = options.fetch(:delimiter_len, 4)
13
+ end
14
+
15
+ def to_adoc
16
+ "\n\n#{gen_anchor}#{gen_attributes}\n#{gen_delimiter}\n" << gen_lines << "\n#{gen_delimiter}\n\n"
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -2,16 +2,18 @@ module Coradoc
2
2
  module Element
3
3
  module Block
4
4
  class Literal < Core
5
- def initialize(_title, options = {})
5
+ def initialize(title, options = {})
6
+ @title = title
6
7
  @id = options.fetch(:id, nil)
7
8
  @anchor = @id.nil? ? nil : Inline::Anchor.new(@id)
9
+ @attributes = options.fetch(:attributes, AttributeList.new)
8
10
  @lines = options.fetch(:lines, [])
9
11
  @delimiter_char = "."
10
12
  @delimiter_len = options.fetch(:delimiter_len, 4)
11
13
  end
12
14
 
13
15
  def to_adoc
14
- "\n\n#{gen_anchor}#{gen_delimiter}\n" << gen_lines << "\n#{gen_delimiter}\n\n"
16
+ "\n\n#{gen_anchor}#{gen_title}#{gen_attributes}#{gen_delimiter}\n" << gen_lines << "\n#{gen_delimiter}\n\n"
15
17
  end
16
18
  end
17
19
  end
@@ -0,0 +1,22 @@
1
+ module Coradoc
2
+ module Element
3
+ module Block
4
+ class Open < Core
5
+ def initialize(title, options = {})
6
+ @title = title
7
+ @id = options.fetch(:id, nil)
8
+ @anchor = @id.nil? ? nil : Inline::Anchor.new(@id)
9
+ @lang = options.fetch(:lang, "")
10
+ @attributes = options.fetch(:attributes, AttributeList.new)
11
+ @lines = options.fetch(:lines, [])
12
+ @delimiter_char = "-"
13
+ @delimiter_len = options.fetch(:delimiter_len, 2)
14
+ end
15
+
16
+ def to_adoc
17
+ "\n\n#{gen_anchor}#{gen_attributes}#{gen_delimiter}\n" << gen_lines << "\n#{gen_delimiter}\n\n"
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -8,8 +8,10 @@ end
8
8
  require_relative "block/core"
9
9
  require_relative "block/example"
10
10
  require_relative "block/literal"
11
- require_relative "block/quote"
11
+ require_relative "block/listing"
12
+ require_relative "block/open"
12
13
  require_relative "block/pass"
14
+ require_relative "block/quote"
13
15
  require_relative "block/side"
14
16
  require_relative "block/sourcecode"
15
17
  require_relative "block/reviewer_comment"
@@ -19,8 +19,8 @@ module Coradoc
19
19
  m = @items.select do |i|
20
20
  i.is_a?(Coradoc::Element::ListItem) &&
21
21
  !i.marker.nil?
22
- end.first&.marker
23
- @ol_count = m.size if m.is_a?(String)
22
+ end.first&.marker.to_s
23
+ @ol_count = m.size
24
24
  end
25
25
  @ol_count = 1 if @ol_count.nil?
26
26
  @attrs = options.fetch(:attrs, AttributeList.new)
@@ -7,6 +7,7 @@ module Coradoc
7
7
  end
8
8
 
9
9
  def prefix
10
+ return @marker if @marker
10
11
  "." * [@ol_count, 1].max
11
12
  end
12
13
  end
@@ -7,6 +7,7 @@ module Coradoc
7
7
  end
8
8
 
9
9
  def prefix
10
+ return @marker if @marker
10
11
  "*" * [@ol_count, 1].max
11
12
  end
12
13
  end
@@ -1,7 +1,7 @@
1
1
  module Coradoc
2
2
  module Element
3
3
  class ListItem < Base
4
- attr_accessor :marker, :id, :anchor, :content, :line_break
4
+ attr_accessor :marker, :id, :anchor, :content, :subitem, :line_break
5
5
 
6
6
  declare_children :content, :id, :anchor
7
7
 
@@ -10,11 +10,14 @@ module Coradoc
10
10
  @id = options.fetch(:id, nil)
11
11
  @anchor = @id.nil? ? nil : Inline::Anchor.new(@id)
12
12
  @content = content
13
+ @attached = options.fetch(:attached, [])
14
+ @nested = options.fetch(:nested, nil)
13
15
  @line_break = options.fetch(:line_break, "\n")
14
16
  end
15
17
 
16
18
  def to_adoc
17
- anchor = @anchor.nil? ? "" : @anchor.to_adoc.to_s
19
+ anchor = @anchor.nil? ? "" : " #{@anchor.to_adoc.to_s} "
20
+ # text = Coradoc::Generator.gen_adoc(@content)
18
21
  content = Array(@content).map do |subitem|
19
22
  next if subitem.is_a? Inline::HardLineBreak
20
23
 
@@ -24,10 +27,15 @@ module Coradoc
24
27
  if Coradoc.a_single?(subitem, Coradoc::Element::TextElement)
25
28
  subcontent = Coradoc.strip_unicode(subcontent)
26
29
  end
27
- subcontent.chomp
30
+ subcontent
28
31
  end.compact.join("\n+\n")
29
-
30
- " #{anchor}#{content.chomp}#{@line_break}"
32
+ # attach = Coradoc::Generator.gen_adoc(@attached)
33
+ attach = @attached.map do |elem|
34
+ "+\n" + Coradoc::Generator.gen_adoc(elem)
35
+ end.join
36
+ nest = Coradoc::Generator.gen_adoc(@nested)
37
+ out = " #{anchor}#{content}#{@line_break}"
38
+ out + attach + nest
31
39
  end
32
40
  end
33
41
  end
@@ -20,7 +20,7 @@ module Coradoc
20
20
  str += "(#{@id})" if @id
21
21
  str += ": "
22
22
  str += @content.inspect
23
- str += " + #{@line_break.inspect}" unless line_break.empty?
23
+ str += " + #{@line_break.inspect}" unless line_break.to_s.empty?
24
24
  str
25
25
  end
26
26
 
@@ -114,6 +114,12 @@ module Coradoc::Input::HTML
114
114
  columns = row.xpath("./td | ./th")
115
115
  column_id = 0
116
116
 
117
+ cell_references[i] ||= []
118
+ cell_matrix[i] ||= []
119
+
120
+ # Empty row support: pass row object via an instance variable
121
+ cell_references[i].instance_variable_set(:@row_obj, row)
122
+
117
123
  columns.each do |cell|
118
124
  colspan = cell["colspan"]&.to_i || 1
119
125
  rowspan = cell["rowspan"]&.to_i || 1
@@ -179,7 +185,7 @@ module Coradoc::Input::HTML
179
185
  min_rows.each do |row|
180
186
  break if row.length != cpr_min
181
187
 
182
- row_obj = row.last.first.parent
188
+ row_obj = row.last&.first&.parent || row.instance_variable_get(:@row_obj)
183
189
  doc = row_obj.document
184
190
  added_node = Nokogiri::XML::Node.new("td", doc)
185
191
  added_node["x-added"] = "x-added"
@@ -11,8 +11,13 @@ module Coradoc
11
11
  match('[^\],]').repeat(1)
12
12
  end
13
13
 
14
+ def named_key
15
+ (str('reviewer') |
16
+ match('[a-zA-Z0-9_-]').repeat(1)).as(:named_key)
17
+ end
18
+
14
19
  def named_attribute
15
- (match('[a-zA-Z0-9_-]').repeat(1).as(:named_key) >>
20
+ ( named_key >>
16
21
  str(' ').maybe >> str("=") >> str(' ').maybe >>
17
22
  match['a-zA-Z0-9_\- \"'].repeat(1).as(:named_value) >>
18
23
  str(' ').maybe
@@ -51,6 +56,7 @@ module Coradoc
51
56
  end
52
57
 
53
58
  def attribute_list(name = :attribute_list)
59
+ str('[').present? >>
54
60
  str('[') >> str("[").absent? >>
55
61
  ( named_many |
56
62
  positional_one_named_many |
@@ -1,3 +1,7 @@
1
+ require "parslet"
2
+ require "parslet/convenience"
3
+
4
+
1
5
  require_relative "admonition"
2
6
  require_relative "attribute_list"
3
7
  require_relative "bibliography"
@@ -12,11 +16,12 @@ require_relative "paragraph"
12
16
  require_relative "section"
13
17
  require_relative "table"
14
18
  require_relative "term"
19
+ require_relative "text"
15
20
 
16
21
  module Coradoc
17
22
  module Parser
18
23
  module Asciidoc
19
- module Base
24
+ class Base < Parslet::Parser
20
25
  include Coradoc::Parser::Asciidoc::Admonition
21
26
  include Coradoc::Parser::Asciidoc::AttributeList
22
27
  include Coradoc::Parser::Asciidoc::Bibliography
@@ -31,141 +36,54 @@ module Coradoc
31
36
  include Coradoc::Parser::Asciidoc::Section
32
37
  include Coradoc::Parser::Asciidoc::Table
33
38
  include Coradoc::Parser::Asciidoc::Term
34
-
35
- def space?
36
- space.maybe
37
- end
38
-
39
- def space
40
- str(' ').repeat(1)
41
- end
42
-
43
- def text
44
- match("[^\n]").repeat(1)
45
- end
46
-
47
- def line_ending
48
- str("\n")
49
- end
50
-
51
- def endline
52
- newline | any.absent?
53
- end
54
-
55
- def newline
56
- (str("\n") | str("\r\n")).repeat(1)
57
- end
58
-
59
- def newline_single
60
- (str("\n") | str("\r\n"))
61
- end
62
-
63
- def keyword
64
- (match('[a-zA-Z0-9_\-.,]') | str(".")).repeat(1)
65
- end
66
-
67
- def empty_line
68
- match("^\n")
69
- end
70
-
71
- def digit
72
- match("[0-9]")
73
- end
74
-
75
- def digits
76
- match("[0-9]").repeat(1)
77
- end
78
-
79
- def word
80
- match("[a-zA-Z0-9_-]").repeat(1)
81
- end
82
-
83
- def words
84
- word >> (space? >> word).repeat
85
- end
86
-
87
- def rich_texts
88
- rich_text >> (space? >> rich_text).repeat
89
- end
90
-
91
- def rich_text
92
- (match("[a-zA-Z0-9_-]") | str(".") | str("*") | match("@")).repeat(1)
93
- end
94
-
95
- def email
96
- word >> str("@") >> word >> str(".") >> word
97
- end
98
-
99
- def special_character
100
- match("^[*:=-]") | str("[#") | str("[[")
101
- end
102
-
103
- def date
104
- digit.repeat(2, 4) >> str("-") >>
105
- digit.repeat(1, 2) >> str("-") >> digit.repeat(1, 2)
106
- end
107
-
108
- def attr_name
109
- match("[^\t\s]").repeat(1)
39
+ include Coradoc::Parser::Asciidoc::Text
40
+
41
+ def rule_dispatch(rule_name, *args, **kwargs)
42
+ @dispatch_data = {} unless @dispatch_data
43
+ dispatch_key = [rule_name, args, kwargs.to_a.sort]
44
+ dispatch_hash = dispatch_key.hash.abs
45
+ unless @dispatch_data.has_key?(dispatch_hash)
46
+ alias_name = "#{rule_name}_#{dispatch_hash}".to_sym
47
+ Coradoc::Parser::Asciidoc::Base.class_exec do
48
+ rule(alias_name) do
49
+ send(rule_name, *args, **kwargs)
50
+ end
51
+ end
52
+ @dispatch_data[dispatch_hash] = alias_name
53
+ end
54
+ dispatch_method = @dispatch_data[dispatch_hash]
55
+ send(dispatch_method)
56
+ end
57
+
58
+ add_dispatch = true
59
+ with_params = true
60
+
61
+ parser_methods = (Coradoc::Parser::Asciidoc.constants - [:Base]).map{ |const|
62
+ Coradoc::Parser::Asciidoc.const_get(const).instance_methods
63
+ }.flatten.uniq
64
+
65
+ parser_methods.each do |rule_name|
66
+ params = Coradoc::Parser::Asciidoc::Base.instance_method(rule_name).parameters
67
+ if add_dispatch && params == []
68
+ alias_name = "alias_nondispatch_#{rule_name}".to_sym
69
+ Coradoc::Parser::Asciidoc::Base.class_exec do
70
+ alias_method alias_name, rule_name
71
+ rule(rule_name) do
72
+ send(alias_name)
73
+ end
74
+ end
75
+ elsif add_dispatch && with_params
76
+ alias_name = "alias_dispatch_#{rule_name}".to_sym
77
+ Coradoc::Parser::Asciidoc::Base.class_exec do
78
+ alias_method alias_name, rule_name
79
+ define_method(rule_name) do |*args, **kwargs|
80
+ rule_dispatch(alias_name, *args, **kwargs)
81
+ end
82
+
83
+ end
84
+ end
110
85
  end
111
86
 
112
- def file_path
113
- match('[^\[]').repeat(1)
114
- end
115
-
116
- def include_directive
117
- (str("include::") >>
118
- file_path.as(:path) >>
119
- attribute_list >>
120
- (newline | str("")).as(:line_break)
121
- ).as(:include)
122
- end
123
-
124
- def inline_image
125
- (str("image::") >>
126
- file_path.as(:path) >>
127
- attribute_list >>
128
- (line_ending)
129
- ).as(:inline_image)
130
- end
131
-
132
- def block_image
133
- (block_id.maybe >>
134
- block_title.maybe >>
135
- (attribute_list >> newline).maybe >>
136
- match('^i') >> str("mage::") >>
137
- file_path.as(:path) >>
138
- attribute_list(:attribute_list_macro) >>
139
- newline.as(:line_break)
140
- ).as(:block_image)
141
- end
142
-
143
- def comment_line
144
- tag.absent? >>
145
- (str('//') >> str("/").absent? >>
146
- space? >>
147
- text.as(:comment_text)
148
- ).as(:comment_line)
149
- end
150
-
151
- def tag
152
- (str('//') >> str('/').absent? >>
153
- space? >>
154
- (str('tag') | str('end')).as(:prefix) >>
155
- str('::') >> str(':').absent? >>
156
- match('[^\[]').repeat(1).as(:name) >>
157
- attribute_list >>
158
- line_ending.maybe.as(:line_break)
159
- ).as(:tag)
160
- end
161
-
162
- def comment_block
163
- ( str('////') >> line_ending >>
164
- ((line_ending >> str('////')).absent? >> any
165
- ).repeat.as(:comment_text) >>
166
- line_ending >> str('////')
167
- ).as(:comment_block)
168
- end
169
87
  end
170
88
  end
171
89
  end
@@ -3,77 +3,90 @@ module Coradoc
3
3
  module Asciidoc
4
4
  module Block
5
5
 
6
- def block
7
- sidebar_block |
8
- example_block |
9
- source_block |
10
- quote_block |
11
- pass_block
6
+ def block(n_deep = 3)
7
+ (example_block(n_deep) |
8
+ sidebar_block(n_deep) |
9
+ source_block(n_deep) |
10
+ quote_block(n_deep) |
11
+ pass_block(n_deep)).as(:block)
12
12
  end
13
13
 
14
- def source_block
15
- block_style("-", 2)
14
+ def example_block(n_deep)
15
+ block_style(n_deep, "=")
16
16
  end
17
17
 
18
- def pass_block
19
- block_style("+", 4, :pass)
18
+ def pass_block(n_deep)
19
+ block_style(n_deep, "+", 4, :pass)
20
20
  end
21
21
 
22
- def source_block
23
- block_style("-", 2)
22
+ def quote_block(n_deep)
23
+ block_style(n_deep, "_")
24
24
  end
25
25
 
26
- def quote_block
27
- block_style("_")
26
+ def sidebar_block(n_deep)
27
+ block_style(n_deep, "*")
28
28
  end
29
29
 
30
- def block_content(n_deep = 2)
31
- c = block_image |
32
- list |
33
- text_line |
34
- empty_line.as(:line_break)
35
- c = c | block_content(n_deep - 1) if (n_deep > 0)
36
- c.repeat(1)
37
- end
38
-
39
- def sidebar_block
40
- block_style("*")
41
- end
42
-
43
- def example_block
44
- block_style("=")
30
+ def source_block(n_deep)
31
+ block_style(n_deep, "-", 2)
45
32
  end
46
33
 
47
34
  def block_title
48
- match('^\\.') >> space.absent? >> text.as(:title) >> newline
35
+ str('.') >> space.absent? >> text.as(:title) >> newline
49
36
  end
50
37
 
51
38
  def block_type(type)
52
- (match('^\[') >> str("[").absent? >>
39
+ (str("[") >> str("[").absent? >>
53
40
  str(type).as(:type) >>
54
41
  str("]")) |
55
42
  (match('^\[') >> keyword.as(:type) >> str("]")) >> newline
56
43
  end
57
44
 
58
45
  def block_id
59
- (match('^\[') >> str("[") >> str('[').absent? >> keyword.as(:id) >> str("]]") |
46
+ line_start? >>
47
+ (str("[[") >> str('[').absent? >> keyword.as(:id) >> str("]]") |
60
48
  str("[#") >> keyword.as(:id) >> str("]")) >> newline
61
49
  end
62
50
 
63
- def block_style(delimiter = "*", repeater = 4, type = nil)
51
+ def block_content(n_deep = 3)
52
+ c = block_image |
53
+ list |
54
+ text_line |
55
+ empty_line.as(:line_break)
56
+ c = c | block(n_deep - 1) if (n_deep > 0)
57
+ c.repeat(1)
58
+ end
59
+
60
+ def block_delimiter
61
+ line_start? >>
62
+ ((str("*") |
63
+ str("=") |
64
+ str("_") |
65
+ str("+") |
66
+ str("-")).repeat(4) |
67
+ str("-").repeat(2,2)) >>
68
+ newline
69
+ end
70
+
71
+ def block_style(n_deep = 3, delimiter = "*", repeater = 4, type = nil)
72
+ block_title.maybe >>
64
73
  block_id.maybe >>
74
+ (attribute_list >> newline ).maybe >>
65
75
  block_title.maybe >>
66
76
  newline.maybe >>
67
- (attribute_list >> newline ).maybe >>
77
+ (line_start? >> str('[').present? >> attribute_list >> newline ).maybe >>
68
78
  block_id.maybe >>
69
- (attribute_list >> newline ).maybe >>
70
- str(delimiter).repeat(repeater).as(:delimiter) >> newline >>
79
+ (str('[').present? >> attribute_list >> newline ).maybe >>
80
+ line_start? >>
81
+ str(delimiter).repeat(repeater).capture(:delimit).as(:delimiter) >> newline >>
71
82
  if type == :pass
72
83
  (text_line | empty_line.as(:line_break)).repeat(1).as(:lines)
73
84
  else
74
- block_content.as(:lines)
85
+ block_delimiter.absent? >> block_content(n_deep-1).as(:lines)
75
86
  end >>
76
- str(delimiter).repeat(repeater) >> newline
87
+ line_start? >>
88
+ dynamic { |s,c| str(c.captures[:delimit].to_s.strip) } >> newline
89
+ # str(delimiter).repeat(repeater) >> str(delimiter).absent? >> newline
77
90
  end
78
91
 
79
92
  end
@@ -25,9 +25,19 @@ module Coradoc
25
25
  literal_space.maybe
26
26
  end
27
27
 
28
+ def list_prefix
29
+ (line_start? >> match('^[*\.]') >> str(' '))
30
+ end
31
+
32
+ def section_prefix
33
+ (line_start? >> match('^[=]') >> str('=').repeat(0) >> match('[^\n]'))
34
+ end
35
+
28
36
  # Text
29
- def text_line(many_breaks = false)
30
- tl = (asciidoc_char_with_id.absent? | text_id) >> literal_space? >>
37
+ def text_line(many_breaks = false) #:zero :one :many
38
+ tl = #section_prefix.absent? >>
39
+ # list_prefix.absent? >>
40
+ (asciidoc_char_with_id.absent? | text_id) >> literal_space? >>
31
41
  text.as(:text)
32
42
  if many_breaks
33
43
  tl >> line_ending.repeat(1).as(:line_break)
@@ -37,7 +47,7 @@ module Coradoc
37
47
  end
38
48
 
39
49
  def asciidoc_char
40
- match('^[*_:=\-+]')
50
+ line_start? >> match['*_:+=\-']
41
51
  end
42
52
 
43
53
  def asciidoc_char_with_id
@@ -1,30 +1,30 @@
1
+ # $DEBUG = true
1
2
  module Coradoc
2
3
  module Parser
3
4
  module Asciidoc
4
5
  module List
5
6
 
6
- def list
7
- (
8
- unordered_list |
9
- ordered_list # definition_list |
7
+ def list(nesting_level = 1)
8
+ (
9
+ unordered_list(nesting_level) |
10
+ ordered_list(nesting_level) |
11
+ definition_list
10
12
  ).as(:list)
11
13
  end
12
14
 
15
+ def list_continuation
16
+ line_start? >> str("+\n")
17
+ end
18
+
13
19
  def ordered_list(nesting_level = 1)
14
20
  attrs = (attribute_list >> newline).maybe
15
21
  r = olist_item(nesting_level)
16
- if nesting_level <= 8
17
- r = r | ordered_list(nesting_level + 1)
18
- end
19
- attrs >> r.repeat(1).as(:ordered)
22
+ attrs >> olist_item(nesting_level).present? >> r.repeat(1).as(:ordered)
20
23
  end
21
24
 
22
25
  def unordered_list(nesting_level = 1)
23
26
  attrs = (attribute_list >> newline).maybe
24
27
  r = ulist_item(nesting_level)
25
- if nesting_level <= 8
26
- r = r | unordered_list(nesting_level + 1)
27
- end
28
28
  attrs >> r.repeat(1).as(:unordered)
29
29
  end
30
30
 
@@ -34,23 +34,57 @@ module Coradoc
34
34
  dlist_item(delimiter).absent?
35
35
  end
36
36
 
37
+ def list_marker(nesting_level = 1)
38
+ olist_marker(nesting_level) | ulist_marker(nesting_level)
39
+ end
40
+
41
+ def olist_marker(nesting_level = 1)
42
+ line_start? >> str('.' * nesting_level) >> str('.').absent?
43
+ end
44
+
37
45
  def olist_item(nesting_level = 1)
38
- nl2 = nesting_level - 1
39
- marker = match(/^\./)
40
- marker = marker >> str(".").repeat(nl2, nl2) if nl2 > 0
41
- str("").as(:list_item) >>
42
- marker.as(:marker) >> str(".").absent? >>
43
- match("\n").absent? >> space >> text_line(true)
46
+ item = olist_marker(nesting_level).as(:marker) >>
47
+ match("\n").absent? >> space >> text_line(true)# >>
48
+ # (list_continuation.present? >> list_continuation >>
49
+ # paragraph #| example_block(n_deep: 1)
50
+ # ).repeat(0).as(:attached)
51
+
52
+ att = (list_continuation.present? >>
53
+ list_continuation >>
54
+ (admonition_line | paragraph | block) #(n_deep: 1))
55
+ ).repeat(0).as(:attached)
56
+ item = item >> att.maybe
57
+
58
+
59
+ if nesting_level <= 4
60
+ item = item >>
61
+ (list_marker(nesting_level + 1).present? >>
62
+ list(nesting_level + 1)).repeat(0).as(:nested)#).maybe
63
+ end
64
+ olist_marker(nesting_level).present? >> item.as(:list_item)
65
+ end
66
+
67
+ def ulist_marker(nesting_level = 1)
68
+ line_start? >> str('*' * nesting_level) >> str('*').absent?
44
69
  end
45
70
 
46
71
  def ulist_item(nesting_level = 1)
47
- nl2 = nesting_level - 1
48
- marker = match(/^\*/)
49
- marker = marker >> str("*").repeat(nl2, nl2) if nl2 > 0
50
- str("").as(:list_item) >>
51
- marker.as(:marker) >> str("*").absent? >>
72
+ item = ulist_marker(nesting_level).as(:marker) >>
52
73
  str(' [[[').absent? >>
53
74
  match("\n").absent? >> space >> text_line(true)
75
+
76
+ att = (list_continuation.present? >>
77
+ list_continuation >>
78
+ (admonition_line | paragraph | block) #(n_deep: 1))
79
+ ).repeat(0).as(:attached)
80
+ item = item >> att.maybe
81
+
82
+ if nesting_level <= 4
83
+ item = item >>
84
+ (list_marker(nesting_level + 1).present? >>
85
+ list(nesting_level + 1)).repeat(0).as(:nested)#).maybe
86
+ end
87
+ ulist_marker(nesting_level).present? >> item.as(:list_item)
54
88
  end
55
89
 
56
90
  def dlist_delimiter
@@ -3,10 +3,22 @@ module Coradoc
3
3
  module Asciidoc
4
4
  module Paragraph
5
5
 
6
+ def line_not_text?
7
+ line_start? >>
8
+ attribute_list.absent? >>
9
+ block_delimiter.absent? >>
10
+ list.absent? >>
11
+ # list_prefix.absent? >>
12
+ section_id.absent? >>
13
+ section_prefix.absent?
14
+ end
15
+
6
16
  def paragraph_text_line
17
+ line_not_text? >>
7
18
  (asciidoc_char_with_id.absent? | text_id ) >>
8
19
  literal_space? >>
9
- (text_formatted.as(:text) # >>
20
+ (line_not_text? >>
21
+ text_formatted.as(:text) # >>
10
22
  ) | term | term2
11
23
  end
12
24
 
@@ -14,9 +26,9 @@ module Coradoc
14
26
  ( block_id.maybe >>
15
27
  block_title.maybe >>
16
28
  (attribute_list >> newline).maybe >>
17
- (paragraph_text_line.repeat(1,1) >> any.absent? |
18
- (paragraph_text_line >> newline_single.as(:line_break)).repeat(1) >>
19
- (paragraph_text_line.repeat(1,1)).repeat(0,1)
29
+ (line_not_text? >> paragraph_text_line.repeat(1,1) >> any.absent? |
30
+ (line_not_text? >> paragraph_text_line >> newline_single.as(:line_break)).repeat(1) >>
31
+ (line_not_text? >> paragraph_text_line.repeat(1,1)).repeat(0,1)
20
32
  ).as(:lines) >>
21
33
  newline.repeat(0)
22
34
  ).as(:paragraph)
@@ -14,7 +14,7 @@ module Coradoc
14
14
  comment_line |
15
15
  include_directive |
16
16
  admonition_line |
17
- block.as(:block) |
17
+ block |
18
18
  table.as(:table) |
19
19
  highlight.as(:highlight) |
20
20
  glossaries.as(:glossaries) |
@@ -35,12 +35,14 @@ module Coradoc
35
35
 
36
36
  # Section id
37
37
  def section_id
38
+ line_start? >>
38
39
  (str("[[") >> keyword.as(:id) >> str("]]") |
39
40
  str("[#") >> keyword.as(:id) >> str("]")) >> newline
40
41
  end
41
42
 
42
43
  # Heading
43
44
  def section_title(level = 2, max_level = 8)
45
+ line_start? >>
44
46
  match("=").repeat(level, max_level).as(:level) >>
45
47
  str('=').absent? >>
46
48
  space? >> text.as(:text) >> endline.as(:line_break)
@@ -7,12 +7,14 @@ module Coradoc
7
7
  end
8
8
 
9
9
  def term
10
+ line_start? >>
10
11
  term_type >> str(':[') >>
11
12
  match('[^\]]').repeat(1).as(:term) >>
12
13
  str("]") >> str("\n").repeat(1).as(:line_break)
13
14
  end
14
15
 
15
16
  def term2
17
+ line_start? >>
16
18
  match('^\[') >> term_type >> str(']#') >>
17
19
  match('[^\#]').repeat(1).as(:term2) >> str('#') >>
18
20
  str("\n").repeat(1).as(:line_break)
@@ -0,0 +1,161 @@
1
+ module Coradoc
2
+ module Parser
3
+ module Asciidoc
4
+ module Text
5
+
6
+ def space?
7
+ space.maybe
8
+ end
9
+
10
+ def space
11
+ str(' ').repeat(1)
12
+ end
13
+
14
+ def text
15
+ match("[^\n]").repeat(1)
16
+ end
17
+
18
+ def line_start?
19
+ match('^[^\n]').present?
20
+ end
21
+
22
+ def line_ending
23
+ str("\n") #| match('[\z]')# | match('$')
24
+ end
25
+
26
+ def eof?
27
+ any.absent?
28
+ end
29
+
30
+ def line_end
31
+ str("\n") | str("\r\n") | eof?
32
+ end
33
+
34
+ def endline
35
+ newline | any.absent?
36
+ end
37
+
38
+ # def endline_single
39
+ # newline_single | any.absent?
40
+ # end
41
+
42
+ def newline
43
+ (str("\n") | str("\r\n")).repeat(1)
44
+ end
45
+
46
+ def newline_single
47
+ (str("\n") | str("\r\n"))
48
+ end
49
+
50
+ def keyword
51
+ (match('[a-zA-Z0-9_\-.,]') | str(".")).repeat(1)
52
+ end
53
+
54
+ def empty_line
55
+ match("^\n")
56
+ end
57
+
58
+ def digit
59
+ match("[0-9]")
60
+ end
61
+
62
+ def digits
63
+ match("[0-9]").repeat(1)
64
+ end
65
+
66
+ def word
67
+ match("[a-zA-Z0-9_-]").repeat(1)
68
+ end
69
+
70
+ def words
71
+ word >> (space? >> word).repeat
72
+ end
73
+
74
+ def rich_texts
75
+ rich_text >> (space? >> rich_text).repeat
76
+ end
77
+
78
+ def rich_text
79
+ (match("[a-zA-Z0-9_-]") | str(".") | str("*") | match("@")).repeat(1)
80
+ end
81
+
82
+ def email
83
+ word >> str("@") >> word >> str(".") >> word
84
+ end
85
+
86
+ def special_character
87
+ match("^[*:=-]") | str("[#") | str("[[")
88
+ end
89
+
90
+ def date
91
+ digit.repeat(2, 4) >> str("-") >>
92
+ digit.repeat(1, 2) >> str("-") >> digit.repeat(1, 2)
93
+ end
94
+
95
+ def attr_name
96
+ match("[^\t\s]").repeat(1)
97
+ end
98
+
99
+ def file_path
100
+ match('[^\[]').repeat(1)
101
+ end
102
+
103
+ def include_directive
104
+ (str("include::") >>
105
+ file_path.as(:path) >>
106
+ attribute_list >>
107
+ (newline | str("")).as(:line_break)
108
+ ).as(:include)
109
+ end
110
+
111
+ def inline_image
112
+ (str("image::") >>
113
+ file_path.as(:path) >>
114
+ attribute_list >>
115
+ (line_ending)
116
+ ).as(:inline_image)
117
+ end
118
+
119
+ def block_image
120
+ (block_id.maybe >>
121
+ block_title.maybe >>
122
+ (attribute_list >> newline).maybe >>
123
+ match('^i') >> str("mage::") >>
124
+ file_path.as(:path) >>
125
+ attribute_list(:attribute_list_macro) >>
126
+ newline.as(:line_break)
127
+ ).as(:block_image)
128
+ end
129
+
130
+ def comment_line
131
+ tag.absent? >>
132
+ (str('//') >> str("/").absent? >>
133
+ space? >>
134
+ text.as(:comment_text)
135
+ ).as(:comment_line)
136
+ end
137
+
138
+ def tag
139
+ (str('//') >> str('/').absent? >>
140
+ space? >>
141
+ (str('tag') | str('end')).as(:prefix) >>
142
+ str('::') >> str(':').absent? >>
143
+ match('[^\[]').repeat(1).as(:name) >>
144
+ attribute_list >>
145
+ line_ending.maybe.as(:line_break)
146
+ ).as(:tag)
147
+ end
148
+
149
+ def comment_block
150
+ ( str('////') >> line_ending >>
151
+ ((line_ending >> str('////')).absent? >> any
152
+ ).repeat.as(:comment_text) >>
153
+ line_ending >> str('////')
154
+ ).as(:comment_block)
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end
160
+
161
+
@@ -1,36 +1,12 @@
1
+ require "digest"
1
2
  require "parslet"
2
3
  require "parslet/convenience"
3
4
 
4
- require_relative "asciidoc/attribute_list"
5
5
  require_relative "asciidoc/base"
6
- require_relative "asciidoc/block"
7
- require_relative "asciidoc/citation"
8
- require_relative "asciidoc/content"
9
- require_relative "asciidoc/document_attributes"
10
- require_relative "asciidoc/header"
11
- require_relative "asciidoc/inline"
12
- require_relative "asciidoc/list"
13
- require_relative "asciidoc/paragraph"
14
- require_relative "asciidoc/section"
15
- require_relative "asciidoc/table"
16
- require_relative "asciidoc/term"
17
6
 
18
7
  module Coradoc
19
8
  module Parser
20
- class Base < Parslet::Parser
21
- include Coradoc::Parser::Asciidoc::AttributeList
22
- include Coradoc::Parser::Asciidoc::Base
23
- include Coradoc::Parser::Asciidoc::Block
24
- include Coradoc::Parser::Asciidoc::Citation
25
- include Coradoc::Parser::Asciidoc::Content
26
- include Coradoc::Parser::Asciidoc::DocumentAttributes
27
- include Coradoc::Parser::Asciidoc::Header
28
- include Coradoc::Parser::Asciidoc::Inline
29
- include Coradoc::Parser::Asciidoc::List
30
- include Coradoc::Parser::Asciidoc::Paragraph
31
- include Coradoc::Parser::Asciidoc::Section
32
- include Coradoc::Parser::Asciidoc::Table
33
- include Coradoc::Parser::Asciidoc::Term
9
+ class Base < Coradoc::Parser::Asciidoc::Base
34
10
 
35
11
  root :document
36
12
  rule(:document) do
@@ -43,8 +19,8 @@ module Coradoc
43
19
  tag |
44
20
  comment_block |
45
21
  comment_line |
46
- block.as(:block) |
47
- section.as(:section) |
22
+ block |
23
+ section |
48
24
  include_directive |
49
25
  document_attributes |
50
26
  list |
@@ -156,27 +156,25 @@ module Coradoc
156
156
  )
157
157
  }
158
158
 
159
- rule(bold_constrained: {
160
- content: simple(:text)
161
- }){
159
+ rule(bold_constrained: sequence(:text)){
162
160
  Element::Inline::Bold.new(text, unconstrained: false)
163
161
  }
164
162
 
165
- rule(bold_unconstrained: {content: simple(:text)}) {
163
+ rule(bold_unconstrained: sequence(:text)) {
166
164
  Element::Inline::Bold.new(text, unconstrained: true)
167
165
  }
168
166
 
169
- rule(highlight_constrained: {content: simple(:text)}) {
167
+ rule(highlight_constrained: sequence(:text)) {
170
168
  Element::Inline::Highlight.new(text, unconstrained: false)
171
169
  }
172
- rule(highlight_unconstrained: {content: simple(:text)}) {
170
+ rule(highlight_unconstrained: sequence(:text)) {
173
171
  Element::Inline::Highlight.new(text, unconstrained: true)
174
172
  }
175
173
 
176
- rule(italic_constrained: {content: simple(:text)}) {
174
+ rule(italic_constrained: sequence(:text)) {
177
175
  Element::Inline::Italic.new(text, unconstrained: false)
178
176
  }
179
- rule(italic_unconstrained: {content: simple(:text)}) {
177
+ rule(italic_unconstrained: sequence(:text)) {
180
178
  Element::Inline::Italic.new(text, unconstrained: true)
181
179
  }
182
180
 
@@ -300,25 +298,24 @@ module Coradoc
300
298
  if attribute_list
301
299
  if (attribute_list.positional == [] &&
302
300
  attribute_list.named.keys[0] == "reviewer")
303
- Element::Block::ReviewerComment.new(
304
- opts
305
- )
301
+ Element::Block::ReviewerComment.new(opts)
306
302
  elsif (attribute_list.positional[0] == "sidebar" &&
307
303
  attribute_list.named == {})
308
- Element::Block::Side.new(
309
- opts
310
- )
304
+ Element::Block::Side.new(opts)
305
+ else
306
+ Element::Block::Side.new(opts)
311
307
  end
312
308
  else
309
+ Element::Block::Side.new(opts)
313
310
  end
314
311
  elsif delimiter_c == "="
315
312
  Element::Block::Example.new(title, opts)
316
313
  elsif delimiter_c == "+"
317
314
  Element::Block::Pass.new(opts)
318
- elsif delimiter_c == "-"
319
- if (attribute_list.positional[0] == "quote")
320
- Element::Block::Quote.new(title, opts)
321
- end
315
+ elsif delimiter_c == "-" && delimiter.size == 2
316
+ Element::Block::Open.new(title, opts)
317
+ elsif delimiter_c == "-"&& delimiter.size >= 4
318
+ Element::Block::SourceCode.new(title, opts)
322
319
  elsif delimiter_c == "_"
323
320
  Element::Block::Quote.new(title, opts)
324
321
  end
@@ -379,28 +376,15 @@ module Coradoc
379
376
  Element::Table.new(title, rows, opts)
380
377
  end
381
378
 
382
- rule(list_item: simple(:list_item),
383
- marker: simple(:marker),
384
- text: simple(:text),
385
- line_break: simple(:line_break)) do
386
- Element::ListItem.new(
387
- text,
388
- marker: marker.to_s,
389
- line_break: line_break
390
- )
391
- end
392
-
393
- rule(list_item: simple(:list_item),
394
- marker: simple(:marker),
395
- id: simple(:id),
396
- text: simple(:text),
397
- line_break: simple(:line_break)) do
379
+ rule(list_item: subtree(:list_item)) do
380
+ marker = list_item[:marker]
381
+ id = list_item[:id]
382
+ text = list_item[:text]
383
+ attached = list_item[:attached]
384
+ nested = list_item[:nested]
385
+ line_break = list_item[:line_break]
398
386
  Element::ListItem.new(
399
- text,
400
- id: id,
401
- marker: marker.to_s,
402
- line_break: line_break
403
- )
387
+ text, id:, marker:, attached:, nested:, line_break: )
404
388
  end
405
389
 
406
390
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Coradoc
4
- VERSION = "1.1.3"
4
+ VERSION = "1.1.4"
5
5
  end
data/utils/round_trip.rb CHANGED
@@ -30,7 +30,7 @@ adoc_files.each do |file_path|
30
30
  generated_adoc = Coradoc::Generator.gen_adoc(doc)
31
31
  cleaned_adoc = Coradoc::Input::HTML.cleaner.tidy(generated_adoc)
32
32
  File.open("#{file_path}.roundtrip","w"){|f| f.write(cleaned_adoc)}
33
- `diff -B #{file_path} #{file_path}.roundtrip > #{file_path}.roundtrip.diff`
33
+ `diff -BNaur #{file_path} #{file_path}.roundtrip > #{file_path}.roundtrip.diff`
34
34
  # rescue
35
35
  # puts "unsuccessful..."
36
36
  # end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: coradoc
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.3
4
+ version: 1.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2024-11-13 00:00:00.000000000 Z
12
+ date: 2024-12-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: marcel
@@ -293,7 +293,9 @@ files:
293
293
  - lib/coradoc/element/block.rb
294
294
  - lib/coradoc/element/block/core.rb
295
295
  - lib/coradoc/element/block/example.rb
296
+ - lib/coradoc/element/block/listing.rb
296
297
  - lib/coradoc/element/block/literal.rb
298
+ - lib/coradoc/element/block/open.rb
297
299
  - lib/coradoc/element/block/pass.rb
298
300
  - lib/coradoc/element/block/quote.rb
299
301
  - lib/coradoc/element/block/reviewer_comment.rb
@@ -410,6 +412,7 @@ files:
410
412
  - lib/coradoc/parser/asciidoc/section.rb
411
413
  - lib/coradoc/parser/asciidoc/table.rb
412
414
  - lib/coradoc/parser/asciidoc/term.rb
415
+ - lib/coradoc/parser/asciidoc/text.rb
413
416
  - lib/coradoc/parser/base.rb
414
417
  - lib/coradoc/reverse_adoc.rb
415
418
  - lib/coradoc/transformer.rb