Module: MaRuKu::In::Markdown::BlockLevelParser
- Includes:
- Helpers, SpanLevelParser, Strings, REXML
- Included in:
- MDDocument
- Defined in:
- lib/maruku.rb,
lib/maruku/input/parse_doc.rb,
lib/maruku/input/linesource.rb,
lib/maruku/input/parse_block.rb
Defined Under Namespace
Classes: BlockContext, LineSource
Constant Summary
Constants included from SpanLevelParser
SpanLevelParser::CharSource, SpanLevelParser::Close_class, SpanLevelParser::EscapedCharInInlineCode, SpanLevelParser::EscapedCharInQuotes, SpanLevelParser::EscapedCharInText, SpanLevelParser::Punct_class, SpanLevelParser::R_REF_ID, SpanLevelParser::Rules, SpanLevelParser::SPACE
Constants included from Strings
Strings::Abbreviation, Strings::AttributeDefinitionList, Strings::Definition, Strings::EMailAddress, Strings::FootnoteText, Strings::HeaderWithAttributes, Strings::HeaderWithId, Strings::IncompleteLink, Strings::InlineAttributeList, Strings::LinkRegex, Strings::MightBeTableHeader, Strings::Sep, Strings::TabSize, Strings::TableSeparator
Instance Method Summary collapse
-
#eventually_comes_a_def_list(src) ⇒ Object
If current line is text, a definition list is coming if 1) text,empty,*,definition.
- #execute_code_blocks ⇒ Object
-
#expand_attribute_list(al, result) ⇒ Object
Expands an attribute list in an Hash.
-
#parse_blocks(src) ⇒ Object
Input is a LineSource.
- #parse_doc(s) ⇒ Object
-
#parse_text_as_markdown(text) ⇒ Object
Splits the string and calls parse_lines_as_markdown.
- #read_abbreviation(src) ⇒ Object
- #read_ald(src) ⇒ Object
- #read_code(src) ⇒ Object
- #read_definition(src) ⇒ Object
- #read_footnote_text(src) ⇒ Object
-
#read_header12(src) ⇒ Object
reads a header (with —– or ========).
-
#read_header3(src) ⇒ Object
reads a header like ‘#### header ####’.
-
#read_indented_content(src, indentation, break_list, item_type) ⇒ Object
This is the only ugly function in the code base.
-
#read_list_item(src) ⇒ Object
Reads one list item, either ordered or unordered.
-
#read_metadata(src) ⇒ Object
Reads a series of metadata lines with empty lines in between.
- #read_paragraph(src) ⇒ Object
- #read_quote(src) ⇒ Object
- #read_raw_html(src) ⇒ Object
- #read_ref_definition(src) ⇒ Object
- #read_table(src) ⇒ Object
- #read_xml_instruction(src, output) ⇒ Object
- #safe_execute_code(object, code) ⇒ Object
- #search_abbreviations ⇒ Object
- #split_cells(s) ⇒ Object
-
#substitute_markdown_inside_raw_html ⇒ Object
(PHP Markdown extra) Search for elements that have markdown=1 or markdown=block defined.
Methods included from SpanLevelParser
#apply_one_rule, #describe_pos, #educate, #extension_meta, #interpret_extension, #is_ial, #md_al, #merge_ial, #parse_lines_as_span, #parse_span_better, #read_attribute_list, #read_em, #read_email_el, #read_emstrong, #read_footnote_ref, #read_image, #read_inline_code, #read_inline_html, #read_link, #read_quoted, #read_quoted_or_unquoted, #read_ref_id, #read_simple, #read_span, #read_strong, #read_url, #read_url_el, #read_xml_instr_span, #unit_tests_for_attribute_lists
Methods included from Helpers
#md_abbr, #md_abbr_def, #md_ald, #md_br, #md_code, #md_codeblock, #md_el, #md_em, #md_email, #md_emstrong, #md_entity, #md_foot_ref, #md_footnote, #md_header, #md_hrule, #md_html, #md_ial, #md_im_image, #md_im_link, #md_image, #md_li, #md_link, #md_par, #md_quote, #md_ref_def, #md_strong, #md_url, #md_xml_instr
Methods included from Strings
#add_tabs, #dbg_describe_ary, #force_linebreak?, #line_md_type, #normalize_key_and_value, #num_leading_hashes, #number_of_leading_spaces, #parse_email_headers, #spaces_before_first_char, #split_lines, #strip_hashes, #strip_indent, #unquote
Instance Method Details
#eventually_comes_a_def_list(src) ⇒ Object
If current line is text, a definition list is coming if 1) text,empty,*,definition
536 537 538 539 540 541 |
# File 'lib/maruku/input/parse_block.rb', line 536 def eventually_comes_a_def_list(src) future = src.tell_me_the_future ok = future =~ %r{^t+e?d}x # puts "future: #{future} - #{ok}" ok end |
#execute_code_blocks ⇒ Object
161 162 163 164 165 166 167 168 169 170 |
# File 'lib/maruku/input/parse_doc.rb', line 161 def execute_code_blocks self.each_element(:xml_instr) do |e| if e.target == 'maruku' result = safe_execute_code(e, e.code) if result.kind_of?(String) puts "Result is : #{result.inspect}" end end end end |
#expand_attribute_list(al, result) ⇒ Object
Expands an attribute list in an Hash
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/maruku/input/parse_doc.rb', line 101 def (al, result) al.each do |k, v| case k when :class if not result[:class] result[:class] = v else result[:class] += " " + v end when :id; result[:id] = v when :ref; if self.ald[v] already = (result[:expanded_references] ||= []) if not already.include?(v) already.push v (self.ald[v], result) else already.push v maruku_error "Circular reference between labels.\n\n"+ "Label #{v.inspect} calls itself via recursion.\nThe recursion is "+ (already.map{|x| x.inspect}.join(' => ')) end else if not result[:unresolved_references] result[:unresolved_references] = v else result[:unresolved_references] << " #{v}" end # $stderr.puts "Unresolved reference #{v.inspect} (avail: #{self.ald.keys.inspect})" result[v.to_sym] = true end else result[k.to_sym]=v end end end |
#parse_blocks(src) ⇒ Object
Input is a LineSource
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/maruku/input/parse_block.rb', line 45 def parse_blocks(src) output = BlockContext.new # run state machine while src.cur_line next if check_block_extensions(src, output, src.cur_line) # Prints detected type (useful for debugging) # puts "#{src.cur_line.md_type}|#{src.cur_line}" case src.cur_line.md_type when :empty; output.push :empty src.ignore_line when :ial m = InlineAttributeList.match src.shift_line content = m[1] || "" # puts "Content: #{content.inspect}" src2 = CharSource.new(content, src) interpret_extension(src2, output, [nil]) when :ald output.push read_ald(src) when :text if src.cur_line =~ MightBeTableHeader and (src.next_line && src.next_line =~ TableSeparator) output.push read_table(src) elsif [:header1,:header2].include? src.next_line.md_type output.push read_header12(src) elsif eventually_comes_a_def_list(src) definition = read_definition(src) if output.last.kind_of?(MDElement) && output.last.node_type == :definition_list then output.last.children << definition else output.push md_el(:definition_list, [definition]) end else # Start of a paragraph output.push read_paragraph(src) end when :header2, :hrule # hrule src.shift_line output.push md_hrule() when :header3 output.push read_header3(src) when :ulist, :olist list_type = src.cur_line.md_type == :ulist ? :ul : :ol li = read_list_item(src) # append to current list if we have one if output.last.kind_of?(MDElement) && output.last.node_type == list_type then output.last.children << li else output.push md_el(list_type, [li]) end when :quote; output.push read_quote(src) when :code; e = read_code(src); output << e if e when :raw_html; e = read_raw_html(src); output << e if e when :footnote_text; output.push read_footnote_text(src) when :ref_definition; output.push read_ref_definition(src) when :abbreviation; output.push read_abbreviation(src) when :xml_instr; read_xml_instruction(src, output) when :metadata; maruku_error "Please use the new meta-data syntax: \n"+ " http://maruku.rubyforge.org/proposal.html\n", src src.ignore_line else # warn if we forgot something md_type = src.cur_line.md_type line = src.cur_line maruku_error "Ignoring line '#{line}' type = #{md_type}", src src.shift_line end end merge_ial(output, src, output) output.delete_if {|x| x.kind_of?(MDElement) && x.node_type == :ial} # get rid of empty line markers output.delete_if {|x| x == :empty} # See for each list if we can omit the paragraphs and use li_span # TODO: do this after output.each do |c| # Remove paragraphs that we can get rid of if [:ul,:ol].include? c.node_type if c.children.all? {|li| !li.want_my_paragraph} then c.children.each do |d| d.node_type = :li_span d.children = d.children[0].children end end end if c.node_type == :definition_list if c.children.all?{|defi| !defi.want_my_paragraph} then c.children.each do |definition| definition.definitions.each do |dd| dd.children = dd.children[0].children end end end end end output end |
#parse_doc(s) ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/maruku/input/parse_doc.rb', line 27 def parse_doc(s) = parse_email_headers(s) data = [:data] .delete :data self.attributes.merge! =begin maruku_doc Attribute: encoding Scope: document Summary: Encoding for the document. If the `encoding` attribute is specified, then the content will be converted from the specified encoding to UTF-8. Conversion happens using the `iconv` library. =end enc = self.attributes[:encoding] self.attributes.delete :encoding if enc && enc.downcase != 'utf-8' converted = Iconv.new('utf-8', enc).iconv(data) # puts "Data: #{data.inspect}: #{data}" # puts "Conv: #{converted.inspect}: #{converted}" data = converted end @children = parse_text_as_markdown(data) if true #markdown_extra? self.search_abbreviations self.substitute_markdown_inside_raw_html end toc = create_toc # use title if not set if not self.attributes[:title] and toc.header_element title = toc.header_element.to_s self.attributes[:title] = title # puts "Set document title to #{title}" end # save for later use self.toc = toc # Now do the attributes magic each_element do |e| # default attribute list if default = self.ald[e.node_type.to_s] (default, e.attributes) end (e.al, e.attributes) # puts "#{e.node_type}: #{e.attributes.inspect}" end =begin maruku_doc Attribute: unsafe_features Scope: global Summary: Enables execution of XML instructions. Disabled by default because of security concerns. =end if Maruku::Globals[:unsafe_features] self.execute_code_blocks # TODO: remove executed code blocks end end |
#parse_text_as_markdown(text) ⇒ Object
Splits the string and calls parse_lines_as_markdown
38 39 40 41 42 |
# File 'lib/maruku/input/parse_block.rb', line 38 def parse_text_as_markdown(text) lines = split_lines(text) src = LineSource.new(lines) return parse_blocks(src) end |
#read_abbreviation(src) ⇒ Object
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 |
# File 'lib/maruku/input/parse_block.rb', line 293 def read_abbreviation(src) if not (l=src.shift_line) =~ Abbreviation maruku_error "Bug: it's Andrea's fault. Tell him.\n#{l.inspect}" end abbr = $1 desc = $2 if (not abbr) or (abbr.size==0) maruku_error "Bad abbrev. abbr=#{abbr.inspect} desc=#{desc.inspect}" end self.abbreviations[abbr] = desc return md_abbr_def(abbr, desc) end |
#read_ald(src) ⇒ Object
154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/maruku/input/parse_block.rb', line 154 def read_ald(src) if (l=src.shift_line) =~ AttributeDefinitionList id = $1; al=$2; al = read_attribute_list(CharSource.new(al,src), context=nil, break_on=[nil]) self.ald[id] = al; return md_ald(id, al) else maruku_error "Bug Bug:\n#{l.inspect}" return nil end end |
#read_code(src) ⇒ Object
416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 |
# File 'lib/maruku/input/parse_block.rb', line 416 def read_code(src) # collect all indented lines lines = [] while src.cur_line && ([:code, :empty].include? src.cur_line.md_type) lines << strip_indent(src.shift_line, 4) end #while lines.last && (lines.last.md_type == :empty ) while lines.last && lines.last.strip.size == 0 lines.pop end while lines.first && lines.first.strip.size == 0 lines.shift end return nil if lines.empty? source = lines.join("\n") # dbg_describe_ary(lines, 'CODE') return md_codeblock(source) end |
#read_definition(src) ⇒ Object
544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 |
# File 'lib/maruku/input/parse_block.rb', line 544 def read_definition(src) # Read one or more terms terms = [] while src.cur_line && src.cur_line.md_type == :text terms << md_el(:definition_term, parse_lines_as_span([src.shift_line])) end # dbg_describe_ary(terms, 'DT') want_my_paragraph = false raise "Chunky Bacon!" if not src.cur_line # one optional empty if src.cur_line.md_type == :empty want_my_paragraph = true src.shift_line end raise "Chunky Bacon!" if src.cur_line.md_type != :definition # Read one or more definitions definitions = [] while src.cur_line && src.cur_line.md_type == :definition parent_offset = src.cur_index first = src.shift_line first =~ Definition first = $1 # I know, it's ugly!!! lines, w_m_p = read_indented_content(src,4, [:definition], :definition) want_my_paragraph ||= w_m_p lines.unshift first # dbg_describe_ary(lines, 'DD') src2 = LineSource.new(lines, src, parent_offset) children = parse_blocks(src2) definitions << md_el(:definition_data, children) end return md_el(:definition, terms+definitions, { :terms => terms, :definitions => definitions, :want_my_paragraph => want_my_paragraph}) end |
#read_footnote_text(src) ⇒ Object
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 |
# File 'lib/maruku/input/parse_block.rb', line 310 def read_footnote_text(src) parent_offset = src.cur_index first = src.shift_line if not first =~ FootnoteText maruku_error "Bug (it's Andrea's fault)" end id = $1 text = $2 # Ugly things going on inside `read_indented_content` indentation = 4 #first.size-text.size # puts "id =_#{id}_; text=_#{text}_ indent=#{indentation}" break_list = [:footnote_text] item_type = :footnote_text lines, want_my_paragraph = read_indented_content(src,indentation, break_list, item_type) # add first line if text && text.strip != "" then lines.unshift text end # dbg_describe_ary(lines, 'FOOTNOTE') src2 = LineSource.new(lines, src, parent_offset) children = parse_blocks(src2) e = md_footnote(id, children) self.footnotes[id] = e return e end |
#read_header12(src) ⇒ Object
reads a header (with —– or ========)
167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/maruku/input/parse_block.rb', line 167 def read_header12(src) line = src.shift_line.strip al = nil # Check if there is an IAL if and line =~ /^(.*)\{(.*)\}\s*$/ line = $1.strip ial = $2 al = read_attribute_list(CharSource.new(ial,src), context=nil, break_on=[nil]) end text = parse_lines_as_span [ line ] level = src.cur_line.md_type == :header2 ? 2 : 1; src.shift_line return md_header(level, text, al) end |
#read_header3(src) ⇒ Object
reads a header like ‘#### header ####’
183 184 185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/maruku/input/parse_block.rb', line 183 def read_header3(src) line = src.shift_line.strip al = nil # Check if there is an IAL if and line =~ /^(.*)\{(.*)\}\s*$/ line = $1.strip ial = $2 al = read_attribute_list(CharSource.new(ial,src), context=nil, break_on=[nil]) end level = num_leading_hashes(line) text = parse_lines_as_span [strip_hashes(line)] return md_header(level, text, al) end |
#read_indented_content(src, indentation, break_list, item_type) ⇒ Object
This is the only ugly function in the code base. It is used to read list items, descriptions, footnote text
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 |
# File 'lib/maruku/input/parse_block.rb', line 347 def read_indented_content(src, indentation, break_list, item_type) lines =[] # collect all indented lines saw_empty = false; saw_anything_after = false while src.cur_line #puts "#{src.cur_line.md_type} #{src.cur_line.inspect}" if src.cur_line.md_type == :empty saw_empty = true lines << src.shift_line next end # after a white line if saw_empty # we expect things to be properly aligned if (ns=number_of_leading_spaces(src.cur_line)) < indentation #puts "breaking for spaces, only #{ns}: #{src.cur_line}" break end saw_anything_after = true else break if break_list.include? src.cur_line.md_type # break if src.cur_line.md_type != :text end stripped = strip_indent(src.shift_line, indentation) lines << stripped #puts "Accepted as #{stripped.inspect}" # You are only required to indent the first line of # a child paragraph. if stripped.md_type == :text while src.cur_line && (src.cur_line.md_type == :text) lines << strip_indent(src.shift_line, indentation) end end end want_my_paragraph = saw_anything_after || (saw_empty && (src.cur_line && (src.cur_line.md_type == item_type))) # dbg_describe_ary(lines, 'LI') # create a new context while lines.last && (lines.last.md_type == :empty) lines.pop end return lines, want_my_paragraph end |
#read_list_item(src) ⇒ Object
Reads one list item, either ordered or unordered.
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 |
# File 'lib/maruku/input/parse_block.rb', line 267 def read_list_item(src) parent_offset = src.cur_index item_type = src.cur_line.md_type first = src.shift_line # Ugly things going on inside `read_indented_content` indentation = spaces_before_first_char(first) break_list = [:ulist, :olist, :ial] lines, want_my_paragraph = read_indented_content(src,indentation, break_list, item_type) # add first line # Strip first '*', '-', '+' from first line stripped = first[indentation, first.size-1] lines.unshift stripped #dbg_describe_ary(lines, 'LIST ITEM ') src2 = LineSource.new(lines, src, parent_offset) children = parse_blocks(src2) with_par = want_my_paragraph || (children.size>1) return md_li(children, with_par) end |
#read_metadata(src) ⇒ Object
Reads a series of metadata lines with empty lines in between
442 443 444 445 446 447 448 449 450 451 452 |
# File 'lib/maruku/input/parse_block.rb', line 442 def (src) hash = {} while src.cur_line case src.cur_line.md_type when :empty; src.shift_line when :metadata; hash.merge! (src.shift_line) else break end end hash end |
#read_paragraph(src) ⇒ Object
244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 |
# File 'lib/maruku/input/parse_block.rb', line 244 def read_paragraph(src) lines = [] while src.cur_line # :olist does not break case t = src.cur_line.md_type when :quote,:header3,:empty,:raw_html,:ref_definition,:ial,:xml_instr break when :olist,:ulist break if src.next_line.md_type == t end break if src.cur_line.strip.size == 0 break if [:header1,:header2].include? src.next_line.md_type break if any_matching_block_extension?(src.cur_line) lines << src.shift_line end # dbg_describe_ary(lines, 'PAR') children = parse_lines_as_span(lines, src) return md_par(children) end |
#read_quote(src) ⇒ Object
401 402 403 404 405 406 407 408 409 410 411 412 413 414 |
# File 'lib/maruku/input/parse_block.rb', line 401 def read_quote(src) parent_offset = src.cur_index lines = [] # collect all indented lines while src.cur_line && src.cur_line.md_type == :quote lines << unquote(src.shift_line) end # dbg_describe_ary(lines, 'QUOTE') src2 = LineSource.new(lines, src, parent_offset) children = parse_blocks(src2) return md_quote(children) end |
#read_raw_html(src) ⇒ Object
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 |
# File 'lib/maruku/input/parse_block.rb', line 226 def read_raw_html(src) h = HTMLHelper.new begin h.eat_this(l=src.shift_line) # puts "\nBLOCK:\nhtml -> #{l.inspect}" while src.cur_line and not h.is_finished? l=src.shift_line # puts "html -> #{l.inspect}" h.eat_this "\n"+l end rescue Exception => e ex = e.inspect + e.backtrace.join("\n") maruku_error "Bad block-level HTML:\n#{add_tabs(ex,1,'|')}\n", src end raw_html = h.stuff_you_read return md_html(raw_html) end |
#read_ref_definition(src) ⇒ Object
455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 |
# File 'lib/maruku/input/parse_block.rb', line 455 def read_ref_definition(src) line = src.shift_line # if link is incomplete, shift next line if src.cur_line && (src.cur_line.md_type != :ref_definition) && ([1,2,3].include? number_of_leading_spaces(src.cur_line) ) line += " "+ src.shift_line end # puts "total= #{line}" match = LinkRegex.match(line) if not match error "Link does not respect format: '#{line}'" end id = match[1]; url = match[2]; title = match[3]; id = id.strip.downcase.gsub(' ','_') hash = self.refs[id] = {:url=>url,:title=>title} stuff=match[4] if stuff stuff.split.each do |couple| # puts "found #{couple}" k, v = couple.split('=') v ||= "" if v[0,1]=='"' then v = v[1, v.size-2] end # puts "key:_#{k}_ value=_#{v}_" hash[k.to_sym] = v end end # puts hash.inspect return md_ref_def(id, url, ={:title=>title}) end |
#read_table(src) ⇒ Object
493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 |
# File 'lib/maruku/input/parse_block.rb', line 493 def read_table(src) def split_cells(s) s.strip.split('|').select{|x|x.strip.size>0}.map{|x|x.strip} end head = split_cells(src.shift_line).map{|s| md_el(:head_cell, parse_lines_as_span([s])) } separator=split_cells(src.shift_line) align = separator.map { |s| s =~ Sep if $1 and $2 then :center elsif $2 then :right else :left end } num_columns = align.size if head.size != num_columns maruku_error "Table head does not have #{num_columns} columns: \n#{head.inspect}" tell_user "I will ignore this table." # XXX try to recover return md_br() end rows = [] while src.cur_line && src.cur_line =~ /\|/ row = split_cells(src.shift_line).map{|s| md_el(:cell, parse_lines_as_span([s]))} if head.size != num_columns maruku_error "Row does not have #{num_columns} columns: \n#{row.inspect}" tell_user "I will ignore this table." # XXX try to recover return md_br() end rows << row end children = (head+rows).flatten return md_el(:table, children, {:align => align}) end |
#read_xml_instruction(src, output) ⇒ Object
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/maruku/input/parse_block.rb', line 197 def read_xml_instruction(src, output) m = /^\s*<\?((\w+)\s*)?(.*)$/.match src.shift_line raise "BugBug" if not m target = m[2] || '' code = m[3] until code =~ /\?>/ code += "\n"+src.shift_line end if not code =~ (/\?>\s*$/) garbage = (/\?>(.*)$/.match(code))[1] maruku_error "Trailing garbage on last line: #{garbage.inspect}:\n"+ add_tabs(code, 1, '|'), src end code.gsub!(/\?>\s*$/, '') if target == 'mrk' && MaRuKu::Globals[:unsafe_features] result = safe_execute_code(self, code) if result if result.kind_of? String raise "Not expected" else output.push *result end end else output.push md_xml_instr(target, code) end end |
#safe_execute_code(object, code) ⇒ Object
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/maruku/input/parse_doc.rb', line 139 def safe_execute_code(object, code) begin return object.instance_eval(code) rescue Exception => e maruku_error "Exception while executing this:\n"+ add_tabs(code, 1, ">")+ "\nThe error was:\n"+ add_tabs(e.inspect+"\n"+e.caller.join("\n"), 1, "|") rescue RuntimeError => e maruku_error "2: Exception while executing this:\n"+ add_tabs(code, 1, ">")+ "\nThe error was:\n"+ add_tabs(e.inspect, 1, "|") rescue SyntaxError => e maruku_error "2: Exception while executing this:\n"+ add_tabs(code, 1, ">")+ "\nThe error was:\n"+ add_tabs(e.inspect, 1, "|") end nil end |
#search_abbreviations ⇒ Object
172 173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/maruku/input/parse_doc.rb', line 172 def search_abbreviations self.abbreviations.each do |abbrev, title| reg = Regexp.new(Regexp.escape(abbrev)) self.replace_each_string do |s| if m = reg.match(s) e = md_abbr(abbrev.dup, title ? title.dup : nil) [m.pre_match, e, m.post_match] else s end end end end |
#split_cells(s) ⇒ Object
495 496 497 |
# File 'lib/maruku/input/parse_block.rb', line 495 def split_cells(s) s.strip.split('|').select{|x|x.strip.size>0}.map{|x|x.strip} end |
#substitute_markdown_inside_raw_html ⇒ Object
(PHP Markdown extra) Search for elements that have markdown=1 or markdown=block defined
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/maruku/input/parse_doc.rb', line 189 def substitute_markdown_inside_raw_html self.each_element(:raw_html) do |e| doc = e.instance_variable_get :@parsed_html if doc # valid html # parse block-level markdown elements in these HTML tags = ['div'] # use xpath to find elements with 'markdown' attribute XPath.match(doc, "//*[attribute::markdown]" ).each do |e| # puts "Found #{e}" # should we parse block-level or span-level? parse_blocks = (e.attributes['markdown'] == 'block') || .include?(e.name) # remove 'markdown' attribute e.delete_attribute 'markdown' # Select all text elements of e XPath.match(e, "//text()" ).each { |original_text| s = original_text.value.strip if s.size > 0 el = md_el(:dummy, parse_blocks ? parse_text_as_markdown(s) : parse_lines_as_span([s]) ) p = original_text.parent el.children_to_html.each do |x| p.insert_before(original_text, x) end p.delete(original_text) end } end end end end |