This module holds the Encoder class and its subclasses. For example, the HTML encoder is named CodeRay::Encoders::HTML can be found in coderay/encoders/html.
Encoders also provides methods and constants for the register mechanism and the [] method that returns the Encoder class belonging to the given format.
TRANSPARENT_TOKEN_KINDS | = | Set[ :delimiter, :modifier, :content, :escape, :inline_delimiter, ] |
Generate a hint about the given kinds in a hint style.
hint may be :info, :info_long or :debug.
# File lib/coderay/encoders/html.rb, line 157 157: def self.token_path_to_hint hint, kinds 158: kinds = Array kinds 159: title = 160: case hint 161: when :info 162: kinds = kinds[1..-1] if TRANSPARENT_TOKEN_KINDS.include? kinds.first 163: TOKEN_KIND_TO_INFO[kinds.first] 164: when :info_long 165: kinds.reverse.map { |kind| TOKEN_KIND_TO_INFO[kind] }.join('/') 166: when :debug 167: kinds.inspect 168: end 169: title ? " title=\"#{title}\"" : '' 170: end
token groups, eg. strings
# File lib/coderay/encoders/html.rb, line 281 281: def begin_group kind 282: @out << (@span_for_kind[@last_opened ? [kind, *@opened] : kind] || '<span>') 283: @opened << kind 284: @last_opened = kind if @set_last_opened 285: end
whole lines to be highlighted, eg. a deleted line in a diff
# File lib/coderay/encoders/html.rb, line 299 299: def begin_line kind 300: if style = @span_for_kind[@last_opened ? [kind, *@opened] : kind] 301: if style['class="'] 302: @out << style.sub('class="', 'class="line ') 303: else 304: @out << style.sub('>', ' class="line">') 305: end 306: else 307: @out << '<span class="line">' 308: end 309: @opened << kind 310: @last_opened = kind if @options[:css] == :style 311: end
# File lib/coderay/encoders/html.rb, line 287 287: def end_group kind 288: if $CODERAY_DEBUG && (@opened.empty? || @opened.last != kind) 289: warn 'Malformed token stream: Trying to close a token (%p) ' \ 290: 'that is not open. Open are: %p.' % [kind, @opened[1..-1]] 291: end 292: if @opened.pop 293: @out << '</span>' 294: @last_opened = @opened.last if @last_opened 295: end 296: end
# File lib/coderay/encoders/html.rb, line 313 313: def end_line kind 314: if $CODERAY_DEBUG && (@opened.empty? || @opened.last != kind) 315: warn 'Malformed token stream: Trying to close a line (%p) ' \ 316: 'that is not open. Open are: %p.' % [kind, @opened[1..-1]] 317: end 318: if @opened.pop 319: @out << '</span>' 320: @last_opened = @opened.last if @last_opened 321: end 322: end
# File lib/coderay/encoders/html.rb, line 232 232: def finish options 233: unless @opened.empty? 234: warn '%d tokens still open: %p' % [@opened.size, @opened] if $CODERAY_DEBUG 235: @out << '</span>' while @opened.pop 236: @last_opened = nil 237: end 238: 239: @out.extend Output 240: @out.css = @css 241: if options[:line_numbers] 242: Numbering.number! @out, options[:line_numbers], options 243: end 244: @out.wrap! options[:wrap] 245: @out.apply_title! options[:title] 246: 247: if defined?(@real_out) && @real_out 248: @real_out << @out 249: @out = @real_out 250: end 251: 252: super 253: end
# File lib/coderay/encoders/html.rb, line 172 172: def setup options 173: super 174: 175: if options[:wrap] || options[:line_numbers] 176: @real_out = @out 177: @out = '' 178: end 179: 180: options[:break_lines] = true if options[:line_numbers] == :inline 181: 182: @break_lines = (options[:break_lines] == true) 183: 184: @HTML_ESCAPE = HTML_ESCAPE.dup 185: @HTML_ESCAPE["\t"] = ' ' * options[:tab_width] 186: 187: @opened = [] 188: @last_opened = nil 189: @css = CSS.new options[:style] 190: 191: hint = options[:hint] 192: if hint && ![:debug, :info, :info_long].include?(hint) 193: raise ArgumentError, "Unknown value %p for :hint; \ 194: expected :info, :info_long, :debug, false, or nil." % hint 195: end 196: 197: css_classes = TokenKinds 198: case options[:css] 199: when :class 200: @span_for_kind = Hash.new do |h, k| 201: if k.is_a? ::Symbol 202: kind = k_dup = k 203: else 204: kind = k.first 205: k_dup = k.dup 206: end 207: if kind != :space && (hint || css_class = css_classes[kind]) 208: title = HTML.token_path_to_hint hint, k if hint 209: css_class ||= css_classes[kind] 210: h[k_dup] = "<span#{title}#{" class=\"#{css_class}\"" if css_class}>" 211: else 212: h[k_dup] = nil 213: end 214: end 215: when :style 216: @span_for_kind = Hash.new do |h, k| 217: kind = k.is_a?(Symbol) ? k : k.first 218: h[k.is_a?(Symbol) ? k : k.dup] = 219: if kind != :space && (hint || css_classes[kind]) 220: title = HTML.token_path_to_hint hint, k if hint 221: style = @css.get_style Array(k).map { |c| css_classes[c] } 222: "<span#{title}#{" style=\"#{style}\"" if style}>" 223: end 224: end 225: else 226: raise ArgumentError, "Unknown value %p for :css." % options[:css] 227: end 228: 229: @set_last_opened = options[:hint] || options[:css] == :style 230: end
# File lib/coderay/encoders/html.rb, line 257 257: def text_token text, kind 258: if text =~ /#{HTML_ESCAPE_PATTERN}/o 259: text = text.gsub(/#{HTML_ESCAPE_PATTERN}/o) { |m| @HTML_ESCAPE[m] } 260: end 261: 262: style = @span_for_kind[@last_opened ? [kind, *@opened] : kind] 263: 264: if @break_lines && (i = text.index("\n")) && (c = @opened.size + (style ? 1 : 0)) > 0 265: close = '</span>' * c 266: reopen = '' 267: @opened.each_with_index do |k, index| 268: reopen << (@span_for_kind[index > 0 ? [k, *@opened[0 ... index ]] : k] || '<span>') 269: end 270: text[i .. -1] = text[i .. -1].gsub("\n", "#{close}\n#{reopen}#{style}") 271: end 272: 273: if style 274: @out << style << text << '</span>' 275: else 276: @out << text 277: end 278: end