module IrcPaint
IrcPaint — parse IRC colour segments and recolour whole blocks at plain-text positions. Public: plain_length, block_at_plain_index, recolor_at, recolor_range Depends: IrcFormat, TextAlign Tests: test/lib/irc_paint_test.rb
Constants
- BOLD
- COLOR_PATTERN
- CTRL
- RESET_ALL
- UNDERLINE
Public Instance Methods
Source
# File lib/irc_paint.rb, line 24 def block_at_plain_index(line, pos) return nil if pos.to_i < 1 segments(line).find do |segment| pos >= segment[:plain_start] && pos <= segment[:plain_end] end end
Source
# File lib/irc_paint.rb, line 145 def control_char?(char) char == CTRL || char == RESET_ALL || char == BOLD || char == UNDERLINE end
Source
# File lib/irc_paint.rb, line 92 def parse_parts(line) parts = [] index = 0 plain = 0 while index < line.length char = line[index] if control_char?(char) raw, code_fg, code_bg, advance = read_control(line, index) parts << { type: :code, raw: raw, fg: code_fg, bg: code_bg } index += advance else start = index index += 1 while index < line.length && !control_char?(line[index]) content = line[start...index] next if content.empty? plain_start = plain + 1 plain_end = plain + content.length parts << { type: :text, content: content, plain_start: plain_start, plain_end: plain_end } plain = plain_end end end parts end
Source
# File lib/irc_paint.rb, line 20 def plain_length(text) TextAlign.plain_length(text) end
Source
# File lib/irc_paint.rb, line 120 def read_control(line, index) char = line[index] case char when CTRL if index + 1 >= line.length || !line[index + 1].match?(/\d/) return [CTRL, nil, nil, 1] end match = line[index + 1..].match(COLOR_PATTERN) return [CTRL, nil, nil, 1] unless match raw = CTRL + match[0] fg = match[1].to_i bg = match[2] ? match[2].to_i : nil [raw, fg, bg, 1 + match[0].length] when RESET_ALL [RESET_ALL, nil, nil, 1] when BOLD, UNDERLINE [char, nil, nil, 1] else [char, nil, nil, 1] end end
Source
# File lib/irc_paint.rb, line 32 def recolor_at(line, pos, fg:, bg: nil) block = block_at_plain_index(line, pos) raise ArgumentError, "no colour block at position #{pos}" unless block recolor_segment(line, block, fg: fg, bg: bg) end
Source
# File lib/irc_paint.rb, line 39 def recolor_range(line, plain_start:, plain_end:, fg:, bg: nil) segment = segments(line).find do |entry| entry[:plain_start] == plain_start.to_i && entry[:plain_end] == plain_end.to_i end return line unless segment recolor_segment(line, segment, fg: fg, bg: bg)[:line] end
Source
# File lib/irc_paint.rb, line 77 def recolor_segment(line, segment, fg:, bg: nil) new_code = IrcFormat.color(fg, bg) updated = line.sub( /#{Regexp.escape(segment[:open_raw])}#{Regexp.escape(segment[:text])}/, "#{new_code}#{segment[:text]}" ) { line: updated, plain_start: segment[:plain_start], plain_end: segment[:plain_end], fg: fg, bg: bg } end
Source
# File lib/irc_paint.rb, line 48 def segments(line) parts = parse_parts(line.to_s) text_segments = [] open_raw = +"" fg = nil bg = nil parts.each do |part| case part[:type] when :code open_raw = part[:raw] fg = part[:fg] bg = part[:bg] when :text text_segments << { text: part[:content], open_raw: open_raw, fg: fg, bg: bg, plain_start: part[:plain_start], plain_end: part[:plain_end] } open_raw = +"" end end text_segments end