konjac 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -2,4 +2,5 @@
2
2
  .bundle
3
3
  .DS_Store
4
4
  Gemfile.lock
5
+ doc/
5
6
  pkg/*
data/README.md CHANGED
@@ -63,13 +63,15 @@ Use multiple dictionaries:
63
63
 
64
64
  konjac translate financial_report_en.txt into japanese using finance
65
65
 
66
- Extract text from a DOCX document (creates a plain-text `test.tags` file):
66
+ Extract text from a DOCX document (creates a plain-text `test.konjac` file from
67
+ `test.docx`):
67
68
 
68
- konjac extract test.docx
69
+ konjac extract test
69
70
 
70
- Import tags file back into DOCX document:
71
+ Import tags file back into DOCX document (file created is named
72
+ `test_imported.docx`):
71
73
 
72
- konjac import test.docx
74
+ konjac import test
73
75
 
74
76
  Extended Example
75
77
  ----------------
@@ -108,7 +110,7 @@ Extended Example
108
110
  en: ""
109
111
  ja: !ruby/regexp /\s(?=[.,:]|$)/
110
112
 
111
- ~/.konjac/test_en.txt
113
+ ~/.konjac/test_en.txt:
112
114
 
113
115
  I like dogs.
114
116
 
@@ -0,0 +1,20 @@
1
+ module Konjac
2
+ module CLI
3
+ class SubCommand
4
+ attr :name, :aliases, :description
5
+
6
+ def initialize(name, aliases, description, &block)
7
+ @name, @aliases, @description = name, aliases, description
8
+ @block = block
9
+ end
10
+
11
+ def alias_text
12
+ @aliases.join ", "
13
+ end
14
+
15
+ def execute
16
+ @block.call
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,77 @@
1
+ module Konjac
2
+ module CLI
3
+ class SubCommandManager
4
+ def initialize
5
+ @sub_commands ||= []
6
+ end
7
+
8
+ def add(name, aliases, description, &block)
9
+ @sub_commands << SubCommand.new(name, aliases, description, &block)
10
+ end
11
+
12
+ def execute(sub_command)
13
+ sub_command = sub_command.to_sym
14
+
15
+ @sub_commands.each do |sc|
16
+ if sc.name == sub_command || sc.aliases.include?(sub_command)
17
+ sc.execute
18
+ return sc.name
19
+ end
20
+ end
21
+
22
+ return nil
23
+ end
24
+
25
+ def all
26
+ @sub_commands
27
+ end
28
+
29
+ def get_lengths
30
+ @lengths = { :name => 8, :aliases => 7, :description => 11 }
31
+
32
+ @sub_commands.each do |sc|
33
+ if sc.name.length > @lengths[:name]
34
+ @lengths[:name] = sc.name.length
35
+ end
36
+ if sc.alias_text.length > @lengths[:aliases]
37
+ @lengths[:aliases] = sc.alias_text.length
38
+ end
39
+ if sc.description.length > @lengths[:description]
40
+ @lengths[:description] = sc.description.length
41
+ end
42
+ end
43
+ end
44
+
45
+ def to_s
46
+ get_lengths
47
+ text = "\n"
48
+
49
+ header_lines = "%s %s %s\n" % [
50
+ "-" * @lengths[:name],
51
+ "-" * @lengths[:aliases],
52
+ "-" * @lengths[:description]
53
+ ]
54
+
55
+ # Create headers
56
+ text << header_lines
57
+ text << "%s %s %s\n" % [
58
+ "Commands".ljust(@lengths[:name]),
59
+ "Aliases".ljust(@lengths[:aliases]),
60
+ "Description".ljust(@lengths[:description])
61
+ ]
62
+ text << header_lines
63
+
64
+ # Write descriptions of each subcommand
65
+ @sub_commands.each do |sc|
66
+ text << "%s %s %s\n" % [
67
+ sc.name.to_s.ljust(@lengths[:name]),
68
+ sc.alias_text.to_s.ljust(@lengths[:aliases]),
69
+ sc.description.to_s.ljust(@lengths[:description])
70
+ ]
71
+ end
72
+
73
+ text
74
+ end
75
+ end
76
+ end
77
+ end
data/lib/konjac/cli.rb CHANGED
@@ -1,28 +1,43 @@
1
1
  module Konjac
2
2
  module CLI
3
+ autoload :SubCommand, "konjac/cli/sub_command"
4
+ autoload :SubCommandManager, "konjac/cli/sub_command_manager"
5
+
3
6
  class << self
7
+ def init_sub_commands
8
+ @valid_commands = SubCommandManager.new
9
+ @valid_commands.add :extract, [:export, :e, :x], "Extract text from a DOCX file" do
10
+ Word.extract_docx_tags(ARGV)
11
+ end
12
+ @valid_commands.add :help, [:h, :"-h", :"?"], "Show help" do
13
+ show_help
14
+ end
15
+ @valid_commands.add :import, [:i, :m], "Import text back into a DOCX file" do
16
+ Word.import_docx_tags(ARGV)
17
+ end
18
+ @valid_commands.add :translate, [:t], "Translate a file" do
19
+ translate
20
+ end
21
+ end
22
+
4
23
  def start
24
+ init_sub_commands
5
25
  show_help if ARGV.empty?
6
26
 
7
27
  # Subcommand
8
- case ARGV.shift
9
- when "translate"
10
- translate
11
- when "extract", "export"
12
- Word.extract_docx_tags(ARGV)
13
- when "import"
14
- Word.import_docx_tags(ARGV)
15
- when "add"
16
- when "help"
28
+ sub_command = ARGV.shift
29
+ result = @valid_commands.execute(sub_command)
30
+
31
+ if result.nil?
17
32
  show_help
18
- else
19
- raise InvalidCommandError.new("Valid commands are translate or add")
33
+ raise InvalidCommandError.new("Invalid subcommand: #{sub_command}")
20
34
  end
35
+
36
+ result
21
37
  end
22
38
 
23
39
  def show_help
24
- puts "Help"
25
- exit 0
40
+ puts @valid_commands.to_s
26
41
  end
27
42
 
28
43
  private
@@ -16,14 +16,13 @@ module Konjac
16
16
  from_lang = from_lang.to_s
17
17
  to_lang = to_lang.to_s
18
18
 
19
+ # Ignore everything if we've been here before
20
+ return @pairs if loaded?(from_lang, to_lang, dictionaries) || opts[:force]
21
+
19
22
  # Build a regex template for the from language
20
23
  from_template = build_regex_template(from_lang)
21
24
  to_template = build_replacement_template(from_lang, to_lang)
22
25
 
23
- # Get full path from name
24
-
25
- return @pairs if loaded?(from_lang, to_lang, dictionaries) || opts[:force]
26
-
27
26
  # Save variables to cache so we can avoid repetitive requests
28
27
  cache_load from_lang, to_lang, dictionaries
29
28
 
@@ -46,40 +45,51 @@ module Konjac
46
45
  # Build a list of search and replace pairs
47
46
  @pairs = []
48
47
  @dictionary.each do |term|
49
- if term.has_key?(to_lang)
50
- # Build to term depending on whether it's a hash for complex
51
- # matches or a simple string
52
- if term[to_lang].is_a?(Hash)
53
- to_term = term[to_lang][to_lang]
54
-
55
- if term[to_lang].has_key?(from_lang)
56
- from_term = term[to_lang][from_lang]
57
- end
58
- else
59
- to_term = term[to_lang]
60
- end
48
+ pair = extract_pair_from_term(term, from_lang, to_lang, from_template, to_template)
49
+ @pairs << pair unless pair.nil?
50
+ end
61
51
 
62
- # Build from term if it doesn't already exist
63
- if term.has_key?(from_lang) && from_term.nil?
64
- from_term = term[from_lang]
65
- end
52
+ @pairs
53
+ end
66
54
 
67
- unless from_term.nil?
68
- # Build a regular expression if it isn't already one
69
- # Note that this will apply word boundary rules, so to avoid them
70
- # create a regular expression in the dictionary file
71
- unless from_term.is_a?(Regexp)
72
- from_term = Regexp.new(from_template % from_term)
73
- end
55
+ def extract_pair_from_term(term, from_lang, to_lang, from_template, to_template)
56
+ if term.has_key?(to_lang)
57
+ # Build to term depending on whether it's a hash for complex
58
+ # matches or a simple string
59
+ if term[to_lang].is_a?(Hash)
60
+ to_term = term[to_lang][to_lang]
74
61
 
75
- to_term = to_template % to_term unless to_term =~ BLANK
62
+ if term[to_lang].has_key?(from_lang)
63
+ from_term = term[to_lang][from_lang]
64
+ end
65
+ else
66
+ to_term = term[to_lang]
67
+ end
76
68
 
77
- @pairs << [ from_term, to_term ]
69
+ # Build from term if it doesn't already exist
70
+ if term.has_key?(from_lang) && from_term.nil?
71
+ from_term = term[from_lang]
72
+ end
73
+
74
+ unless from_term.nil?
75
+ # Build a regular expression if it isn't already one.
76
+ # Note that this will apply word boundary rules, so to avoid them
77
+ # create a regular expression in the dictionary file.
78
+ # Matching is case-insensitive unless the expression contains a
79
+ # capital letter.
80
+ unless from_term.is_a?(Regexp)
81
+ from_term = Regexp.new(from_template % from_term,
82
+ ("i" unless from_term =~ /[A-Z]/))
78
83
  end
84
+
85
+ to_term = to_template % to_term unless to_term =~ BLANK
86
+
87
+ return [ from_term, to_term ]
79
88
  end
80
89
  end
81
90
 
82
- @pairs
91
+ # Return nil if no term could be constructed
92
+ return nil
83
93
  end
84
94
 
85
95
  # Verifies whether the dictionary exists on the specified path, creating
@@ -1,3 +1,3 @@
1
1
  module Konjac
2
- VERSION = "0.1.3"
2
+ VERSION = "0.1.4"
3
3
  end
data/spec/cli_spec.rb CHANGED
@@ -3,8 +3,15 @@ require File.dirname(__FILE__) + "/spec_helper"
3
3
  require "tempfile"
4
4
 
5
5
  describe CLI do
6
+ # Super hacky way of setting a constant without setting off a warnings that the
7
+ # constant has already been initialized
8
+ def set_argv(*params)
9
+ Object.__send__ :remove_const, :ARGV
10
+ Object.const_set :ARGV, params
11
+ end
12
+
6
13
  it "should fail on an invalid subcommand" do
7
- ARGV = ["invalid"]
14
+ set_argv "invalid"
8
15
  lambda { CLI.start }.should raise_error InvalidCommandError
9
16
  end
10
17
 
@@ -14,8 +21,8 @@ describe CLI do
14
21
  @dictionary = Tempfile.new(["dict", ".yml"])
15
22
  @dictionary.write <<-eos
16
23
  -
17
- en: dogs
18
- ja: 犬
24
+ en: dogs
25
+ ja: 犬
19
26
  eos
20
27
  @dictionary.rewind
21
28
 
@@ -23,14 +30,17 @@ describe CLI do
23
30
  @english = Tempfile.new(["english", "_en.txt"])
24
31
  @english.write "I like dogs."
25
32
  @english.rewind
33
+
34
+ # Set ARGV
35
+ set_argv "translate", @english.path, "into", "japanese", "using",
36
+ @dictionary.path
26
37
  end
27
38
 
28
39
  it "should correctly translate English text" do
29
40
  begin
30
- ARGV = ["translate", @english.path, "into", "japanese", "using", @dictionary.path]
31
41
  CLI.start
32
42
  converted_path = Utils.build_converted_file_name(@english.path, "en", "ja")
33
- puts File.read(@english.path).should == "I like dogs."
43
+ File.read(@english.path).should == "I like dogs."
34
44
  File.read(converted_path).should == "I like 犬.\n"
35
45
  ensure
36
46
  @dictionary.close!
@@ -38,5 +48,9 @@ describe CLI do
38
48
  File.delete converted_path
39
49
  end
40
50
  end
51
+
52
+ it "should return the name of the sub_command" do
53
+ CLI.start.should == :translate
54
+ end
41
55
  end
42
56
  end
@@ -7,14 +7,82 @@ describe Dictionary do
7
7
  @dictionary = Tempfile.new(["dict", ".yml"])
8
8
  @dictionary.write <<-eos
9
9
  -
10
- en: dogs
11
- ja: 犬
10
+ en: dogs
11
+ ja: 犬
12
+ -
13
+ en: cat
14
+ ja:
15
+ ja: 猫
16
+ en: cats?
17
+ -
18
+ ja:
19
+ ja: 。
20
+ en: !ruby/regexp /\\.\\s?/
21
+ -
22
+ en: mouth
23
+ es: boca
24
+ -
25
+ es: mano
26
+ ja: 手
27
+ -
28
+ en:
29
+ en: book
30
+ ja: 本
31
+ -
32
+ en: North Carolina
33
+ ja: ノースカロライナ
12
34
  eos
13
35
  @dictionary.rewind
14
36
  end
15
37
 
16
- it "should correctly load YAML" do
17
- Dictionary.load "en", "ja", [@dictionary.path]
18
- Dictionary.pairs.should == [[/\bdogs\b/, ""]]
38
+ describe "when converting from English to Japanese" do
39
+ before :each do
40
+ Dictionary.load "en", "ja", [@dictionary.path]
41
+ end
42
+
43
+ it "should correctly load a simple term" do
44
+ Dictionary.pairs.first.should == [/\bdogs\b/i, "犬"]
45
+ end
46
+
47
+ it "should correctly load a slightly more complex regular expression" do
48
+ Dictionary.pairs[1].should == [/\bcats?\b/i, "猫"]
49
+ end
50
+
51
+ it "should correctly load a manual regular expression" do
52
+ Dictionary.pairs[2].should == [/\.\s?/, "。"]
53
+ end
54
+
55
+ it "should ignore examples for which the source language cannot be found" do
56
+ Dictionary.pairs.keep_if { |t| t[0] == /\bmano\b/i }.empty?.should == true
57
+ end
58
+
59
+ it "should ignore examples for which the target language cannot be found" do
60
+ Dictionary.pairs.keep_if { |t| t[1] == "book" }.empty?.should == true
61
+ end
62
+
63
+ it "should only have a case-insensitive search if the search contains capital letters" do
64
+ Dictionary.pairs[0][0].should == /\bdogs\b/i
65
+ Dictionary.pairs[3][0].should == /\bNorth Carolina\b/
66
+ end
67
+ end
68
+
69
+ describe "when converting from Japanese to English" do
70
+ before :each do
71
+ Dictionary.load "ja", "en", [@dictionary.path]
72
+ end
73
+
74
+ it "should add whitespace to term replacement" do
75
+ Dictionary.pairs.first.should == [/犬/i, "dogs "]
76
+ end
77
+ end
78
+
79
+ describe "when converting from English to Spanish" do
80
+ before :each do
81
+ Dictionary.load "en", "es", [@dictionary.path]
82
+ end
83
+
84
+ it "should not add whitespace to term replacement" do
85
+ Dictionary.pairs[0].should == [/\bmouth\b/i, "boca"]
86
+ end
19
87
  end
20
88
  end
@@ -11,6 +11,10 @@ describe Language do
11
11
  Language.find(:jpn).should == :ja
12
12
  end
13
13
 
14
+ it "should fail to find a made-up language" do
15
+ lambda { Language.find(:black_speech) }.should raise_error InvalidLanguageError
16
+ end
17
+
14
18
  it "should return equal results for both strings and symbols" do
15
19
  Language.find(:english).should == Language.find("english")
16
20
  end
data/spec/tag_spec.rb CHANGED
@@ -6,15 +6,18 @@ describe Tag do
6
6
  before :each do
7
7
  @tags_file = Tempfile.new(["tags", ".tags"])
8
8
  @tags_file.write <<-eos.gsub(/^\s+/, "")
9
- [[KJ-1]]
9
+ [[KJ-0]]
10
10
  > 犬
11
11
  dog
12
- [[KJ-2]]
12
+ [[KJ-1]]
13
13
  > 何ですか。
14
14
  What is it?
15
- [[KJ-3]]
15
+ [[KJ-2]]
16
16
  > 空白
17
- [[KJ-6]]
17
+ [[KJ-3]] #=> comment
18
+ > コメント
19
+ Comment
20
+ [[KJ-5]]
18
21
  > 以上
19
22
  -- end --
20
23
  eos
@@ -22,26 +25,37 @@ describe Tag do
22
25
  @manager = TagManager.new(@tags_file.path)
23
26
  end
24
27
 
25
- it "should accurately read a tag file" do
28
+ it "should accurately read a tag" do
26
29
  @manager.all.should_not == nil
27
- @manager[0].index.should == 1
30
+ @manager[0].index.should == 0
28
31
  @manager[0].original.should == "犬"
29
32
  @manager[0].translated.should == "dog"
30
33
  end
31
34
 
32
- it "should succeed reading multiple lines" do
33
- @manager[1].index.should == 2
35
+ it "should succeed reading multiple tags" do
36
+ @manager[1].index.should == 1
34
37
  @manager[1].original.should == "何ですか。"
35
38
  @manager[1].translated.should == "What is it?"
36
39
  end
37
40
 
38
41
  it "should ignore blank translations" do
39
- @manager[2].index.should == 3
42
+ @manager[2].index.should == 2
40
43
  @manager[2].original.should == "空白"
41
44
  @manager[2].translated.should == nil
42
45
  end
43
46
 
47
+ it "should know whether a tag has been translated" do
48
+ @manager[0].translated?.should == true
49
+ @manager[2].translated?.should == false
50
+ end
51
+
52
+ it "should ignore comments and additional info after an index tag" do
53
+ @manager[3].index.should == 3
54
+ @manager[3].original.should == "コメント"
55
+ @manager[3].translated.should == "Comment"
56
+ end
57
+
44
58
  it "should skip over blank indexes" do
45
- @manager[3].index.should == 6
59
+ @manager[4].index.should == 5
46
60
  end
47
61
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: konjac
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2012-01-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri
16
- requirement: &70101148958680 !ruby/object:Gem::Requirement
16
+ requirement: &70265140795800 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70101148958680
24
+ version_requirements: *70265140795800
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: bundler
27
- requirement: &70101148958040 !ruby/object:Gem::Requirement
27
+ requirement: &70265140794440 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70101148958040
35
+ version_requirements: *70265140794440
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rspec
38
- requirement: &70101148683020 !ruby/object:Gem::Requirement
38
+ requirement: &70265140793660 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70101148683020
46
+ version_requirements: *70265140793660
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: sdoc
49
- requirement: &70101148682400 !ruby/object:Gem::Requirement
49
+ requirement: &70265140792780 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70101148682400
57
+ version_requirements: *70265140792780
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: autotest
60
- requirement: &70101148681900 !ruby/object:Gem::Requirement
60
+ requirement: &70265140791700 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70101148681900
68
+ version_requirements: *70265140791700
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: autotest-fsevent
71
- requirement: &70101148681460 !ruby/object:Gem::Requirement
71
+ requirement: &70265140790860 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70101148681460
79
+ version_requirements: *70265140790860
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: autotest-growl
82
- requirement: &70101148681040 !ruby/object:Gem::Requirement
82
+ requirement: &70265140789760 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,7 +87,7 @@ dependencies:
87
87
  version: '0'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *70101148681040
90
+ version_requirements: *70265140789760
91
91
  description: A Ruby command-line utility for translating files using a YAML wordlist
92
92
  email:
93
93
  - bryan.mckelvey@gmail.com
@@ -107,6 +107,8 @@ files:
107
107
  - konjac.gemspec
108
108
  - lib/konjac.rb
109
109
  - lib/konjac/cli.rb
110
+ - lib/konjac/cli/sub_command.rb
111
+ - lib/konjac/cli/sub_command_manager.rb
110
112
  - lib/konjac/dictionary.rb
111
113
  - lib/konjac/exception.rb
112
114
  - lib/konjac/language.rb