├── test ├── data │ ├── tw2s.in │ ├── tw2s.ans │ ├── hk2s.ans │ ├── hk2s.in │ ├── hk2t.ans │ ├── hk2t.in │ ├── s2tw.ans │ ├── s2tw.in │ ├── t2hk.in │ ├── t2hk.ans │ ├── s2hk.ans │ ├── s2hk.in │ ├── tw2t.ans │ ├── tw2t.in │ ├── t2jp.ans │ ├── t2jp.in │ ├── jp2t.ans │ ├── jp2t.in │ ├── s2twp.in │ ├── s2twp.ans │ ├── t2s.in │ ├── t2s.ans │ ├── tw2sp.ans │ ├── tw2sp.in │ ├── s2t.ans │ └── s2t.in ├── test_helper.rb ├── opencc_test.rb └── opencc_converter_test.rb ├── lib ├── opencc │ └── version.rb └── opencc.rb ├── ext └── opencc │ ├── opencc.h │ ├── extconf.rb │ └── opencc.c ├── bin ├── setup └── console ├── .gitignore ├── Gemfile ├── .travis └── install.sh ├── Gemfile.lock ├── Rakefile ├── .travis.yml ├── LICENSE.txt ├── opencc.gemspec └── README.md /test/data/tw2s.in: -------------------------------------------------------------------------------- 1 | 著裝著作汙染虛偽發洩稜柱群眾裡面 2 | -------------------------------------------------------------------------------- /test/data/tw2s.ans: -------------------------------------------------------------------------------- 1 | 着装著作污染虚伪发泄棱柱群众里面 2 | -------------------------------------------------------------------------------- /test/data/hk2s.ans: -------------------------------------------------------------------------------- 1 | 虚伪叹息 2 | 潮湿灶台 3 | 赞叹沙河涌汹涌的波浪 4 | -------------------------------------------------------------------------------- /test/data/hk2s.in: -------------------------------------------------------------------------------- 1 | 虛偽歎息 2 | 潮濕灶台 3 | 讚歎沙河涌洶湧的波浪 4 | -------------------------------------------------------------------------------- /test/data/hk2t.ans: -------------------------------------------------------------------------------- 1 | 爲賦新詞強說愁 2 | 想到自己一緊張就口吃,我就沒胃口喫飯 3 | -------------------------------------------------------------------------------- /test/data/hk2t.in: -------------------------------------------------------------------------------- 1 | 為賦新詞強説愁 2 | 想到自己一緊張就口吃,我就沒胃口吃飯 3 | -------------------------------------------------------------------------------- /test/data/s2tw.ans: -------------------------------------------------------------------------------- 1 | 著裝汙染虛偽發洩稜柱群眾裡面 2 | 鯰魚和鯰魚是一種生物。 3 | -------------------------------------------------------------------------------- /test/data/s2tw.in: -------------------------------------------------------------------------------- 1 | 着装污染虚伪发泄棱柱群众里面 2 | 鲶鱼和鲇鱼是一种生物。 3 | -------------------------------------------------------------------------------- /test/data/t2hk.in: -------------------------------------------------------------------------------- 1 | 潮溼的露臺 2 | 爲了覈實這說法 3 | 包糉子活動告一段落 4 | -------------------------------------------------------------------------------- /test/data/t2hk.ans: -------------------------------------------------------------------------------- 1 | 潮濕的露台 2 | 為了核實這説法 3 | 包粽子活動告一段落 4 | -------------------------------------------------------------------------------- /test/data/s2hk.ans: -------------------------------------------------------------------------------- 1 | 虛偽嘆息 2 | 潮濕灶台 3 | 讚歎沙河涌洶湧的波浪 4 | 為了核實這説法 5 | -------------------------------------------------------------------------------- /test/data/s2hk.in: -------------------------------------------------------------------------------- 1 | 虚伪叹息 2 | 潮湿灶台 3 | 赞叹沙河涌汹涌的波浪 4 | 为了核实这说法 5 | -------------------------------------------------------------------------------- /lib/opencc/version.rb: -------------------------------------------------------------------------------- 1 | module OpenCC 2 | VERSION = "1.0.6" 3 | end 4 | -------------------------------------------------------------------------------- /test/data/tw2t.ans: -------------------------------------------------------------------------------- 1 | 爲了衆人化妝牀頭裏面衛生,醞釀羣峯鐵鉤嘆氣事件 2 | 在廚房裏做手擀麪 3 | 想到自己一緊張就口吃,我就沒胃口喫飯 4 | -------------------------------------------------------------------------------- /test/data/tw2t.in: -------------------------------------------------------------------------------- 1 | 為了眾人化妝床頭裡面衛生,醞釀群峰鐵鉤嘆氣事件 2 | 在廚房裡做手擀麵 3 | 想到自己一緊張就口吃,我就沒胃口吃飯 4 | -------------------------------------------------------------------------------- /test/data/t2jp.ans: -------------------------------------------------------------------------------- 1 | 旧字体歴史仮名遣 新字体現代仮名遣 2 | 横浜 糸魚川 伊予国 3 | 駅弁当 弁別 弁護士 弁膜 4 | 芸術 欠航 飲料缶 5 | -------------------------------------------------------------------------------- /test/data/t2jp.in: -------------------------------------------------------------------------------- 1 | 舊字體歷史假名遣 新字體現代假名遣 2 | 橫濱 絲魚川 伊豫國 3 | 驛辨當 辨別 辯護士 瓣膜 4 | 藝術 缺航 飲料罐 5 | -------------------------------------------------------------------------------- /test/data/jp2t.ans: -------------------------------------------------------------------------------- 1 | 舊字體歷史假名遣 新字體現代假名遣 2 | 橫濱 絲魚川 伊豫國 3 | 驛辨當 辨別 辯護士 瓣膜 4 | 藝術 缺航 欠缺 飲料罐 5 | -------------------------------------------------------------------------------- /test/data/jp2t.in: -------------------------------------------------------------------------------- 1 | 旧字体歴史仮名遣 新字体現代仮名遣 2 | 横浜 糸魚川 伊予国 3 | 駅弁当 弁別 弁護士 弁膜 4 | 芸術 欠航 欠缺 飲料缶 5 | -------------------------------------------------------------------------------- /test/data/s2twp.in: -------------------------------------------------------------------------------- 1 | 鼠标里面的硅二极管坏了,导致光标分辨率降低。 2 | 我们在老挝的服务器的硬盘需要使用互联网算法软件解决异步的问题。 3 | 为什么你在床里面睡着? 4 | -------------------------------------------------------------------------------- /test/data/s2twp.ans: -------------------------------------------------------------------------------- 1 | 滑鼠裡面的矽二極體壞了,導致游標解析度降低。 2 | 我們在寮國的伺服器的硬碟需要使用網際網路演算法軟體解決非同步的問題。 3 | 為什麼你在床裡面睡著? 4 | -------------------------------------------------------------------------------- /test/data/t2s.in: -------------------------------------------------------------------------------- 1 | 曾經有一份真誠的愛情放在我面前,我沒有珍惜,等我失去的時候我才後悔莫及。人事間最痛苦的事莫過於此。如果上天能夠給我一個再來一次得機會,我會對那個女孩子說三個字,我愛你。如果非要在這份愛上加個期限,我希望是,一萬年。 2 | -------------------------------------------------------------------------------- /test/data/t2s.ans: -------------------------------------------------------------------------------- 1 | 曾经有一份真诚的爱情放在我面前,我没有珍惜,等我失去的时候我才后悔莫及。人事间最痛苦的事莫过于此。如果上天能够给我一个再来一次得机会,我会对那个女孩子说三个字,我爱你。如果非要在这份爱上加个期限,我希望是,一万年。 2 | -------------------------------------------------------------------------------- /test/data/tw2sp.ans: -------------------------------------------------------------------------------- 1 | 鼠标里面的硅二极管坏了,导致光标分辨率降低。 2 | 我们在老挝的服务器的硬盘需要使用互联网算法软件解决异步的问题。 3 | 为什么你在床里面睡着? 4 | 用鼠标点击正则表达式 5 | KB大桥也被视为帕劳人的后花园 6 | -------------------------------------------------------------------------------- /test/data/tw2sp.in: -------------------------------------------------------------------------------- 1 | 滑鼠裡面的矽二極體壞了,導致游標解析度降低。 2 | 我們在寮國的伺服器的硬碟需要使用網際網路演算法軟體解決非同步的問題。 3 | 為什麼你在床裡面睡著? 4 | 用滑鼠點選正規表示式 5 | KB大橋也被視為帛琉人的後花園 6 | -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift File.expand_path("../lib", __dir__) 2 | require "opencc" 3 | 4 | require "minitest/autorun" 5 | -------------------------------------------------------------------------------- /ext/opencc/opencc.h: -------------------------------------------------------------------------------- 1 | #ifndef RUBY_OPENCC_H 2 | #define RUBY_OPENCC_H 1 3 | 4 | #include 5 | #include 6 | 7 | #endif /* RUBY_OPENCC_H */ 8 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | IFS=$'\n\t' 4 | set -vx 5 | 6 | bundle install 7 | 8 | # Do any other automated setup that you need to do here 9 | -------------------------------------------------------------------------------- /test/opencc_test.rb: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | 3 | class OpenCCTest < Minitest::Test 4 | def test_that_it_has_a_version_number 5 | refute_nil ::OpenCC::VERSION 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle/ 2 | /.yardoc 3 | /_yardoc/ 4 | /coverage/ 5 | /doc/ 6 | /pkg/ 7 | /spec/reports/ 8 | /tmp/ 9 | *.bundle 10 | *.so 11 | *.o 12 | *.a 13 | mkmf.log 14 | .DS_Store 15 | .keep -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | # Specify your gem's dependencies in opencc.gemspec 4 | gemspec 5 | 6 | gem "rake", "~> 13.0" 7 | gem "rake-compiler" 8 | gem "minitest", "~> 5.14", ">= 5.14.3" 9 | -------------------------------------------------------------------------------- /.travis/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ $TRAVIS_OS_NAME = 'osx' ]; then 4 | brew install opencc 5 | else 6 | git clone https://github.com/BYVoid/OpenCC 7 | cd OpenCC 8 | git checkout ver.1.1.2 9 | make PREFIX=/usr/local 10 | sudo make install 11 | fi 12 | -------------------------------------------------------------------------------- /test/data/s2t.ans: -------------------------------------------------------------------------------- 1 | 誇誇其談 夸父逐日 2 | 我幹什麼不干你事。 3 | 太后的頭髮很乾燥。 4 | 燕燕于飛,差池其羽。之子于歸,遠送於野。 5 | 請成相,世之殃,愚闇愚闇墮賢良。人主無賢,如瞽無相何倀倀!請布基,慎聖人,愚而自專事不治。主忌苟勝,羣臣莫諫必逢災。 6 | 曾經有一份真誠的愛情放在我面前,我沒有珍惜,等我失去的時候我才後悔莫及。人事間最痛苦的事莫過於此。如果上天能夠給我一個再來一次得機會,我會對那個女孩子說三個字,我愛你。如果非要在這份愛上加個期限,我希望是,一萬年。 7 | 新的理論被發現了。 8 | 金胄不是金色的甲冑。 9 | -------------------------------------------------------------------------------- /test/data/s2t.in: -------------------------------------------------------------------------------- 1 | 夸夸其谈 夸父逐日 2 | 我干什么不干你事。 3 | 太后的头发很干燥。 4 | 燕燕于飞,差池其羽。之子于归,远送于野。 5 | 请成相,世之殃,愚暗愚暗堕贤良。人主无贤,如瞽无相何伥伥!请布基,慎圣人,愚而自专事不治。主忌苟胜,群臣莫谏必逢灾。 6 | 曾经有一份真诚的爱情放在我面前,我没有珍惜,等我失去的时候我才后悔莫及。人事间最痛苦的事莫过于此。如果上天能够给我一个再来一次得机会,我会对那个女孩子说三个字,我爱你。如果非要在这份爱上加个期限,我希望是,一万年。 7 | 新的理论被发现了。 8 | 金胄不是金色的甲胄。 9 | -------------------------------------------------------------------------------- /bin/console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require "bundler/setup" 4 | require "opencc" 5 | 6 | # You can add fixtures and/or initialization code here to make experimenting 7 | # with your gem easier. You can also use a different console, if you like. 8 | 9 | # (If you use this, don't forget to add pry to your Gemfile!) 10 | # require "pry" 11 | # Pry.start 12 | 13 | require "irb" 14 | IRB.start(__FILE__) 15 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: . 3 | specs: 4 | opencc-rb (1.0.6) 5 | 6 | GEM 7 | remote: https://rubygems.org/ 8 | specs: 9 | minitest (5.14.4) 10 | rake (13.0.3) 11 | rake-compiler (1.1.1) 12 | rake 13 | 14 | PLATFORMS 15 | ruby 16 | 17 | DEPENDENCIES 18 | minitest (~> 5.14, >= 5.14.3) 19 | opencc-rb! 20 | rake (~> 13.0) 21 | rake-compiler 22 | 23 | BUNDLED WITH 24 | 2.2.22 25 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler/gem_tasks" 2 | require "rake/testtask" 3 | 4 | Rake::TestTask.new(:test) do |t| 5 | t.libs << "test" 6 | t.libs << "lib" 7 | t.test_files = FileList["test/**/*_test.rb"] 8 | end 9 | 10 | require "rake/extensiontask" 11 | 12 | task :build => :compile 13 | 14 | Rake::ExtensionTask.new("opencc") do |ext| 15 | ext.lib_dir = "lib/opencc" 16 | end 17 | 18 | task :default => [:clobber, :compile, :test] 19 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: ruby 3 | os: 4 | - linux 5 | - osx 6 | dist: focal 7 | compiler: 8 | - clang 9 | - gcc 10 | cache: bundler 11 | rvm: 12 | - 2.7.0 13 | - 2.6.5 14 | - 2.5.5 15 | addons: 16 | apt: 17 | update: true 18 | packages: 19 | - cmake 20 | - doxygen 21 | before_install: 22 | - gem install bundler -v 2.1.4 23 | install: 24 | - ./.travis/install.sh 25 | - bundle install 26 | script: bundle exec rake -------------------------------------------------------------------------------- /ext/opencc/extconf.rb: -------------------------------------------------------------------------------- 1 | require "mkmf" 2 | 3 | def missing!(lib) 4 | if RUBY_PLATFORM =~ /mingw|mswin/ 5 | abort "-----\n#{lib} is missing. Check your installation of OpenCC, and try again.\n-----" 6 | elsif RUBY_PLATFORM =~ /darwin/ 7 | abort "-----\n#{lib} is missing. You may need to 'brew install opencc', and try again.\n-----" 8 | else 9 | abort "-----\n#{lib} is missing. You may need to 'sudo apt-get install libopencc-dev', 'sudo pacman -Sy opencc' or 'sudo yum install opencc-devel' and try again.\n-----" 10 | end 11 | end 12 | 13 | missing!('opencc') if !have_library('opencc') 14 | missing!('opencc.h') if !have_header('opencc.h') 15 | 16 | have_func 'opencc_open' 17 | have_func 'opencc_convert_utf8' 18 | have_func 'opencc_convert_utf8_free' 19 | have_func 'opencc_close' 20 | 21 | create_makefile 'opencc/opencc' 22 | -------------------------------------------------------------------------------- /lib/opencc.rb: -------------------------------------------------------------------------------- 1 | require "opencc/version" 2 | require "opencc/opencc" 3 | 4 | module OpenCC 5 | CONFIGS = %w[ s2t t2s s2tw tw2s s2hk hk2s s2twp tw2sp hk2t t2hk t2jp jp2t tw2t ] 6 | 7 | class << self 8 | def with(config, &block) 9 | converter = Converter.new(config) 10 | 11 | begin 12 | if block.arity == 0 13 | converter.instance_eval(&block) 14 | else 15 | yield converter 16 | end 17 | ensure 18 | converter && converter.close 19 | end 20 | end 21 | 22 | CONFIGS.each do |config| 23 | define_method :"#{config}" do |input| 24 | begin 25 | converter = Converter.new(config) 26 | converter.convert(input) 27 | ensure 28 | converter && converter.close 29 | end 30 | end 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2020 zsj 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /opencc.gemspec: -------------------------------------------------------------------------------- 1 | require_relative "lib/opencc/version" 2 | 3 | Gem::Specification.new do |spec| 4 | spec.name = "opencc-rb" 5 | spec.version = OpenCC::VERSION 6 | spec.authors = ["zsj"] 7 | spec.email = ["lekyzsj@gmail.com"] 8 | 9 | spec.summary = %q{This gem is for conversions between Traditional Chinese, Simplified Chinese and Japanese Kanji (Shinjitai).} 10 | spec.description = %q{This gem is for conversions between Traditional Chinese, Simplified Chinese and Japanese Kanji (Shinjitai). It supports character-level and phrase-level conversion, character variant conversion and regional idioms among Mainland China, Taiwan and Hong Kong.} 11 | spec.homepage = "https://github.com/songjiz/opencc-rb" 12 | spec.license = "MIT" 13 | spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0") 14 | 15 | spec.metadata["homepage_uri"] = spec.homepage 16 | spec.metadata["source_code_uri"] = spec.homepage 17 | 18 | spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do 19 | `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } 20 | end 21 | spec.bindir = "exe" 22 | spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } 23 | spec.require_paths = ["lib"] 24 | spec.extensions = ["ext/opencc/extconf.rb"] 25 | end 26 | -------------------------------------------------------------------------------- /test/opencc_converter_test.rb: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | 3 | class OpenCC::ConverterTest < Minitest::Test 4 | def get_input(cfg) 5 | File.read(File.join(__dir__, 'data', "#{cfg}.in" )).force_encoding("UTF-8").strip 6 | end 7 | 8 | def get_answer(cfg) 9 | File.read(File.join(__dir__, 'data', "#{cfg}.ans" )).force_encoding("UTF-8").strip 10 | end 11 | 12 | def test_instance_methods 13 | converter = OpenCC::Converter.new 14 | assert_respond_to converter, :convert 15 | assert_respond_to converter, :close 16 | ensure 17 | converter.close 18 | end 19 | 20 | def test_hk2s 21 | cfg = :hk2s 22 | input = get_input(cfg) 23 | answer = get_answer(cfg) 24 | assert_equal OpenCC.hk2s(input), answer 25 | end 26 | 27 | def test_hk2t 28 | cfg = :hk2t 29 | input = get_input(cfg) 30 | answer = get_answer(cfg) 31 | assert_equal OpenCC.hk2t(input), answer 32 | end 33 | 34 | def test_jp2t 35 | cfg = :jp2t 36 | input = get_input(cfg) 37 | answer = get_answer(cfg) 38 | assert_equal OpenCC.jp2t(input), answer 39 | end 40 | 41 | def test_s2hk 42 | cfg = :s2hk 43 | input = get_input(cfg) 44 | answer = get_answer(cfg) 45 | assert_equal OpenCC.s2hk(input), answer 46 | end 47 | 48 | def test_s2t 49 | cfg = :s2t 50 | input = get_input(cfg) 51 | answer = get_answer(cfg) 52 | assert_equal OpenCC.s2t(input), answer 53 | end 54 | 55 | def test_s2tw 56 | cfg = :s2tw 57 | input = get_input(cfg) 58 | answer = get_answer(cfg) 59 | assert_equal OpenCC.s2tw(input), answer 60 | end 61 | 62 | def test_s2twp 63 | cfg = :s2twp 64 | input = get_input(cfg) 65 | answer = get_answer(cfg) 66 | assert_equal OpenCC.s2twp(input), answer 67 | end 68 | 69 | def test_t2hk 70 | cfg = :t2hk 71 | input = get_input(cfg) 72 | answer = get_answer(cfg) 73 | assert_equal OpenCC.t2hk(input), answer 74 | end 75 | 76 | def test_t2jp 77 | cfg = :t2jp 78 | input = get_input(cfg) 79 | answer = get_answer(cfg) 80 | assert_equal OpenCC.t2jp(input), answer 81 | end 82 | 83 | def test_t2s 84 | cfg = :t2s 85 | input = get_input(cfg) 86 | answer = get_answer(cfg) 87 | assert_equal OpenCC.t2s(input), answer 88 | end 89 | 90 | def test_tw2s 91 | cfg = :tw2s 92 | input = get_input(cfg) 93 | answer = get_answer(cfg) 94 | assert_equal OpenCC.tw2s(input), answer 95 | end 96 | 97 | def test_tw2sp 98 | cfg = :tw2sp 99 | input = get_input(cfg) 100 | answer = get_answer(cfg) 101 | assert_equal OpenCC.tw2sp(input), answer 102 | end 103 | 104 | def test_tw2t 105 | cfg = :tw2t 106 | input = get_input(cfg) 107 | answer = get_answer(cfg) 108 | assert_equal OpenCC.tw2t(input), answer 109 | end 110 | end 111 | -------------------------------------------------------------------------------- /ext/opencc/opencc.c: -------------------------------------------------------------------------------- 1 | #include "opencc.h" 2 | 3 | #define OPENCC_DEFAULT_CONFIG_SIMP_TO_TRAD "s2t.json" 4 | 5 | VALUE mOpenCC; 6 | VALUE cConverter; 7 | 8 | typedef struct { 9 | opencc_t opencc; 10 | } opencc_converter_t; 11 | 12 | static void opencc_converter_t_dfree(void* _ptr) { 13 | opencc_converter_t* ptr = (opencc_converter_t*)_ptr; 14 | if (ptr->opencc != NULL && ptr->opencc != (opencc_t) - 1) { 15 | opencc_close(ptr->opencc); 16 | } 17 | free(ptr); 18 | } 19 | 20 | static size_t opencc_converter_t_dsize(const void* _ptr) { 21 | return sizeof(opencc_converter_t); 22 | } 23 | 24 | static const rb_data_type_t opencc_converter_data_type = { 25 | .wrap_struct_name = "opencc converter object", 26 | .function = { 27 | .dfree = opencc_converter_t_dfree, 28 | .dsize = opencc_converter_t_dsize, 29 | }, 30 | .flags = RUBY_TYPED_FREE_IMMEDIATELY, 31 | }; 32 | 33 | VALUE opencc_converter_t_alloc(VALUE self) { 34 | opencc_converter_t *ptr = malloc(sizeof(opencc_converter_t)); 35 | 36 | return TypedData_Wrap_Struct(self, &opencc_converter_data_type, ptr); 37 | } 38 | 39 | static VALUE opencc_converter_t_initialize(int argc, VALUE* argv, VALUE self) { 40 | opencc_converter_t *ptr; 41 | const char *cfg = NULL; 42 | 43 | if (argv[0] != Qnil) { 44 | switch (TYPE(argv[0])) { 45 | case T_SYMBOL: 46 | cfg = RSTRING_PTR(rb_sym_to_s(argv[0])); 47 | break; 48 | case T_STRING: 49 | cfg = RSTRING_PTR(argv[0]); 50 | break; 51 | } 52 | } 53 | 54 | TypedData_Get_Struct(self, opencc_converter_t, &opencc_converter_data_type, ptr); 55 | 56 | ptr->opencc = opencc_open(cfg); 57 | 58 | // On error the return value will be (opencc_t) -1. 59 | if (ptr->opencc == (opencc_t) - 1) { 60 | free(ptr); 61 | rb_raise(rb_eException, "%s", "(opencc_open) failed to allocate instance of opencc"); 62 | } 63 | return self; 64 | } 65 | 66 | static VALUE opencc_converter_t_convert(VALUE self, VALUE input) { 67 | opencc_converter_t *ptr; 68 | TypedData_Get_Struct(self, opencc_converter_t, &opencc_converter_data_type, ptr); 69 | 70 | if (ptr->opencc != NULL) { 71 | char * buff = opencc_convert_utf8(ptr->opencc, RSTRING_PTR(input), RSTRING_LEN(input)); 72 | VALUE result = rb_utf8_str_new_cstr(buff); 73 | opencc_convert_utf8_free(buff); 74 | return result; 75 | } else { 76 | rb_warn("%s", "opencc has been closed"); 77 | return Qnil; 78 | } 79 | } 80 | 81 | static VALUE opencc_converter_t_close(VALUE self) { 82 | opencc_converter_t *ptr; 83 | TypedData_Get_Struct(self, opencc_converter_t, &opencc_converter_data_type, ptr); 84 | 85 | if (ptr->opencc != NULL && opencc_close(ptr->opencc) == 0) { 86 | ptr->opencc = NULL; 87 | return Qtrue; 88 | } else { 89 | return Qfalse; 90 | } 91 | } 92 | 93 | void Init_opencc(void) { 94 | mOpenCC = rb_define_module("OpenCC"); 95 | cConverter = rb_define_class_under(mOpenCC, "Converter", rb_cObject); 96 | 97 | rb_define_alloc_func(cConverter, opencc_converter_t_alloc); 98 | rb_define_method(cConverter, "initialize", opencc_converter_t_initialize, -1); 99 | rb_define_method(cConverter, "convert", opencc_converter_t_convert, 1); 100 | rb_define_method(cConverter, "close", opencc_converter_t_close, 0); 101 | } 102 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OpenCC [![Build Status](https://travis-ci.org/songjiz/opencc-rb.svg?branch=master)](https://travis-ci.org/songjiz/opencc-rb) 2 | 3 | ## Description 4 | 5 | This gem is for conversions between Traditional Chinese, Simplified Chinese and Japanese Kanji (Shinjitai). It's builded on [OpenCC](https://github.com/BYVoid/OpenCC). 6 | 7 | ## Installation 8 | 9 | You have to install OpenCC firstly. 10 | 11 | MacOS: 12 | 13 | ```shell 14 | brew install opencc 15 | ``` 16 | 17 | Debian/Ubuntu: 18 | 19 | ```shell 20 | sudo apt install libopencc-dev 21 | ``` 22 | Archlinux: 23 | 24 | ```shell 25 | sudo pacman -Sy opencc 26 | ``` 27 | 28 | Fedora: 29 | 30 | ```shell 31 | sudo yum install opencc-devel 32 | ``` 33 | 34 | Or install from source code: 35 | 36 | ```shell 37 | cd /usr/src 38 | git clone https://github.com/BYVoid/OpenCC 39 | cd OpenCC 40 | git checkout ver.1.1.1 41 | make PREFIX=/usr/local 42 | sudo make install 43 | ``` 44 | 45 | Then add this line to your application's Gemfile: 46 | 47 | ```ruby 48 | gem 'opencc-rb' 49 | ``` 50 | 51 | And then execute: 52 | 53 | ```shell 54 | bundle install 55 | ``` 56 | 57 | Or install it yourself as: 58 | 59 | ```shell 60 | gem install opencc-rb 61 | ``` 62 | 63 | ## Usage 64 | 65 | ```ruby 66 | require "opencc" 67 | 68 | # The converter will automatically be closed when the block terminates. 69 | OpenCC.with(:s2t) do |ct| 70 | ct.convert("汉字") # => "漢字" 71 | ct.convert("曾经有一份真诚的爱情放在我面前,我没有珍惜,等我失去的时候我才后悔莫及。人事间最痛苦的事莫过于此。如果上天能够给我一个再来一次得机会,我会对那个女孩子说三个字,我爱你。如果非要在这份爱上加个期限,我希望是,一万年。") # => "曾經有一份真誠的愛情放在我面前,我沒有珍惜,等我失去的時候我才後悔莫及。人事間最痛苦的事莫過於此。如果上天能夠給我一個再來一次得機會,我會對那個女孩子說三個字,我愛你。如果非要在這份愛上加個期限,我希望是,一萬年。" 72 | end 73 | 74 | OpenCC.with(:s2t) do 75 | convert("汉字") # => "漢字" 76 | convert("曾经有一份真诚的爱情放在我面前,我没有珍惜,等我失去的时候我才后悔莫及。人事间最痛苦的事莫过于此。如果上天能够给我一个再来一次得机会,我会对那个女孩子说三个字,我爱你。如果非要在这份爱上加个期限,我希望是,一万年。") # => "曾經有一份真誠的愛情放在我面前,我沒有珍惜,等我失去的時候我才後悔莫及。人事間最痛苦的事莫過於此。如果上天能夠給我一個再來一次得機會,我會對那個女孩子說三個字,我愛你。如果非要在這份愛上加個期限,我希望是,一萬年。" 77 | end 78 | 79 | # Or 80 | OpenCC.s2t("汉字") # => "漢字" 81 | OpenCC.t2s("漢字") # => "汉字" 82 | OpenCC.s2tw('着装污染虚伪发泄棱柱群众里面') # => "著裝汙染虛偽發洩稜柱群眾裡面" 83 | OpenCC.tw2s("著裝汙染虛偽發洩稜柱群眾裡面") # => "着装污染虚伪发泄棱柱群众里面" 84 | OpenCC.s2hk("虚伪叹息") # => "虛偽嘆息" 85 | OpenCC.hk2s("虛偽嘆息") # => "虚伪叹息" 86 | OpenCC.s2twp("海内存知己") # => "海內存知己" 87 | OpenCC.tw2sp("海內存知己") # => "海内存知己" 88 | OpenCC.hk2t("想到自己一緊張就口吃,我就沒胃口吃飯") # => "想到自己一緊張就口吃,我就沒胃口喫飯" 89 | OpenCC.t2hk("想到自己一緊張就口吃,我就沒胃口喫飯") # => "想到自己一緊張就口吃,我就沒胃口吃飯" 90 | OpenCC.t2jp("藝術 缺航 飲料罐") # => "芸術 欠航 飲料缶" 91 | OpenCC.jp2t("芸術 欠航 飲料缶") # => "藝術 缺航 飲料罐" 92 | OpenCC.tw2t("想到自己一緊張就口吃,我就沒胃口吃飯") # => "想到自己一緊張就口吃,我就沒胃口喫飯" 93 | 94 | # Or 95 | # You *must* call close when you're finished 96 | converter = OpenCC::Converter.new(:s2t) 97 | converter.convert("汉字") # => '漢字' 98 | converter.close # => true 99 | converter.close # => false 100 | ``` 101 | 102 | ## Development 103 | 104 | After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. 105 | 106 | To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). 107 | 108 | ## Contributing 109 | 110 | Bug reports and pull requests are welcome on GitHub at https://github.com/songjiz/opencc-rb. 111 | 112 | 113 | ## License 114 | 115 | The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT). 116 | --------------------------------------------------------------------------------