Skip to content

Instantly share code, notes, and snippets.

@melborne
Last active June 27, 2017 20:11
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save melborne/4642105 to your computer and use it in GitHub Desktop.
Save melborne/4642105 to your computer and use it in GitHub Desktop.
Text Upside Down with Ruby. data source: twitter→ɹəʇʇɪʍʇのように英数字を180度回転して表示する方法|Colorless Green Ideas http://id.fnshr.info/2013/01/25/upsidedowntext/
# encoding: UTF-8
require "nokogiri"
require "open-uri"
class Scraper
class << self
def build(path, target)
parse get(path), target
end
def get(url)
Nokogiri::HTML(open url)
rescue OpenURI::HTTPError => e
STDERR.puts "HTTP Access Error:#{e}"
exit
end
def parse(html, target)
q = []
html.css(target).each do |tr|
q << tr
end
q
end
end
end
#!/usr/bin/env ruby
require_relative 'textupdown'
require "optparse"
opt = OptionParser.new
method = :text
opt.on('-c') { method = :code }
opt.on('-t') { method = :text }
opt.parse!(ARGV)
puts TextUpDown.new.send(method, ARGV.join(' '))
__END__
Usage:
% updown hello, world!
% updown -c hello, world! #get codepoints
# encoding: UTF-8
# Text Upside Down with Ruby by kyoendo
# Data source from Fumiaki Nishihara
# Read this;
# twitter→ɹəʇʇɪʍʇのように英数字を180度回転して表示する方法|Colorless Green Ideas
# http://id.fnshr.info/2013/01/25/upsidedowntext/
require "yaml"
require_relative "scraper"
class TextUpDown
URL = "http://id.fnshr.info/2013/01/25/upsidedowntext/"
Path = File.expand_path(File.dirname(__FILE__))
PAIR = %w(( [ < ) ] >)
def initialize
@table = nil
@code = {}
end
def text(text)
code(text).map do |c|
case c
when /^U\+/
$'.to_i(16).chr('UTF-8')
when *PAIR
PAIR[ (PAIR.index(c) + 3) % PAIR.size ]
else
c
end
end.join
end
def code(text)
@code[text] ||= begin
text.reverse.chars.map { |chr| (table[chr] || [chr]).sample }
end
end
def table(path=nil)
path = File.join(Path, 'textupdown.yaml') unless path
@table ||= begin
data =
if File.exist?(path)
YAML.load_file(path)
else
get(URL).tap do |res|
File.write(path, YAML.dump(res))
end
end
build_table(data)
end
end
def get(url)
body = Scraper.build(url, 'table tr')
body.map { |tr| tr.search('td').map(&:text) }.delete_if(&:empty?)
end
def build_table(table)
res = table.group_by(&:first).map do |k, records|
[k, records.map { |r| r.last }]
end
Hash[res]
end
end
if __FILE__ == $0
t = TextUpDown.new
t.code('twitter')
t.text("twitter")
end
# -*- coding:utf-8 -*-
# Termtter plugin for ugly messages by kyoendo
require "textupdown"
if RUBY_VERSION < '1.9.0'
$KCODE = 'u'
require "jcode"
end
class String
def mirror(opt)
reversed = RUBY_VERSION < '1.9.0' ? self.split(//).reverse.join : self.reverse
opt.empty? ? self.replace(reversed) : self.replace(self.chop + reversed)
end
def rot13(opt=nil)
from = 'A-Ma-mN-Zn-zあ-なア-ナに-んニ-ン'
to = 'N-Zn-zA-Ma-mに-んニ-ンあ-なア-ナ'
if RUBY_VERSION >= '1.9.0'
from += '一-盒盓-龥'
to += '盓-龥一-盒'
end
self.tr(from, to)
end
def scooch(opt)
opt = opt.to_i.zero? ? 1 : opt.to_i
self.split(//).map { |c| opt.times { c = c.next }; c }.join
end
def updown(opt=nil)
TextUpDown.new.text(self)
end
end
module Termtter::Client
uglies = {
:update_mirror => [[:um], :mirror, 'Mirror message'],
:update_rot13 => [[:u13], :rot13, 'Rot13 message'],
:update_scooch => [[:us], :scooch, 'Scooch message'],
:update_crypt => [[:uc], :crypt, 'Crypt message'],
:update_updown => [[:uud], :updown, 'Upside down message'],
}
uglies.each do |name, (aliases, meth, help)|
register_command(
:name => name, :aliases => aliases,
:exec_proc => lambda {|arg|
opt = ''
arg.sub!(/^-\s*([\d\w]+)\s+/) { opt = $1; '' }
text = "#{arg.send(meth, opt)} ##{meth.to_s}"
text = text + "#{opt}" if [:update_crypt, :update_scooch].include? name
Termtter::API::twitter.update(text)
puts "=> #{text}"
},
:help => ["#{name},#{aliases.join(',')} [-VALUE] TEXT", help]
)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment