class Rouge::Formatters::Prawn
Transforms a token stream into an array of formatted text fragments for use with Prawn.
Constants
- BoldItalicStyle
- BoldStyle
- EOL
- GuardedIndent
- GuardedInnerIndent
- InnerIndent
- ItalicStyle
- NoBreakSpace
Public Class Methods
new(opts = {})
click to toggle source
# File lib/asciidoctor-pdf/rouge_ext/formatters/prawn.rb, line 17 def initialize opts = {} unless ::Rouge::Theme === (theme = opts[:theme]) unless theme && (theme = ::Rouge::Theme.find theme) theme = ::Rouge::Themes::Pastie end theme = theme.new end @theme = theme @normalized_colors = {} @linenum_fragment_base = (create_fragment Token['Generic.Lineno']).merge linenum: true end
Public Instance Methods
create_fragment(tok, val = nil)
click to toggle source
TODO method could still be optimized (for instance, check if val is EOL or empty)
# File lib/asciidoctor-pdf/rouge_ext/formatters/prawn.rb, line 89 def create_fragment tok, val = nil fragment = val ? { text: val } : {} if (style_rules = @theme.style_for tok) # TODO support background color if (fg = normalize_color style_rules.fg) fragment[:color] = fg end if style_rules[:bold] fragment[:styles] = style_rules[:italic] ? BoldItalicStyle : BoldStyle elsif style_rules[:italic] fragment[:styles] = ItalicStyle end end fragment end
create_linenum_fragment(linenum)
click to toggle source
# File lib/asciidoctor-pdf/rouge_ext/formatters/prawn.rb, line 105 def create_linenum_fragment linenum @linenum_fragment_base.merge text: %Q(#{linenum} ) end
format(tokens, opts = {})
click to toggle source
Override format method so fragments don't get flatted to a string and to add an options Hash.
# File lib/asciidoctor-pdf/rouge_ext/formatters/prawn.rb, line 31 def format tokens, opts = {} stream tokens, opts end
normalize_color(raw)
click to toggle source
# File lib/asciidoctor-pdf/rouge_ext/formatters/prawn.rb, line 109 def normalize_color raw return unless raw if (normalized = @normalized_colors[raw]) normalized else normalized = (raw.start_with? '#') ? raw[1..-1] : raw normalized = normalized.each_char.map {|c| c * 2 }.join if normalized.size == 3 @normalized_colors[raw] = normalized end end
stream(tokens, opts = {})
click to toggle source
# File lib/asciidoctor-pdf/rouge_ext/formatters/prawn.rb, line 35 def stream tokens, opts = {} if opts[:line_numbers] # TODO implement line number start (offset) linenum = 0 fragments = [] fragments << (create_linenum_fragment linenum += 1) tokens.each do |tok, val| if val == EOL fragments << { text: EOL } fragments << (create_linenum_fragment linenum += 1) elsif val.include? EOL base_fragment = create_fragment tok, val val.each_line do |line| fragments << (base_fragment.merge text: line) # NOTE append linenum fragment if there's a next line; only works if source doesn't have trailing endline if line.end_with? EOL fragments << (create_linenum_fragment linenum += 1) end end else fragments << (create_fragment tok, val) end end # NOTE drop orphaned linenum fragment (due to trailing endline in source) fragments.pop if (last_fragment = fragments[-1]) && last_fragment[:linenum] # NOTE pad numbers that have less digits than the largest line number if (linenum_w = (linenum / 10) + 1) > 1 # NOTE extra column is the trailing space after the line number linenum_w += 1 fragments.each do |fragment| fragment[:text] = %Q(#{fragment[:text].rjust linenum_w, NoBreakSpace}) if fragment[:linenum] end end fragments else start_of_line = true tokens.map do |tok, val| # match one or more consecutive endlines if val == EOL || (val == (EOL * val.length)) start_of_line = true { text: val } else val[0] = GuardedIndent if start_of_line && (val.start_with? ' ') val.gsub! InnerIndent, GuardedInnerIndent if val.include? InnerIndent start_of_line = val.end_with? EOL # NOTE this optimization assumes we don't support/use background colors val.rstrip.empty? ? { text: val } : (create_fragment tok, val) end end # QUESTION should we strip trailing newline? end end