maruku 0.2.13 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. data/bin/maruku +23 -15
  2. data/bin/maruku0.3 +37 -0
  3. data/bin/marutest +277 -0
  4. data/docs/changelog-0.3.html +99 -0
  5. data/docs/changelog-0.3.md +84 -0
  6. data/docs/faq.html +46 -0
  7. data/docs/faq.md +32 -0
  8. data/docs/index.html +629 -64
  9. data/docs/markdown_extra2.html +67 -14
  10. data/docs/markdown_syntax.html +631 -94
  11. data/docs/markdown_syntax_2.html +152 -0
  12. data/docs/maruku.html +629 -64
  13. data/docs/maruku.md +108 -105
  14. data/docs/proposal.html +362 -55
  15. data/docs/proposal.md +133 -169
  16. data/docs/todo.html +30 -0
  17. data/lib/maruku.rb +13 -3
  18. data/lib/maruku/errors_management.rb +75 -0
  19. data/lib/maruku/helpers.rb +164 -0
  20. data/lib/maruku/html_helper.rb +33 -13
  21. data/lib/maruku/parse_block.rb +89 -92
  22. data/lib/maruku/parse_doc.rb +43 -18
  23. data/lib/maruku/parse_span.rb +17 -46
  24. data/lib/maruku/parse_span_better.rb +681 -0
  25. data/lib/maruku/string_utils.rb +17 -10
  26. data/lib/maruku/structures.rb +62 -35
  27. data/lib/maruku/structures_iterators.rb +39 -0
  28. data/lib/maruku/tests/benchmark.rb +12 -4
  29. data/lib/maruku/tests/new_parser.rb +318 -0
  30. data/lib/maruku/to_html.rb +113 -44
  31. data/lib/maruku/to_latex.rb +32 -14
  32. data/lib/maruku/to_markdown.rb +110 -0
  33. data/lib/maruku/toc.rb +35 -1
  34. data/lib/maruku/version.rb +10 -1
  35. data/lib/test.rb +29 -0
  36. data/tests/others/escaping.md +6 -4
  37. data/tests/others/links.md +1 -1
  38. data/tests/others/lists_after_paragraph.md +44 -0
  39. data/tests/unittest/abbreviations.md +71 -0
  40. data/tests/unittest/blank.md +43 -0
  41. data/tests/unittest/blanks_in_code.md +131 -0
  42. data/tests/unittest/code.md +64 -0
  43. data/tests/unittest/code2.md +59 -0
  44. data/tests/unittest/code3.md +121 -0
  45. data/tests/unittest/easy.md +36 -0
  46. data/tests/unittest/email.md +39 -0
  47. data/tests/unittest/encoding/iso-8859-1.md +9 -0
  48. data/tests/unittest/encoding/utf-8.md +38 -0
  49. data/tests/unittest/entities.md +174 -0
  50. data/tests/unittest/escaping.md +97 -0
  51. data/tests/unittest/extra_dl.md +81 -0
  52. data/tests/unittest/extra_header_id.md +96 -0
  53. data/tests/unittest/extra_table1.md +78 -0
  54. data/tests/unittest/footnotes.md +120 -0
  55. data/tests/unittest/headers.md +64 -0
  56. data/tests/unittest/hrule.md +77 -0
  57. data/tests/unittest/images.md +114 -0
  58. data/tests/unittest/inline_html.md +185 -0
  59. data/tests/unittest/links.md +162 -0
  60. data/tests/unittest/list1.md +80 -0
  61. data/tests/unittest/list2.md +75 -0
  62. data/tests/unittest/list3.md +111 -0
  63. data/tests/unittest/list4.md +43 -0
  64. data/tests/unittest/lists.md +262 -0
  65. data/tests/unittest/lists_after_paragraph.md +280 -0
  66. data/tests/unittest/lists_ol.md +323 -0
  67. data/tests/unittest/misc_sw.md +751 -0
  68. data/tests/unittest/notyet/escape.md +46 -0
  69. data/tests/unittest/notyet/header_after_par.md +85 -0
  70. data/tests/unittest/notyet/ticks.md +67 -0
  71. data/tests/unittest/notyet/triggering.md +210 -0
  72. data/tests/unittest/one.md +33 -0
  73. data/tests/unittest/paragraph.md +34 -0
  74. data/tests/unittest/paragraph_rules/dont_merge_ref.md +60 -0
  75. data/tests/unittest/paragraph_rules/tab_is_blank.md +43 -0
  76. data/tests/unittest/paragraphs.md +84 -0
  77. data/tests/unittest/recover/recover_links.md +32 -0
  78. data/tests/unittest/references/long_example.md +87 -0
  79. data/tests/unittest/references/spaces_and_numbers.md +27 -0
  80. data/tests/unittest/syntax_hl.md +99 -0
  81. data/tests/unittest/test.md +36 -0
  82. data/tests/unittest/wrapping.md +88 -0
  83. data/tests/utf8-files/simple.md +1 -0
  84. metadata +139 -86
  85. data/lib/maruku/maruku.rb +0 -50
  86. data/tests/a.md +0 -10
