coderay 1.0.0 → 1.0.0.598.pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/FOLDERS +49 -0
- data/Rakefile +6 -5
- data/bin/coderay +74 -190
- data/bin/coderay_stylesheet +4 -0
- data/{README_INDEX.rdoc → lib/README} +20 -10
- data/lib/coderay.rb +60 -62
- data/lib/coderay/duo.rb +55 -2
- data/lib/coderay/encoder.rb +39 -52
- data/lib/coderay/encoders/_map.rb +7 -11
- data/lib/coderay/encoders/comment_filter.rb +61 -0
- data/lib/coderay/encoders/count.rb +26 -11
- data/lib/coderay/encoders/debug.rb +60 -11
- data/lib/coderay/encoders/div.rb +8 -9
- data/lib/coderay/encoders/filter.rb +52 -12
- data/lib/coderay/encoders/html.rb +113 -106
- data/lib/coderay/encoders/html/css.rb +7 -2
- data/lib/coderay/encoders/html/numbering.rb +27 -24
- data/lib/coderay/encoders/html/output.rb +58 -15
- data/lib/coderay/encoders/json.rb +44 -37
- data/lib/coderay/encoders/lines_of_code.rb +56 -9
- data/lib/coderay/encoders/null.rb +13 -6
- data/lib/coderay/encoders/page.rb +8 -8
- data/lib/coderay/encoders/span.rb +9 -10
- data/lib/coderay/encoders/statistic.rb +114 -51
- data/lib/coderay/encoders/terminal.rb +10 -7
- data/lib/coderay/encoders/text.rb +36 -17
- data/lib/coderay/encoders/token_kind_filter.rb +58 -1
- data/lib/coderay/encoders/xml.rb +11 -13
- data/lib/coderay/encoders/yaml.rb +14 -16
- data/lib/coderay/for_redcloth.rb +1 -1
- data/lib/coderay/helpers/file_type.rb +240 -125
- data/lib/coderay/helpers/gzip_simple.rb +123 -0
- data/lib/coderay/helpers/plugin.rb +307 -241
- data/lib/coderay/helpers/word_list.rb +126 -65
- data/lib/coderay/scanner.rb +103 -153
- data/lib/coderay/scanners/_map.rb +16 -18
- data/lib/coderay/scanners/c.rb +13 -13
- data/lib/coderay/scanners/cpp.rb +6 -6
- data/lib/coderay/scanners/css.rb +48 -47
- data/lib/coderay/scanners/debug.rb +55 -9
- data/lib/coderay/scanners/delphi.rb +4 -4
- data/lib/coderay/scanners/diff.rb +25 -43
- data/lib/coderay/scanners/groovy.rb +2 -2
- data/lib/coderay/scanners/html.rb +30 -107
- data/lib/coderay/scanners/java.rb +5 -6
- data/lib/coderay/scanners/java/builtin_types.rb +0 -2
- data/lib/coderay/scanners/java_script.rb +6 -6
- data/lib/coderay/scanners/json.rb +6 -7
- data/lib/coderay/scanners/nitro_xhtml.rb +136 -0
- data/lib/coderay/scanners/php.rb +12 -13
- data/lib/coderay/scanners/plaintext.rb +26 -0
- data/lib/coderay/scanners/python.rb +4 -4
- data/lib/coderay/scanners/{erb.rb → rhtml.rb} +11 -19
- data/lib/coderay/scanners/ruby.rb +208 -219
- data/lib/coderay/scanners/ruby/patterns.rb +85 -18
- data/lib/coderay/scanners/scheme.rb +136 -0
- data/lib/coderay/scanners/sql.rb +22 -29
- data/lib/coderay/scanners/yaml.rb +10 -11
- data/lib/coderay/styles/_map.rb +2 -2
- data/lib/coderay/styles/alpha.rb +104 -102
- data/lib/coderay/styles/cycnus.rb +143 -0
- data/lib/coderay/styles/murphy.rb +123 -0
- data/lib/coderay/token_kinds.rb +86 -87
- data/lib/coderay/tokens.rb +169 -26
- data/test/functional/basic.rb +14 -200
- data/test/functional/examples.rb +14 -20
- data/test/functional/for_redcloth.rb +8 -15
- data/test/functional/load_plugin_scanner.rb +11 -0
- data/test/functional/suite.rb +6 -9
- data/test/functional/vhdl.rb +126 -0
- data/test/functional/word_list.rb +79 -0
- metadata +129 -107
- data/lib/coderay/helpers/gzip.rb +0 -41
- data/lib/coderay/scanners/clojure.rb +0 -217
- data/lib/coderay/scanners/haml.rb +0 -168
- data/lib/coderay/scanners/ruby/string_state.rb +0 -71
- data/lib/coderay/scanners/text.rb +0 -26
- data/lib/coderay/tokens_proxy.rb +0 -55
- data/lib/coderay/version.rb +0 -3
| @@ -20,7 +20,7 @@ module Encoders | |
| 20 20 | 
             
                    parse style::TOKEN_COLORS
         | 
