Module CodeRay::Encoders::HTML::Output
In: lib/coderay/encoders/html/output.rb
lib/coderay/encoders/html/numerization.rb

This module is included in the output String from thew HTML Encoder.

It provides methods like wrap, div, page etc.

Remember to use clone instead of dup to keep the modules the object was extended with.

TODO: more doc.

Methods

Classes and Modules

Class CodeRay::Encoders::HTML::Output::Template

Constants

SPAN = `<span class="CodeRay"><%CONTENT%></span>`
DIV = <<-`DIV` <div class="CodeRay"> <div class="code"><pre><%CONTENT%></pre></div> </div> DIV
TABLE = <<-`TABLE` <table class="CodeRay"><tr> <td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre><%LINE_NUMBERS%></pre></td> <td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><%CONTENT%></pre></td> </tr></table> TABLE
LIST = <<-`LIST` <ol class="CodeRay"> <%CONTENT%> </ol> LIST   title="double click to expand"
PAGE = <<-`PAGE` <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="de"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title></title> <style type="text/css"> <%CSS%> </style> </head> <body style="background-color: white;"> <%CONTENT%> </body> </html> PAGE

Attributes

css  [RW] 
wrapped_in  [W] 

Public Class methods

Raises an exception if an object that doesn‘t respond to to_str is extended by Output, to prevent users from misuse. Use Module#remove_method to disable.

[Source]

    # File lib/coderay/encoders/html/output.rb, line 37
37:         def extended o
38:           warn "The Output module is intended to extend instances of String, not #{o.class}." unless o.respond_to? :to_str
39:         end

[Source]

    # File lib/coderay/encoders/html/output.rb, line 41
41:         def make_stylesheet css, in_tag = false
42:           sheet = css.stylesheet
43:           sheet = "<style type=\"text/css\">\n\#{sheet}\n</style>\n" if in_tag
44:           sheet
45:         end

This makes Output look like a class.

Example:

 a = Output.new '<span class="co">Code</span>'
 a.wrap! :page

[Source]

    # File lib/coderay/encoders/html/output.rb, line 28
28:         def new string, css = CSS.new, element = nil
29:           output = string.clone.extend self
30:           output.wrapped_in = element
31:           output.css = css
32:           output
33:         end

[Source]

    # File lib/coderay/encoders/html/output.rb, line 52
52:         def page_template_for_css css
53:           sheet = make_stylesheet css
54:           PAGE.apply 'CSS', sheet
55:         end

Define a new wrapper. This is meta programming.

[Source]

    # File lib/coderay/encoders/html/output.rb, line 58
58:         def wrapper *wrappers
59:           wrappers.each do |wrapper|
60:             define_method wrapper do |*args|
61:               wrap wrapper, *args
62:             end
63:             define_method "#{wrapper}!".to_sym do |*args|
64:               wrap! wrapper, *args
65:             end
66:           end
67:         end

Public Instance methods

[Source]

    # File lib/coderay/encoders/html/output.rb, line 91
91:       def apply_title! title
92:         self.sub!(/(<title>)(<\/title>)/) { $1 + title + $2 }
93:         self
94:       end

[Source]

     # File lib/coderay/encoders/html/numerization.rb, line 117
117:       def line_count
118:         line_count = count("\n")
119:         position_of_last_newline = rindex(?\n)
120:         if position_of_last_newline
121:           after_last_newline = self[position_of_last_newline + 1 .. -1]
122:           ends_with_newline = after_last_newline[/\A(?:<\/span>)*\z/]
123:           line_count += 1 if not ends_with_newline
124:         end
125:         line_count
126:       end

[Source]

    # File lib/coderay/encoders/html/numerization.rb, line 8
 8:       def numerize *args
 9:         clone.numerize!(*args)
10:       end

