govspeak 6.3.0 → 6.4.0

Sign up to get free protection for your applications and to get access to all the features.
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