lingua_rs 0.4.5 → 0.6.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/README.md +99 -14
- data/Rakefile +6 -0
- data/exe/lingua +125 -0
- data/ext/lingua/src/detector.rs +71 -0
- data/lib/lingua/version.rb +1 -1
- metadata +6 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5c97528f5d90b92214436ba9938f56a4ffde0d9997081b896d80eed180ebe59a
|
|
4
|
+
data.tar.gz: 147e2bca0a928e18b23027f323ac2a297ccbb5c3480e178cc7054f3c1fc230d1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f29859f59b455c0672c8411ab269c78e95b501a350a29dfc5d0966204e593b26aa36268f8c895aeb066962bf7d1d15a75b6ca3bbf576d3074b3b3d34bc393e03
|
|
7
|
+
data.tar.gz: e5320aba0f339e3d6e8ac92a1fff314a0946dd5713fe5e335f057601a97159ffa031b761eace762859180b786670370d94281903ac1c9d96b60e970e959a31ba
|
data/README.md
CHANGED
|
@@ -25,7 +25,7 @@ Then run `bundle install`.
|
|
|
25
25
|
|
|
26
26
|
### Build requirements
|
|
27
27
|
|
|
28
|
-
A Rust toolchain is required to compile the native extension.
|
|
28
|
+
A Rust toolchain (**1.87+**) is required to compile the native extension.
|
|
29
29
|
|
|
30
30
|
## Usage
|
|
31
31
|
|
|
@@ -66,8 +66,6 @@ Lingua.detect('Bonjour', languages: %w[en french deu])
|
|
|
66
66
|
|
|
67
67
|
### Options
|
|
68
68
|
|
|
69
|
-
All options accept both symbol and string keys.
|
|
70
|
-
|
|
71
69
|
| Option | Type | Description |
|
|
72
70
|
|---|---|---|
|
|
73
71
|
| `languages` | `Array<String>` | Restrict detection to these languages (names, ISO 639-1 or ISO 639-3 codes) |
|
|
@@ -132,7 +130,61 @@ detector = Lingua::Detector.new(languages: %w[en fr de])
|
|
|
132
130
|
detector.detect_multiple(text)
|
|
133
131
|
```
|
|
134
132
|
|
|
135
|
-
###
|
|
133
|
+
### Parallel batch detection
|
|
134
|
+
|
|
135
|
+
`Lingua::Detector` provides batch methods that process multiple texts in parallel using [Rayon](https://github.com/rayon-rs/rayon). These are significantly faster than calling single-text methods in a loop.
|
|
136
|
+
|
|
137
|
+
```ruby
|
|
138
|
+
detector = Lingua::Detector.new(languages: %w[en fr de])
|
|
139
|
+
|
|
140
|
+
# Detect language of multiple texts
|
|
141
|
+
detector.detect_batch(['Bonjour le monde', 'Hello world', 'Hallo Welt'])
|
|
142
|
+
# => [#<Lingua::Language French>, #<Lingua::Language English>, #<Lingua::Language German>]
|
|
143
|
+
|
|
144
|
+
# Confidence for a specific language across multiple texts
|
|
145
|
+
detector.confidence_batch(['Bonjour le monde', 'Hello world'], :fr)
|
|
146
|
+
# => [0.8217, 0.0215]
|
|
147
|
+
|
|
148
|
+
# Confidence values for multiple texts
|
|
149
|
+
detector.confidence_values_batch(['Bonjour le monde', 'Hello world'])
|
|
150
|
+
# => [[#<Lingua::ConfidenceResult French (0.82)>, ...], [#<Lingua::ConfidenceResult English (0.91)>, ...]]
|
|
151
|
+
|
|
152
|
+
# Mixed-language detection on multiple texts
|
|
153
|
+
detector.detect_multiple_batch(['Bonjour le monde. Hello world.', 'Ich bin müde. Salut tout le monde.'])
|
|
154
|
+
# => [[#<Lingua::Segment French ...>, #<Lingua::Segment English ...>], [#<Lingua::Segment German ...>, #<Lingua::Segment French ...>]]
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
| Method | Return type | Description |
|
|
158
|
+
|---|---|---|
|
|
159
|
+
| `detect_batch(texts)` | `Array<Language\|nil>` | Detect language of each text |
|
|
160
|
+
| `confidence_batch(texts, language)` | `Array<Float>` | Confidence for a specific language across texts |
|
|
161
|
+
| `confidence_values_batch(texts)` | `Array<Array<ConfidenceResult>>` | Confidence values for each text |
|
|
162
|
+
| `detect_multiple_batch(texts)` | `Array<Array<Segment>>` | Mixed-language detection for each text |
|
|
163
|
+
|
|
164
|
+
Results are returned in the same order as the input, so you can pair them with `zip`:
|
|
165
|
+
|
|
166
|
+
```ruby
|
|
167
|
+
texts = ['Bonjour le monde', 'Hello world', 'Hallo Welt']
|
|
168
|
+
texts.zip(detector.detect_batch(texts)) do |text, language|
|
|
169
|
+
puts "#{text} => #{language}"
|
|
170
|
+
end
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Error handling
|
|
174
|
+
|
|
175
|
+
`Lingua::UnknownLanguageError` (subclass of `ArgumentError`) is raised when an unrecognized language name or code is passed:
|
|
176
|
+
|
|
177
|
+
```ruby
|
|
178
|
+
begin
|
|
179
|
+
Lingua.detect('Hello', languages: %w[en zzzz])
|
|
180
|
+
rescue Lingua::UnknownLanguageError => e
|
|
181
|
+
puts e.message # => unknown language: "zzzz"
|
|
182
|
+
end
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## API Reference
|
|
186
|
+
|
|
187
|
+
### `Lingua::Language`
|
|
136
188
|
|
|
137
189
|
`Lingua::Language` objects support equality (`==`) and can be used as Hash keys. You can look up a language by name, ISO 639-1 code, or ISO 639-3 code using `[]`:
|
|
138
190
|
|
|
@@ -163,7 +215,7 @@ Lingua::Language['xxx'] # => nil
|
|
|
163
215
|
| `==` | `Boolean` | Compare two languages |
|
|
164
216
|
| `hash` | `Integer` | Hash value (usable as Hash key) |
|
|
165
217
|
|
|
166
|
-
### `Lingua::ConfidenceResult`
|
|
218
|
+
### `Lingua::ConfidenceResult`
|
|
167
219
|
|
|
168
220
|
Returned by `confidence_values`.
|
|
169
221
|
|
|
@@ -174,7 +226,7 @@ Returned by `confidence_values`.
|
|
|
174
226
|
| `to_s` | `String` | `'French (0.82)'` |
|
|
175
227
|
| `inspect` | `String` | `'#<Lingua::ConfidenceResult French (0.8217)>'` |
|
|
176
228
|
|
|
177
|
-
### `Lingua::Segment`
|
|
229
|
+
### `Lingua::Segment`
|
|
178
230
|
|
|
179
231
|
Returned by `detect_multiple`.
|
|
180
232
|
|
|
@@ -188,18 +240,49 @@ Returned by `detect_multiple`.
|
|
|
188
240
|
| `to_s` | `String` | `'French (0-22): Parlez-vous français? '` |
|
|
189
241
|
| `inspect` | `String` | `'#<Lingua::Segment French (0-22) "Parlez-vous français? ">'` |
|
|
190
242
|
|
|
191
|
-
|
|
243
|
+
## Command-line tool
|
|
192
244
|
|
|
193
|
-
|
|
245
|
+
The gem ships with a `lingua` executable that wraps the library for shell use.
|
|
194
246
|
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
247
|
+
```bash
|
|
248
|
+
# Text as argument or on stdin
|
|
249
|
+
lingua 'Bonjour le monde' # => French
|
|
250
|
+
echo 'Hello world' | lingua # => English
|
|
251
|
+
|
|
252
|
+
# Output format
|
|
253
|
+
lingua -f iso 'Bonjour le monde' # => fr
|
|
254
|
+
lingua -f iso6393 'Bonjour le monde' # => fra
|
|
255
|
+
lingua -f json 'Bonjour le monde' # => {"name":"French","iso":"fr","iso6393":"fra"}
|
|
256
|
+
|
|
257
|
+
# Confidence values
|
|
258
|
+
lingua -c -l en,fr,de 'Bonjour le monde'
|
|
259
|
+
# French: 0.8217
|
|
260
|
+
# German: 0.1216
|
|
261
|
+
# English: 0.0567
|
|
262
|
+
|
|
263
|
+
# Mixed-language detection
|
|
264
|
+
lingua -m -l en,fr,de 'Parlez-vous français? Hello world.'
|
|
265
|
+
# French (0-22): Parlez-vous français?
|
|
266
|
+
# English (22-34): Hello world.
|
|
267
|
+
|
|
268
|
+
# Restrict candidates
|
|
269
|
+
lingua -l en,fr,de 'Bonjour'
|
|
270
|
+
|
|
271
|
+
# Batch: one text per line (use "-" for stdin)
|
|
272
|
+
lingua --batch texts.txt
|
|
273
|
+
cat texts.txt | lingua --batch -
|
|
201
274
|
```
|
|
202
275
|
|
|
276
|
+
| Option | Description |
|
|
277
|
+
|---|---|
|
|
278
|
+
| `-f`, `--format FORMAT` | Output format: `name` (default), `iso`, `iso6393`, `json` |
|
|
279
|
+
| `-c`, `--confidences` | Output confidence for all candidate languages |
|
|
280
|
+
| `-m`, `--multiple` | Detect multiple languages within the text |
|
|
281
|
+
| `-l`, `--languages LIST` | Comma-separated list of languages (names or ISO codes) |
|
|
282
|
+
| `--batch FILE` | Treat each line of FILE (or `-` for stdin) as a separate input |
|
|
283
|
+
| `-v`, `--version` | Show version |
|
|
284
|
+
| `-h`, `--help` | Show help |
|
|
285
|
+
|
|
203
286
|
## Optimization: selecting languages
|
|
204
287
|
|
|
205
288
|
By default, all 75 languages are compiled into the native extension (~278 MB). If you only need a subset, select languages at build time to reduce binary size and improve detection speed.
|
|
@@ -266,6 +349,8 @@ Supported languages (from [Lingua Rust's official list](https://github.com/pemis
|
|
|
266
349
|
|
|
267
350
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake compile` to build the native extension and `rake test` to run the tests.
|
|
268
351
|
|
|
352
|
+
To run benchmarks (sequential vs batch performance comparison): `rake bench`
|
|
353
|
+
|
|
269
354
|
## Acknowledgements
|
|
270
355
|
|
|
271
356
|
This gem is built on top of [Lingua](https://github.com/pemistahl/lingua-rs) by [Peter M. Stahl](https://github.com/pemistahl), a highly accurate natural language detection library written in Rust.
|
data/Rakefile
CHANGED
|
@@ -19,4 +19,10 @@ RbSys::ExtensionTask.new('lingua', GEMSPEC) do |ext|
|
|
|
19
19
|
ext.lib_dir = 'lib/lingua'
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
desc 'Run benchmarks (sequential vs batch)'
|
|
23
|
+
task bench: :compile do
|
|
24
|
+
ENV['BENCH'] = '1'
|
|
25
|
+
ruby '-Itest', 'test/test_benchmark.rb'
|
|
26
|
+
end
|
|
27
|
+
|
|
22
28
|
task default: %i[compile test rubocop]
|
data/exe/lingua
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'optparse'
|
|
5
|
+
require 'json'
|
|
6
|
+
require 'lingua'
|
|
7
|
+
|
|
8
|
+
def build_parser(options)
|
|
9
|
+
OptionParser.new do |opts|
|
|
10
|
+
opts.banner = 'Usage: lingua [options] [TEXT]'
|
|
11
|
+
opts.separator ''
|
|
12
|
+
opts.separator 'If TEXT is omitted, input is read from stdin.'
|
|
13
|
+
opts.separator ''
|
|
14
|
+
opts.separator 'Options:'
|
|
15
|
+
|
|
16
|
+
opts.on('-f', '--format FORMAT', %w[iso iso6393 name json],
|
|
17
|
+
'Output format: name (default), iso, iso6393, json') { |f| options[:format] = f.to_sym }
|
|
18
|
+
opts.on('-c', '--confidences',
|
|
19
|
+
'Output confidence values for all candidate languages') { options[:mode] = :confidences }
|
|
20
|
+
opts.on('-m', '--multiple',
|
|
21
|
+
'Detect multiple languages within the text') { options[:mode] = :multiple }
|
|
22
|
+
opts.on('-l', '--languages LIST',
|
|
23
|
+
'Restrict detection to comma-separated languages (names or ISO codes)') do |list|
|
|
24
|
+
options[:languages] = list.split(',').map(&:strip)
|
|
25
|
+
end
|
|
26
|
+
opts.on('--batch FILE',
|
|
27
|
+
'Treat each line of FILE (or "-" for stdin) as a separate input') { |f| options[:batch] = f }
|
|
28
|
+
opts.on('-h', '--help', 'Show this help') do
|
|
29
|
+
puts opts
|
|
30
|
+
exit
|
|
31
|
+
end
|
|
32
|
+
opts.on('-v', '--version', 'Show version') do
|
|
33
|
+
puts Lingua::VERSION
|
|
34
|
+
exit
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
options = { format: :name, mode: :detect, languages: nil, batch: nil }
|
|
40
|
+
build_parser(options).parse!
|
|
41
|
+
|
|
42
|
+
def format_language(lang, format)
|
|
43
|
+
return nil if lang.nil?
|
|
44
|
+
|
|
45
|
+
case format
|
|
46
|
+
when :iso then lang.to_iso
|
|
47
|
+
when :iso6393 then lang.to_iso6393
|
|
48
|
+
when :name then lang.name
|
|
49
|
+
when :json then { name: lang.name, iso: lang.to_iso, iso6393: lang.to_iso6393 }
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def render_detect(lang, format)
|
|
54
|
+
formatted = format_language(lang, format)
|
|
55
|
+
if format == :json
|
|
56
|
+
JSON.generate(formatted)
|
|
57
|
+
else
|
|
58
|
+
formatted.to_s
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def render_confidences(results, format)
|
|
63
|
+
if format == :json
|
|
64
|
+
JSON.generate(results.map do |r|
|
|
65
|
+
{ language: format_language(r.language, :iso), confidence: r.confidence }
|
|
66
|
+
end)
|
|
67
|
+
else
|
|
68
|
+
results.map { |r| "#{format_language(r.language, format)}: #{format('%.4f', r.confidence)}" }
|
|
69
|
+
.join("\n")
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def render_multiple(segments, format)
|
|
74
|
+
if format == :json
|
|
75
|
+
JSON.generate(segments.map do |s|
|
|
76
|
+
{ language: format_language(s.language, :iso),
|
|
77
|
+
start_index: s.start_index,
|
|
78
|
+
end_index: s.end_index,
|
|
79
|
+
text: s.text }
|
|
80
|
+
end)
|
|
81
|
+
else
|
|
82
|
+
segments.map do |s|
|
|
83
|
+
"#{format_language(s.language, format)} (#{s.start_index}-#{s.end_index}): #{s.text}"
|
|
84
|
+
end.join("\n")
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def process(text, detector, options)
|
|
89
|
+
case options[:mode]
|
|
90
|
+
when :detect
|
|
91
|
+
render_detect(detector.detect(text), options[:format])
|
|
92
|
+
when :confidences
|
|
93
|
+
render_confidences(detector.confidence_values(text), options[:format])
|
|
94
|
+
when :multiple
|
|
95
|
+
render_multiple(detector.detect_multiple(text), options[:format])
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
begin
|
|
100
|
+
detector_options = {}
|
|
101
|
+
detector_options[:languages] = options[:languages] if options[:languages]
|
|
102
|
+
detector = Lingua::Detector.new(**detector_options)
|
|
103
|
+
|
|
104
|
+
if options[:batch]
|
|
105
|
+
io = options[:batch] == '-' ? $stdin : File.open(options[:batch], 'r')
|
|
106
|
+
io.each_line do |line|
|
|
107
|
+
line = line.chomp
|
|
108
|
+
next if line.empty?
|
|
109
|
+
|
|
110
|
+
puts process(line, detector, options)
|
|
111
|
+
end
|
|
112
|
+
io.close unless io == $stdin
|
|
113
|
+
else
|
|
114
|
+
text = ARGV.empty? ? $stdin.read : ARGV.join(' ')
|
|
115
|
+
text = text.strip
|
|
116
|
+
if text.empty?
|
|
117
|
+
warn 'lingua: no input text'
|
|
118
|
+
exit 1
|
|
119
|
+
end
|
|
120
|
+
puts process(text, detector, options)
|
|
121
|
+
end
|
|
122
|
+
rescue Lingua::UnknownLanguageError => e
|
|
123
|
+
warn "lingua: #{e.message}"
|
|
124
|
+
exit 1
|
|
125
|
+
end
|
data/ext/lingua/src/detector.rs
CHANGED
|
@@ -13,6 +13,10 @@ pub fn define(ruby: &Ruby, module: &RModule) -> Result<(), Error> {
|
|
|
13
13
|
class.define_method("confidence", method!(RubyDetector::confidence, 2))?;
|
|
14
14
|
class.define_method("confidence_values", method!(RubyDetector::confidence_values, 1))?;
|
|
15
15
|
class.define_method("detect_multiple", method!(RubyDetector::detect_multiple, 1))?;
|
|
16
|
+
class.define_method("detect_batch", method!(RubyDetector::detect_batch, 1))?;
|
|
17
|
+
class.define_method("detect_multiple_batch", method!(RubyDetector::detect_multiple_batch, 1))?;
|
|
18
|
+
class.define_method("confidence_values_batch", method!(RubyDetector::confidence_values_batch, 1))?;
|
|
19
|
+
class.define_method("confidence_batch", method!(RubyDetector::confidence_batch, 2))?;
|
|
16
20
|
Ok(())
|
|
17
21
|
}
|
|
18
22
|
|
|
@@ -81,6 +85,73 @@ impl RubyDetector {
|
|
|
81
85
|
pub fn detect_multiple(&self, subject: String) -> Result<RArray, Error> {
|
|
82
86
|
compute_detect_multiple(&self.detector, &subject)
|
|
83
87
|
}
|
|
88
|
+
|
|
89
|
+
pub fn detect_batch(&self, texts: Vec<String>) -> Result<RArray, Error> {
|
|
90
|
+
let ruby = Ruby::get().unwrap();
|
|
91
|
+
let results = self.detector.detect_languages_in_parallel_of(&texts);
|
|
92
|
+
let array = ruby.ary_new_capa(results.len());
|
|
93
|
+
for result in results {
|
|
94
|
+
array.push(result.map(WrappedLanguage))?;
|
|
95
|
+
}
|
|
96
|
+
Ok(array)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
pub fn detect_multiple_batch(&self, texts: Vec<String>) -> Result<RArray, Error> {
|
|
100
|
+
let ruby = Ruby::get().unwrap();
|
|
101
|
+
let results = self.detector.detect_multiple_languages_in_parallel_of(&texts);
|
|
102
|
+
let outer = ruby.ary_new_capa(results.len());
|
|
103
|
+
for (detection_results, subject) in results.iter().zip(texts.iter()) {
|
|
104
|
+
let inner = ruby.ary_new_capa(detection_results.len());
|
|
105
|
+
for r in detection_results {
|
|
106
|
+
let text = subject[r.start_index()..r.end_index()].to_string();
|
|
107
|
+
let start_index = subject[..r.start_index()].chars().count();
|
|
108
|
+
let end_index = start_index + text.chars().count();
|
|
109
|
+
inner.push(Segment {
|
|
110
|
+
language: r.language(),
|
|
111
|
+
start_index,
|
|
112
|
+
end_index,
|
|
113
|
+
word_count: r.word_count(),
|
|
114
|
+
text,
|
|
115
|
+
})?;
|
|
116
|
+
}
|
|
117
|
+
outer.push(inner)?;
|
|
118
|
+
}
|
|
119
|
+
Ok(outer)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
pub fn confidence_values_batch(&self, texts: Vec<String>) -> Result<RArray, Error> {
|
|
123
|
+
let ruby = Ruby::get().unwrap();
|
|
124
|
+
let results = self.detector.compute_language_confidence_values_in_parallel(&texts);
|
|
125
|
+
let outer = ruby.ary_new_capa(results.len());
|
|
126
|
+
for values in results {
|
|
127
|
+
let inner = ruby.ary_new_capa(values.len());
|
|
128
|
+
for (language, confidence) in values {
|
|
129
|
+
inner.push(ConfidenceResult {
|
|
130
|
+
language,
|
|
131
|
+
confidence,
|
|
132
|
+
})?;
|
|
133
|
+
}
|
|
134
|
+
outer.push(inner)?;
|
|
135
|
+
}
|
|
136
|
+
Ok(outer)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
pub fn confidence_batch(&self, texts: Vec<String>, language: magnus::Value) -> Result<RArray, Error> {
|
|
140
|
+
let ruby = Ruby::get().unwrap();
|
|
141
|
+
let language_str = value_to_string(language)?;
|
|
142
|
+
let lang = parse_language(&language_str).ok_or_else(|| {
|
|
143
|
+
Error::new(
|
|
144
|
+
unknown_language_error(&ruby),
|
|
145
|
+
format!("unknown language: \"{language_str}\""),
|
|
146
|
+
)
|
|
147
|
+
})?;
|
|
148
|
+
let results = self.detector.compute_language_confidence_in_parallel(&texts, lang);
|
|
149
|
+
let array = ruby.ary_new_capa(results.len());
|
|
150
|
+
for score in results {
|
|
151
|
+
array.push(score)?;
|
|
152
|
+
}
|
|
153
|
+
Ok(array)
|
|
154
|
+
}
|
|
84
155
|
}
|
|
85
156
|
|
|
86
157
|
pub fn compute_detect_multiple(
|
data/lib/lingua/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lingua_rs
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sébastien Vrillaud
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-04-
|
|
10
|
+
date: 2026-04-20 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: rb_sys
|
|
@@ -42,7 +42,8 @@ description: Native Ruby bindings for the Lingua Rust library, bringing highly a
|
|
|
42
42
|
scores and ISO 639-1/639-3 language codes.
|
|
43
43
|
email:
|
|
44
44
|
- kochka@gmail.com
|
|
45
|
-
executables:
|
|
45
|
+
executables:
|
|
46
|
+
- lingua
|
|
46
47
|
extensions:
|
|
47
48
|
- ext/lingua/extconf.rb
|
|
48
49
|
extra_rdoc_files: []
|
|
@@ -50,6 +51,7 @@ files:
|
|
|
50
51
|
- LICENSE.txt
|
|
51
52
|
- README.md
|
|
52
53
|
- Rakefile
|
|
54
|
+
- exe/lingua
|
|
53
55
|
- ext/lingua/Cargo.toml
|
|
54
56
|
- ext/lingua/extconf.rb
|
|
55
57
|
- ext/lingua/src/confidence_result.rs
|
|
@@ -84,7 +86,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
84
86
|
- !ruby/object:Gem::Version
|
|
85
87
|
version: '0'
|
|
86
88
|
requirements: []
|
|
87
|
-
rubygems_version: 4.0.
|
|
89
|
+
rubygems_version: 4.0.10
|
|
88
90
|
specification_version: 4
|
|
89
91
|
summary: High-accuracy language detection powered by Lingua (Rust).
|
|
90
92
|
test_files: []
|