@@ -18,10 +18,15 @@
18
18
 
19
19
  # Structures definition
20
20
  require 'maruku/structures'
21
+ # Less typing
22
+ require 'maruku/helpers'
21
23
 
22
24
  # Code for parsing whole Markdown documents
23
25
  require 'maruku/parse_doc'
24
26
 
27
+ # Ugly things kept in a closet
28
+ require 'maruku/string_utils'
29
+
25
30
  # A class for reading and sanitizing inline HTML
26
31
  require 'maruku/html_helper'
27
32
 
@@ -29,10 +34,12 @@ require 'maruku/html_helper'
29
34
  require 'maruku/parse_block'
30
35
 
31
36
  # Code for parsing Markdown span-level elements
32
- require 'maruku/parse_span'
37
+ require 'maruku/parse_span_better'
38
+
39
+ require 'maruku/structures_iterators'
40
+
41
+ require 'maruku/errors_management'
33
42
 
34
- # Ugly things kept in a closet
35
- require 'maruku/string_utils'
36
43
 
37
44
  # Code for creating a table of contents
38
45
  require 'maruku/toc'
@@ -49,5 +56,8 @@ require 'maruku/to_latex'
49
56
  require 'maruku/to_latex_strings'
50
57
  require 'maruku/to_latex_entities'
51
58
 
59
+ # Pretty print
60
+ require 'maruku/to_markdown'
61
+
52
62
  # Exporting to text: strips all formatting (not complete)
53
63
  require 'maruku/to_s'
