Class: Coradoc::Markdown::Parser::InlineParser
- Inherits:
-
Parslet::Parser
- Object
- Parslet::Parser
- Coradoc::Markdown::Parser::InlineParser
- Defined in:
- lib/coradoc/markdown/parser/inline_parser.rb
Instance Method Summary collapse
- #build_delim_stack(tree) ⇒ Object
- #can_close_emphasis(elem) ⇒ Object
- #can_open_emphasis(elem) ⇒ Object
- #lookup_entity(s) ⇒ Object
- #parse(io, options = {}) ⇒ Object
- #process_code(s) ⇒ Object
- #process_emphasis(tree) ⇒ Object
- #rule_of_three(opener, closer) ⇒ Object
- #unicode_codepoint(base, s) ⇒ Object
- #unicode_dec(s) ⇒ Object
- #unicode_hex(s) ⇒ Object
- #used_delims_to_text(elems) ⇒ Object
Instance Method Details
#build_delim_stack(tree) ⇒ Object
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/coradoc/markdown/parser/inline_parser.rb', line 183 def build_delim_stack(tree) delim_stack = [] tree.each_with_index do |elem, idx| next unless elem.is_a?(Hash) || elem.length != 1 key = elem.first.first if %i[rsp rpp rfp].include?(key) outer_key = key tree[idx] = elem = elem[key] key = elem.first.first end next unless %i[bfdr lfdr rfdr nfdr].include?(key) delim_stack << idx # pp elem elem[:char] = elem[key].to_s[0] elem[:length] = elem[key].length elem[:left_flanking] = %i[bfdr lfdr].include?(key) elem[:right_flanking] = %i[bfdr rfdr].include?(key) elem[:preceded_by_punc] = %i[rsp rpp].include?(outer_key) elem[:followed_by_punc] = %i[rsp rfp].include?(outer_key) # elem[:active] = true end # pp delim_stack delim_stack end |
#can_close_emphasis(elem) ⇒ Object
156 157 158 159 160 161 |
# File 'lib/coradoc/markdown/parser/inline_parser.rb', line 156 def can_close_emphasis(elem) return false unless elem[:right_flanking] return true unless elem[:char] == '_' !elem[:left_flanking] || (elem[:left_flanking] && elem[:followed_by_punc]) end |
#can_open_emphasis(elem) ⇒ Object
149 150 151 152 153 154 |
# File 'lib/coradoc/markdown/parser/inline_parser.rb', line 149 def can_open_emphasis(elem) return false unless elem[:left_flanking] return true unless elem[:char] == '_' !elem[:right_flanking] || (elem[:right_flanking] && elem[:preceded_by_punc]) end |
#lookup_entity(s) ⇒ Object
35 36 37 |
# File 'lib/coradoc/markdown/parser/inline_parser.rb', line 35 def lookup_entity(s) HTML_ENTITIES[s.to_s] || "&#{s};" end |
#parse(io, options = {}) ⇒ Object
268 269 270 |
# File 'lib/coradoc/markdown/parser/inline_parser.rb', line 268 def parse(io, = {}) process_emphasis(super(io, )) end |
#process_code(s) ⇒ Object
39 40 41 42 43 44 45 |
# File 'lib/coradoc/markdown/parser/inline_parser.rb', line 39 def process_code(s) s = s.to_s s.tr!("\n", ' ') return s.slice(1, s.length - 2) if s.length > 2 && s.start_with?(' ') && s.end_with?(' ') s end |
#process_emphasis(tree) ⇒ Object
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 |
# File 'lib/coradoc/markdown/parser/inline_parser.rb', line 210 def process_emphasis(tree) delim_stack = build_delim_stack(tree) cur_pos = 0 openers_bottom = { '*' => 0, '_' => 0 } while (closer_offset = delim_stack[cur_pos..].index { |i| can_close_emphasis(tree[i]) }) # puts "-----" # pp tree # puts "clofset #{closer_offset} -> cur_pos #{closer_offset + cur_pos}" cur_pos += closer_offset closer = tree[closer_idx = delim_stack[cur_pos]] # puts "closer:#{cur_pos}, #{closer}" # look back - in reverse? opener_bottom = openers_bottom[closer[:char]] opener_to_cur = delim_stack.slice(opener_bottom, cur_pos - opener_bottom) # puts "obottom #{opener_bottom} len #{cur_pos - opener_bottom} -> opener_to_cur #{opener_to_cur}" opener_offset = (opener_to_cur || []).rindex do |i| can_open_emphasis(tree[i]) && tree[i][:char] == closer[:char] && rule_of_three(tree[i], closer) end # puts "opener:#{opener_offset}" if opener_offset opener = tree[opener_idx = delim_stack[opener_bottom + opener_offset]] strong = opener[:length] > 1 && closer[:length] > 1 # pp opener contents_range = (opener_idx + 1)..(closer_idx - 1) # puts "crange #{contents_range} size #{contents_range.size}" contents = used_delims_to_text(tree.slice!(contents_range)) tree.insert(opener_idx + 1, { (strong ? :strong : :emph) => contents }) middle = (opener_bottom + opener_offset + 1)..(cur_pos - 1) delim_stack.slice!(middle) # puts "slice middle #{middle} -> #{delim_stack}" delim_stack.map! { |i| i <= opener_idx ? i : (i - contents_range.size + 1) } # puts "slice map <dstack.map!> #{delim_stack}" cur_pos -= middle.size if (opener[:length] -= strong ? 2 : 1).zero? delim_stack.slice!(opener_bottom + opener_offset) cur_pos -= 1 # puts "slice opener #{opener_bottom + opener_offset} -> #{delim_stack} @#{cur_pos}" end if (closer[:length] -= strong ? 2 : 1).zero? delim_stack.slice!(cur_pos) # puts "slice closer #{cur_pos} -> #{delim_stack}" end else openers_bottom[closer[:chr]] = cur_pos - 1 if can_open_emphasis(closer) cur_pos += 1 else delim_stack.slice!(cur_pos) # puts "nopener slice #{cur_pos} -> #{delim_stack}" end end end # puts "----------" used_delims_to_text(tree) # puts "----------" # pp x end |
#rule_of_three(opener, closer) ⇒ Object
163 164 165 166 167 168 169 |
# File 'lib/coradoc/markdown/parser/inline_parser.rb', line 163 def rule_of_three(opener, closer) return true unless (can_open_emphasis(opener) && can_close_emphasis(opener)) || (can_open_emphasis(closer) && can_close_emphasis(closer)) ((opener[:length] % 3).zero? && (closer[:length] % 3).zero?) || (opener[:length] + closer[:length]) % 3 != 0 end |
#unicode_codepoint(base, s) ⇒ Object
18 19 20 21 22 23 24 25 |
# File 'lib/coradoc/markdown/parser/inline_parser.rb', line 18 def unicode_codepoint(base, s) i = s.to_s.to_i(base) return "\uFFFD" if i.zero? i.chr(Encoding::UTF_8) rescue RangeError "\uFFFD" end |
#unicode_dec(s) ⇒ Object
27 28 29 |
# File 'lib/coradoc/markdown/parser/inline_parser.rb', line 27 def unicode_dec(s) unicode_codepoint(10, s) end |
#unicode_hex(s) ⇒ Object
31 32 33 |
# File 'lib/coradoc/markdown/parser/inline_parser.rb', line 31 def unicode_hex(s) unicode_codepoint(16, s) end |
#used_delims_to_text(elems) ⇒ Object
171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/coradoc/markdown/parser/inline_parser.rb', line 171 def used_delims_to_text(elems) elems.map do |elem| if elem.key?(:char) next if elem[:length] < 1 { text: elem[:char] * elem[:length] } else elem end end.compact end |