spoonerize 2.0.0 → 2.1.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.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +2 -1
- data/lib/spoonerize/version.rb +1 -1
- data/lib/spoonerize/web/public/styles.css +160 -2
- data/lib/spoonerize/web/views/index.erb +7 -5
- data/lib/spoonerize/web/views/saved.erb +44 -0
- data/lib/spoonerize/web.rb +25 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bf971b88e97e4e680e1aaa25fdd21238734738ff4b6e230580f93305f5c823a5
|
|
4
|
+
data.tar.gz: da9f97e86eeb122f7c1ecbe057a5f73bc0908a86ab5dc5acbb76898ff4e326cd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8a74bb8fa978b4a298ea9c3e5fbb3fb53be59875a9a41749570a1014462d5fe4a8aa13dd02683163ee1177b812cd3a69edff1a880975463b83a1fa143f5b2508
|
|
7
|
+
data.tar.gz: 263a67ba0a8d3bc0d3d89f46a4f2ef9a4f2cb9475684ca0a16309916dab7ffc370c5bd0796224e411f0b22a209aac1779aa21b340bdae96fd88a27836d50bc11
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# Welcome to Spoonerize -- a word game.
|
|
2
2
|
[](https://actions-badge.atrox.dev/evanthegrayt/spoonerize/goto?ref=master)
|
|
3
|
-
[](https://rubygems.org/gems/spoonerize)
|
|
4
|
+

|
|
4
5
|
[](https://opensource.org/licenses/MIT)
|
|
5
6
|
|
|
6
7
|
> Spoonerism *[noun]* a verbal error in which a speaker accidentally transposes
|
data/lib/spoonerize/version.rb
CHANGED
|
@@ -41,10 +41,41 @@ body {
|
|
|
41
41
|
padding-bottom: 1.25rem;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
.masthead-with-action {
|
|
45
|
+
display: flex;
|
|
46
|
+
align-items: flex-end;
|
|
47
|
+
justify-content: space-between;
|
|
48
|
+
gap: 1rem;
|
|
49
|
+
}
|
|
50
|
+
|
|
44
51
|
h1 {
|
|
45
52
|
margin: 0;
|
|
46
|
-
font-size: clamp(
|
|
47
|
-
line-height: 1;
|
|
53
|
+
font-size: clamp(1.9rem, 4vw, 2.75rem);
|
|
54
|
+
line-height: 1.08;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.lede {
|
|
58
|
+
margin: 0.5rem 0 0;
|
|
59
|
+
color: var(--muted);
|
|
60
|
+
font-family: ui-sans-serif, system-ui, sans-serif;
|
|
61
|
+
font-size: 0.95rem;
|
|
62
|
+
font-weight: 700;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.action-link {
|
|
66
|
+
flex: 0 0 auto;
|
|
67
|
+
color: var(--accent-dark);
|
|
68
|
+
font-family: ui-sans-serif, system-ui, sans-serif;
|
|
69
|
+
font-size: 0.95rem;
|
|
70
|
+
font-weight: 750;
|
|
71
|
+
text-decoration-color: color-mix(in srgb, var(--accent-dark) 35%, transparent);
|
|
72
|
+
text-underline-offset: 0.18em;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.action-link:hover,
|
|
76
|
+
.action-link:focus {
|
|
77
|
+
color: var(--accent);
|
|
78
|
+
text-decoration-color: currentcolor;
|
|
48
79
|
}
|
|
49
80
|
|
|
50
81
|
.result {
|
|
@@ -141,6 +172,72 @@ button:focus {
|
|
|
141
172
|
background: var(--accent-dark);
|
|
142
173
|
}
|
|
143
174
|
|
|
175
|
+
.table-wrap {
|
|
176
|
+
overflow-x: auto;
|
|
177
|
+
border: 1px solid var(--line);
|
|
178
|
+
border-radius: 4px;
|
|
179
|
+
background: var(--panel);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.saved-table {
|
|
183
|
+
width: 100%;
|
|
184
|
+
border-collapse: collapse;
|
|
185
|
+
font-family: ui-sans-serif, system-ui, sans-serif;
|
|
186
|
+
font-size: 0.95rem;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.saved-table th {
|
|
190
|
+
border-bottom: 1px solid var(--line);
|
|
191
|
+
padding: 0.8rem 0.9rem;
|
|
192
|
+
text-align: left;
|
|
193
|
+
vertical-align: top;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.saved-table td {
|
|
197
|
+
border-bottom: 1px solid var(--line);
|
|
198
|
+
padding: 0;
|
|
199
|
+
text-align: left;
|
|
200
|
+
vertical-align: top;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.saved-table th {
|
|
204
|
+
color: var(--muted);
|
|
205
|
+
font-size: 0.78rem;
|
|
206
|
+
letter-spacing: 0;
|
|
207
|
+
text-transform: uppercase;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.saved-table tbody tr:last-child td {
|
|
211
|
+
border-bottom: 0;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.saved-table td {
|
|
215
|
+
color: var(--ink);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.saved-table .row-link {
|
|
219
|
+
display: block;
|
|
220
|
+
min-height: 100%;
|
|
221
|
+
padding: 0.8rem 0.9rem;
|
|
222
|
+
color: inherit;
|
|
223
|
+
text-decoration: none;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
.saved-table tbody tr:hover,
|
|
227
|
+
.saved-table tbody tr:focus-within {
|
|
228
|
+
background: color-mix(in srgb, var(--accent) 7%, var(--panel));
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
.saved-table .row-link:focus {
|
|
232
|
+
outline: 3px solid color-mix(in srgb, var(--accent) 22%, transparent);
|
|
233
|
+
outline-offset: 2px;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
.saved-table td:last-child {
|
|
237
|
+
color: var(--muted);
|
|
238
|
+
white-space: nowrap;
|
|
239
|
+
}
|
|
240
|
+
|
|
144
241
|
.footer {
|
|
145
242
|
width: min(100%, 46rem);
|
|
146
243
|
margin-top: 2.5rem;
|
|
@@ -175,4 +272,65 @@ button:focus {
|
|
|
175
272
|
button {
|
|
176
273
|
width: 100%;
|
|
177
274
|
}
|
|
275
|
+
|
|
276
|
+
.masthead-with-action {
|
|
277
|
+
display: grid;
|
|
278
|
+
align-items: start;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
@media (max-width: 34rem) {
|
|
283
|
+
.table-wrap {
|
|
284
|
+
overflow: visible;
|
|
285
|
+
border: 0;
|
|
286
|
+
background: transparent;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
.saved-table,
|
|
290
|
+
.saved-table thead,
|
|
291
|
+
.saved-table tbody,
|
|
292
|
+
.saved-table th,
|
|
293
|
+
.saved-table td,
|
|
294
|
+
.saved-table tr {
|
|
295
|
+
display: block;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
.saved-table thead {
|
|
299
|
+
position: absolute;
|
|
300
|
+
width: 1px;
|
|
301
|
+
height: 1px;
|
|
302
|
+
overflow: hidden;
|
|
303
|
+
clip: rect(0 0 0 0);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.saved-table tr {
|
|
307
|
+
margin-bottom: 0.8rem;
|
|
308
|
+
border: 1px solid var(--line);
|
|
309
|
+
border-radius: 4px;
|
|
310
|
+
background: var(--panel);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.saved-table td {
|
|
314
|
+
display: grid;
|
|
315
|
+
grid-template-columns: 7rem 1fr;
|
|
316
|
+
gap: 0.75rem;
|
|
317
|
+
border-bottom: 1px solid var(--line);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
.saved-table td::before {
|
|
321
|
+
content: attr(data-label);
|
|
322
|
+
padding: 0.8rem 0 0.8rem 0.9rem;
|
|
323
|
+
color: var(--muted);
|
|
324
|
+
font-size: 0.78rem;
|
|
325
|
+
font-weight: 800;
|
|
326
|
+
text-transform: uppercase;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
.saved-table .row-link {
|
|
330
|
+
padding: 0.8rem 0.9rem 0.8rem 0;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
.saved-table td:last-child {
|
|
334
|
+
white-space: normal;
|
|
335
|
+
}
|
|
178
336
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<section class="shell">
|
|
2
|
-
<header class="masthead">
|
|
3
|
-
<h1>
|
|
2
|
+
<header class="masthead masthead-with-action">
|
|
3
|
+
<h1>Spoonerize a phrase</h1>
|
|
4
|
+
<a class="action-link" href="/saved/">Saved spoonerisms</a>
|
|
4
5
|
</header>
|
|
5
6
|
|
|
6
7
|
<% if @result %>
|
|
@@ -9,7 +10,8 @@
|
|
|
9
10
|
<p class="notice">Saved.</p>
|
|
10
11
|
<% end %>
|
|
11
12
|
<% elsif @error %>
|
|
12
|
-
|
|
13
|
+
<% display_error = @error == "Not enough words to flip." ? "Not enough words to spoonerize." : @error %>
|
|
14
|
+
<p class="notice"><%= h display_error %></p>
|
|
13
15
|
<% end %>
|
|
14
16
|
|
|
15
17
|
<form action="/" method="post" class="spoonerize-form">
|
|
@@ -28,7 +30,7 @@
|
|
|
28
30
|
|
|
29
31
|
<label class="check">
|
|
30
32
|
<input type="checkbox" name="reverse" value="1" <%= checked?("reverse") %>>
|
|
31
|
-
<span>Reverse
|
|
33
|
+
<span>Reverse spoonerizing</span>
|
|
32
34
|
</label>
|
|
33
35
|
|
|
34
36
|
<label class="check">
|
|
@@ -38,7 +40,7 @@
|
|
|
38
40
|
|
|
39
41
|
<label class="check">
|
|
40
42
|
<input type="checkbox" name="consonants_only" value="1" <%= checked?("consonants_only") %>>
|
|
41
|
-
<span>Only
|
|
43
|
+
<span>Only spoonerize consonant-starting words</span>
|
|
42
44
|
</label>
|
|
43
45
|
|
|
44
46
|
<label class="check">
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
<section class="shell">
|
|
2
|
+
<header class="masthead masthead-with-action">
|
|
3
|
+
<div>
|
|
4
|
+
<h1>Saved spoonerisms</h1>
|
|
5
|
+
<p class="lede"><%= @entries.size %> saved <%= @entries.size == 1 ? "spoonerism" : "spoonerisms" %></p>
|
|
6
|
+
</div>
|
|
7
|
+
<a class="action-link" href="/">New spoonerism</a>
|
|
8
|
+
</header>
|
|
9
|
+
|
|
10
|
+
<% if @entries.empty? %>
|
|
11
|
+
<p class="notice">No saved spoonerisms yet.</p>
|
|
12
|
+
<% else %>
|
|
13
|
+
<div class="table-wrap">
|
|
14
|
+
<table class="saved-table">
|
|
15
|
+
<thead>
|
|
16
|
+
<tr>
|
|
17
|
+
<th scope="col">Phrase</th>
|
|
18
|
+
<th scope="col">Result</th>
|
|
19
|
+
<th scope="col">Options</th>
|
|
20
|
+
</tr>
|
|
21
|
+
</thead>
|
|
22
|
+
<tbody>
|
|
23
|
+
<% @entries.each do |entry| %>
|
|
24
|
+
<% phrase = entry[0].to_s %>
|
|
25
|
+
<% result = entry[1].to_s %>
|
|
26
|
+
<% options = entry[2].to_s %>
|
|
27
|
+
<% entry_path = saved_entry_path(phrase, result) %>
|
|
28
|
+
<tr>
|
|
29
|
+
<td data-label="Phrase">
|
|
30
|
+
<a class="row-link" href="<%= h entry_path %>"><%= h phrase %></a>
|
|
31
|
+
</td>
|
|
32
|
+
<td data-label="Result">
|
|
33
|
+
<a class="row-link" href="<%= h entry_path %>"><strong><%= h result %></strong></a>
|
|
34
|
+
</td>
|
|
35
|
+
<td data-label="Options">
|
|
36
|
+
<a class="row-link" href="<%= h entry_path %>"><%= h options %></a>
|
|
37
|
+
</td>
|
|
38
|
+
</tr>
|
|
39
|
+
<% end %>
|
|
40
|
+
</tbody>
|
|
41
|
+
</table>
|
|
42
|
+
</div>
|
|
43
|
+
<% end %>
|
|
44
|
+
</section>
|
data/lib/spoonerize/web.rb
CHANGED
|
@@ -54,13 +54,34 @@ module Spoonerize
|
|
|
54
54
|
def h(value)
|
|
55
55
|
Rack::Utils.escape_html(value)
|
|
56
56
|
end
|
|
57
|
+
|
|
58
|
+
##
|
|
59
|
+
# Path for loading a saved spoonerism on the main web form.
|
|
60
|
+
#
|
|
61
|
+
# @param [String] phrase The original phrase.
|
|
62
|
+
# @param [String] result The saved spoonerized result.
|
|
63
|
+
#
|
|
64
|
+
# @return [String]
|
|
65
|
+
def saved_entry_path(phrase, result)
|
|
66
|
+
"/?#{Rack::Utils.build_query("phrase" => phrase, "result" => result)}"
|
|
67
|
+
end
|
|
57
68
|
end
|
|
58
69
|
|
|
59
70
|
get "/" do
|
|
60
71
|
prepare_request(false)
|
|
72
|
+
@result = params["result"].to_s unless params["result"].to_s.empty?
|
|
61
73
|
erb :index
|
|
62
74
|
end
|
|
63
75
|
|
|
76
|
+
get "/saved" do
|
|
77
|
+
redirect "/saved/"
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
get "/saved/" do
|
|
81
|
+
@entries = saved_entries
|
|
82
|
+
erb :saved
|
|
83
|
+
end
|
|
84
|
+
|
|
64
85
|
post "/" do
|
|
65
86
|
prepare_request(true)
|
|
66
87
|
@result = spoonerize_phrase if @submitted && !@phrase.strip.empty?
|
|
@@ -96,6 +117,10 @@ module Spoonerize
|
|
|
96
117
|
@save = @submitted && params.key?("save")
|
|
97
118
|
end
|
|
98
119
|
|
|
120
|
+
def saved_entries
|
|
121
|
+
Spoonerize::Log.new(Spoonerize.config.logfile_name).contents.reverse
|
|
122
|
+
end
|
|
123
|
+
|
|
99
124
|
def spoonerize_phrase
|
|
100
125
|
spoonerism = Spoonerism.new(
|
|
101
126
|
*@phrase.split,
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: spoonerize
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Evan Gray
|
|
@@ -163,6 +163,7 @@ files:
|
|
|
163
163
|
- lib/spoonerize/web/public/styles.css
|
|
164
164
|
- lib/spoonerize/web/views/index.erb
|
|
165
165
|
- lib/spoonerize/web/views/layout.erb
|
|
166
|
+
- lib/spoonerize/web/views/saved.erb
|
|
166
167
|
- spoonerize.gemspec
|
|
167
168
|
homepage: https://evanthegrayt.github.io/spoonerize/
|
|
168
169
|
licenses:
|