Skip to content

Commit

Permalink
Removed Ruby 1.8.x/IConv/FasterCSV support
Browse files Browse the repository at this point in the history
Removed Rails 2.x support
Added BOM (Byte Order Mark) for UTF-16LE
Added support for UTF-16LE for MS Excel
Convert \r\n\t to whitespace
Specs update
  • Loading branch information
deltadd committed Feb 8, 2012
1 parent a4550a7 commit 77eda67
Show file tree
Hide file tree
Showing 10 changed files with 33 additions and 42 deletions.
3 changes: 1 addition & 2 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ Jeweler::Tasks.new do |gem|
gem.add_development_dependency 'rack'
gem.add_development_dependency 'sqlite3'

gem.requirements << 'iconv'
gem.requirements << 'Ruby 1.9.x or FasterCSV'
gem.requirements << 'Ruby 1.9.x'
end
Jeweler::RubygemsDotOrgTasks.new
2 changes: 1 addition & 1 deletion csv_builder.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Gem::Specification.new do |s|
s.homepage = %q{http://github.com/dasil003/csv_builder}
s.licenses = [%q{MIT}]
s.require_paths = [%q{lib}]
s.requirements = [%q{iconv}, %q{Ruby 1.9.x or FasterCSV}]
s.requirements = [%q{Ruby 1.9.x}]
s.rubygems_version = %q{1.8.6}
s.summary = %q{CSV template handler for Rails}

Expand Down
11 changes: 2 additions & 9 deletions lib/csv_builder.rb
Original file line number Diff line number Diff line change
@@ -1,17 +1,10 @@
# encoding: utf-8
require 'csv'
require 'action_view'

module CsvBuilder
if RUBY_VERSION.to_f >= 1.9
require 'csv'
CSV_LIB = CSV
else
require 'fastercsv'
CSV_LIB = FasterCSV
end
end

require 'action_view'
require 'iconv'
require 'csv_builder/transliterating_filter'
require 'csv_builder/template_handler'
require 'csv_builder/railtie'
2 changes: 1 addition & 1 deletion lib/csv_builder/railtie.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class CsvBuilder::Railtie < Rails::Railtie
initializer "csv_builder.register_template_handler.action_view" do
ActionView::Template.register_template_handler 'csvbuilder', CsvBuilder::TemplateHandler
ActionView::Template.register_template_handler :csvbuilder, CsvBuilder::TemplateHandler
end
end
25 changes: 16 additions & 9 deletions lib/csv_builder/template_handler.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# encoding: utf-8

module CsvBuilder # :nodoc:

BOM = "\377\376" # Start characters for UTF-16LE

# Template handler for csv templates
#
# Add rows to your CSV file in the template by pushing arrays of columns into csv
Expand All @@ -23,12 +26,6 @@ module CsvBuilder # :nodoc:
#
# @output_encoding = 'UTF-8'

if defined?(Rails) and Rails.version < '3'
class TemplateHandler < ActionView::Template::Handler
include ActionView::Template::Handlers::Compilable
end
end

# The ruby csv class will try to infer a separator to use, if the csv options
# do not set it. ruby's csv calls pos, eof?, read, and rewind to check the first line
# of the io to infer a separator. Rails' output object does not support these methods
Expand Down Expand Up @@ -81,7 +78,7 @@ def initialize(template_proc)

def each
yielder = CsvBuilder::Yielder.new(Proc.new{|data| yield data})
csv_stream = CsvBuilder::CSV_LIB.new(yielder, @csv_options || {})
csv_stream = CSV.new(yielder, @csv_options || {})
csv = CsvBuilder::TransliteratingFilter.new(csv_stream, @input_encoding || 'UTF-8', @output_encoding || 'LATIN1')
@template_proc.call(csv)
end
Expand Down Expand Up @@ -113,11 +110,21 @@ def self.call(template)
#{template.source}
}
CsvBuilder::Streamer.new(template)
else
output = CsvBuilder::CSV_LIB.generate(@csv_options || {}) do |faster_csv|
else
output = CSV.generate(@csv_options || {}) do |faster_csv|
csv = CsvBuilder::TransliteratingFilter.new(faster_csv, @input_encoding || 'UTF-8', @output_encoding || 'LATIN1')
#{template.source}
end
@output_encoding ||= 'UTF-8'
output.force_encoding('UTF-8')
if @output_encoding == 'UTF-16LE'
bom = String.new(CsvBuilder::BOM)
output = bom.force_encoding(@output_encoding) + output.encode(@output_encoding)
else
output = output.encode(@output_encoding)
end
output
end
rescue Exception => e
Expand Down
19 changes: 5 additions & 14 deletions lib/csv_builder/transliterating_filter.rb
Original file line number Diff line number Diff line change
@@ -1,23 +1,14 @@
#encoding: utf-8

class CsvBuilder::TransliteratingFilter
# Transliterate into the required encoding if necessary
def initialize(faster_csv, input_encoding = 'UTF-8', output_encoding = 'LATIN1')
@faster_csv = faster_csv

# TODO: do some checking to make sure iconv works correctly in
# current environment. See ActiveSupport::Inflector#transliterate
# definition for details
#
# Not using the more standard //IGNORE//TRANSLIT because it raises
# Iconv::IllegalSequence for some inputs
@iconv = Iconv.new("#{output_encoding}//TRANSLIT//IGNORE", input_encoding) if input_encoding != output_encoding
def initialize(csv, input_encoding = 'UTF-8', output_encoding = 'LATIN1')
@csv = csv
end

# Transliterate before passing to FasterCSV so that the right characters (e.g. quotes) get escaped

def <<(row)
@faster_csv << if @iconv then row.map { |value| @iconv.iconv(value.to_s) } else row end
@csv << row.map { |value| value.to_s.gsub(/\r|\n|\t/, ' ') }
end

alias :add_row :<<
end
2 changes: 1 addition & 1 deletion rails/init.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
require 'csv_builder'

ActionView::Template.register_template_handler 'csvbuilder', CsvBuilder::TemplateHandler
ActionView::Template.register_template_handler :csvbuilder, CsvBuilder::TemplateHandler
7 changes: 5 additions & 2 deletions spec/controllers/csv_builder_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def complex

def encoding
respond_to do |format|
format.csv { @output_encoding = 'UTF-16' }
format.csv { @output_encoding = 'UTF-16LE' }
end
end

Expand Down Expand Up @@ -63,7 +63,10 @@ def massive
describe "Layout with options" do
it "sets output encoding correctly" do
get 'encoding', :format => 'csv'
correct_output = generate({}, [Iconv.iconv('UTF-16//TRANSLIT//IGNORE', 'UTF-8', 'ąčęėįšųūž')])

bom = String.new(CsvBuilder::BOM)
correct_output = bom.force_encoding('UTF-16LE') + "ąčęėįšųūž\n".encode('UTF-16LE')

response.body.to_s.should == correct_output
end

Expand Down
2 changes: 0 additions & 2 deletions spec/rails_app/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,3 @@ source 'http://rubygems.org'
gemspec :path => File.expand_path(File.join(File.dirname(__FILE__), '../..'))

gem 'csv_builder', :path => '../..'

gem 'fastercsv', :platforms => :ruby_18
2 changes: 1 addition & 1 deletion spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
]

def generate(options = {}, data = TEST_DATA)
CsvBuilder::CSV_LIB.generate(options) do |csv|
CSV.generate(options) do |csv|
data.each do |row|
csv << row
end
Expand Down

0 comments on commit 77eda67

Please sign in to comment.