| 21 21 | 
             
                  end
         | 
| 22 22 |  | 
| 23 | 
            -
                  def  | 
| 23 | 
            +
                  def [] *styles
         | 
| 24 24 | 
             
                    cl = @classes[styles.first]
         | 
| 25 25 | 
             
                    return '' unless cl
         | 
| 26 26 | 
             
                    style = ''
         | 
| @@ -44,7 +44,7 @@ module Encoders | |
| 44 44 | 
             
                    ( [^\}]+ )?          # $2 = style
         | 
| 45 45 | 
             
                    \s* \} \s*
         | 
| 46 46 | 
             
                  |
         | 
| 47 | 
            -
                    (  | 
| 47 | 
            +
                    ( . )                # $3 = error
         | 
| 48 48 | 
             
                  /mx
         | 
| 49 49 | 
             
                  def parse stylesheet
         | 
| 50 50 | 
             
                    stylesheet.scan CSS_CLASS_PATTERN do |selectors, style, error|
         | 
| @@ -63,3 +63,8 @@ module Encoders | |
| 63 63 |  | 
| 64 64 | 
             
            end
         | 
| 65 65 | 
             
            end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
            if $0 == __FILE__
         | 
| 68 | 
            +
              require 'pp'
         | 
| 69 | 
            +
              pp CodeRay::Encoders::HTML::CSS.new
         | 
| 70 | 
            +
            end
         | 
| @@ -3,9 +3,9 @@ module Encoders | |
| 3 3 |  | 
| 4 4 | 
             
              class HTML
         | 
| 5 5 |  | 
| 6 | 
            -
                module  | 
| 6 | 
            +
                module Output  # :nodoc:
         | 
| 7 7 |  | 
| 8 | 
            -
                  def  | 
| 8 | 
            +
                  def number! mode = :table, options = {}
         | 
| 9 9 | 
             
                    return self unless mode
         | 
| 10 10 |  | 
| 11 11 | 
             
                    options = DEFAULT_OPTIONS.merge options
         | 
| @@ -26,7 +26,7 @@ module Encoders | |
| 26 26 | 
             
                          "<a href=\"##{anchor}\" name=\"#{anchor}\">#{line}</a>"
         | 
| 27 27 | 
             
                        end
         | 
| 28 28 | 
             
                      else
         | 
| 29 | 
            -
                        proc { |line| line.to_s } | 
| 29 | 
            +
                        proc { |line| line.to_s }
         | 
| 30 30 | 
             
                      end
         | 
| 31 31 |  | 
| 32 32 | 
             
                    bold_every = options[:bold_every]
         | 
| @@ -56,45 +56,37 @@ module Encoders | |
| 56 56 | 
             
                        raise ArgumentError, 'Invalid value %p for :bolding; false or Integer expected.' % bold_every
         | 
| 57 57 | 
             
                      end
         | 
| 58 58 |  | 
| 59 | 
            -
                    line_count = output.count("\n")
         | 
| 60 | 
            -
                    position_of_last_newline = output.rindex(RUBY_VERSION >= '1.9' ? /\n/ : ?\n)
         | 
| 61 | 
            -
                    if position_of_last_newline
         | 
| 62 | 
            -
                      after_last_newline = output[position_of_last_newline + 1 .. -1]
         | 
| 63 | 
            -
                      ends_with_newline = after_last_newline[/\A(?:<\/span>)*\z/]
         | 
| 64 | 
            -
                      line_count += 1 if not ends_with_newline
         | 
| 65 | 
            -
                    end
         | 
| 66 | 
            -
                    
         | 
| 67 59 | 
             
                    case mode
         | 
| 68 60 | 
             
                    when :inline
         | 
| 69 61 | 
             
                      max_width = (start + line_count).to_s.size
         | 
| 70 62 | 
             
                      line_number = start
         | 
| 71 | 
            -
                       | 
| 72 | 
            -
                       | 
| 63 | 
            +
                      opened_tags = []
         | 
| 64 | 
            +
                      gsub!(/^.*$\n?/) do |line|
         | 
| 73 65 | 
             
                        line.chomp!
         | 
| 74 | 
            -
                        open =  | 
| 66 | 
            +
                        open = opened_tags.join
         | 
| 75 67 | 
             
                        line.scan(%r!<(/)?span[^>]*>?!) do |close,|
         | 
| 76 68 | 
             
                          if close
         | 
| 77 | 
            -
                             | 
| 69 | 
            +
                            opened_tags.pop
         | 
| 78 70 | 
             
                          else
         | 
| 79 | 
            -
                             | 
| 71 | 
            +
                            opened_tags << $&
         | 
| 80 72 | 
             
                          end
         | 
| 81 73 | 
             
                        end
         | 
| 82 | 
            -
                        close = '</span>' *  | 
| 74 | 
            +
                        close = '</span>' * opened_tags.size
         | 
| 83 75 |  | 
| 84 76 | 
             
                        line_number_text = bolding.call line_number
         | 
| 85 77 | 
             
                        indent = ' ' * (max_width - line_number.to_s.size)  # TODO: Optimize (10^x)
         | 
| 86 78 | 
             
                        line_number += 1
         | 
| 87 | 
            -
                        "<span class=\" | 
| 79 | 
            +
                        "<span class=\"no\">#{indent}#{line_number_text}</span>#{open}#{line}#{close}\n"
         | 
| 88 80 | 
             
                      end
         | 
| 89 81 |  | 
| 90 82 | 
             
                    when :table
         | 
| 91 | 
            -
                      line_numbers = (start ... start + line_count).map(&bolding).join("\n")
         | 
| 83 | 
            +
                      line_numbers = (start ... start + line_count).to_a.map(&bolding).join("\n")
         | 
| 92 84 | 
             
                      line_numbers << "\n"
         | 
| 93 | 
            -
                      line_numbers_table_template = Output::TABLE.apply('LINE_NUMBERS', line_numbers)
         | 
| 94 85 |  | 
| 95 | 
            -
                       | 
| 96 | 
            -
                       | 
| 97 | 
            -
                       | 
| 86 | 
            +
                      line_numbers_table_template = TABLE.apply('LINE_NUMBERS', line_numbers)
         | 
| 87 | 
            +
                      gsub!(/<\/div>\n/) { '</div>' }
         | 
| 88 | 
            +
                      wrap_in! line_numbers_table_template
         | 
| 89 | 
            +
                      @wrapped_in = :div
         | 
| 98 90 |  | 
| 99 91 | 
             
                    when :list
         | 
| 100 92 | 
             
                      raise NotImplementedError, 'The :list option is no longer available. Use :table.'
         | 
| @@ -104,7 +96,18 @@ module Encoders | |
| 104 96 | 
             
                        [mode, [:table, :inline]]
         | 
| 105 97 | 
             
                    end
         | 
| 106 98 |  | 
| 107 | 
            -
                     | 
| 99 | 
            +
                    self
         | 
| 100 | 
            +
                  end
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                  def line_count
         | 
| 103 | 
            +
                    line_count = count("\n")
         | 
| 104 | 
            +
                    position_of_last_newline = rindex(?\n)
         | 
| 105 | 
            +
                    if position_of_last_newline
         | 
| 106 | 
            +
                      after_last_newline = self[position_of_last_newline + 1 .. -1]
         | 
| 107 | 
            +
                      ends_with_newline = after_last_newline[/\A(?:<\/span>)*\z/]
         | 
| 108 | 
            +
                      line_count += 1 if not ends_with_newline
         | 
| 109 | 
            +
                    end
         | 
| 110 | 
            +
                    line_count
         | 
| 108 111 | 
             
                  end
         | 
| 109 112 |  | 
| 110 113 | 
             
                end
         | 
| @@ -3,29 +3,42 @@ module Encoders | |
| 3 3 |  | 
| 4 4 | 
             
              class HTML
         | 
| 5 5 |  | 
| 6 | 
            -
                # This module is included in the output String  | 
| 6 | 
            +
                # This module is included in the output String from thew HTML Encoder.
         | 
| 7 7 | 
             
                #
         | 
| 8 8 | 
             
                # It provides methods like wrap, div, page etc.
         | 
| 9 9 | 
             
                #
         | 
| 10 10 | 
             
                # Remember to use #clone instead of #dup to keep the modules the object was
         | 
| 11 11 | 
             
                # extended with.
         | 
| 12 12 | 
             
                #
         | 
| 13 | 
            -
                # TODO:  | 
| 13 | 
            +
                # TODO: more doc.
         | 
| 14 14 | 
             
                module Output
         | 
| 15 15 |  | 
| 16 16 | 
             
                  attr_accessor :css
         | 
| 17 17 |  | 
| 18 18 | 
             
                  class << self
         | 
| 19 19 |  | 
| 20 | 
            +
                    # This makes Output look like a class.
         | 
| 21 | 
            +
                    #
         | 
| 22 | 
            +
                    # Example:
         | 
| 23 | 
            +
                    #
         | 
| 24 | 
            +
                    #  a = Output.new '<span class="co">Code</span>'
         | 
| 25 | 
            +
                    #  a.wrap! :page
         | 
| 26 | 
            +
                    def new string, css = CSS.new, element = nil
         | 
| 27 | 
            +
                      output = string.clone.extend self
         | 
| 28 | 
            +
                      output.wrapped_in = element
         | 
| 29 | 
            +
                      output.css = css
         | 
| 30 | 
            +
                      output
         | 
| 31 | 
            +
                    end
         | 
| 32 | 
            +
             | 
| 20 33 | 
             
                    # Raises an exception if an object that doesn't respond to to_str is extended by Output,
         | 
| 21 34 | 
             
                    # to prevent users from misuse. Use Module#remove_method to disable.
         | 
| 22 | 
            -
                    def extended o | 
| 35 | 
            +
                    def extended o
         | 
| 23 36 | 
             
                      warn "The Output module is intended to extend instances of String, not #{o.class}." unless o.respond_to? :to_str
         | 
| 24 37 | 
             
                    end
         | 
| 25 38 |  | 
| 26 | 
            -
                    def make_stylesheet css, in_tag = false | 
| 39 | 
            +
                    def make_stylesheet css, in_tag = false
         | 
| 27 40 | 
             
                      sheet = css.stylesheet
         | 
| 28 | 
            -
                      sheet = <<- | 
| 41 | 
            +
                      sheet = <<-CSS if in_tag
         | 
| 29 42 | 
             
            <style type="text/css">
         | 
| 30 43 | 
             
            #{sheet}
         | 
| 31 44 | 
             
            </style>
         | 
| @@ -33,13 +46,27 @@ module Encoders | |
| 33 46 | 
             
                      sheet
         | 
| 34 47 | 
             
                    end
         | 
| 35 48 |  | 
| 36 | 
            -
                    def page_template_for_css css | 
| 49 | 
            +
                    def page_template_for_css css
         | 
| 37 50 | 
             
                      sheet = make_stylesheet css
         | 
| 38 51 | 
             
                      PAGE.apply 'CSS', sheet
         | 
| 39 52 | 
             
                    end
         | 
| 40 53 |  | 
| 54 | 
            +
                    # Define a new wrapper. This is meta programming.
         | 
| 55 | 
            +
                    def wrapper *wrappers
         | 
| 56 | 
            +
                      wrappers.each do |wrapper|
         | 
| 57 | 
            +
                        define_method wrapper do |*args|
         | 
| 58 | 
            +
                          wrap wrapper, *args
         | 
| 59 | 
            +
                        end
         | 
| 60 | 
            +
                        define_method "#{wrapper}!".to_sym do |*args|
         | 
| 61 | 
            +
                          wrap! wrapper, *args
         | 
| 62 | 
            +
                        end
         | 
| 63 | 
            +
                      end
         | 
| 64 | 
            +
                    end
         | 
| 65 | 
            +
             | 
| 41 66 | 
             
                  end
         | 
| 42 67 |  | 
| 68 | 
            +
                  wrapper :div, :span, :page
         | 
| 69 | 
            +
             | 
| 43 70 | 
             
                  def wrapped_in? element
         | 
| 44 71 | 
             
                    wrapped_in == element
         | 
| 45 72 | 
             
                  end
         | 
| @@ -49,6 +76,10 @@ module Encoders | |
| 49 76 | 
             
                  end
         | 
| 50 77 | 
             
                  attr_writer :wrapped_in
         | 
| 51 78 |  | 
| 79 | 
            +
                  def wrap_in template
         | 
| 80 | 
            +
                    clone.wrap_in! template
         | 
| 81 | 
            +
                  end
         | 
| 82 | 
            +
             | 
| 52 83 | 
             
                  def wrap_in! template
         | 
| 53 84 | 
             
                    Template.wrap! self, template, 'CONTENT'
         | 
| 54 85 | 
             
                    self
         | 
| @@ -85,12 +116,14 @@ module Encoders | |
| 85 116 | 
             
                    self
         | 
| 86 117 | 
             
                  end
         | 
| 87 118 |  | 
| 119 | 
            +
                  def wrap *args
         | 
| 120 | 
            +
                    clone.wrap!(*args)
         | 
| 121 | 
            +
                  end
         | 
| 122 | 
            +
             | 
| 88 123 | 
             
                  def stylesheet in_tag = false
         | 
| 89 124 | 
             
                    Output.make_stylesheet @css, in_tag
         | 
| 90 125 | 
             
                  end
         | 
| 91 126 |  | 
| 92 | 
            -
            #-- don't include the templates in docu
         | 
| 93 | 
            -
             | 
| 94 127 | 
             
                  class Template < String  # :nodoc:
         | 
| 95 128 |  | 
| 96 129 | 
             
                    def self.wrap! str, template, target
         | 
| @@ -112,31 +145,41 @@ module Encoders | |
| 112 145 | 
             
                      end
         | 
| 113 146 | 
             
                    end
         | 
| 114 147 |  | 
| 148 | 
            +
                    module Simple  # :nodoc:
         | 
| 149 | 
            +
                      def ` str  #` <-- for stupid editors
         | 
| 150 | 
            +
                        Template.new str
         | 
| 151 | 
            +
                      end
         | 
| 152 | 
            +
                    end
         | 
| 115 153 | 
             
                  end
         | 
| 116 154 |  | 
| 117 | 
            -
                   | 
| 155 | 
            +
                  extend Template::Simple
         | 
| 156 | 
            +
             | 
| 157 | 
            +
            #-- don't include the templates in docu
         | 
| 158 | 
            +
             | 
| 159 | 
            +
                  SPAN = `<span class="CodeRay"><%CONTENT%></span>`
         | 
| 118 160 |  | 
| 119 | 
            -
                  DIV =  | 
| 161 | 
            +
                  DIV = <<-`DIV`
         | 
| 120 162 | 
             
            <div class="CodeRay">
         | 
| 121 163 | 
             
              <div class="code"><pre><%CONTENT%></pre></div>
         | 
| 122 164 | 
             
            </div>
         | 
| 123 165 | 
             
                  DIV
         | 
| 124 166 |  | 
| 125 | 
            -
                  TABLE =  | 
| 167 | 
            +
                  TABLE = <<-`TABLE`
         | 
| 126 168 | 
             
            <table class="CodeRay"><tr>
         | 
| 127 | 
            -
              <td class=" | 
| 128 | 
            -
              <td class="code"><pre><%CONTENT%></pre></td>
         | 
| 169 | 
            +
              <td class="line_numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre><%LINE_NUMBERS%></pre></td>
         | 
| 170 | 
            +
              <td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><%CONTENT%></pre></td>
         | 
| 129 171 | 
             
            </tr></table>
         | 
| 130 172 | 
             
                  TABLE
         | 
| 173 | 
            +
                  # title="double click to expand"
         | 
| 131 174 |  | 
| 132 | 
            -
                  PAGE =  | 
| 175 | 
            +
                  PAGE = <<-`PAGE`
         | 
| 133 176 | 
             
            <!DOCTYPE html>
         | 
| 134 177 | 
             
            <html>
         | 
| 135 178 | 
             
            <head>
         | 
| 136 179 | 
             
              <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
         | 
| 137 180 | 
             
              <title></title>
         | 
| 138 181 | 
             
              <style type="text/css">
         | 
| 139 | 
            -
            .CodeRay . | 
| 182 | 
            +
            .CodeRay .line_numbers a, .CodeRay .no a {
         | 
| 140 183 | 
             
              text-decoration: inherit;
         | 
| 141 184 | 
             
              color: inherit;
         | 
| 142 185 | 
             
            }
         | 
| @@ -1,3 +1,4 @@ | |
| 1 | 
            +
            ($:.unshift '../..'; require 'coderay') unless defined? CodeRay
         | 
| 1 2 | 
             
            module CodeRay
         | 
| 2 3 | 
             
            module Encoders
         | 
| 3 4 |  | 
| @@ -17,67 +18,73 @@ module Encoders | |
| 17 18 | 
             
              #  ]
         | 
| 18 19 | 
             
              class JSON < Encoder
         | 
| 19 20 |  | 
| 20 | 
            -
                begin
         | 
| 21 | 
            -
                  require 'json'
         | 
| 22 | 
            -
                rescue LoadError
         | 
| 23 | 
            -
                  begin
         | 
| 24 | 
            -
                    require 'rubygems' unless defined? Gem
         | 
| 25 | 
            -
                    gem 'json'
         | 
| 26 | 
            -
                    require 'json'
         | 
| 27 | 
            -
                  rescue LoadError
         | 
| 28 | 
            -
                    $stderr.puts "The JSON encoder needs the JSON library.\n" \
         | 
| 29 | 
            -
                      "Please gem install json."
         | 
| 30 | 
            -
                    raise
         | 
| 31 | 
            -
                  end
         | 
| 32 | 
            -
                end
         | 
| 33 | 
            -
                
         | 
| 34 21 | 
             
                register_for :json
         | 
| 35 22 | 
             
                FILE_EXTENSION = 'json'
         | 
| 36 23 |  | 
| 37 24 | 
             
              protected
         | 
| 38 25 | 
             
                def setup options
         | 
| 39 | 
            -
                   | 
| 40 | 
            -
             | 
| 41 | 
            -
                   | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 44 | 
            -
                
         | 
| 45 | 
            -
                def finish options
         | 
| 46 | 
            -
                  @out << ']'
         | 
| 47 | 
            -
                end
         | 
| 48 | 
            -
                
         | 
| 49 | 
            -
                def append data
         | 
| 50 | 
            -
                  if @first
         | 
| 51 | 
            -
                    @first = false
         | 
| 52 | 
            -
                  else
         | 
| 53 | 
            -
                    @out << ','
         | 
| 26 | 
            +
                  begin
         | 
| 27 | 
            +
                    require 'json'
         | 
| 28 | 
            +
                  rescue LoadError
         | 
| 29 | 
            +
                    require 'rubygems'
         | 
| 30 | 
            +
                    require 'json'
         | 
| 54 31 | 
             
                  end
         | 
| 55 | 
            -
                  
         | 
| 56 | 
            -
                  @out << data.to_json
         | 
| 32 | 
            +
                  @out = []
         | 
| 57 33 | 
             
                end
         | 
| 58 34 |  | 
| 59 | 
            -
              public
         | 
| 60 35 | 
             
                def text_token text, kind
         | 
| 61 | 
            -
                   | 
| 36 | 
            +
                  @out << { :type => 'text', :text => text, :kind => kind }
         | 
| 62 37 | 
             
                end
         | 
| 63 38 |  | 
| 64 39 | 
             
                def begin_group kind
         | 
| 65 | 
            -
                   | 
| 40 | 
            +
                  @out << { :type => 'block', :action => 'open', :kind => kind }
         | 
| 66 41 | 
             
                end
         | 
| 67 42 |  | 
| 68 43 | 
             
                def end_group kind
         | 
| 69 | 
            -
                   | 
| 44 | 
            +
                  @out << { :type => 'block', :action => 'close', :kind => kind }
         | 
| 70 45 | 
             
                end
         | 
| 71 46 |  | 
| 72 47 | 
             
                def begin_line kind
         | 
| 73 | 
            -
                   | 
| 48 | 
            +
                  @out << { :type => 'block', :action => 'begin_line', :kind => kind }
         | 
| 74 49 | 
             
                end
         | 
| 75 50 |  | 
| 76 51 | 
             
                def end_line kind
         | 
| 77 | 
            -
                   | 
| 52 | 
            +
                  @out << { :type => 'block', :action => 'end_line', :kind => kind }
         | 
| 53 | 
            +
                end
         | 
| 54 | 
            +
                
         | 
| 55 | 
            +
                def finish options
         | 
| 56 | 
            +
                  @out.to_json
         | 
| 78 57 | 
             
                end
         | 
| 79 58 |  | 
| 80 59 | 
             
              end
         | 
| 81 60 |  | 
| 82 61 | 
             
            end
         | 
| 83 62 | 
             
            end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
            if $0 == __FILE__
         | 
| 65 | 
            +
              $VERBOSE = true
         | 
| 66 | 
            +
              $: << File.join(File.dirname(__FILE__), '..')
         | 
| 67 | 
            +
              eval DATA.read, nil, $0, __LINE__ + 4
         | 
| 68 | 
            +
            end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
            __END__
         | 
| 71 | 
            +
            require 'test/unit'
         | 
| 72 | 
            +
            $:.delete '.'
         | 
| 73 | 
            +
            require 'rubygems' if RUBY_VERSION < '1.9'
         | 
| 74 | 
            +
             | 
| 75 | 
            +
            class JSONEncoderTest < Test::Unit::TestCase
         | 
| 76 | 
            +
              
         | 
| 77 | 
            +
              def test_json_output
         | 
| 78 | 
            +
                json = CodeRay.scan('puts "Hello world!"', :ruby).json
         | 
| 79 | 
            +
                assert_equal [
         | 
| 80 | 
            +
                  {"type"=>"text", "text"=>"puts", "kind"=>"ident"},
         | 
| 81 | 
            +
                  {"type"=>"text", "text"=>" ", "kind"=>"space"},
         | 
| 82 | 
            +
                  {"type"=>"block", "action"=>"open", "kind"=>"string"},
         | 
| 83 | 
            +
                  {"type"=>"text", "text"=>"\"", "kind"=>"delimiter"},
         | 
| 84 | 
            +
                  {"type"=>"text", "text"=>"Hello world!", "kind"=>"content"},
         | 
| 85 | 
            +
                  {"type"=>"text", "text"=>"\"", "kind"=>"delimiter"},
         | 
| 86 | 
            +
                  {"type"=>"block", "action"=>"close", "kind"=>"string"},
         | 
| 87 | 
            +
                ], JSON.load(json)
         | 
| 88 | 
            +
              end
         | 
| 89 | 
            +
              
         | 
| 90 | 
            +
            end
         | 
| @@ -1,3 +1,4 @@ | |
| 1 | 
            +
            ($:.unshift '../..'; require 'coderay') unless defined? CodeRay
         | 
| 1 2 | 
             
            module CodeRay
         | 
| 2 3 | 
             
            module Encoders
         | 
| 3 4 |  | 
| @@ -14,7 +15,7 @@ module Encoders | |
| 14 15 | 
             
              # 
         | 
| 15 16 | 
             
              # A Scanner class should define the token kinds that are not code in the
         | 
| 16 17 | 
             
              # KINDS_NOT_LOC constant, which defaults to [:comment, :doctype].
         | 
| 17 | 
            -
              class LinesOfCode <  | 
| 18 | 
            +
              class LinesOfCode < Encoder
         | 
| 18 19 |  | 
| 19 20 | 
             
                register_for :lines_of_code
         | 
| 20 21 |  | 
| @@ -22,24 +23,70 @@ module Encoders | |
| 22 23 |  | 
| 23 24 | 
             
              protected
         | 
| 24 25 |  | 
| 25 | 
            -
                def  | 
| 26 | 
            -
                  if scanner
         | 
| 26 | 
            +
                def compile tokens, options
         | 
| 27 | 
            +
                  if scanner = tokens.scanner
         | 
| 27 28 | 
             
                    kinds_not_loc = scanner.class::KINDS_NOT_LOC
         | 
| 28 29 | 
             
                  else
         | 
| 29 | 
            -
                    warn  | 
| 30 | 
            +
                    warn 'Tokens have no scanner.' if $VERBOSE
         | 
| 30 31 | 
             
                    kinds_not_loc = CodeRay::Scanners::Scanner::KINDS_NOT_LOC
         | 
| 31 32 | 
             
                  end
         | 
| 32 | 
            -
                  
         | 
| 33 | 
            -
                   | 
| 34 | 
            -
                  
         | 
| 35 | 
            -
                  super options
         | 
| 33 | 
            +
                  code = tokens.token_kind_filter :exclude => kinds_not_loc
         | 
| 34 | 
            +
                  @loc = code.text.scan(NON_EMPTY_LINE).size
         | 
| 36 35 | 
             
                end
         | 
| 37 36 |  | 
| 38 37 | 
             
                def finish options
         | 
| 39 | 
            -
                   | 
| 38 | 
            +
                  @loc
         | 
| 40 39 | 
             
                end
         | 
| 41 40 |  | 
| 42 41 | 
             
              end
         | 
| 43 42 |  | 
| 44 43 | 
             
            end
         | 
| 45 44 | 
             
            end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
            if $0 == __FILE__
         | 
| 47 | 
            +
              $VERBOSE = true
         | 
| 48 | 
            +
              $: << File.join(File.dirname(__FILE__), '..')
         | 
| 49 | 
            +
              eval DATA.read, nil, $0, __LINE__ + 4
         | 
| 50 | 
            +
            end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
            __END__
         | 
| 53 | 
            +
            require 'test/unit'
         | 
| 54 | 
            +
             | 
| 55 | 
            +
            class LinesOfCodeTest < Test::Unit::TestCase
         | 
| 56 | 
            +
              
         | 
| 57 | 
            +
              def test_creation
         | 
| 58 | 
            +
                assert CodeRay::Encoders::LinesOfCode < CodeRay::Encoders::Encoder
         | 
| 59 | 
            +
                filter = nil
         | 
| 60 | 
            +
                assert_nothing_raised do
         | 
| 61 | 
            +
                  filter = CodeRay.encoder :loc
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
                assert_kind_of CodeRay::Encoders::LinesOfCode, filter
         | 
| 64 | 
            +
                assert_nothing_raised do
         | 
| 65 | 
            +
                  filter = CodeRay.encoder :lines_of_code
         | 
| 66 | 
            +
                end
         | 
| 67 | 
            +
                assert_kind_of CodeRay::Encoders::LinesOfCode, filter
         | 
| 68 | 
            +
              end
         | 
| 69 | 
            +
              
         | 
| 70 | 
            +
              def test_lines_of_code
         | 
| 71 | 
            +
                tokens = CodeRay.scan <<-RUBY, :ruby
         | 
| 72 | 
            +
            #!/usr/bin/env ruby
         | 
| 73 | 
            +
             | 
| 74 | 
            +
            # a minimal Ruby program
         | 
| 75 | 
            +
            puts "Hello world!"
         | 
| 76 | 
            +
                RUBY
         | 
| 77 | 
            +
                assert_equal 1, CodeRay::Encoders::LinesOfCode.new.encode_tokens(tokens)
         | 
| 78 | 
            +
                assert_equal 1, tokens.lines_of_code
         | 
| 79 | 
            +
                assert_equal 1, tokens.loc
         | 
| 80 | 
            +
              end
         | 
| 81 | 
            +
              
         | 
| 82 | 
            +
              def test_filtering_block_tokens
         | 
| 83 | 
            +
                tokens = CodeRay::Tokens.new
         | 
| 84 | 
            +
                tokens.concat ["Hello\n", :world]
         | 
| 85 | 
            +
                tokens.concat ["Hello\n", :space]
         | 
| 86 | 
            +
                tokens.concat ["Hello\n", :comment]
         | 
| 87 | 
            +
                assert_equal 2, CodeRay::Encoders::LinesOfCode.new.encode_tokens(tokens)
         | 
| 88 | 
            +
                assert_equal 2, tokens.lines_of_code
         | 
| 89 | 
            +
                assert_equal 2, tokens.loc
         | 
| 90 | 
            +
              end
         | 
| 91 | 
            +
              
         | 
| 92 | 
            +
            end
         |