coradoc 1.1.2 → 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.
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)