Class: Eprayim::Parser
- Inherits:
-
Object
- Object
- Eprayim::Parser
- Defined in:
- lib/eprayim/parser.rb
Constant Summary collapse
- HEAD_RULE =
/\A(?<level>=+)\s*(?<title>[^=#\n]*)(?:#(?<anchor>[^\n]*))?\s*/- BLOCK_RULES =
[ [:head, HEAD_RULE], [:hr, /\A---+\n*/], [:code, /\A```(?<code>.*?)```\s*$/m], [:quote, /\A(>([^\n]*)\n*)+/m], [:list, /\A(\* ([^\n]*)\n*( [^\n]*\n*)*)+/], [:list, /\A(\+ ([^\n]*)\n*( [^\n]*\n*)*)+/], ]
- INLINE_RULES =
[ [:escape, /\A\\(?<char>[\*\\`\+_~])/], [:icode, /\A`(?<content>.+?)`/], [:strong, /\A\*\*(?<content>.+?)\*\*/], [:bold, /\A\*(?<content>.+?)\*/], [:deleted,/\A~(?<content>.+?)~/], [:italic, /\A_(?<content>.+?)_/], [:link, /\A\[\s*(?<float>!|\$|\^)?(?<content>.+\s+)?(?<url>.+)\s*\]/], ]
Instance Method Summary collapse
-
#initialize(input) ⇒ Parser
constructor
————————-.
- #parse ⇒ Object
- #parse_block ⇒ Object
- #parse_inline(text) ⇒ Object
-
#peek_head ⇒ Object
peek the title and anchor without reading all the content.
Constructor Details
#initialize(input) ⇒ Parser
28 29 30 31 32 33 34 35 36 |
# File 'lib/eprayim/parser.rb', line 28 def initialize(input) @input = if input.nil? or input.is_a? String StringIO.new(input.to_s) elsif input.respond_to?(:read) input.clone else raise "#{input.inspect} should be a string." end end |
Instance Method Details
#parse ⇒ Object
54 55 56 57 58 59 60 |
# File 'lib/eprayim/parser.rb', line 54 def parse elements = [] while element = self.parse_block elements << element end return Element.new(:doc, *elements) end |
#parse_block ⇒ Object
87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/eprayim/parser.rb', line 87 def parse_block @text_tail = @input.read if @text_tail.nil? return nil if @text_tail.empty? BLOCK_RULES.each do |type, regex| m = regex.match(@text_tail) next if not m @text_tail = m.post_match return self.send("parse_#{type}", m.to_s, m) end p, @text_tail = @text_tail.split(/\n\r?\n\r?/, 2) @text_tail = '' if @text_tail.nil? return parse_para(p, nil) end |
#parse_inline(text) ⇒ Object
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/eprayim/parser.rb', line 62 def parse_inline(text) return [] if text.to_s.empty? i = 0 while not text[i..-1].empty? INLINE_RULES.each do |type, regex| m = regex.match(text[i..-1]) next if not m r = case type when :escape m[:char] when :link parse_link(m.to_s, m) when :icode Element.new(:icode, m[:content]) else Element.new(type, *parse_inline(m[:content])) end return [r, *parse_inline(m.post_match)] if i-1 < 0 return [text[0..i-1], r, *parse_inline(m.post_match)] end i += 1 end return [text[0..i]] end |
#peek_head ⇒ Object
peek the title and anchor without reading all the content.
40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/eprayim/parser.rb', line 40 def peek_head return [@title, @anchor] if @title @input.rewind @input.each_line do |line| m = line.match HEAD_RULE if m and m[:level] == '=' @title = m[:title].strip @anchor = m[:anchor].strip return [@title, @anchor] end end return [nil, nil] end |