To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

Statistics Download as Zip
| Branch: | Tag: | Revision:

root / .svn / pristine / 8c / 8cc3b49fb336589b0c77ad88bf1cb1e4d4cc2b4b.svn-base @ 1297:0a574315af3e

History | View | Annotate | Download (5.62 KB)

1
#!/usr/bin/env ruby
2
require 'coderay'
3

    
4
$options, args = ARGV.partition { |arg| arg[/^-[hv]$|--\w+/] }
5
subcommand = args.first if /^\w/ === args.first
6
subcommand = nil if subcommand && File.exist?(subcommand)
7
args.delete subcommand
8

    
9
def option? *options
10
  !($options & options).empty?
11
end
12

    
13
def tty?
14
  $stdout.tty? || option?('--tty')
15
end
16

    
17
def version
18
  puts <<-USAGE
19
CodeRay #{CodeRay::VERSION}
20
  USAGE
21
end
22

    
23
def help
24
  puts <<-HELP
25
This is CodeRay #{CodeRay::VERSION}, a syntax highlighting tool for selected languages.
26

    
27
usage:
28
  coderay [-language] [input] [-format] [output]
29
  
30
defaults:
31
  language   detect from input file name or shebang; fall back to plain text
32
  input      STDIN
33
  format     detect from output file name or use terminal; fall back to HTML
34
  output     STDOUT
35

    
36
common:
37
  coderay file.rb                      # highlight file to terminal
38
  coderay file.rb > file.html          # highlight file to HTML page
39
  coderay file.rb -div > file.html     # highlight file to HTML snippet
40

    
41
configure output:
42
  coderay file.py output.json          # output tokens as JSON
43
  coderay file.py -loc                 # count lines of code in Python file
44

    
45
configure input:
46
  coderay -python file                 # specify the input language
47
  coderay -ruby                        # take input from STDIN
48

    
49
more:
50
  coderay stylesheet [style]           # print CSS stylesheet
51
  HELP
52
end
53

    
54
def commands
55
  puts <<-COMMANDS
56
  general:
57
    highlight   code highlighting (default command, optional)
58
    stylesheet  print the CSS stylesheet with the given name (aliases: style, css)
59
  
60
  about:
61
    list [of]   list all available plugins (or just the scanners|encoders|styles|filetypes)
62
    commands    print this list
63
    help        show some help
64
    version     print CodeRay version
65
  COMMANDS
66
end
67

    
68
def print_list_of plugin_host
69
  plugins = plugin_host.all_plugins.map do |plugin|
70
    info = "  #{plugin.plugin_id}: #{plugin.title}"
71
    
72
    aliases = (plugin.aliases - [:default]).map { |key| "-#{key}" }.sort_by { |key| key.size }
73
    if plugin.respond_to?(:file_extension) || !aliases.empty?
74
      additional_info = []
75
      additional_info << aliases.join(', ') unless aliases.empty?
76
      info << " (#{additional_info.join('; ')})"
77
    end
78
    
79
    info << '  <-- default' if plugin.aliases.include? :default
80
    
81
    info
82
  end
83
  puts plugins.sort
84
end
85

    
86
if option? '-v', '--version'
87
  version
88
end
89

    
90
if option? '-h', '--help'
91
  help
92
end
93

    
94
case subcommand
95
when 'highlight', nil
96
  if ARGV.empty?
97
    version
98
    help
99
  else
100
    signature = args.map { |arg| arg[/^-/] ? '-' : 'f' }.join
101
    names     = args.map { |arg| arg.sub(/^-/, '') }
102
    case signature
103
    when /^$/
104
      exit
105
    when /^ff?$/
106
      input_file, output_file, = *names
107
    when /^f-f?$/
108
      input_file, output_format, output_file, = *names
109
    when /^-ff?$/
110
      input_lang, input_file, output_file, = *names
111
    when /^-f-f?$/
112
      input_lang, input_file, output_format, output_file, = *names
113
    when /^--?f?$/
114
      input_lang, output_format, output_file, = *names
115
    else
116
      $stdout = $stderr
117
      help
118
      puts
119
      puts "Unknown parameter order: #{args.join ' '}, expected: [-language] [input] [-format] [output]"
120
      exit 1
121
    end
122
    
123
    if input_file
124
      input_lang ||= CodeRay::FileType.fetch input_file, :text, true
125
    end
126
    
127
    if output_file
128
      output_format ||= CodeRay::FileType[output_file]
129
    else
130
      output_format ||= :terminal
131
    end
132
    
133
    output_format = :page if output_format.to_s == 'html'
134
    
135
    if input_file
136
      input = File.read input_file
137
    else
138
      input = $stdin.read
139
    end
140
    
141
    begin
142
      file =
143
        if output_file
144
          File.open output_file, 'w'
145
        else
146
          $stdout.sync = true
147
          $stdout
148
        end
149
      CodeRay.encode(input, input_lang, output_format, :out => file)
150
      file.puts
151
    rescue CodeRay::PluginHost::PluginNotFound => boom
152
      $stdout = $stderr
153
      if boom.message[/CodeRay::(\w+)s could not load plugin :?(.*?): /]
154
        puts "I don't know the #$1 \"#$2\"."
155
      else
156
        puts boom.message
157
      end
158
      # puts "I don't know this plugin: #{boom.message[/Could not load plugin (.*?): /, 1]}."
159
    rescue CodeRay::Scanners::Scanner::ScanError  # FIXME: rescue Errno::EPIPE
160
      # this is sometimes raised by pagers; ignore [TODO: wtf?]
161
    ensure
162
      file.close if output_file
163
    end
164
  end
165
when 'li', 'list'
166
  arg = args.first && args.first.downcase
167
  if [nil, 's', 'sc', 'scanner', 'scanners'].include? arg
168
    puts 'input languages (Scanners):'
169
    print_list_of CodeRay::Scanners
170
  end
171
  
172
  if [nil, 'e', 'en', 'enc', 'encoder', 'encoders'].include? arg
173
    puts 'output formats (Encoders):'
174
    print_list_of CodeRay::Encoders
175
  end
176
  
177
  if [nil, 'st', 'style', 'styles'].include? arg
178
    puts 'CSS themes for HTML output (Styles):'
179
    print_list_of CodeRay::Styles
180
  end
181
  
182
  if [nil, 'f', 'ft', 'file', 'filetype', 'filetypes'].include? arg
183
    puts 'recognized file types:'
184
    
185
    filetypes = Hash.new { |h, k| h[k] = [] }
186
    CodeRay::FileType::TypeFromExt.inject filetypes do |types, (ext, type)|
187
      types[type.to_s] << ".#{ext}"
188
      types
189
    end
190
    CodeRay::FileType::TypeFromName.inject filetypes do |types, (name, type)|
191
      types[type.to_s] << name
192
      types
193
    end
194
    
195
    filetypes.sort.each do |type, exts|
196
      puts "  #{type}: #{exts.sort_by { |ext| ext.size }.join(', ')}"
197
    end
198
  end
199
when 'stylesheet', 'style', 'css'
200
  puts CodeRay::Encoders[:html]::CSS.new(args.first).stylesheet
201
when 'commands'
202
  commands
203
when 'help'
204
  help
205
else
206
  $stdout = $stderr
207
  help
208
  puts
209
  if subcommand[/\A\w+\z/]
210
    puts "Unknown command: #{subcommand}"
211
  else
212
    puts "File not found: #{subcommand}"
213
  end
214
  exit 1
215
end