Skip to content

Instantly share code, notes, and snippets.

@tompng
Last active April 28, 2024 18:20
Show Gist options
  • Save tompng/d5fb2c649d92b06321e56c991294f54e to your computer and use it in GitHub Desktop.
Save tompng/d5fb2c649d92b06321e56c991294f54e to your computer and use it in GitHub Desktop.
Copy ansi_colored_text or ruby_code as rich text
require 'open3'
# Usage: cat code.rb | ruby ansi_pbcopy.rb --size 64 --font monospace
FONT = ARGV[ARGV.index('--font') + 1] rescue 'courier'
SIZE = ARGV[ARGV.index('--size') + 1] rescue 16
COLORS = ARGV[ARGV.index('--color') + 1].split rescue %w[#000000 #A00000 #008000 #606000 #0000C0 #800080 #008080 #808080]
initial = { bg: 9, fg: 9, bold: false, italic: false, underline: false }
style = initial.dup
def style2css(style)
css = []
css << 'font-weight: bold;' if style[:bold]
css << 'font-style: italic;' if style[:italic]
css << 'text-decoration: underline;' if style[:underline]
css << "color: #{COLORS[style[:fg]] || 'black'};"
css << "background-color: #{COLORS[style[:bg]]};" if COLORS[style[:bg]]
css.join
end
input = STDIN.read
if input !~ /\e\[[\d;]*m/
require 'irb'
def (IRB::Color).colorable?() = true
input = IRB::Color.colorize_code(input)
end
html = input.gsub(/(\n|\e\[[\d;]*[a-zA-Z])|[^\e\n]+/) do |seq|
next "<br>\n" if seq == "\n"
next seq.gsub('&', '&amp;').gsub('<', '&lt;').gsub('>', '&gt;').gsub('"', '&quot') unless seq.start_with?("\e")
next '' if seq[-1] != 'm'
numbers = seq.scan(/\d+/).map(&:to_i)
style = initial.dup if numbers.empty?
numbers.each do |n|
case n
when 0
style = initial.dup
when 1
style[:bold] = true
when 3
style[:italic] = true
when 4
style[:underline] = true
when 30..37
style[:fg] = n - 30
when 40..47
style[:bg] = n - 40
end
end
"</span><span style='#{style2css(style)}'>"
end
html = "<meta charset='utf-8'><span style='font-family:#{FONT};font-size:#{SIZE}px;white-space:pre'><span>#{html}</span></span>"
rtf, = Open3.capture2('textutil -stdin -format html -convert rtf -stdout', stdin_data: html)
Open3.capture2('pbcopy', stdin_data: rtf)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment