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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9ad82a22fd996a0e5af1653a6ed66f27863da252331b4fa58865980d6a27b063
4
- data.tar.gz: d206494ce8cc6e9dabbda3ab86389d080e57d1baf0a003800ba6edd3fe3c3b13
3
+ metadata.gz: bf971b88e97e4e680e1aaa25fdd21238734738ff4b6e230580f93305f5c823a5
4
+ data.tar.gz: da9f97e86eeb122f7c1ecbe057a5f73bc0908a86ab5dc5acbb76898ff4e326cd
5
5
  SHA512:
6
- metadata.gz: f8b89f4ea9ca38fb0ee9773ca55e6fb654e94d4135f4b4748abc91c90fe014e3c1bd90e6f0c9c4f9d74f2efcf64b7bfd8b488ebcf3cf92dc40d9c2616089d30e
7
- data.tar.gz: 1c81200ffd8922cc1384c11b9a8a8766eae3d59f3301c544dbf9a6928617c85d231f931cec768d4ad4c7c8fcbc697ca94d666c182340974c7d406411c11dab34
6
+ metadata.gz: 8a74bb8fa978b4a298ea9c3e5fbb3fb53be59875a9a41749570a1014462d5fe4a8aa13dd02683163ee1177b812cd3a69edff1a880975463b83a1fa143f5b2508
7
+ data.tar.gz: 263a67ba0a8d3bc0d3d89f46a4f2ef9a4f2cb9475684ca0a16309916dab7ffc370c5bd0796224e411f0b22a209aac1779aa21b340bdae96fd88a27836d50bc11
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- spoonerize (2.0.0)
4
+ spoonerize (2.1.0)
5
5
  csv
6
6
  puma (~> 8.0)
7
7
  rackup (~> 2.3)
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # Welcome to Spoonerize -- a word game.
2
2
  [![Build Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2Fevanthegrayt%2Fspoonerize%2Fbadge%3Fref%3Dmaster&style=flat)](https://actions-badge.atrox.dev/evanthegrayt/spoonerize/goto?ref=master)
3
- [![Gem Version](https://badge.fury.io/rb/spoonerize.svg)](https://badge.fury.io/rb/spoonerize)
3
+ [![Gem Version](https://img.shields.io/gem/v/spoonerize.svg)](https://rubygems.org/gems/spoonerize)
4
+ ![Language: Ruby](https://img.shields.io/static/v1?label=language&message=Ruby&color=CC342D&style=flat&logo=ruby&logoColor=CC342D)
4
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
6
 
6
7
  > Spoonerism *[noun]* a verbal error in which a speaker accidentally transposes
@@ -15,7 +15,7 @@ module Spoonerize
15
15
  # Minor version.
16
16
  #
17
17
  # @return [Integer]
18
- MINOR = 0
18
+ MINOR = 1
19
19
 
20
20
  ##
21
21
  # Patch version.
@@ -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(2.2rem, 7vw, 4rem);
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>Flip a phrase</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
- <p class="notice"><%= h @error %></p>
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 flipping</span>
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 flip consonant-starting words</span>
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>
@@ -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.0.0
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: