govspeak 6.3.0 → 6.4.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: bc558071169d3b288446dddcb1657bef2dfac22add83004e13f8acfbdc6f8b90
4
- data.tar.gz: 4147b7545a3fb2aa1fe09a1d494d02f14065cf3020a65ac46d985e7fc8059f35
3
+ metadata.gz: fbff4078955867159e914ac1dd26310ab9295a0618a58529b42b64c7e55399fd
4
+ data.tar.gz: ce83e999fab5cec2919c21b4561cf06a26c42056dde7c1740b04ca7b1df9d1df
5
5
  SHA512:
6
- metadata.gz: 412b37d58e002eb577de464235f5bc1ec59f7267835320f4d6e509ea16c99d45943922f2697443bdad125cb8dbb68c903062b78185c3ae1bc15f98bb80ae7192
7
- data.tar.gz: '0869244c4588b27a308cee8c54e3aed025a8b7b4f921ebe4989a9e490eb90a6f21e69af31f71bb7b00db750627c4d686ff6a96b55b1c2d5b1f8c28af6d034481'
6
+ metadata.gz: 1972d6f7430d74f570dd23e9e529e581460fb02b535c834abada9c1c14b4d59914ddfeedec8c6209e6992a303c44211c0759fd9592ab5e9be42b776824d5efcb
7
+ data.tar.gz: 139c744c3c51456f6ceac2b75f1cba186cdca54cf518b06b36768bd675560e00f9c95306228b076adadd6f08c6c2ad505447df42e5cce52095fc874bc4eeff21
@@ -1,4 +1,8 @@
1
- ## 6.3.0
1
+ ## 6.4.0
2
+
3
+ * Add table heading syntax that allows a table cell outside of `thead` to be marked as a table heading with a scope of row. (PR#161)
4
+
5
+ ## 6.3.0
2
6
 
3
7
  * Unicode characters forbidden in HTML are stripped from input
4
8
  * Validation is now more lenient for HTML input
data/README.md CHANGED
@@ -319,6 +319,41 @@ will create a box for the specified locality
319
319
  </div>
320
320
  ```
321
321
 
322
+ ## Tables
323
+
324
+ Tables follow the [Kramdown syntax for tables](https://kramdown.gettalong.org/syntax.html#tables) with one addition - table headers can be specified by adding a `#` at the start of the cell. A table header inside the table head will be given a `scope` of `col`; a table header outside will be given a `scope` of `row`.
325
+
326
+ ```markdown
327
+ | |# Column header one |# Column header two |
328
+ |---------------|--------------------|--------------------|
329
+ |# Row header 1 | Content #1 | Content #2 |
330
+ |# Row header 1 | Content #3 | Content #4 |
331
+ ```
332
+
333
+ ```html
334
+ <table>
335
+ <thead>
336
+ <tr>
337
+ <td></td>
338
+ <th scope="col">Column header one</th>
339
+ <th scope="col">Column header two</th>
340
+ </tr>
341
+ </thead>
342
+ <tbody>
343
+ <tr>
344
+ <th scope="row">Row header 1</th>
345
+ <td>Content #1</td>
346
+ <td>Content #2</td>
347
+ </tr>
348
+ <tr>
349
+ <th scope="row">Row header 2</th>
350
+ <td>Content #3</td>
351
+ <td>Content #4</td>
352
+ </tr>
353
+ </tbody>
354
+ </table>
355
+ ```
356
+
322
357
  ## Barcharts
323
358
 
324
359
  For when you want a table to be progressively enhanced by Javascript to be
@@ -83,6 +83,23 @@ module Govspeak
83
83
  end
84
84
  end
85
85
 
86
+ extension("Add table headers and row / column scopes") do |document|
87
+ document.css("thead th").map do |el|
88
+ el.content = el.content.gsub(/^# /, '')
89
+ el.content = el.content.gsub(/[[:space:]]/, '') if el.content.blank? # Removes a strange whitespace in the cell if the cell is already blank.
90
+ el.name = 'td' if el.content.blank? # This prevents a `th` with nothing inside it; a `td` is preferable.
91
+ el[:scope] = "col" if el.content.present? # `scope` shouldn't be used if there's nothing in the table heading.
92
+ end
93
+
94
+ document.css(":not(thead) tr td:first-child").map do |el|
95
+ if el.content.match?(/^#($|\s.*$)/)
96
+ el.content = el.content.gsub(/^#($|\s)/, '') # Replace '# ' and '#', but not '#Word'.
97
+ el.name = 'th' if el.content.present? # This also prevents a `th` with nothing inside it; a `td` is preferable.
98
+ el[:scope] = 'row' if el.content.present? # `scope` shouldn't be used if there's nothing in the table heading.
99
+ end
100
+ end
101
+ end
102
+
86
103
  attr_reader :input, :govspeak_document
87
104
 
88
105
  def initialize(html, govspeak_document)
@@ -1,3 +1,3 @@
1
1
  module Govspeak
2
- VERSION = "6.3.0".freeze
2
+ VERSION = "6.4.0".freeze
3
3
  end
@@ -0,0 +1,198 @@
1
+ require 'test_helper'
2
+
3
+ class GovspeakTableWithHeadersTest < Minitest::Test
4
+ def expected_outcome
5
+ %{
6
+ <table>
7
+ <thead>
8
+ <tr>
9
+ <td></td>
10
+ <th scope="col">Second Column</th>
11
+ <th scope="col">Third Column</th>
12
+ </tr>
13
+ </thead>
14
+ <tbody>
15
+ <tr>
16
+ <th scope="row">First row</th>
17
+ <td>Cell</td>
18
+ <td>Cell</td>
19
+ </tr>
20
+ <tr>
21
+ <th scope="row">Second row</th>
22
+ <td>Cell</td>
23
+ <td>Cell</td>
24
+ </tr>
25
+ </tbody>
26
+ </table>
27
+ }
28
+ end
29
+
30
+ def expected_outcome_with_hashes_in_cell_contents
31
+ %{
32
+ <table>
33
+ <thead>
34
+ <tr>
35
+ <td></td>
36
+ <th scope="col">Second Column</th>
37
+ <th scope="col">Third Column</th>
38
+ </tr>
39
+ </thead>
40
+ <tbody>
41
+ <tr>
42
+ <th scope="row">First row</th>
43
+ <td># Cell</td>
44
+ <td># Cell</td>
45
+ </tr>
46
+ <tr>
47
+ <th scope="row">Second row</th>
48
+ <td>Cell</td>
49
+ <td>Cell</td>
50
+ </tr>
51
+ </tbody>
52
+ </table>
53
+ }
54
+ end
55
+
56
+ def expected_outcome_for_table_with_alignments
57
+ %{
58
+ <table>
59
+ <thead>
60
+ <tr>
61
+ <td style="text-align: left"></td>
62
+ <th style="text-align: center" scope="col">Second Column</th>
63
+ <th style="text-align: right" scope="col">Third Column</th>
64
+ </tr>
65
+ </thead>
66
+ <tbody>
67
+ <tr>
68
+ <th style="text-align: left" scope="row">First row</th>
69
+ <td style="text-align: center">Cell</td>
70
+ <td style="text-align: right">Cell</td>
71
+ </tr>
72
+ <tr>
73
+ <th style="text-align: left" scope="row">Second row</th>
74
+ <td style="text-align: center">Cell</td>
75
+ <td style="text-align: right">Cell</td>
76
+ </tr>
77
+ </tbody>
78
+ </table>
79
+ }
80
+ end
81
+
82
+ def expected_outcome_for_table_headers_in_the_wrong_place
83
+ %{
84
+ <table>
85
+ <thead>
86
+ <tr>
87
+ <td></td>
88
+ <th scope="col">Second Column</th>
89
+ <th scope="col">Third Column</th>
90
+ </tr>
91
+ </thead>
92
+ <tbody>
93
+ <tr>
94
+ <th scope="row">First row</th>
95
+ <td># Cell</td>
96
+ <td>Cell</td>
97
+ </tr>
98
+ <tr>
99
+ <th scope="row">Second row</th>
100
+ <td>Cell</td>
101
+ <td># Cell</td>
102
+ </tr>
103
+ </tbody>
104
+ </table>
105
+ }
106
+ end
107
+
108
+ def expected_outcome_for_table_with_blank_table_headers
109
+ %{
110
+ <table>
111
+ <thead>
112
+ <tr>
113
+ <td></td>
114
+ <th scope="col">Second Column</th>
115
+ <th scope="col">Third Column</th>
116
+ </tr>
117
+ </thead>
118
+ <tbody>
119
+ <tr>
120
+ <td></td>
121
+ <td>Cell</td>
122
+ <td>Cell</td>
123
+ </tr>
124
+ <tr>
125
+ <th scope="row">Second row</th>
126
+ <td>Cell</td>
127
+ <td>Cell</td>
128
+ </tr>
129
+ </tbody>
130
+ </table>
131
+ }
132
+ end
133
+
134
+ def document_body_with_hashes_for_all_headers
135
+ @document_body_with_hashes_for_all_headers ||= Govspeak::Document.new(%{
136
+ | |# Second Column |# Third Column |
137
+ | --------------- | --------------- | ------------------- |
138
+ |# First row | Cell | Cell |
139
+ |# Second row | Cell | Cell |
140
+ })
141
+ end
142
+
143
+ def document_body_with_hashes_for_row_headers
144
+ @document_body_with_hashes_for_row_headers ||= Govspeak::Document.new(%{
145
+ | | Second Column | Third Column |
146
+ | --------------- | --------------- | ------------------- |
147
+ |# First row | Cell | Cell |
148
+ |# Second row | Cell | Cell |
149
+ })
150
+ end
151
+
152
+ def document_body_with_alignments
153
+ @document_body_with_alignments ||= Govspeak::Document.new(%{
154
+ | | Second Column | Third Column |
155
+ | :-------------- | :-------------: | ------------------: |
156
+ |# First row | Cell | Cell |
157
+ |# Second row | Cell | Cell |
158
+ })
159
+ end
160
+
161
+ def document_body_with_table_headers_in_the_wrong_place
162
+ @document_body_with_table_headers_in_the_wrong_place ||= Govspeak::Document.new(%{
163
+ | | Second Column | Third Column |
164
+ | --------------- | --------------- | ------------------- |
165
+ |# First row |# Cell | Cell |
166
+ |# Second row | Cell |# Cell |
167
+ })
168
+ end
169
+
170
+ def document_body_with_blank_table_headers
171
+ @document_body_with_blank_table_headers ||= Govspeak::Document.new(%{
172
+ | | Second Column | Third Column |
173
+ | --------------- | --------------- | ------------------- |
174
+ |# | Cell | Cell |
175
+ |# Second row | Cell | Cell |
176
+ })
177
+ end
178
+
179
+ test "Cells with |# are headers" do
180
+ assert_equal document_body_with_hashes_for_all_headers.to_html, expected_outcome
181
+ end
182
+
183
+ test "Cells outside of thead with |# are th; thead still only contains th" do
184
+ assert_equal document_body_with_hashes_for_row_headers.to_html, expected_outcome
185
+ end
186
+
187
+ test "Cells are aligned correctly" do
188
+ assert_equal document_body_with_alignments.to_html, expected_outcome_for_table_with_alignments
189
+ end
190
+
191
+ test "Table headers with a scope of row are only in the first column of the table" do
192
+ assert_equal document_body_with_table_headers_in_the_wrong_place.to_html, expected_outcome_for_table_headers_in_the_wrong_place
193
+ end
194
+
195
+ test "Table headers are not blank" do
196
+ assert_equal document_body_with_blank_table_headers.to_html, expected_outcome_for_table_with_blank_table_headers
197
+ end
198
+ end
@@ -119,7 +119,7 @@ Teston
119
119
  {barchart}
120
120
  GOVSPEAK
121
121
  html = Govspeak::Document.new(input).to_html
122
- assert_equal %{<table class=\"js-barchart-table mc-auto-outdent\">\n <thead>\n <tr>\n <th>col</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td>val</td>\n </tr>\n </tbody>\n</table>\n}, html
122
+ assert_equal %{<table class=\"js-barchart-table mc-auto-outdent\">\n <thead>\n <tr>\n <th scope="col">col</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td>val</td>\n </tr>\n </tbody>\n</table>\n}, html
123
123
  end
124
124
 
125
125
  test "should convert barchart with stacked compact and negative" do
@@ -130,7 +130,7 @@ Teston
130
130
  {barchart stacked compact negative}
131
131
  GOVSPEAK
132
132
  html = Govspeak::Document.new(input).to_html
133
- assert_equal %{<table class=\"js-barchart-table mc-stacked compact mc-negative mc-auto-outdent\">\n <thead>\n <tr>\n <th>col</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td>val</td>\n </tr>\n </tbody>\n</table>\n}, html
133
+ assert_equal %{<table class=\"js-barchart-table mc-stacked compact mc-negative mc-auto-outdent\">\n <thead>\n <tr>\n <th scope="col">col</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td>val</td>\n </tr>\n </tbody>\n</table>\n}, html
134
134
  end
135
135
 
136
136
  test "address div is separated from paragraph text by a couple of line-breaks" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: govspeak
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.3.0
4
+ version: 6.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GOV.UK Dev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-07-18 00:00:00.000000000 Z
11
+ date: 2019-07-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionview
@@ -329,6 +329,7 @@ files:
329
329
  - test/govspeak_link_extractor_test.rb
330
330
  - test/govspeak_link_test.rb
331
331
  - test/govspeak_structured_headers_test.rb
332
+ - test/govspeak_table_with_headers_test.rb
332
333
  - test/govspeak_test.rb
333
334
  - test/govspeak_test_helper.rb
334
335
  - test/html_sanitizer_test.rb
@@ -358,22 +359,23 @@ signing_key:
358
359
  specification_version: 4
359
360
  summary: Markup language for single domain
360
361
  test_files:
361
- - test/blockquote_extra_quote_remover_test.rb
362
- - test/govspeak_test_helper.rb
363
- - test/govspeak_structured_headers_test.rb
364
- - test/govspeak_attachment_link_test.rb
365
- - test/govspeak_attachments_image_test.rb
366
- - test/test_helper.rb
367
362
  - test/govspeak_attachments_inline_test.rb
368
- - test/html_sanitizer_test.rb
369
- - test/govspeak_button_test.rb
370
- - test/govspeak_images_bang_test.rb
371
- - test/govspeak_images_test.rb
372
- - test/html_validator_test.rb
373
363
  - test/govspeak_attachment_test.rb
374
- - test/govspeak_extract_contact_content_ids_test.rb
375
- - test/govspeak_test.rb
376
- - test/govspeak_link_extractor_test.rb
364
+ - test/govspeak_attachment_link_test.rb
365
+ - test/govspeak_images_test.rb
366
+ - test/govspeak_table_with_headers_test.rb
377
367
  - test/govspeak_link_test.rb
368
+ - test/govspeak_images_bang_test.rb
369
+ - test/govspeak_link_extractor_test.rb
378
370
  - test/govspeak_contacts_test.rb
371
+ - test/test_helper.rb
372
+ - test/govspeak_test.rb
373
+ - test/govspeak_attachments_image_test.rb
374
+ - test/html_validator_test.rb
375
+ - test/govspeak_structured_headers_test.rb
376
+ - test/govspeak_extract_contact_content_ids_test.rb
377
+ - test/blockquote_extra_quote_remover_test.rb
379
378
  - test/presenters/h_card_presenter_test.rb
379
+ - test/govspeak_button_test.rb
380
+ - test/govspeak_test_helper.rb
381
+ - test/html_sanitizer_test.rb