Permalink
Browse files

initial import

  • Loading branch information...
0 parents commit ef06ca5648c6631e6915b638e8a4f273a4cba798 @shaiguitar committed Mar 11, 2013
Showing with 461 additions and 0 deletions.
  1. +17 −0 .gitignore
  2. +4 −0 Gemfile
  3. +22 −0 LICENSE
  4. +29 −0 README.md
  5. +49 −0 Rakefile
  6. +27 −0 haml-i18n-extractor.gemspec
  7. +11 −0 lib/haml-i18n-extractor.rb
  8. +94 −0 lib/haml-i18n-extractor/find_text.rb
  9. +7 −0 lib/haml-i18n-extractor/version.rb
  10. +110 −0 test/find_text_test.rb
  11. +91 −0 test/test_helper.rb
@@ -0,0 +1,17 @@
+*.gem
+*.rbc
+.bundle
+.config
+.yardoc
+Gemfile.lock
+InstalledFiles
+_yardoc
+coverage
+doc/
+lib/bundler/man
+pkg
+rdoc
+spec/reports
+test/tmp
+test/version_tmp
+tmp
@@ -0,0 +1,4 @@
+source 'https://rubygems.org'
+
+# Specify your gem's dependencies in haml-i18n-extractor.gemspec
+gemspec
22 LICENSE
@@ -0,0 +1,22 @@
+Copyright (c) 2013 Shai Rosenfeld
+
+MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,29 @@
+# Haml::I18n::Extractor
+
+TODO: Write a gem description
+
+## Installation
+
+Add this line to your application's Gemfile:
+
+ gem 'haml-i18n-extractor'
+
+And then execute:
+
+ $ bundle
+
+Or install it yourself as:
+
+ $ gem install haml-i18n-extractor
+
+## Usage
+
+TODO: Write usage instructions here
+
+## Contributing
+
+1. Fork it
+2. Create your feature branch (`git checkout -b my-new-feature`)
+3. Commit your changes (`git commit -am 'Added some feature'`)
+4. Push to the branch (`git push origin my-new-feature`)
+5. Create new Pull Request
@@ -0,0 +1,49 @@
+#!/usr/bin/env rake
+require "bundler/gem_tasks"
+require 'rake/testtask'
+
+def with_each_gemfile
+ old_env = ENV['BUNDLE_GEMFILE']
+ gemfiles.each do |gemfile|
+ puts "Using gemfile: #{gemfile}"
+ ENV['BUNDLE_GEMFILE'] = gemfile
+ yield
+ end
+ensure
+ ENV['BUNDLE_GEMFILE'] = old_env
+end
+
+def silence_warnings
+ the_real_stderr, $stderr = $stderr, StringIO.new
+ yield
+ensure
+ $stderr = the_real_stderr
+end
+
+Rake::TestTask.new do |t|
+ t.libs << 'lib' << 'test'
+ t.test_files = Dir["test/**/*_test.rb"]
+ t.warning = true
+ t.verbose = true
+end
+
+task :default => :test
+namespace :test do
+ namespace :bundles do
+ desc "Install all dependencies necessary to test."
+ task :install do
+ with_each_gemfile {sh "bundle"}
+ end
+
+ desc "Update all dependencies for testing."
+ task :update do
+ with_each_gemfile {sh "bundle update"}
+ end
+ end
+
+ desc "Test all supported versions of rails. This takes a while."
+ task :rails_compatibility => 'test:bundles:install' do
+ with_each_gemfile {sh "bundle exec rake test"}
+ end
+ task :rc => :rails_compatibility
+end
@@ -0,0 +1,27 @@
+# -*- encoding: utf-8 -*-
+require File.expand_path('../lib/haml-i18n-extractor/version', __FILE__)
+
+Gem::Specification.new do |gem|
+ gem.authors = ["Shai Rosenfeld"]
+ gem.email = ["shaiguitar@gmail.com"]
+ gem.description = %q{Parse the texts out of the haml files into localization files}
+ gem.summary = %q{Parse the texts out of the haml files into localization files}
+ gem.homepage = ""
+
+ gem.files = `git ls-files`.split($\)
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
+ gem.name = "haml-i18n-extractor"
+ gem.require_paths = ["lib"]
+ gem.version = Haml::I18n::Extractor::VERSION
+
+ gem.add_dependency "tilt"
+ gem.add_dependency "haml"
+
+ gem.add_development_dependency 'rails', '>= 3.0.0'
+ gem.add_development_dependency 'rbench'
+ gem.add_development_dependency 'pry'
+ gem.add_development_dependency 'minitest'
+ gem.add_development_dependency 'nokogiri'
+
+end
@@ -0,0 +1,11 @@
+require "haml-i18n-extractor/version"
+require "haml-i18n-extractor/find_text"
+
+module Haml
+ module I18n
+ module Extractor
+
+
+ end
+ end
+end
@@ -0,0 +1,94 @@
+require 'haml'
+require 'haml/parser'
+module Haml
+ module I18n
+ module Extractor
+ class FindText
+
+ def initialize(haml)
+ @haml = haml
+ @parser = Haml::Parser.new(haml, Haml::Options.new)
+ create_lines(@haml)
+ end
+
+ def create_lines(haml)
+ match = haml.rstrip.scan(/(([ \t]+)?(.*?))(?:\Z|\r\n|\r|\n)/m)
+ match.pop
+ match.each_with_index.map do |(full, whitespace, text), index|
+ Haml::Parser::Line.new(whitespace, text.rstrip, full, index, @parser, false)
+ end
+ end
+
+ def run
+ result = []
+ create_lines(@haml).each{|line|
+ if txt = plain_text(line)
+ result << txt
+ end
+ }
+ result.compact
+ end
+
+ THINGS_THAT_ARE_NOT_TEXT = [ Haml::Parser::DIV_CLASS, Haml::Parser::DIV_ID,
+ Haml::Parser::COMMENT, Haml::Parser::SANITIZE, Haml::Parser::FLAT_SCRIPT,
+ Haml::Parser::FILTER, Haml::Parser::DOCTYPE, Haml::Parser::ESCAPE ]
+
+ ## hint: Use http://rubular.com
+ SIMPLE_STRING_REGEX = /["'](.*)["']/
+ # = "yes"
+ # = 'yes'
+ LINK_TO_REGEX = /link_to\s*\(?\s*['"](.*)['"]\s*,\s*(.*)\)?/
+ # = link_to "yes", "http://bla.com"
+ # = link_to('yes' , "http://bla.com")
+ # = link_to( "yes's w space", "http://bla.com")
+ ELEMENT_REGEX = /%([\w.#-]+)({.+?})?(=)?(.*)/
+ # %foo.bar yes
+ # %foo.bar= no
+ # %foo{:a => 'b'} yes
+ # rubular.com against %foo#bar#cheez{:cheeze => 'hell'}= "what #{var}"
+
+ def plain_text(line)
+ case line.full[0]
+ when *THINGS_THAT_ARE_NOT_TEXT
+ nil
+ when Haml::Parser::SILENT_SCRIPT
+ parse_silent_script(line)
+ when Haml::Parser::ELEMENT
+ parse_element(line)
+ when Haml::Parser::SCRIPT
+ parse_loud_script(line)
+ else
+ line.full.strip
+ end
+ end
+
+ private
+
+ def parse_silent_script(line)
+ line.full.match(/-[\s\t]*#{SIMPLE_STRING_REGEX}/) && $1
+ end
+
+ def parse_loud_script(line)
+ line.full.match(/=[\s\t]*#{LINK_TO_REGEX}/)
+ return $1 if text = $1
+ line.full.match(/=[\s\t]*#{SIMPLE_STRING_REGEX}/)
+ return $1
+ end
+
+ def parse_element(line)
+ line.full.match(ELEMENT_REGEX)
+ elem_with_class_and_ids = $1
+ attributes_ruby_style = $2
+ is_loud_script = $3
+ text = $4
+ if is_loud_script
+ parse_loud_script(create_lines("= #{text}").first) # just treat it like a loud script
+ else
+ text.strip
+ end
+ end
+
+ end
+ end
+ end
+end
@@ -0,0 +1,7 @@
+module Haml
+ module I18n
+ module Extractor
+ VERSION = "0.0.1"
+ end
+ end
+end
@@ -0,0 +1,110 @@
+require 'test_helper'
+
+module Haml
+ class StringFinderTest < MiniTest::Unit::TestCase
+
+ # TODO when translating the text found to t() make sure to take into account duplicates of the same entry.
+
+ # regular text mode
+ test "silent scripts with strings and regular text" do
+ assert_equal find_text("iphone"), ["iphone"]
+ assert_equal find_text(" iphone4"), ["iphone4"]
+ end
+
+ # silent script mode
+ test "silent scripts with strings" do
+ assert_equal find_text("- 'jessica'"), ["jessica"]
+ end
+
+ test "silent scripts with strings" do
+ assert_equal find_text("Sheen"), ["Sheen"]
+ end
+
+ # html element mode
+ test "%tag Text" do
+ assert_equal find_text("%span Text to find"), ["Text to find"]
+ end
+
+ test "%tag Text with class" do
+ assert_equal find_text("%span.whatever-with-thing Text to find"), ["Text to find"]
+ end
+
+ test "%tag Text with ruby eval code" do
+ assert_equal find_text("%span= ruby_eval_code"), []
+ end
+
+ test "%tag Text with ruby eval code and class" do
+ assert_equal find_text( "%span#whatever-with-thing= ruby_eval_code"), []
+ end
+
+ test "Ruby style tags %a{'href' => 'http://whatever'} whatever" do
+ assert_equal find_text("%a{'href' => 'http://whatever'} whatever"), ["whatever"]
+ end
+
+ # loud scripts / ruby eval mode
+ test "loud scripts with strings" do
+ assert_equal find_text('= "bob"'), ["bob"]
+ assert_equal find_text("= 'bob'"), ["bob"]
+ end
+
+ test "loud scripts does not interpolate ruby vars in strings" do
+ assert_equal find_text('= "ruby can #{var}"'), ["ruby can \#{var}"]
+ end
+
+ # special loud scripts exceptions
+ test "it finds link_to texts as an exception to the rule" do
+ assert_equal find_text('= link_to "This should be found", "/"'), ["This should be found"]
+ end
+
+ test "it finds link_to texts as an exception to the rule and does not interpolate" do
+ assert_equal find_text('= "Statistics for #{@name}"'), ["Statistics for \#{@name}"]
+ end
+
+ # html element mode with ruby evaling
+ test "html element with ruby eval with strings" do
+ assert_equal find_text('%p= "bob"'), ["bob"]
+ assert_equal find_text("%p.what= 'bob'"), ["bob"]
+ assert_equal find_text("%p.what{:attr => :val}= 'bob'"), ["bob"]
+ end
+
+ test "html element loud scripts does not interpolate ruby vars in strings" do
+ assert_equal find_text('%p= "ruby can #{var}"'), ["ruby can \#{var}"]
+ assert_equal find_text('%p.what= "ruby can #{var}"'), ["ruby can \#{var}"]
+ assert_equal find_text('%p.what{:attr => :val}= "ruby can #{var}"'), ["ruby can \#{var}"]
+ end
+
+ test "html element it finds link_to texts as an exception to the rule" do
+ assert_equal find_text('%p= link_to "This should be found", "/"'), ["This should be found"]
+ assert_equal find_text('%p.what= link_to "This should be found", "/"'), ["This should be found"]
+ assert_equal find_text('%p.what{:attr => :val}= link_to "This should be found", "/"'), ["This should be found"]
+ end
+
+ test "html element it finds link_to texts as an exception to the rule and does not interpolate" do
+ assert_equal find_text('%p= "Statistics for #{@name}"'), ["Statistics for \#{@name}"]
+ assert_equal find_text('%p.what= "Statistics for #{@name}"'), ["Statistics for \#{@name}"]
+ assert_equal find_text('%p.what{:attr => :val}= "Statistics for #{@name}"'), ["Statistics for \#{@name}"]
+ end
+
+ private
+
+ def find_text(haml)
+ output_haml_debug(haml) if ENV['DEBUG']
+ find_text = Haml::I18n::Extractor::FindText.new(haml) # this is on a line per-line basis.
+ find_text.run
+ end
+
+ def output_haml_debug(haml)
+ begin
+ 6.times do puts ; end
+ puts haml
+ 2.times do puts ; end
+ r = Haml::Engine.new(haml).render
+ puts r
+ 6.times do puts; end
+ rescue => e
+ puts e.message
+ end
+ end
+
+ end
+end
Oops, something went wrong.

0 comments on commit ef06ca5

Please sign in to comment.