[Source]

     # File lib/coderay/encoders/html/numerization.rb, line 19
 19:       def numerize! mode = :table, options = {}
 20:         return self unless mode
 21: 
 22:         options = DEFAULT_OPTIONS.merge options
 23: 
 24:         start = options[:line_number_start]
 25:         unless start.is_a? Integer
 26:           raise ArgumentError, "Invalid value %p for :line_number_start; Integer expected." % start
 27:         end
 28: 
 29:         #allowed_wrappings = NUMERIZABLE_WRAPPINGS[mode]
 30:         #unless allowed_wrappings == :all or allowed_wrappings.include? options[:wrap]
 31:         #  raise ArgumentError, "Can't numerize, :wrap must be in %p, but is %p" % [NUMERIZABLE_WRAPPINGS, options[:wrap]]
 32:         #end
 33: 
 34:         bold_every = options[:bold_every]
 35:         highlight_lines = options[:highlight_lines]
 36:         bolding =
 37:           if bold_every == false && highlight_lines == nil
 38:             proc { |line| line.to_s }
 39:           elsif highlight_lines.is_a? Enumerable
 40:             highlight_lines = highlight_lines.to_set
 41:             proc do |line|
 42:               if highlight_lines.include? line
 43:                 "<strong class=\"highlighted\">#{line}</strong>"  # highlighted line numbers in bold
 44:               else
 45:                 line.to_s
 46:               end
 47:             end
 48:           elsif bold_every.is_a? Integer
 49:             raise ArgumentError, ":bolding can't be 0." if bold_every == 0
 50:             proc do |line|
 51:               if line % bold_every == 0
 52:                 "<strong>#{line}</strong>"  # every bold_every-th number in bold
 53:               else
 54:                 line.to_s
 55:               end
 56:             end
 57:           else
 58:             raise ArgumentError, 'Invalid value %p for :bolding; false or Integer expected.' % bold_every
 59:           end
 60: 
 61:         case mode
 62:         when :inline
 63:           max_width = (start + line_count).to_s.size
 64:           line_number = start
 65:           gsub!(/^/) do
 66:             line_number_text = bolding.call line_number
 67:             indent = ' ' * (max_width - line_number.to_s.size)  # TODO: Optimize (10^x)
 68:             res = "<span class=\"no\">#{indent}#{line_number_text}</span> "
 69:             line_number += 1
 70:             res
 71:           end
 72: 
 73:         when :table
 74:           # This is really ugly.
 75:           # Because even monospace fonts seem to have different heights when bold,
 76:           # I make the newline bold, both in the code and the line numbers.
 77:           # FIXME Still not working perfect for Mr. Internet Exploder
 78:           line_numbers = (start ... start + line_count).to_a.map(&bolding).join("\n")
 79:           line_numbers << "\n"  # also for Mr. MS Internet Exploder :-/
 80:           line_numbers.gsub!(/\n/) { "<tt>\n</tt>" }
 81: 
 82:           line_numbers_table_tpl = TABLE.apply('LINE_NUMBERS', line_numbers)
 83:           gsub!("</div>\n", '</div>')
 84:           gsub!("\n", "<tt>\n</tt>")
 85:           wrap_in! line_numbers_table_tpl
 86:           @wrapped_in = :div
 87: 
 88:         when :list
 89:           opened_tags = []
 90:           gsub!(/^.*$\n?/) do |line|
 91:             line.chomp!
 92: 
 93:             open = opened_tags.join
 94:             line.scan(%r!<(/)?span[^>]*>?!) do |close,|
 95:               if close
 96:                 opened_tags.pop
 97:               else
 98:                 opened_tags << $&
 99:               end
100:             end
101:             close = '</span>' * opened_tags.size
102: 
103:             "<li>#{open}#{line}#{close}</li>\n"
104:           end
105:           chomp!("\n")
106:           wrap_in! LIST
107:           @wrapped_in = :div
108: 
109:         else
110:           raise ArgumentError, 'Unknown value %p for mode: expected one of %p' %
111:             [mode, [:table, :list, :inline]]
112:         end
113: 
114:         self
115:       end

[Source]

     # File lib/coderay/encoders/html/output.rb, line 126
126:       def stylesheet in_tag = false
127:         Output.make_stylesheet @css, in_tag
128:       end

[Source]

     # File lib/coderay/encoders/html/output.rb, line 122
122:       def wrap *args
123:         clone.wrap!(*args)
124:       end

[Source]

     # File lib/coderay/encoders/html/output.rb, line 96
 96:       def wrap! element, *args
 97:         return self if not element or element == wrapped_in
 98:         case element
 99:         when :div
100:           raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? nil
101:           wrap_in! DIV
102:         when :span
103:           raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? nil
104:           wrap_in! SPAN
105:         when :page
106:           wrap! :div if wrapped_in? nil
107:           raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? :div
108:           wrap_in! Output.page_template_for_css(@css)
109:           if args.first.is_a?(Hash) && title = args.first[:title]
110:             apply_title! title
111:           end
112:           self
113:         when nil
114:           return self
115:         else
116:           raise "Unknown value %p for :wrap" % element
117:         end
118:         @wrapped_in = element
119:         self
120:       end

[Source]

    # File lib/coderay/encoders/html/output.rb, line 82
82:       def wrap_in template
83:         clone.wrap_in! template
84:       end

[Source]

    # File lib/coderay/encoders/html/output.rb, line 86
86:       def wrap_in! template
87:         Template.wrap! self, template, 'CONTENT'
88:         self
89:       end

[Source]

    # File lib/coderay/encoders/html/output.rb, line 77
77:       def wrapped_in
78:         @wrapped_in ||= nil
79:       end

[Source]

    # File lib/coderay/encoders/html/output.rb, line 73
73:       def wrapped_in? element
74:         wrapped_in == element
75:       end

[Validate]