Module CodeRay::Encoders::HTML::Output
In: lib/coderay/encoders/html/numerization.rb
lib/coderay/encoders/html/output.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>CodeRay Output</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/numerization.rb, line 108
108:       def line_count
109:         line_count = count("\n")
110:         position_of_last_newline = rindex(?\n)
111:         if position_of_last_newline
112:           after_last_newline = self[position_of_last_newline + 1 .. -1]
113:           ends_with_newline = after_last_newline[/\A(?:<\/span>)*\z/]
114:           line_count += 1 if not ends_with_newline
115:         end
116:         line_count
117:       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:         bolding =
 36:           if bold_every == false
 37:             proc { |line| line.to_s }
 38:           elsif bold_every.is_a? Integer
 39:             raise ArgumentError, ":bolding can't be 0." if bold_every == 0
 40:             proc do |line|
 41:               if line % bold_every == 0
 42:                 "<strong>#{line}</strong>"  # every bold_every-th number in bold
 43:               else
 44:                 line.to_s
 45:               end
 46:             end
 47:           else
 48:             raise ArgumentError, 'Invalid value %p for :bolding; false or Integer expected.' % bold_every
 49:           end
 50: 
 51:         case mode
 52:         when :inline
 53:           max_width = (start + line_count).to_s.size
 54:           line_number = start
 55:           gsub!(/^/) do
 56:             line_number_text = bolding.call line_number
 57:             indent = ' ' * (max_width - line_number.to_s.size)  # TODO: Optimize (10^x)
 58:             res = "<span class=\"no\">#{indent}#{line_number_text}</span> "
 59:             line_number += 1
 60:             res
 61:           end
 62: 
 63:         when :table
 64:           # This is really ugly.
 65:           # Because even monospace fonts seem to have different heights when bold,
 66:           # I make the newline bold, both in the code and the line numbers.
 67:           # FIXME Still not working perfect for Mr. Internet Exploder
 68:           # FIXME Firefox struggles with very long codes (> 200 lines)
 69:           line_numbers = (start ... start + line_count).to_a.map(&bolding).join("\n")
 70:           line_numbers << "\n"  # also for Mr. MS Internet Exploder :-/
 71:           line_numbers.gsub!(/\n/) { "<tt>\n</tt>" }
 72: 
 73:           line_numbers_table_tpl = TABLE.apply('LINE_NUMBERS', line_numbers)
 74:           gsub!(/<\/div>\n/) { '</div>' }
 75:           gsub!(/\n/) { "<tt>\n</tt>" }
 76:           wrap_in! line_numbers_table_tpl
 77:           @wrapped_in = :div
 78: 
 79:         when :list
 80:           opened_tags = []
 81:           gsub!(/^.*$\n?/) do |line|
 82:             line.chomp!
 83: 
 84:             open = opened_tags.join
 85:             line.scan(%r!<(/)?span[^>]*>?!) do |close,|
 86:               if close
 87:                 opened_tags.pop
 88:               else
 89:                 opened_tags << $&
 90:               end
 91:             end
 92:             close = '</span>' * opened_tags.size
 93: 
 94:             "<li>#{open}#{line}#{close}</li>\n"
 95:           end
 96:           chomp!("\n")
 97:           wrap_in! LIST
 98:           @wrapped_in = :div
 99: 
100:         else
101:           raise ArgumentError, 'Unknown value %p for mode: expected one of %p' %
102:             [mode, [:table, :list, :inline]]
103:         end
104: 
105:         self
106:       end

[Source]

     # File lib/coderay/encoders/html/output.rb, line 117
117:       def stylesheet in_tag = false
118:         Output.make_stylesheet @css, in_tag
119:       end

[Source]

     # File lib/coderay/encoders/html/output.rb, line 113
113:       def wrap *args
114:         clone.wrap!(*args)
115:       end

[Source]

     # File lib/coderay/encoders/html/output.rb, line 91
 91:       def wrap! element, *args
 92:         return self if not element or element == wrapped_in
 93:         case element
 94:         when :div
 95:           raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? nil
 96:           wrap_in! DIV
 97:         when :span
 98:           raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? nil
 99:           wrap_in! SPAN
100:         when :page
101:           wrap! :div if wrapped_in? nil
102:           raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? :div
103:           wrap_in! Output.page_template_for_css(@css)
104:         when nil
105:           return self
106:         else
107:           raise "Unknown value %p for :wrap" % element
108:         end
109:         @wrapped_in = element
110:         self
111:       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]