omf_web 1.2.3 → 1.2.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.
@@ -21,596 +21,595 @@
21
21
 
22
22
  module MaRuKu; module In; module Markdown; module BlockLevelParser
23
23
 
24
- include Helpers
25
- include MaRuKu::Strings
26
- include MaRuKu::In::Markdown::SpanLevelParser
27
-
28
- class BlockContext < Array
29
- def describe
30
- n = 5
31
- desc = size > n ? self[-n,n] : self
32
- "Last #{n} elements: "+
33
- desc.map{|x| "\n -" + x.inspect}.join
34
- end
35
- end
36
-
37
- # Splits the string and calls parse_lines_as_markdown
38
- def parse_text_as_markdown(text)
39
- lines = split_lines(text)
40
- src = LineSource.new(lines)
41
- return parse_blocks(src)
42
- end
43
-
44
- # Input is a LineSource
45
- def parse_blocks(src)
46
- output = BlockContext.new
47
-
48
- # run state machine
49
- while src.cur_line
50
-
51
- next if check_block_extensions(src, output, src.cur_line)
24
+ include Helpers
25
+ include MaRuKu::Strings
26
+ include MaRuKu::In::Markdown::SpanLevelParser
27
+
28
+ class BlockContext < Array
29
+ def describe
30
+ n = 5
31
+ desc = size > n ? self[-n,n] : self
32
+ "Last #{n} elements: "+
33
+ desc.map{|x| "\n -" + x.inspect}.join
34
+ end
35
+ end
36
+
37
+ # Splits the string and calls parse_lines_as_markdown
38
+ def parse_text_as_markdown(text)
39
+ lines = split_lines(text)
40
+ src = LineSource.new(lines)
41
+ return parse_blocks(src)
42
+ end
43
+
44
+ # Input is a LineSource
45
+ def parse_blocks(src)
46
+ output = BlockContext.new
47
+
48
+ # run state machine
49
+ while src.cur_line
50
+
51
+ next if check_block_extensions(src, output, src.cur_line)
52
52
 
53
53
  # Prints detected type (useful for debugging)
54
- # puts "#{src.cur_line.md_type}|#{src.cur_line}"
55
- case src.cur_line.md_type
56
- when :empty;
57
- output.push :empty
58
- src.ignore_line
59
- when :ial
60
- m = InlineAttributeList.match src.shift_line
61
- content = m[1] || ""
54
+ #puts "PARSE>>>> #{src.cur_line.md_type}|#{src.cur_line}"
55
+ case src.cur_line.md_type
56
+ when :empty;
57
+ output.push :empty
58
+ src.ignore_line
59
+ when :ial
60
+ m = InlineAttributeList.match src.shift_line
61
+ content = m[1] || ""
62
62
  # puts "Content: #{content.inspect}"
