threedaymonk-l10nizer 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +54 -0
- data/bin/l10nizer +21 -0
- data/lib/l10nizer.rb +2 -0
- data/lib/l10nizer/grammar.treetop +49 -0
- data/lib/l10nizer/keygen.rb +33 -0
- data/lib/l10nizer/node.rb +96 -0
- data/lib/l10nizer/parser.rb +17 -0
- data/lib/l10nizer/processor.rb +23 -0
- data/lib/l10nizer/version.rb +9 -0
- data/test/samples/input.html.erb +34 -0
- data/test/samples/output.html.erb +34 -0
- data/test/test_key_generator.rb +56 -0
- data/test/test_processor.rb +105 -0
- metadata +96 -0
data/Rakefile
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "rake/gempackagetask"
|
3
|
+
require "rake/testtask"
|
4
|
+
require "lib/l10nizer/version"
|
5
|
+
|
6
|
+
task :default => [:test]
|
7
|
+
|
8
|
+
Rake::TestTask.new("test") do |t|
|
9
|
+
t.libs << "test"
|
10
|
+
t.pattern = "test/**/test_*.rb"
|
11
|
+
t.verbose = true
|
12
|
+
end
|
13
|
+
|
14
|
+
task :default => :test
|
15
|
+
|
16
|
+
require "rake/testtask"
|
17
|
+
Rake::TestTask.new do |t|
|
18
|
+
t.libs << "test"
|
19
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
20
|
+
t.verbose = true
|
21
|
+
end
|
22
|
+
|
23
|
+
spec = Gem::Specification.new do |s|
|
24
|
+
s.name = "l10nizer"
|
25
|
+
s.version = L10nizer::VERSION::STRING
|
26
|
+
s.summary = "Automatically extract strings from ERB templates and replace with calls to t()"
|
27
|
+
s.author = "Paul Battley"
|
28
|
+
s.email = "pbattley@gmail.com"
|
29
|
+
|
30
|
+
s.has_rdoc = false
|
31
|
+
|
32
|
+
s.files = %w(Rakefile) + Dir.glob("{bin,test,lib}/**/*")
|
33
|
+
s.executables = FileList["bin/**"].map { |f| File.basename(f) }
|
34
|
+
|
35
|
+
s.require_paths = ["lib"]
|
36
|
+
|
37
|
+
s.add_dependency("treetop", "~> 1.2.6")
|
38
|
+
s.add_dependency("polyglot", "~> 0.2.5")
|
39
|
+
|
40
|
+
s.add_development_dependency("shoulda")
|
41
|
+
end
|
42
|
+
|
43
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
44
|
+
pkg.gem_spec = spec
|
45
|
+
|
46
|
+
# Generate the gemspec file for github.
|
47
|
+
file = File.dirname(__FILE__) + "/#{spec.name}.gemspec"
|
48
|
+
File.open(file, "w") {|f| f << spec.to_ruby }
|
49
|
+
end
|
50
|
+
|
51
|
+
desc 'Clear out generated packages'
|
52
|
+
task :clean => [:clobber_package] do
|
53
|
+
rm "#{spec.name}.gemspec"
|
54
|
+
end
|
data/bin/l10nizer
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "l10nizer"
|
3
|
+
require "yaml"
|
4
|
+
|
5
|
+
keygen = L10nizer::KeyGenerator.new
|
6
|
+
l10ns = {}
|
7
|
+
|
8
|
+
templates = Dir["app/views/**/*.html.erb"]
|
9
|
+
templates.each do |path|
|
10
|
+
keygen.namespace = path.split("/")[2 .. -2] * "_"
|
11
|
+
source = File.read(path)
|
12
|
+
l10nizer = L10nizer::Processor.new(source, keygen)
|
13
|
+
l10ns.merge!(l10nizer.l10ns)
|
14
|
+
File.open(path, "w") do |f|
|
15
|
+
f << l10nizer.reformed
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
File.open("config/locales/l10nized.yml", "w") do |f|
|
20
|
+
f << l10ns.to_yaml
|
21
|
+
end
|
data/lib/l10nizer.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
grammar HtmlErb
|
2
|
+
rule document
|
3
|
+
(html_comment / javascript / erb_control / whitespace / just_erb_eval / text / tag)* <Document>
|
4
|
+
end
|
5
|
+
|
6
|
+
rule html_comment
|
7
|
+
"<!--" ([^\-] / "-" [^\-] / "--" [^>])* "-->"
|
8
|
+
end
|
9
|
+
|
10
|
+
rule javascript
|
11
|
+
"<script" ([^<] / "<" [^/] / "</" [^s] / "</s" [^c] / "</sc" [^r] / "</scr" [^i] / "</scri" [^p] / "</scrip" [^t] / "</script" [^>"])* "</script>"
|
12
|
+
end
|
13
|
+
|
14
|
+
rule erb_control
|
15
|
+
"<%" [^=] ruby_code "%>"
|
16
|
+
end
|
17
|
+
|
18
|
+
rule tag
|
19
|
+
"<" (erb_eval / [^>])+ ">"
|
20
|
+
end
|
21
|
+
|
22
|
+
rule whitespace
|
23
|
+
[\s]+
|
24
|
+
end
|
25
|
+
|
26
|
+
rule optional_whitespace
|
27
|
+
[\s]*
|
28
|
+
end
|
29
|
+
|
30
|
+
rule just_erb_eval
|
31
|
+
(optional_whitespace erb_eval)+
|
32
|
+
end
|
33
|
+
|
34
|
+
rule text
|
35
|
+
(optional_whitespace erb_eval / optional_whitespace word)+ <Text>
|
36
|
+
end
|
37
|
+
|
38
|
+
rule word
|
39
|
+
[^<\s]+
|
40
|
+
end
|
41
|
+
|
42
|
+
rule erb_eval
|
43
|
+
"<%=" ruby_code "%>" <Eval>
|
44
|
+
end
|
45
|
+
|
46
|
+
rule ruby_code
|
47
|
+
(("%" [^>]) / [^%])+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module L10nizer
|
2
|
+
class KeyGenerator
|
3
|
+
attr_accessor :namespace
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@seen = {}
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(string)
|
10
|
+
provisional = [make_safe(namespace), make_safe(string)].compact * "."
|
11
|
+
|
12
|
+
until try(provisional, string)
|
13
|
+
provisional.sub!(/(?:_\d+)?$/){ |m| "_" + m.to_i.succ.to_s }
|
14
|
+
end
|
15
|
+
|
16
|
+
return provisional
|
17
|
+
end
|
18
|
+
|
19
|
+
def try(key, string)
|
20
|
+
if [nil, string].include?(@seen[key])
|
21
|
+
@seen[key] = string
|
22
|
+
true
|
23
|
+
else
|
24
|
+
false
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def make_safe(string)
|
29
|
+
return nil if string.nil?
|
30
|
+
string.downcase.gsub(/[^a-z0-9]+/, "_").gsub(/^_|_$/, "")[0, 40]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module L10nizer
|
2
|
+
class NodeWrapperFactory
|
3
|
+
def self.wrap(node, keygen=nil)
|
4
|
+
case node
|
5
|
+
when HtmlErb::Text
|
6
|
+
TextNode.new(node, keygen)
|
7
|
+
when HtmlErb::Eval
|
8
|
+
EvalNode.new(node, keygen)
|
9
|
+
else
|
10
|
+
BasicNode.new(node)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class BasicNode
|
16
|
+
def initialize(node, keygen=nil)
|
17
|
+
@node = node
|
18
|
+
@keygen = keygen
|
19
|
+
end
|
20
|
+
|
21
|
+
def l10n
|
22
|
+
{}
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_s
|
26
|
+
@node.text_value
|
27
|
+
end
|
28
|
+
|
29
|
+
def evaluated?
|
30
|
+
false
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class TextNode < BasicNode
|
35
|
+
def l10n
|
36
|
+
_, text = vars_and_text
|
37
|
+
text ? {key => text} : {}
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_s
|
41
|
+
vars, _ = vars_and_text
|
42
|
+
return super unless vars
|
43
|
+
|
44
|
+
params = ['"' + key + '"']
|
45
|
+
vars.each_with_index do |v, i|
|
46
|
+
params << %{:#{variable_name(i)} => #{v}}
|
47
|
+
end
|
48
|
+
|
49
|
+
%{<%= t(#{params * ", "}) %>}
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
def children
|
54
|
+
@node.children.map{ |e| NodeWrapperFactory.wrap(e) }
|
55
|
+
end
|
56
|
+
|
57
|
+
def variable_name(index)
|
58
|
+
("a" .. "z").to_a[index]
|
59
|
+
end
|
60
|
+
|
61
|
+
def vars_and_text
|
62
|
+
@vars_and_text ||= (
|
63
|
+
if children.all?{ |c| c.evaluated? }
|
64
|
+
[]
|
65
|
+
else
|
66
|
+
l10n = ""
|
67
|
+
vars = []
|
68
|
+
children.each do |e|
|
69
|
+
if e.evaluated?
|
70
|
+
l10n << "{{#{variable_name(vars.length)}}}"
|
71
|
+
vars << e.to_s
|
72
|
+
else
|
73
|
+
l10n << e.to_s
|
74
|
+
end
|
75
|
+
end
|
76
|
+
[vars, l10n]
|
77
|
+
end
|
78
|
+
)
|
79
|
+
end
|
80
|
+
|
81
|
+
def key
|
82
|
+
_, text = vars_and_text
|
83
|
+
@key ||= @keygen.call(text)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
class EvalNode < BasicNode
|
88
|
+
def to_s
|
89
|
+
super[/\A<%=\s*(.*?)\s*%>\Z/, 1]
|
90
|
+
end
|
91
|
+
|
92
|
+
def evaluated?
|
93
|
+
true
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "treetop"
|
2
|
+
require "polyglot"
|
3
|
+
require "l10nizer/grammar"
|
4
|
+
|
5
|
+
module HtmlErb
|
6
|
+
class Document < Treetop::Runtime::SyntaxNode
|
7
|
+
end
|
8
|
+
|
9
|
+
class Text < Treetop::Runtime::SyntaxNode
|
10
|
+
def children
|
11
|
+
elements.map{ |e| e.elements }.flatten
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class Eval < Treetop::Runtime::SyntaxNode
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "l10nizer/parser"
|
2
|
+
require "l10nizer/node"
|
3
|
+
|
4
|
+
module L10nizer
|
5
|
+
class Processor
|
6
|
+
def initialize(html, keygen)
|
7
|
+
@html = html
|
8
|
+
@keygen = keygen
|
9
|
+
end
|
10
|
+
|
11
|
+
def l10ns
|
12
|
+
processed.inject({}){ |hash, node| hash.merge(node.l10n) }
|
13
|
+
end
|
14
|
+
|
15
|
+
def reformed
|
16
|
+
processed.map{ |e| e.to_s }.join
|
17
|
+
end
|
18
|
+
|
19
|
+
def processed
|
20
|
+
@processed ||= HtmlErbParser.new.parse(@html).elements.map{ |e| NodeWrapperFactory.wrap(e, @keygen) }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
<li id="action_<%=h thing.whatsit.id %>" class="item underway">
|
2
|
+
<div class="wrap">
|
3
|
+
<div class="placeholder">
|
4
|
+
<%- if thing.whatsit.identity? -%>
|
5
|
+
<%- if thing.whatsit.identity.processed? -%>
|
6
|
+
<%= image_tag thing.whatsit.identity.url(:medium) %>
|
7
|
+
<%- else -%>
|
8
|
+
<%= t("general.processing_image") %>
|
9
|
+
<%- end -%>
|
10
|
+
<%- end -%>
|
11
|
+
</div>
|
12
|
+
<h3>
|
13
|
+
<% link_to(thing) do %>
|
14
|
+
<span><%=h thing.whatsit.name %></span><%=h thing.short_address %>
|
15
|
+
<% end %>
|
16
|
+
</h3>
|
17
|
+
</div>
|
18
|
+
<div class="details">
|
19
|
+
<div class="format">
|
20
|
+
<h4 class="obfuscate">Skills</h4>
|
21
|
+
<ul class="skills">
|
22
|
+
<% thing.whatsit.skills.each do |skill| %>
|
23
|
+
<li class="skill">
|
24
|
+
<%= skill_icon(skill, :small) %>
|
25
|
+
</li>
|
26
|
+
<% end %>
|
27
|
+
<li class="engagement">
|
28
|
+
<%= engagement_icon(4, :small) %>
|
29
|
+
</li>
|
30
|
+
</ul>
|
31
|
+
<%=h truncate(thing.whatsit.short_description, :length => 130) %>
|
32
|
+
</div>
|
33
|
+
</div>
|
34
|
+
</li>
|
@@ -0,0 +1,34 @@
|
|
1
|
+
<li id="action_<%=h thing.whatsit.id %>" class="item underway">
|
2
|
+
<div class="wrap">
|
3
|
+
<div class="placeholder">
|
4
|
+
<%- if thing.whatsit.identity? -%>
|
5
|
+
<%- if thing.whatsit.identity.processed? -%>
|
6
|
+
<%= image_tag thing.whatsit.identity.url(:medium) %>
|
7
|
+
<%- else -%>
|
8
|
+
<%= t("general.processing_image") %>
|
9
|
+
<%- end -%>
|
10
|
+
<%- end -%>
|
11
|
+
</div>
|
12
|
+
<h3>
|
13
|
+
<% link_to(thing) do %>
|
14
|
+
<span><%=h thing.whatsit.name %></span><%=h thing.short_address %>
|
15
|
+
<% end %>
|
16
|
+
</h3>
|
17
|
+
</div>
|
18
|
+
<div class="details">
|
19
|
+
<div class="format">
|
20
|
+
<h4 class="obfuscate"><%= t("skills") %></h4>
|
21
|
+
<ul class="skills">
|
22
|
+
<% thing.whatsit.skills.each do |skill| %>
|
23
|
+
<li class="skill">
|
24
|
+
<%= skill_icon(skill, :small) %>
|
25
|
+
</li>
|
26
|
+
<% end %>
|
27
|
+
<li class="engagement">
|
28
|
+
<%= engagement_icon(4, :small) %>
|
29
|
+
</li>
|
30
|
+
</ul>
|
31
|
+
<%=h truncate(thing.whatsit.short_description, :length => 130) %>
|
32
|
+
</div>
|
33
|
+
</div>
|
34
|
+
</li>
|
@@ -0,0 +1,56 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
|
2
|
+
|
3
|
+
require "test/unit"
|
4
|
+
require "l10nizer/keygen"
|
5
|
+
require "shoulda"
|
6
|
+
|
7
|
+
class KeyGeneratorTest < Test::Unit::TestCase
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@keygen = L10nizer::KeyGenerator.new
|
11
|
+
end
|
12
|
+
|
13
|
+
context "without namespacing" do
|
14
|
+
should "generate keys based on string" do
|
15
|
+
assert_equal "foo_bar_baz_a", @keygen.call("Foo bar baz {{a}}")
|
16
|
+
end
|
17
|
+
|
18
|
+
should "truncate exceptionally long keys" do
|
19
|
+
long = "blah_" * 20
|
20
|
+
short = long[0, 40]
|
21
|
+
assert_equal short, @keygen.call(long)
|
22
|
+
end
|
23
|
+
|
24
|
+
should "reuse key for same text" do
|
25
|
+
assert_equal @keygen.call("the same"), @keygen.call("the same")
|
26
|
+
end
|
27
|
+
|
28
|
+
should "prevent duplicate keys for different texts" do
|
29
|
+
assert_equal "a_thing", @keygen.call("a thing")
|
30
|
+
assert_equal "a_thing_1", @keygen.call("A thing")
|
31
|
+
assert_equal "a_thing_2", @keygen.call("A Thing")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "with namespacing" do
|
36
|
+
setup do
|
37
|
+
@keygen.namespace = "ns1"
|
38
|
+
end
|
39
|
+
|
40
|
+
should "prepend namespace" do
|
41
|
+
assert_equal "ns1.foo", @keygen.call("Foo")
|
42
|
+
end
|
43
|
+
|
44
|
+
should "prevent duplicate keys for different texts" do
|
45
|
+
assert_equal "ns1.a_thing", @keygen.call("a thing")
|
46
|
+
assert_equal "ns1.a_thing_1", @keygen.call("A thing")
|
47
|
+
assert_equal "ns1.a_thing_2", @keygen.call("A Thing")
|
48
|
+
end
|
49
|
+
|
50
|
+
should "check duplication by namespace" do
|
51
|
+
assert_equal "ns1.a_thing", @keygen.call("a thing")
|
52
|
+
@keygen.namespace = "ns2"
|
53
|
+
assert_equal "ns2.a_thing", @keygen.call("A thing")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
|
2
|
+
|
3
|
+
require "test/unit"
|
4
|
+
require "l10nizer/processor"
|
5
|
+
require "shoulda"
|
6
|
+
|
7
|
+
class ProcessorTest < Test::Unit::TestCase
|
8
|
+
|
9
|
+
class DumbKeyGenerator
|
10
|
+
def call(string)
|
11
|
+
string.downcase.gsub(/[^a-z0-9]+/, "_").gsub(/^_|_$/, "")[0, 40]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context "when finding text" do
|
16
|
+
setup do
|
17
|
+
html = "just some text"
|
18
|
+
@l10nizer = L10nizer::Processor.new(html, DumbKeyGenerator.new)
|
19
|
+
end
|
20
|
+
|
21
|
+
should "pass key to t()" do
|
22
|
+
expected = %{<%= t("just_some_text") %>}
|
23
|
+
assert_equal expected, @l10nizer.reformed
|
24
|
+
end
|
25
|
+
|
26
|
+
should "extract l10n strings" do
|
27
|
+
expected = {"just_some_text" => "just some text"}
|
28
|
+
assert_equal expected, @l10nizer.l10ns
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "when interpolating inline eval" do
|
33
|
+
setup do
|
34
|
+
html = "String <%= 27 %> with <%= 42 %>"
|
35
|
+
@l10nizer = L10nizer::Processor.new(html, DumbKeyGenerator.new)
|
36
|
+
end
|
37
|
+
|
38
|
+
should "pass values to t()" do
|
39
|
+
expected = %{<%= t("string_a_with_b", :a => 27, :b => 42) %>}
|
40
|
+
assert_equal expected, @l10nizer.reformed
|
41
|
+
end
|
42
|
+
|
43
|
+
should "extract l10n strings" do
|
44
|
+
expected = {"string_a_with_b" => "String {{a}} with {{b}}"}
|
45
|
+
assert_equal expected, @l10nizer.l10ns
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "when interpolating in multiple text strings" do
|
50
|
+
setup do
|
51
|
+
html = "<p>String <%= 27 %> with <%= 42 %></p><p>Another <%= 'x' %></p>"
|
52
|
+
@l10nizer = L10nizer::Processor.new(html, DumbKeyGenerator.new)
|
53
|
+
end
|
54
|
+
|
55
|
+
should "pass values to t() reusing placeholder variables" do
|
56
|
+
expected = %{<p><%= t("string_a_with_b", :a => 27, :b => 42) %></p><p><%= t("another_a", :a => 'x') %></p>}
|
57
|
+
assert_equal expected, @l10nizer.reformed
|
58
|
+
end
|
59
|
+
|
60
|
+
should "extract l10n strings with placeholder variables" do
|
61
|
+
expected = {"string_a_with_b" => "String {{a}} with {{b}}", "another_a" => "Another {{a}}"}
|
62
|
+
assert_equal expected, @l10nizer.l10ns
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
should "not try to localise inline eval on its own" do
|
67
|
+
html = "<p><%= 27 %></p>"
|
68
|
+
l10nizer = L10nizer::Processor.new(html, DumbKeyGenerator.new)
|
69
|
+
assert_equal html, l10nizer.reformed
|
70
|
+
end
|
71
|
+
|
72
|
+
should "not try to localise an HTML comment" do
|
73
|
+
html = "<!-- <p><%= 27 %></p> --> <p> <!-- fooo --> </p>"
|
74
|
+
l10nizer = L10nizer::Processor.new(html, DumbKeyGenerator.new)
|
75
|
+
assert_equal html, l10nizer.reformed
|
76
|
+
end
|
77
|
+
|
78
|
+
should "not try to localise Javascript" do
|
79
|
+
html = "<script>var a = 3;</script> <script>var b = 'b';</script>"
|
80
|
+
l10nizer = L10nizer::Processor.new(html, DumbKeyGenerator.new)
|
81
|
+
assert_equal html, l10nizer.reformed
|
82
|
+
end
|
83
|
+
|
84
|
+
context "when parsing a sample document" do
|
85
|
+
setup do
|
86
|
+
@html = File.read(File.join(File.dirname(__FILE__), "samples", "input.html.erb"))
|
87
|
+
@expected = File.read(File.join(File.dirname(__FILE__), "samples", "output.html.erb"))
|
88
|
+
@l10nizer = L10nizer::Processor.new(@html, DumbKeyGenerator.new)
|
89
|
+
end
|
90
|
+
|
91
|
+
should "replace embedded text" do
|
92
|
+
actual = @l10nizer.reformed
|
93
|
+
#@expected.split(/\n/).zip(actual.split(/\n/)).each do |a, b|
|
94
|
+
# puts a, b unless a == b
|
95
|
+
#end
|
96
|
+
assert_equal @expected, actual
|
97
|
+
end
|
98
|
+
|
99
|
+
should "extract l10n strings" do
|
100
|
+
expected = {"skills" => "Skills"}
|
101
|
+
assert_equal expected, @l10nizer.l10ns
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: threedaymonk-l10nizer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Paul Battley
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-07-10 00:00:00 -07:00
|
13
|
+
default_executable: l10nizer
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: treetop
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ~>
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.2.6
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: polyglot
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.2.5
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: shoulda
|
37
|
+
type: :development
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: "0"
|
44
|
+
version:
|
45
|
+
description:
|
46
|
+
email: pbattley@gmail.com
|
47
|
+
executables:
|
48
|
+
- l10nizer
|
49
|
+
extensions: []
|
50
|
+
|
51
|
+
extra_rdoc_files: []
|
52
|
+
|
53
|
+
files:
|
54
|
+
- Rakefile
|
55
|
+
- bin/l10nizer
|
56
|
+
- test/samples
|
57
|
+
- test/samples/input.html.erb
|
58
|
+
- test/samples/output.html.erb
|
59
|
+
- test/test_key_generator.rb
|
60
|
+
- test/test_processor.rb
|
61
|
+
- lib/l10nizer
|
62
|
+
- lib/l10nizer/grammar.treetop
|
63
|
+
- lib/l10nizer/keygen.rb
|
64
|
+
- lib/l10nizer/node.rb
|
65
|
+
- lib/l10nizer/parser.rb
|
66
|
+
- lib/l10nizer/processor.rb
|
67
|
+
- lib/l10nizer/version.rb
|
68
|
+
- lib/l10nizer.rb
|
69
|
+
has_rdoc: false
|
70
|
+
homepage:
|
71
|
+
post_install_message:
|
72
|
+
rdoc_options: []
|
73
|
+
|
74
|
+
require_paths:
|
75
|
+
- lib
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: "0"
|
81
|
+
version:
|
82
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: "0"
|
87
|
+
version:
|
88
|
+
requirements: []
|
89
|
+
|
90
|
+
rubyforge_project:
|
91
|
+
rubygems_version: 1.2.0
|
92
|
+
signing_key:
|
93
|
+
specification_version: 3
|
94
|
+
summary: Automatically extract strings from ERB templates and replace with calls to t()
|
95
|
+
test_files: []
|
96
|
+
|