movable_erb 0.2.6 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gems +1 -0
- data/CHANGELOG +4 -0
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/bin/movable_erb +11 -2
- data/config.ru +4 -0
- data/features/csv.feature +4 -7
- data/features/step_definitions/csv_steps.rb +1 -3
- data/lib/app.rb +12 -0
- data/lib/templates/mtimport.erb +14 -6
- data/movable_erb.gemspec +12 -5
- data/public/blueprint.css +200 -0
- data/public/custom.css +69 -0
- data/spec/csv_spec.rb +13 -15
- data/tasks/rspec.rake +1 -1
- data/views/index.erb +9 -0
- data/views/layout.erb +27 -0
- metadata +10 -2
data/.gems
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
fastercsv --version='>=1.5.0'
|
data/CHANGELOG
CHANGED
data/Rakefile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
data/bin/movable_erb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
$:.unshift File.expand_path(File.dirname(__FILE__) + "/..")
|
2
3
|
require 'pp'
|
3
4
|
require 'rubygems'
|
4
5
|
require 'lib/trollop'
|
5
|
-
|
6
|
-
require File.expand_path(File.join(File.dirname(__FILE__), %w[.. lib movable_erb]))
|
6
|
+
require 'lib/movable_erb'
|
7
7
|
|
8
8
|
DEFAULT_TEMPLATE = File.expand_path(File.join(File.dirname(__FILE__), %w[.. lib templates mtimport.erb]))
|
9
9
|
|
@@ -22,11 +22,20 @@ opts = Trollop::options do
|
|
22
22
|
# Options
|
23
23
|
opt :separator, "Separator between records", :default => "", :short => '-s'
|
24
24
|
opt :template, "path to ERB template", :default => DEFAULT_TEMPLATE, :short => '-t'
|
25
|
+
banner ""
|
26
|
+
opt :server, "Run movable_erb server (requires Sinatra)"
|
27
|
+
opt :port, "Port to run server on", :default => 4567, :short => '-p'
|
25
28
|
|
26
29
|
# Show the help screen when no file given
|
27
30
|
educate if ARGV.empty?
|
28
31
|
end
|
29
32
|
|
33
|
+
if opts[:server]
|
34
|
+
require 'sinatra/base'
|
35
|
+
require 'lib/app'
|
36
|
+
Sinatra::Application.run!(:port => opts[:port])
|
37
|
+
end
|
38
|
+
|
30
39
|
# Only continue if the CSV file is found
|
31
40
|
Trollop::die "That file could not be found" if ARGV.first && !File.exist?(ARGV.first)
|
32
41
|
|
data/config.ru
ADDED
data/features/csv.feature
CHANGED
@@ -17,24 +17,21 @@ Feature: CSV Conversion
|
|
17
17
|
TITLE: John
|
18
18
|
-----
|
19
19
|
BODY:
|
20
|
-
|
21
20
|
773-123-1234
|
22
21
|
john@example.com
|
23
|
-
|
22
|
+
-----
|
24
23
|
--------
|
25
24
|
TITLE: Abigail
|
26
25
|
-----
|
27
26
|
BODY:
|
28
|
-
|
29
27
|
abby@example.com
|
30
|
-
|
28
|
+
-----
|
31
29
|
--------
|
32
30
|
TITLE: Bernard
|
33
31
|
-----
|
34
32
|
BODY:
|
35
|
-
|
36
33
|
903-294-3921
|
37
|
-
|
34
|
+
-----
|
38
35
|
--------
|
39
|
-
|
36
|
+
|
40
37
|
"""
|
@@ -3,12 +3,10 @@ Given /^I am on the commandline$/ do
|
|
3
3
|
end
|
4
4
|
|
5
5
|
When /^I invoke the utility with the following CSV file:?$/ do |string|
|
6
|
-
File.open(File.dirname(__FILE__) + '/tmp.csv', 'w') {|f| f.write(string) }
|
7
|
-
puts FasterCSV.parse(string).inspect
|
6
|
+
File.open(File.dirname(__FILE__) + '/tmp.csv', 'w') {|f| f.write(string) }
|
8
7
|
@erb = MovableErb.new({:csv => File.dirname(__FILE__) + '/tmp.csv', :separator => ''})
|
9
8
|
end
|
10
9
|
|
11
10
|
Then /^I should see the following output:?$/ do |string|
|
12
|
-
puts @erb.csv.to_hashes.inspect
|
13
11
|
@erb.convert.should == string
|
14
12
|
end
|
data/lib/app.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
%w{rubygems sinatra erb lib/movable_erb}.each { |lib| require lib }
|
2
|
+
|
3
|
+
set :root, File.expand_path(File.dirname(__FILE__) + '/..')
|
4
|
+
|
5
|
+
get '/' do
|
6
|
+
erb :index
|
7
|
+
end
|
8
|
+
|
9
|
+
post '/' do
|
10
|
+
content_type "text/plain"
|
11
|
+
MovableErb.new(:csv => params[:file][:tempfile].path).convert
|
12
|
+
end
|
data/lib/templates/mtimport.erb
CHANGED
@@ -1,22 +1,30 @@
|
|
1
|
-
|
1
|
+
<% if data['title'] %>
|
2
|
+
TITLE: <%= data['title'].join(', ') %>
|
3
|
+
<% end %>
|
2
4
|
<% if data['author'] %>
|
3
5
|
AUTHOR: <%= data['author'].join(', ') %>
|
4
6
|
<% end %>
|
7
|
+
<% if data['date'] %>
|
8
|
+
DATE: <%= DateTime.parse(data['date'].first).strftime("%m/%d/%Y %X") %>
|
9
|
+
<% end %>
|
10
|
+
<% if data['published'] %>
|
11
|
+
STATUS: <%= [0,'0',false,'f'].include?(data['published'].first) ? "draft" : "published" %>
|
12
|
+
<% end %>
|
5
13
|
<% data['category'] && data['category'].each do |cat| %>
|
6
14
|
CATEGORY: <%= cat %>
|
7
15
|
<% end %>
|
16
|
+
<% if data['tags'] %>
|
17
|
+
TAGS: "<%= data['tags'].first.split.join('","') %>"
|
18
|
+
<% end %>
|
8
19
|
-----
|
9
20
|
BODY:
|
10
|
-
|
11
21
|
<%= data['body'].join("\n") if data['body'] %>
|
12
22
|
|
13
|
-
<% if data['extended_body'] %>
|
14
|
-
|
15
23
|
-----
|
24
|
+
<% if data['extended_body'] %>
|
16
25
|
EXTENDED BODY:
|
17
|
-
|
18
26
|
<%= data['extended_body'] %>
|
19
27
|
|
28
|
+
-----
|
20
29
|
<% end %>
|
21
|
-
|
22
30
|
--------
|
data/movable_erb.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{movable_erb}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.3.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Joshua Davey"]
|
12
|
-
s.date = %q{
|
12
|
+
s.date = %q{2010-02-01}
|
13
13
|
s.default_executable = %q{movable_erb}
|
14
14
|
s.description = %q{A General-purpose CSV to ERB template formatter. Useful for converting legacy CSV data to an importable blog format.}
|
15
15
|
s.email = %q{josh@joshuadavey.com}
|
@@ -19,32 +19,39 @@ Gem::Specification.new do |s|
|
|
19
19
|
"README.rdoc"
|
20
20
|
]
|
21
21
|
s.files = [
|
22
|
-
".
|
22
|
+
".gems",
|
23
|
+
".gitignore",
|
23
24
|
"CHANGELOG",
|
24
25
|
"LICENSE",
|
25
26
|
"README.rdoc",
|
26
27
|
"Rakefile",
|
27
28
|
"VERSION",
|
28
29
|
"bin/movable_erb",
|
30
|
+
"config.ru",
|
29
31
|
"cucumber.yml",
|
30
32
|
"features/csv.feature",
|
31
33
|
"features/step_definitions/csv_steps.rb",
|
32
34
|
"features/step_definitions/tmp.csv",
|
33
35
|
"features/support/env.rb",
|
36
|
+
"lib/app.rb",
|
34
37
|
"lib/movable_erb.rb",
|
35
38
|
"lib/templates/mtimport.erb",
|
36
39
|
"lib/trollop.rb",
|
37
40
|
"movable_erb.gemspec",
|
41
|
+
"public/blueprint.css",
|
42
|
+
"public/custom.css",
|
38
43
|
"spec/csv_spec.rb",
|
39
44
|
"spec/fixtures/advanced.csv",
|
40
45
|
"spec/fixtures/example.csv",
|
41
46
|
"spec/fixtures/template.erb",
|
42
47
|
"spec/spec.opts",
|
43
48
|
"spec/spec_helper.rb",
|
44
|
-
"tasks/rspec.rake"
|
49
|
+
"tasks/rspec.rake",
|
50
|
+
"views/index.erb",
|
51
|
+
"views/layout.erb"
|
45
52
|
]
|
46
53
|
s.homepage = %q{http://github.com/jgdavey/movable_erb}
|
47
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
54
|
+
s.rdoc_options = ["--charset=UTF-8", "--exclude=trollop"]
|
48
55
|
s.require_paths = ["lib"]
|
49
56
|
s.rubygems_version = %q{1.3.5}
|
50
57
|
s.summary = %q{A General-purpose CSV to ERB template formatter}
|
@@ -0,0 +1,200 @@
|
|
1
|
+
/* -----------------------------------------------------------------------
|
2
|
+
|
3
|
+
|
4
|
+
Blueprint CSS Framework 0.9
|
5
|
+
http://blueprintcss.org
|
6
|
+
|
7
|
+
* Copyright (c) 2007-Present. See LICENSE for more info.
|
8
|
+
* See README for instructions on how to use Blueprint.
|
9
|
+
* For credits and origins, see AUTHORS.
|
10
|
+
* This is a compressed file. See the sources in the 'src' directory.
|
11
|
+
|
12
|
+
----------------------------------------------------------------------- */
|
13
|
+
|
14
|
+
/* reset.css */
|
15
|
+
html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, code, del, dfn, em, img, q, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td {margin:0;padding:0;border:0;font-weight:inherit;font-style:inherit;font-size:100%;font-family:inherit;vertical-align:baseline;}
|
16
|
+
body {line-height:1.5;}
|
17
|
+
table {border-collapse:separate;border-spacing:0;}
|
18
|
+
caption, th, td {text-align:left;font-weight:normal;}
|
19
|
+
table, td, th {vertical-align:middle;}
|
20
|
+
blockquote:before, blockquote:after, q:before, q:after {content:"";}
|
21
|
+
blockquote, q {quotes:"" "";}
|
22
|
+
a img {border:none;}
|
23
|
+
|
24
|
+
/* typography.css */
|
25
|
+
html {font-size:100.01%;}
|
26
|
+
body {font-size:75%;color:#222;background:#fff;font-family:"Helvetica Neue", Arial, Helvetica, sans-serif;}
|
27
|
+
h1, h2, h3, h4, h5, h6 {font-weight:normal;color:#111;}
|
28
|
+
h1 {font-size:3em;line-height:1;margin-bottom:0.5em;}
|
29
|
+
h2 {font-size:2em;margin-bottom:0.75em;}
|
30
|
+
h3 {font-size:1.5em;line-height:1;margin-bottom:1em;}
|
31
|
+
h4 {font-size:1.2em;line-height:1.25;margin-bottom:1.25em;}
|
32
|
+
h5 {font-size:1em;font-weight:bold;margin-bottom:1.5em;}
|
33
|
+
h6 {font-size:1em;font-weight:bold;}
|
34
|
+
h1 img, h2 img, h3 img, h4 img, h5 img, h6 img {margin:0;}
|
35
|
+
p {margin:0 0 1.5em;}
|
36
|
+
p img.left {float:left;margin:1.5em 1.5em 1.5em 0;padding:0;}
|
37
|
+
p img.right {float:right;margin:1.5em 0 1.5em 1.5em;}
|
38
|
+
a:focus, a:hover {color:#000;}
|
39
|
+
a {color:#009;text-decoration:underline;}
|
40
|
+
blockquote {margin:1.5em;color:#666;font-style:italic;}
|
41
|
+
strong {font-weight:bold;}
|
42
|
+
em, dfn {font-style:italic;}
|
43
|
+
dfn {font-weight:bold;}
|
44
|
+
sup, sub {line-height:0;}
|
45
|
+
abbr, acronym {border-bottom:1px dotted #666;}
|
46
|
+
address {margin:0 0 1.5em;font-style:italic;}
|
47
|
+
del {color:#666;}
|
48
|
+
pre {margin:1.5em 0;white-space:pre;}
|
49
|
+
pre, code, tt {font:1em 'andale mono', 'lucida console', monospace;line-height:1.5;}
|
50
|
+
li ul, li ol {margin:0 1.5em;}
|
51
|
+
ul, ol {margin:0 1.5em 1.5em 1.5em;}
|
52
|
+
ul {list-style-type:disc;}
|
53
|
+
ol {list-style-type:decimal;}
|
54
|
+
dl {margin:0 0 1.5em 0;}
|
55
|
+
dl dt {font-weight:bold;}
|
56
|
+
dd {margin-left:1.5em;}
|
57
|
+
table {margin-bottom:1.4em;width:100%;}
|
58
|
+
th {font-weight:bold;}
|
59
|
+
thead th {background:#c3d9ff;}
|
60
|
+
th, td, caption {padding:4px 10px 4px 5px;}
|
61
|
+
tr.even td {background:#e5ecf9;}
|
62
|
+
tfoot {font-style:italic;}
|
63
|
+
caption {background:#eee;}
|
64
|
+
.small {font-size:.8em;margin-bottom:1.875em;line-height:1.875em;}
|
65
|
+
.large {font-size:1.2em;line-height:2.5em;margin-bottom:1.25em;}
|
66
|
+
.hide {display:none;}
|
67
|
+
.quiet {color:#666;}
|
68
|
+
.loud {color:#000;}
|
69
|
+
.highlight {background:#ff0;}
|
70
|
+
.added {background:#060;color:#fff;}
|
71
|
+
.removed {background:#900;color:#fff;}
|
72
|
+
.first {margin-left:0;padding-left:0;}
|
73
|
+
.last {margin-right:0;padding-right:0;}
|
74
|
+
.top {margin-top:0;padding-top:0;}
|
75
|
+
.bottom {margin-bottom:0;padding-bottom:0;}
|
76
|
+
|
77
|
+
/* forms.css */
|
78
|
+
label {font-weight:bold;}
|
79
|
+
fieldset {padding:1.4em;margin:0 0 1.5em 0;border:1px solid #ccc;}
|
80
|
+
legend {font-weight:bold;font-size:1.2em;}
|
81
|
+
input[type=text], input[type=password], input.text, input.title, textarea, select {background-color:#fff;border:1px solid #bbb;}
|
82
|
+
input[type=text]:focus, input[type=password]:focus, input.text:focus, input.title:focus, textarea:focus, select:focus {border-color:#666;}
|
83
|
+
input[type=text], input[type=password], input.text, input.title, textarea, select {margin:0.5em 0;}
|
84
|
+
input.text, input.title {width:300px;padding:5px;}
|
85
|
+
input.title {font-size:1.5em;}
|
86
|
+
textarea {width:390px;height:250px;padding:5px;}
|
87
|
+
input[type=checkbox], input[type=radio], input.checkbox, input.radio {position:relative;top:.25em;}
|
88
|
+
form.inline {line-height:3;}
|
89
|
+
form.inline p {margin-bottom:0;}
|
90
|
+
.error, .notice, .success {padding:.8em;margin-bottom:1em;border:2px solid #ddd;}
|
91
|
+
.error {background:#FBE3E4;color:#8a1f11;border-color:#FBC2C4;}
|
92
|
+
.notice {background:#FFF6BF;color:#514721;border-color:#FFD324;}
|
93
|
+
.success {background:#E6EFC2;color:#264409;border-color:#C6D880;}
|
94
|
+
.error a {color:#8a1f11;}
|
95
|
+
.notice a {color:#514721;}
|
96
|
+
.success a {color:#264409;}
|
97
|
+
|
98
|
+
/* grid.css */
|
99
|
+
.container {width:645px;margin:0 auto;}
|
100
|
+
.showgrid {background:url(src/grid.png);}
|
101
|
+
.column, div.span-1, div.span-2, div.span-3, div.span-4, div.span-5, div.span-6, div.span-7, div.span-8, div.span-9, div.span-10, div.span-11, div.span-12 {float:left;margin-right:15px;}
|
102
|
+
.last, div.last {margin-right:0;}
|
103
|
+
.span-1 {width:40px;}
|
104
|
+
.span-2 {width:95px;}
|
105
|
+
.span-3 {width:150px;}
|
106
|
+
.span-4 {width:205px;}
|
107
|
+
.span-5 {width:260px;}
|
108
|
+
.span-6 {width:315px;}
|
109
|
+
.span-7 {width:370px;}
|
110
|
+
.span-8 {width:425px;}
|
111
|
+
.span-9 {width:480px;}
|
112
|
+
.span-10 {width:535px;}
|
113
|
+
.span-11 {width:590px;}
|
114
|
+
.span-12, div.span-12 {width:645px;margin-right:0;}
|
115
|
+
input.span-1, textarea.span-1, input.span-2, textarea.span-2, input.span-3, textarea.span-3, input.span-4, textarea.span-4, input.span-5, textarea.span-5, input.span-6, textarea.span-6, input.span-7, textarea.span-7, input.span-8, textarea.span-8, input.span-9, textarea.span-9, input.span-10, textarea.span-10, input.span-11, textarea.span-11, input.span-12, textarea.span-12 {border-left-width:1px!important;border-right-width:1px!important;padding-left:5px!important;padding-right:5px!important;}
|
116
|
+
input.span-1, textarea.span-1 {width:28px!important;}
|
117
|
+
input.span-2, textarea.span-2 {width:83px!important;}
|
118
|
+
input.span-3, textarea.span-3 {width:138px!important;}
|
119
|
+
input.span-4, textarea.span-4 {width:193px!important;}
|
120
|
+
input.span-5, textarea.span-5 {width:248px!important;}
|
121
|
+
input.span-6, textarea.span-6 {width:303px!important;}
|
122
|
+
input.span-7, textarea.span-7 {width:358px!important;}
|
123
|
+
input.span-8, textarea.span-8 {width:413px!important;}
|
124
|
+
input.span-9, textarea.span-9 {width:468px!important;}
|
125
|
+
input.span-10, textarea.span-10 {width:523px!important;}
|
126
|
+
input.span-11, textarea.span-11 {width:578px!important;}
|
127
|
+
input.span-12, textarea.span-12 {width:633px!important;}
|
128
|
+
.append-1 {padding-right:55px;}
|
129
|
+
.append-2 {padding-right:110px;}
|
130
|
+
.append-3 {padding-right:165px;}
|
131
|
+
.append-4 {padding-right:220px;}
|
132
|
+
.append-5 {padding-right:275px;}
|
133
|
+
.append-6 {padding-right:330px;}
|
134
|
+
.append-7 {padding-right:385px;}
|
135
|
+
.append-8 {padding-right:440px;}
|
136
|
+
.append-9 {padding-right:495px;}
|
137
|
+
.append-10 {padding-right:550px;}
|
138
|
+
.append-11 {padding-right:605px;}
|
139
|
+
.prepend-1 {padding-left:55px;}
|
140
|
+
.prepend-2 {padding-left:110px;}
|
141
|
+
.prepend-3 {padding-left:165px;}
|
142
|
+
.prepend-4 {padding-left:220px;}
|
143
|
+
.prepend-5 {padding-left:275px;}
|
144
|
+
.prepend-6 {padding-left:330px;}
|
145
|
+
.prepend-7 {padding-left:385px;}
|
146
|
+
.prepend-8 {padding-left:440px;}
|
147
|
+
.prepend-9 {padding-left:495px;}
|
148
|
+
.prepend-10 {padding-left:550px;}
|
149
|
+
.prepend-11 {padding-left:605px;}
|
150
|
+
div.border {padding-right:6px;margin-right:7px;border-right:1px solid #eee;}
|
151
|
+
div.colborder {padding-right:34px;margin-right:35px;border-right:1px solid #eee;}
|
152
|
+
.pull-1 {margin-left:-55px;}
|
153
|
+
.pull-2 {margin-left:-110px;}
|
154
|
+
.pull-3 {margin-left:-165px;}
|
155
|
+
.pull-4 {margin-left:-220px;}
|
156
|
+
.pull-5 {margin-left:-275px;}
|
157
|
+
.pull-6 {margin-left:-330px;}
|
158
|
+
.pull-7 {margin-left:-385px;}
|
159
|
+
.pull-8 {margin-left:-440px;}
|
160
|
+
.pull-9 {margin-left:-495px;}
|
161
|
+
.pull-10 {margin-left:-550px;}
|
162
|
+
.pull-11 {margin-left:-605px;}
|
163
|
+
.pull-12 {margin-left:-660px;}
|
164
|
+
.pull-1, .pull-2, .pull-3, .pull-4, .pull-5, .pull-6, .pull-7, .pull-8, .pull-9, .pull-10, .pull-11, .pull-12 {float:left;position:relative;}
|
165
|
+
.push-1 {margin:0 -55px 1.5em 55px;}
|
166
|
+
.push-2 {margin:0 -110px 1.5em 110px;}
|
167
|
+
.push-3 {margin:0 -165px 1.5em 165px;}
|
168
|
+
.push-4 {margin:0 -220px 1.5em 220px;}
|
169
|
+
.push-5 {margin:0 -275px 1.5em 275px;}
|
170
|
+
.push-6 {margin:0 -330px 1.5em 330px;}
|
171
|
+
.push-7 {margin:0 -385px 1.5em 385px;}
|
172
|
+
.push-8 {margin:0 -440px 1.5em 440px;}
|
173
|
+
.push-9 {margin:0 -495px 1.5em 495px;}
|
174
|
+
.push-10 {margin:0 -550px 1.5em 550px;}
|
175
|
+
.push-11 {margin:0 -605px 1.5em 605px;}
|
176
|
+
.push-12 {margin:0 -660px 1.5em 660px;}
|
177
|
+
.push-1, .push-2, .push-3, .push-4, .push-5, .push-6, .push-7, .push-8, .push-9, .push-10, .push-11, .push-12 {float:right;position:relative;}
|
178
|
+
.prepend-top {margin-top:1.5em;}
|
179
|
+
.append-bottom {margin-bottom:1.5em;}
|
180
|
+
.box {padding:1.5em;margin-bottom:1.5em;background:#E5ECF9;}
|
181
|
+
hr {background:#ddd;color:#ddd;clear:both;float:none;width:100%;height:.1em;margin:0 0 1.45em;border:none;}
|
182
|
+
hr.space {background:#fff;color:#fff;visibility:hidden;}
|
183
|
+
.clearfix:after, .container:after {content:"\0020";display:block;height:0;clear:both;visibility:hidden;overflow:hidden;}
|
184
|
+
.clearfix, .container {display:block;}
|
185
|
+
.clear {clear:both;}
|
186
|
+
|
187
|
+
/* buttons */
|
188
|
+
a.button, button {display:block;float:left;margin:0.7em 0.5em 0.7em 0;padding:5px 10px 5px 7px;border:1px solid #dedede;border-top:1px solid #eee;border-left:1px solid #eee;background-color:#f5f5f5;font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif;font-size:100%;line-height:130%;text-decoration:none;font-weight:bold;color:#565656;cursor:pointer;}
|
189
|
+
button {width:auto;overflow:visible;padding:4px 10px 3px 7px;}
|
190
|
+
button[type] {padding:4px 10px 4px 7px;line-height:17px;}
|
191
|
+
*:first-child+html button[type] {padding:4px 10px 3px 7px;}
|
192
|
+
button img, a.button img {margin:0 3px -3px 0 !important;padding:0;border:none;width:16px;height:16px;float:none;}
|
193
|
+
button:hover, a.button:hover {background-color:#dff4ff;border:1px solid #c2e1ef;color:#336699;}
|
194
|
+
a.button:active {background-color:#6299c5;border:1px solid #6299c5;color:#fff;}
|
195
|
+
body .positive {color:#529214;}
|
196
|
+
a.positive:hover, button.positive:hover {background-color:#E6EFC2;border:1px solid #C6D880;color:#529214;}
|
197
|
+
a.positive:active {background-color:#529214;border:1px solid #529214;color:#fff;}
|
198
|
+
body .negative {color:#d12f19;}
|
199
|
+
a.negative:hover, button.negative:hover {background-color:#fbe3e4;border:1px solid #fbc2c4;color:#d12f19;}
|
200
|
+
a.negative:active {background-color:#d12f19;border:1px solid #d12f19;color:#fff;}
|
data/public/custom.css
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
.nofloat, button {
|
2
|
+
float:none;
|
3
|
+
}
|
4
|
+
|
5
|
+
body {
|
6
|
+
background-color: #f0f0f0;
|
7
|
+
color: #bbb;
|
8
|
+
}
|
9
|
+
|
10
|
+
#header {
|
11
|
+
margin: 3em 0;
|
12
|
+
}
|
13
|
+
|
14
|
+
h1 {
|
15
|
+
font-size: 5em;
|
16
|
+
font-weight:bold;
|
17
|
+
color: #bbb;
|
18
|
+
}
|
19
|
+
|
20
|
+
form {
|
21
|
+
padding: 3em;
|
22
|
+
background-color: white;
|
23
|
+
border: 1px solid #ddd;
|
24
|
+
border-radius: 10px;
|
25
|
+
-moz-border-radius: 10px;
|
26
|
+
-webkit-border-radius: 10px;
|
27
|
+
}
|
28
|
+
|
29
|
+
p.top {
|
30
|
+
margin-top: 3em;
|
31
|
+
}
|
32
|
+
|
33
|
+
form label {
|
34
|
+
font-size: 1.4em;
|
35
|
+
color: #aaa;
|
36
|
+
}
|
37
|
+
|
38
|
+
button {
|
39
|
+
margin-left: auto;
|
40
|
+
margin-right: auto;
|
41
|
+
background-color: #3CBBC7;
|
42
|
+
border-color: #3CBBC7;
|
43
|
+
color: #fff;
|
44
|
+
font-size: 2em;
|
45
|
+
border-radius: 8px;
|
46
|
+
-moz-border-radius: 8px;
|
47
|
+
-webkit-border-radius: 8px;
|
48
|
+
text-shadow: 1px 1px 2px #389;
|
49
|
+
}
|
50
|
+
|
51
|
+
button:hover {
|
52
|
+
color: #3CBBC7;
|
53
|
+
text-shadow: 1px 1px 0px #fff;
|
54
|
+
}
|
55
|
+
|
56
|
+
#footer {
|
57
|
+
margin-top: 1em;
|
58
|
+
text-shadow: 1px 1px 0 #fff;
|
59
|
+
}
|
60
|
+
|
61
|
+
#footer a {
|
62
|
+
color: #999;
|
63
|
+
text-decoration:none;
|
64
|
+
}
|
65
|
+
|
66
|
+
#footer a:hover {
|
67
|
+
color: #777;
|
68
|
+
text-decoration: underline;
|
69
|
+
}
|
data/spec/csv_spec.rb
CHANGED
@@ -30,7 +30,7 @@ describe MovableErb do
|
|
30
30
|
@m = MovableErb.new
|
31
31
|
end
|
32
32
|
it "should raise an error if it's missing a CSV and/or Erb instance" do
|
33
|
-
lambda { @m.convert }.should raise_error
|
33
|
+
lambda { @m.convert }.should raise_error
|
34
34
|
end
|
35
35
|
|
36
36
|
it "should raise an error if it's CSV instance can't parse!" do
|
@@ -77,15 +77,15 @@ describe MovableErb do
|
|
77
77
|
|
78
78
|
it "should set the csv file" do
|
79
79
|
m = MovableErb.new({ :csv => CSV_FIXTURE })
|
80
|
-
m.csv.filename.should == CSV_FIXTURE
|
80
|
+
m.csv.filename.should == CSV_FIXTURE
|
81
81
|
end
|
82
|
-
|
82
|
+
|
83
83
|
it "should set a separator if given" do
|
84
84
|
m = MovableErb.new({ :separator => ', ' })
|
85
85
|
m.separator.should == ', '
|
86
86
|
end
|
87
87
|
end
|
88
|
-
|
88
|
+
|
89
89
|
context "full-on run-through" do
|
90
90
|
it "should work!" do
|
91
91
|
movable_erb = MovableErb.new({
|
@@ -98,16 +98,14 @@ describe MovableErb do
|
|
98
98
|
CATEGORY: Blah
|
99
99
|
-----
|
100
100
|
BODY:
|
101
|
-
|
102
101
|
This is the content for hambone
|
103
|
-
|
102
|
+
-----
|
104
103
|
--------
|
105
104
|
TITLE: WillyNilly
|
106
105
|
-----
|
107
106
|
BODY:
|
108
|
-
|
109
107
|
More body
|
110
|
-
|
108
|
+
-----
|
111
109
|
--------
|
112
110
|
ERB
|
113
111
|
end
|
@@ -188,16 +186,16 @@ describe MovableErb::CSV do
|
|
188
186
|
CSV_PARSER.stubs(:read).returns([["Name"],["Billy Bob"]])
|
189
187
|
@csv.to_hashes.should == [{'name' => ['Billy Bob']}]
|
190
188
|
end
|
191
|
-
|
189
|
+
|
192
190
|
it "should convert the header row to snake_case" do
|
193
191
|
CSV_PARSER.stubs(:read).returns([["Extended Body"],["Billy Bob"]])
|
194
|
-
@csv.to_hashes.should == [{'extended_body' => ['Billy Bob']}]
|
192
|
+
@csv.to_hashes.should == [{'extended_body' => ['Billy Bob']}]
|
195
193
|
end
|
196
194
|
|
197
195
|
it "should return an array of hashes (3 rows, 3 columns)" do
|
198
|
-
CSV_PARSER.stubs(:read).returns([["Name", "Phone", "Email"],
|
199
|
-
["John", "773-123-1234", "john@example.com"],
|
200
|
-
["Abigail", nil, "abby@example.com"],
|
196
|
+
CSV_PARSER.stubs(:read).returns([["Name", "Phone", "Email"],
|
197
|
+
["John", "773-123-1234", "john@example.com"],
|
198
|
+
["Abigail", nil, "abby@example.com"],
|
201
199
|
["Casius", nil, nil]])
|
202
200
|
@csv.to_hashes.should == [
|
203
201
|
{'name' => ['John'], 'phone' => ['773-123-1234'], 'email' => ['john@example.com'] },
|
@@ -207,12 +205,12 @@ describe MovableErb::CSV do
|
|
207
205
|
end
|
208
206
|
|
209
207
|
it "should collect values with the same key" do
|
210
|
-
CSV_PARSER.stubs(:read).returns([["Name", "Name", "Email"], ["John", "James", "john@example.com"]])
|
208
|
+
CSV_PARSER.stubs(:read).returns([["Name", "Name", "Email"], ["John", "James", "john@example.com"]])
|
211
209
|
@csv.to_hashes.should == [{'name' => ['John', 'James'],'email' => ['john@example.com']}]
|
212
210
|
end
|
213
211
|
|
214
212
|
it "should collect values with the same key (more than 2)" do
|
215
|
-
CSV_PARSER.stubs(:read).returns([["Name", "Name", "Name"], ["John", "James", "Jill"]])
|
213
|
+
CSV_PARSER.stubs(:read).returns([["Name", "Name", "Name"], ["John", "James", "Jill"]])
|
216
214
|
@csv.to_hashes.should == [{'name' => ['John', 'James', 'Jill']}]
|
217
215
|
end
|
218
216
|
end
|
data/tasks/rspec.rake
CHANGED
@@ -6,6 +6,6 @@ namespace :spec do
|
|
6
6
|
t.spec_files = FileList['spec']
|
7
7
|
t.spec_opts << ["--color"]
|
8
8
|
t.rcov = true
|
9
|
-
t.rcov_opts = ['--exclude', 'spec/,tasks/,coverage/,features/,/System/,/Library/']
|
9
|
+
t.rcov_opts = ['--exclude', 'spec/,tasks/,coverage/,features/,/System/,/Library/,lib/trollop.rb']
|
10
10
|
end
|
11
11
|
end
|
data/views/index.erb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
|
2
|
+
<form action="/" method="POST" enctype="multipart/form-data" class="">
|
3
|
+
<div class="clearfix">
|
4
|
+
<label for="file" class="span-2 prepend-2 column">CSV file</label>
|
5
|
+
<input type="file" class="span-6 last column" name="file" id="file" />
|
6
|
+
</div>
|
7
|
+
<hr class="space"/>
|
8
|
+
<p class="top clear"><button type="submit" class="top">Convert!</button></p>
|
9
|
+
</form>
|
data/views/layout.erb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
3
|
+
|
4
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
5
|
+
<head>
|
6
|
+
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
|
7
|
+
<title>Movable Erb</title>
|
8
|
+
<link rel="stylesheet" href="/blueprint.css" type="text/css" media="screen" />
|
9
|
+
<link rel="stylesheet" href="/custom.css" type="text/css" media="screen" />
|
10
|
+
</head>
|
11
|
+
<body>
|
12
|
+
<div class="container" id="container">
|
13
|
+
<div id="header">
|
14
|
+
<h1>Movable Erb</h1>
|
15
|
+
</div>
|
16
|
+
|
17
|
+
<%= yield %>
|
18
|
+
|
19
|
+
<div id="footer">
|
20
|
+
<p>
|
21
|
+
Created by <a href="http://github.com/jgdavey/">Joshua Davey</a>.
|
22
|
+
<a href="http://github.com/jgdavey/movable_erb">Fork me on github</a>.
|
23
|
+
</p>
|
24
|
+
</div>
|
25
|
+
</div>
|
26
|
+
</body>
|
27
|
+
</html>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: movable_erb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joshua Davey
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2010-02-01 00:00:00 -06:00
|
13
13
|
default_executable: movable_erb
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -32,6 +32,7 @@ extra_rdoc_files:
|
|
32
32
|
- LICENSE
|
33
33
|
- README.rdoc
|
34
34
|
files:
|
35
|
+
- .gems
|
35
36
|
- .gitignore
|
36
37
|
- CHANGELOG
|
37
38
|
- LICENSE
|
@@ -39,15 +40,19 @@ files:
|
|
39
40
|
- Rakefile
|
40
41
|
- VERSION
|
41
42
|
- bin/movable_erb
|
43
|
+
- config.ru
|
42
44
|
- cucumber.yml
|
43
45
|
- features/csv.feature
|
44
46
|
- features/step_definitions/csv_steps.rb
|
45
47
|
- features/step_definitions/tmp.csv
|
46
48
|
- features/support/env.rb
|
49
|
+
- lib/app.rb
|
47
50
|
- lib/movable_erb.rb
|
48
51
|
- lib/templates/mtimport.erb
|
49
52
|
- lib/trollop.rb
|
50
53
|
- movable_erb.gemspec
|
54
|
+
- public/blueprint.css
|
55
|
+
- public/custom.css
|
51
56
|
- spec/csv_spec.rb
|
52
57
|
- spec/fixtures/advanced.csv
|
53
58
|
- spec/fixtures/example.csv
|
@@ -55,6 +60,8 @@ files:
|
|
55
60
|
- spec/spec.opts
|
56
61
|
- spec/spec_helper.rb
|
57
62
|
- tasks/rspec.rake
|
63
|
+
- views/index.erb
|
64
|
+
- views/layout.erb
|
58
65
|
has_rdoc: true
|
59
66
|
homepage: http://github.com/jgdavey/movable_erb
|
60
67
|
licenses: []
|
@@ -62,6 +69,7 @@ licenses: []
|
|
62
69
|
post_install_message:
|
63
70
|
rdoc_options:
|
64
71
|
- --charset=UTF-8
|
72
|
+
- --exclude=trollop
|
65
73
|
require_paths:
|
66
74
|
- lib
|
67
75
|
required_ruby_version: !ruby/object:Gem::Requirement
|