summaryrefslogtreecommitdiff
path: root/bin/coderay
blob: 2a4ba3bed316dc92fff05a871f1e25e52f2da4c5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#!/usr/bin/env ruby
require 'coderay'

$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 option? *options
  !($options & options).empty?
end

def tty?
  $stdout.tty? || option?('--tty')
end

def version
  puts <<-USAGE
CodeRay #{CodeRay::VERSION}
  USAGE
end

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

usage:
  coderay [-language] [input] [-format] [output]
  
defaults:
  language   detect from input file name or shebang; fall back to plain text
  input      STDIN
  format     detect from output file name or use terminal; fall back to HTML page
  output     STDOUT

common:
  coderay file.rb                      # highlight file to terminal
  coderay file.rb > file.html          # highlight file to HTML page
  coderay file.rb -div > file.html     # highlight file to HTML snippet

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

configure input:
  coderay -python file                 # specify the input language
  coderay -ruby                        # take input from STDIN

more:
  coderay stylesheet [style]           # print CSS stylesheet
  HELP
end

def commands
  puts <<-COMMANDS
  general:
    highlight   code highlighting (default command)
    stylesheet  print the CSS stylesheet with the given name
  
  about:
    list [of]   list all available plugins (or just the scanners|encoders)
    commands    print this list
    help        show some help
    version     print CodeRay version
  COMMANDS
end

if option? '-v', '--version'
  version
end

if option? '-h', '--help'
  help
end

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 /^f-f?$/
      input_file, output_filetype, 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
      raise signature
    end
    
    if input_file
      input_filetype ||= CodeRay::FileType.fetch input_file, :text, true
    end
    
    if output_file
      output_filetype ||= CodeRay::FileType[output_file]
    else
      output_filetype ||= tty? ? :term : :page
    end
    
    if input_file
      input = File.read input_file
    else
      input = $stdin.read
    end
    
    output = CodeRay.scan(input, input_filetype).encode(output_filetype)
    
    if output_file
      File.open output_file, 'w' do |file|
        file.puts output
      end
    else
      puts output
    end
  end
when 'list'
  arg = args.first && args.first.downcase
  if [nil, 's', 'sc', 'scanner', 'scanners'].include? arg
    puts 'input languages (Scanners):'
    scanners = CodeRay::Scanners.all_plugins.map do |plugin|
      aliases = (plugin.aliases - [nil]).map { |key| "-#{key}" }.sort_by { |key| key.size }
      "  #{plugin.lang}: #{plugin.title}#{" (.#{plugin.file_extension}; #{aliases.join(', ')})" unless aliases.empty?}"
    end
    puts scanners.sort
    puts
  end
  
  if [nil, 'e', 'en', 'enc', 'encoder', 'encoders'].include? arg
    puts 'output formats (Encoders):'
    encoders = CodeRay::Encoders.all_plugins.map do |plugin|
      aliases = (plugin.aliases - [nil]).map { |key| "-#{key}" }.sort_by { |key| key.size }
      "  #{plugin.plugin_id}: #{plugin.title}#{" (.#{plugin.file_extension}; #{aliases.join(', ')})" unless aliases.empty?}"
    end
    puts encoders.sort
  end
when 'stylesheet'
  puts CodeRay::Encoders[:html]::CSS.new(args.first).stylesheet
when 'commands'
  commands
when 'help'
  help
else
  puts "Unknown command: #{subcommand}"
  help
end