63
- src2 = CharSource.new(content, src)
64
- interpret_extension(src2, output, [nil])
65
- when :ald
66
- output.push read_ald(src)
67
- when :text
68
- # paragraph, or table, or definition list
69
- read_text_material(src, output)
70
- when :header2, :hrule
71
- # hrule
72
- src.shift_line
73
- output.push md_hrule()
74
- when :header3
75
- output.push read_header3(src)
76
- when :ulist, :olist
77
- list_type = src.cur_line.md_type == :ulist ? :ul : :ol
78
- li = read_list_item(src)
79
- # append to current list if we have one
80
- if output.last.kind_of?(MDElement) &&
81
- output.last.node_type == list_type then
82
- output.last.children << li
83
- else
84
- output.push md_el(list_type, [li])
85
- end
86
- when :quote; output.push read_quote(src)
87
- when :code; e = read_code(src); output << e if e
88
- when :raw_html; e = read_raw_html(src); output << e if e
89
-
90
- when :footnote_text; output.push read_footnote_text(src)
91
- when :ref_definition
92
- if src.parent && (src.cur_index == 0)
93
- read_text_material(src, output)
94
- else
95
- read_ref_definition(src, output)
96
- end
97
- when :abbreviation; output.push read_abbreviation(src)
98
- when :xml_instr; read_xml_instruction(src, output)
99
- when :metadata;
100
- maruku_error "Please use the new meta-data syntax: \n"+
101
- " http://maruku.rubyforge.org/proposal.html\n", src
102
- src.ignore_line
103
- else # warn if we forgot something
104
- md_type = src.cur_line.md_type
105
- line = src.cur_line
106
- maruku_error "Ignoring line '#{line}' type = #{md_type}", src
107
- src.shift_line
108
- end
109
- end
110
-
111
- merge_ial(output, src, output)
112
- output.delete_if {|x| x.kind_of?(MDElement) &&
113
- x.node_type == :ial}
114
-
115
- # get rid of empty line markers
116
- output.delete_if {|x| x == :empty}
117
- # See for each list if we can omit the paragraphs and use li_span
118
- # TODO: do this after
119
- output.each do |c|
120
- # Remove paragraphs that we can get rid of
121
- if [:ul,:ol].include? c.node_type
122
- if c.children.all? {|li| !li.want_my_paragraph} then
123
- c.children.each do |d|
124
- d.node_type = :li_span
125
- d.children = d.children[0].children
126
- end
127
- end
128
- end
129
- if c.node_type == :definition_list
130
- if c.children.all?{|defi| !defi.want_my_paragraph} then
131
- c.children.each do |definition|
132
- definition.definitions.each do |dd|
133
- dd.children = dd.children[0].children
134
- end
135
- end
136
- end
137
- end
138
- end
139
-
140
- output
141
- end
142
-
143
- def read_text_material(src, output)
144
- if src.cur_line =~ MightBeTableHeader and
145
- (src.next_line && src.next_line =~ TableSeparator)
146
- output.push read_table(src)
147
- elsif [:header1,:header2].include? src.next_line.md_type
148
- output.push read_header12(src)
149
- elsif eventually_comes_a_def_list(src)
150
- definition = read_definition(src)
151
- if output.last.kind_of?(MDElement) &&
152
- output.last.node_type == :definition_list then
153
- output.last.children << definition
154
- else
155
- output.push md_el(:definition_list, [definition])
156
- end
157
- else # Start of a paragraph
158
- output.push read_paragraph(src)
159
- end
160
- end
161
-
162
-
163
- def read_ald(src)
164
- if (l=src.shift_line) =~ AttributeDefinitionList
165
- id = $1; al=$2;
166
- al = read_attribute_list(CharSource.new(al,src), context=nil, break_on=[nil])
167
- self.ald[id] = al;
168
- return md_ald(id, al)
169
- else
170
- maruku_error "Bug Bug:\n#{l.inspect}"
171
- return nil
172
- end
173
- end
174
-
175
- # reads a header (with ----- or ========)
176
- def read_header12(src)
177
- line = src.shift_line.strip
178
- al = nil
179
- # Check if there is an IAL
180
- if new_meta_data? and line =~ /^(.*)\{(.*)\}\s*$/
181
- line = $1.strip
182
- ial = $2
183
- al = read_attribute_list(CharSource.new(ial,src), context=nil, break_on=[nil])
184
- end
185
- text = parse_lines_as_span [ line ]
186
- level = src.cur_line.md_type == :header2 ? 2 : 1;
187
- src.shift_line
188
- return md_header(level, text, al, src.cur_index)
189
- end
190
-
191
- # reads a header like '#### header ####'
192
- def read_header3(src)
63
+ src2 = CharSource.new(content, src)
64
+ interpret_extension(src2, output, [nil])
65
+ when :ald
66
+ output.push read_ald(src)
67
+ when :text
68
+ # paragraph, or table, or definition list
69
+ read_text_material(src, output)
70
+ when :header2, :hrule
71
+ src.shift_line
72
+ output.push md_hrule()
73
+ when :header3
74
+ output.push read_header3(src)
75
+ when :ulist, :olist
76
+ list_type = src.cur_line.md_type == :ulist ? :ul : :ol
77
+ li = read_list_item(src)
78
+ # append to current list if we have one
79
+ if output.last.kind_of?(MDElement) &&
80
+ output.last.node_type == list_type then
81
+ output.last.children << li
82
+ else
83
+ output.push md_el(list_type, [li])
84
+ end
85
+ when :quote; output.push read_quote(src)
86
+ when :code; e = read_code(src); output << e if e
87
+ when :raw_html; e = read_raw_html(src); output << e if e
88
+
89
+ when :footnote_text; output.push read_footnote_text(src)
90
+ when :ref_definition
91
+ if src.parent && (src.cur_index == 0)
92
+ read_text_material(src, output)
93
+ else
94
+ read_ref_definition(src, output)
95
+ end
96
+ when :abbreviation; output.push read_abbreviation(src)
97
+ when :xml_instr; read_xml_instruction(src, output)
98
+ when :metadata;
99
+ maruku_error "Please use the new meta-data syntax: \n"+
100
+ " http://maruku.rubyforge.org/proposal.html\n", src
101
+ src.ignore_line
102
+ else # warn if we forgot something
103
+ md_type = src.cur_line.md_type
104
+ line = src.cur_line
105
+ maruku_error "Ignoring line '#{line}' type = #{md_type}", src
106
+ src.shift_line
107
+ end
108
+ end
109
+
110
+ merge_ial(output, src, output)
111
+ output.delete_if {|x| x.kind_of?(MDElement) &&
112
+ x.node_type == :ial}
113
+
114
+ # get rid of empty line markers
115
+ output.delete_if {|x| x == :empty}
116
+ # See for each list if we can omit the paragraphs and use li_span
117
+ # TODO: do this after
118
+ output.each do |c|
119
+ # Remove paragraphs that we can get rid of
120
+ if [:ul,:ol].include? c.node_type
121
+ if c.children.all? {|li| !li.want_my_paragraph} then
122
+ c.children.each do |d|
123
+ d.node_type = :li_span
124
+ d.children = d.children[0].children
125
+ end
126
+ end
127
+ end
128
+ if c.node_type == :definition_list
129
+ if c.children.all?{|defi| !defi.want_my_paragraph} then
130
+ c.children.each do |definition|
131
+ definition.definitions.each do |dd|
132
+ dd.children = dd.children[0].children
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
138
+
139
+ output
140
+ end
141
+
142
+ def read_text_material(src, output)
143
+ if src.cur_line =~ MightBeTableHeader and
144
+ (src.next_line && src.next_line =~ TableSeparator)
145
+ output.push read_table(src)
146
+ elsif [:header1,:header2].include? src.next_line.md_type
147
+ output.push read_header12(src)
148
+ elsif eventually_comes_a_def_list(src)
149
+ definition = read_definition(src)
150
+ if output.last.kind_of?(MDElement) &&
151
+ output.last.node_type == :definition_list then
152
+ output.last.children << definition
153
+ else
154
+ output.push md_el(:definition_list, [definition])
155
+ end
156
+ else # Start of a paragraph
157
+ output.push read_paragraph(src)
158
+ end
159
+ end
160
+
161
+
162
+ def read_ald(src)
163
+ if (l=src.shift_line) =~ AttributeDefinitionList
164
+ id = $1; al=$2;
165
+ al = read_attribute_list(CharSource.new(al,src), context=nil, break_on=[nil])
166
+ self.ald[id] = al;
167
+ return md_ald(id, al)
168
+ else
169
+ maruku_error "Bug Bug:\n#{l.inspect}"
170
+ return nil
171
+ end
172
+ end
173
+
174
+ # reads a header (with ----- or ========)
175
+ def read_header12(src)
176
+ line = src.shift_line.strip
177
+ al = nil
178
+ # Check if there is an IAL
179
+ if new_meta_data? and line =~ /^(.*)\{(.*)\}\s*$/
180
+ line = $1.strip
181
+ ial = $2
182
+ al = read_attribute_list(CharSource.new(ial,src), context=nil, break_on=[nil])
183
+ end
184
+ text = parse_lines_as_span [ line ]
185
+ level = src.cur_line.md_type == :header2 ? 2 : 1;
186
+ src.shift_line
187
+ return md_header(level, text, al, src.cur_index)
188
+ end
189
+
190
+ # reads a header like '#### header ####'
191
+ def read_header3(src)
193
192
  # puts "READ_H3: #{src.inspect}"
