Class: Kramdown::Parser::Kramdown
- Inherits:
-
Object
- Object
- Kramdown::Parser::Kramdown
- Defined in:
- lib/monkey_patches/kramdown/parser/kramdown/html.rb,
lib/monkey_patches/kramdown/parser/kramdown/link.rb,
lib/monkey_patches/kramdown/parser/kramdown/list.rb,
lib/monkey_patches/kramdown/parser/kramdown/header.rb,
lib/monkey_patches/kramdown/parser/kramdown/autolink.rb,
lib/monkey_patches/kramdown/parser/kramdown/emphasis.rb,
lib/monkey_patches/kramdown/parser/kramdown/footnote.rb,
lib/monkey_patches/kramdown/parser/kramdown/code_span.rb,
lib/monkey_patches/kramdown/parser/kramdown/paragraph.rb,
lib/monkey_patches/kramdown/parser/kramdown/blockquote.rb,
lib/monkey_patches/kramdown/parser/kramdown/code_block.rb,
lib/monkey_patches/kramdown/parser/kramdown/escaped_chars.rb,
lib/monkey_patches/kramdown/parser/kramdown/horizontal_rule.rb,
lib/monkey_patches/kramdown/parser/kramdown/typographic_symbol.rb
Direct Known Subclasses
Instance Method Summary collapse
-
#add_link(el, href, title, alt_text = nil, ial = nil, link_id = nil) ⇒ Object
This helper methods adds the approriate attributes to the element
el
of typea
orimg
and the element itself to the @tree. -
#parse_atx_header ⇒ Object
Parse the Atx header at the current location.
-
#parse_autolink ⇒ Object
Parse the autolink at the current location.
-
#parse_blockquote ⇒ Object
Parse the blockquote at the current location.
-
#parse_codeblock ⇒ Object
Parse the indented codeblock at the current location.
-
#parse_codeblock_fenced ⇒ Object
Parse the fenced codeblock at the current location.
-
#parse_codespan ⇒ Object
Parse the codespan at the current scanner location.
-
#parse_emphasis ⇒ Object
Parse the emphasis at the current location.
-
#parse_escaped_chars ⇒ Object
Parse the backslash-escaped character at the current location.
-
#parse_footnote_marker ⇒ Object
Parse the footnote marker at the current location.
-
#parse_horizontal_rule ⇒ Object
Parse the horizontal rule at the current location.
- #parse_link ⇒ Object
- #parse_list ⇒ Object
-
#parse_paragraph ⇒ Object
Parse the paragraph at the current location.
-
#parse_setext_header ⇒ Object
Parse the Setext header at the current location.
-
#parse_span_html ⇒ Object
Parse the HTML at the current position as span-level HTML.
-
#parse_typographic_syms ⇒ Object
Parse the typographic symbols at the current location.
Instance Method Details
#add_link(el, href, title, alt_text = nil, ial = nil, link_id = nil) ⇒ Object
This helper methods adds the approriate attributes to the element el
of type a
or img
and the element itself to the @tree.
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# File 'lib/monkey_patches/kramdown/parser/kramdown/link.rb', line 6 def add_link(el, href, title, alt_text = nil, ial = nil, link_id = nil) el.[:ial] = ial el.[:link_id] = link_id update_attr_with_ial(el.attr, ial) if ial if el.type == :a el.attr['href'] = href el.[:link_text] = alt_text else el.attr['src'] = href el.attr['alt'] = alt_text el.children.clear end el.attr['title'] = title if title @tree.children << el end |
#parse_atx_header ⇒ Object
Parse the Atx header at the current location.
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/monkey_patches/kramdown/parser/kramdown/header.rb', line 21 def parse_atx_header return false if !after_block_boundary? start_line_number = @src.current_line_number @src.check(ATX_HEADER_MATCH) level, text, id = @src[1], @src[2].to_s.strip, @src[3] return false if text.empty? @src.pos += @src.matched_size el = new_block_el(:header, nil, nil, :level => level.length, :raw_text => text, :location => start_line_number, :original_text => @src[0].chomp) add_text(text, el) el.attr['id'] = id if id @tree.children << el true end |
#parse_autolink ⇒ Object
Parse the autolink at the current location.
6 7 8 9 10 11 12 13 |
# File 'lib/monkey_patches/kramdown/parser/kramdown/autolink.rb', line 6 def parse_autolink start_line_number = @src.current_line_number @src.pos += @src.matched_size href = (@src[2].nil? ? "mailto:#{@src[1]}" : @src[1]) el = Element.new(:a, nil, {'href' => href}, :location => start_line_number, :raw_text => @src[0].dup) add_text(@src[1].sub(/^mailto:/, ''), el) @tree.children << el end |
#parse_blockquote ⇒ Object
Parse the blockquote at the current location.
6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# File 'lib/monkey_patches/kramdown/parser/kramdown/blockquote.rb', line 6 def parse_blockquote start_line_number = @src.current_line_number result = @src.scan(PARAGRAPH_MATCH) while !@src.match?(self.class::LAZY_END) result << @src.scan(PARAGRAPH_MATCH) end raw_text = result.dup result.gsub!(BLOCKQUOTE_START, '') el = new_block_el(:blockquote, nil, nil, :location => start_line_number, :raw_text => raw_text) @tree.children << el parse_blocks(el, result) true end |
#parse_codeblock ⇒ Object
Parse the indented codeblock at the current location.
6 7 8 9 10 11 12 13 |
# File 'lib/monkey_patches/kramdown/parser/kramdown/code_block.rb', line 6 def parse_codeblock start_line_number = @src.current_line_number data = @src.scan(self.class::CODEBLOCK_MATCH) data.gsub!(/\n( {0,3}\S)/, ' \\1') data.gsub!(INDENT, '') @tree.children << new_block_el(:codeblock, data, nil, :location => start_line_number, :raw_text => @src.matched.dup) true end |
#parse_codeblock_fenced ⇒ Object
Parse the fenced codeblock at the current location.
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/monkey_patches/kramdown/parser/kramdown/code_block.rb', line 16 def parse_codeblock_fenced if @src.check(self.class::FENCED_CODEBLOCK_MATCH) start_line_number = @src.current_line_number @src.pos += @src.matched_size el = new_block_el(:codeblock, @src[5], nil, :location => start_line_number, :raw_text => @src.matched.dup) lang = @src[3].to_s.strip unless lang.empty? el.[:lang] = lang el.attr['class'] = "language-#{@src[4]}" end @tree.children << el true else false end end |
#parse_codespan ⇒ Object
Parse the codespan at the current scanner location.
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/monkey_patches/kramdown/parser/kramdown/code_span.rb', line 5 def parse_codespan start_line_number = @src.current_line_number result = @src.scan(CODESPAN_DELIMITER) simple = (result.length == 1) saved_pos = @src.save_pos if simple && @src.pre_match =~ /\s\Z/ && @src.match?(/\s/) add_text(result) return end if text = @src.scan_until(/#{result}/) raw_text = result + text text.sub!(/#{result}\Z/, '') if !simple text = text[1..-1] if text[0..0] == ' ' text = text[0..-2] if text[-1..-1] == ' ' end @tree.children << Element.new(:codespan, text, nil, :location => start_line_number, :raw_text => raw_text) else @src.revert_pos(saved_pos) add_text(result) end end |
#parse_emphasis ⇒ Object
Parse the emphasis at the current location.
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/monkey_patches/kramdown/parser/kramdown/emphasis.rb', line 6 def parse_emphasis start_line_number = @src.current_line_number saved_pos = @src.save_pos result = @src.scan(EMPHASIS_START) element = (result.length == 2 ? :strong : :em) type = result[0..0] if (type == '_' && @src.pre_match =~ /[[:alpha:]-]\z/) || @src.check(/\s/) || @tree.type == element || @stack.any? { |el, _| el.type == element } add_text(result) return end sub_parse = lambda do |delim, elem| el = Element.new(elem, nil, nil, :location => start_line_number, :delim => delim) stop_re = /#{Regexp.escape(delim)}/ found = parse_spans(el, stop_re) do (@src.pre_match[-1, 1] !~ /\s/) && (elem != :em || !@src.match?(/#{Regexp.escape(delim*2)}(?!#{Regexp.escape(delim)})/)) && (type != '_' || !@src.match?(/#{Regexp.escape(delim)}[[:alnum:]]/)) && el.children.size > 0 end [found, el, stop_re] end found, el, stop_re = sub_parse.call(result, element) if !found && element == :strong && @tree.type != :em @src.revert_pos(saved_pos) @src.pos += 1 found, el, stop_re = sub_parse.call(type, :em) end if found @src.scan(stop_re) @tree.children << el else @src.revert_pos(saved_pos) @src.pos += result.length add_text(result) end end |
#parse_escaped_chars ⇒ Object
Parse the backslash-escaped character at the current location.
6 7 8 9 |
# File 'lib/monkey_patches/kramdown/parser/kramdown/escaped_chars.rb', line 6 def parse_escaped_chars @src.pos += @src.matched_size add_text(@src[0]) end |
#parse_footnote_marker ⇒ Object
Parse the footnote marker at the current location.
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/monkey_patches/kramdown/parser/kramdown/footnote.rb', line 5 def parse_footnote_marker start_line_number = @src.current_line_number @src.pos += @src.matched_size fn_def = @footnotes[@src[1]] if fn_def if fn_def[:eob] update_attr_with_ial(fn_def[:eob].attr, fn_def[:eob].[:ial] || {}) fn_def[:attr] = fn_def[:eob].attr fn_def[:options] = fn_def[:eob]. fn_def.delete(:eob) end fn_def[:marker] ||= [] fn_def[:marker].push(Element.new(:footnote, fn_def[:content], fn_def[:attr], fn_def[:options].merge(:name => @src[1], :location => start_line_number, :raw_text => @src[0].dup))) @tree.children << fn_def[:marker].last else warning("Footnote definition for '#{@src[1]}' not found on line #{start_line_number}") add_text(@src.matched) end end |
#parse_horizontal_rule ⇒ Object
Parse the horizontal rule at the current location.
6 7 8 9 10 11 |
# File 'lib/monkey_patches/kramdown/parser/kramdown/horizontal_rule.rb', line 6 def parse_horizontal_rule start_line_number = @src.current_line_number @src.pos += @src.matched_size @tree.children << new_block_el(:hr, nil, nil, :location => start_line_number, raw_text: @src[0].dup) true end |
#parse_link ⇒ Object
23 24 25 26 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 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/monkey_patches/kramdown/parser/kramdown/link.rb', line 23 def parse_link start_line_number = @src.current_line_number result = @src.scan(LINK_START) raw_text = result.dup cur_pos = @src.pos saved_pos = @src.save_pos link_type = (result =~ /^!/ ? :img : :a) # no nested links allowed if link_type == :a && (@tree.type == :img || @tree.type == :a || @stack.any? { |t, s| t && (t.type == :img || t.type == :a) }) add_text(result) return end el = Element.new(link_type, nil, nil, :location => start_line_number) count = 1 found = parse_spans(el, LINK_BRACKET_STOP_RE) do count = count + (@src[1] ? -1 : 1) count - el.children.select { |c| c.type == :img }.size == 0 end unless found @src.revert_pos(saved_pos) add_text(result) return end alt_text = extract_string(cur_pos...@src.pos, @src).gsub(ESCAPED_CHARS, '\1') raw_text << alt_text.dup @src.scan(LINK_BRACKET_STOP_RE) raw_text << @src[0].dup # reference style link or no link url if @src.scan(LINK_INLINE_ID_RE) || !@src.check(/\(/) link_id = normalize_link_id(@src[1] || alt_text) if @link_defs.has_key?(link_id) add_link(el, @link_defs[link_id][0], @link_defs[link_id][1], alt_text, @link_defs[link_id][2] && @link_defs[link_id][2].[:ial], link_id) else warning("No link definition for link ID '#{link_id}' found on line #{start_line_number}") @src.revert_pos(saved_pos) add_text(result) end raw_text << @src[0].dup unless @src[0].nil? el.[:raw_text] = raw_text return end # link url in parentheses if @src.scan(/\(<(.*?)>/) link_url = @src[1] if @src.scan(/\)/) raw_text += "(<#{link_url}>)" el.[:raw_text] = raw_text add_link(el, link_url, nil, alt_text) return end else link_url = '' nr_of_brackets = 0 while temp = @src.scan_until(LINK_PAREN_STOP_RE) link_url << temp if @src[2] nr_of_brackets -= 1 break if nr_of_brackets == 0 elsif @src[1] nr_of_brackets += 1 else break end end raw_text << link_url.dup link_url = link_url[1..-2] link_url.strip! if nr_of_brackets == 0 el.[:raw_text] = raw_text add_link(el, link_url, nil, alt_text) return end end if @src.scan(LINK_INLINE_TITLE_RE) raw_text << @src[0].dup el.[:raw_text] = raw_text add_link(el, link_url, @src[0][0..-2], alt_text) else @src.revert_pos(saved_pos) add_text(result) end end |
#parse_list ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 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 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/monkey_patches/kramdown/parser/kramdown/list.rb', line 4 def parse_list start_line_number = @src.current_line_number type, list_start_re = (@src.check(LIST_START_UL) ? [:ul, LIST_START_UL] : [:ol, LIST_START_OL]) list = new_block_el(type, nil, nil, :location => start_line_number, :raw_text => "") item = nil content_re, lazy_re, indent_re = nil eob_found = false nested_list_found = false last_is_blank = false while !@src.eos? start_line_number = @src.current_line_number if last_is_blank && @src.check(HR_START) break elsif @src.scan(EOB_MARKER) eob_found = true break elsif @src.scan(list_start_re) item = Element.new(:li, nil, nil, :location => start_line_number, :raw_text => @src.matched.dup) list.[:raw_text] += @src[0] item.value, indentation, content_re, lazy_re, indent_re = parse_first_list_line(@src[1].length, @src[2]) list.children << item item.value.sub!(self.class::LIST_ITEM_IAL) do |match| parse_attribute_list($1, item.[:ial] ||= {}) '' end list_start_re = (type == :ul ? /^( {0,#{[3, indentation - 1].min}}[+*-])([\t| ].*?\n)/ : /^( {0,#{[3, indentation - 1].min}}\d+\.)([\t| ].*?\n)/) nested_list_found = (item.value =~ LIST_START) last_is_blank = false item.value = [item.value] elsif (result = @src.scan(content_re)) || (!last_is_blank && (result = @src.scan(lazy_re))) result.sub!(/^(\t+)/) { " " * 4 * $1.length } indentation_found = result.sub!(indent_re, '') if !nested_list_found && indentation_found && result =~ LIST_START item.value << '' nested_list_found = true elsif nested_list_found && !indentation_found && result =~ LIST_START result = " " * (indentation + 4) << result end item.[:raw_text] += @src[0] list.[:raw_text] += @src[0] item.value.last << result last_is_blank = false elsif result = @src.scan(BLANK_LINE) nested_list_found = true last_is_blank = true item.[:raw_text] += @src.matched list.[:raw_text] += @src.matched if list.children.last.type != :blank bl = new_block_el(:blank, [@src.matched.dup]) bl.[:raw_text] = @src.matched.dup list.children << bl end item.value.last << result else break end end list.[:raw_text].gsub!(/\R{2,}\z/, "\n") list.children.pop if list.children.last.type == :blank @tree.children << list last = nil list.children.each do |it| temp = Element.new(:temp, nil, nil, :location => it.[:location]) env = save_env location = it.[:location] it.value.each do |val| @src = ::Kramdown::Utils::StringScanner.new(val, location) parse_blocks(temp) location = @src.current_line_number end restore_env(env) it.children = temp.children it.value = nil next if it.children.size == 0 # Handle the case where an EOB marker is inserted by a block IAL for the first paragraph it.children.delete_at(1) if it.children.first.type == :p && it.children.length >= 2 && it.children[1].type == :eob && it.children.first.[:ial] if it.children.first.type == :p && (it.children.length < 2 || it.children[1].type != :blank || (it == list.children.last && it.children.length == 2 && !eob_found)) && (list.children.last != it || list.children.size == 1 || list.children[0..-2].any? { |cit| !cit.children.first || cit.children.first.type != :p || cit.children.first.[:transparent] }) it.children.first.children.first.value << "\n" if it.children.size > 1 && it.children[1].type != :blank it.children.first.[:transparent] = true end if it.children.last.type == :blank last = it.children.pop else last = nil end end @tree.children << last if !last.nil? && !eob_found true end |
#parse_paragraph ⇒ Object
Parse the paragraph at the current location.
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/monkey_patches/kramdown/parser/kramdown/paragraph.rb', line 6 def parse_paragraph start_line_number = @src.current_line_number result = @src.scan(PARAGRAPH_MATCH) while !@src.match?(paragraph_end) result << @src.scan(PARAGRAPH_MATCH) end raw_text = result.dup result.rstrip! if @tree.children.last && @tree.children.last.type == :p @tree.children.last.[:raw_text] += result @tree.children.last.children.first.value << "\n" << result else @tree.children << new_block_el(:p, nil, nil, :location => start_line_number, raw_text: raw_text) result.lstrip! add_text(result, @tree.children.last) end true end |
#parse_setext_header ⇒ Object
Parse the Setext header at the current location.
6 7 8 9 10 11 12 13 14 15 16 17 18 |
# File 'lib/monkey_patches/kramdown/parser/kramdown/header.rb', line 6 def parse_setext_header return false if !after_block_boundary? start_line_number = @src.current_line_number @src.pos += @src.matched_size text, id, level = @src[1], @src[2], @src[3] text.strip! el = new_block_el(:header, nil, nil, :level => (level == '-' ? 2 : 1), :raw_text => text, :location => start_line_number, :original_text => @src[0].chomp) add_text(text, el) el.attr['id'] = id if id @tree.children << el true end |
#parse_span_html ⇒ Object
Parse the HTML at the current position as span-level HTML.
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 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 |
# File 'lib/monkey_patches/kramdown/parser/kramdown/html.rb', line 5 def parse_span_html line = @src.current_line_number if result = @src.scan(HTML_COMMENT_RE) @tree.children << Element.new(:xml_comment, result, nil, :category => :span, :location => line) elsif result = @src.scan(HTML_INSTRUCTION_RE) @tree.children << Element.new(:xml_pi, result, nil, :category => :span, :location => line) elsif result = @src.scan(HTML_TAG_CLOSE_RE) warning("Found invalidly used HTML closing tag for '#{@src[1]}' on line #{line}") add_text(result) elsif result = @src.scan(HTML_TAG_RE) tag_name = @src[1] tag_name.downcase! if HTML_ELEMENT[tag_name.downcase] if HTML_BLOCK_ELEMENTS.include?(tag_name) warning("Found block HTML tag '#{tag_name}' in span-level text on line #{line}") add_text(result) return end attrs = parse_html_attributes(@src[2], line, HTML_ELEMENT[tag_name]) attrs.each { |name, value| value.gsub!(/\n+/, ' ') } do_parsing = (HTML_CONTENT_MODEL[tag_name] == :raw || @tree.[:content_model] == :raw ? false : @options[:parse_span_html]) if val = HTML_MARKDOWN_ATTR_MAP[attrs.delete('markdown')] if val == :block warning("Cannot use block-level parsing in span-level HTML tag (line #{line}) - using default mode") elsif val == :span do_parsing = true elsif val == :default do_parsing = HTML_CONTENT_MODEL[tag_name] != :raw elsif val == :raw do_parsing = false end end el = Element.new(:html_element, tag_name, attrs, :category => :span, :location => line, :content_model => (do_parsing ? :span : :raw), :is_closed => !!@src[4], :opening_tag => result) @tree.children << el stop_re = /<\/#{Regexp.escape(tag_name)}\s*>/ stop_re = Regexp.new(stop_re.source, Regexp::IGNORECASE) if HTML_ELEMENT[tag_name] if !@src[4] && !HTML_ELEMENTS_WITHOUT_BODY.include?(el.value) if parse_spans(el, stop_re, (do_parsing ? nil : [:span_html])) @src.scan(stop_re) else warning("Found no end tag for '#{el.value}' (line #{line}) - auto-closing it") add_text(@src.rest, el) @src.terminate end end Kramdown::Parser::Html::ElementConverter.convert(@root, el) if @options[:html_to_native] else add_text(@src.getch) end end |
#parse_typographic_syms ⇒ Object
Parse the typographic symbols at the current location.
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/monkey_patches/kramdown/parser/kramdown/typographic_symbol.rb', line 6 def parse_typographic_syms start_line_number = @src.current_line_number @src.pos += @src.matched_size val = TYPOGRAPHIC_SYMS_SUBST[@src.matched] if val.kind_of?(Symbol) @tree.children << Element.new(:typographic_sym, val, nil, :location => start_line_number, symbol: @src.matched) elsif @src.matched == '\\<<' @tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('lt'), nil, :location => start_line_number) @tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('lt'), nil, :location => start_line_number) else @tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('gt'), nil, :location => start_line_number) @tree.children << Element.new(:entity, ::Kramdown::Utils::Entities.entity('gt'), nil, :location => start_line_number) end end |