Last active
August 29, 2015 14:22
-
-
Save jcsjcs/e56dff5137d48578bfc0 to your computer and use it in GitHub Desktop.
Format code in syntax-highlighted html for clipboard using xclip and rouge.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# Format code with syntax highlighting for pasting in emails. | |
# To use: | |
# 1) Highlight the code. | |
# 2) fmail ruby/sql/java_script etc... | |
# 3) Middle-click in email to paste html code. | |
# | |
# CLI program xclip must be installed. http://sourceforge.net/projects/xclip/ | |
require_relative 'trollop' | |
require 'rouge' | |
require 'open3' | |
begin | |
str = `xclip -o` | |
rescue Errno::ENOENT # Requires xclip | |
puts "\"xclip\" is not installed." | |
exit 1 | |
end | |
global_opts = Trollop::options do | |
banner <<-EOS | |
fmail - Format code on the middle-mouse clipboard for pasting as HTML | |
Usage: | |
<<Select (highlight) code>> | |
fmail [-ib] <format> | |
<<Middle-click mouse button to paste HTML>> | |
Use one of the following formats (e.g. fmail -i sql): | |
\t#{Rouge::Lexer.all.map {|l| [l.tag, l.aliases] }.sort.map {|l| [l.first, l.last].flatten.sort.uniq.map {|a| a.ljust(20)} }.flatten.each_slice(5).map {|a| a.join(" ") }.join("\n\t")} | |
Options: | |
EOS | |
opt :inline, "Wrap the output in <code> instead of <pre>.", :short => "-i" | |
opt :base16, "Use the base16 colour theme instead of the github theme.", :short => "-b" | |
opt :lineno, "Print line numbers. Not compatible with --inline.", :short => "-l" | |
end | |
cmd = ARGV.shift # get the subcommand | |
Trollop::die "please provide a format" if cmd.nil? | |
Trollop::die "unknown format #{cmd.inspect}" unless Rouge::Lexer.find(cmd) | |
inline = global_opts[:inline] | |
is_irb = 'irb' == cmd | |
cmd = 'ruby' if is_irb | |
opts = {:css_class => nil, :inline_theme => global_opts[:base16] ? 'base16' : 'github', :line_numbers => global_opts[:lineno]} | |
if is_irb | |
opts[:wrap] = false | |
formatter = Rouge::Formatters::HTML.new(opts) | |
new = [] | |
lexer = Rouge::Lexers::Ruby.new | |
arb4 = str.split("\n") | |
arb4.each do |a| | |
m = a.match(/^.+?>/) | |
b = m.nil? ? '' : m[0] | |
c = b =~ /.*=>/ ? '<span style="background-color:#ffff00;color:#00f">=></span>' : '' | |
new << (c << formatter.format(lexer.lex(a.sub(b, '')))) | |
end | |
output = "<#{pre}>#{new.join("\n")}</#{pre}>" | |
else | |
opts[:wrap] = false if inline | |
formatter = Rouge::Formatters::HTML.new(opts) | |
if inline | |
tag_start = '<code>' | |
tag_end = '</code>' | |
else | |
tag_start = '' | |
tag_end = '' | |
end | |
lexer = Rouge::Lexer.find(cmd) | |
output = "#{tag_start}#{formatter.format(lexer.lex(str))}#{tag_end}" | |
end | |
# Pipe output to xclip... | |
Open3.popen2e("xclip") {|i,o,t| | |
i << output | |
i.close | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment