diff options
author | murphy <murphy@rubychan.de> | 2011-06-17 23:13:24 +0000 |
---|---|---|
committer | murphy <murphy@rubychan.de> | 2011-06-17 23:13:24 +0000 |
commit | 90f70ee61e87e137aa192c5db97c382e1ec7d24b (patch) | |
tree | a9d5e9c7e0664faaada8d99741679d0bb8f6403c | |
parent | 4c8b5dac9d881b916a49e20401659bf107168e0b (diff) | |
download | coderay-90f70ee61e87e137aa192c5db97c382e1ec7d24b.tar.gz |
issue #45: new command line interface!
-rwxr-xr-x | bin/coderay | 167 | ||||
-rwxr-xr-x | bin/coderay_stylesheet | 4 | ||||
-rw-r--r-- | etc/CodeRay.tmproj | 50 | ||||
-rw-r--r-- | lib/coderay.rb | 4 | ||||
-rw-r--r-- | rake_tasks/gem.rake | 2 | ||||
-rw-r--r-- | test/executable/source.py | 1 | ||||
-rw-r--r-- | test/executable/source.rb | 1 | ||||
-rw-r--r-- | test/executable/suite.rb | 191 |
8 files changed, 317 insertions, 103 deletions
diff --git a/bin/coderay b/bin/coderay index 690d8fc..70baa99 100755 --- a/bin/coderay +++ b/bin/coderay @@ -1,99 +1,112 @@ #!/usr/bin/env ruby -# CodeRay Executable -# -# Version: 0.2 -# Author: murphy +require 'coderay' -def err msg - $stderr.puts msg -end +$options, $args = ARGV.partition { |arg| arg[/^-[hv]$|--\w+/] } +subcommand = $args.detect { |arg| arg[/^\w/] } +subcommand = nil if subcommand && File.exist?(subcommand) +$args.delete subcommand -def read - if file = ARGV[2] - File.read file - else - $stdin.read - end +def option? *options + !($options & options).empty? end -begin - require 'coderay' +def tty? + $stdout.tty? || option?('--tty') +end - if ARGV.empty? - puts <<-USAGE -CodeRay #{CodeRay::VERSION} (http://coderay.rubychan.de) +def version + puts <<-USAGE +CodeRay #{CodeRay::VERSION} + USAGE +end +def help + puts <<-HELP Usage: - coderay -<lang> [-<format>] < file > output - coderay file [-<format>] + coderay [-<language>] [input] [-<format>] [output] Examples: - coderay -ruby -statistic < foo.rb - coderay -ruby < foo.rb # colorized output to terminal - coderay -ruby -page foo.rb # HTML page output to terminal - coderay -ruby -page foo.rb > foo.html # HTML page output to file - coderay codegen.c # generates codegen.c.html - USAGE - end + coderay -ruby file -loc # count lines of code in Ruby file + coderay -ruby < foo.rb # colorized output to terminal + coderay -ruby foo.rb -page foo.html # HTML page output to file + coderay stylesheet # CSS stylesheet + HELP +end + +def commands + puts <<-COMMANDS + General: + help print some help + version print CodeRay version + commands print this list + stylesheet print the CSS stylesheet with the given name + COMMANDS +end - first, second = ARGV +if option? '-v', '--version' + version +end + +if option? '-h', '--help' + help +end - if first - if first[/-(\w+)/] == first - lang = $1 - input = read - tokens = :scan - elsif first == '-' - lang = $1 - input = read - tokens = :scan +case subcommand +when 'highlight', nil + if ARGV.empty? + version + help + else + signature = $args.map { |arg| arg[/^-/] ? '-' : 'f' }.join + names = $args.map { |arg| arg.sub(/^-/, '') } + case signature + when /^$/ + exit + when /^ff?$/ + input_file, output_file, = *names + when /^-ff?$/ + input_filetype, input_file, output_file, = *names + when /^-f-f?$/ + input_filetype, input_file, output_filetype, output_file, = *names + when /^--?f?$/ + input_filetype, output_filetype, output_file, = *names else - file = first - tokens = CodeRay.scan_file file - output_filename, output_ext = file, /#{Regexp.escape(File.extname(file))}$/ + raise signature end - else - puts 'No lang/file given.' - exit 1 - end - - if second - if second[/-(\w+)/] == second - format = $1 + + if input_file + input_filetype ||= CodeRay::FileType.fetch input_file, :text, true + end + + if output_file + output_filetype ||= CodeRay::FileType[output_file] else - raise 'invalid format (must be -xxx)' + output_filetype ||= tty? ? :term : :page end - else - if $stdout.tty? - format = :term + + if input_file + input = File.read input_file else - $stderr.puts 'No format given; setting to default (HTML Page).' - format = :page + input = $stdin.read end - end - - if tokens == :scan - output = CodeRay.encoder(format).encode(input, lang) - else - output = tokens.encode format - end - out = $stdout - if output_filename - output_filename += '.' + CodeRay::Encoders[format]::FILE_EXTENSION.to_s - if File.exist? output_filename - err 'File %s already exists.' % output_filename - exit + + output = CodeRay.scan(input, input_filetype).encode(output_filetype) + + if output_file + File.open output_file, 'w' do |file| + file.puts output + end else - out = File.open output_filename, 'w' - puts "Writing to #{output_filename}..." + puts output end end - out.puts output - -rescue => boom - err "Error: #{boom.message}\n" - err boom.backtrace - err '-' * 50 - err ARGV - exit 1 +when 'stylesheet' + puts CodeRay::Encoders[:html]::CSS.new($args.first).stylesheet +when 'commands' + commands +when 'help' + help +else + puts "Unknown command: #{subcommand}" + help end diff --git a/bin/coderay_stylesheet b/bin/coderay_stylesheet deleted file mode 100755 index 0e19395..0000000 --- a/bin/coderay_stylesheet +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env ruby -require 'coderay' - -puts CodeRay::Encoders[:html]::CSS.new.stylesheet diff --git a/etc/CodeRay.tmproj b/etc/CodeRay.tmproj index af6886f..1bbbc22 100644 --- a/etc/CodeRay.tmproj +++ b/etc/CodeRay.tmproj @@ -2,6 +2,8 @@ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> + <key>currentDocument</key> + <string>../lib/coderay/scanners/ruby.rb</string> <key>documents</key> <array> <dict> @@ -174,7 +176,55 @@ <key>firstVisibleLine</key> <integer>3</integer> </dict> + <key>../lib/coderay/scanners/ruby.rb</key> + <dict> + <key>caret</key> + <dict> + <key>column</key> + <integer>39</integer> + <key>line</key> + <integer>83</integer> + </dict> + <key>firstVisibleColumn</key> + <integer>0</integer> + <key>firstVisibleLine</key> + <integer>71</integer> + </dict> + <key>../lib/coderay/scanners/ruby/patterns.rb</key> + <dict> + <key>caret</key> + <dict> + <key>column</key> + <integer>28</integer> + <key>line</key> + <integer>28</integer> + </dict> + <key>firstVisibleColumn</key> + <integer>0</integer> + <key>firstVisibleLine</key> + <integer>0</integer> + </dict> + <key>../lib/coderay/scanners/scheme.rb</key> + <dict> + <key>caret</key> + <dict> + <key>column</key> + <integer>32</integer> + <key>line</key> + <integer>21</integer> + </dict> + <key>firstVisibleColumn</key> + <integer>0</integer> + <key>firstVisibleLine</key> + <integer>0</integer> + </dict> </dict> + <key>openDocuments</key> + <array> + <string>../lib/coderay/scanners/scheme.rb</string> + <string>../lib/coderay/scanners/ruby/patterns.rb</string> + <string>../lib/coderay/scanners/ruby.rb</string> + </array> <key>showFileHierarchyDrawer</key> <true/> <key>windowFrame</key> diff --git a/lib/coderay.rb b/lib/coderay.rb index 60dcfd0..9b81772 100644 --- a/lib/coderay.rb +++ b/lib/coderay.rb @@ -134,6 +134,9 @@ module CodeRay # Revision: Subversion Revision number (generated on rake gem:make) VERSION = '1.0.0' + # helpers + autoload :FileType, 'coderay/helpers/file_type' + # Tokens autoload :Tokens, 'coderay/tokens' autoload :TokenKinds, 'coderay/token_kinds' @@ -178,7 +181,6 @@ module CodeRay def scan_file filename, lang = :auto, options = {}, &block file = IO.read filename if lang == :auto - require 'coderay/helpers/file_type' lang = FileType.fetch filename, :text, true end scan file, lang, options = {}, &block diff --git a/rake_tasks/gem.rake b/rake_tasks/gem.rake index bef2ac9..71b55a1 100644 --- a/rake_tasks/gem.rake +++ b/rake_tasks/gem.rake @@ -31,7 +31,7 @@ def gemspec s.files = Dir['lib/**/*.rb'] + %w(Rakefile README.rdoc LICENSE) + Dir['test/functional/*.rb']
s.test_files = Dir['test/functional/*.rb']
- s.executables = [ 'coderay', 'coderay_stylesheet' ]
+ s.executables = ['coderay']
s.require_paths = ['lib']
s.rubyforge_project = s.name
diff --git a/test/executable/source.py b/test/executable/source.py new file mode 100644 index 0000000..1bb2c00 --- /dev/null +++ b/test/executable/source.py @@ -0,0 +1 @@ +class ClassName(): pass
\ No newline at end of file diff --git a/test/executable/source.rb b/test/executable/source.rb new file mode 100644 index 0000000..226f15f --- /dev/null +++ b/test/executable/source.rb @@ -0,0 +1 @@ +class ClassName; end
\ No newline at end of file diff --git a/test/executable/suite.rb b/test/executable/suite.rb index ddb0527..fd40909 100644 --- a/test/executable/suite.rb +++ b/test/executable/suite.rb @@ -1,4 +1,6 @@ require 'test/unit' +require 'shoulda-context' + require 'pathname' $:.unshift 'lib' require 'coderay' @@ -8,38 +10,187 @@ puts "Running CodeRay #{CodeRay::VERSION} executable tests..." class TestCodeRayExecutable < Test::Unit::TestCase ruby = `ps -c #$$`[/\w+\Z/] - ruby = 'jruby' if ruby == 'java' ROOT_DIR = Pathname.new(File.dirname(__FILE__)) + '..' + '..' EXECUTABLE = ROOT_DIR + 'bin' + 'coderay' EXE_COMMAND = '%s -wI%s %s'% [ - ruby, # calling Ruby process command + ruby, # calling Ruby process command ROOT_DIR + 'lib', # library dir - EXECUTABLE + EXECUTABLE # coderay ] - def coderay args - command = "#{EXE_COMMAND} #{args}" - # puts command - `#{command}` + def coderay args, fake_tty = false + if fake_tty + command = "#{EXE_COMMAND} #{args} --tty" + else + command = "#{EXE_COMMAND} #{args}" + end + puts command if $DEBUG + output = `#{command} 2>&1` + if output[EXECUTABLE.to_s] + raise output + else + output + end + end + + context 'a simple call with no arguments' do + should 'work' do + assert_nothing_raised { coderay('') } + end + should 'print version and help' do + assert_match(/CodeRay #{CodeRay::VERSION}/, coderay('')) + assert_match(/Usage:/, coderay('')) + end + end + + context 'version' do + should 'be printed with -v' do + assert_match(/\ACodeRay #{CodeRay::VERSION}\Z/, coderay('-v')) + end + should 'be printed with --version' do + assert_match(/\ACodeRay #{CodeRay::VERSION}\Z/, coderay('--version')) + end + end + + context 'help' do + should 'be printed with -h' do + assert_match(/^Usage:/, coderay('-h')) + end + should 'be printed with --help' do + assert_match(/^Usage:/, coderay('--help')) + end + should 'be printed with subcommand help' do + assert_match(/^Usage:/, coderay('help')) + end + end + + context 'commands' do + should 'be printed with subcommand commands' do + assert_match(/^ +help/, coderay('commands')) + assert_match(/^ +version/, coderay('commands')) + end + end + + context 'highlighting a file to the terminal' do + source_file = 'test/executable/source.py' + + source = File.read source_file + + ansi_seq = /\e\[[0-9;]+m/ + + should 'not throw an error' do + assert_nothing_raised { coderay(source_file, :tty) } + end + should 'output its contents to stdout' do + target = coderay(source_file, :tty) + assert_equal source, target.chomp.gsub(ansi_seq, '') + end + should 'output ANSI-colored text' do + target = coderay(source_file, :tty) + assert_not_equal source, target.chomp + assert_equal 6, target.scan(ansi_seq).size + end + end + + context 'highlighting a file into a pipe (source.rb > source.rb.html)' do + source_file = 'test/executable/source.rb' + target_file = "#{source_file}.html" + command = "#{source_file} > #{target_file}" + + source = File.read source_file + + pre = %r{<pre [^>]*>(.*?)</pre>}m + tag = /<[^>]*>/ + + should 'not throw an error' do + assert_nothing_raised { coderay(command) } + end + should 'output its contents to the pipe' do + coderay(command) + target = File.read(target_file) + if target = target[pre, 1] + assert_equal source, target.gsub(tag, '').strip + else + flunk "target code has no <pre> tag: #{target}" + end + end + should 'output valid HTML' do + coderay(command) + target = File.read(target_file) + assert_not_equal source, target[pre, 1] + assert_equal 6, target[pre, 1].scan(tag).size + assert_match %r{\A<!DOCTYPE html>\n<html>\n<head>}, target + end + end + + context 'highlighting a file into another file (source.rb source.rb.json)' do + source_file = 'test/executable/source.rb' + target_file = "#{source_file}.json" + command = "#{source_file} #{target_file}" + + source = File.read source_file + + text = /"text":"([^"]*)"/ + + should 'not throw an error' do + assert_nothing_raised { coderay(command) } + end + should 'output its contents to the file' do + coderay(command) + target = File.read(target_file) + assert_equal source, target.scan(text).join + end + should 'output JSON' do + coderay(command) + target = File.read(target_file) + assert_not_equal source, target + assert_equal 6, target.scan(text).size + end end - def test_simple - assert_nothing_raised { coderay('') } + context 'highlighting a file without explicit input type (source.py)' do + source_file = 'test/executable/source.py' + command = source_file + + source = File.read source_file + + pre = %r{<pre [^>]*>(.*?)</pre>}m + tag_class = /<span class="([^>"]*)"?[^>]*>/ + + should 'respect the file extension and highlight the input as Python' do + target = coderay(command) + assert_equal %w(kw cl kw), target[pre, 1].scan(tag_class).flatten + end end - VERSION_PATTERN = /CodeRay \d\.\d\.\d/ - def test_version - assert_match(VERSION_PATTERN, coderay('')) - # assert_match(VERSION_PATTERN, coderay('--version')) - # assert_match(VERSION_PATTERN, coderay('-v')) + context 'highlighting a file with explicit input type (-ruby source.py)' do + source_file = 'test/executable/source.py' + command = "-ruby #{source_file}" + + source = File.read source_file + + pre = %r{<pre [^>]*>(.*?)</pre>}m + tag_class = /<span class="([^>"]*)"?[^>]*>/ + + should 'ignore the file extension and highlight the input as Ruby' do + target = coderay(command) + assert_equal %w(kw cl), target[pre, 1].scan(tag_class).flatten + end end - HELP_PATTERN = /Usage:/ - def test_help - assert_match(HELP_PATTERN, coderay('')) - # assert_match(HELP_PATTERN, coderay('--help')) - # assert_match(HELP_PATTERN, coderay('-h')) + context 'highlighting a file with explicit input and output type (-ruby source.py -span)' do + source_file = 'test/executable/source.py' + command = "-ruby #{source_file} -span" + + source = File.read source_file + + span_tags = /<\/?span[^>]*>/ + + should 'just respect the output type and include span tags' do + target = coderay(command) + assert_equal source, target.chomp.gsub(span_tags, '') + end end -end
\ No newline at end of file +end |