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