Class: Kotoshu::Keyboard::Layout

Inherits:
Object
  • Object
show all
Defined in:
lib/kotoshu/keyboard/layout.rb

Overview

Base class for keyboard layouts

Each layout defines key positions and provides distance calculations for typo detection and suggestion ranking in spell checking.

Examples:

Using a keyboard layout

layout = Keyboard::Layouts::QWERTY.new
layout.distance('q', 'w')  # => 1 (adjacent keys)
layout.distance('q', 'p')  # => 8 (far apart)
layout.adjacent_keys('q')  # => ['w', 'a', 's']

Checking language support

qwerty = Keyboard::Layouts::QWERTY.new
qwerty.supports_language?('en')  # => true
qwerty.supports_language?('de')  # => false

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name:, language_codes:, key_positions:) ⇒ Layout

Initialize a keyboard layout

Parameters:

  • name (String)

    the name of the layout

  • language_codes (Array<String>)

    list of language codes this layout supports

  • key_positions (Hash)

    mapping of key characters to [row, col] positions



36
37
38
39
40
# File 'lib/kotoshu/keyboard/layout.rb', line 36

def initialize(name:, language_codes:, key_positions:)
  @name = name
  @language_codes = Array(language_codes).freeze
  @key_positions = key_positions.freeze
end

Instance Attribute Details

#key_positionsHash (readonly)

Returns mapping of key characters to [row, col] positions.

Returns:

  • (Hash)

    mapping of key characters to [row, col] positions



29
30
31
# File 'lib/kotoshu/keyboard/layout.rb', line 29

def key_positions
  @key_positions
end

#language_codesArray<String> (readonly)

Returns list of language codes this layout supports.

Returns:

  • (Array<String>)

    list of language codes this layout supports



26
27
28
# File 'lib/kotoshu/keyboard/layout.rb', line 26

def language_codes
  @language_codes
end

#nameString (readonly)

Returns the name of this keyboard layout.

Returns:

  • (String)

    the name of this keyboard layout



23
24
25
# File 'lib/kotoshu/keyboard/layout.rb', line 23

def name
  @name
end

Instance Method Details

#adjacent_keys(key) ⇒ Array<String>

Get adjacent keys for a given key (within 1 unit distance)

Adjacent keys are those that are directly next to the given key horizontally or vertically (not diagonal).

Parameters:

  • key (String)

    the key character to find adjacent keys for

Returns:

  • (Array<String>)

    list of adjacent key characters



90
91
92
93
94
95
96
97
98
# File 'lib/kotoshu/keyboard/layout.rb', line 90

def adjacent_keys(key)
  pos = position(key)
  return [] unless pos

  @key_positions.select do |k, p|
    next if k == key
    ((p[0] - pos[0]).abs + (p[1] - pos[1]).abs) == 1
  end.keys
end

#distance(key1, key2) ⇒ Integer

Calculate Manhattan distance between two keys

Manhattan distance is the sum of absolute differences of row and column: distance = abs(row1 - row2) + abs(col1 - col2)

Parameters:

  • key1 (String)

    first key character

  • key2 (String)

    second key character

Returns:

  • (Integer)

    Manhattan distance (0 if same key, Float::INFINITY if either key not found)



58
59
60
61
62
63
64
65
# File 'lib/kotoshu/keyboard/layout.rb', line 58

def distance(key1, key2)
  pos1 = position(key1)
  pos2 = position(key2)

  return Float::INFINITY unless pos1 && pos2

  (pos1[0] - pos2[0]).abs + (pos1[1] - pos2[1]).abs
end

#inspectString

Inspect method for debugging

Returns:

  • (String)

    detailed inspection string



110
111
112
# File 'lib/kotoshu/keyboard/layout.rb', line 110

def inspect
  "#<#{self.class} name=#{@name} languages=#{@language_codes.join(',')}>"
end

#position(key) ⇒ Array<Integer>?

Get position [row, col] for a key

Parameters:

  • key (String)

    the key character to look up

Returns:

  • (Array<Integer>, nil)

    the [row, col] position, or nil if key not found



46
47
48
# File 'lib/kotoshu/keyboard/layout.rb', line 46

def position(key)
  @key_positions[key.downcase]
end

#supports_language?(language_code) ⇒ Boolean

Check if layout supports a language

Supports both exact matching and language variant matching. For example, if ‘en’ is supported, then ‘en-US’, ‘en-GB’, etc. are also supported.

Parameters:

  • language_code (String)

    the language code to check (e.g., ‘en’, ‘en-US’, ‘de’)

Returns:

  • (Boolean)

    true if this layout supports the language



74
75
76
77
78
79
80
81
# File 'lib/kotoshu/keyboard/layout.rb', line 74

def supports_language?(language_code)
  # Try exact match first
  return true if @language_codes.include?(language_code)

  # Try base language match (e.g., 'en' for 'en-US')
  base_lang = language_code.to_s.split('-').first
  @language_codes.include?(base_lang)
end

#to_sString

String representation of the layout

Returns:

  • (String)

    layout name



103
104
105
# File 'lib/kotoshu/keyboard/layout.rb', line 103

def to_s
  "Keyboard::#{@name}"
end