movable_erb 0.2.6 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|