194
- line = src.shift_line.strip
195
- al = nil
196
- # Check if there is an IAL
197
- if new_meta_data? and line =~ /^(.*)\{(.*)\}\s*$/
198
- line = $1.strip
199
- ial = $2
200
- al = read_attribute_list(CharSource.new(ial,src), context=nil, break_on=[nil])
201
- end
202
- level = num_leading_hashes(line)
203
- text = parse_lines_as_span [strip_hashes(line)]
204
- return md_header(level, text, al, src.cur_index)
205
- end
206
-
207
- def read_xml_instruction(src, output)
208
- m = /^\s*<\?((\w+)\s*)?(.*)$/.match src.shift_line
209
- raise "BugBug" if not m
210
- target = m[2] || ''
211
- code = m[3]
212
- until code =~ /\?>/
213
- code += "\n"+src.shift_line
214
- end
215
- if not code =~ (/\?>\s*$/)
216
- garbage = (/\?>(.*)$/.match(code))[1]
217
- maruku_error "Trailing garbage on last line: #{garbage.inspect}:\n"+
218
- add_tabs(code, 1, '|'), src
219
- end
220
- code.gsub!(/\?>\s*$/, '')
221
-
222
- if target == 'mrk' && MaRuKu::Globals[:unsafe_features]
223
- result = safe_execute_code(self, code)
224
- if result
225
- if result.kind_of? String
226
- raise "Not expected"
227
- else
228
- output.push(*result)
229
- end
230
- end
231
- else
232
- output.push md_xml_instr(target, code)
233
- end
234
- end
235
-
236
- def read_raw_html(src)
237
- h = HTMLHelper.new
238
- begin
239
- h.eat_this(l=src.shift_line)
193
+ line = src.shift_line.strip
194
+ al = nil
195
+ # Check if there is an IAL
196
+ if new_meta_data? and line =~ /^(.*)\{(.*)\}\s*$/
197
+ line = $1.strip
198
+ ial = $2
199
+ al = read_attribute_list(CharSource.new(ial,src), context=nil, break_on=[nil])
200
+ end
201
+ level = num_leading_hashes(line)
202
+ text = parse_lines_as_span [strip_hashes(line)]
203
+ return md_header(level, text, al, src.cur_index)
204
+ end
205
+
206
+ def read_xml_instruction(src, output)
207
+ m = /^\s*<\?((\w+)\s*)?(.*)$/.match src.shift_line
208
+ raise "BugBug" if not m
209
+ target = m[2] || ''
210
+ code = m[3]
211
+ until code =~ /\?>/
212
+ code += "\n"+src.shift_line
213
+ end
214
+ if not code =~ (/\?>\s*$/)
215
+ garbage = (/\?>(.*)$/.match(code))[1]
216
+ maruku_error "Trailing garbage on last line: #{garbage.inspect}:\n"+
217
+ add_tabs(code, 1, '|'), src
218
+ end
219
+ code.gsub!(/\?>\s*$/, '')
220
+
221
+ if target == 'mrk' && MaRuKu::Globals[:unsafe_features]
222
+ result = safe_execute_code(self, code)
223
+ if result
224
+ if result.kind_of? String
225
+ raise "Not expected"
226
+ else
227
+ output.push(*result)
228
+ end
229
+ end
230
+ else
231
+ output.push md_xml_instr(target, code)
232
+ end
233
+ end
234
+
235
+ def read_raw_html(src)
236
+ h = HTMLHelper.new
237
+ begin
238
+ h.eat_this(l=src.shift_line)
240
239
  # puts "\nBLOCK:\nhtml -> #{l.inspect}"
241
- while src.cur_line and not h.is_finished?
242
- l=src.shift_line
240
+ while src.cur_line and not h.is_finished?
241
+ l=src.shift_line
243
242
  # puts "html -> #{l.inspect}"
244
- h.eat_this "\n"+l
245
- end
246
- rescue Exception => e
247
- ex = e.inspect + e.backtrace.join("\n")
248
- maruku_error "Bad block-level HTML:\n#{add_tabs(ex,1,'|')}\n", src
249
- end
250
- if not (h.rest =~ /^\s*$/)
251
- maruku_error "Could you please format this better?\n"+
252
- "I see that #{h.rest.inspect} is left after the raw HTML.", src
253
- end
254
- raw_html = h.stuff_you_read
255
-
256
- return md_html(raw_html)
257
- end
258
-
259
- def read_paragraph(src)
260
- lines = [src.shift_line]
261
- while src.cur_line
262
- # :olist does not break
263
- case t = src.cur_line.md_type
264
- when :quote,:header3,:empty,:ref_definition,:ial #,:xml_instr,:raw_html
265
- break
266
- when :olist,:ulist
267
- break if src.next_line.md_type == t
268
- end
269
- break if src.cur_line.strip.size == 0
270
- break if [:header1,:header2].include? src.next_line.md_type
271
- break if any_matching_block_extension?(src.cur_line)
272
-
273
- lines << src.shift_line
274
- end
243
+ h.eat_this "\n"+l
244
+ end
245
+ rescue Exception => e
246
+ ex = e.inspect + e.backtrace.join("\n")
247
+ maruku_error "Bad block-level HTML:\n#{add_tabs(ex,1,'|')}\n", src
248
+ end
249
+ if not (h.rest =~ /^\s*$/)
250
+ maruku_error "Could you please format this better?\n"+
251
+ "I see that #{h.rest.inspect} is left after the raw HTML.", src
252
+ end
253
+ raw_html = h.stuff_you_read
254
+
255
+ return md_html(raw_html)
256
+ end
257
+
258
+ def read_paragraph(src)
259
+ lines = [src.shift_line]
260
+ while src.cur_line
261
+ # :olist does not break
262
+ case t = src.cur_line.md_type
263
+ when :quote,:header3,:empty,:ref_definition,:ial #,:xml_instr,:raw_html
264
+ break
265
+ when :olist,:ulist
266
+ break if src.next_line.md_type == t
267
+ end
268
+ break if src.cur_line.strip.size == 0
269
+ break if [:header1,:header2].include? src.next_line.md_type
270
+ break if any_matching_block_extension?(src.cur_line)
271
+
272
+ lines << src.shift_line
273
+ end
275
274
  # dbg_describe_ary(lines, 'PAR')
276
- children = parse_lines_as_span(lines, src)
275
+ children = parse_lines_as_span(lines, src)
277
276
 
278
- return md_par(children, nil, src.cur_index)
279
- end
277
+ return md_par(children, nil, src.cur_index)
278
+ end
280
279
 
281
- # Reads one list item, either ordered or unordered.
282
- def read_list_item(src)
283
- parent_offset = src.cur_index
280
+ # Reads one list item, either ordered or unordered.
281
+ def read_list_item(src)
282
+ parent_offset = src.cur_index
284
283
 
285
- item_type = src.cur_line.md_type
286
- first = src.shift_line
284
+ item_type = src.cur_line.md_type
285
+ first = src.shift_line
287
286
 
288
- indentation, ial = spaces_before_first_char(first)
289
- al = read_attribute_list(CharSource.new(ial,src), context=nil, break_on=[nil]) if ial
290
- break_list = [:ulist, :olist, :ial]
291
- # Ugly things going on inside `read_indented_content`
292
- lines, want_my_paragraph =
293
- read_indented_content(src,indentation, break_list, item_type)
287
+ indentation, ial = spaces_before_first_char(first)
288
+ al = read_attribute_list(CharSource.new(ial,src), context=nil, break_on=[nil]) if ial
289
+ break_list = [:ulist, :olist, :ial]
290
+ # Ugly things going on inside `read_indented_content`
291
+ lines, want_my_paragraph =
292
+ read_indented_content(src,indentation, break_list, item_type)
294
293
 
295
- # add first line
296
- # Strip first '*', '-', '+' from first line
297
- stripped = first[indentation, first.size-1]
298
- lines.unshift stripped
294
+ # add first line
295
+ # Strip first '*', '-', '+' from first line
296
+ stripped = first[indentation, first.size-1]
297
+ lines.unshift stripped
299
298
 
