Module: Konjac::Dictionary

Defined in:
lib/konjac/dictionary.rb

Overview

A module for loading and manipulating the user’s dictionaries

Constant Summary collapse

BLANK =

A regular expression used to determine whether a string is blank

/^\s*$/

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.dictionariesObject

The dictionaries currently in use



14
15
16
# File 'lib/konjac/dictionary.rb', line 14

def dictionaries
  @dictionaries
end

.from_langObject

The most recent language from which to translate



8
9
10
# File 'lib/konjac/dictionary.rb', line 8

def from_lang
  @from_lang
end

.pairsObject

The current pairs



17
18
19
# File 'lib/konjac/dictionary.rb', line 17

def pairs
  @pairs
end

.to_langObject

The most recent language into which to translated



11
12
13
# File 'lib/konjac/dictionary.rb', line 11

def to_lang
  @to_lang
end

Class Method Details

.add_word(opts = {}) ⇒ Object

Adds a word to the dictionary



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/konjac/dictionary.rb', line 145

def add_word(opts = {})
  from_lang    = Language.find(opts[:from]).to_s
  to_lang      = Language.find(opts[:to]).to_s
  dictionaries = find_dictionaries(opts[:using])
  counter      = dictionaries.length

  dictionaries.each do |path|
    dict = ::YAML.load_file(path)
    found = false
    dict.each do |term|
      if term.has_key?(to_lang)
        if term[to_lang].is_a?(Hash)
          to_term   = term[to_lang][to_lang]
          from_term = term[to_lang][from_lang]
        else
          to_term = term[to_lang]
        end

        from_term ||= term[from_lang]

        if to_term == opts[:translation]
          if from_term.is_a?(Regexp) && from_term =~ opts[:original]
            found = true
            break
          elsif from_term == opts[:original]
            found = true
            break
          end
        end
      end
    end

    if found
      counter -= 1
    else
      dict.unshift({ to_lang => opts[:translation], from_lang => opts[:original] })
    end

    File.open(path, "w") do |file|
      YAML.dump dict, file
    end
  end

  counter
end

.build_replacement_template(from_lang, to_lang) ⇒ Object

Builds a replacement template for the to language, depending on whether the both from and to languages allow for whitespace



136
137
138
139
140
141
142
# File 'lib/konjac/dictionary.rb', line 136

def build_replacement_template(from_lang, to_lang)
  if !Language.has_spaces?(from_lang) && Language.has_spaces?(to_lang)
    "%s "
  else
    "%s"
  end
end

.extract_pair_from_term(term, from_lang, to_lang, has_spaces, to_template) ⇒ Object

Extracts a regular expression and string replacement pair from a term in the Dictionary, based on the supplied languages and their templates



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/konjac/dictionary.rb', line 61

def extract_pair_from_term(term, from_lang, to_lang, has_spaces, to_template)
  if term.has_key?(to_lang)
    # Build to term depending on whether it's a hash for complex
    # matches or a simple string
    if term[to_lang].is_a?(Hash)
      to_term        = term[to_lang][to_lang]
      case_sensitive = term[to_lang]["case_sensitive"]
      no_space       = term[to_lang]["no_space"]
      is_regex       = term[to_lang]["regex"]

      if term[to_lang].has_key?(from_lang)
        from_term = term[to_lang][from_lang]
      end
    else
      to_term = term[to_lang]
    end

    # Build from term if it doesn't already exist
    if term.has_key?(from_lang) && from_term.nil?
      if term[from_lang].is_a?(Hash)
        from_term = term[from_lang][from_lang]
      else
        from_term = term[from_lang]
      end
    end

    unless from_term.nil?
      # Build a regular expression if it isn't already one.
      # Note that this will apply word boundary rules, so to avoid them
      # create a regular expression in the dictionary file.
      # Matching is case-insensitive unless the expression contains a
      # capital letter.
      from_fuzzy = from_term
      unless from_term.is_a?(Regexp)
        flags = (case_sensitive || (from_term =~ /[A-Z]/)) ? nil : "i"
        from_term = Regexp.escape(from_term) unless is_regex
        if has_spaces
          from_term = Regexp.new(add_word_boundaries(from_term), flags)
        else
          from_term = Regexp.new(from_term, flags)
        end
      end

      to_term = to_template % to_term unless to_term =~ BLANK || no_space

      return [ from_term, to_term, from_fuzzy ]
    end
  end

  # Return nil if no term could be constructed
  return nil
end

.load(from_lang, to_lang, opts = {}) ⇒ Object

Loads the specified languages and dictionaries

Dictionary.load :en, :ja, :using => [:dict]


25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/konjac/dictionary.rb', line 25

def load(from_lang, to_lang, opts = {})
  # Allow both symbol and string arguments for languages
  from_lang = from_lang.to_s
  to_lang   = to_lang.to_s

  # Ignore everything if we've been here before
  return @pairs if loaded?(from_lang, to_lang, opts[:using])

  if opts[:use_cache]
    @pairs = load_serialized(from_lang, to_lang, opts[:using])
    return @pairs unless @pairs.nil?
  end
  
  # Build a regex template for the from language
  has_spaces  = Language.has_spaces?(from_lang)
  to_template = build_replacement_template(from_lang, to_lang)

  # Save variables to cache so we can avoid repetitive requests
  cache_load from_lang, to_lang, opts[:using]
  
  # Make sure dictionary exists and load
  dictionary = build_dictionary(opts[:using])

  # Build a list of search and replace pairs
  @pairs = []
  dictionary.each do |term|
    pair = extract_pair_from_term(term, from_lang, to_lang, has_spaces, to_template)
    @pairs << pair unless pair.nil?
  end

  save_serialized from_lang, to_lang, dictionaries, @pairs
  @pairs
end

.loaded?(from_lang, to_lang, dictionaries) ⇒ Boolean

Tests whether the same from language, to language and dictionary path have been loaded before

Returns:

  • (Boolean)


127
128
129
130
131
132
# File 'lib/konjac/dictionary.rb', line 127

def loaded?(from_lang, to_lang, dictionaries)
  (@from_lang    == from_lang   ) &&
  (@to_lang      == to_lang     ) &&
  (@dictionaries == dictionaries) &&
  !@pairs.nil?
end

.verify_dictionary_exists(full_path) ⇒ Object

Verifies whether the dictionary exists on the specified path, creating a blank file if it doesn’t



116
117
118
119
120
121
122
123
# File 'lib/konjac/dictionary.rb', line 116

def verify_dictionary_exists(full_path)
  unless File.file?(full_path)
    FileUtils.mkpath File.dirname(full_path)
    File.open(full_path, "w") do |file|
      file.puts "--- []"
    end
  end
end