whatlanguage 2.0.0 → 2.1.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 +20 -0
- data/README.md +38 -9
- data/exe/whatlanguage +8 -0
- data/lib/whatlanguage/version.rb +1 -1
- data/lib/whatlanguage.rb +42 -54
- data/whatlanguage.gemspec +3 -0
- metadata +5 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4707fce379ca4e085886aef33b8bd45f3480c79bd93c1a7d040c068aff16a94c
|
|
4
|
+
data.tar.gz: e4b0156f7d3ee2dda4efb77cd2cd8c6abd6f96eac8c27d821166f927fe7421e6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fa04498461b8e07de91debf3ddf5ebece5d701a2006fe45a08a0baa7f1d8e7947a1c90fa726b175cbe08a3201ac510041f3f952f4b89abfd61ba0d42de0e5c77
|
|
7
|
+
data.tar.gz: 7f2ba53f9248b9f8559c06758205874b61a624c485a1e6bad02f5d192a5a93e09ae38018c73a5ac46bc93dc9e742a648757b6e00fc75ed12698588530f0124a9
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.1.0 / 2026-09-05
|
|
4
|
+
|
|
5
|
+
- Added a fixed short-text preference for English, Chinese, Hindi, Spanish, and
|
|
6
|
+
French: a 600-point trigram bonus through 10 letters, fading to zero at 50.
|
|
7
|
+
Script routing, candidate restrictions, and minimum-length rules still apply.
|
|
8
|
+
- Replaced hard-coded ranges with Unicode script properties, recognizing
|
|
9
|
+
uppercase Georgian, extended Greek, and supplementary Han letters.
|
|
10
|
+
- Combined Han and kana when detecting Japanese instead of misclassifying
|
|
11
|
+
Han-heavy Japanese text as Chinese.
|
|
12
|
+
- Excluded digits, punctuation, and emoji from script votes and minimum-length
|
|
13
|
+
counting, and treated them as trigram separators while preserving combining marks.
|
|
14
|
+
- Added regression coverage for short texts and Unicode handling. Short-text
|
|
15
|
+
preferences are a heuristic; ambiguous fragments can still be misclassified.
|
|
16
|
+
|
|
17
|
+
## 2.0.1 / 2026-07-11
|
|
18
|
+
|
|
19
|
+
- Added a `whatlanguage` command-line executable that reads from files given as
|
|
20
|
+
arguments (or stdin) and prints the ISO 639 code of the detected language, or
|
|
21
|
+
`und` if undetermined. (#50, suggested by Keith Bennett)
|
|
22
|
+
|
|
3
23
|
## 2.0.0 / 2026-06-10
|
|
4
24
|
|
|
5
25
|
- Rewrote the detection engine from scratch. Bloom-filter dictionary lookups are
|
data/README.md
CHANGED
|
@@ -13,17 +13,25 @@ WhatLanguage.language("Que linguagem é essa? É uma pergunta sobre a língua po
|
|
|
13
13
|
- No runtime dependencies.
|
|
14
14
|
- Supports 20+ writing systems.
|
|
15
15
|
- Ships a compact ~220 KB trigram model.
|
|
16
|
-
- Requires Ruby 3.0+
|
|
17
|
-
- Best on sentence-length text or longer.
|
|
16
|
+
- Requires Ruby 3.0+ (JRuby and TruffleRuby also good)
|
|
17
|
+
- **Best on sentence-length text or longer.** Short texts can have ambiguous results.
|
|
18
|
+
|
|
19
|
+
> [!IMPORTANT]
|
|
20
|
+
> v2.0 has many breaking changes as the entire library has been reimplemented, though the core `WhatLanguage.language` API remains similar. Versions 1.0.6 and earlier (so the 2007-2025 run of the library) used a Bloom-filter technique and had 5MB of binary files to handle ~20 languages. Version 2.0 is more accurate, faster, and supports more languages from a single 220KB JSON file :-)
|
|
18
21
|
|
|
19
22
|
## How it works
|
|
20
23
|
|
|
21
|
-
|
|
24
|
+
> [!NOTE]
|
|
25
|
+
> Version 2.1 improves Unicode and mixed-script Japanese handling and adds a fixed
|
|
26
|
+
> preference for five widely spoken languages on short texts. The public API and
|
|
27
|
+
> default 10-letter minimum for statistical detection are unchanged.
|
|
28
|
+
|
|
29
|
+
Detection is in two stages. First, the dominant Unicode script is detected from letters; scripts used by a single supported language (Greek, Korean, Thai, Japanese using Hiragana/Katakana) resolve immediately. When kana is present, Han, Hiragana, and Katakana count together as Japanese, while a dominant unrelated script can still win. For scripts shared by several languages (e.g. Latin, Cyrillic, Arabic, Hebrew) trigrams are ranked by frequency and compared against candidate language profiles.
|
|
30
|
+
|
|
31
|
+
Digits, punctuation, and emoji do not count toward the minimum text length and are treated as separators when extracting trigrams. Combining marks are preserved in trigrams but do not count as additional letters. Unicode script coverage follows the Unicode version supported by your Ruby runtime.
|
|
22
32
|
|
|
23
33
|
The trigram profiles are vendored from [whatlang](https://github.com/greyblake/whatlang-rs), a port of [Franc](https://github.com/wooorm/franc), whose models are built from the public-domain UDHR corpus (see Credits). The model is a ~220 KB JSON file.
|
|
24
34
|
|
|
25
|
-
> [!IMPORTANT]
|
|
26
|
-
> v2.0 has many breaking changes as the entire library has been rewritten, though the core `WhatLanguage.language` API remains similar. Versions 1.0.6 and earlier (so the 2007-2025 run of the library) used a Bloom-filter technique and had 5MB of binary files to handle ~20 languages. Version 2.0 is more accurate, faster, and supports more languages from a single 220KB JSON file :-)
|
|
27
35
|
|
|
28
36
|
## Usage
|
|
29
37
|
|
|
@@ -39,7 +47,7 @@ result.score # => 79018
|
|
|
39
47
|
result.ranked # => [[:german, 79018], [:dutch, 77631], ... ]
|
|
40
48
|
```
|
|
41
49
|
|
|
42
|
-
Return ranked scores, or the
|
|
50
|
+
Return ranked scores, or the score hash:
|
|
43
51
|
|
|
44
52
|
```ruby
|
|
45
53
|
wl.ranked(text) # => [[:german, 79018], [:dutch, 77631], ... ]
|
|
@@ -52,15 +60,36 @@ Restrict candidate languages:
|
|
|
52
60
|
wl = WhatLanguage.new(only: [:english, :german, :french])
|
|
53
61
|
```
|
|
54
62
|
|
|
55
|
-
|
|
63
|
+
For short texts, English, Chinese (Mandarin), Hindi, Spanish, and French receive
|
|
64
|
+
a built-in preference. These five were selected using the
|
|
65
|
+
[2025 total-speaker ranking](https://www.visualcapitalist.com/ranked-the-worlds-most-spoken-languages-in-2025/)
|
|
66
|
+
(including second-language speakers). Eligible trigram candidates receive the
|
|
67
|
+
same bonus: 600 ranking points through 10 letters, decreasing linearly to zero
|
|
68
|
+
at 50 letters. Longer texts keep their original scores. The preference is not
|
|
69
|
+
configurable; it respects `only:` and script detection. Chinese already resolves
|
|
70
|
+
from its script, so it does not need a statistical bonus. Scores exposed by the
|
|
71
|
+
API include the bonus and remain ranking values, not probabilities.
|
|
72
|
+
|
|
73
|
+
Short shared-script fragments are ignored by default because there is not enough signal to rank their languages reliably. The threshold applies to the statistical trigram stage; scripts that identify a single supported language, such as Greek, Korean, or Thai, can still resolve from shorter text. The threshold can be adjusted:
|
|
56
74
|
|
|
57
75
|
```ruby
|
|
58
76
|
wl = WhatLanguage.new(min_chars: 0)
|
|
59
77
|
```
|
|
60
78
|
|
|
79
|
+
## Command line
|
|
80
|
+
|
|
81
|
+
Installing the gem also installs a `whatlanguage` executable that reads from files given as arguments (or stdin) and prints the ISO 639 code of the detected language, or `und` if undetermined:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
$ whatlanguage README.md
|
|
85
|
+
en
|
|
86
|
+
$ echo "Wie geht es dir heute?" | whatlanguage
|
|
87
|
+
de
|
|
88
|
+
```
|
|
89
|
+
|
|
61
90
|
## Known limitations
|
|
62
91
|
|
|
63
|
-
- Short fragments
|
|
92
|
+
- Short fragments remain unreliable. For languages resolved by statistical comparison, fewer than 10 letters returns `nil` by default. The built-in preference helps some common phrases, but can also favor a preferred language over a less widely spoken one when evidence is weak. It does not lower the minimum length.
|
|
64
93
|
- Scores are relative ranking values, not probabilities. Use `#ranked` or `#detect.ranked` when close runners-up matter.
|
|
65
94
|
- Closely related written languages can be hard to separate, especially Norwegian Bokmål/Danish, Hebrew/Yiddish, and similar language pairs.
|
|
66
95
|
- Kanji-only Japanese text can classify as Chinese because Han characters alone do not identify the language.
|
|
@@ -68,6 +97,6 @@ wl = WhatLanguage.new(min_chars: 0)
|
|
|
68
97
|
|
|
69
98
|
## Credits
|
|
70
99
|
|
|
71
|
-
Contributions from Konrad Reiche, Salimane Adjao Moustapha, Andrew Cone, Lasse Skindstad Ebert, Henrik Nyh, Daniel Sandbecker, Michael Hartl, Pedro Lambert, Tobias Preuss, Pepijn Looije, and others appreciated.
|
|
100
|
+
Contributions from Konrad Reiche, Salimane Adjao Moustapha, Andrew Cone, Lasse Skindstad Ebert, Henrik Nyh, Daniel Sandbecker, Michael Hartl, Pedro Lambert, Tobias Preuss, Pepijn Looije, Keith Bennett, and others appreciated.
|
|
72
101
|
|
|
73
102
|
The trigram language profiles in `lib/whatlanguage/trigrams.json` are taken from [whatlang](https://github.com/greyblake/whatlang-rs) (MIT, © Sergey Potapov), itself a derivative of [Franc](https://github.com/wooorm/franc) (MIT, © Titus Wormer). Those profiles are derived from the public-domain Universal Declaration of Human Rights translations.
|
data/exe/whatlanguage
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'whatlanguage'
|
|
5
|
+
|
|
6
|
+
# Reads from files given as arguments, or stdin otherwise. Prints the ISO 639
|
|
7
|
+
# code of the detected language, or "und" (undetermined) if detection fails.
|
|
8
|
+
puts WhatLanguage.language_iso(ARGF.read) || 'und'
|
data/lib/whatlanguage/version.rb
CHANGED
data/lib/whatlanguage.rb
CHANGED
|
@@ -9,12 +9,15 @@ class WhatLanguage
|
|
|
9
9
|
MAX_TOTAL_DISTANCE = MAX_TRIGRAM_DISTANCE * MAX_TRIGRAM_DISTANCE # 90_000
|
|
10
10
|
TEXT_TRIGRAMS_SIZE = 600
|
|
11
11
|
DEFAULT_MIN_CHARS = 10
|
|
12
|
+
SHORT_TEXT_PREFERENCES = %i[english chinese hindi spanish french].freeze
|
|
13
|
+
SHORT_TEXT_BONUS = 600
|
|
14
|
+
SHORT_TEXT_FADE_CHARS = 50
|
|
12
15
|
|
|
13
16
|
Result = Struct.new(:language, :iso, :score, :ranked, keyword_init: true) do
|
|
14
17
|
alias scores ranked
|
|
15
18
|
end
|
|
16
19
|
|
|
17
|
-
# Scripts that resolve to a single language
|
|
20
|
+
# Scripts that resolve to a single supported language from their letters.
|
|
18
21
|
# (Hiragana and Katakana both indicate Japanese.) Scripts NOT listed here but
|
|
19
22
|
# present in the trigram dataset are disambiguated statistically instead.
|
|
20
23
|
DETERMINISTIC = {
|
|
@@ -27,43 +30,13 @@ class WhatLanguage
|
|
|
27
30
|
'Katakana' => 'jpn'
|
|
28
31
|
}.freeze
|
|
29
32
|
|
|
30
|
-
# Unicode
|
|
31
|
-
#
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
['Cyrillic', [[0x400,0x484],[0x487,0x52F],[0x2DE0,0x2DFF],[0xA640,0xA69D],
|
|
38
|
-
[0x1D2B,0x1D2B],[0x1D78,0x1D78],[0xA69F,0xA69F]]],
|
|
39
|
-
['Arabic', [[0x600,0x6FF],[0x750,0x7FF],[0x8A0,0x8FF],[0xFB50,0xFDFF],
|
|
40
|
-
[0xFE70,0xFEFF],[0x10E60,0x10E7F],[0x1EE00,0x1EEFF]]],
|
|
41
|
-
['Mandarin', [[0x2E80,0x2E99],[0x2E9B,0x2EF3],[0x2F00,0x2FD5],[0x3005,0x3005],
|
|
42
|
-
[0x3007,0x3007],[0x3021,0x3029],[0x3038,0x303B],[0x3400,0x4DB5],
|
|
43
|
-
[0x4E00,0x9FCC],[0xF900,0xFA6D],[0xFA70,0xFAD9]]],
|
|
44
|
-
['Devanagari', [[0x900,0x97F],[0xA8E0,0xA8FF],[0x1CD0,0x1CFF]]],
|
|
45
|
-
['Hebrew', [[0x590,0x5FF]]],
|
|
46
|
-
['Ethiopic', [[0x1200,0x139F],[0x2D80,0x2DDF],[0xAB00,0xAB2F]]],
|
|
47
|
-
['Georgian', [[0x10A0,0x10FF]]],
|
|
48
|
-
['Bengali', [[0x980,0x9FF]]],
|
|
49
|
-
['Hangul', [[0xAC00,0xD7AF],[0x1100,0x11FF],[0x3130,0x318F],[0x3200,0x32FF],
|
|
50
|
-
[0xA960,0xA97F],[0xD7B0,0xD7FF]]],
|
|
51
|
-
['Hiragana', [[0x3040,0x309F]]],
|
|
52
|
-
['Katakana', [[0x30A0,0x30FF]]],
|
|
53
|
-
['Greek', [[0x370,0x3FF]]],
|
|
54
|
-
['Kannada', [[0xC80,0xCFF]]],
|
|
55
|
-
['Tamil', [[0xB80,0xBFF]]],
|
|
56
|
-
['Thai', [[0xE00,0xE7F]]],
|
|
57
|
-
['Gujarati', [[0xA80,0xAFF]]],
|
|
58
|
-
['Gurmukhi', [[0xA00,0xA7F]]],
|
|
59
|
-
['Telugu', [[0xC00,0xC7F]]],
|
|
60
|
-
['Malayalam', [[0xD00,0xD7F]]],
|
|
61
|
-
['Oriya', [[0xB00,0xB7F]]],
|
|
62
|
-
['Myanmar', [[0x1000,0x109F]]],
|
|
63
|
-
['Sinhala', [[0xD80,0xDFF]]],
|
|
64
|
-
['Khmer', [[0x1780,0x17FF],[0x19E0,0x19FF]]],
|
|
65
|
-
['Armenian', [[0x530,0x58F],[0xFB13,0xFB17]]]
|
|
66
|
-
].freeze
|
|
33
|
+
# Unicode script properties include letters outside the original BMP blocks.
|
|
34
|
+
# Keep the model's historical "Mandarin" key for the Han script.
|
|
35
|
+
SCRIPT_PATTERNS = %w[
|
|
36
|
+
Latin Cyrillic Arabic Han Devanagari Hebrew Ethiopic Georgian Bengali
|
|
37
|
+
Hangul Hiragana Katakana Greek Kannada Tamil Thai Gujarati Gurmukhi
|
|
38
|
+
Telugu Malayalam Oriya Myanmar Sinhala Khmer Armenian
|
|
39
|
+
].map { |script| [script == 'Han' ? 'Mandarin' : script, Regexp.new("\\p{#{script}}")] }.freeze
|
|
67
40
|
|
|
68
41
|
# ISO 639-1 (with 639-3 fallback) lookup by language-name symbol, plus the
|
|
69
42
|
# historical nil => nil entry. Internal; kept for backward compatibility.
|
|
@@ -76,8 +49,9 @@ class WhatLanguage
|
|
|
76
49
|
end.freeze
|
|
77
50
|
|
|
78
51
|
private_constant :MAX_TRIGRAM_DISTANCE, :MAX_TOTAL_DISTANCE, :TEXT_TRIGRAMS_SIZE,
|
|
79
|
-
:DEFAULT_MIN_CHARS, :DETERMINISTIC, :
|
|
80
|
-
:NAME_TO_CODE
|
|
52
|
+
:DEFAULT_MIN_CHARS, :DETERMINISTIC, :SCRIPT_PATTERNS, :ISO_CODES,
|
|
53
|
+
:NAME_TO_CODE, :SHORT_TEXT_PREFERENCES, :SHORT_TEXT_BONUS,
|
|
54
|
+
:SHORT_TEXT_FADE_CHARS
|
|
81
55
|
|
|
82
56
|
class << self
|
|
83
57
|
def detect(text)
|
|
@@ -156,14 +130,17 @@ class WhatLanguage
|
|
|
156
130
|
|
|
157
131
|
candidates = self.class.profiles[script]
|
|
158
132
|
return results unless candidates
|
|
159
|
-
|
|
133
|
+
char_count = significant_char_count(text)
|
|
134
|
+
return results if char_count < @min_chars
|
|
160
135
|
|
|
136
|
+
bonus = short_text_bonus(char_count)
|
|
161
137
|
positions = trigram_positions(text)
|
|
162
138
|
candidates.each do |code, trigrams|
|
|
163
139
|
name = CODE_INFO[code].first
|
|
164
140
|
next unless allowed?(name)
|
|
165
141
|
|
|
166
142
|
results[name] = MAX_TOTAL_DISTANCE - distance(trigrams, positions)
|
|
143
|
+
results[name] += bonus if SHORT_TEXT_PREFERENCES.include?(name)
|
|
167
144
|
end
|
|
168
145
|
results
|
|
169
146
|
end
|
|
@@ -198,6 +175,14 @@ class WhatLanguage
|
|
|
198
175
|
|
|
199
176
|
private
|
|
200
177
|
|
|
178
|
+
# A small fixed prior for widely spoken languages: full strength through ten
|
|
179
|
+
# letters, fading linearly to zero at fifty. These are ranking points, not
|
|
180
|
+
# probabilities. Script routing and the caller's candidate selection still win.
|
|
181
|
+
def short_text_bonus(char_count)
|
|
182
|
+
remaining = (SHORT_TEXT_FADE_CHARS - char_count).clamp(0, SHORT_TEXT_FADE_CHARS - DEFAULT_MIN_CHARS)
|
|
183
|
+
SHORT_TEXT_BONUS * remaining / (SHORT_TEXT_FADE_CHARS - DEFAULT_MIN_CHARS)
|
|
184
|
+
end
|
|
185
|
+
|
|
201
186
|
def normalize_text(text)
|
|
202
187
|
text.to_s.unicode_normalize(:nfkc)
|
|
203
188
|
end
|
|
@@ -215,18 +200,17 @@ class WhatLanguage
|
|
|
215
200
|
end
|
|
216
201
|
|
|
217
202
|
def significant_char_count(text)
|
|
218
|
-
text.each_char.count { |ch|
|
|
203
|
+
text.each_char.count { |ch| /\p{L}/.match?(ch) }
|
|
219
204
|
end
|
|
220
205
|
|
|
221
206
|
# Dominant Unicode script of the text, or nil if it has no script characters.
|
|
222
207
|
def detect_script(text)
|
|
223
208
|
counts = Hash.new(0)
|
|
224
209
|
text.each_char do |ch|
|
|
225
|
-
|
|
226
|
-
next if stop_char?(cp)
|
|
210
|
+
next unless /\p{L}/.match?(ch)
|
|
227
211
|
|
|
228
|
-
|
|
229
|
-
if
|
|
212
|
+
SCRIPT_PATTERNS.each do |name, pattern|
|
|
213
|
+
if pattern.match?(ch)
|
|
230
214
|
counts[name] += 1
|
|
231
215
|
break
|
|
232
216
|
end
|
|
@@ -234,14 +218,23 @@ class WhatLanguage
|
|
|
234
218
|
end
|
|
235
219
|
return nil if counts.empty?
|
|
236
220
|
|
|
221
|
+
# Japanese uses Han, Hiragana, and Katakana together. Combine their votes
|
|
222
|
+
# when kana is present, but still let a dominant unrelated script win.
|
|
223
|
+
if counts['Hiragana'] + counts['Katakana'] > 0
|
|
224
|
+
japanese = counts['Mandarin'] + counts['Hiragana'] + counts['Katakana']
|
|
225
|
+
counts.delete('Mandarin')
|
|
226
|
+
counts.delete('Katakana')
|
|
227
|
+
counts['Hiragana'] = japanese
|
|
228
|
+
end
|
|
229
|
+
|
|
237
230
|
counts.max_by { |_name, n| n }.first
|
|
238
231
|
end
|
|
239
232
|
|
|
240
233
|
# Text trigrams ranked by descending frequency, mapped to their rank index.
|
|
241
|
-
#
|
|
242
|
-
# the
|
|
234
|
+
# Non-letter/mark characters become spaces. Preserve combining marks used
|
|
235
|
+
# by the profiles; bound the stream by spaces and ignore repeated spaces.
|
|
243
236
|
def trigram_positions(text)
|
|
244
|
-
chars = text.downcase.each_char.map { |c|
|
|
237
|
+
chars = text.downcase.each_char.map { |c| /[\p{L}\p{M}]/.match?(c) ? c : ' ' }
|
|
245
238
|
return {} if chars.empty?
|
|
246
239
|
|
|
247
240
|
occurrences = Hash.new(0)
|
|
@@ -272,9 +265,4 @@ class WhatLanguage
|
|
|
272
265
|
total -= (MAX_TRIGRAM_DISTANCE - count) * MAX_TRIGRAM_DISTANCE if MAX_TRIGRAM_DISTANCE > count
|
|
273
266
|
total.clamp(0, MAX_TOTAL_DISTANCE)
|
|
274
267
|
end
|
|
275
|
-
|
|
276
|
-
# Space, ASCII punctuation, or digit: no value for script/language detection.
|
|
277
|
-
def stop_char?(codepoint)
|
|
278
|
-
codepoint <= 0x40 || (codepoint >= 0x5B && codepoint <= 0x60) || (codepoint >= 0x7B && codepoint <= 0x7E)
|
|
279
|
-
end
|
|
280
268
|
end
|
data/whatlanguage.gemspec
CHANGED
|
@@ -16,6 +16,7 @@ Gem::Specification.new do |gem|
|
|
|
16
16
|
gem.required_ruby_version = '>= 3.0'
|
|
17
17
|
|
|
18
18
|
gem.files = Dir['lib/**/*'] + [
|
|
19
|
+
'exe/whatlanguage',
|
|
19
20
|
'README.md',
|
|
20
21
|
'CHANGELOG.md',
|
|
21
22
|
'LICENSE.txt',
|
|
@@ -23,6 +24,8 @@ Gem::Specification.new do |gem|
|
|
|
23
24
|
'Rakefile',
|
|
24
25
|
'whatlanguage.gemspec'
|
|
25
26
|
]
|
|
27
|
+
gem.bindir = 'exe'
|
|
28
|
+
gem.executables = ['whatlanguage']
|
|
26
29
|
gem.require_paths = ['lib']
|
|
27
30
|
|
|
28
31
|
gem.add_development_dependency 'minitest', '~> 5.0'
|
metadata
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: whatlanguage
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Peter Cooper
|
|
8
|
-
bindir:
|
|
8
|
+
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
@@ -40,7 +40,8 @@ dependencies:
|
|
|
40
40
|
description: WhatLanguage rapidly detects the language of a sample of text
|
|
41
41
|
email:
|
|
42
42
|
- git@peterc.org
|
|
43
|
-
executables:
|
|
43
|
+
executables:
|
|
44
|
+
- whatlanguage
|
|
44
45
|
extensions: []
|
|
45
46
|
extra_rdoc_files: []
|
|
46
47
|
files:
|
|
@@ -49,6 +50,7 @@ files:
|
|
|
49
50
|
- LICENSE.txt
|
|
50
51
|
- README.md
|
|
51
52
|
- Rakefile
|
|
53
|
+
- exe/whatlanguage
|
|
52
54
|
- lib/whatlanguage.rb
|
|
53
55
|
- lib/whatlanguage/languages.rb
|
|
54
56
|
- lib/whatlanguage/trigrams.json
|