300
- # dbg_describe_ary(lines, 'LIST ITEM ')
299
+ # dbg_describe_ary(lines, 'LIST ITEM ')
301
300
 
302
- src2 = LineSource.new(lines, src, parent_offset)
303
- children = parse_blocks(src2)
304
- with_par = want_my_paragraph || (children.size>1)
301
+ src2 = LineSource.new(lines, src, parent_offset)
302
+ children = parse_blocks(src2)
303
+ with_par = want_my_paragraph || (children.size>1)
305
304
 
306
- return md_li(children, with_par, al)
307
- end
305
+ return md_li(children, with_par, al)
306
+ end
308
307
 
309
- def read_abbreviation(src)
310
- if not (l=src.shift_line) =~ Abbreviation
311
- maruku_error "Bug: it's Andrea's fault. Tell him.\n#{l.inspect}"
312
- end
308
+ def read_abbreviation(src)
309
+ if not (l=src.shift_line) =~ Abbreviation
310
+ maruku_error "Bug: it's Andrea's fault. Tell him.\n#{l.inspect}"
311
+ end
313
312
 
314
- abbr = $1
315
- desc = $2
313
+ abbr = $1
314
+ desc = $2
316
315
 
317
- if (not abbr) or (abbr.size==0)
318
- maruku_error "Bad abbrev. abbr=#{abbr.inspect} desc=#{desc.inspect}"
319
- end
316
+ if (not abbr) or (abbr.size==0)
317
+ maruku_error "Bad abbrev. abbr=#{abbr.inspect} desc=#{desc.inspect}"
318
+ end
320
319
 
321
- self.abbreviations[abbr] = desc
320
+ self.abbreviations[abbr] = desc
322
321
 
323
- return md_abbr_def(abbr, desc)
324
- end
322
+ return md_abbr_def(abbr, desc)
323
+ end
325
324
 
326
- def read_footnote_text(src)
327
- parent_offset = src.cur_index
325
+ def read_footnote_text(src)
326
+ parent_offset = src.cur_index
328
327
 
329
- first = src.shift_line
328
+ first = src.shift_line
330
329
 
331
- if not first =~ FootnoteText
332
- maruku_error "Bug (it's Andrea's fault)"
333
- end
330
+ if not first =~ FootnoteText
331
+ maruku_error "Bug (it's Andrea's fault)"
332
+ end
334
333
 
335
- id = $1
336
- text = $2
334
+ id = $1
335
+ text = $2
337
336
 
338
- # Ugly things going on inside `read_indented_content`
339
- indentation = 4 #first.size-text.size
337
+ # Ugly things going on inside `read_indented_content`
338
+ indentation = 4 #first.size-text.size
340
339
 
341
340
  # puts "id =_#{id}_; text=_#{text}_ indent=#{indentation}"
342
341
 
343
- break_list = [:footnote_text, :ref_definition, :definition, :abbreviation]
344
- item_type = :footnote_text
345
- lines, want_my_paragraph =
346
- read_indented_content(src,indentation, break_list, item_type)
342
+ break_list = [:footnote_text, :ref_definition, :definition, :abbreviation]
343
+ item_type = :footnote_text
344
+ lines, want_my_paragraph =
345
+ read_indented_content(src,indentation, break_list, item_type)
347
346
 
348
- # add first line
349
- if text && text.strip != "" then lines.unshift text end
347
+ # add first line
348
+ if text && text.strip != "" then lines.unshift text end
350
349
 
351
350
  # dbg_describe_ary(lines, 'FOOTNOTE')
352
- src2 = LineSource.new(lines, src, parent_offset)
353
- children = parse_blocks(src2)
354
-
355
- e = md_footnote(id, children)
356
- self.footnotes[id] = e
357
- return e
358
- end
359
-
360
-
361
- # This is the only ugly function in the code base.
362
- # It is used to read list items, descriptions, footnote text
363
- def read_indented_content(src, indentation, break_list, item_type)
364
- lines =[]
365
- # collect all indented lines
366
- saw_empty = false; saw_anything_after = false
367
- while src.cur_line
351
+ src2 = LineSource.new(lines, src, parent_offset)
352
+ children = parse_blocks(src2)
353
+
354
+ e = md_footnote(id, children)
355
+ self.footnotes[id] = e
356
+ return e
357
+ end
358
+
359
+
360
+ # This is the only ugly function in the code base.
361
+ # It is used to read list items, descriptions, footnote text
362
+ def read_indented_content(src, indentation, break_list, item_type)
363
+ lines =[]
364
+ # collect all indented lines
365
+ saw_empty = false; saw_anything_after = false
366
+ while src.cur_line
368
367
  # puts "Reading indent = #{indentation} #{src.cur_line.inspect}"
