unicopy 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/.travis.yml +22 -0
- data/CHANGELOG.md +67 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +7 -0
- data/MIT-LICENSE.txt +20 -0
- data/README.md +188 -0
- data/Rakefile +38 -0
- data/bin/unicopy +184 -0
- data/lib/unicopy.rb +143 -0
- data/lib/unicopy/kernel_method.rb +9 -0
- data/lib/unicopy/version.rb +3 -0
- data/spec/unicopy_spec.rb +102 -0
- data/unicopy.gemspec +25 -0
- metadata +111 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b52015a55845441084cce91c2820e7faa888078b
|
4
|
+
data.tar.gz: e23151d662fac4f0c811748fc5b1be0c4a451637
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b40c34ec4178cb320a175f3ad4a716539f167882a251281a6f0320fe0db970d8246048109eca0e95d467187c2bcb160fed8c74ef3dad519dc0fb4c78d9338df1
|
7
|
+
data.tar.gz: a8d21e068ea34e19668e09129884def732ea387002defab2870d2696ece52eff01eb4e115099ef3d9ed3d66027669714584924821f883f9355a04f3ee5c64012
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
sudo: false
|
2
|
+
language: ruby
|
3
|
+
|
4
|
+
rvm:
|
5
|
+
- ruby-head
|
6
|
+
- 2.4.1
|
7
|
+
- 2.3.4
|
8
|
+
- 2.2
|
9
|
+
- 2.1
|
10
|
+
- 2.0
|
11
|
+
- jruby-head
|
12
|
+
- jruby-9.1.8.0
|
13
|
+
|
14
|
+
cache:
|
15
|
+
- bundler
|
16
|
+
|
17
|
+
matrix:
|
18
|
+
allow_failures:
|
19
|
+
- rvm: jruby-head
|
20
|
+
- rvm: ruby-head
|
21
|
+
- rvm: 2.0
|
22
|
+
# fast_finish: true
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
## CHANGELOG
|
2
|
+
|
3
|
+
### 2.4.0
|
4
|
+
|
5
|
+
* Extract symbolification logic into extra [symbolify](https://github.com/janlelis/symbolify) gem (includes fixes and non-character detection)
|
6
|
+
* Update characteristics gem (includes a new blank)
|
7
|
+
|
8
|
+
### 2.3.0
|
9
|
+
|
10
|
+
* More consistent handling of bidi controls (always symbolify with alias, but highlight ALM, RLM, LRM as blanks)
|
11
|
+
* Highlight control chars that are also blanks as blank
|
12
|
+
* Highlight CGJ as blank
|
13
|
+
* Highlight NEL as blank (only in Unicode)
|
14
|
+
* Add Unicode version to `unibits --version` command
|
15
|
+
|
16
|
+
### 2.2.0
|
17
|
+
|
18
|
+
* Add mongolian free variation selectors and combining grapheme joiner to interesting codepoints list
|
19
|
+
* Green highlighting of "marks" in Unicode
|
20
|
+
* Always use dotted circle for non-spacing marks
|
21
|
+
* Always prepend enclosing marks with a space
|
22
|
+
* Update characteristics gem (includes new blanks and UTF-8 dialects with japanese emojis)
|
23
|
+
|
24
|
+
### 2.1.1
|
25
|
+
|
26
|
+
* Proper UTF-32 validness / invalid codepoint highlighting, see https://bugs.ruby-lang.org/issues/13292
|
27
|
+
|
28
|
+
### 2.1.0
|
29
|
+
|
30
|
+
* Support more encoding: IBMX, CP85X, macX, TIS-620/Windows-874, and KOI8-X
|
31
|
+
* Highlight non-control formatting characters in pink
|
32
|
+
* Improve `unibits --help` command
|
33
|
+
|
34
|
+
### 2.0.0
|
35
|
+
|
36
|
+
* Support more encodings: ISO-8859-X and Windows-125X
|
37
|
+
* Add three HANGUL characters (U+115F, U+1160, U+3164) to list of possible white spaces
|
38
|
+
* Move character handling to separate gem. It is called [characteristics](https://github.com/janlelis/characteristics).
|
39
|
+
* Highlight control chars in blue and blanks in light blue
|
40
|
+
* Handle encodings that are not convertible to UTF-8
|
41
|
+
|
42
|
+
### 1.3.0
|
43
|
+
|
44
|
+
* Add variation selectors 17-256 (U+E0100 - U+E01EF)
|
45
|
+
* Add U+1D159 (MUSICAL SYMBOL NULL NOTEHEAD) to list of possible white spaces
|
46
|
+
* Bump unicode-categories dependency for more reliable unassigned codepoint detection
|
47
|
+
|
48
|
+
### 1.2.1
|
49
|
+
|
50
|
+
* Fix bug that inserted wrong bytes
|
51
|
+
|
52
|
+
### 1.2.0
|
53
|
+
|
54
|
+
* Do not display (but highlight) unassigned codepoints
|
55
|
+
|
56
|
+
### 1.1.0
|
57
|
+
|
58
|
+
* Support (and highlight) invalid encodings \o/
|
59
|
+
* Improve character symbolification
|
60
|
+
* Fix that the Kernel method would not take keyword arguments
|
61
|
+
* New option for setting a custom output width to use
|
62
|
+
* New option for activating wide ambiguous characters
|
63
|
+
|
64
|
+
### 1.0.0
|
65
|
+
|
66
|
+
* Initial release
|
67
|
+
|
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
2
|
+
|
3
|
+
## Our Pledge
|
4
|
+
|
5
|
+
In the interest of fostering an open and welcoming environment, we as
|
6
|
+
contributors and maintainers pledge to making participation in our project and
|
7
|
+
our community a harassment-free experience for everyone, regardless of age, body
|
8
|
+
size, disability, ethnicity, gender identity and expression, level of experience,
|
9
|
+
nationality, personal appearance, race, religion, or sexual identity and
|
10
|
+
orientation.
|
11
|
+
|
12
|
+
## Our Standards
|
13
|
+
|
14
|
+
Examples of behavior that contributes to creating a positive environment
|
15
|
+
include:
|
16
|
+
|
17
|
+
* Using welcoming and inclusive language
|
18
|
+
* Being respectful of differing viewpoints and experiences
|
19
|
+
* Gracefully accepting constructive criticism
|
20
|
+
* Focusing on what is best for the community
|
21
|
+
* Showing empathy towards other community members
|
22
|
+
|
23
|
+
Examples of unacceptable behavior by participants include:
|
24
|
+
|
25
|
+
* The use of sexualized language or imagery and unwelcome sexual attention or
|
26
|
+
advances
|
27
|
+
* Trolling, insulting/derogatory comments, and personal or political attacks
|
28
|
+
* Public or private harassment
|
29
|
+
* Publishing others' private information, such as a physical or electronic
|
30
|
+
address, without explicit permission
|
31
|
+
* Other conduct which could reasonably be considered inappropriate in a
|
32
|
+
professional setting
|
33
|
+
|
34
|
+
## Our Responsibilities
|
35
|
+
|
36
|
+
Project maintainers are responsible for clarifying the standards of acceptable
|
37
|
+
behavior and are expected to take appropriate and fair corrective action in
|
38
|
+
response to any instances of unacceptable behavior.
|
39
|
+
|
40
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
41
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
42
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
43
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
44
|
+
threatening, offensive, or harmful.
|
45
|
+
|
46
|
+
## Scope
|
47
|
+
|
48
|
+
This Code of Conduct applies both within project spaces and in public spaces
|
49
|
+
when an individual is representing the project or its community. Examples of
|
50
|
+
representing a project or community include using an official project e-mail
|
51
|
+
address, posting via an official social media account, or acting as an appointed
|
52
|
+
representative at an online or offline event. Representation of a project may be
|
53
|
+
further defined and clarified by project maintainers.
|
54
|
+
|
55
|
+
## Enforcement
|
56
|
+
|
57
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
58
|
+
reported by contacting the project team at opensource@janlelis.com. All
|
59
|
+
complaints will be reviewed and investigated and will result in a response that
|
60
|
+
is deemed necessary and appropriate to the circumstances. The project team is
|
61
|
+
obligated to maintain confidentiality with regard to the reporter of an incident.
|
62
|
+
Further details of specific enforcement policies may be posted separately.
|
63
|
+
|
64
|
+
Project maintainers who do not follow or enforce the Code of Conduct in good
|
65
|
+
faith may face temporary or permanent repercussions as determined by other
|
66
|
+
members of the project's leadership.
|
67
|
+
|
68
|
+
## Attribution
|
69
|
+
|
70
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
71
|
+
available at [http://contributor-covenant.org/version/1/4][version]
|
72
|
+
|
73
|
+
[homepage]: http://contributor-covenant.org
|
74
|
+
[version]: http://contributor-covenant.org/version/1/4/
|
data/Gemfile
ADDED
data/MIT-LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2017 Jan Lelis, mail@janlelis.de
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,188 @@
|
|
1
|
+
# unicopy [![[version]](https://badge.fury.io/rb/unicopy.svg)](http://badge.fury.io/rb/unicopy) [![[travis]](https://travis-ci.org/janlelis/unicopy.svg)](https://travis-ci.org/janlelis/unicopy)
|
2
|
+
|
3
|
+
CLI utility which converts Unicode codepoints to a string (or vice versa). Copies the result to the system clipboard or just prints it to the console.
|
4
|
+
|
5
|
+
Can also convert codepoints to many dump formats.
|
6
|
+
|
7
|
+
## Setup
|
8
|
+
|
9
|
+
Make sure you have Ruby installed and installing gems works properly. Then do:
|
10
|
+
|
11
|
+
```
|
12
|
+
$ gem install unicopy
|
13
|
+
```
|
14
|
+
|
15
|
+
## Usage
|
16
|
+
|
17
|
+
### Codepoints to String
|
18
|
+
|
19
|
+
Codepoints format is hexadecimal, "U+" is permitted, examples:
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
$ unicopy 52 75 62 79 --print
|
23
|
+
Ruby
|
24
|
+
```
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
$ unicopy U+0052 U+0075 U+0062 U+0079 --print
|
28
|
+
Ruby
|
29
|
+
```
|
30
|
+
|
31
|
+
### String to Codepoints
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
$ unicopy --string Ruby --print
|
35
|
+
U+0052 U+0075 U+0062 U+0079
|
36
|
+
```
|
37
|
+
|
38
|
+
### Options
|
39
|
+
|
40
|
+
```
|
41
|
+
--help | | this help page
|
42
|
+
--parse-decimal | | interpret given codepoints as decimal, instead of hexadecimal values
|
43
|
+
--print | -p | do not copy to system clipboard, but print to screen
|
44
|
+
--string | -s | see above
|
45
|
+
--version | | displays version of unicopy
|
46
|
+
--(dump format) | | specify the format to be used for dumping the codepoints (see below)
|
47
|
+
```
|
48
|
+
|
49
|
+
### Dump Formats
|
50
|
+
|
51
|
+
#### Short Hexadecimal
|
52
|
+
|
53
|
+
```
|
54
|
+
$ unicopy 52 75 62 79 20 1F32B --print --hex
|
55
|
+
52 75 62 79 20 1F32B
|
56
|
+
```
|
57
|
+
|
58
|
+
```
|
59
|
+
$ unicopy --string "Ruby 🌫" --print --hex
|
60
|
+
52 75 62 79 20 1F32B
|
61
|
+
```
|
62
|
+
|
63
|
+
#### Hexadecimal With `U+` Prefix
|
64
|
+
|
65
|
+
```
|
66
|
+
$ unicopy 52 75 62 79 20 1F32B --print --uplus
|
67
|
+
U+0052 U+0075 U+0062 U+0079 U+0020 U+1F32B
|
68
|
+
```
|
69
|
+
|
70
|
+
```
|
71
|
+
$ unicopy --string "Ruby 🌫" --print --uplus
|
72
|
+
U+0052 U+0075 U+0062 U+0079 U+0020 U+1F32B
|
73
|
+
```
|
74
|
+
|
75
|
+
#### Hexadecimal With `0x` Prefix
|
76
|
+
|
77
|
+
```
|
78
|
+
$ unicopy 52 75 62 79 20 1F32B --print --0x
|
79
|
+
0x0052 0x0075 0x0062 0x0079 0x0020 0x1F32B
|
80
|
+
```
|
81
|
+
|
82
|
+
```
|
83
|
+
$ unicopy --string "Ruby 🌫" --print --0x
|
84
|
+
0x0052 0x0075 0x0062 0x0079 0x0020 0x1F32B
|
85
|
+
```
|
86
|
+
|
87
|
+
#### Decimal
|
88
|
+
|
89
|
+
```
|
90
|
+
$ unicopy 52 75 62 79 20 1F32B --print --dec
|
91
|
+
82 117 98 121 32 127787
|
92
|
+
```
|
93
|
+
|
94
|
+
```
|
95
|
+
$ unicopy --string "Ruby 🌫" --print --dec
|
96
|
+
82 117 98 121 32 127787
|
97
|
+
```
|
98
|
+
|
99
|
+
#### Ruby Escape Syntax
|
100
|
+
|
101
|
+
```
|
102
|
+
$ unicopy 52 75 62 79 20 1F32B --print --ruby
|
103
|
+
\\u{52 75 62 79 20 1F32B}
|
104
|
+
```
|
105
|
+
|
106
|
+
```
|
107
|
+
$ unicopy --string "Ruby 🌫" --print --ruby
|
108
|
+
\\u{52 75 62 79 20 1F32B}
|
109
|
+
```
|
110
|
+
|
111
|
+
#### JavaScript Escape Syntax (Since ES6)
|
112
|
+
|
113
|
+
```
|
114
|
+
$ unicopy 52 75 62 79 20 1F32B --print --es6
|
115
|
+
\\u{52}\\u{75}\\u{62}\\u{79}\\u{20}\\u{1F32B}
|
116
|
+
```
|
117
|
+
|
118
|
+
```
|
119
|
+
$ unicopy --string "Ruby 🌫" --print --es6
|
120
|
+
\\u{52}\\u{75}\\u{62}\\u{79}\\u{20}\\u{1F32B}
|
121
|
+
```
|
122
|
+
|
123
|
+
#### JavaScript Escape Syntax (Before ES6)
|
124
|
+
|
125
|
+
```
|
126
|
+
$ unicopy 52 75 62 79 20 1F32B --print --js
|
127
|
+
\\u0052\\u0075\\u0062\\u0079\\u0020\\uD83C\\uDF2B
|
128
|
+
```
|
129
|
+
|
130
|
+
```
|
131
|
+
$ unicopy --string "Ruby 🌫" --print --js
|
132
|
+
\\u0052\\u0075\\u0062\\u0079\\u0020\\uD83C\\uDF2B
|
133
|
+
```
|
134
|
+
|
135
|
+
#### CSS Escape Syntax
|
136
|
+
|
137
|
+
```
|
138
|
+
$ unicopy 52 75 62 79 20 1F32B --print --css
|
139
|
+
\\52\\75\\62\\79\\20\\1f32b
|
140
|
+
```
|
141
|
+
|
142
|
+
```
|
143
|
+
$ unicopy --string "Ruby 🌫" --print --css
|
144
|
+
\\52\\75\\62\\79\\20\\1f32b
|
145
|
+
```
|
146
|
+
|
147
|
+
#### Hexadecimal HTML Entities
|
148
|
+
|
149
|
+
```
|
150
|
+
$ unicopy 52 75 62 79 20 1F32B --print --html-hex
|
151
|
+
Ruby 🌫
|
152
|
+
```
|
153
|
+
|
154
|
+
```
|
155
|
+
$ unicopy --string "Ruby 🌫" --print --html-hex
|
156
|
+
Ruby 🌫
|
157
|
+
```
|
158
|
+
|
159
|
+
#### Decimal HTML Entities
|
160
|
+
|
161
|
+
```
|
162
|
+
$ unicopy 52 75 62 79 20 1F32B --print --html-dec
|
163
|
+
Ruby 🌫
|
164
|
+
```
|
165
|
+
|
166
|
+
```
|
167
|
+
$ unicopy --string "Ruby 🌫" --print --html-dec
|
168
|
+
Ruby 🌫
|
169
|
+
```
|
170
|
+
|
171
|
+
#### UTF-8 in Hexadecimal Bytes
|
172
|
+
|
173
|
+
```
|
174
|
+
$ unicopy 52 75 62 79 20 1F32B --print --bytes-utf8
|
175
|
+
52 75 62 79 20 F0 9F 8C AB
|
176
|
+
```
|
177
|
+
|
178
|
+
```
|
179
|
+
$ unicopy --string "Ruby 🌫" --print --bytes-utf8
|
180
|
+
52 75 62 79 20 F0 9F 8C AB
|
181
|
+
```
|
182
|
+
|
183
|
+
## Also see
|
184
|
+
|
185
|
+
- [unibits](https://github.com/janlelis/unibits)
|
186
|
+
- [uniscribe](https://github.com/janlelis/uniscribe)
|
187
|
+
|
188
|
+
Copyright (C) 2017 Jan Lelis <http://janlelis.com>. Released under the MIT license.
|
data/Rakefile
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# # #
|
2
|
+
# Get gemspec info
|
3
|
+
|
4
|
+
gemspec_file = Dir['*.gemspec'].first
|
5
|
+
gemspec = eval File.read(gemspec_file), binding, gemspec_file
|
6
|
+
info = "#{gemspec.name} | #{gemspec.version} | " \
|
7
|
+
"#{gemspec.runtime_dependencies.size} dependencies | " \
|
8
|
+
"#{gemspec.files.size} files"
|
9
|
+
|
10
|
+
# # #
|
11
|
+
# Gem build and install task
|
12
|
+
|
13
|
+
desc info
|
14
|
+
task :gem do
|
15
|
+
puts info + "\n\n"
|
16
|
+
print " "; sh "gem build #{gemspec_file}"
|
17
|
+
FileUtils.mkdir_p 'pkg'
|
18
|
+
FileUtils.mv "#{gemspec.name}-#{gemspec.version}.gem", 'pkg'
|
19
|
+
puts; sh %{gem install --no-document pkg/#{gemspec.name}-#{gemspec.version}.gem}
|
20
|
+
end
|
21
|
+
|
22
|
+
# # #
|
23
|
+
# Start an IRB session with the gem loaded
|
24
|
+
|
25
|
+
desc "#{gemspec.name} | IRB"
|
26
|
+
task :irb do
|
27
|
+
sh "irb -I ./lib -r #{gemspec.name.gsub '-','/'}/kernel_method"
|
28
|
+
end
|
29
|
+
|
30
|
+
# # #
|
31
|
+
# Run specs
|
32
|
+
|
33
|
+
desc "#{gemspec.name} | Spec"
|
34
|
+
task :spec do
|
35
|
+
sh "for file in spec/*_spec.rb; do ruby $file; done"
|
36
|
+
end
|
37
|
+
task default: :spec
|
38
|
+
|
data/bin/unicopy
ADDED
@@ -0,0 +1,184 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "rationalist"
|
4
|
+
require "paint"
|
5
|
+
require "unicopy"
|
6
|
+
|
7
|
+
argv = Rationalist.parse(
|
8
|
+
ARGV,
|
9
|
+
string: '_',
|
10
|
+
alias: {
|
11
|
+
p: 'print',
|
12
|
+
s: 'string',
|
13
|
+
v: 'version',
|
14
|
+
}.merge(Hash[Unicopy::DUMP_FORMATS.select{ |k,v| v[:alias] }.map{ |k,v| [v[:alias], k] }]),
|
15
|
+
boolean: [
|
16
|
+
'parse-decimal',
|
17
|
+
'help',
|
18
|
+
'print',
|
19
|
+
'string',
|
20
|
+
'version',
|
21
|
+
*Unicopy::DUMP_FORMATS.keys
|
22
|
+
]
|
23
|
+
)
|
24
|
+
|
25
|
+
if argv[:version]
|
26
|
+
puts "unicopy #{Unicopy::VERSION} by #{Paint["J-_-L", :bold]} <https://github.com/janlelis/unicopy>"
|
27
|
+
exit(0)
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
if argv[:help]
|
32
|
+
dump_format_description = Unicopy::DUMP_FORMATS.map{ |dump_format, info|
|
33
|
+
"--#{dump_format.ljust(20)}| #{info[:alias] ? "-#{info[:alias]}" : " "} | #{info[:description]}"
|
34
|
+
}.join("\n ")
|
35
|
+
|
36
|
+
puts <<-HELP
|
37
|
+
|
38
|
+
#{Paint["DESCRIPTION", :underline]}
|
39
|
+
|
40
|
+
Converts Unicode codepoints to a string (or vice versa) and copies it to the system clipboard.
|
41
|
+
Can also convert codepoints to many dump formats.
|
42
|
+
|
43
|
+
#{Paint["USAGE", :underline]}
|
44
|
+
|
45
|
+
CODEPOINTS TO STRING
|
46
|
+
|
47
|
+
#{Paint["unicopy", :bold]} [options] codepoints
|
48
|
+
|
49
|
+
Codepoints format is hexadecimal, "U+" is permitted, examples:
|
50
|
+
|
51
|
+
$ unicopy 52 75 62 79 20 1F32B --print
|
52
|
+
Ruby 🌫
|
53
|
+
|
54
|
+
$ unicopy U+0052 U+0075 U+0062 U+0079 U+0020 U+1F32B --print
|
55
|
+
Ruby 🌫
|
56
|
+
|
57
|
+
STRING TO CODEPOINTS
|
58
|
+
|
59
|
+
#{Paint["unicopy", :bold]} (--string|-s) [options] string
|
60
|
+
|
61
|
+
$ unicopy -sp "Ruby 🌫"
|
62
|
+
U+0052 U+0075 U+0062 U+0079 U+0020 U+1F32B
|
63
|
+
|
64
|
+
If data is retrieved via STDIN, it will split alongside newlines.
|
65
|
+
|
66
|
+
#{Paint["OPTIONS", :underline]}
|
67
|
+
|
68
|
+
--help | | this help page
|
69
|
+
--parse-decimal | | interpret given codepoints as decimal, instead of hexadecimal values
|
70
|
+
--print | -p | do not copy to system clipboard, but print to screen
|
71
|
+
--string | -s | see above
|
72
|
+
--version | | displays version of unicopy
|
73
|
+
--(dump format) | | specify the format to be used for dumping the codepoints (see below)
|
74
|
+
|
75
|
+
#{Paint["DUMP FORMATS", :underline]}
|
76
|
+
|
77
|
+
#{dump_format_description}
|
78
|
+
|
79
|
+
Examples:
|
80
|
+
|
81
|
+
$ unicopy 52 75 62 79 20 1F32B --print --hex
|
82
|
+
52 75 62 79 20 1F32B
|
83
|
+
|
84
|
+
$ unicopy --string "Ruby 🌫" --print --hex
|
85
|
+
52 75 62 79 20 1F32B
|
86
|
+
|
87
|
+
$ unicopy 52 75 62 79 20 1F32B --print --uplus
|
88
|
+
U+0052 U+0075 U+0062 U+0079 U+0020 U+1F32B
|
89
|
+
|
90
|
+
$ unicopy --string "Ruby 🌫" --print --uplus
|
91
|
+
U+0052 U+0075 U+0062 U+0079 U+0020 U+1F32B
|
92
|
+
|
93
|
+
$ unicopy 52 75 62 79 20 1F32B --print --0x
|
94
|
+
0x0052 0x0075 0x0062 0x0079 0x0020 0x1F32B
|
95
|
+
|
96
|
+
$ unicopy --string "Ruby 🌫" --print --0x
|
97
|
+
0x0052 0x0075 0x0062 0x0079 0x0020 0x1F32B
|
98
|
+
|
99
|
+
$ unicopy 52 75 62 79 20 1F32B --print --dec
|
100
|
+
82 117 98 121 32 127787
|
101
|
+
|
102
|
+
$ unicopy --string "Ruby 🌫" --print --dec
|
103
|
+
82 117 98 121 32 127787
|
104
|
+
|
105
|
+
$ unicopy 52 75 62 79 20 1F32B --print --ruby
|
106
|
+
\\u{52 75 62 79 20 1F32B}
|
107
|
+
|
108
|
+
$ unicopy --string "Ruby 🌫" --print --ruby
|
109
|
+
\\u{52 75 62 79 20 1F32B}
|
110
|
+
|
111
|
+
$ unicopy 52 75 62 79 20 1F32B --print --js
|
112
|
+
\\u0052\\u0075\\u0062\\u0079\\u0020\\uD83C\\uDF2B
|
113
|
+
|
114
|
+
$ unicopy --string "Ruby 🌫" --print --js
|
115
|
+
\\u0052\\u0075\\u0062\\u0079\\u0020\\uD83C\\uDF2B
|
116
|
+
|
117
|
+
$ unicopy 52 75 62 79 20 1F32B --print --es6
|
118
|
+
\\u{52}\\u{75}\\u{62}\\u{79}\\u{20}\\u{1F32B}
|
119
|
+
|
120
|
+
$ unicopy --string "Ruby 🌫" --print --es6
|
121
|
+
\\u{52}\\u{75}\\u{62}\\u{79}\\u{20}\\u{1F32B}
|
122
|
+
|
123
|
+
$ unicopy 52 75 62 79 20 1F32B --print --css
|
124
|
+
\\52\\75\\62\\79\\20\\1f32b
|
125
|
+
|
126
|
+
$ unicopy --string "Ruby 🌫" --print --css
|
127
|
+
\\52\\75\\62\\79\\20\\1f32b
|
128
|
+
|
129
|
+
$ unicopy 52 75 62 79 20 1F32B --print --html-hex
|
130
|
+
Ruby 🌫
|
131
|
+
|
132
|
+
$ unicopy --string "Ruby 🌫" --print --html-hex
|
133
|
+
Ruby 🌫
|
134
|
+
|
135
|
+
$ unicopy 52 75 62 79 20 1F32B --print --html-dec
|
136
|
+
Ruby 🌫
|
137
|
+
|
138
|
+
$ unicopy --string "Ruby 🌫" --print --html-dec
|
139
|
+
Ruby 🌫
|
140
|
+
|
141
|
+
$ unicopy 52 75 62 79 20 1F32B --print --bytes-utf8
|
142
|
+
52 75 62 79 20 F0 9F 8C AB
|
143
|
+
|
144
|
+
$ unicopy --string "Ruby 🌫" --print --bytes-utf8
|
145
|
+
52 75 62 79 20 F0 9F 8C AB
|
146
|
+
|
147
|
+
#{Paint["MORE INFO", :underline]}
|
148
|
+
|
149
|
+
https://github.com/janlelis/unicopy
|
150
|
+
|
151
|
+
HELP
|
152
|
+
exit(0)
|
153
|
+
end
|
154
|
+
|
155
|
+
if argv[:_]
|
156
|
+
codepoints = argv.delete :_
|
157
|
+
elsif !$stdin.tty?
|
158
|
+
codepoints = $stdin.read.split($/)
|
159
|
+
else
|
160
|
+
codepoints = nil
|
161
|
+
end
|
162
|
+
|
163
|
+
options = {
|
164
|
+
parse_decimal: argv[:"parse-decimal"],
|
165
|
+
print: argv[:print],
|
166
|
+
string: argv[:string],
|
167
|
+
}
|
168
|
+
|
169
|
+
dump_formats = Unicopy::DUMP_FORMATS.keys.select{ |dump_format| argv[dump_format.to_sym] }
|
170
|
+
case dump_formats.size
|
171
|
+
when 0
|
172
|
+
# nothing
|
173
|
+
when 1
|
174
|
+
options[:dump] = dump_formats[0]
|
175
|
+
else
|
176
|
+
raise ArgumentError, "only one dump format can be passed to unicopy"
|
177
|
+
end
|
178
|
+
|
179
|
+
begin
|
180
|
+
Unicopy.unicopy(*codepoints, **options)
|
181
|
+
rescue ArgumentError
|
182
|
+
$stderr.puts Paint[$!.message, :red]
|
183
|
+
exit(1)
|
184
|
+
end
|
data/lib/unicopy.rb
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
# enable-frozen-string: true
|
2
|
+
|
3
|
+
require_relative "unicopy/version"
|
4
|
+
|
5
|
+
require "clipboard"
|
6
|
+
|
7
|
+
module Unicopy
|
8
|
+
DUMP_FORMATS = {
|
9
|
+
'hex' => {
|
10
|
+
description: "____ (hexadecimal)",
|
11
|
+
replace: "%X",
|
12
|
+
alias: "x",
|
13
|
+
},
|
14
|
+
'uplus' => {
|
15
|
+
description: "U+____ (hexadecimal)",
|
16
|
+
replace: "U+%04X",
|
17
|
+
alias: "u",
|
18
|
+
},
|
19
|
+
'0x' => {
|
20
|
+
description: "0x____ (hexadecimal)",
|
21
|
+
replace: "0x%04X",
|
22
|
+
alias: "0",
|
23
|
+
},
|
24
|
+
'dec' => {
|
25
|
+
description: "____ (decimal)",
|
26
|
+
replace: "%d",
|
27
|
+
alias: "d",
|
28
|
+
},
|
29
|
+
'ruby' => {
|
30
|
+
description: "Ruby \\u{____} (hexadecimal)",
|
31
|
+
prefix: "\\u{",
|
32
|
+
replace: "%X",
|
33
|
+
suffix: "}",
|
34
|
+
alias: "r",
|
35
|
+
},
|
36
|
+
'css' => {
|
37
|
+
description: "CSS \\____ (hexadecimal)",
|
38
|
+
replace: "\\%x",
|
39
|
+
joiner: "",
|
40
|
+
suffix: " ",
|
41
|
+
},
|
42
|
+
'js' => {
|
43
|
+
description: "JavaScript \\u____ with UTF-16 surrogates (hexadecimal)",
|
44
|
+
replace: ->(x){
|
45
|
+
[x].pack("U").encode("UTF-16BE").each_byte.each_slice(2).map{ |a,b| "\\u%04X" % (a*256 + b) }
|
46
|
+
},
|
47
|
+
joiner: "",
|
48
|
+
},
|
49
|
+
'es6' => {
|
50
|
+
description: "EcmaScript 6+ \\u{____} (hexadecimal)",
|
51
|
+
replace: "\\u{%X}",
|
52
|
+
joiner: "",
|
53
|
+
alias: "6",
|
54
|
+
},
|
55
|
+
'html-hex' => {
|
56
|
+
description: "HTML entitiy &#x____ (hexadecimal)",
|
57
|
+
replace: "&#x%X;",
|
58
|
+
joiner: "",
|
59
|
+
},
|
60
|
+
'html-dec' => {
|
61
|
+
description: "HTML entitiy &#____ (decimal)",
|
62
|
+
replace: "&#%d;",
|
63
|
+
joiner: "",
|
64
|
+
},
|
65
|
+
'bytes-utf8' => {
|
66
|
+
description: "UTF-8 encoded (bytes)",
|
67
|
+
replace: ->(x){
|
68
|
+
[x].pack("U").unpack("C*").map{ |x| x.to_s(16).upcase }.join(" ")
|
69
|
+
},
|
70
|
+
}
|
71
|
+
}
|
72
|
+
DUMP_FORMAT_DEFAULTS = {
|
73
|
+
prefix: "",
|
74
|
+
replace: "%s",
|
75
|
+
joiner: " ",
|
76
|
+
suffix: "",
|
77
|
+
}
|
78
|
+
|
79
|
+
def self.unicopy(*args, string: false, dump: nil, parse_decimal: false, print: false)
|
80
|
+
if args.empty?
|
81
|
+
raise ArgumentError, "no data given to copy"
|
82
|
+
elsif !string
|
83
|
+
codepoints = transform_raw_codepoints(args.join(" ").split(" "), parse_decimal)
|
84
|
+
if dump
|
85
|
+
deliver(dump_codepoints(codepoints, format: dump), print: print, codepoints_length: codepoints.length, message: "dump of")
|
86
|
+
else # default
|
87
|
+
deliver(codepoints.pack("U*"), print: print, codepoints_length: codepoints.length, message: "string of")
|
88
|
+
end
|
89
|
+
else
|
90
|
+
data = args.join("")
|
91
|
+
data = data.encode("UTF-8") unless data.encoding.name == "UTF-8"
|
92
|
+
codepoints = data.unpack("U*")
|
93
|
+
|
94
|
+
deliver(dump_codepoints(codepoints, format: dump), print: print, codepoints_length: codepoints.length, message: "dump of")
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.deliver(output, print: false, message: "", codepoints_length:)
|
99
|
+
if print
|
100
|
+
puts(output)
|
101
|
+
else
|
102
|
+
Clipboard.copy(output)
|
103
|
+
puts Paint["Copied #{message} #{codepoints_length} codepoint#{codepoints_length != 1 ? "s" : ""} to clipboard", :green]
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def self.transform_raw_codepoints(codepoints, parse_decimal = false)
|
108
|
+
if parse_decimal
|
109
|
+
parse_numerals_regex = /\A([0-9]+)\z/
|
110
|
+
numeral_base = 10
|
111
|
+
else
|
112
|
+
parse_numerals_regex = /\A(?:U\+)?(\h+)\z/
|
113
|
+
numeral_base = 16
|
114
|
+
end
|
115
|
+
|
116
|
+
codepoints.map{ |cp|
|
117
|
+
case cp
|
118
|
+
when Integer
|
119
|
+
cp
|
120
|
+
when parse_numerals_regex
|
121
|
+
$1.to_i(numeral_base)
|
122
|
+
else
|
123
|
+
raise ArgumentError, "unicopy does not understand codepoint \"#{cp}\". Please pass hexadecimal codepoint values, separated by spaces, or use --string option"
|
124
|
+
end
|
125
|
+
}.tap{ |codepoints|
|
126
|
+
codepoints.pack("U*").valid_encoding? or raise ArgumentError, "invalid codepoints passed to unicopy"
|
127
|
+
}
|
128
|
+
end
|
129
|
+
|
130
|
+
def self.dump_codepoints(codepoints, format: nil)
|
131
|
+
format ||= "uplus"
|
132
|
+
if dump_format_details = DUMP_FORMATS[format]
|
133
|
+
prefix = dump_format_details[:prefix] || DUMP_FORMAT_DEFAULTS[:prefix]
|
134
|
+
replace = dump_format_details[:replace] || DUMP_FORMAT_DEFAULTS[:replace]
|
135
|
+
joiner = dump_format_details[:joiner] || DUMP_FORMAT_DEFAULTS[:joiner]
|
136
|
+
suffix = dump_format_details[:suffix] || DUMP_FORMAT_DEFAULTS[:suffix]
|
137
|
+
else
|
138
|
+
raise ArgumentError, "unicopy does not know dump format \"#{format}\""
|
139
|
+
end
|
140
|
+
|
141
|
+
prefix + codepoints.map{ |cp| replace.is_a?(Proc) ? replace[cp] : replace % cp }.join(joiner) + suffix
|
142
|
+
end
|
143
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require_relative "../lib/unicopy/kernel_method"
|
2
|
+
require "minitest/autorun"
|
3
|
+
|
4
|
+
describe Unicopy do
|
5
|
+
it "converts codepoints to string and, with --print, outputs it to STDOUT" do
|
6
|
+
assert_output(/Ruby 🌫/){ unicopy("52 75 62 79 20 1F32B", print: true) }
|
7
|
+
end
|
8
|
+
|
9
|
+
it "also works with U+ prefixes" do
|
10
|
+
assert_output(/Ruby 🌫/){ unicopy("U+0052 U+0075 U+0062 U+0079 U+0020 U+1F32B", print: true) }
|
11
|
+
end
|
12
|
+
|
13
|
+
it "parses codepoints as decimal if --parse-decimal option is given" do
|
14
|
+
assert_output(/4K>O/){ unicopy("52 75 62 79", print: true, parse_decimal: true) }
|
15
|
+
end
|
16
|
+
|
17
|
+
it "will convert string to codepoints with --string option" do
|
18
|
+
assert_output(Regexp.compile(Regexp.escape("U+0052 U+0075 U+0062 U+0079 U+0020 U+1F32B"))){
|
19
|
+
unicopy("Ruby 🌫", print: true, string: true)
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
it "works with non-UTF-8 input" do
|
24
|
+
assert_output(Regexp.compile(Regexp.escape("U+0052 U+0075 U+0062 U+0079 U+0020 U+1F32B"))){
|
25
|
+
unicopy("Ruby 🌫".encode("UTF-16LE"), print: true, string: true)
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "[dump formats]" do
|
30
|
+
it "dumps hex" do
|
31
|
+
assert_output(Regexp.compile(Regexp.escape("52 75 62 79 20 1F32B"))){
|
32
|
+
unicopy("52 75 62 79 20 1F32B", print: true, dump: "hex")
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
it "dumps hex (string input)" do
|
37
|
+
assert_output(Regexp.compile(Regexp.escape("52 75 62 79 20 1F32B"))){
|
38
|
+
unicopy("Ruby 🌫", print: true, string: true, dump: "hex")
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
it "dumps uplus (string input) [default]" do
|
43
|
+
assert_output(Regexp.compile(Regexp.escape("U+0052 U+0075 U+0062 U+0079 U+0020 U+1F32B"))){
|
44
|
+
unicopy("Ruby 🌫", print: true, string: true)
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
it "dumps 0x (string input)" do
|
49
|
+
assert_output(Regexp.compile(Regexp.escape("0x0052 0x0075 0x0062 0x0079 0x0020 0x1F32B"))){
|
50
|
+
unicopy("Ruby 🌫", print: true, string: true, dump: "0x")
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
it "dumps dec (string input)" do
|
55
|
+
assert_output(Regexp.compile(Regexp.escape("82 117 98 121 32 127787"))){
|
56
|
+
unicopy("Ruby 🌫", print: true, string: true, dump: "dec")
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
it "dumps ruby (string input)" do
|
61
|
+
assert_output(Regexp.compile(Regexp.escape("\\u{52 75 62 79 20 1F32B}"))){
|
62
|
+
unicopy("Ruby 🌫", print: true, string: true, dump: "ruby")
|
63
|
+
}
|
64
|
+
end
|
65
|
+
|
66
|
+
it "dumps js (string input)" do
|
67
|
+
assert_output(Regexp.compile(Regexp.escape("\\u0052\\u0075\\u0062\\u0079\\u0020\\uD83C\\uDF2B"))){
|
68
|
+
unicopy("Ruby 🌫", print: true, string: true, dump: "js")
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
it "dumps es6 (string input)" do
|
73
|
+
assert_output(Regexp.compile(Regexp.escape("\\u{52}\\u{75}\\u{62}\\u{79}\\u{20}\\u{1F32B}"))){
|
74
|
+
unicopy("Ruby 🌫", print: true, string: true, dump: "es6")
|
75
|
+
}
|
76
|
+
end
|
77
|
+
|
78
|
+
it "dumps css (string input)" do
|
79
|
+
assert_output(Regexp.compile(Regexp.escape("\\52\\75\\62\\79\\20\\1f32b"))){
|
80
|
+
unicopy("Ruby 🌫", print: true, string: true, dump: "css")
|
81
|
+
}
|
82
|
+
end
|
83
|
+
|
84
|
+
it "dumps html-hex (string input)" do
|
85
|
+
assert_output(Regexp.compile(Regexp.escape("Ruby 🌫"))){
|
86
|
+
unicopy("Ruby 🌫", print: true, string: true, dump: "html-hex")
|
87
|
+
}
|
88
|
+
end
|
89
|
+
|
90
|
+
it "dumps html-dec (string input)" do
|
91
|
+
assert_output(Regexp.compile(Regexp.escape("Ruby 🌫"))){
|
92
|
+
unicopy("Ruby 🌫", print: true, string: true, dump: "html-dec")
|
93
|
+
}
|
94
|
+
end
|
95
|
+
|
96
|
+
it "dumps bytes-utf8 (string input)" do
|
97
|
+
assert_output(Regexp.compile(Regexp.escape("52 75 62 79 20 F0 9F 8C AB"))){
|
98
|
+
unicopy("Ruby 🌫", print: true, string: true, dump: "bytes-utf8")
|
99
|
+
}
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
data/unicopy.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require File.dirname(__FILE__) + "/lib/unicopy/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gem.name = "unicopy"
|
7
|
+
gem.version = Unicopy::VERSION
|
8
|
+
gem.summary = "Converts Unicode codepoints to a string (or vice versa) and copies it to the system clipboard."
|
9
|
+
gem.description = "Converts Unicode codepoints to a string (or vice versa) and copies it to the system clipboard. Can also convert codepoints to many dump formats."
|
10
|
+
gem.authors = ["Jan Lelis"]
|
11
|
+
gem.email = ["mail@janlelis.de"]
|
12
|
+
gem.homepage = "https://github.com/janlelis/unicopy"
|
13
|
+
gem.license = "MIT"
|
14
|
+
|
15
|
+
gem.files = Dir["{**/}{.*,*}"].select{ |path| File.file?(path) && path !~ /^(pkg|screenshots)/ }
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_dependency 'paint', '>= 0.9', '< 3.0'
|
21
|
+
gem.add_dependency 'rationalist', '~> 2.0'
|
22
|
+
gem.add_dependency 'clipboard', '~> 1.1'
|
23
|
+
|
24
|
+
gem.required_ruby_version = "~> 2.0"
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: unicopy
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jan Lelis
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-04-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: paint
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.9'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '3.0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0.9'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '3.0'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: rationalist
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '2.0'
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '2.0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: clipboard
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '1.1'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '1.1'
|
61
|
+
description: Converts Unicode codepoints to a string (or vice versa) and copies it
|
62
|
+
to the system clipboard. Can also convert codepoints to many dump formats.
|
63
|
+
email:
|
64
|
+
- mail@janlelis.de
|
65
|
+
executables:
|
66
|
+
- unicopy
|
67
|
+
extensions: []
|
68
|
+
extra_rdoc_files: []
|
69
|
+
files:
|
70
|
+
- ".gitignore"
|
71
|
+
- ".travis.yml"
|
72
|
+
- CHANGELOG.md
|
73
|
+
- CODE_OF_CONDUCT.md
|
74
|
+
- Gemfile
|
75
|
+
- Gemfile.lock
|
76
|
+
- MIT-LICENSE.txt
|
77
|
+
- README.md
|
78
|
+
- Rakefile
|
79
|
+
- bin/unicopy
|
80
|
+
- lib/unicopy.rb
|
81
|
+
- lib/unicopy/kernel_method.rb
|
82
|
+
- lib/unicopy/version.rb
|
83
|
+
- spec/unicopy_spec.rb
|
84
|
+
- unicopy.gemspec
|
85
|
+
homepage: https://github.com/janlelis/unicopy
|
86
|
+
licenses:
|
87
|
+
- MIT
|
88
|
+
metadata: {}
|
89
|
+
post_install_message:
|
90
|
+
rdoc_options: []
|
91
|
+
require_paths:
|
92
|
+
- lib
|
93
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - "~>"
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '2.0'
|
98
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
requirements: []
|
104
|
+
rubyforge_project:
|
105
|
+
rubygems_version: 2.6.8
|
106
|
+
signing_key:
|
107
|
+
specification_version: 4
|
108
|
+
summary: Converts Unicode codepoints to a string (or vice versa) and copies it to
|
109
|
+
the system clipboard.
|
110
|
+
test_files:
|
111
|
+
- spec/unicopy_spec.rb
|