coradoc 1.1.2 → 1.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/lib/coradoc/element/attribute_list.rb +13 -1
  3. data/lib/coradoc/element/base.rb +2 -0
  4. data/lib/coradoc/element/block/core.rb +4 -3
  5. data/lib/coradoc/element/block/example.rb +1 -1
  6. data/lib/coradoc/element/block/listing.rb +21 -0
  7. data/lib/coradoc/element/block/literal.rb +4 -2
  8. data/lib/coradoc/element/block/open.rb +22 -0
  9. data/lib/coradoc/element/block.rb +3 -1
  10. data/lib/coradoc/element/list/core.rb +2 -2
  11. data/lib/coradoc/element/list/ordered.rb +1 -0
  12. data/lib/coradoc/element/list/unordered.rb +1 -0
  13. data/lib/coradoc/element/list_item.rb +13 -5
  14. data/lib/coradoc/element/section.rb +2 -2
  15. data/lib/coradoc/element/text_element.rb +9 -0
  16. data/lib/coradoc/input/html/converters/base.rb +2 -2
  17. data/lib/coradoc/input/html/converters/div.rb +1 -0
  18. data/lib/coradoc/input/html/converters/table.rb +7 -1
  19. data/lib/coradoc/input/html/postprocessor.rb +77 -15
  20. data/lib/coradoc/parser/asciidoc/attribute_list.rb +7 -1
  21. data/lib/coradoc/parser/asciidoc/base.rb +52 -134
  22. data/lib/coradoc/parser/asciidoc/block.rb +51 -38
  23. data/lib/coradoc/parser/asciidoc/content.rb +13 -3
  24. data/lib/coradoc/parser/asciidoc/list.rb +56 -22
  25. data/lib/coradoc/parser/asciidoc/paragraph.rb +16 -4
  26. data/lib/coradoc/parser/asciidoc/section.rb +3 -1
  27. data/lib/coradoc/parser/asciidoc/term.rb +2 -0
  28. data/lib/coradoc/parser/asciidoc/text.rb +161 -0
  29. data/lib/coradoc/parser/base.rb +4 -28
  30. data/lib/coradoc/transformer.rb +23 -39
  31. data/lib/coradoc/version.rb +1 -1
  32. data/utils/round_trip.rb +1 -1
  33. metadata +5 -2
@@ -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)