thai_keyboard_corrector 0.1.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ade7acc9f2b07c72e55d0f89cfe1c3a23002f5c01ba19e5eff0b27b1c1d483ca
4
+ data.tar.gz: f010ec32ab5064c6346643162e029876d5c7450e4d584bf3d7cdc4e569ed1b59
5
+ SHA512:
6
+ metadata.gz: 1005a6452fd77bd31271c0db49612ff39f8451a4be5de998524d2ccf5edbce384b753a90ec681b17ca9a8127327333e4847156ec502c02e850fdb370c7acedbb
7
+ data.tar.gz: b18cffcd017adb5f5d1dd64782f0a8b87c1bdccffa96028765c5a8ca48ddd284127092fa34d12160d72aaa83088bf7c50e5a0fc0feead296409e04554fbe2cc4
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Chayut Orapinpatipat
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,93 @@
1
+ # 🇹🇭 Thai Keyboard Corrector – แก้ไขข้อความไทยพิมพ์ผิด
2
+
3
+ **Thai Keyboard Corrector** (TKC) แก้ปัญหาการพิมพ์ **สลับแป้น** ระหว่างแป้นพิมพ์ภาษาไทยเกษมณี (Thai Kedmanee) และแป้นภาษาอังกฤษ QWERTY
4
+ ตัวอย่าง `l;ylfu` ➜ **สวัสดี** │ `ฟหกด` ➜ **asdf**
5
+
6
+ ---
7
+
8
+ ## Features
9
+
10
+ | | |
11
+ |---------|---------|
12
+ | Detects text that *looks* like **Thai-in-English** (`:thai_in_en`) or **English-in-Thai** (`:en_in_th`). | ตรวจจับข้อความที่พิมพ์สลับแป้น ทั้ง ไทยในอังกฤษ และ อังกฤษในไทย |
13
+ | Converts both directions with a **fixed key-position map** (no locale files). | แปลงกลับได้ทั้งสองทางด้วยตารางแมปคีย์ถาวร |
14
+ | **Pure Ruby, zero dependencies** – works ≥ Ruby 2.7. | เขียนด้วย Ruby ล้วน ๆ ไม่พึ่งไลบรารีภายนอก |
15
+ | Offers a **clean Ruby API** *and* a **CLI tool** (`thai_kbd_correct`). | ใช้ง่ายผ่านโค้ด Ruby หรือ CLI |
16
+
17
+ ---
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ gem install thai_keyboard_corrector
23
+ ````
24
+
25
+ (หรือเพิ่ม `gem "thai_keyboard_corrector"` ใน Gemfile)
26
+
27
+ ---
28
+
29
+ ## Usage – Ruby API
30
+
31
+ ```ruby
32
+ require "thai_keyboard_corrector"
33
+
34
+ # 1. Auto-correct if layout seems wrong
35
+ ThaiKeyboardCorrector.correct("l;ylfu") # => "สวัสดี"
36
+ ThaiKeyboardCorrector.correct("้รทัืฟทำ รห") # => "asdf"
37
+
38
+ # 2. Detect layout (returns a Symbol)
39
+ ThaiKeyboardCorrector.detect_layout("้รทัืฟทำรห") # => :thai
40
+ ThaiKeyboardCorrector.detect_layout("l;ylfu") # => :thai_in_en
41
+ ThaiKeyboardCorrector.detect_layout("ฟหกด") # => :en_in_th
42
+ ThaiKeyboardCorrector.detect_layout("helloส") # => :mixed
43
+ ```
44
+
45
+ ### Detection Symbols
46
+
47
+ | Symbol | Meaning |
48
+ | ------------- | ------------------------------------------------------------ |
49
+ | `:thai` | Normal Thai text |
50
+ | `:en` | Normal English text |
51
+ | `:thai_in_en` | Thai characters typed on **EN** layout (needs flip EN→TH) |
52
+ | `:en_in_th` | English characters typed on **TH** layout (needs flip TH→EN) |
53
+ | `:mixed` | Contains both Thai & English letters in correct positions |
54
+ | `:unknown` | Blank or symbols only |
55
+
56
+ ---
57
+
58
+ ## Usage – CLI
59
+
60
+ ```bash
61
+ $ thai_kbd_correct "l;ylfu"
62
+ สวัสดี
63
+
64
+ $ echo "ฟหกด" | thai_kbd_correct
65
+ asdf
66
+ ```
67
+
68
+ Flags:
69
+
70
+ | Flag | ใช้ทำอะไร |
71
+ | ------- | --------------------------------- |
72
+ | `-f th` | บังคับแปลง EN→TH (ข้ามการตรวจจับ) |
73
+ | `-f en` | บังคับแปลง TH→EN |
74
+ | `-h` | แสดงวิธีใช้ |
75
+
76
+ ---
77
+
78
+ ## 🛠️ Development
79
+
80
+ ```bash
81
+ git clone https://github.com/<you>/thai_keyboard_corrector.git
82
+ cd thai_keyboard_corrector
83
+ bundle install
84
+ bundle exec rspec # ✅ tests should pass
85
+ bundle exec rubocop -A # ✅ style conforms
86
+ ```
87
+
88
+ ---
89
+
90
+ ## License
91
+
92
+ © 2025 Chayut Orapinpatipat
93
+ Released under the MIT License. See [LICENSE.txt](LICENSE.txt) for details.
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative '../lib/thai_keyboard_corrector'
5
+ require 'optparse'
6
+
7
+ options = { force: nil }
8
+
9
+ OptionParser.new do |opts|
10
+ opts.banner = 'Usage: thai_kbd_correct [options] <text>'
11
+ opts.on('-fLAYOUT', '--force=LAYOUT', 'Force convert (en|th)') { |v| options[:force] = v }
12
+ opts.on('-h', '--help', 'Show help') do
13
+ puts opts
14
+ exit
15
+ end
16
+ end.parse!
17
+
18
+ input_text = ARGV.empty? ? $stdin.read : ARGV.join(' ')
19
+
20
+ if options[:force] == 'th'
21
+ puts ThaiKeyboardCorrector::Mapping.map_eng_to_thai(input_text)
22
+ elsif options[:force] == 'en'
23
+ puts ThaiKeyboardCorrector::Mapping.map_thai_to_eng(input_text)
24
+ else
25
+ puts ThaiKeyboardCorrector.correct(input_text)
26
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ThaiKeyboardCorrector
4
+ # This module detects the layout of a given string.
5
+ module Detector
6
+ THAI_RANGE = (0x0E00..0x0E7F).freeze
7
+ THRESHOLD = 0.7
8
+ VOWELS = 'aeiouy'
9
+ FULL_HIT = 1.0 - Float::EPSILON
10
+
11
+ module_function
12
+
13
+ # Returns :thai_in_en, :en_in_th, :thai, :en, :mixed, :unknown
14
+ def detect_layout(str)
15
+ clean = str.strip
16
+ return :unknown if clean.empty?
17
+
18
+ thai_cnt, latin_cnt = char_stats(clean)
19
+ return :unknown if thai_cnt.zero? && latin_cnt.zero?
20
+
21
+ # ---------- pure-Latin ----------
22
+ if thai_cnt.zero?
23
+ # ▼ Treat 1-3-letter words as Thai-in-EN (they’re almost never real English)
24
+ return :thai_in_en if clean.length <= 3 &&
25
+ hit_ratio(clean, Mapping::ENG_TO_THAI) >= FULL_HIT
26
+
27
+ return :thai_in_en if clean.match?(/[^A-Za-z]/) &&
28
+ hit_ratio(clean, Mapping::ENG_TO_THAI) >= THRESHOLD
29
+
30
+ return :en
31
+ end
32
+
33
+ # ---------- pure-Thai ----------
34
+ if latin_cnt.zero?
35
+ return :thai if clean.length < 4 # ignore tiny words like “ดี”
36
+
37
+ eng = Mapping.map_thai_to_eng(clean)
38
+ vowelish = eng.count(VOWELS).positive?
39
+ if eng.match?(/\A[a-z]+\z/i) && vowelish &&
40
+ hit_ratio(clean, Mapping::THAI_TO_ENG) >= THRESHOLD
41
+ return :en_in_th
42
+ end
43
+
44
+ return :thai
45
+ end
46
+
47
+ # ---------- mixed ----------
48
+ return :mixed if thai_cnt.positive? && latin_cnt.positive?
49
+ return :thai_in_en if hit_ratio(clean, Mapping::ENG_TO_THAI) >= THRESHOLD
50
+ return :en_in_th if hit_ratio(clean, Mapping::THAI_TO_ENG) >= THRESHOLD
51
+
52
+ :mixed
53
+ end
54
+
55
+ # helpers ----------------------------------------------------------------
56
+ def char_stats(str)
57
+ clean = str.gsub(/\s+/, '') # remove ALL Unicode whitespace
58
+ thai = clean.each_char.count { |c| THAI_RANGE.include?(c.ord) }
59
+ latin = clean.each_char.count { |c| c =~ /[A-Za-z]/ }
60
+ [thai, latin]
61
+ end
62
+ private_class_method :char_stats
63
+
64
+ def hit_ratio(str, table)
65
+ chars = str.gsub(/\s+/, '').chars # whitespace-free array
66
+ return 0.0 if chars.empty?
67
+
68
+ hits = chars.count { |c| table.key?(c) }
69
+ hits.to_f / chars.length
70
+ end
71
+ private_class_method :hit_ratio
72
+ end
73
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ThaiKeyboardCorrector
4
+ # Mapping module provides methods to convert between English and Thai characters
5
+ module Mapping
6
+ # Base (lower-case) map
7
+ BASE = {
8
+ 'q' => 'ๆ', 'w' => 'ไ', 'e' => 'ำ', 'r' => 'พ', 't' => 'ะ',
9
+ 'y' => 'ั', 'u' => 'ี', 'i' => 'ร', 'o' => 'น', 'p' => 'ย',
10
+ '[' => 'บ', ']' => 'ล',
11
+ 'a' => 'ฟ', 's' => 'ห', 'd' => 'ก', 'f' => 'ด', 'g' => 'เ',
12
+ 'h' => '้', 'j' => '่', 'k' => 'า', 'l' => 'ส', ';' => 'ว', "'" => 'ง',
13
+ 'z' => 'ผ', 'x' => 'ป', 'c' => 'แ', 'v' => 'อ', 'b' => 'ิ',
14
+ 'n' => 'ื', 'm' => 'ท', ',' => 'ม', '.' => 'ใ', '/' => 'ฝ'
15
+ }.freeze
16
+
17
+ ENG_TO_THAI = BASE.merge(BASE.transform_keys(&:upcase)).freeze
18
+ THAI_TO_ENG = BASE.invert.freeze # ⇒ always lower-case
19
+
20
+ module_function
21
+
22
+ def map_eng_to_thai(str)
23
+ str.chars.map { |c| ENG_TO_THAI.fetch(c, c) }.join
24
+ end
25
+
26
+ def map_thai_to_eng(str)
27
+ str.chars.map { |c| THAI_TO_ENG.fetch(c, c) }.join
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ThaiKeyboardCorrector
4
+ VERSION = '0.1.1'
5
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'thai_keyboard_corrector/version'
4
+ require 'thai_keyboard_corrector/mapping'
5
+ require 'thai_keyboard_corrector/detector'
6
+
7
+ # Main entry point
8
+ module ThaiKeyboardCorrector
9
+ module_function
10
+
11
+ # Corrects a string if it appears to be typed on the wrong layout.
12
+ # @param str [String] input string
13
+ # @return [String] corrected or original string
14
+ def correct(str)
15
+ case detect_layout(str)
16
+ when :thai_in_en
17
+ Mapping.map_eng_to_thai(str)
18
+ when :en_in_th
19
+ Mapping.map_thai_to_eng(str)
20
+ else
21
+ str
22
+ end
23
+ end
24
+
25
+ # Detects keyboard layout scenario for the given string.
26
+ # @param str [String]
27
+ # @return [Symbol] one of :thai_in_en, :en_in_th, :thai, :en, :mixed, :unknown
28
+ def detect_layout(str)
29
+ Detector.detect_layout(str)
30
+ end
31
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: thai_keyboard_corrector
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Chayut Orapinpatipat
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2025-06-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: Detects and converts Thai text mistakenly typed on an English QWERTY
28
+ layout (and vice versa) back to its intended form. Perfect for search bars, chat
29
+ apps, and form inputs.
30
+ email:
31
+ - chayut_o@hotmail.com
32
+ executables:
33
+ - thai_kbd_correct
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - LICENSE.txt
38
+ - README.md
39
+ - bin/thai_kbd_correct
40
+ - lib/thai_keyboard_corrector.rb
41
+ - lib/thai_keyboard_corrector/detector.rb
42
+ - lib/thai_keyboard_corrector/mapping.rb
43
+ - lib/thai_keyboard_corrector/version.rb
44
+ homepage: https://github.com/chayuto/thai_keyboard_corrector
45
+ licenses:
46
+ - MIT
47
+ metadata: {}
48
+ post_install_message:
49
+ rdoc_options: []
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '2.7'
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ requirements: []
63
+ rubygems_version: 3.5.11
64
+ signing_key:
65
+ specification_version: 4
66
+ summary: Corrects Thai text typed on the wrong keyboard layout (EN/TH) and vice versa.
67
+ test_files: []