Commit dc61de23 by Andrew Cantino

Merge remote-tracking branch 'mwunsch/master'

Conflicts:
	lib/rumoji/emoji/symbols.rb
parents 9647b786 344433e1
language: ruby
rvm:
- 1.9.3
- 2.0.0
- 2.1.0
- rbx
matrix:
allow_failures:
- rvm: rbx
......@@ -4,3 +4,8 @@ source 'https://rubygems.org'
gemspec
gem 'rake'
platforms :rbx do
gem 'rubysl', '~> 2.0'
gem 'minitest'
end
Copyright (c) 2012 Mark Wunsch
Copyright (c) 2013 Mark Wunsch
MIT License
......@@ -19,4 +19,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
......@@ -48,12 +48,10 @@ On the command line
Implement the emoji codes from emoji-cheat-sheet.com using a tool like [gemoji](https://github.com/github/gemoji) along with Rumoji, and you'll easily be able to transform user input with raw emoji unicode into images you can show to all users.
Currently, Rumoji only supports the _People_ and _Nature_ characters in emoji-cheat-sheet, but that will change!
_Having trouble discerning what's happening in this README?_ You might be on a device with NO emoji support! All the more reason to use Rumoji. Transcode the raw unicode into something users can understand across devices!
Thanks!
## Copyright
Copyright (c) 2009 - 2012 Mark Wunsch. Licensed under the [MIT License](http://opensource.org/licenses/mit-license.php).
Copyright (c) 2012 - 2015 Mark Wunsch. Licensed under the [MIT License](http://opensource.org/licenses/mit-license.php).
......@@ -8,24 +8,49 @@ module Rumoji
# Transform emoji into its cheat-sheet code
def encode(str)
remapped_codepoints = str.codepoints.flat_map do |codepoint|
emoji = Emoji.find_by_codepoint(codepoint)
emoji ? emoji.code.codepoints.entries : codepoint
end
remapped_codepoints.pack("U*")
io = StringIO.new(str)
encode_io(io).string
end
# Transform a cheat-sheet code into an Emoji
def decode(str)
str.gsub(/:(\S?\w+):/) {|sym| Emoji.find($1.intern).to_s }
str.gsub(/:([^s:]?[\w-]+):/) {|sym| (Emoji.find($1.intern) || sym).to_s }
end
def encode_io(readable, writeable=StringIO.new(""))
previous_codepoints = []
readable.each_codepoint do |codepoint|
emoji = Emoji.find_by_codepoint(codepoint)
emoji_or_character = emoji ? emoji.code : [codepoint].pack("U")
writeable.write emoji_or_character
possible_emoji = Emoji.select_by_codepoint(codepoint)
sequence = if possible_emoji.empty?
# If this codepoint is not part of an emoji
# just write it back out, along with any previously stored codepoints.
dump_codepoints_to_string(previous_codepoints << codepoint)
elsif !possible_emoji.any?(&:multiple?)
# If this codepoint is part of an emoji, but not one
# that contains multiple codepoints, write out the
# first possiblity's cheat code and the previously stored codepoints
dump_codepoints_to_string(previous_codepoints) << possible_emoji.first.code
else
# This codepoint is a part of an emoji with multiple
# codepoints, so push it onto the stack.
previous_codepoints.push(codepoint)
# Check and see if this completes the emoji, otherwise,
# write out an empty string.
if found = possible_emoji.find {|e| e.codepoints.eql?(previous_codepoints) }
previous_codepoints.clear and found.code
else
""
end
end
writeable.write sequence
end
# Write any remaining codepoints.
writeable.write dump_codepoints_to_string(previous_codepoints) if previous_codepoints.any?
writeable
end
......@@ -36,4 +61,12 @@ module Rumoji
writeable
end
private
def dump_codepoints_to_string(codepoints)
codepoints.pack("U*").tap do
codepoints.clear
end
end
end
......@@ -23,7 +23,7 @@ module Rumoji
end
def to_s
@codepoints.to_a.pack("U*")
codepoints.pack("U*")
end
def hash
......@@ -34,6 +34,14 @@ module Rumoji
@codepoints.map{|point| point.to_s(16).upcase }.join("-")
end
def codepoints
@codepoints.entries
end
def multiple?
codepoints.size > 1
end
autoload :PEOPLE, 'rumoji/emoji/people'
autoload :NATURE, 'rumoji/emoji/nature'
autoload :OBJECTS, 'rumoji/emoji/objects'
......@@ -50,8 +58,13 @@ module Rumoji
ALL.find {|emoji| emoji.to_s == string }
end
def self.select_by_codepoint(codepoint)
ALL.select {|emoji| emoji.codepoints.include? codepoint }
end
def self.find_by_codepoint(codepoint)
ALL.find {|emoji| emoji.hex == codepoint.to_s(16).upcase }
end
end
end
......@@ -97,7 +97,7 @@ module Rumoji
self.new("\u{1F333}", [:deciduous_tree]),
self.new("\u{1F330}", [:chestnut]),
self.new("\u{1F331}", [:seedling]),
self.new("\u{1F33C}", [:blossum]), # "daisy"
self.new("\u{1F33C}", [:blossom]), # "daisy"
self.new("\u{1F33E}", [:ear_of_rice]),
self.new("\u{1F41A}", [:shell], "SPIRAL SHELL"),
self.new("\u{1F310}", [:globe_with_meridians]), # "used to indicate international input source, world clocks with time zones, etc."
......
......@@ -20,7 +20,7 @@ module Rumoji
self.new("\u{1F60C}", [:satisfied], "RELIEVED FACE"),
self.new("\u{1F601}", [:grin], "GRINNING FACE WITH SMILING EYES"),
self.new("\u{1F609}", [:wink], "WINKING FACE"),
self.new("\u{1F61C}", [:wink2, :stuck_out_tongue_winking_eye], "FACE WITH STUCK OUT TONGUE AND WINKING EYE"), # "kidding, not serious"
self.new("\u{1F61C}", [:stuck_out_tongue_winking_eye, :wink2], "FACE WITH STUCK OUT TONGUE AND WINKING EYE"), # "kidding, not serious"
self.new("\u{1F61D}", [:stuck_out_tongue_closed_eyes], "FACE WITH STUCK-OUT TONGUE AND TIGHTLY-CLOSED EYES"), # "kidding, not serious"
self.new("\u{1F600}", [:grinning], "GRINNING FACE"),
self.new("\u{1F617}", [:kissing], "KISSING FACE"),
......@@ -40,7 +40,7 @@ module Rumoji
self.new("\u{1F613}", [:sweat], "FACE WITH COLD SWEAT"),
self.new("\u{1F629}", [:weary], "WEARY FACE"),
self.new("\u{1F614}", [:pensive], "PENSIVE FACE"),
self.new("\u{1F61E}", [:dissapointed], "DISAPPOINTED FACE"),
self.new("\u{1F61E}", [:disappointed], "DISAPPOINTED FACE"),
self.new("\u{1F616}", [:confounded], "CONFOUNDED FACE"),
self.new("\u{1F628}", [:fearful], "FEARFUL FACE"),
self.new("\u{1F630}", [:cold_sweat], "FACE WITH OPEN MOUTH AND COLD SWEAT"),
......@@ -94,7 +94,7 @@ module Rumoji
self.new("\u{1F3B5}", [:musical_note]), # "music, being in good mood"
self.new("\u{1F525}", [:fire], "FIRE"),
# Poop
self.new("\u{1F4A9}", [:hankey, :poop, :shit], "PILE OF POO"), # "dog dirt"
self.new("\u{1F4A9}", [:poop, :hankey, :shit], "PILE OF POO"), # "dog dirt"
self.new("\u{1F44D}", [:thumbsup, :"+1"], "THUMBS UP SIGN"),
self.new("\u{1F44E}", [:thumbsdown, :"-1"], "THUMBS DOWN SIGN"),
self.new("\u{1F44C}", [:ok_hand], "OK HAND SIGN"),
......
......@@ -98,16 +98,16 @@ module Rumoji
self.new("\u{26a0}" , [:warning]),
self.new("\u{1f492}", [:wedding]),
# Regional Indicator Symbols
self.new("\u{1f1ef}\u{1f1f5}", [:jp], "REGIONAL INDICATOR SYMBOL LETTERS JP"),
self.new("\u{1f1f0}\u{1f1f7}", [:kr], "REGIONAL INDICATOR SYMBOL LETTERS KR"),
self.new("\u{1f1e8}\u{1f1f3}", [:cn], "REGIONAL INDICATOR SYMBOL LETTERS CN"),
self.new("\u{1f1fa}\u{1f1f8}", [:us], "REGIONAL INDICATOR SYMBOL LETTERS US"),
self.new("\u{1f1eb}\u{1f1f7}", [:fr], "REGIONAL INDICATOR SYMBOL LETTERS FR"),
self.new("\u{1f1ea}\u{1f1f8}", [:es], "REGIONAL INDICATOR SYMBOL LETTERS ES"),
self.new("\u{1f1ee}\u{1f1f9}", [:it], "REGIONAL INDICATOR SYMBOL LETTERS IT"),
self.new("\u{1f1f7}\u{1f1fa}", [:ru], "REGIONAL INDICATOR SYMBOL LETTERS RU"),
self.new("\u{1f1ec}\u{1f1e7}", [:gb, :uk], "REGIONAL INDICATOR SYMBOL LETTERS GB"),
self.new("\u{1f1e9}\u{1f1ea}", [:de], "REGIONAL INDICATOR SYMBOL LETTERS DE"),
self.new("\u{1f1ef 1f1f5}", [:jp], "REGIONAL INDICATOR SYMBOL LETTERS JP"),
self.new("\u{1f1f0 1f1f7}", [:kr], "REGIONAL INDICATOR SYMBOL LETTERS KR"),
self.new("\u{1f1e8 1f1f3}", [:cn], "REGIONAL INDICATOR SYMBOL LETTERS CN"),
self.new("\u{1f1fa 1f1f8}", [:us], "REGIONAL INDICATOR SYMBOL LETTERS US"),
self.new("\u{1f1eb 1f1f7}", [:fr], "REGIONAL INDICATOR SYMBOL LETTERS FR"),
self.new("\u{1f1ea 1f1f8}", [:es], "REGIONAL INDICATOR SYMBOL LETTERS ES"),
self.new("\u{1f1ee 1f1f9}", [:it], "REGIONAL INDICATOR SYMBOL LETTERS IT"),
self.new("\u{1f1f7 1f1fa}", [:ru], "REGIONAL INDICATOR SYMBOL LETTERS RU"),
self.new("\u{1f1ec 1f1e7}", [:gb, :uk], "REGIONAL INDICATOR SYMBOL LETTERS GB"),
self.new("\u{1f1e9 1f1ea}", [:de], "REGIONAL INDICATOR SYMBOL LETTERS DE"),
]
end
end
......@@ -81,16 +81,16 @@ module Rumoji
self.new("\u{1f6c3}", [:customs]),
self.new("\u{1f4a0}", [:diamond_shape_with_a_dot_inside]),
self.new("\u{1f6af}", [:do_not_litter]),
# self.new("\u{0038}" , [:eight]),
self.new("\u{0038 fe0f 20e3}" , [:eight]),
self.new("\u{2734}" , [:eight_pointed_black_star]),
self.new("\u{2733}" , [:eight_spoked_asterisk]),
self.new("\u{1f51a}", [:end]),
self.new("\u{23e9}" , [:fast_forward]),
# self.new("\u{0035}" , [:five]),
# self.new("\u{0034}" , [:four]),
self.new("\u{0035 fe0f 20e3}" , [:five]),
self.new("\u{0034 fe0f 20e3}" , [:four]),
self.new("\u{1f193}", [:free]),
self.new("\u{264a}" , [:gemini]),
# self.new("\u{0023}" , [:hash]),
self.new("\u{0023 fe0f 20e3}" , [:hash]),
self.new("\u{1f49f}", [:heart_decoration]),
self.new("\u{2714}" , [:heavy_check_mark]),
self.new("\u{2797}" , [:heavy_division_sign]),
......@@ -120,7 +120,7 @@ module Rumoji
self.new("\u{274e}" , [:negative_squared_cross_mark]),
self.new("\u{1f195}", [:new]),
self.new("\u{1f196}", [:ng]),
# self.new("\u{0039}" , [:nine]),
self.new("\u{0039 fe0f 20e3}" , [:nine]),
self.new("\u{1f6b3}", [:no_bicycles]),
self.new("\u{26d4}" , [:no_entry]),
self.new("\u{1f6ab}", [:no_entry_sign]),
......@@ -132,7 +132,7 @@ module Rumoji
self.new("\u{1f17e}", [:o2]),
self.new("\u{1f197}", [:ok]),
self.new("\u{1f51b}", [:on]),
# self.new("\u{0031}" , [:one]),
self.new("\u{0031 fe0f 20e3}" , [:one]),
self.new("\u{26ce}" , [:ophiuchus]),
self.new("\u{1f17f}", [:parking]),
self.new("\u{303d}" , [:part_alternation_mark]),
......@@ -152,9 +152,9 @@ module Rumoji
self.new("\u{2650}" , [:sagittarius]),
self.new("\u{264f}" , [:scorpius]),
self.new("\u{3299}" , [:secret]),
# self.new("\u{0037}" , [:seven]),
self.new("\u{0037 fe0f 20e3}" , [:seven]),
self.new("\u{1f4f6}", [:signal_strength]),
# self.new("\u{0036}" , [:six]),
self.new("\u{0036 fe0f 20e3}" , [:six]),
self.new("\u{1f52f}", [:six_pointed_star]),
self.new("\u{1f539}", [:small_blue_diamond]),
self.new("\u{1f538}", [:small_orange_diamond]),
......@@ -164,12 +164,12 @@ module Rumoji
self.new("\u{1f198}", [:sos]),
self.new("\u{1f523}", [:symbols]),
self.new("\u{2649}" , [:taurus]),
# self.new("\u{0033}" , [:three]),
self.new("\u{0033 fe0f 20e3}" , [:three]),
self.new("\u{2122}" , [:tm]),
self.new("\u{1f51d}", [:top]),
self.new("\u{1f531}", [:trident]),
self.new("\u{1f500}", [:twisted_rightwards_arrows]),
# self.new("\u{0032}" , [:two]),
self.new("\u{0032 fe0f 20e3}" , [:two]),
self.new("\u{1f239}", [:u5272]),
self.new("\u{1f234}", [:u5408]),
self.new("\u{1f23a}", [:u55b6]),
......@@ -195,7 +195,7 @@ module Rumoji
self.new("\u{1f533}", [:white_square_button]),
self.new("\u{1f6ba}", [:womens]),
self.new("\u{274c}" , [:x]),
# self.new("\u{0030}" , [:zero])
self.new("\u{0030 fe0f 20e3}" , [:zero])
]
end
end
module Rumoji
VERSION = "0.2.0"
VERSION = "0.4.1"
end
......@@ -5,14 +5,14 @@ require 'minitest/autorun'
describe Rumoji::Emoji do
let(:symbols) { [:hankey, :poop, :shit] }
let(:name) { "PILE OF POO" }
let(:emoji_name) { "PILE OF POO" }
let(:poo_string) { "\u{1F4A9}" }
subject do
Rumoji::Emoji.new(poo_string, symbols, name)
Rumoji::Emoji.new(poo_string, symbols, emoji_name)
end
it("has a name") { subject.name.must_equal name }
it("has a name") { subject.name.must_equal emoji_name }
it("has a cheat sheet code") { symbols.must_include subject.code[1...-1].intern }
it("can test if it includes a cheat sheet code") { symbols.all?{|symbol| subject.include?(symbol) }.must_equal true }
it("converts to the emoji string") { subject.to_s.must_equal poo_string }
......@@ -44,11 +44,11 @@ describe Rumoji::Emoji do
#
# http://www.unicode.org/versions/Unicode6.2.0/
let(:symbol) { :us }
let(:name) { "REGIONAL INDICATOR SYMBOL LETTERS US" }
let(:emoji_name) { "REGIONAL INDICATOR SYMBOL LETTERS US" }
let(:us_string) { "\xF0\x9F\x87\xBA\xF0\x9F\x87\xB8" }
subject do
Rumoji::Emoji.new(us_string, symbol, name)
Rumoji::Emoji.new(us_string, symbol, emoji_name)
end
it("has one symbol, representing the code") { subject.symbol.must_equal symbol }
......
......@@ -7,12 +7,16 @@ describe Rumoji do
before do
@poop = "💩"
@smile = "😄"
@zero = "0️⃣"
@us = "🇺🇸"
@non_potable_water = "🚱"
end
describe "#encode" do
it "transforms emoji into cheat-sheet form" do
key = :smile
Rumoji.encode(@smile).must_equal ":smile:"
Rumoji.encode("#{@smile}").must_equal ":smile:"
end
end
......@@ -20,6 +24,18 @@ describe Rumoji do
it "transforms a cheat-sheet code into an emoji" do
Rumoji.decode(":poop:").must_equal @poop
end
it "transforms a cheat-sheet code into an emoji with colon" do
Rumoji.decode("::poop:").must_equal ':' + @poop
end
it "transforms a cheat-sheet code with a dash into an emoji" do
Rumoji.decode(":non-potable_water:").must_equal @non_potable_water
end
it "does not transform an arbitrary string wrapped in colons" do
Rumoji.decode(":this-is-just-a-string:").must_equal ":this-is-just-a-string:"
end
end
describe "#encode_io" do
......@@ -27,6 +43,48 @@ describe Rumoji do
io = StringIO.new("#{@smile}")
Rumoji.encode_io(io).string.must_equal ":smile:"
end
it "keeps codepoints that match the beginnings of multi-codepoint emoji" do
text = "i like #hashtags and 1direction they are the #1 band. end with 9"
io = StringIO.new(text)
Rumoji.encode_io(io).string.must_equal text
end
describe "with multiple codepoints" do
it "transforms a stream" do
io1 = StringIO.new("#{@zero}")
io2 = StringIO.new("#{@us}")
Rumoji.encode_io(io1).string.must_equal ":zero:"
Rumoji.encode_io(io2).string.must_equal ":us:"
end
it "transforms a stream of many emoji" do
num = ":one: :two: :three: :four: :five: :six: :seven: :eight: :nine: :zero: :hash:"
emoji = StringIO.new"1️⃣ 2️⃣ 3️⃣ 4️⃣ 5️⃣ 6️⃣ 7️⃣ 8️⃣ 9️⃣ 0️⃣ #️⃣"
Rumoji.encode_io(emoji).string.must_equal num
end
it "does not encode double digits" do
num = ":zero: :one: :two: :three: :four: :five: :six: :seven: :eight: :nine: :hash:"
double_digits = StringIO.new("00 11 22 33 44 55 66 77 88 99 ##")
Rumoji.encode_io(double_digits).string.wont_equal num
end
describe "with leading and trailing characters" do
it "is able to pull multipoint emoji out of a sequence" do
io = StringIO.new("An example of a multipoint emoji is the #{@us} flag.")
Rumoji.encode_io(io).string.must_equal "An example of a multipoint emoji is the :us: flag."
end
end
describe "with trailing emoji" do
it "writes characters that are in a multipoint emoji followed by an emoji" do
io = StringIO.new "I would like 0#{@poop}"
Rumoji.encode_io(io).string.must_equal "I would like 0:poop:"
end
end
end
end
describe "#decode_io" do
......@@ -34,5 +92,12 @@ describe Rumoji do
io = StringIO.new(":poop:")
Rumoji.decode_io(io).string.must_equal @poop
end
describe "with multiple codepoints" do
it "decodes a stream" do
io = StringIO.new(":zero:")
Rumoji.decode_io(io).string.must_equal @zero
end
end
end
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment