class Rouge::CLI::Highlight
def self.desc
def self.desc "highlight code" end
def self.doc
def self.doc return enum_for(:doc) unless block_given? yield %[usage: rougify highlight <filename> [options...]] yield %[ rougify highlight [options...]] yield %[] yield %[--input-file|-i <filename> specify a file to read, or - to use stdin] yield %[] yield %[--lexer|-l <lexer> specify the lexer to use.] yield %[ If not provided, rougify will try to guess] yield %[ based on --mimetype, the filename, and the] yield %[ file contents.] yield %[] yield %[--formatter-preset|-f <opts> specify the output formatter to use.] yield %[ If not provided, rougify will default to] yield %[ terminal256. options are: terminal256,] yield %[ terminal-truecolor, html, html-pygments,] yield %[ html-inline, html-line-table, html-table,] yield %[ null/raw/tokens, or tex.] yield %[] yield %[--theme|-t <theme> specify the theme to use for highlighting] yield %[ the file. (only applies to some formatters)] yield %[] yield %[--mimetype|-m <mimetype> specify a mimetype for lexer guessing] yield %[] yield %[--lexer-opts|-L <opts> specify lexer options in CGI format] yield %[ (opt1=val1&opt2=val2)] yield %[] yield %[--formatter-opts|-F <opts> specify formatter options in CGI format] yield %[ (opt1=val1&opt2=val2)] yield %[] yield %[--require|-r <filename> require a filename or library before] yield %[ highlighting] yield %[] yield %[--escape allow the use of escapes between <! and !>] yield %[] yield %[--escape-with <l> <r> allow the use of escapes between custom] yield %[ delimiters. implies --escape] end
def self.parse(argv)
def self.parse(argv) new(parse_opts(argv)) end
def self.parse_cgi(str)
def self.parse_cgi(str) (str).map { |k, v| [k.to_sym, v.first] }
def self.parse_opts(argv)
def self.parse_opts(argv) opts = { :formatter => supports_truecolor? ? 'terminal-truecolor' : 'terminal256', :theme => 'thankful_eyes', :css_class => 'codehilite', :input_file => '-', :lexer_opts => {}, :formatter_opts => {}, :requires => [], } until argv.empty? arg = argv.shift case arg when '-r', '--require' opts[:requires] << argv.shift when '--input-file', '-i' opts[:input_file] = argv.shift when '--mimetype', '-m' opts[:mimetype] = argv.shift when '--lexer', '-l' opts[:lexer] = argv.shift when '--formatter-preset', '-f' opts[:formatter] = argv.shift when '--theme', '-t' opts[:theme] = argv.shift when '--css-class', '-c' opts[:css_class] = argv.shift when '--lexer-opts', '-L' opts[:lexer_opts] = parse_cgi(argv.shift) when '--escape' opts[:escape] = ['<!', '!>'] when '--escape-with' opts[:escape] = [argv.shift, argv.shift] when /^--/ error! "unknown option #{arg.inspect}" else opts[:input_file] = arg end end opts end
def self.supports_truecolor?
There is no consistent way to do this, but this is used elsewhere,
def self.supports_truecolor? return true if %w(24bit truecolor).include?(ENV['COLORTERM']) return false if ENV['COLORTERM'] && ENV['COLORTERM'] =~ /256/ if RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ ENV['ConEmuANSI'] == 'ON' && !ENV['ANSICON'] else ENV['TERM'] !~ /(^rxvt)|(-color$)/ end end
def escape_lexer
def escape_lexer Rouge::Lexers::Escape.new( start: @escape[0], end: @escape[1], lang: raw_lexer, ) end
def initialize(opts={})
def initialize(opts={}) Rouge::Lexer.enable_debug! opts[:requires].each do |r| require r end @input_file = opts[:input_file] if opts[:lexer] @lexer_class = Lexer.find(opts[:lexer]) \ or error! "unknown lexer #{opts[:lexer].inspect}" else @lexer_name = opts[:lexer] @mimetype = opts[:mimetype] end @lexer_opts = opts[:lexer_opts] theme = Theme.find(opts[:theme]).new or error! "unknown theme #{opts[:theme]}" # TODO: document this in --help @formatter = case opts[:formatter] when 'terminal256' then Formatters::Terminal256.new(theme) when 'terminal-truecolor' then Formatters::TerminalTruecolor.new(theme) when 'html' then Formatters::HTML.new when 'html-pygments' then Formatters::HTMLPygments.new(Formatters::HTML.new, opts[:css_class]) when 'html-inline' then Formatters::HTMLInline.new(theme) when 'html-line-table' then Formatters::HTMLLineTable.new(Formatters::HTML.new) when 'html-table' then Formatters::HTMLTable.new(Formatters::HTML.new) when 'null', 'raw', 'tokens' then Formatters::Null.new when 'tex' then Formatters::Tex.new else error! "unknown formatter preset #{opts[:formatter]}" end @escape = opts[:escape] end
def input
def input @input ||= input_stream.read end
def input_stream
def input_stream @input_stream ||= FileReader.new(@input_file) end
def lexer
def lexer @lexer ||= @escape ? escape_lexer : raw_lexer end
def lexer_class
def lexer_class @lexer_class ||= Lexer.guess( :filename => @input_file, :mimetype => @mimetype, :source => input_stream, ) end
def raw_lexer
def raw_lexer lexer_class.new(@lexer_opts) end
def run
def run Formatter.enable_escape! if @escape formatter.format(lexer.lex(input), &method(:print)) end