class Rfix::Highlighter
Constants
- NEWLINE
- SPACE
- TEXT
Public Instance Methods
call(source)
click to toggle source
# File lib/rfix/highlighter.rb, line 30 def call(source) unless source.is_a?(String) raise Error, "Source must be a string" end unless source.end_with?(NEWLINE) return call(source + NEWLINE) end format(lexer.lex(source)) end
stream(tokens, &block)
click to toggle source
Calls superclass method
# File lib/rfix/highlighter.rb, line 42 def stream(tokens, &block) max_with = TTY::Screen.width lines = token_lines(tokens) pastel = Pastel.new prefix_spaces = 2 indentation = lines.map.with_index(1) do |tokens, lineno| next unless visible_lines.include?(lineno) text = tokens.map(&:last).join next if text.empty? text.chars.take_while do |char| char.strip.empty? end.length end.compact.min || 0 is_h = lines.reduce([0, 1, EMPTY_HASH]) do |(position, lineno, lookup), tokens| tokens.reduce([position, lineno, lookup.dup]) do |(index, lineno, lookup), (_, value)| [index + value.length, lineno, lookup].tap do if highlight.include?(index) lookup[lineno] = true end end end.then do |index, lineno, lookup| [index.succ, lineno.succ, lookup] end end.last lines.reduce([0, 1]) do |(position, lineno), tokens| print_line_number = lambda do style = is_h[lineno] ? pastel.yellow.detach : pastel.dim.detach block.call((SPACE * 2) + style.call(lineno.to_s.ljust(4, SPACE)) + SPACE) end tokens.reduce(position) do |index, (token, value)| (index + value.length).tap do if index == position value = value.chars.drop(indentation).join if visible_lines.include?(lineno) print_line_number.call end end if highlight.include?(index) && visible_lines.include?(lineno) if index == position head = value.chars.take_while(&:blank?).join tail = value.chars.drop_while(&:blank?).join super([[TEXT, head]], &block) super([[token, tail]], &block) else super([[token, value]], &block) end elsif visible_lines.include?(lineno) super([[token, value]], &block) end end end.tap do |new_position| if visible_lines.include?(lineno) if position == new_position print_line_number.call end super([[TEXT, NEWLINE]], &block) end end.then do |position| [position.succ, lineno.succ] end end end