kanamei-kanamei-keystone 0.0.7 → 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- data/example/batch_sample.rb +34 -0
- data/example/string_util.rb +8 -0
- data/lib/keystone.rb +20 -2
- data/lib/keystone/base.rb +36 -0
- data/lib/keystone/batch_base.rb +17 -0
- data/lib/keystone/core_ext.rb +76 -0
- data/lib/keystone/environment.rb +47 -0
- data/lib/keystone/mail.rb +6 -0
- data/lib/keystone/mail/send.rb +68 -0
- data/lib/keystone/string_util.rb +45 -3
- data/test/test_string_util.rb +56 -0
- data/vendor/flag_set_maker.rb +121 -0
- data/vendor/moji.rb +501 -0
- metadata +16 -1
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'keystone'
|
3
|
+
require 'keystone/batch_base'
|
4
|
+
require 'keystone/mail'
|
5
|
+
|
6
|
+
include Keystone::BatchBase
|
7
|
+
|
8
|
+
if ARGV[0] == nil
|
9
|
+
puts "set mail addr"
|
10
|
+
exit
|
11
|
+
end
|
12
|
+
|
13
|
+
MAIL_FROM = ARGV[0]
|
14
|
+
MAIL_TO = [ARGV[0]]
|
15
|
+
MAIL_SUBJECT = 'テストメール~~'
|
16
|
+
MAIL_BODY = <<BODY
|
17
|
+
こんにちは
|
18
|
+
どないでしょう??
|
19
|
+
〜〜〜
|
20
|
+
#{Keystone::Environment.dump}
|
21
|
+
BODY
|
22
|
+
|
23
|
+
execute do
|
24
|
+
info "batch process01"
|
25
|
+
sleep 1.2
|
26
|
+
|
27
|
+
begin
|
28
|
+
raise 'error occur'
|
29
|
+
rescue => e
|
30
|
+
error e
|
31
|
+
Keystone::Mail::Send.new().send(MAIL_FROM,MAIL_TO,MAIL_SUBJECT,MAIL_BODY)
|
32
|
+
Keystone::Mail::Send.send(MAIL_FROM,MAIL_TO,MAIL_SUBJECT,MAIL_BODY)
|
33
|
+
end
|
34
|
+
end
|
data/lib/keystone.rb
CHANGED
@@ -1,7 +1,25 @@
|
|
1
|
+
|
2
|
+
$KCODE = 'u'
|
3
|
+
|
4
|
+
require 'keystone/core_ext'
|
5
|
+
require 'keystone/base'
|
6
|
+
|
7
|
+
include Keystone::Base
|
8
|
+
|
9
|
+
autoload :FlagSetMaker , 'flag_set_maker'
|
10
|
+
autoload :Moji , 'moji'
|
11
|
+
|
1
12
|
module Keystone
|
2
|
-
|
13
|
+
|
14
|
+
VERSION = '0.0.10'
|
15
|
+
|
16
|
+
autoload :StringUtil , 'keystone/string_util'
|
17
|
+
autoload :BatchUtil , 'keystone/batch_util'
|
18
|
+
autoload :Environment , 'keystone/environment'
|
19
|
+
autoload :Mail , 'keystone/mail'
|
3
20
|
|
4
21
|
module Rails
|
5
22
|
#autoload :ActiveSupportExt, 'keystone/rails/active_support_ext'
|
6
23
|
end
|
7
|
-
end
|
24
|
+
end
|
25
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Keystone
|
2
|
+
module Base
|
3
|
+
def log(log_type,message, is_base_info = true)
|
4
|
+
if is_base_info
|
5
|
+
puts "[#{Time.now.strftime("%Y/%m/%d %H:%M:%S")}][#{$$}][#{log_type.to_s}] #{message}"
|
6
|
+
else
|
7
|
+
puts "[#{log_type.to_s}] #{message}"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def info(message)
|
12
|
+
log(:INFO,message)
|
13
|
+
end
|
14
|
+
|
15
|
+
def error(message)
|
16
|
+
if message.is_a? Exception
|
17
|
+
log(:ERROR," #{message.message}")
|
18
|
+
message.backtrace.each_with_index {|line, i|
|
19
|
+
log(:ERROR," #{line})",false)
|
20
|
+
}
|
21
|
+
else
|
22
|
+
log(:ERROR,message.to_s)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def warn(message)
|
27
|
+
log(:WARN,message)
|
28
|
+
end
|
29
|
+
|
30
|
+
def debug(message)
|
31
|
+
if $DEBUG
|
32
|
+
log(:DEBUG,message)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Keystone
|
2
|
+
module BatchBase
|
3
|
+
def execute(&process)
|
4
|
+
info "start script"
|
5
|
+
script_started_at = Time.now
|
6
|
+
begin
|
7
|
+
return (yield process)
|
8
|
+
rescue => e
|
9
|
+
error e
|
10
|
+
Skutil::Mail.send_error(ERROR_MAIL_FROM,ERROR_MAIL_TO,ERROR_MAIL_SUBJECT,e)
|
11
|
+
return e
|
12
|
+
ensure
|
13
|
+
info "finish script (%1.3fsec)" % (Time.now - script_started_at)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
|
2
|
+
require 'tempfile'
|
3
|
+
|
4
|
+
class Uri
|
5
|
+
#
|
6
|
+
def self.escape_raw(st)
|
7
|
+
st.gsub(/([^a-zA-Z0-9_\-\.~])/) { "%#{$1.unpack('H*')[0].scan(/../).join('%').upcase }" }
|
8
|
+
end
|
9
|
+
|
10
|
+
#
|
11
|
+
# usage
|
12
|
+
# @search_tag = Uri.unescape_raw(params[:tag]).toutf8
|
13
|
+
#
|
14
|
+
#
|
15
|
+
def self.unescape_raw(st)
|
16
|
+
st.tr('+',' ').gsub(/%([A-Fa-f0-9][A-Fa-f0-9])/) { [$1.hex].pack('C') }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Tempfile
|
21
|
+
def self.open_with_block(name = nil, dir = nil)
|
22
|
+
name ||= (0..8).map{rand(36).to_s(36)}.join
|
23
|
+
args = dir ? [name, dir] : [name]
|
24
|
+
tmp = Tempfile.open *args
|
25
|
+
begin
|
26
|
+
yield tmp
|
27
|
+
ensure
|
28
|
+
tmp.close true
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class Dir
|
34
|
+
def self.mkdir_r(dirPath)
|
35
|
+
folders = dirPath.split('/')
|
36
|
+
folderToCreate = ''
|
37
|
+
folders.each do |folder|
|
38
|
+
folderToCreate += folder + '/'
|
39
|
+
if !File.directory?(folderToCreate)
|
40
|
+
Dir.mkdir(folderToCreate)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class Object
|
47
|
+
# http://www.yohasebe.com/pages/trans-seeing-metaclasses-clearly/
|
48
|
+
def metaclass
|
49
|
+
class << self
|
50
|
+
self
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# http://www.yohasebe.com/pages/trans-seeing-metaclasses-clearly/
|
55
|
+
def meta_eval(&blk)
|
56
|
+
metaclass.instance_eval(&blk)
|
57
|
+
end
|
58
|
+
|
59
|
+
# http://www.yohasebe.com/pages/trans-seeing-metaclasses-clearly/
|
60
|
+
def meta_def(name, &blk)
|
61
|
+
meta_eval { define_method name, &blk }
|
62
|
+
end
|
63
|
+
|
64
|
+
# http://www.yohasebe.com/pages/trans-seeing-metaclasses-clearly/
|
65
|
+
def class_def(name, &blk)
|
66
|
+
class_eval { define_method name, &blk }
|
67
|
+
end
|
68
|
+
|
69
|
+
# 1.8.7 エミュレート
|
70
|
+
def tap
|
71
|
+
yield(self)
|
72
|
+
self
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Keystone
|
2
|
+
class Environment
|
3
|
+
def self.ip_address
|
4
|
+
ifconfig = `/sbin/ifconfig`
|
5
|
+
ips = []
|
6
|
+
|
7
|
+
# TODO mac
|
8
|
+
ifconfig.gsub(/inet addr:(\d+\.\d+\.\d+\.\d+)/){|ip|
|
9
|
+
if $1 != '127.0.0.1'
|
10
|
+
ips << $1
|
11
|
+
end
|
12
|
+
}
|
13
|
+
return ips
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.hostname
|
17
|
+
`/bin/hostname`.chomp
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.df
|
21
|
+
`/bin/df -h`.chomp
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.ps
|
25
|
+
`/bin/ps -ef`.chomp
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.netstat
|
29
|
+
`/usr/sbin/netstat -an`.chomp
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.execute(command)
|
33
|
+
`#{command}`.chomp
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.dump
|
37
|
+
self_methods = self.methods - Class.methods
|
38
|
+
self_methods.delete("dump")
|
39
|
+
self_methods.delete("execute")
|
40
|
+
st = ""
|
41
|
+
self_methods.each do |method|
|
42
|
+
st << "#{method}:\n #{self.__send__(method).to_s.split("\n").join("\n ")}\n"
|
43
|
+
end
|
44
|
+
return st
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
#
|
2
|
+
# 普通なことをしたいならTMailを使いましょう
|
3
|
+
#
|
4
|
+
|
5
|
+
require 'net/smtp'
|
6
|
+
require 'kconv'
|
7
|
+
|
8
|
+
module Keystone
|
9
|
+
module Mail
|
10
|
+
class Send
|
11
|
+
def initialize(smtp_addr="127.0.0.1",smtp_port=25)
|
12
|
+
@smtp_addr,@smtp_port=smtp_addr,smtp_port
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.send(from,to,title,body,smtp_addr="127.0.0.1",smtp_port=25)
|
16
|
+
from_addr,from_addr_4_header = create_addr_and_header(from)
|
17
|
+
title = Kconv.tojis(title)
|
18
|
+
title = title.split(//,1).pack('m'); title = title.chomp
|
19
|
+
if to.class.to_s == 'Array'
|
20
|
+
tomany = to.join(',')
|
21
|
+
else
|
22
|
+
tomany = to.to_s;
|
23
|
+
end
|
24
|
+
|
25
|
+
head = <<HEAD
|
26
|
+
Subject: =?ISO-2022-JP?B?#{title}?=
|
27
|
+
To: #{tomany}
|
28
|
+
From: #{from_addr_4_header}
|
29
|
+
Mime-Version: 1.0
|
30
|
+
Content-Transfer-Encoding: 7bit
|
31
|
+
Content-Type: Text/Plain; charset=iso-2022-jp
|
32
|
+
HEAD
|
33
|
+
src = head + "\n" + Kconv.tojis(body)
|
34
|
+
# puts src
|
35
|
+
m = Net::SMTPSession.new(smtp_addr, smtp_port)
|
36
|
+
m.start()
|
37
|
+
m.sendmail(src, from_addr, to)
|
38
|
+
m.finish
|
39
|
+
end
|
40
|
+
|
41
|
+
def send(from,to,title,body)
|
42
|
+
self.class.send(from,to,title,body,@smtp_addr,@smtp_port)
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def self.create_addr_and_header(addr_data)
|
48
|
+
addr = ''
|
49
|
+
addr_4_header = ''
|
50
|
+
case addr_data.class.to_s
|
51
|
+
when 'String'
|
52
|
+
addr = addr_data.dup
|
53
|
+
addr_4_header = addr.dup
|
54
|
+
when 'Array'
|
55
|
+
addr = addr_data[1].dup
|
56
|
+
addr_4_header = addr_data[0].dup
|
57
|
+
addr_4_header = Kconv.tojis(addr_4_header)
|
58
|
+
addr_4_header = addr_4_header.split(//,1).pack('m'); addr_4_header = addr_4_header.chomp
|
59
|
+
addr_4_header = "=?ISO-2022-JP?B?#{addr_4_header}?=<#{addr}>"
|
60
|
+
else
|
61
|
+
# TODO exception
|
62
|
+
raise 'addr_data must be String or Array'
|
63
|
+
end
|
64
|
+
return addr,addr_4_header
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/keystone/string_util.rb
CHANGED
@@ -2,8 +2,8 @@ module Keystone
|
|
2
2
|
class StringUtil
|
3
3
|
def self.int_to_splitted_path(i_value,value_length,base_folder,suffix="")
|
4
4
|
file_name = Integer(i_value).to_s
|
5
|
-
raise "value_length must bigger than 0" if value_length < 1
|
6
|
-
raise 'i_value length is bigger than value_length' if file_name.size > value_length
|
5
|
+
raise RangeError,"value_length must bigger than 0" if value_length < 1
|
6
|
+
raise RangeError, 'i_value length is bigger than value_length' if file_name.size > value_length
|
7
7
|
file_name = file_name.rjust(value_length, '0')
|
8
8
|
new_path = base_folder.dup
|
9
9
|
group_regex = ""
|
@@ -28,5 +28,47 @@ module Keystone
|
|
28
28
|
new_path << suffix if suffix != ""
|
29
29
|
return new_path
|
30
30
|
end
|
31
|
+
|
32
|
+
def self.reverse_mail(mail)
|
33
|
+
if mail.index('@') == nil
|
34
|
+
return mail
|
35
|
+
end
|
36
|
+
user,dom = mail.split('@')
|
37
|
+
if dom == nil
|
38
|
+
return "@#{user}"
|
39
|
+
end
|
40
|
+
return dom.split('.').reverse.join(".") + "@" + user
|
41
|
+
end
|
42
|
+
|
43
|
+
MULTIBYTE_SPACE = [0x3000].pack("U")
|
44
|
+
PRESERVED_QUERY_WORDS_RE = /(AND|OR|ANDNOT)/
|
45
|
+
#
|
46
|
+
# adviced by Mr.morohashi
|
47
|
+
#
|
48
|
+
def self.serach_string_to_array(query)
|
49
|
+
tokens = query.scan(/'([^']*)'|"([^"]*)"|([^\s#{MULTIBYTE_SPACE}]*)/).flatten.reject{|i| i == nil || i == "" }
|
50
|
+
tokens.map do |token|
|
51
|
+
next unless token
|
52
|
+
#token.gsub!(PRESERVED_QUERY_WORDS_RE, $1.downcase) if token =~ PRESERVED_QUERY_WORDS_RE
|
53
|
+
token.gsub!(/\A['"]|['"]\z/, '') # strip quatos
|
54
|
+
token
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
#
|
60
|
+
# TODO
|
61
|
+
def self.downcase_roma_number(st)
|
62
|
+
st.tr("ⅠⅡⅢⅣ", "ⅰⅱⅲⅳ")
|
63
|
+
end
|
64
|
+
|
65
|
+
#
|
66
|
+
# making search text for indexing
|
67
|
+
#
|
68
|
+
def self.to_searchtext(str)
|
69
|
+
self.downcase_roma_number(Moji.han_to_zen(
|
70
|
+
Moji.zen_to_han(str,Moji::ZEN_ALNUM | Moji::ZEN_SYMBOL).downcase,Moji::HAN_KATA | Moji::HAN_JSYMBOL).tr("ー~/","ー~/")
|
71
|
+
)
|
72
|
+
end
|
31
73
|
end
|
32
|
-
end
|
74
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'redgreen'
|
3
|
+
require 'lib/keystone'
|
4
|
+
require 'lib/keystone/string_util'
|
5
|
+
|
6
|
+
$KCODE='u'
|
7
|
+
|
8
|
+
class TestStringUtilBase < Test::Unit::TestCase
|
9
|
+
def setup
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_reverse_mail
|
13
|
+
assert_equal(Keystone::StringUtil::reverse_mail("testuser@softbank.ne.jp"),"jp.ne.softbank@testuser")
|
14
|
+
assert_equal(Keystone::StringUtil::reverse_mail("test.user@somedomain.com"),"com.somedomain@test.user")
|
15
|
+
assert_equal(Keystone::StringUtil::reverse_mail("a.b@c.d"),"d.c@a.b")
|
16
|
+
assert_equal(Keystone::StringUtil::reverse_mail("a.b@"),"@a.b")
|
17
|
+
assert_equal(Keystone::StringUtil::reverse_mail("@c.d"),"d.c@")
|
18
|
+
assert_equal(Keystone::StringUtil::reverse_mail("a.b"),"a.b")
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_int_to_splitted_path
|
22
|
+
assert_equal(Keystone::StringUtil.int_to_splitted_path(113355,12,"/tmp",".jpg"),"/tmp/000/000/113/355.jpg")
|
23
|
+
assert_equal(Keystone::StringUtil.int_to_splitted_path(1234567890,10,"/temp",".png"),"/temp/1/234/567/890.png")
|
24
|
+
assert_equal(Keystone::StringUtil.int_to_splitted_path(1234567890,11,"/temp",".png"),"/temp/01/234/567/890.png")
|
25
|
+
assert_raise(RangeError){Keystone::StringUtil.int_to_splitted_path(12345678901,10,"/tmp")}
|
26
|
+
assert_equal(Keystone::StringUtil.int_to_splitted_path(00000000000000001,11,"/tmp",".gif"),"/tmp/00/000/000/001.gif")
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_serach_string_to_array
|
30
|
+
assert_equal(Keystone::StringUtil.serach_string_to_array(%|test test2 test3|),%w|test test2 test3|)
|
31
|
+
assert_equal(Keystone::StringUtil.serach_string_to_array(%|test "test2" test3|),%w|test test2 test3|)
|
32
|
+
assert_equal(Keystone::StringUtil.serach_string_to_array(%|test "test 2" test3|),["test","test 2","test3"])
|
33
|
+
assert_equal(Keystone::StringUtil.serach_string_to_array(%|"test 1" "test 2" test3|),["test 1","test 2","test3"])
|
34
|
+
assert_equal(Keystone::StringUtil.serach_string_to_array(%|"日本語 1" "test 2" test3|),["日本語 1","test 2","test3"])
|
35
|
+
assert_equal(Keystone::StringUtil.serach_string_to_array(%|"日本語 1" "test 2" ハンカク|),["日本語 1","test 2","ハンカク"])
|
36
|
+
# TODO
|
37
|
+
# assert_equal(Keystone::StringUtil.serach_string_to_array(%|"日本語 1" "tes\"t 2" ハンカク|),["日本語 1","test 2","ハンカク"])
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_to_searchtext
|
41
|
+
assert_equal(Keystone::StringUtil.to_searchtext("日本語"),"日本語")
|
42
|
+
assert_equal(Keystone::StringUtil.to_searchtext("カタカナ"),"カタカナ")
|
43
|
+
assert_equal(Keystone::StringUtil.to_searchtext("ハンカク"),"ハンカク")
|
44
|
+
assert_equal(Keystone::StringUtil.to_searchtext("A"),"a")
|
45
|
+
assert_equal(Keystone::StringUtil.to_searchtext("1"),"1")
|
46
|
+
assert_equal(Keystone::StringUtil.to_searchtext("abCD1234"),"abcd1234")
|
47
|
+
assert_equal(Keystone::StringUtil.to_searchtext("スープ"),"スープ")
|
48
|
+
assert_equal(Keystone::StringUtil.to_searchtext("スープ"),"スープ") # ハンカク半濁点
|
49
|
+
assert_equal(Keystone::StringUtil.to_searchtext("コズミックラナウェイ"),"コズミックラナウェイ") # ハンカク濁点
|
50
|
+
assert_equal(Keystone::StringUtil.to_searchtext("句読点。、・/"),"句読点。、・/") # ??? ここおかしくない??
|
51
|
+
# TODO
|
52
|
+
assert_equal(Keystone::StringUtil.to_searchtext("!”$%&¥’()*+,-./:;<=>?@[¥]^_‘{|}~#"),"!\"$%&\\'()*+,-./:;<=>?@[\\]^_`{|}~#") # 半角全角変換可能記号
|
53
|
+
assert_equal(Keystone::StringUtil.to_searchtext("。「」、ー゙゚・"),"。「」、ー゛゜・")
|
54
|
+
assert_equal(Keystone::StringUtil.to_searchtext("ⅠⅡⅢⅣ"),"ⅰⅱⅲⅳ")
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require "forwardable"
|
2
|
+
|
3
|
+
|
4
|
+
module FlagSetMaker
|
5
|
+
|
6
|
+
|
7
|
+
class FlagSet
|
8
|
+
|
9
|
+
def initialize(mod, names, zero= nil)
|
10
|
+
@module= mod
|
11
|
+
@flag_names= names.to_a()
|
12
|
+
@zero_name= zero
|
13
|
+
for i in 0...@flag_names.size
|
14
|
+
mod.const_set(@flag_names[i], Flags.new(1 << i, self))
|
15
|
+
end
|
16
|
+
mod.const_set(@zero_name, Flags.new(0, self)) if @zero_name
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_s(v)
|
20
|
+
names= []
|
21
|
+
@flag_names.each_with_index(){ |name, i| names.push(name) if v[i]==1 }
|
22
|
+
if names.empty?()
|
23
|
+
return (@zero_name.to_s() || "0")
|
24
|
+
elsif names.size==1
|
25
|
+
return names[0].to_s()
|
26
|
+
else
|
27
|
+
return "("+names.join("|")+")"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def inspect(v= nil)
|
32
|
+
return v ? format("%p::%s", @module, to_s(v)) : super()
|
33
|
+
end
|
34
|
+
|
35
|
+
def validate(v)
|
36
|
+
return v&((1 << @flag_names.size)-1)
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
class Flags
|
43
|
+
|
44
|
+
extend(Forwardable)
|
45
|
+
|
46
|
+
def initialize(v, fs)
|
47
|
+
@value= fs.validate(v)
|
48
|
+
@flag_set= fs
|
49
|
+
end
|
50
|
+
|
51
|
+
def to_i()
|
52
|
+
return @value
|
53
|
+
end
|
54
|
+
|
55
|
+
def to_s()
|
56
|
+
return @flag_set.to_s(@value)
|
57
|
+
end
|
58
|
+
|
59
|
+
def inspect()
|
60
|
+
return @flag_set.inspect(@value)
|
61
|
+
end
|
62
|
+
|
63
|
+
def ==(rhs)
|
64
|
+
return rhs.is_a?(Flags) && @flag_set==rhs.flag_set && @value==rhs.to_i()
|
65
|
+
end
|
66
|
+
|
67
|
+
alias :eql? :==
|
68
|
+
|
69
|
+
def_delegators(:to_i, :hash)
|
70
|
+
|
71
|
+
def &(rhs)
|
72
|
+
return new_flag(@value&rhs.to_i())
|
73
|
+
end
|
74
|
+
|
75
|
+
def |(rhs)
|
76
|
+
return new_flag(@value|rhs.to_i())
|
77
|
+
end
|
78
|
+
|
79
|
+
def ~()
|
80
|
+
return new_flag(~@value)
|
81
|
+
end
|
82
|
+
|
83
|
+
def include?(flags)
|
84
|
+
return (@value&flags.to_i())==flags.to_i()
|
85
|
+
end
|
86
|
+
|
87
|
+
def empty?()
|
88
|
+
return @value!=0
|
89
|
+
end
|
90
|
+
|
91
|
+
protected
|
92
|
+
|
93
|
+
attr_reader(:flag_set)
|
94
|
+
|
95
|
+
private
|
96
|
+
|
97
|
+
def new_flag(v)
|
98
|
+
return Flags.new(v, @flag_set)
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
|
104
|
+
def make_flag_set(*args)
|
105
|
+
FlagSet.new(self, *args)
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
if __FILE__==$0
|
112
|
+
|
113
|
+
class Hoge
|
114
|
+
|
115
|
+
extend(FlagSetMaker)
|
116
|
+
|
117
|
+
make_flag_set([:FOO, :BAR, :HOGE], :NONE)
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
data/vendor/moji.rb
ADDED
@@ -0,0 +1,501 @@
|
|
1
|
+
#このファイルの文字コードはUTF-8です。
|
2
|
+
#このファイルをUnicode非対応のエディタで編集してはいけません(〜が文字化ける)。
|
3
|
+
|
4
|
+
=begin
|
5
|
+
|
6
|
+
=Moji モジュール
|
7
|
+
|
8
|
+
日本語の文字種判定、文字種変換(半角→全角、ひらがな→カタカナなど)を行います。
|
9
|
+
|
10
|
+
==インストール:
|
11
|
+
|
12
|
+
解凍してできた moji ディレクトリの中で以下のコマンドを実行してください。
|
13
|
+
|
14
|
+
# ruby setup.rb
|
15
|
+
|
16
|
+
または、 moji/lib の中の moji.rb と flag_set_maker.rb を lib/ruby/site_ruby/1.8 にコピーしてください。
|
17
|
+
|
18
|
+
==使い方:
|
19
|
+
|
20
|
+
(({$KCODE})) を指定してから (({require "moji"})) してください。
|
21
|
+
Moji モジュールの関数に渡す文字列の文字コードは (({$KCODE})) と一致させてください。
|
22
|
+
|
23
|
+
$KCODE= "UTF8"
|
24
|
+
require "moji"
|
25
|
+
|
26
|
+
#文字種判定。
|
27
|
+
p Moji.type("漢") # => Moji::ZEN_KANJI
|
28
|
+
p Moji.type?("A", Moji::ZEN) # => true
|
29
|
+
|
30
|
+
#文字種変換。
|
31
|
+
p Moji.zen_to_han("Ruby") # => "Ruby"
|
32
|
+
p Moji.upcase("Ruby") # => "RUBY"
|
33
|
+
p Moji.kata_to_hira("ルビー") # => "るびー"
|
34
|
+
|
35
|
+
#文字種による正規表現。
|
36
|
+
p /#{Moji.kata}+#{Moji.hira}+/ =~ "ぼくドラえもん" # => 6
|
37
|
+
p Regexp.last_match.to_s # => "ドラえもん"
|
38
|
+
|
39
|
+
==定数:
|
40
|
+
|
41
|
+
以下の定数は、文字種の一番細かい分類です。
|
42
|
+
(({Moji.type})) が返すのは、以下の定数のうちの1つです。
|
43
|
+
|
44
|
+
--- HAN_CONTROL
|
45
|
+
制御文字。
|
46
|
+
--- HAN_ASYMBOL
|
47
|
+
ASCIIに含まれる半角記号。
|
48
|
+
--- HAN_JSYMBOL
|
49
|
+
JISに含まれるがASCIIには含まれない半角記号。
|
50
|
+
--- HAN_NUMBER
|
51
|
+
半角数字。
|
52
|
+
--- HAN_UPPER
|
53
|
+
半角アルファベット大文字。
|
54
|
+
--- HAN_LOWER
|
55
|
+
半角アルファベット小文字。
|
56
|
+
--- HAN_KATA
|
57
|
+
半角カタカナ。
|
58
|
+
--- ZEN_ASYMBOL
|
59
|
+
JISの全角記号のうち、ASCIIに対応する半角記号があるもの。
|
60
|
+
--- ZEN_JSYMBOL
|
61
|
+
JISの全角記号のうち、ASCIIに対応する半角記号がないもの。
|
62
|
+
--- ZEN_NUMBER
|
63
|
+
全角数字。
|
64
|
+
--- ZEN_UPPER
|
65
|
+
全角アルファベット大文字。
|
66
|
+
--- ZEN_LOWER
|
67
|
+
全角アルファベット小文字。
|
68
|
+
--- ZEN_HIRA
|
69
|
+
ひらがな。
|
70
|
+
--- ZEN_KATA
|
71
|
+
全角カタカナ。
|
72
|
+
--- ZEN_GREEK
|
73
|
+
ギリシャ文字。
|
74
|
+
--- ZEN_CYRILLIC
|
75
|
+
キリル文字。
|
76
|
+
--- ZEN_LINE
|
77
|
+
罫線のかけら。
|
78
|
+
--- ZEN_KANJI
|
79
|
+
漢字。
|
80
|
+
|
81
|
+
以下の定数は、上の文字種の組み合わせと別名です。
|
82
|
+
|
83
|
+
--- HAN_SYMBOL
|
84
|
+
JISに含まれる半角記号。(({HAN_ASYMBOL | HAN_JSYMBOL}))
|
85
|
+
--- HAN_ALPHA
|
86
|
+
半角アルファベット。(({HAN_UPPER | HAN_LOWER}))
|
87
|
+
--- HAN_ALNUM
|
88
|
+
半角英数字。(({HAN_ALPHA | HAN_NUMBER}))
|
89
|
+
--- HAN
|
90
|
+
全ての半角文字。(({HAN_CONTROL | HAN_SYMBOL | HAN_ALNUM | HAN_KATA}))
|
91
|
+
--- ZEN_SYMBOL
|
92
|
+
JISに含まれる全角記号。(({ZEN_ASYMBOL | ZEN_JSYMBOL}))
|
93
|
+
--- ZEN_ALPHA
|
94
|
+
全角アルファベット。(({ZEN_UPPER | ZEN_LOWER}))
|
95
|
+
--- ZEN_ALNUM
|
96
|
+
全角英数字。(({ZEN_ALPHA | ZEN_NUMBER}))
|
97
|
+
--- ZEN_KANA
|
98
|
+
全角かな/カナ。(({ZEN_KATA | ZEN_HIRA}))
|
99
|
+
--- ZEN
|
100
|
+
JISに含まれる全ての全角文字。(({ZEN_SYMBOL | ZEN_ALNUM | ZEN_KANA | ZEN_GREEK | ZEN_CYRILLIC | ZEN_LINE | ZEN_KANJI}))
|
101
|
+
--- ASYMBOL
|
102
|
+
ASCIIに含まれる半角記号とその全角版。(({HAN_ASYMBOL | ZEN_ASYMBOL}))
|
103
|
+
--- JSYMBOL
|
104
|
+
JISに含まれるが (({ASYMBOL})) には含まれない全角/半角記号。(({HAN_JSYMBOL | ZEN_JSYMBOL}))
|
105
|
+
--- SYMBOL
|
106
|
+
JISに含まれる全ての全角/半角記号。(({HAN_SYMBOL | ZEN_SYMBOL}))
|
107
|
+
--- NUMBER
|
108
|
+
全角/半角数字。(({HAN_NUMBER | ZEN_NUMBER}))
|
109
|
+
--- UPPER
|
110
|
+
全角/半角アルファベット大文字。(({HAN_UPPER | ZEN_UPPER}))
|
111
|
+
--- LOWER
|
112
|
+
全角/半角アルファベット小文字。(({HAN_LOWER | ZEN_LOWER}))
|
113
|
+
--- ALPHA
|
114
|
+
全角/半角アルファベット。(({HAN_ALPHA | ZEN_ALPHA}))
|
115
|
+
--- ALNUM
|
116
|
+
全角/半角英数字。(({HAN_ALNUM | ZEN_ALNUM}))
|
117
|
+
--- HIRA
|
118
|
+
(({ZEN_HIRA})) の別名。
|
119
|
+
--- KATA
|
120
|
+
全角/半角カタカナ。(({HAN_KATA | ZEN_KATA}))
|
121
|
+
--- KANA
|
122
|
+
全角/半角 かな/カナ。(({KATA | ZEN_HIRA}))
|
123
|
+
--- GREEK
|
124
|
+
(({ZEN_GREEK})) の別名。
|
125
|
+
--- CYRILLIC
|
126
|
+
(({ZEN_CYRILLIC})) の別名。
|
127
|
+
--- LINE
|
128
|
+
(({ZEN_LINE})) の別名。
|
129
|
+
--- KANJI
|
130
|
+
(({ZEN_KANJI})) の別名。
|
131
|
+
--- ALL
|
132
|
+
上記全ての文字。
|
133
|
+
|
134
|
+
==モジュール関数:
|
135
|
+
|
136
|
+
--- Moji.type(ch)
|
137
|
+
|
138
|
+
文字 ((|ch|)) の文字種を返します。
|
139
|
+
|
140
|
+
「一番細かい分類」の((<定数|定数:>))のうち1つを返します。
|
141
|
+
|
142
|
+
上の分類に当てはまらない文字(Unicodeのハングルなど)に対しては (({nil})) を返します。
|
143
|
+
また、UnicodeのB面以降の文字に対しても (({nil})) を返します。
|
144
|
+
|
145
|
+
文字が割り当てられていない文字コードに対する結果は不定です( (({nil})) を返す事もあります)。
|
146
|
+
|
147
|
+
p Moji.type("漢") # => Moji::ZEN_KANJI
|
148
|
+
|
149
|
+
--- Moji.type?(ch, type)
|
150
|
+
|
151
|
+
文字 ((|ch|)) が文字種 ((|type|)) に含まれれば、 (({true})) を返します。
|
152
|
+
|
153
|
+
((|type|)) には全ての((<定数|定数:>))と、それらを (({|}))
|
154
|
+
で結んだものを使えます。
|
155
|
+
|
156
|
+
p Moji.type?("A", Moji::ZEN) # => true
|
157
|
+
|
158
|
+
--- Moji.regexp(type)
|
159
|
+
|
160
|
+
文字種 ((|type|)) の1文字を表す正規表現を返します。
|
161
|
+
|
162
|
+
((|type|)) には全ての((<定数|定数:>))と、それらを (({|}))
|
163
|
+
で結んだものを使えます。
|
164
|
+
|
165
|
+
p Moji.regexp(Moji::HIRA) # => /[ぁ-ん]/
|
166
|
+
|
167
|
+
--- Moji.zen_to_han(str[, type])
|
168
|
+
|
169
|
+
文字列 ((|str|)) の全角を半角に変換して返します。
|
170
|
+
|
171
|
+
((|type|)) には、変換対象とする文字種を((<定数|定数:>))で指定します。
|
172
|
+
デフォルトは (({ALL})) (全て)です。
|
173
|
+
|
174
|
+
p Moji.zen_to_han("Ruby!?") # => "Ruby!?"
|
175
|
+
p Moji.zen_to_han("Ruby!?", Moji::ALPHA) # => "Ruby!?"
|
176
|
+
|
177
|
+
--- Moji.han_to_zen(str[, type])
|
178
|
+
|
179
|
+
文字列 ((|str|)) の半角を全角に変換して返します。
|
180
|
+
|
181
|
+
((|type|)) には、変換対象とする文字種を((<定数|定数:>))で指定します。
|
182
|
+
デフォルトは (({ALL})) (全て)です。
|
183
|
+
|
184
|
+
p Moji.han_to_zen("Ruby!?") # => "Ruby!?"
|
185
|
+
p Moji.han_to_zen("Ruby!?", Moji::SYMBOL) # => "Ruby!?"
|
186
|
+
|
187
|
+
--- Moji.normalize_zen_han(str)
|
188
|
+
|
189
|
+
文字列 ((|str|)) の大文字、小文字を一般的なものに統一します。
|
190
|
+
|
191
|
+
具体的には、ASCIIに含まれる記号と英数字( (({ALNUM|ASYMBOL}))
|
192
|
+
)を半角に、それ以外の記号とカタカナ( (({JSYMBOL|HAN_KATA})) )を全角に変換します。
|
193
|
+
|
194
|
+
--- Moji.upcase(str[, type])
|
195
|
+
|
196
|
+
文字列 ((|str|)) の小文字を大文字に変換して返します。
|
197
|
+
|
198
|
+
((|type|)) には、変換対象とする文字種を((<定数|定数:>))で指定します。
|
199
|
+
デフォルトは (({LOWER})) (全角/半角のアルファベット)です。
|
200
|
+
ギリシャ文字、キリル文字には対応していません。
|
201
|
+
|
202
|
+
p Moji.upcase("Ruby") # => "RUBY"
|
203
|
+
|
204
|
+
--- Moji.downcase(str[, type])
|
205
|
+
|
206
|
+
文字列 ((|str|)) の小文字を大文字に変換して返します。
|
207
|
+
|
208
|
+
((|type|)) には、変換対象とする文字種を((<定数|定数:>))で指定します。
|
209
|
+
デフォルトは (({UPPER})) (全角/半角のアルファベット)です。
|
210
|
+
ギリシャ文字、キリル文字には対応していません。
|
211
|
+
|
212
|
+
p Moji.downcase("Ruby") # => "ruby"
|
213
|
+
|
214
|
+
--- Moji.kata_to_hira(str)
|
215
|
+
|
216
|
+
文字列 ((|str|)) の全角カタカナをひらがなに変換して返します。
|
217
|
+
|
218
|
+
半角カタカナは直接変換できません。 (({han_to_zen})) で全角にしてから変換してください。
|
219
|
+
|
220
|
+
p Moji.kata_to_hira("ルビー") # => "るびー"
|
221
|
+
|
222
|
+
--- Moji.hira_to_kata(str)
|
223
|
+
|
224
|
+
文字列 ((|str|)) のひらがなを全角カタカナに変換して返します。
|
225
|
+
|
226
|
+
p Moji.hira_to_kata("るびー") # => "ルビー"
|
227
|
+
|
228
|
+
--- Moji.han_control
|
229
|
+
--- Moji.han_asymbol
|
230
|
+
--- ...
|
231
|
+
--- Moji.kana
|
232
|
+
--- ...
|
233
|
+
|
234
|
+
((<定数|定数:>))それぞれに対応するメソッドが有り、
|
235
|
+
それぞれの文字種の1文字を表す正規表現を返します。
|
236
|
+
|
237
|
+
例えば、 (({Moji.kana})) は (({Moji.regexp(Moji::KANA)})) と同じです。
|
238
|
+
|
239
|
+
以下の例のように、文字クラスっぽく使えます。
|
240
|
+
p /#{Moji.kata}+#{Moji.hira}+/ =~ "ぼくドラえもん" # => 6
|
241
|
+
p Regexp.last_match.to_s # => "ドラえもん"
|
242
|
+
|
243
|
+
==動作環境:
|
244
|
+
|
245
|
+
たぶんRuby 1.8以降。
|
246
|
+
|
247
|
+
FreeBSD Ruby 1.8.5にて動作確認しました。
|
248
|
+
|
249
|
+
==置き場所/連絡先:
|
250
|
+
|
251
|
+
置き場所: ((<URL:http://gimite.ddo.jp/pukiwiki/index.php?Ruby%BE%AE%CA%AA%BD%B8>))
|
252
|
+
|
253
|
+
作者: Gimite 市川 (連絡先: ((<URL:http://gimite.ddo.jp/bbs/tnote.cgi>)) )
|
254
|
+
|
255
|
+
==ライセンス:
|
256
|
+
|
257
|
+
Public Domainです。煮るなり焼くなりご自由に。
|
258
|
+
|
259
|
+
==更新履歴:
|
260
|
+
|
261
|
+
2006/7/23 Ver.1.3
|
262
|
+
*半角中黒(・)の字種判別、全角中黒との相互変換ができていなかったのを修正。(thanks to xyzzyさん)
|
263
|
+
|
264
|
+
2006/10/5 Ver.1.2
|
265
|
+
*EUC 以外の文字コードにも対応し、ライブラリ名を Moji に変更。
|
266
|
+
*han_to_zen, zen_to_han の対象文字種のデフォルトを全て( (({ALL})) )に。
|
267
|
+
*normalize_zen_han 追加。
|
268
|
+
|
269
|
+
2005/1/3 Ver.1.1
|
270
|
+
*(({$KCODE})) が指定されていないとEUCUtil.typeが正常動作しない問題を修正。
|
271
|
+
*定数に (({ASYMBOL})) と (({JSYMBOL})) を追加。
|
272
|
+
|
273
|
+
2004/11/16 Ver.1.0
|
274
|
+
*EUCUtil 公開。
|
275
|
+
|
276
|
+
=end
|
277
|
+
|
278
|
+
|
279
|
+
if $KCODE=="NONE"
|
280
|
+
warn("Warning: Set $KCODE before requiring 'moji' (UTF8 assumed)")
|
281
|
+
$KCODE= "u"
|
282
|
+
end
|
283
|
+
|
284
|
+
require "nkf"
|
285
|
+
require "jcode"
|
286
|
+
require "enumerator"
|
287
|
+
require "flag_set_maker"
|
288
|
+
|
289
|
+
nkf_kcode= {"SJIS" => "s", "EUC" => "e"}[$KCODE]
|
290
|
+
|
291
|
+
script= <<'EOS'
|
292
|
+
|
293
|
+
|
294
|
+
module Moji
|
295
|
+
|
296
|
+
extend(FlagSetMaker)
|
297
|
+
|
298
|
+
module Detail
|
299
|
+
|
300
|
+
HAN_ASYMBOL_LIST= ' !"#$%&\'()*+,-./:;<=>?@[\]^_`{|}~'
|
301
|
+
ZEN_ASYMBOL_LIST= ' !”#$%&’()*+,-./:;<=>?@[¥]^_‘{|} ̄'
|
302
|
+
HAN_JSYMBOL1_LIST= '。「」、ー゙゚・'
|
303
|
+
ZEN_JSYMBOL1_LIST= '。「」、ー゛゜・'
|
304
|
+
ZEN_JSYMBOL_LIST= '、。・゛゜´`¨ヽヾゝゞ〃仝々〆〇ー―‐\~〜∥…‥“〔〕〈〉《》「」『』【】'+
|
305
|
+
'±×÷≠≦≧∞∴♂♀°′″℃¢£§☆★○●◎◇◇◆□■△▲▽▼※〒→←↑↓〓'
|
306
|
+
HAN_KATA_LIST= 'ハヒフヘホウカキクケコサシスセソタチツテトアイエオナニヌネノマミムメモヤユヨラリルレロワヲンァィゥェォャュョッ'.split(//)
|
307
|
+
HAN_VSYMBOLS= ['', '゙', '゚']
|
308
|
+
ZEN_KATA_LISTS= [
|
309
|
+
'ハヒフヘホウカキクケコサシスセソタチツテトアイエオ'+
|
310
|
+
'ナニヌネノマミムメモヤユヨラリルレロワヲンァィゥェォャュョッ',
|
311
|
+
'バビブベボヴガギグゲゴザジズゼゾダヂヅデド',
|
312
|
+
'パピプペポ',
|
313
|
+
].map(){ |s| s.split(//) }
|
314
|
+
|
315
|
+
end
|
316
|
+
|
317
|
+
def self.uni_range(*args)
|
318
|
+
if $KCODE=="UTF8"
|
319
|
+
str= args.map(){ |n| NKF.nkf("-wW160x", [n].pack("n")) }.
|
320
|
+
enum_slice(2).map(){ |f, e| "#{f}-#{e}" }.to_s()
|
321
|
+
return /[#{str}]/u
|
322
|
+
else
|
323
|
+
return nil
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
make_flag_set([
|
328
|
+
:HAN_CONTROL, :HAN_ASYMBOL, :HAN_JSYMBOL, :HAN_NUMBER, :HAN_UPPER, :HAN_LOWER, :HAN_KATA,
|
329
|
+
:ZEN_ASYMBOL, :ZEN_JSYMBOL, :ZEN_NUMBER, :ZEN_UPPER, :ZEN_LOWER, :ZEN_HIRA, :ZEN_KATA,
|
330
|
+
:ZEN_GREEK, :ZEN_CYRILLIC, :ZEN_LINE, :ZEN_KANJI,
|
331
|
+
])
|
332
|
+
|
333
|
+
HAN_SYMBOL= HAN_ASYMBOL | HAN_JSYMBOL
|
334
|
+
HAN_ALPHA= HAN_UPPER | HAN_LOWER
|
335
|
+
HAN_ALNUM= HAN_ALPHA | HAN_NUMBER
|
336
|
+
HAN= HAN_CONTROL | HAN_SYMBOL | HAN_ALNUM | HAN_KATA
|
337
|
+
ZEN_SYMBOL= ZEN_ASYMBOL | ZEN_JSYMBOL
|
338
|
+
ZEN_ALPHA= ZEN_UPPER | ZEN_LOWER
|
339
|
+
ZEN_ALNUM= ZEN_ALPHA | ZEN_NUMBER
|
340
|
+
ZEN_KANA= ZEN_KATA | ZEN_HIRA
|
341
|
+
ZEN= ZEN_SYMBOL | ZEN_ALNUM | ZEN_KANA | ZEN_GREEK | ZEN_CYRILLIC | ZEN_LINE | ZEN_KANJI
|
342
|
+
ASYMBOL= HAN_ASYMBOL | ZEN_ASYMBOL
|
343
|
+
JSYMBOL= HAN_JSYMBOL | ZEN_JSYMBOL
|
344
|
+
SYMBOL= HAN_SYMBOL | ZEN_SYMBOL
|
345
|
+
NUMBER= HAN_NUMBER | ZEN_NUMBER
|
346
|
+
UPPER= HAN_UPPER | ZEN_UPPER
|
347
|
+
LOWER= HAN_LOWER | ZEN_LOWER
|
348
|
+
ALPHA= HAN_ALPHA | ZEN_ALPHA
|
349
|
+
ALNUM= HAN_ALNUM | ZEN_ALNUM
|
350
|
+
HIRA= ZEN_HIRA
|
351
|
+
KATA= HAN_KATA | ZEN_KATA
|
352
|
+
KANA= KATA | ZEN_HIRA
|
353
|
+
GREEK= ZEN_GREEK
|
354
|
+
CYRILLIC= ZEN_CYRILLIC
|
355
|
+
LINE= ZEN_LINE
|
356
|
+
KANJI= ZEN_KANJI
|
357
|
+
ALL= HAN | ZEN
|
358
|
+
|
359
|
+
CHAR_REGEXPS= {
|
360
|
+
HAN_CONTROL => /[\x00-\x1f\x7f]/,
|
361
|
+
HAN_ASYMBOL =>
|
362
|
+
Regexp.new("["+Detail::HAN_ASYMBOL_LIST.gsub(/[\[\]\-\^\\]/){ "\\"+$& }+"]"),
|
363
|
+
HAN_JSYMBOL => Regexp.new("["+Detail::HAN_JSYMBOL1_LIST+"]"),
|
364
|
+
HAN_NUMBER => /[0-9]/,
|
365
|
+
HAN_UPPER => /[A-Z]/,
|
366
|
+
HAN_LOWER => /[a-z]/,
|
367
|
+
HAN_KATA => /[ヲ-ッア-ン]/,
|
368
|
+
ZEN_ASYMBOL => Regexp.new("["+Detail::ZEN_ASYMBOL_LIST+"]"),
|
369
|
+
ZEN_JSYMBOL => Regexp.new("["+Detail::ZEN_JSYMBOL_LIST+"]"),
|
370
|
+
ZEN_NUMBER => /[0-9]/,
|
371
|
+
ZEN_UPPER => /[A-Z]/,
|
372
|
+
ZEN_LOWER => /[a-z]/,
|
373
|
+
ZEN_HIRA => /[ぁ-ん]/,
|
374
|
+
ZEN_KATA => /[ァ-ヶ]/,
|
375
|
+
ZEN_GREEK => /[Α-Ωα-ω]/,
|
376
|
+
ZEN_CYRILLIC => /[А-Яа-я]/,
|
377
|
+
ZEN_LINE => uni_range(0x2570, 0x25ff) || /[─-╂]/,
|
378
|
+
ZEN_KANJI => uni_range(0x3400, 0x9fff, 0xf900, 0xfaff) || /[亜-瑤]/,
|
379
|
+
}
|
380
|
+
|
381
|
+
def type(ch)
|
382
|
+
ch=~/^./
|
383
|
+
ch= $&
|
384
|
+
for tp, reg in CHAR_REGEXPS
|
385
|
+
return tp if ch=~reg
|
386
|
+
end
|
387
|
+
return nil
|
388
|
+
end
|
389
|
+
|
390
|
+
def type?(ch, tp)
|
391
|
+
return tp.include?(type(ch))
|
392
|
+
end
|
393
|
+
|
394
|
+
def regexp(tp)
|
395
|
+
regs= []
|
396
|
+
for tp2, reg in CHAR_REGEXPS
|
397
|
+
regs.push(reg) if tp.include?(tp2)
|
398
|
+
end
|
399
|
+
return regs.size==1 ? regs[0] : Regexp.new(regs.join("|"))
|
400
|
+
end
|
401
|
+
|
402
|
+
def zen_to_han(str, tp= ALL)
|
403
|
+
if tp.include?(ZEN_KATA)
|
404
|
+
reg= Regexp.new("["+Detail::ZEN_KATA_LISTS.to_s()+"]")
|
405
|
+
str= str.gsub(reg) do
|
406
|
+
for i in 0...3
|
407
|
+
pos= Detail::ZEN_KATA_LISTS[i].index($&)
|
408
|
+
break Detail::HAN_KATA_LIST[pos]+Detail::HAN_VSYMBOLS[i] if pos
|
409
|
+
end
|
410
|
+
end
|
411
|
+
end
|
412
|
+
str= str.tr("a-z", "a-z") if tp.include?(ZEN_LOWER)
|
413
|
+
str= str.tr("A-Z", "A-Z") if tp.include?(ZEN_UPPER)
|
414
|
+
str= str.tr("0-9", "0-9") if tp.include?(ZEN_NUMBER)
|
415
|
+
str= str.tr(Detail::ZEN_ASYMBOL_LIST,
|
416
|
+
Detail::HAN_ASYMBOL_LIST.gsub(/[\-\^\\]/){ "\\"+$& }) if tp.include?(ZEN_ASYMBOL)
|
417
|
+
str= str.tr(Detail::ZEN_JSYMBOL1_LIST,
|
418
|
+
Detail::HAN_JSYMBOL1_LIST) if tp.include?(ZEN_JSYMBOL)
|
419
|
+
return str
|
420
|
+
end
|
421
|
+
|
422
|
+
def han_to_zen(str, tp= ALL)
|
423
|
+
#[半]濁音記号がJSYMBOLに含まれるので、KATAの変換をJSYMBOLより前にやる必要あり。
|
424
|
+
if tp.include?(HAN_KATA)
|
425
|
+
str= str.gsub(/(#{han_kata})([゙゚]?)/) do
|
426
|
+
i= {""=>0, "゙"=>1, "゚"=>2}[$2]
|
427
|
+
pos= Detail::HAN_KATA_LIST.index($1)
|
428
|
+
s= Detail::ZEN_KATA_LISTS[i][pos]
|
429
|
+
(!s || s=="") ? Detail::ZEN_KATA_LISTS[0][pos]+$2 : s
|
430
|
+
end
|
431
|
+
end
|
432
|
+
str= str.tr("a-z", "a-z") if tp.include?(HAN_LOWER)
|
433
|
+
str= str.tr("A-Z", "A-Z") if tp.include?(HAN_UPPER)
|
434
|
+
str= str.tr("0-9", "0-9") if tp.include?(HAN_NUMBER)
|
435
|
+
str= str.tr(Detail::HAN_ASYMBOL_LIST.gsub(/[\-\^\\]/){ "\\"+$& },
|
436
|
+
Detail::ZEN_ASYMBOL_LIST) if tp.include?(HAN_ASYMBOL)
|
437
|
+
str= str.tr(Detail::HAN_JSYMBOL1_LIST,
|
438
|
+
Detail::ZEN_JSYMBOL1_LIST) if tp.include?(HAN_JSYMBOL)
|
439
|
+
return str
|
440
|
+
end
|
441
|
+
|
442
|
+
def normalize_zen_han(str)
|
443
|
+
return zen_to_han(han_to_zen(str, HAN_JSYMBOL|HAN_KATA), ZEN_ALNUM|ZEN_ASYMBOL)
|
444
|
+
end
|
445
|
+
|
446
|
+
def upcase(str, tp= LOWER)
|
447
|
+
str= str.tr("a-z", "A-Z") if tp.include?(HAN_LOWER)
|
448
|
+
str= str.tr("a-z", "A-Z") if tp.include?(ZEN_LOWER)
|
449
|
+
end
|
450
|
+
|
451
|
+
def downcase(str, tp= UPPER)
|
452
|
+
str= str.tr("A-Z", "a-z") if tp.include?(HAN_UPPER)
|
453
|
+
str= str.tr("A-Z", "a-z") if tp.include?(ZEN_UPPER)
|
454
|
+
end
|
455
|
+
|
456
|
+
def kata_to_hira(str)
|
457
|
+
return str.tr("ァ-ン", "ぁ-ん")
|
458
|
+
end
|
459
|
+
|
460
|
+
def hira_to_kata(str)
|
461
|
+
return str.tr("ぁ-ん", "ァ-ン")
|
462
|
+
end
|
463
|
+
|
464
|
+
module_function(
|
465
|
+
:type, :type?, :regexp, :zen_to_han, :han_to_zen, :normalize_zen_han, :upcase, :downcase,
|
466
|
+
:kata_to_hira, :hira_to_kata
|
467
|
+
)
|
468
|
+
|
469
|
+
def self.define_regexp_method(name, tp)
|
470
|
+
define_method(name){ regexp(tp) }
|
471
|
+
module_function(name)
|
472
|
+
end
|
473
|
+
|
474
|
+
#han_control, han_asymbol, …などのモジュール関数を定義。
|
475
|
+
for cons in constants
|
476
|
+
val= const_get(cons)
|
477
|
+
define_regexp_method(cons.downcase(), val) if val.is_a?(FlagSetMaker::Flags)
|
478
|
+
end
|
479
|
+
|
480
|
+
def self.test()
|
481
|
+
str= "ドラえもん(Doraemon)は、日本で1番有名な漫画だ。"
|
482
|
+
str.each_char() do |ch|
|
483
|
+
printf("%2s %s\n", ch, Moji.type(ch))
|
484
|
+
end
|
485
|
+
str= Moji.zen_to_han(str, Moji::ALL)
|
486
|
+
puts(str)
|
487
|
+
str= Moji.han_to_zen(str, Moji::ALL)
|
488
|
+
puts(str)
|
489
|
+
end
|
490
|
+
|
491
|
+
end
|
492
|
+
|
493
|
+
EOS
|
494
|
+
|
495
|
+
script= NKF.nkf("-#{nkf_kcode}Wx", script) if nkf_kcode
|
496
|
+
#UTF-8の場合、nkfしてはいけない(~が〜になるので)。
|
497
|
+
eval(script, TOPLEVEL_BINDING)
|
498
|
+
|
499
|
+
if __FILE__==$0
|
500
|
+
Moji.test()
|
501
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kanamei-kanamei-keystone
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- kanamei
|
@@ -22,9 +22,21 @@ extensions: []
|
|
22
22
|
extra_rdoc_files: []
|
23
23
|
|
24
24
|
files:
|
25
|
+
- example/batch_sample.rb
|
26
|
+
- example/string_util.rb
|
27
|
+
- test/test_string_util.rb
|
25
28
|
- lib/keystone
|
29
|
+
- lib/keystone/base.rb
|
30
|
+
- lib/keystone/batch_base.rb
|
31
|
+
- lib/keystone/core_ext.rb
|
32
|
+
- lib/keystone/environment.rb
|
33
|
+
- lib/keystone/mail
|
34
|
+
- lib/keystone/mail/send.rb
|
35
|
+
- lib/keystone/mail.rb
|
26
36
|
- lib/keystone/string_util.rb
|
27
37
|
- lib/keystone.rb
|
38
|
+
- vendor/flag_set_maker.rb
|
39
|
+
- vendor/moji.rb
|
28
40
|
has_rdoc: false
|
29
41
|
homepage: http://github.com/kanamei/keystone/tree/master
|
30
42
|
post_install_message:
|
@@ -32,6 +44,9 @@ rdoc_options: []
|
|
32
44
|
|
33
45
|
require_paths:
|
34
46
|
- lib
|
47
|
+
- vendor
|
48
|
+
- example
|
49
|
+
- test
|
35
50
|
required_ruby_version: !ruby/object:Gem::Requirement
|
36
51
|
requirements:
|
37
52
|
- - ">="
|