@@ -0,0 +1,75 @@
1
+
2
+
3
+ # Any method that detects formatting error calls the
4
+ # error() method.
5
+ # if @meta[:on_error] ==
6
+ #
7
+ # - :warning write on the standard err (or @error_stream if defined),
8
+ # then do your best.
9
+ # - :ignore be shy and try to continue
10
+ # - :raise raises a MarukuException
11
+ #
12
+ # default is :raise
13
+
14
+ class MarukuException < RuntimeError
15
+
16
+ end
17
+
18
+
19
+ module MarukuErrors
20
+ Default_on_error = :warning
21
+
22
+ def maruku_error(s,src=nil,con=nil)
23
+ policy = @doc ? (@doc.meta[:on_error] || Default_on_error) : :raise
24
+
25
+ case policy
26
+ when :ignore
27
+ when :raise
28
+ raise_error describe_error(s,src,con)
29
+ when :warning
30
+ tell_user describe_error(s,src,con)
31
+ end
32
+ end
33
+
34
+ alias error maruku_error
35
+
36
+ def raise_error(s)
37
+ raise MarukuException, s, caller
38
+ end
39
+
40
+ def tell_user(s)
41
+ n = 75
42
+ (@error_stream || $stderr) <<
43
+ " "+"_"*n << "\n"<<
44
+ "| Maruku tells you (#{caller[0]})\n" <<
45
+ "+"+"-"*n +"\n"+
46
+ add_tabs(s,1,'| ') << "\n" <<
47
+ "+" << "-"*n << "\n" <<
48
+ add_tabs(caller.join("\n"),1,'!') << "\n" <<
49
+ "\\" << "_"*n << "\n"
50
+ end
51
+
52
+ def set_error_stream(os)
53
+ @error_stream = os
54
+ end
55
+
56
+ def describe_error(s,src,con)
57
+ t = s
58
+ if src
59
+ t += "\n#{src.describe}\n"
60
+ end
61
+ if con
62
+ t += "\n#{con.describe}\n"
63
+ end
64
+ t
65
+ end
66
+
67
+ end
68
+
69
+ class MDElement
70
+ include MarukuErrors
71
+ end
72
+
73
+
74
+
75
+
@@ -0,0 +1,164 @@
1
+
2
+
3
+ # A series of helper functions for creating elements
4
+
5
+ module Helpers
6
+
7
+ def md_el(node_type, children=[], meta={})
8
+ e=MDElement.new(node_type, children, meta)
9
+ e.doc = self
10
+ e
11
+ end
12
+
13
+ def md_code(code)
14
+ md_el(:inline_code, [], {:raw_code => code})
15
+ end
16
+
17
+ def md_par(children, meta={})
18
+ md_el(:paragraph, [], meta)
19
+ end
20
+
21
+ def md_html(raw_html)
22
+ e = md_el(:raw_html, [], {:raw_html=>raw_html})
23
+ begin
24
+ # remove newlines and whitespace at begin
25
+ # end end of string, or else REXML gets confused
26
+ raw_html = raw_html.gsub(/\A\s*</,'<').
27
+ gsub(/>[\s\n]*\Z/,'>')
28
+ e.instance_variable_set :@parsed_html,
29
+ REXML::Document.new(raw_html)
30
+
31
+ rescue Exception => ex
32
+ tell_user "Malformed block of HTML:\n"+
33
+ add_tabs(raw_html,1,'|')
34
+ # " #{raw_html.inspect}\n\n"+ex.inspect
35
+ end
36
+ e
37
+ end
38
+
39
+ def md_link(children, ref_id)
40
+ md_el(:link, children, {:ref_id=>ref_id.downcase})
41
+ end
42
+
43
+ def md_im_link(children, url, title=nil)
44
+ md_el(:link, children, {:url=>url,:title=>title})
45
+ end
46
+
47
+
48
+ def md_image(children, ref_id)
49
+ md_el(:image, children, {:ref_id=>ref_id})
50
+ end
51
+
52
+ def md_im_image(children, url, title=nil)
53
+ md_el(:image, children, {:url=>url,:title=>title})
54
+ end
55
+
56
+ def md_em(children)
57
+ md_el(:emphasis, [children].flatten)
58
+ end
59
+
60
+ def md_strong(children)
61
+ md_el(:strong, [children].flatten)
62
+ end
63
+
64
+ def md_emstrong(children)
65
+ md_strong(md_em(children))
66
+ end
67
+
68
+ # <http://www.example.com/>
69
+ def md_url(url)
70
+ md_el(:immediate_link, [], {:url=>url})
71
+ end
72
+
73
+ # <andrea@rubyforge.org>
74
+ # <mailto:andrea@rubyforge.org>
75
+ def md_email(email)
76
+ md_el(:email_address, [], {:email=>email})
77
+ end
78
+
79
+ def md_entity(entity_name)
80
+ md_el(:entity, [], {:entity_name=>entity_name})
81
+ end
82
+
83
+ # Markdown extra
84
+ def md_foot_ref(ref_id)
85
+ md_el(:footnote_reference, [], {:footnote_id=>ref_id})
86
+ end
87
+
88
+ def md_par(children, meta={})
89
+ md_el(:paragraph, children, meta)
90
+ end
91
+
92
+ # [1]: http://url [properties]
93
+ def md_ref_def(ref_id, url, title=nil, meta={})
94
+ meta[:url] = url
95
+ meta[:ref_id] = ref_id
96
+ meta[:title] = title if title
97
+ md_el(:ref_definition, [], meta)
98
+ end
99
+ end
100
+
101
+ class MDElement
102
+ # outputs abbreviated form
103
+ def inspect2
104
+ case @node_type
105
+ when :paragraph
106
+ "md_par(%s)" % children_inspect
107
+ when :footnote_reference
108
+ "md_foot_ref(%s)" % @meta[:footnote_id].inspect
109
+ when :entity
110
+ "md_entity(%s)" % @meta[:entity_name].inspect
111
+ when :email_address
112
+ "md_email(%s)" % @meta[:email].inspect
113
+ when :inline_code
114
+ "md_code(%s)" % @meta[:raw_code].inspect
115
+ when :raw_html
116
+ "md_html(%s)" % @meta[:raw_html].inspect
117
+ when :emphasis
118
+ "md_em(%s)" % children_inspect
119
+ when :strong
120
+ "md_strong(%s)" % children_inspect
121
+ when :immediate_link
122
+ "md_url(%s)" % @meta[:url].inspect
123
+ when :image
124
+ if @meta[:ref_id]
125
+ "md_image(%s,%s)" % [
126
+ children_inspect, @meta[:ref_id].inspect]
127
+ else
128
+ "md_im_image(%s, %s %s)" % [
129
+ children_inspect, @meta[:url].inspect,
130
+ (title=@meta[:title]) ? (", "+ title.inspect) : ""
131
+ ]
132
+ end
133
+ when :link
134
+ if @meta[:ref_id]
135
+ "md_link(%s,%s)" % [
136
+ children_inspect, @meta[:ref_id].inspect]
137
+ else
138
+ "md_im_link(%s, %s %s)" % [
139
+ children_inspect, @meta[:url].inspect,
140
+ (title=@meta[:title]) ? (", "+ title.inspect) : ""
141
+ ]
142
+ end
143
+ when :ref_definition
144
+ "md_ref_def(%s, %s %s)" %
145
+ [
146
+ @meta[:ref_id].inspect,
147
+ @meta[:url].inspect,
148
+ @meta[:title] ? ","+@meta[:title].inspect : ""
149
+ ]
150
+ else
151
+ nil
152
+ end
153
+ end
154
+
155
+ end
156
+
157
+
158
+
159
+
160
+
161
+
162
+
163
+
164
+
@@ -1,16 +1,21 @@
1
1
 
2
2
  class Maruku
3
3
 
4
- # this class helps me read and sanitize code blocks
4
+ # This class helps me read and sanitize HTML blocks
5
+
6
+ # I tried to do this with REXML, but wasn't able to. (suggestions?)
5
7
 
6
8
  class HTMLHelper
7
- Tag = %r{^<(/)?(\w+)([^>]*)>}m
9
+ include MarukuStrings
10
+
11
+ Tag = %r{^<(/)?(\w+)\s*([^>]*)>}m
8
12
  EverythingElse = %r{^[^<]+}m
9
13
  CommentStart = %r{^<!--}x
10
14
  CommentEnd = %r{^.*-->}
11
15
  TO_SANITIZE = ['img','hr']
12
16
 
13
- attr_accessor :inside_comment
17
+ # attr_accessor :inside_comment
18
+ attr_reader :rest
14
19
 
15
20
  def initialize
16
21
  @rest = ""
@@ -21,8 +26,8 @@ class Maruku
21
26
  end
22
27
 
23
28
  def eat_this(line)
24
- @rest = line + "\n" + @rest
25
-
29
+ @rest = line + @rest
30
+ things_read = 0
26
31
  until @rest.empty?
27
32
  if @inside_comment
28
33
  if @m = CommentEnd.match(@rest)
@@ -35,10 +40,12 @@ class Maruku
35
40
  end
36
41
  else
37
42
  if @m = CommentStart.match(@rest)
43
+ things_read += 1
38
44
  @inside_comment = true
39
45
  @already += @m.pre_match + @m.to_s
40
46
  @rest = @m.post_match
41
47
  elsif @m = Tag.match(@rest)
48
+ things_read += 1
42
49
  @already += @m.pre_match
43
50
  @rest = @m.post_match
44
51
 
@@ -53,7 +60,13 @@ class Maruku
53
60
  end
54
61
 
55
62
  if TO_SANITIZE.include? tag
56
- @already += '<%s %s />' % [tag, attributes]
63
+ attributes.strip!
64
+ # puts "Attributes: #{attributes.inspect}"
65
+ if attributes.size > 0
66
+ @already += '<%s %s />' % [tag, attributes]
67
+ else
68
+ @already += '<%s />' % [tag]
69
+ end
57
70
  elsif is_closing
58
71
  @already += @m.to_s
59
72
  if @tag_stack.last != tag
@@ -73,29 +86,36 @@ class Maruku
73
86
  @already += @m.pre_match + @m.to_s
74
87
  @rest = @m.post_match
75
88
  else
76
- # puts "No match??? #{@rest.inspect}"
89
+ error "Malformed HTML: not complete: #{@rest.inspect}"
77
90
  end
78
91
  end # not inside comment
79
92
 
80
93
  # puts inspect
81
94
  # puts "Read: #{@tag_stack.inspect}"
95
+ break if is_finished? and things_read>0
82
96
  end
83
97
  end
84
98
 
85
99
 
86
100
  def error(s)
87
- raise "Error: #{s} "+ inspect
101
+ raise RuntimeError, "Error: #{s} "+ inspect, caller
88
102
  end
89
103
 
90
- def inspect; "HTML READER\n comment=#{inside_comment} "+
91
- "match=#{@m.to_s.inspect}"+
92
- "\n * * * BEFORE * * *\n#{@already.inspect}"+
93
- "\n * * * AFTER * * *\n#{@rest.inspect}"+
94
- "\n * * * TAGS stack * * *\n#{@tag_stack.inspect}"
104
+ def inspect; "HTML READER\n comment=#{@inside_comment} "+
105
+ "match=#{@m.to_s.inspect}\n"+
106
+ "Tag stack = #{@tag_stack.inspect} \n"+
107
+ "Before:\n"+
108
+ add_tabs(@already,1,'|')+"\n"+
109
+ "After:\n"+
110
+ add_tabs(@rest,1,'|')+"\n"
111
+
95
112
  end
113
+
114
+
96
115
  def stuff_you_read
97
116
  @already
98
117
  end
118
+
99
119
  def is_finished?
100
120
  not @inside_comment and @tag_stack.empty?
101
121
  end
@@ -17,9 +17,11 @@
17
17
  # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
18
 
19
19
  class Maruku
20
+ include Helpers
21
+
20
22
  # Splits the string and calls parse_lines_as_markdown
21
23
  def parse_text_as_markdown(text)
22
- lines = split_lines(text)
24
+ lines = Maruku.split_lines(text)
23
25
  parse_lines_as_markdown(lines)
24
26
  end
25
27
 
@@ -74,7 +76,7 @@ class Maruku
74
76
 
75
77
  # these do not produce output
76
78
  when :footnote_text; read_footnote_text
77
- when :ref; read_ref
79
+ when :ref_definition; output << read_ref_definition
78
80
  when :abbreviation; read_abbreviation
79
81
  when :metadata; just_read_metadata = read_metadata
80
82
 
@@ -82,7 +84,7 @@ class Maruku
82
84
  else
83
85
  node_type = cur_line_node_type
84
86
  line = shift_line
85
- # $stderr.puts "Ignoring line '#{line}' type = #{node_type}"
87
+ tell_user "Ignoring line '#{line}' type = #{node_type}"
86
88
  end
87
89
 
88
90
  if current_metadata and output.last
@@ -122,10 +124,8 @@ class Maruku
122
124
  output
123
125
  end
124
126
 
125
- def create_md_element(node_type, children=[])
126
- e = MDElement.new
127
- e.node_type = node_type
128
- e.children = children
127
+ def create_md_element(node_type, children=[], meta = {})
128
+ e = MDElement.new(node_type, children, meta)
129
129
  e.doc = self
130
130
  e
131
131
  end
@@ -134,7 +134,8 @@ class Maruku
134
134
  def cur_line_node_type; line_node_type top.first end
135
135
  def cur_line; top.empty? ? nil : top.first end
136
136
  def next_line; top.empty? ? nil : top[1] end
137
- def next_line_node_type; (top.size >= 2) ? line_node_type(top[1]) : nil end
137
+ def next_line_node_type
138
+ (top.size >= 2) ? line_node_type(top[1]) : nil end
138
139
  def shift_line; top.shift; end
139
140
 
140
141
  # reads a header (with ----- or ========)
@@ -191,41 +192,33 @@ class Maruku
191
192
  while cur_line and not h.is_finished?
192
193
  l=shift_line
193
194
  # puts "html -> #{l.inspect}"
194
- h.eat_this l
195
+ h.eat_this "\n"+l
195
196
  end
196
197
  rescue Exception => e
197
- puts e.inspect
198
+ tell_user e.inspect + e.backtrace.join("\n")
198
199
  # puts h.inspect
199
200
  end
200
201
 
201
202
  raw_html = h.stuff_you_read
202
203
 
203
- e = create_md_element(:raw_html)
204
-
205
- begin
206
- # remove newlines and whitespace at begin
207
- # end end of string, or else REXML gets confused
208
- raw_html = raw_html.gsub(/\A\s*</,'<').
209
- gsub(/>[\s\n]*\Z/,'>')
210
- e.meta[:parsed_html] = Document.new(raw_html)
211
- rescue
212
- #$stderr.puts "Malformed block of HTML:\n#{raw_html}"
213
- #puts h.inspect
214
- end
215
-
216
- e.meta[:raw_html] = raw_html
217
- e
204
+ md_html(raw_html)
218
205
  end
219
206
 
220
207
  def read_paragraph
221
208
  lines = []
222
- while cur_line && cur_line_node_type == :text
209
+ while cur_line
210
+ break if [:quote,:header3,:empty,:raw_html,:ref_definition].include?(
211
+ cur_line_node_type)
212
+ break if cur_line.strip.size == 0
213
+
214
+ break if [:header1,:header2].include? next_line_node_type
215
+
223
216
  lines << shift_line
224
217
  end
225
218
  # dbg_describe_ary(lines, 'PAR')
226
219
  children = parse_lines_as_span(lines)
227
220
 
228
- e = create_md_element(:paragraph, children)
221
+ md_par(children)
229
222
  end
230
223
 
231
224
 
@@ -291,56 +284,56 @@ class Maruku
291
284
  # This is the only ugly function in the code base.
292
285
  # It is used to read list items, descriptions, footnote text
293
286
  def read_indented_content(indentation, break_list, item_type)
294
- lines =[]
295
- # collect all indented lines
296
- saw_empty = false; saw_anything_after = false
297
- while cur_line
298
- if cur_line_node_type == :empty
299
- saw_empty = true
300
- lines << shift_line
301
- next
302
- end
303
-
304
- # after a white line
305
- if saw_empty
306
- # we expect things to be properly aligned
307
- if number_of_leading_spaces(cur_line) < indentation
287
+ lines =[]
288
+ # collect all indented lines
289
+ saw_empty = false; saw_anything_after = false
290
+ while cur_line
291
+ if cur_line_node_type == :empty
292
+ saw_empty = true
293
+ lines << shift_line
294
+ next
295
+ end
296
+
297
+ # after a white line
298
+ if saw_empty
299
+ # we expect things to be properly aligned
300
+ if number_of_leading_spaces(cur_line) < indentation
308
301
  # debug "breaking for spaces: #{cur_line}"
309
- break
310
- end
311
- saw_anything_after = true
312
- else
313
- break if break_list.include? cur_line_node_type
314
- # break if cur_line_node_type != :text
315
- end
316
-
317
- # debug "Accepted '#{cur_line}'"
318
-
319
- stripped = strip_indent(shift_line, indentation)
320
- lines << stripped
321
-
322
- # You are only required to indent the first line of
323
- # a child paragraph.
324
- if line_node_type(stripped) == :text
325
- while cur_line && (cur_line_node_type == :text)
326
- lines << strip_indent(shift_line, indentation)
327
- end
302
+ break
328
303
  end
304
+ saw_anything_after = true
305
+ else
306
+ break if break_list.include? cur_line_node_type
307
+ # break if cur_line_node_type != :text
329
308
  end
330
-
331
- want_my_paragraph = saw_anything_after ||
332
- (saw_empty && (cur_line && (cur_line_node_type == item_type)))
333
309
 
334
- # dbg_describe_ary(lines, 'LI')
335
- # create a new context
310
+ # debug "Accepted '#{cur_line}'"
311
+
312
+ stripped = strip_indent(shift_line, indentation)
313
+ lines << stripped
336
314
 