369
- #puts "#{src.cur_line.md_type} #{src.cur_line.inspect}"
370
- if src.cur_line.md_type == :empty
371
- saw_empty = true
372
- lines << src.shift_line
373
- next
374
- end
375
-
376
- # after a white line
377
- if saw_empty
378
- # we expect things to be properly aligned
379
- if (ns=number_of_leading_spaces(src.cur_line)) < indentation
380
- #puts "breaking for spaces, only #{ns}: #{src.cur_line}"
381
- break
382
- end
383
- saw_anything_after = true
384
- else
368
+ #puts "#{src.cur_line.md_type} #{src.cur_line.inspect}"
369
+ if src.cur_line.md_type == :empty
370
+ saw_empty = true
371
+ lines << src.shift_line
372
+ next
373
+ end
374
+
375
+ # after a white line
376
+ if saw_empty
377
+ # we expect things to be properly aligned
378
+ if (ns=number_of_leading_spaces(src.cur_line)) < indentation
379
+ #puts "breaking for spaces, only #{ns}: #{src.cur_line}"
380
+ break
381
+ end
382
+ saw_anything_after = true
383
+ else
385
384
  # if src.cur_line[0] != ?\
386
- break if break_list.include? src.cur_line.md_type
385
+ break if break_list.include? src.cur_line.md_type
387
386
  # end
388
387
  # break if src.cur_line.md_type != :text
389
- end
388
+ end
390
389
 
391
390
 
392
- stripped = strip_indent(src.shift_line, indentation)
393
- lines << stripped
391
+ stripped = strip_indent(src.shift_line, indentation)
392
+ lines << stripped
394
393
 
395
- #puts "Accepted as #{stripped.inspect}"
394
+ #puts "Accepted as #{stripped.inspect}"
396
395
 
397
- # You are only required to indent the first line of
398
- # a child paragraph.
399
- if stripped.md_type == :text
400
- while src.cur_line && (src.cur_line.md_type == :text)
401
- lines << strip_indent(src.shift_line, indentation)
402
- end
403
- end
404
- end
396
+ # You are only required to indent the first line of
397
+ # a child paragraph.
398
+ if stripped.md_type == :text
399
+ while src.cur_line && (src.cur_line.md_type == :text)
400
+ lines << strip_indent(src.shift_line, indentation)
401
+ end
402
+ end
403
+ end
405
404
 
406
- want_my_paragraph = saw_anything_after ||
407
- (saw_empty && (src.cur_line && (src.cur_line.md_type == item_type)))
405
+ want_my_paragraph = saw_anything_after ||
406
+ (saw_empty && (src.cur_line && (src.cur_line.md_type == item_type)))
408
407
 
409
408
  # dbg_describe_ary(lines, 'LI')
410
- # create a new context
409
+ # create a new context
411
410
 
412
- while lines.last && (lines.last.md_type == :empty)
413
- lines.pop
414
- end
411
+ while lines.last && (lines.last.md_type == :empty)
412
+ lines.pop
413
+ end
415
414
 
416
- return lines, want_my_paragraph
417
- end
415
+ return lines, want_my_paragraph
416
+ end
418
417
 
419
418
 
420
- def read_quote(src)
421
- parent_offset = src.cur_index
419
+ def read_quote(src)
420
+ parent_offset = src.cur_index
422
421
 
423
- lines = []
424
- # collect all indented lines
425
- while src.cur_line && src.cur_line.md_type == :quote
426
- lines << unquote(src.shift_line)
427
- end
422
+ lines = []
423
+ # collect all indented lines
424
+ while src.cur_line && src.cur_line.md_type == :quote
425
+ lines << unquote(src.shift_line)
426
+ end
428
427
  # dbg_describe_ary(lines, 'QUOTE')
429
428
 
430
- src2 = LineSource.new(lines, src, parent_offset)
431
- children = parse_blocks(src2)
432
- return md_quote(children)
433
- end
429
+ src2 = LineSource.new(lines, src, parent_offset)
430
+ children = parse_blocks(src2)
431
+ return md_quote(children)
432
+ end
434
433
 
435
- def read_code(src)
436
- # collect all indented lines
437
- lines = []
438
- while src.cur_line && ([:code, :empty].include? src.cur_line.md_type)
439
- lines << strip_indent(src.shift_line, 4)
440
- end
434
+ def read_code(src)
435
+ # collect all indented lines
436
+ lines = []
437
+ while src.cur_line && ([:code, :empty].include? src.cur_line.md_type)
438
+ lines << strip_indent(src.shift_line, 4)
439
+ end
441
440
 
442
- #while lines.last && (lines.last.md_type == :empty )
443
- while lines.last && lines.last.strip.size == 0
444
- lines.pop
445
- end
441
+ #while lines.last && (lines.last.md_type == :empty )
442
+ while lines.last && lines.last.strip.size == 0
443
+ lines.pop
444
+ end
446
445
 
447
- while lines.first && lines.first.strip.size == 0
448
- lines.shift
449
- end
446
+ while lines.first && lines.first.strip.size == 0
447
+ lines.shift
448
+ end
450
449
 
451
- return nil if lines.empty?
450
+ return nil if lines.empty?
452
451
 
453
- source = lines.join("\n")
452
+ source = lines.join("\n")
454
453
 
455
454
  # dbg_describe_ary(lines, 'CODE')
456
455
 
457
- return md_codeblock(source)
458
- end
456
+ return md_codeblock(source)
457
+ end
459
458
 
