cyrillic 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -0
- data/README.md +59 -3
- data/Rakefile +14 -0
- data/benchmark/run.rb +58 -0
- data/cyrillic.gemspec +4 -0
- data/exe/cyrillic +22 -14
- data/lib/cyrillic/belarusian.rb +21 -0
- data/lib/cyrillic/bgn_pcgn.rb +21 -0
- data/lib/cyrillic/bulgarian.rb +21 -0
- data/lib/cyrillic/de.rb +1 -0
- data/lib/cyrillic/gost779b.rb +21 -0
- data/lib/cyrillic/iso9.rb +1 -0
- data/lib/cyrillic/mongolian.rb +1 -0
- data/lib/cyrillic/serbian.rb +21 -0
- data/lib/cyrillic/ukrainian.rb +1 -0
- data/lib/cyrillic/version.rb +1 -1
- data/lib/cyrillic.rb +71 -4
- metadata +50 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6ccb18a2a8380ecae221098c62b00e1d21654f99020a78a48d921763075adaac
|
|
4
|
+
data.tar.gz: d5ef041b472f740ab9461b67efbeb683b85120adf5a34d5d21d5fa10067a7d30
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8e60b7cb7871b6b7bc0d787cf4520ef0a28dbd2ac63ddb117f1a2d44527191576037f6cf7d269b1e66a157489c56a89c32d5269cf0cd074fec68553427759e3f
|
|
7
|
+
data.tar.gz: 26d33008bf7af9bc70926dff63ce77d0d4cff9542cfd73dc3bd787aae2a0171a35617339684fcbb14401b94e1368f750968f9bbded55d95e9b66f72872de9b4a
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.4.0] - 2026-09-17
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- 5 new transliteration schemes:
|
|
14
|
+
- Serbian (`:serbian`) translating Vuk's Cyrillic to Gaj's Latin (`Lj`, `Nj`, `Dž`, `Đ`, `Ć`).
|
|
15
|
+
- GOST 7.79-2000 System B (`:gost779b`) with standard ASCII digraphs.
|
|
16
|
+
- BGN/PCGN 1947 geographic romanization (`:bgn_pcgn`).
|
|
17
|
+
- Bulgarian official Streamlined System (`:bulgarian`).
|
|
18
|
+
- Belarusian national / UN 2012 Łacinka (`:belarusian`).
|
|
19
|
+
- Reverse transliteration (detransliteration) via `Cyrillic.detransliterate` (and aliases `.det`, `.reverse_transliterate`) with reverse mapping tables and longest-token-first greedy matching.
|
|
20
|
+
- CLI flag `-r, --reverse` for reversing transliterated text back to Cyrillic.
|
|
21
|
+
- Comprehensive fixture datasets in `test/fixtures/` and automated test suite in `test/fixtures_test.rb` verifying Ukrainian, Serbian, Bulgarian, Belarusian, Mongolian, and standard international schemes.
|
|
22
|
+
- Comprehensive performance benchmark suite in `benchmark/run.rb` with `rake benchmark` task testing all schemes, detransliteration, and text scale using `benchmark-ips`.
|
|
23
|
+
- Automated YARD documentation generation and deployment to GitHub Pages via `.github/workflows/docs.yml` and `rake yard` task.
|
|
24
|
+
- Documentation link badge in `README.md` and `documentation_uri` gem metadata.
|
|
25
|
+
- CLI executable support and unit test coverage for all new schemes and detransliteration.
|
|
26
|
+
|
|
10
27
|
## [0.3.0] - 2026-09-17
|
|
11
28
|
|
|
12
29
|
### Added
|
data/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# Cyrillic
|
|
2
2
|
|
|
3
3
|
[](https://github.com/rovetz/cyrillic/actions/workflows/ruby.yml)
|
|
4
|
+
[](https://rovetz.github.io/cyrillic/)
|
|
4
5
|
[](https://badge.fury.io/rb/cyrillic)
|
|
5
6
|
[](https://opensource.org/licenses/MIT)
|
|
6
7
|
|
|
@@ -9,9 +10,14 @@
|
|
|
9
10
|
## Supported Schemes
|
|
10
11
|
|
|
11
12
|
* `:cyrillic` (Default generic Cyrillic transliteration)
|
|
12
|
-
* `:iso9` (ISO 9:1995 standard)
|
|
13
|
+
* `:iso9` (ISO 9:1995 international standard)
|
|
14
|
+
* `:serbian` (Serbian Vuk's Cyrillic to Gaj's Latin)
|
|
15
|
+
* `:gost779b` (GOST 7.79-2000 System B ASCII digraphs)
|
|
16
|
+
* `:bgn_pcgn` (BGN/PCGN 1947 geographic romanization)
|
|
17
|
+
* `:bulgarian` (Bulgarian official Streamlined System)
|
|
18
|
+
* `:belarusian` (Belarusian national / UN 2012 Łacinka)
|
|
13
19
|
* `:ukrainian` (Ukrainian national standard)
|
|
14
|
-
* `:ua_passport` (Ukrainian international passport
|
|
20
|
+
* `:ua_passport` (Ukrainian international passport standard)
|
|
15
21
|
* `:mongolian` (Mongolian Cyrillic MNS 5217:2012)
|
|
16
22
|
* `:de` (German Duden/phonetic transliteration)
|
|
17
23
|
|
|
@@ -48,6 +54,26 @@ Cyrillic.t("Кириллица")
|
|
|
48
54
|
Cyrillic.t("Не важно, как медленно ты продвигаешься", :iso9)
|
|
49
55
|
# => "Ne važno, kak medlenno ty prodvigaešʹsâ"
|
|
50
56
|
|
|
57
|
+
# Serbian Cyrillic to Latin (Vukovica to Gajica)
|
|
58
|
+
Cyrillic.t("Љубљана", :serbian)
|
|
59
|
+
# => "Ljubljana"
|
|
60
|
+
|
|
61
|
+
# GOST 7.79-2000 System B (ASCII digraphs)
|
|
62
|
+
Cyrillic.t("Щука", :gost779b)
|
|
63
|
+
# => "Shhuka"
|
|
64
|
+
|
|
65
|
+
# BGN/PCGN 1947 geographic romanization
|
|
66
|
+
Cyrillic.t("Хабаровск", :bgn_pcgn)
|
|
67
|
+
# => "Khabarovsk"
|
|
68
|
+
|
|
69
|
+
# Bulgarian Streamlined System
|
|
70
|
+
Cyrillic.t("България", :bulgarian)
|
|
71
|
+
# => "Balgariya"
|
|
72
|
+
|
|
73
|
+
# Belarusian national / UN 2012 Łacinka
|
|
74
|
+
Cyrillic.t("Мінск", :belarusian)
|
|
75
|
+
# => "Minsk"
|
|
76
|
+
|
|
51
77
|
# Ukrainian scheme
|
|
52
78
|
Cyrillic.t("Київ", :ukrainian)
|
|
53
79
|
# => "Kyiv"
|
|
@@ -63,6 +89,14 @@ Cyrillic.t("Монгол хэл", :mongolian)
|
|
|
63
89
|
# German transliteration scheme
|
|
64
90
|
Cyrillic.t("Чайковский", :de)
|
|
65
91
|
# => "Tschajkowskij"
|
|
92
|
+
|
|
93
|
+
# Reverse transliteration (Detransliteration)
|
|
94
|
+
Cyrillic.detransliterate("Transliteraciâ", :iso9)
|
|
95
|
+
# => "Транслитерация"
|
|
96
|
+
|
|
97
|
+
# Short alias .det
|
|
98
|
+
Cyrillic.det("Ljubljana", :serbian)
|
|
99
|
+
# => "Љубљана"
|
|
66
100
|
```
|
|
67
101
|
|
|
68
102
|
### Command Line Interface (CLI)
|
|
@@ -85,6 +119,21 @@ $ cyrillic text.txt
|
|
|
85
119
|
$ cyrillic -s iso9 "Транслитерация"
|
|
86
120
|
Transliteraciâ
|
|
87
121
|
|
|
122
|
+
$ cyrillic -s serbian "Љубљана"
|
|
123
|
+
Ljubljana
|
|
124
|
+
|
|
125
|
+
$ cyrillic -s gost779b "Щука"
|
|
126
|
+
Shhuka
|
|
127
|
+
|
|
128
|
+
$ cyrillic -s bgn_pcgn "Хабаровск"
|
|
129
|
+
Khabarovsk
|
|
130
|
+
|
|
131
|
+
$ cyrillic -s bulgarian "България"
|
|
132
|
+
Balgariya
|
|
133
|
+
|
|
134
|
+
$ cyrillic -s belarusian "Мінск"
|
|
135
|
+
Minsk
|
|
136
|
+
|
|
88
137
|
$ cyrillic -s ukrainian "Київ"
|
|
89
138
|
Kyiv
|
|
90
139
|
|
|
@@ -93,11 +142,18 @@ Borshchahivka
|
|
|
93
142
|
|
|
94
143
|
$ cyrillic -s de "Весна"
|
|
95
144
|
Wesna
|
|
145
|
+
|
|
146
|
+
# Reverse transliteration (-r, --reverse)
|
|
147
|
+
$ cyrillic -r "Transliteraciâ"
|
|
148
|
+
Транслитерация
|
|
149
|
+
|
|
150
|
+
$ cyrillic -r -s serbian "Ljubljana"
|
|
151
|
+
Љубљана
|
|
96
152
|
```
|
|
97
153
|
|
|
98
154
|
## Development
|
|
99
155
|
|
|
100
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rake` to run tests and code style checks (RuboCop). You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
156
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rake` to run tests and code style checks (RuboCop). You can run performance benchmarks with `bundle exec rake benchmark`. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
101
157
|
|
|
102
158
|
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).
|
|
103
159
|
|
data/Rakefile
CHANGED
|
@@ -12,4 +12,18 @@ end
|
|
|
12
12
|
|
|
13
13
|
RuboCop::RakeTask.new(:rubocop)
|
|
14
14
|
|
|
15
|
+
desc "Run performance benchmarks"
|
|
16
|
+
task :benchmark do
|
|
17
|
+
ruby "benchmark/run.rb"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
begin
|
|
21
|
+
require "yard"
|
|
22
|
+
YARD::Rake::YardocTask.new do |t|
|
|
23
|
+
t.files = ["lib/**/*.rb", "-", "README.md", "CHANGELOG.md", "LICENSE.txt"]
|
|
24
|
+
end
|
|
25
|
+
rescue LoadError
|
|
26
|
+
# YARD not available
|
|
27
|
+
end
|
|
28
|
+
|
|
15
29
|
task default: %i[test rubocop]
|
data/benchmark/run.rb
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "benchmark/ips"
|
|
4
|
+
require_relative "../lib/cyrillic"
|
|
5
|
+
|
|
6
|
+
SHORT_TEXT = "Не важно, как медленно ты продвигаешься, главное, что ты не останавливаешься."
|
|
7
|
+
PARAGRAPH_TEXT = [
|
|
8
|
+
"Весна пришла в город с первыми теплыми лучами солнца и ароматом цветущих садов.",
|
|
9
|
+
"На центральных улицах кипела жизнь: открывались уютные кафе, люди гуляли по набережной.",
|
|
10
|
+
"Каждый новый день приносил вдохновение, надежду и стремление к созиданию прекрасного будущего.",
|
|
11
|
+
"В библиотеках и университетах студенты усердно готовились к весенним экзаменам и научным конференциям."
|
|
12
|
+
].join(" ")
|
|
13
|
+
LONG_TEXT = "#{PARAGRAPH_TEXT} " * 30
|
|
14
|
+
|
|
15
|
+
puts "=" * 60
|
|
16
|
+
puts "Cyrillic Gem Performance Benchmarks"
|
|
17
|
+
puts "Ruby: #{RUBY_DESCRIPTION}"
|
|
18
|
+
puts "=" * 60
|
|
19
|
+
|
|
20
|
+
puts "\n[1] Schemes Comparison (Paragraph Text, ~350 chars)"
|
|
21
|
+
Benchmark.ips do |x|
|
|
22
|
+
x.config(time: 1, warmup: 0.5)
|
|
23
|
+
|
|
24
|
+
%i[cyrillic iso9 serbian gost779b bgn_pcgn bulgarian belarusian mongolian ukrainian ua_passport de].each do |scheme|
|
|
25
|
+
x.report(scheme.to_s) do
|
|
26
|
+
Cyrillic.t(PARAGRAPH_TEXT, scheme)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
x.compare!
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
puts "\n[2] Forward vs Reverse Transliteration (ISO 9 & Serbian)"
|
|
34
|
+
iso9_latin = Cyrillic.t(PARAGRAPH_TEXT, :iso9)
|
|
35
|
+
serbian_cyr = "Београд, Нови Сад, Ниш, Крагујевац, Суботица, Зрењанин, Панчево, Чачак, Краљево, Ваљево."
|
|
36
|
+
serbian_lat = Cyrillic.t(serbian_cyr, :serbian)
|
|
37
|
+
|
|
38
|
+
Benchmark.ips do |x|
|
|
39
|
+
x.config(time: 1, warmup: 0.5)
|
|
40
|
+
|
|
41
|
+
x.report("iso9 forward") { Cyrillic.t(PARAGRAPH_TEXT, :iso9) }
|
|
42
|
+
x.report("iso9 reverse") { Cyrillic.det(iso9_latin, :iso9) }
|
|
43
|
+
x.report("serbian fwd") { Cyrillic.t(serbian_cyr, :serbian) }
|
|
44
|
+
x.report("serbian rev") { Cyrillic.det(serbian_lat, :serbian) }
|
|
45
|
+
|
|
46
|
+
x.compare!
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
puts "\n[3] Scalability by Text Size (ISO 9: short, medium, long)"
|
|
50
|
+
Benchmark.ips do |x|
|
|
51
|
+
x.config(time: 1, warmup: 0.5)
|
|
52
|
+
|
|
53
|
+
x.report("short (~75 chars)") { Cyrillic.t(SHORT_TEXT, :iso9) }
|
|
54
|
+
x.report("medium (~350 chars)") { Cyrillic.t(PARAGRAPH_TEXT, :iso9) }
|
|
55
|
+
x.report("long (~10,500 chars)") { Cyrillic.t(LONG_TEXT, :iso9) }
|
|
56
|
+
|
|
57
|
+
x.compare!
|
|
58
|
+
end
|
data/cyrillic.gemspec
CHANGED
|
@@ -20,6 +20,7 @@ Gem::Specification.new do |spec|
|
|
|
20
20
|
spec.metadata["source_code_uri"] = "https://github.com/rovetz/cyrillic"
|
|
21
21
|
spec.metadata["changelog_uri"] = "https://github.com/rovetz/cyrillic/blob/main/CHANGELOG.md"
|
|
22
22
|
spec.metadata["bug_tracker_uri"] = "https://github.com/rovetz/cyrillic/issues"
|
|
23
|
+
spec.metadata["documentation_uri"] = "https://rovetz.github.io/cyrillic/"
|
|
23
24
|
spec.metadata["rubygems_mfa_required"] = "true"
|
|
24
25
|
|
|
25
26
|
spec.files = Dir.chdir(__dir__) do
|
|
@@ -32,10 +33,13 @@ Gem::Specification.new do |spec|
|
|
|
32
33
|
spec.executables = ["cyrillic"]
|
|
33
34
|
spec.require_paths = ["lib"]
|
|
34
35
|
|
|
36
|
+
spec.add_development_dependency "benchmark"
|
|
37
|
+
spec.add_development_dependency "benchmark-ips"
|
|
35
38
|
spec.add_development_dependency "irb"
|
|
36
39
|
spec.add_development_dependency "minitest", ">= 5.25"
|
|
37
40
|
spec.add_development_dependency "rake", ">= 13.2"
|
|
38
41
|
spec.add_development_dependency "rdoc"
|
|
39
42
|
spec.add_development_dependency "rubocop", ">= 1.64"
|
|
40
43
|
spec.add_development_dependency "simplecov", ">= 0.22"
|
|
44
|
+
spec.add_development_dependency "yard", ">= 0.9.36"
|
|
41
45
|
end
|
data/exe/cyrillic
CHANGED
|
@@ -5,29 +5,33 @@ require "optparse"
|
|
|
5
5
|
require "cyrillic"
|
|
6
6
|
|
|
7
7
|
scheme = nil
|
|
8
|
+
reverse = false
|
|
8
9
|
|
|
9
10
|
parser = OptionParser.new do |opts|
|
|
10
11
|
opts.banner = "Usage: cyrillic [options] [text | file...]"
|
|
11
12
|
opts.separator ""
|
|
12
|
-
opts.separator "Transliterate Cyrillic script to Roman (Latin) script."
|
|
13
|
+
opts.separator "Transliterate Cyrillic script to Roman (Latin) script, or reverse with -r."
|
|
13
14
|
opts.separator ""
|
|
14
15
|
opts.separator "Examples:"
|
|
15
16
|
opts.separator " cyrillic 'Кириллица'"
|
|
16
17
|
opts.separator " echo 'Кириллица' | cyrillic"
|
|
17
|
-
opts.separator " cyrillic
|
|
18
|
-
opts.separator " cyrillic -s
|
|
19
|
-
opts.separator " cyrillic -s
|
|
20
|
-
opts.separator " cyrillic -s
|
|
21
|
-
opts.separator " cyrillic -s mongolian 'Монгол'"
|
|
22
|
-
opts.separator " cyrillic -s de 'Весна'"
|
|
18
|
+
opts.separator " cyrillic -r 'Transliteraciâ'"
|
|
19
|
+
opts.separator " cyrillic -s serbian 'Љубљана'"
|
|
20
|
+
opts.separator " cyrillic -r -s serbian 'Ljubljana'"
|
|
21
|
+
opts.separator " cyrillic -r -s gost779b 'Shhuka'"
|
|
23
22
|
opts.separator ""
|
|
24
23
|
opts.separator "Options:"
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
schemes = %w[default cyrillic iso9 mongolian ukrainian ua_passport de serbian gost779b bgn_pcgn bulgarian belarusian]
|
|
26
|
+
opts.on("-s", "--scheme SCHEME", schemes,
|
|
27
|
+
"Transliteration scheme (#{schemes.join(', ')})") do |s|
|
|
28
28
|
scheme = s == "default" ? nil : s.to_sym
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
+
opts.on("-r", "--reverse", "Reverse transliteration (Latin to Cyrillic)") do
|
|
32
|
+
reverse = true
|
|
33
|
+
end
|
|
34
|
+
|
|
31
35
|
opts.on("-v", "--version", "Show version") do
|
|
32
36
|
puts "cyrillic #{Cyrillic::VERSION}"
|
|
33
37
|
exit
|
|
@@ -41,8 +45,12 @@ end
|
|
|
41
45
|
|
|
42
46
|
parser.parse!
|
|
43
47
|
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
process = lambda do |text|
|
|
49
|
+
if reverse
|
|
50
|
+
Cyrillic.detransliterate(text, from: scheme || :iso9)
|
|
51
|
+
else
|
|
52
|
+
Cyrillic.transliterate(text, scheme || :cyrillic)
|
|
53
|
+
end
|
|
46
54
|
end
|
|
47
55
|
|
|
48
56
|
if ARGV.empty?
|
|
@@ -51,17 +59,17 @@ if ARGV.empty?
|
|
|
51
59
|
exit 1
|
|
52
60
|
else
|
|
53
61
|
$stdin.each_line do |line|
|
|
54
|
-
puts
|
|
62
|
+
puts process.call(line.chomp)
|
|
55
63
|
end
|
|
56
64
|
end
|
|
57
65
|
else
|
|
58
66
|
ARGV.each do |arg|
|
|
59
67
|
if File.file?(arg)
|
|
60
68
|
File.foreach(arg) do |line|
|
|
61
|
-
puts
|
|
69
|
+
puts process.call(line.chomp)
|
|
62
70
|
end
|
|
63
71
|
else
|
|
64
|
-
puts
|
|
72
|
+
puts process.call(arg)
|
|
65
73
|
end
|
|
66
74
|
end
|
|
67
75
|
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Cyrillic
|
|
4
|
+
# Belarusian national / UN 2012 Łacinka transliteration.
|
|
5
|
+
module Belarusian
|
|
6
|
+
k = %w[
|
|
7
|
+
А Б В Г Д Е Ё Ж З І Й К Л М Н О П Р С Т У Ў Ф Х Ц Ч Ш Ы Ь Э Ю Я
|
|
8
|
+
а б в г д е ё ж з і й к л м н о п р с т у ў ф х ц ч ш ы ь э ю я
|
|
9
|
+
].freeze
|
|
10
|
+
|
|
11
|
+
v = %w[
|
|
12
|
+
A B V H D E Jo Ž Z I J K L M N O P R S T U Ŭ F Ch C Č Š Y ' E Ju Ja
|
|
13
|
+
a b v h d e jo ž z i j k l m n o p r s t u ŭ f ch c č š y ' e ju ja
|
|
14
|
+
].freeze
|
|
15
|
+
|
|
16
|
+
CHARACTER_TABLE = k.zip(v).to_h.freeze
|
|
17
|
+
REGEXP = Regexp.union(CHARACTER_TABLE.keys).freeze
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
Belarusian = Cyrillic::Belarusian unless defined?(Belarusian)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Cyrillic
|
|
4
|
+
# BGN/PCGN 1947 geographic romanization system.
|
|
5
|
+
module BgnPcgn
|
|
6
|
+
k = %w[
|
|
7
|
+
А Б В Г Д Е Ё Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я
|
|
8
|
+
а б в г д е ё ж з и й к л м н о п р с т у ф х ц ч ш щ ъ ы ь э ю я
|
|
9
|
+
].freeze
|
|
10
|
+
|
|
11
|
+
v = %w[
|
|
12
|
+
A B V G D E Yo Zh Z I Y K L M N O P R S T U F Kh Ts Ch Sh Shch " Y ' E Yu Ya
|
|
13
|
+
a b v g d e yo zh z i y k l m n o p r s t u f kh ts ch sh shch " y ' e yu ya
|
|
14
|
+
].freeze
|
|
15
|
+
|
|
16
|
+
CHARACTER_TABLE = k.zip(v).to_h.freeze
|
|
17
|
+
REGEXP = Regexp.union(CHARACTER_TABLE.keys).freeze
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
BgnPcgn = Cyrillic::BgnPcgn unless defined?(BgnPcgn)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Cyrillic
|
|
4
|
+
# Bulgarian official Streamlined System (2006/2009) transliteration.
|
|
5
|
+
module Bulgarian
|
|
6
|
+
k = %w[
|
|
7
|
+
А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ь Ю Я
|
|
8
|
+
а б в г д е ж з и й к л м н о п р с т у ф х ц ч ш щ ъ ь ю я
|
|
9
|
+
].freeze
|
|
10
|
+
|
|
11
|
+
v = %w[
|
|
12
|
+
A B V G D E Zh Z I Y K L M N O P R S T U F H Ts Ch Sh Sht A Y Yu Ya
|
|
13
|
+
a b v g d e zh z i y k l m n o p r s t u f h ts ch sh sht a y yu ya
|
|
14
|
+
].freeze
|
|
15
|
+
|
|
16
|
+
CHARACTER_TABLE = k.zip(v).to_h.freeze
|
|
17
|
+
REGEXP = Regexp.union(CHARACTER_TABLE.keys).freeze
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
Bulgarian = Cyrillic::Bulgarian unless defined?(Bulgarian)
|
data/lib/cyrillic/de.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Cyrillic
|
|
4
|
+
# German (Duden/phonetic) transliteration system.
|
|
4
5
|
module De
|
|
5
6
|
k = %w[А Б В Г Д Е Ё Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я а б в г д е ё ж з и й к л м н о п р с т у ф х ц ч ш щ ъ ы ь э ю я].freeze
|
|
6
7
|
v = %w[A B W G D E Jo Sch S I J K L M N O P R S T U F Ch Z Tsch Sch Schtsch "" Y "" E Ju Ja a b w g d e jo sch s i j k l m n o p r s t u f ch z tsch sch schtsch "" y "" e ju ja].freeze
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Cyrillic
|
|
4
|
+
# GOST 7.79-2000 System B (ISO 9 System B) ASCII digraphs transliteration.
|
|
5
|
+
module Gost779b
|
|
6
|
+
k = %w[
|
|
7
|
+
А Б В Г Д Е Ё Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я
|
|
8
|
+
а б в г д е ё ж з и й к л м н о п р с т у ф х ц ч ш щ ъ ы ь э ю я
|
|
9
|
+
].freeze
|
|
10
|
+
|
|
11
|
+
v = %w[
|
|
12
|
+
A B V G D E Yo Zh Z I J K L M N O P R S T U F X Cz Ch Sh Shh " Y ' E' Yu Ya
|
|
13
|
+
a b v g d e yo zh z i j k l m n o p r s t u f x cz ch sh shh " y ' e' yu ya
|
|
14
|
+
].freeze
|
|
15
|
+
|
|
16
|
+
CHARACTER_TABLE = k.zip(v).to_h.freeze
|
|
17
|
+
REGEXP = Regexp.union(CHARACTER_TABLE.keys).freeze
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
Gost779b = Cyrillic::Gost779b unless defined?(Gost779b)
|
data/lib/cyrillic/iso9.rb
CHANGED
data/lib/cyrillic/mongolian.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Cyrillic
|
|
4
|
+
# Mongolian Cyrillic standard (MNS 5217:2012) romanization.
|
|
4
5
|
module Mongolian
|
|
5
6
|
k = %w[А Б В Г Д Е Ё Ж З И Й К Л М Н О Ө П Р С Т У Ү Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я а б в г д е ё ж з и й к л м н о ө п р с т у ү ф х ц ч ш щ ъ ы ь э ю я].freeze
|
|
6
7
|
v = %w[A B V G D Ye Yo J Z I I K L M N O O P R S T U U F Kh Ts Ch Sh Sh I Y I E Yu Ya a b v g d ye yo j z i i k l m n o o p r s t u u f kh ts ch sh sh i y i e yu ya].freeze
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Cyrillic
|
|
4
|
+
# Serbian Cyrillic to Gaj's Latin transliteration (Vukovica to Gajica).
|
|
5
|
+
module Serbian
|
|
6
|
+
k = %w[
|
|
7
|
+
А Б В Г Д Ђ Е Ж З И Ј К Л Љ М Н Њ О П Р С Т Ћ У Ф Х Ц Ч Џ Ш
|
|
8
|
+
а б в г д ђ е ж з и ј к л љ м н њ о п р с т ћ у ф х ц ч џ ш
|
|
9
|
+
].freeze
|
|
10
|
+
|
|
11
|
+
v = %w[
|
|
12
|
+
A B V G D Đ E Ž Z I J K L Lj M N Nj O P R S T Ć U F H C Č Dž Š
|
|
13
|
+
a b v g d đ e ž z i j k l lj m n nj o p r s t ć u f h c č dž š
|
|
14
|
+
].freeze
|
|
15
|
+
|
|
16
|
+
CHARACTER_TABLE = k.zip(v).to_h.freeze
|
|
17
|
+
REGEXP = Regexp.union(CHARACTER_TABLE.keys).freeze
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
Serbian = Cyrillic::Serbian unless defined?(Serbian)
|
data/lib/cyrillic/ukrainian.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Cyrillic
|
|
4
|
+
# Ukrainian national transliteration system.
|
|
4
5
|
module Ukrainian
|
|
5
6
|
k = %w[А Б В Г Ґ Д Е Є Ж З И І Ї Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ь Ю Я а б в г ґ д е є ж з и і ї й к л м н о п р с т у ф х ц ч ш щ ь ю я].freeze
|
|
6
7
|
v = %w[A B V H G D E Ye Zh Z Y I Yi I K L M N O P R S T U F Kh Ts Ch Sh Shch ʹ Iu Ia a b v h g d e ye zh z y i yi i k l m n o p r s t u f kh ts ch sh shch ʹ iu ia].freeze
|
data/lib/cyrillic/version.rb
CHANGED
data/lib/cyrillic.rb
CHANGED
|
@@ -6,6 +6,11 @@ require "cyrillic/mongolian"
|
|
|
6
6
|
require "cyrillic/ukrainian"
|
|
7
7
|
require "cyrillic/ua_passport"
|
|
8
8
|
require "cyrillic/de"
|
|
9
|
+
require "cyrillic/serbian"
|
|
10
|
+
require "cyrillic/gost779b"
|
|
11
|
+
require "cyrillic/bgn_pcgn"
|
|
12
|
+
require "cyrillic/bulgarian"
|
|
13
|
+
require "cyrillic/belarusian"
|
|
9
14
|
|
|
10
15
|
module Cyrillic
|
|
11
16
|
k = %w[
|
|
@@ -27,14 +32,44 @@ module Cyrillic
|
|
|
27
32
|
mongolian: [Mongolian::CHARACTER_TABLE, Mongolian::REGEXP].freeze,
|
|
28
33
|
ukrainian: [Ukrainian::CHARACTER_TABLE, Ukrainian::REGEXP].freeze,
|
|
29
34
|
ua_passport: :ua_passport,
|
|
30
|
-
de: [De::CHARACTER_TABLE, De::REGEXP].freeze
|
|
35
|
+
de: [De::CHARACTER_TABLE, De::REGEXP].freeze,
|
|
36
|
+
serbian: [Serbian::CHARACTER_TABLE, Serbian::REGEXP].freeze,
|
|
37
|
+
gost779b: [Gost779b::CHARACTER_TABLE, Gost779b::REGEXP].freeze,
|
|
38
|
+
bgn_pcgn: [BgnPcgn::CHARACTER_TABLE, BgnPcgn::REGEXP].freeze,
|
|
39
|
+
bulgarian: [Bulgarian::CHARACTER_TABLE, Bulgarian::REGEXP].freeze,
|
|
40
|
+
belarusian: [Belarusian::CHARACTER_TABLE, Belarusian::REGEXP].freeze
|
|
41
|
+
}.freeze
|
|
42
|
+
|
|
43
|
+
def self.build_reverse_mapping(table, extra = {})
|
|
44
|
+
rev = table.reject { |_cyr, lat| lat.nil? || lat.empty? }.to_h { |cyr, lat| [lat, cyr] }
|
|
45
|
+
rev.merge!(extra)
|
|
46
|
+
sorted_keys = rev.keys.sort_by { |key| -key.length }
|
|
47
|
+
[rev.freeze, Regexp.union(sorted_keys).freeze].freeze
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
REVERSE_SCHEMES = {
|
|
51
|
+
iso9: build_reverse_mapping(Iso9::CHARACTER_TABLE),
|
|
52
|
+
serbian: build_reverse_mapping(
|
|
53
|
+
Serbian::CHARACTER_TABLE,
|
|
54
|
+
{ "LJ" => "Љ", "NJ" => "Њ", "DŽ" => "Џ", "DZ" => "Џ", "dz" => "џ" }
|
|
55
|
+
),
|
|
56
|
+
gost779b: build_reverse_mapping(Gost779b::CHARACTER_TABLE),
|
|
57
|
+
bgn_pcgn: build_reverse_mapping(BgnPcgn::CHARACTER_TABLE),
|
|
58
|
+
bulgarian: build_reverse_mapping(Bulgarian::CHARACTER_TABLE),
|
|
59
|
+
belarusian: build_reverse_mapping(Belarusian::CHARACTER_TABLE),
|
|
60
|
+
mongolian: build_reverse_mapping(Mongolian::CHARACTER_TABLE),
|
|
61
|
+
ukrainian: build_reverse_mapping(Ukrainian::CHARACTER_TABLE),
|
|
62
|
+
de: build_reverse_mapping(De::CHARACTER_TABLE),
|
|
63
|
+
cyrillic: build_reverse_mapping(CHARACTER_TABLE),
|
|
64
|
+
default: build_reverse_mapping(CHARACTER_TABLE)
|
|
31
65
|
}.freeze
|
|
32
66
|
|
|
33
67
|
class << self
|
|
34
68
|
# Transliterates Cyrillic text into Roman (Latin) script.
|
|
35
69
|
#
|
|
36
70
|
# @param string [String, #to_s] The text to transliterate.
|
|
37
|
-
# @param to [Symbol, String] The transliteration scheme (:cyrillic, :iso9, :mongolian,
|
|
71
|
+
# @param to [Symbol, String] The transliteration scheme (:cyrillic, :iso9, :mongolian,
|
|
72
|
+
# :ukrainian, :ua_passport, :de, :serbian, :gost779b, :bgn_pcgn, :bulgarian, :belarusian).
|
|
38
73
|
# @return [String] The transliterated Latin script string.
|
|
39
74
|
# @raise [ArgumentError] If the given transliteration scheme is unknown.
|
|
40
75
|
#
|
|
@@ -44,8 +79,8 @@ module Cyrillic
|
|
|
44
79
|
# @example Short alias .t with ISO 9 scheme
|
|
45
80
|
# Cyrillic.t("Кириллица", :iso9) #=> "Kirillica"
|
|
46
81
|
#
|
|
47
|
-
# @example
|
|
48
|
-
# Cyrillic.t("
|
|
82
|
+
# @example Serbian Cyrillic to Latin (Vukovica to Gajica)
|
|
83
|
+
# Cyrillic.t("Љубљана", :serbian) #=> "Ljubljana"
|
|
49
84
|
def transliterate(string = "", to = :cyrillic)
|
|
50
85
|
return "" if string.nil? || string.empty?
|
|
51
86
|
|
|
@@ -62,5 +97,37 @@ module Cyrillic
|
|
|
62
97
|
string.to_s.gsub(regexp, table)
|
|
63
98
|
end
|
|
64
99
|
alias t transliterate
|
|
100
|
+
|
|
101
|
+
# Detransliterates (reverses) Latin script text back into Cyrillic script.
|
|
102
|
+
#
|
|
103
|
+
# @param string [String, #to_s] The Latin script text to detransliterate.
|
|
104
|
+
# @param from [Symbol, String] The scheme to reverse (:iso9, :serbian, :gost779b, etc.).
|
|
105
|
+
# @return [String] The Cyrillic script string.
|
|
106
|
+
# @raise [ArgumentError] If the given scheme is unknown.
|
|
107
|
+
#
|
|
108
|
+
# @example Reverse ISO 9:1995 transliteration
|
|
109
|
+
# Cyrillic.detransliterate("Transliteraciâ", from: :iso9) #=> "Транслитерация"
|
|
110
|
+
#
|
|
111
|
+
# @example Reverse Serbian transliteration (Gajica to Vukovica)
|
|
112
|
+
# Cyrillic.det("Ljubljana", from: :serbian) #=> "Љубљана"
|
|
113
|
+
#
|
|
114
|
+
# @example Reverse GOST 7.79 System B
|
|
115
|
+
# Cyrillic.det("Shhuka", from: :gost779b) #=> "Щука"
|
|
116
|
+
def detransliterate(string = "", scheme = nil, from: nil)
|
|
117
|
+
return "" if string.nil? || string.empty?
|
|
118
|
+
|
|
119
|
+
chosen = from || scheme || :iso9
|
|
120
|
+
scheme_key = chosen.to_s.downcase.to_sym
|
|
121
|
+
scheme_data = REVERSE_SCHEMES[scheme_key]
|
|
122
|
+
unless scheme_data
|
|
123
|
+
available = (REVERSE_SCHEMES.keys - [:default]).map(&:inspect).join(", ")
|
|
124
|
+
raise ArgumentError, "Unknown detransliteration scheme: #{chosen.inspect}. Available schemes: #{available}"
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
table, regexp = scheme_data
|
|
128
|
+
string.to_s.gsub(regexp, table)
|
|
129
|
+
end
|
|
130
|
+
alias det detransliterate
|
|
131
|
+
alias reverse_transliterate detransliterate
|
|
65
132
|
end
|
|
66
133
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cyrillic
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- rovetz
|
|
@@ -9,6 +9,34 @@ bindir: exe
|
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: benchmark
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0'
|
|
19
|
+
type: :development
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: benchmark-ips
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '0'
|
|
33
|
+
type: :development
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '0'
|
|
12
40
|
- !ruby/object:Gem::Dependency
|
|
13
41
|
name: irb
|
|
14
42
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -93,6 +121,20 @@ dependencies:
|
|
|
93
121
|
- - ">="
|
|
94
122
|
- !ruby/object:Gem::Version
|
|
95
123
|
version: '0.22'
|
|
124
|
+
- !ruby/object:Gem::Dependency
|
|
125
|
+
name: yard
|
|
126
|
+
requirement: !ruby/object:Gem::Requirement
|
|
127
|
+
requirements:
|
|
128
|
+
- - ">="
|
|
129
|
+
- !ruby/object:Gem::Version
|
|
130
|
+
version: 0.9.36
|
|
131
|
+
type: :development
|
|
132
|
+
prerelease: false
|
|
133
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
134
|
+
requirements:
|
|
135
|
+
- - ">="
|
|
136
|
+
- !ruby/object:Gem::Version
|
|
137
|
+
version: 0.9.36
|
|
96
138
|
description: Converts Cyrillic text to the Roman (Latin) script
|
|
97
139
|
email:
|
|
98
140
|
- zakbox@gmail.com
|
|
@@ -107,12 +149,18 @@ files:
|
|
|
107
149
|
- LICENSE.txt
|
|
108
150
|
- README.md
|
|
109
151
|
- Rakefile
|
|
152
|
+
- benchmark/run.rb
|
|
110
153
|
- cyrillic.gemspec
|
|
111
154
|
- exe/cyrillic
|
|
112
155
|
- lib/cyrillic.rb
|
|
156
|
+
- lib/cyrillic/belarusian.rb
|
|
157
|
+
- lib/cyrillic/bgn_pcgn.rb
|
|
158
|
+
- lib/cyrillic/bulgarian.rb
|
|
113
159
|
- lib/cyrillic/de.rb
|
|
160
|
+
- lib/cyrillic/gost779b.rb
|
|
114
161
|
- lib/cyrillic/iso9.rb
|
|
115
162
|
- lib/cyrillic/mongolian.rb
|
|
163
|
+
- lib/cyrillic/serbian.rb
|
|
116
164
|
- lib/cyrillic/ua_passport.rb
|
|
117
165
|
- lib/cyrillic/ukrainian.rb
|
|
118
166
|
- lib/cyrillic/version.rb
|
|
@@ -123,6 +171,7 @@ metadata:
|
|
|
123
171
|
source_code_uri: https://github.com/rovetz/cyrillic
|
|
124
172
|
changelog_uri: https://github.com/rovetz/cyrillic/blob/main/CHANGELOG.md
|
|
125
173
|
bug_tracker_uri: https://github.com/rovetz/cyrillic/issues
|
|
174
|
+
documentation_uri: https://rovetz.github.io/cyrillic/
|
|
126
175
|
rubygems_mfa_required: 'true'
|
|
127
176
|
rdoc_options: []
|
|
128
177
|
require_paths:
|