337
- while lines.last && (line_node_type(lines.last) == :empty)
338
- lines.pop
315
+ # You are only required to indent the first line of
316
+ # a child paragraph.
317
+ if line_node_type(stripped) == :text
318
+ while cur_line && (cur_line_node_type == :text)
319
+ lines << strip_indent(shift_line, indentation)
320
+ end
339
321
  end
340
-
341
- return lines, want_my_paragraph
342
322
  end
343
323
 
324
+ want_my_paragraph = saw_anything_after ||
325
+ (saw_empty && (cur_line && (cur_line_node_type == item_type)))
326
+
327
+ # dbg_describe_ary(lines, 'LI')
328
+ # create a new context
329
+
330
+ while lines.last && (line_node_type(lines.last) == :empty)
331
+ lines.pop
332
+ end
333
+
334
+ return lines, want_my_paragraph
335
+ end
336
+
344
337
 
345
338
  def read_quote
346
339
  lines = []
@@ -413,40 +406,42 @@ class Maruku
413
406
 
414
407
 
415
408
 
416
- def read_ref
409
+ def read_ref_definition
417
410
  line = shift_line
418
411
 
419
412
  # if link is incomplete, shift next line
420
- while cur_line && (cur_line_node_type != :ref) &&
413
+ if cur_line && (cur_line_node_type != :ref_definition) &&
421
414
  ([1,2,3].include? number_of_leading_spaces(cur_line) )
422
415
  line += " "+ shift_line
423
416
  end
424
417
 
425
418
  # puts "total= #{line}"
426
419
 
427
- if match = LinkRegex.match(line)
428
- id = match[1]; url = match[2]; title = match[3];
429
- id = id.strip.downcase
430
-
431
- hash = self.refs[id] = {:url=>url,:title=>title}
432
-
433
- stuff=match[4]
434
-
435
- if stuff
436
- stuff.split.each do |couple|
420
+ match = LinkRegex.match(line)
421
+ if not match
422
+ error "Link does not respect format: '#{line}'"
423
+ end
424
+
425
+ id = match[1]; url = match[2]; title = match[3];
426
+ id = id.strip.downcase
427
+
428
+ hash = self.refs[id] = {:url=>url,:title=>title}
429
+
430
+ stuff=match[4]
431
+
432
+ if stuff
433
+ stuff.split.each do |couple|
437
434
  # puts "found #{couple}"
438
- k, v = couple.split('=')
439
- v ||= ""
440
- if v[0,1]=='"' then v = v[1, v.size-2] end
435
+ k, v = couple.split('=')
436
+ v ||= ""
437
+ if v[0,1]=='"' then v = v[1, v.size-2] end
441
438
  # puts "key:_#{k}_ value=_#{v}_"
442
- hash[k.to_sym] = v
443
- end
439
+ hash[k.to_sym] = v
444
440
  end
445
- # puts hash.inspect
446
-
447
- else
448
- raise "Link does not respect format: '#{line}'"
449
441
  end
442
+ # puts hash.inspect
443
+
444
+ md_ref_def(id, url, meta={:title=>title})
450
445
  end
451
446
 
452
447
  def read_table
@@ -466,7 +461,8 @@ class Maruku
466
461
  num_columns = align.size
467
462
 
468
463
  if head.size != num_columns
469
- $stderr.puts "Head does not have #{num_columns} columns: \n#{head.inspect}"
464
+ error "Head does not have #{num_columns} columns: \n#{head.inspect}"
465
+ # XXX try to recover
470
466
  return create_md_element(:linebreak)
471
467
  end
472
468
 
@@ -476,7 +472,8 @@ class Maruku
476
472
  row = split_cells(shift_line).map{|s|
477
473
  create_md_element(:cell, parse_lines_as_span([s]))}
478
474
  if head.size != num_columns
479
- $stderr.puts "Row does not have #{num_columns} columns: \n#{row.inspect}"
475
+ error "Row does not have #{num_columns} columns: \n#{row.inspect}"
476
+ # XXX try to recover
480
477
  return create_md_element(:linebreak)
481
478
  end
482
479
  rows << row