460
- # Reads a series of metadata lines with empty lines in between
461
- def read_metadata(src)
462
- hash = {}
463
- while src.cur_line
464
- case src.cur_line.md_type
465
- when :empty; src.shift_line
466
- when :metadata; hash.merge! parse_metadata(src.shift_line)
467
- else break
468
- end
469
- end
470
- hash
471
- end
459
+ # Reads a series of metadata lines with empty lines in between
460
+ def read_metadata(src)
461
+ hash = {}
462
+ while src.cur_line
463
+ case src.cur_line.md_type
464
+ when :empty; src.shift_line
465
+ when :metadata; hash.merge! parse_metadata(src.shift_line)
466
+ else break
467
+ end
468
+ end
469
+ hash
470
+ end
472
471
 
473
472
 
474
- def read_ref_definition(src, out)
475
- line = src.shift_line
473
+ def read_ref_definition(src, out)
474
+ line = src.shift_line
476
475
 
477
476
 
478
- # if link is incomplete, shift next line
479
- if src.cur_line && !([:footnote_text, :ref_definition, :definition, :abbreviation].include? src.cur_line.md_type) &&
480
- ([1,2,3].include? number_of_leading_spaces(src.cur_line) )
481
- line += " "+ src.shift_line
482
- end
477
+ # if link is incomplete, shift next line
478
+ if src.cur_line && !([:footnote_text, :ref_definition, :definition, :abbreviation].include? src.cur_line.md_type) &&
479
+ ([1,2,3].include? number_of_leading_spaces(src.cur_line) )
480
+ line += " "+ src.shift_line
481
+ end
483
482
 
484
483
  # puts "total= #{line}"
485
484
 
486
- match = LinkRegex.match(line)
487
- if not match
488
- maruku_error "Link does not respect format: '#{line}'"
489
- return
490
- end
485
+ match = LinkRegex.match(line)
486
+ if not match
487
+ maruku_error "Link does not respect format: '#{line}'"
488
+ return
489
+ end
491
490
 
492
- id = match[1]; url = match[2]; title = match[3];
493
- id = sanitize_ref_id(id)
491
+ id = match[1]; url = match[2]; title = match[3];
492
+ id = sanitize_ref_id(id)
494
493
 
495
- hash = self.refs[id] = {:url=>url,:title=>title}
494
+ hash = self.refs[id] = {:url=>url,:title=>title}
496
495
 
497
- stuff=match[4]
496
+ stuff=match[4]
498
497
 
499
- if stuff
500
- stuff.split.each do |couple|
498
+ if stuff
499
+ stuff.split.each do |couple|
501
500
  # puts "found #{couple}"
502
- k, v = couple.split('=')
503
- v ||= ""
504
- if v[0,1]=='"' then v = v[1, v.size-2] end
501
+ k, v = couple.split('=')
502
+ v ||= ""
503
+ if v[0,1]=='"' then v = v[1, v.size-2] end
505
504
  # puts "key:_#{k}_ value=_#{v}_"
506
- hash[k.to_sym] = v
507
- end
508
- end
505
+ hash[k.to_sym] = v
506
+ end
507
+ end
509
508
  # puts hash.inspect
510
509
 
511
- out.push md_ref_def(id, url, meta={:title=>title})
512
- end
510
+ out.push md_ref_def(id, url, meta={:title=>title})
511
+ end
513
512
 
514
- def split_cells(s)
513
+ def split_cells(s)
515
514
  # s.strip.split('|').select{|x|x.strip.size>0}.map{|x|x.strip}
516
515
  # changed to allow empty cells
