tagen 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/.yardopts +5 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +24 -0
- data/README.md +60 -0
- data/Rakefile +9 -0
- data/docs/Architecture.md +17 -0
- data/docs/CoreExtensions.md +56 -0
- data/docs/ExtraExtensions.md +20 -0
- data/lib/tagen/audioinfo.rb +21 -0
- data/lib/tagen/cairo.rb +809 -0
- data/lib/tagen/core.rb +34 -0
- data/lib/tagen/core/array.rb +41 -0
- data/lib/tagen/core/array/extract_options.rb +40 -0
- data/lib/tagen/core/hash.rb +17 -0
- data/lib/tagen/core/io.rb +29 -0
- data/lib/tagen/core/kernel.rb +73 -0
- data/lib/tagen/core/marshal.rb +34 -0
- data/lib/tagen/core/module.rb +25 -0
- data/lib/tagen/core/numeric.rb +10 -0
- data/lib/tagen/core/object.rb +21 -0
- data/lib/tagen/core/pa.rb +187 -0
- data/lib/tagen/core/pa/cmd.rb +374 -0
- data/lib/tagen/core/pa/dir.rb +144 -0
- data/lib/tagen/core/pa/path.rb +190 -0
- data/lib/tagen/core/pa/state.rb +56 -0
- data/lib/tagen/core/process.rb +11 -0
- data/lib/tagen/core/re.rb +8 -0
- data/lib/tagen/core/string.rb +43 -0
- data/lib/tagen/core/string/pyformat.rb +322 -0
- data/lib/tagen/core/time.rb +8 -0
- data/lib/tagen/gdk_pixbuf2.rb +26 -0
- data/lib/tagen/gtk2.rb +122 -0
- data/lib/tagen/magick.rb +23 -0
- data/lib/tagen/ncurses.rb +245 -0
- data/lib/tagen/net/http.rb +34 -0
- data/lib/tagen/pathname.rb +8 -0
- data/lib/tagen/poppler.rb +47 -0
- data/lib/tagen/socket.rb +20 -0
- data/lib/tagen/tree.rb +75 -0
- data/lib/tagen/vim.rb +19 -0
- data/lib/tagen/xmpp4r.rb +1 -0
- data/lib/tagen/xmpp4r/roster.rb +20 -0
- data/spec/cairo_spec.rb +137 -0
- data/spec/core/pa/cmd_spec.rb +251 -0
- data/spec/core/pa/dir_spec.rb +59 -0
- data/spec/core/string/pyformat_spec.rb +86 -0
- data/spec/spec_helper.rb +0 -0
- data/tagen.gemspec +20 -0
- data/version.rb +7 -0
- metadata +117 -0
data/lib/tagen/core.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# from ActiveSupport
|
2
|
+
%w(
|
3
|
+
object/blank object/try
|
4
|
+
module/attribute_accessors
|
5
|
+
class/attribute_accessors
|
6
|
+
string/strip string/access
|
7
|
+
numeric/bytes
|
8
|
+
enumerable
|
9
|
+
array/access array/wrap
|
10
|
+
hash/deep_merge
|
11
|
+
).each {|n| require "active_support/core_ext/#{n}"}
|
12
|
+
|
13
|
+
# from core
|
14
|
+
%w(
|
15
|
+
core/kernel
|
16
|
+
core/object
|
17
|
+
core/module
|
18
|
+
|
19
|
+
core/numeric
|
20
|
+
core/string
|
21
|
+
core/array
|
22
|
+
core/hash
|
23
|
+
core/re
|
24
|
+
|
25
|
+
core/time
|
26
|
+
core/io
|
27
|
+
core/process
|
28
|
+
|
29
|
+
core/pa
|
30
|
+
).each {|n| require_relative n }
|
31
|
+
|
32
|
+
# from stdlib
|
33
|
+
require "time"
|
34
|
+
require "date"
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require_relative "array/extract_options"
|
2
|
+
=begin
|
3
|
+
Additional method list
|
4
|
+
----------------------
|
5
|
+
|
6
|
+
* `#append` _alias from push_
|
7
|
+
|
8
|
+
=end
|
9
|
+
class Array
|
10
|
+
alias append push
|
11
|
+
|
12
|
+
alias original_delete delete
|
13
|
+
|
14
|
+
# support delete more than one values.
|
15
|
+
#
|
16
|
+
# original: delete(v)
|
17
|
+
# currrent: delete(*v)
|
18
|
+
#
|
19
|
+
# @return [Array]
|
20
|
+
def delete *values, &blk
|
21
|
+
indexs = values.each.with_object [] do |v,m|
|
22
|
+
m << original_delete(v, &blk)
|
23
|
+
end
|
24
|
+
values.length==1 ? indexs[0] : indexs
|
25
|
+
end
|
26
|
+
|
27
|
+
alias original_delete_at delete_at
|
28
|
+
|
29
|
+
# support delate_at more than one index.
|
30
|
+
#
|
31
|
+
# original: delete_at(i)
|
32
|
+
# current: delte_at(*i)
|
33
|
+
#
|
34
|
+
# @return [Array]
|
35
|
+
def delete_at *indexs, &blk
|
36
|
+
values = indexs.each.with_object [] do |i,m|
|
37
|
+
m << original_delete_at(i, &blk)
|
38
|
+
end
|
39
|
+
indexs.length==1 ? values[0] : values
|
40
|
+
end
|
41
|
+
end # class Array
|
@@ -0,0 +1,40 @@
|
|
1
|
+
class Array
|
2
|
+
# Extracts options from a set of arguments. Removes and returns the last
|
3
|
+
# element in the array if it's a hash, otherwise returns a blank hash.
|
4
|
+
# you can also pass a default option.
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# def options(*args)
|
8
|
+
# o = args.extract_options!(:a=>1)
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# options(1, 2) # => {:a=>1}
|
12
|
+
# options(1, 2, :a => :b) # => {:a=>:b}
|
13
|
+
#
|
14
|
+
# @param [Hash] default default options
|
15
|
+
# @return [Hash]
|
16
|
+
def extract_options! default={}
|
17
|
+
if self.last.is_a?(Hash) && self.last.instance_of?(Hash)
|
18
|
+
self.pop.merge default
|
19
|
+
else
|
20
|
+
default
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# extract options
|
25
|
+
# @see extract_options!
|
26
|
+
# @example
|
27
|
+
# def mkdir(*args)
|
28
|
+
# paths, o = args.extract_options
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# @return [Array<Array,Hash>]
|
32
|
+
def extract_options default={}
|
33
|
+
if self.last.is_a?(Hash) && self.last.instance_of?(Hash)
|
34
|
+
[self[0...-1], self[-1].merge(default)]
|
35
|
+
else
|
36
|
+
[self, default]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class Hash
|
2
|
+
alias :original_delete :delete
|
3
|
+
|
4
|
+
# support delete more than one keys
|
5
|
+
#
|
6
|
+
# original: delete(key)
|
7
|
+
# current: delete(*keys)
|
8
|
+
#
|
9
|
+
# return [Hash]
|
10
|
+
def delete *keys, &blk
|
11
|
+
values = keys.each.with_object [] do |k,m|
|
12
|
+
m << original_delete(k, &blk)
|
13
|
+
end
|
14
|
+
keys.length==1 ? values[0] : values
|
15
|
+
end
|
16
|
+
|
17
|
+
end # class Hash
|
@@ -0,0 +1,29 @@
|
|
1
|
+
=begin
|
2
|
+
Additional Method list
|
3
|
+
----------------------
|
4
|
+
|
5
|
+
* `#fd` _alias from fileno_
|
6
|
+
|
7
|
+
=end
|
8
|
+
class IO
|
9
|
+
|
10
|
+
# a convient function to write text.
|
11
|
+
#
|
12
|
+
# use open(path, "w"){|f| f.write(text)}
|
13
|
+
#
|
14
|
+
# @param [String] path
|
15
|
+
# @param [String] text
|
16
|
+
# @return [String]
|
17
|
+
def self.write(path, text) open(path, "w"){|f| f.write(text)} end
|
18
|
+
|
19
|
+
# a convient function to append text.
|
20
|
+
#
|
21
|
+
# use open(path, "a"){|f| f.write(text)}
|
22
|
+
#
|
23
|
+
# @param [String] path
|
24
|
+
# @param [String] text
|
25
|
+
# @return [String]
|
26
|
+
def self.append(path, text) open(path, "a"){|f| f.write(text)} end
|
27
|
+
|
28
|
+
alias fd fileno
|
29
|
+
end # class IO
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Kernel
|
2
|
+
private
|
3
|
+
|
4
|
+
# same as `` `` ``, but add some options
|
5
|
+
#
|
6
|
+
# @param [String] cmd a shell command
|
7
|
+
# @param [Symbol, Hash] *o
|
8
|
+
# @option o [Boolean] :verbose puts(cmd) to STDOUT
|
9
|
+
def sh cmd, *o
|
10
|
+
o = o.to_o
|
11
|
+
puts cmd if o[:verbose]
|
12
|
+
`#{cmd}`
|
13
|
+
end
|
14
|
+
|
15
|
+
# convert block to method.
|
16
|
+
#
|
17
|
+
# you can call a block with arguments
|
18
|
+
#
|
19
|
+
# @example USAGE
|
20
|
+
# instance_eval(&blk)
|
21
|
+
# blk2method(&blk).call *args
|
22
|
+
#
|
23
|
+
def blk2method &blk
|
24
|
+
self.class.class_eval do
|
25
|
+
define_method(:__blk2method, &blk)
|
26
|
+
end
|
27
|
+
method(:__blk2method)
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
# detect Platform information.
|
32
|
+
#
|
33
|
+
# RUBY_PLATFORM is "i686-linux" "i386-migw32"
|
34
|
+
#
|
35
|
+
# @return [Boolean]
|
36
|
+
def linux?; RUBY_PLATFORM=~/linux/ end
|
37
|
+
|
38
|
+
# detect PLatform information.
|
39
|
+
#
|
40
|
+
# @return [Boolean]
|
41
|
+
# @see {#linux?}
|
42
|
+
def win32?; RUBY_PLATFORM=~/mingw32|mswin/ end
|
43
|
+
|
44
|
+
|
45
|
+
# *for debug* pd(print debug), search 'pd' is much easier than 'p' in a text-editor.
|
46
|
+
#
|
47
|
+
# like p, but use " " in each argument instead of "\n".
|
48
|
+
#
|
49
|
+
# @example
|
50
|
+
# p 1,2
|
51
|
+
# =>
|
52
|
+
# 1
|
53
|
+
# 2
|
54
|
+
# pd 1,2
|
55
|
+
# =>
|
56
|
+
# 1 2
|
57
|
+
#
|
58
|
+
# @param [Object] *args
|
59
|
+
# @return nil
|
60
|
+
def pd *args
|
61
|
+
args.each do |arg| print arg.inspect," " end
|
62
|
+
print "\n"
|
63
|
+
end
|
64
|
+
|
65
|
+
# *for debug* print hr. puts '='*14 + " #{name}"
|
66
|
+
#
|
67
|
+
# sometime, we just need a horizonal line to separate message for debug.
|
68
|
+
# @param [String] name
|
69
|
+
def phr name=nil
|
70
|
+
puts '='*14 + " #{name}"
|
71
|
+
end
|
72
|
+
|
73
|
+
end # module Kernel
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Marshal
|
2
|
+
class <<self
|
3
|
+
|
4
|
+
alias :original_load :load
|
5
|
+
|
6
|
+
# add support with Pa
|
7
|
+
#
|
8
|
+
# Marshal.load(Pa(path))
|
9
|
+
#
|
10
|
+
# @param [IO,String,Pa] obj
|
11
|
+
# @return [String]
|
12
|
+
def load(obj) original_load Pa===obj ? File.read(obj.p) : obj end
|
13
|
+
|
14
|
+
alias :original_dump :dump
|
15
|
+
|
16
|
+
# add support with Pa
|
17
|
+
#
|
18
|
+
# Marshal.dump(obj, Pa(path))
|
19
|
+
# dump(con, [obj], limit=-1)
|
20
|
+
#
|
21
|
+
# @param [String,Pa] obj
|
22
|
+
# @return [String]
|
23
|
+
def dump(obj, *args)
|
24
|
+
case args[0]
|
25
|
+
when String, Pa
|
26
|
+
path = String===args[0] ? args[0] : args[0].p
|
27
|
+
open(path, "wb"){|f| f.write(original_dump(con))}
|
28
|
+
else
|
29
|
+
original_dump con, *args
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class Module
|
2
|
+
|
3
|
+
alias :original_append_features :append_features
|
4
|
+
|
5
|
+
# after include module, convert methods in ClassMethods to class methods.
|
6
|
+
# @see ruby-core Module#append_features
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# module Guten
|
10
|
+
# module ClassMethods
|
11
|
+
# def foo; end # after include Guten, method 'foo' becomes a class method.
|
12
|
+
# end
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# class Tag
|
16
|
+
# include Guten
|
17
|
+
# end
|
18
|
+
# Tag.foo
|
19
|
+
#
|
20
|
+
def append_features base
|
21
|
+
original_append_features base
|
22
|
+
base.extend const_get(:ClassMethods) if const_defined?(:ClassMethods)
|
23
|
+
end
|
24
|
+
|
25
|
+
end #class Module
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class Object
|
2
|
+
# default \#dup is shallow.
|
3
|
+
#
|
4
|
+
# @example
|
5
|
+
# # dup
|
6
|
+
# a={a: { b: 1 }}
|
7
|
+
# a2 = a.dup
|
8
|
+
# a2[:a][:b] = 2
|
9
|
+
# p a #=> {a: {b: 2} }
|
10
|
+
#
|
11
|
+
# # use deepdup
|
12
|
+
# a= {a: {b: 1 }}
|
13
|
+
# a2 = a.deepdup
|
14
|
+
# a2[:a][:b] = 2
|
15
|
+
# p a #=> {a: {b: 1}}
|
16
|
+
#
|
17
|
+
# @return [Object]
|
18
|
+
def deepdup
|
19
|
+
Marshal.load(Marshal.dump(self))
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,187 @@
|
|
1
|
+
=begin
|
2
|
+
Pa(Path) is similary to Pathname, but more powerful.
|
3
|
+
it combines fileutils, tmpdir, find, tempfile, File, Dir, Pathname
|
4
|
+
|
5
|
+
all class methods support Pa as parameter.
|
6
|
+
|
7
|
+
Examples:
|
8
|
+
---------
|
9
|
+
pa = Pa('/home/a.vim')
|
10
|
+
pa.dir #=> '/home'
|
11
|
+
pa.base #=> 'a.vim'
|
12
|
+
pa.name #=> 'a'
|
13
|
+
pa.ext #=> 'vim'
|
14
|
+
pa.fext #=> '.vim'
|
15
|
+
|
16
|
+
Filename parts:
|
17
|
+
---------
|
18
|
+
/home/guten.ogg
|
19
|
+
base: guten.ogg
|
20
|
+
dir: /home
|
21
|
+
ext: ogg
|
22
|
+
name: guten
|
23
|
+
|
24
|
+
Additional method list
|
25
|
+
---------------------
|
26
|
+
* Pa.absolute _alias from `File.absolute_path`_
|
27
|
+
* Pa.expand _aliss from `File.expand_path`_
|
28
|
+
|
29
|
+
=== create, modify path
|
30
|
+
Example1:
|
31
|
+
pa = Pa('/home/foo')
|
32
|
+
pa.join('a.txt') #=> new Pa('/home/foo/a.txt')
|
33
|
+
|
34
|
+
Example2:
|
35
|
+
pa1 = Pa('/home/foo/a.txt')
|
36
|
+
pa2 = Pa('/home/bar/b.txt')
|
37
|
+
pa1+'~' #=> new Pa('/home/foo/a.txt~')
|
38
|
+
Pa.join(pa1.dir, pa2.base) #=> '/home/foo/b.txt'
|
39
|
+
|
40
|
+
Example3:
|
41
|
+
pa1 = Pa('/home/foo/a.txt')
|
42
|
+
pa2 = Pa('/home/bar')
|
43
|
+
pa2.join(pa1.base) #=> new Pa('/home/bar/a.txt')
|
44
|
+
|
45
|
+
**Attributes**
|
46
|
+
|
47
|
+
name abbr description
|
48
|
+
|
49
|
+
path p
|
50
|
+
absolute a absolute path
|
51
|
+
dir d dirname of a path
|
52
|
+
base b basename of a path
|
53
|
+
name n filename of a path
|
54
|
+
ext e extname of a path, return "" or "ogg"
|
55
|
+
fext fe return "" or ".ogg"
|
56
|
+
=end
|
57
|
+
|
58
|
+
class Pa
|
59
|
+
Error = Class.new Exception
|
60
|
+
EUnkonwType = Class.new Error
|
61
|
+
|
62
|
+
attr_accessor :path
|
63
|
+
attr_reader :absolute, :dir, :base, :name, :ext, :fext
|
64
|
+
alias p path
|
65
|
+
alias a absolute
|
66
|
+
alias d dir
|
67
|
+
alias b base
|
68
|
+
alias n name
|
69
|
+
alias e ext
|
70
|
+
alias fe fext
|
71
|
+
|
72
|
+
# @param [String,Pa,Pathname] path
|
73
|
+
# @api also used by replace
|
74
|
+
def initialize path
|
75
|
+
@path = case path.class.to_s
|
76
|
+
when "Pathname"
|
77
|
+
path.to_s
|
78
|
+
when "Pa"
|
79
|
+
path.path
|
80
|
+
when "String"
|
81
|
+
path
|
82
|
+
else
|
83
|
+
raise ArgumentError, path.inspect
|
84
|
+
end
|
85
|
+
@absolute = Pa.absolute(@path)
|
86
|
+
@dir = Pa.dirname(@path)
|
87
|
+
@base = Pa.basename(@path)
|
88
|
+
@name, @ext = Pa.basename(@path, ext: true)
|
89
|
+
@fext = @ext.empty? ? "" : "."+@ext
|
90
|
+
end
|
91
|
+
|
92
|
+
# @param [String,Pa,Pathname]
|
93
|
+
# @return [Pa] the same Pa object
|
94
|
+
def replace path
|
95
|
+
initialize path
|
96
|
+
end
|
97
|
+
|
98
|
+
# add string to path
|
99
|
+
#
|
100
|
+
# @example
|
101
|
+
# pa = Pa('/home/foo/a.txt')
|
102
|
+
# pa+'~' #=> new Pa('/home/foo/a.txt~')
|
103
|
+
#
|
104
|
+
# @param [String] str
|
105
|
+
# @return [Pa]
|
106
|
+
def + str
|
107
|
+
Pa(@path+str)
|
108
|
+
end
|
109
|
+
|
110
|
+
# return '#<Pa @path="foo", @absolute="/home/foo">'
|
111
|
+
#
|
112
|
+
# @return [String]
|
113
|
+
def inspect
|
114
|
+
ret="#<" + self.class.to_s + " "
|
115
|
+
ret += "@path=\"#{@path}\", @absolute=\"#{@absolute}\""
|
116
|
+
ret += " >"
|
117
|
+
ret
|
118
|
+
end
|
119
|
+
|
120
|
+
# return '/home/foo'
|
121
|
+
#
|
122
|
+
# @return [String] path
|
123
|
+
def to_s
|
124
|
+
@path
|
125
|
+
end
|
126
|
+
|
127
|
+
# join path
|
128
|
+
#
|
129
|
+
# param [String] *names
|
130
|
+
# return [Pa]
|
131
|
+
def join(*names)
|
132
|
+
Pa(Pa.join(@path, *names))
|
133
|
+
end
|
134
|
+
|
135
|
+
# get parent path
|
136
|
+
#
|
137
|
+
# return [Pa]
|
138
|
+
def parent
|
139
|
+
Pa(Pa.join(@path, '..'))
|
140
|
+
end
|
141
|
+
|
142
|
+
|
143
|
+
# missing method goes to Pa.class-method
|
144
|
+
# return@ [Pa,..] return Pa for some methods.
|
145
|
+
def method_missing(name, *args, &blk)
|
146
|
+
ret = self.class.__send__(name, *args, @path, &blk)
|
147
|
+
[ :readlink ]
|
148
|
+
.include?(name) ? Pa(ret) : ret
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
|
153
|
+
require_relative "pa/path"
|
154
|
+
require_relative "pa/cmd"
|
155
|
+
require_relative "pa/dir"
|
156
|
+
require_relative "pa/state"
|
157
|
+
class Pa
|
158
|
+
class << self
|
159
|
+
|
160
|
+
# missing method goes to File class method
|
161
|
+
def method_missing name, *args, &blk
|
162
|
+
return if args.size>1
|
163
|
+
File.__send__ name, get(args[0]), &blk
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
class Pa
|
170
|
+
extend Path
|
171
|
+
extend Directory
|
172
|
+
extend State
|
173
|
+
extend Cmd
|
174
|
+
end
|
175
|
+
|
176
|
+
module Kernel
|
177
|
+
private
|
178
|
+
# a very convient function.
|
179
|
+
#
|
180
|
+
# @example
|
181
|
+
# Pa('/home').exists?
|
182
|
+
def Pa(path)
|
183
|
+
return path if Pa===path
|
184
|
+
Pa.new path
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|