require 'fileutils' module Twiddler module TargetBuilder def self.build(output_dir, dictionary, config) FileUtils::mkdir_p(output_dir) File::open(dictionary, "r") do |dict| Builder::registered.each do |klass| dict.rewind klass.new(output_dir, dict, config).go end end end class Builder class << self def register @@registered ||= [] @@registered << self end def registered @@registered || [] end end def initialize(dir, dict, config) @dir = dir @dict = dict @config = config end def output_to(name) File::open(File::expand_path("#{name}.list", @dir), "w") do |file| yield(file) end end def go end end class RegexpBuilder < Builder def match_any_of(list) return "(?:#{list.map{|it| Regexp::escape(it)}.join(")|(?:")})" end def go output_to(filename) do |file| @dict.grep(regexp) do |word| file.puts(word) end end end end class ShortWords < RegexpBuilder register def filename "Short Words" end def regexp /^.{1,5}$/ end end class Macros < RegexpBuilder register def filename "Macros" end def regexp macros = @config.keyboard.find_all do |chord| chord.keystrokes.length > 1 and chord.keystrokes.all? do |stroke| stroke[1].empty? end end return %r{^.{0,1}(?:#{match_any_of(macros.map{|chord| chord.render_action})}).{0,1}$} end end class Flow < RegexpBuilder register def filename "Flow" end def regexp flow = [] chords = @config.keyboard.find_all do |chord| chord.single? and chord.keystrokes[0][1].empty? and Config.keytable.is_tagged?(chord.keystrokes[0][0], :letters) end chords.each do |first| chords.each do |second| next if first == second pairs = first.rows.zip(second.rows).find_all{|one,two| one != two} case pairs.length when 1 flow << first.render_action + second.render_action next when 2 next if pairs.find{|pair| !pair.include?(:open)} if pairs[0][0] == pairs[1][1] and pairs[0][1] == pairs[1][0] flow << first.render_action + second.render_action next end end end end return %r{^.{0,1}(?:#{match_any_of(flow)}).{0,1}$} end end end end