517
- s.strip.split('|').select{|x|x.size>0}.map{|x|x.strip}
518
- end
519
-
520
- def read_table(src)
521
- head = split_cells(src.shift_line).map{|s| md_el(:head_cell, parse_lines_as_span([s])) }
522
-
523
- separator=split_cells(src.shift_line)
524
-
525
- align = separator.map { |s| s =~ Sep
526
- if $1 and $2 then :center elsif $2 then :right else :left end }
527
-
528
- num_columns = align.size
529
-
530
- if head.size != num_columns
531
- maruku_error "Table head does not have #{num_columns} columns: \n#{head.inspect}"
532
- tell_user "I will ignore this table."
533
- # XXX try to recover
534
- return md_br()
535
- end
536
-
537
- rows = []
538
-
539
- while src.cur_line && src.cur_line =~ /\|/
540
- row = split_cells(src.shift_line).map{|s|
541
- md_el(:cell, parse_lines_as_span([s]))}
542
- if head.size != num_columns
543
- maruku_error "Row does not have #{num_columns} columns: \n#{row.inspect}"
544
- tell_user "I will ignore this table."
545
- # XXX try to recover
546
- return md_br()
547
- end
548
- rows << row
549
- end
550
-
551
- children = (head+rows).flatten
552
- return md_el(:table, children, {:align => align})
553
- end
554
-
555
- # If current line is text, a definition list is coming
556
- # if 1) text,empty,[text,empty]*,definition
557
-
558
- def eventually_comes_a_def_list(src)
559
- future = src.tell_me_the_future
560
- ok = future =~ %r{^t+e?d}x
516
+ s.strip.split('|').select{|x|x.size>0}.map{|x|x.strip}
517
+ end
518
+
519
+ def read_table(src)
520
+ head = split_cells(src.shift_line).map{|s| md_el(:head_cell, parse_lines_as_span([s])) }
521
+
522
+ separator=split_cells(src.shift_line)
523
+
524
+ align = separator.map { |s| s =~ Sep
525
+ if $1 and $2 then :center elsif $2 then :right else :left end }
526
+
527
+ num_columns = align.size
528
+
529
+ if head.size != num_columns
530
+ maruku_error "Table head does not have #{num_columns} columns: \n#{head.inspect}"
531
+ tell_user "I will ignore this table."
532
+ # XXX try to recover
533
+ return md_br()
534
+ end
535
+
536
+ rows = []
537
+
538
+ while src.cur_line && src.cur_line =~ /\|/
539
+ row = split_cells(src.shift_line).map{|s|
540
+ md_el(:cell, parse_lines_as_span([s]))}
541
+ if head.size != num_columns
542
+ maruku_error "Row does not have #{num_columns} columns: \n#{row.inspect}"
543
+ tell_user "I will ignore this table."
544
+ # XXX try to recover
545
+ return md_br()
546
+ end
547
+ rows << row
548
+ end
549
+
550
+ children = (head+rows).flatten
551
+ return md_el(:table, children, {:align => align})
552
+ end
553
+
554
+ # If current line is text, a definition list is coming
555
+ # if 1) text,empty,[text,empty]*,definition
556
+
557
+ def eventually_comes_a_def_list(src)
558
+ future = src.tell_me_the_future
559
+ ok = future =~ %r{^t+e?d}x
561
560
  # puts "future: #{future} - #{ok}"
562
- ok
563
- end
561
+ ok
562
+ end
564
563
 
565
564
 
566
- def read_definition(src)
567
- # Read one or more terms
568
- terms = []
569
- while src.cur_line && src.cur_line.md_type == :text
570
- terms << md_el(:definition_term, parse_lines_as_span([src.shift_line]))
571
- end
565
+ def read_definition(src)
566
+ # Read one or more terms
567
+ terms = []
568
+ while src.cur_line && src.cur_line.md_type == :text
569
+ terms << md_el(:definition_term, parse_lines_as_span([src.shift_line]))
570
+ end
572
571
  # dbg_describe_ary(terms, 'DT')
573
572
 
574
- want_my_paragraph = false
573
+ want_my_paragraph = false
575
574
 
576
- raise "Chunky Bacon!" if not src.cur_line
575
+ raise "Chunky Bacon!" if not src.cur_line
577
576
 
578
- # one optional empty
579
- if src.cur_line.md_type == :empty
580
- want_my_paragraph = true
581
- src.shift_line
582
- end
577
+ # one optional empty
578
+ if src.cur_line.md_type == :empty
579
+ want_my_paragraph = true
580
+ src.shift_line
581
+ end
583
582
 
584
- raise "Chunky Bacon!" if src.cur_line.md_type != :definition
583
+ raise "Chunky Bacon!" if src.cur_line.md_type != :definition
585
584
 
586
- # Read one or more definitions
587
- definitions = []
588
- while src.cur_line && src.cur_line.md_type == :definition
589
- parent_offset = src.cur_index
585
+ # Read one or more definitions
586
+ definitions = []
587
+ while src.cur_line && src.cur_line.md_type == :definition
588
+ parent_offset = src.cur_index
590
589
 
591
- first = src.shift_line
592
- first =~ Definition
593
- first = $1
590
+ first = src.shift_line
591
+ first =~ Definition
592
+ first = $1
594
593
 
595
- # I know, it's ugly!!!
594
+ # I know, it's ugly!!!
596
595
 
597
- lines, w_m_p =
598
- read_indented_content(src,4, [:definition], :definition)
599
- want_my_paragraph ||= w_m_p
596
+ lines, w_m_p =
597
+ read_indented_content(src,4, [:definition], :definition)
598
+ want_my_paragraph ||= w_m_p
600
599
 
601
- lines.unshift first
600
+ lines.unshift first
602
601
 
603
602
  # dbg_describe_ary(lines, 'DD')
604
- src2 = LineSource.new(lines, src, parent_offset)
605
- children = parse_blocks(src2)
606
- definitions << md_el(:definition_data, children)
607
- end
608
-
609
- return md_el(:definition, terms+definitions, {
610
- :terms => terms,
611
- :definitions => definitions,
612
- :want_my_paragraph => want_my_paragraph})
613
- end
603
+ src2 = LineSource.new(lines, src, parent_offset)
604
+ children = parse_blocks(src2)
605
+ definitions << md_el(:definition_data, children)
606
+ end
607
+
608
+ return md_el(:definition, terms+definitions, {
609
+ :terms => terms,
610
+ :definitions => definitions,
611
+ :want_my_paragraph => want_my_paragraph})
612
+ end
614
613
  end # BlockLevelParser
615
614
  end # MaRuKu
616
615
  end