govspeak 6.6.0 → 6.7.3
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/CHANGELOG.md +22 -0
- data/README.md +21 -4
- data/lib/govspeak/header_extractor.rb +3 -2
- data/lib/govspeak/post_processor.rb +1 -1
- data/lib/govspeak/presenters/attachment_presenter.rb +2 -1
- data/lib/govspeak/presenters/contact_presenter.rb +12 -12
- data/lib/govspeak/version.rb +1 -1
- data/lib/govspeak.rb +77 -10
- data/lib/templates/contact.html.erb +1 -1
- data/test/govspeak_attachment_test.rb +2 -2
- data/test/govspeak_attachments_image_test.rb +1 -1
- data/test/govspeak_button_test.rb +8 -24
- data/test/govspeak_contacts_test.rb +3 -3
- data/test/govspeak_footnote_test.rb +4 -4
- data/test/govspeak_images_bang_test.rb +7 -27
- data/test/govspeak_images_test.rb +9 -34
- data/test/govspeak_test.rb +347 -1
- data/test/govspeak_test_helper.rb +7 -1
- data/test/test_helper.rb +4 -4
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a3fb6617b89131244243bd9fcc7317e6c28266122a75eb01f7e2164cd2d46775
|
4
|
+
data.tar.gz: d6241111b4db6cee72273862559d27abd842a83171cd044069ca370c20f3e0e8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7ed67517b5fdf63bd9e5e8e95510d801ea4457ed7fb290777f72d263802b67bd9cf30a4644b99edc6c11571bd93a9b61862e076e2d68fe43973b083d6bab98df
|
7
|
+
data.tar.gz: 58f86183335235a8b07cd059fe82e509e5e9701bbbbab02af250598778a720c65e136fb29e505acfe3a68727aeb09ae5e7b4d18cca20b93f67bfd3d940082fb1
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,25 @@
|
|
1
|
+
## Unreleased
|
2
|
+
|
3
|
+
* Minimum Ruby version specified at 2.6 [215](https://github.com/alphagov/govspeak/pull/215)
|
4
|
+
|
5
|
+
## 6.7.3
|
6
|
+
|
7
|
+
* Fix regex for footnotes in legislative lists [218](
|
8
|
+
https://github.com/alphagov/govspeak/pull/218
|
9
|
+
|
10
|
+
## 6.7.2
|
11
|
+
|
12
|
+
* Fix footnotes in legislative lists [216](https://github.com/alphagov/govspeak/pull/216)
|
13
|
+
|
14
|
+
## 6.7.1
|
15
|
+
|
16
|
+
* Update failing test [212](https://github.com/alphagov/govspeak/pull/212)
|
17
|
+
* Fix stats headline HTML semantics [213](https://github.com/alphagov/govspeak/pull/213)
|
18
|
+
|
19
|
+
## 6.7.0
|
20
|
+
|
21
|
+
* Update heading & docs [#206](https://github.com/alphagov/govspeak/pull/206)
|
22
|
+
|
1
23
|
## 6.6.0
|
2
24
|
|
3
25
|
* Allow passed elements to be relaxed from sanitization [#203](https://github.com/alphagov/govspeak/pull/203)
|
data/README.md
CHANGED
@@ -18,6 +18,23 @@ then create a new document
|
|
18
18
|
doc = Govspeak::Document.new "^Test^"
|
19
19
|
puts doc.to_html
|
20
20
|
|
21
|
+
## Changes appearing across GOV.UK
|
22
|
+
|
23
|
+
Some additional steps or considerations are needed to ensure changes to govspeak cascade across GOV.UK in a holistic way.
|
24
|
+
|
25
|
+
Once govspeak has been updated and version incremented then:
|
26
|
+
- [`govuk_publishing_components` govspeak](https://components.publishing.service.gov.uk/component-guide/govspeak) will also need updating to reflect your most recent change.
|
27
|
+
- [Publishing apps](https://docs.publishing.service.gov.uk/apps.html) (including but not limited to [content-publisher](https://github.com/alphagov/content-publisher) & [whitehall](https://github.com/alphagov/whitehall)) also use govspeak, these apps will need to be released with the new govspeak version present.
|
28
|
+
|
29
|
+
Also, consider if:
|
30
|
+
- [whitehall](https://github.com/alphagov/whitehall) needs updating (as custom govspeak changes are present)
|
31
|
+
- [govuk-content-schema](https://github.com/alphagov/govuk-content-schemas) needs updating
|
32
|
+
- [govpspeak-preview](https://github.com/alphagov/govspeak-preview) is worth updating
|
33
|
+
|
34
|
+
Any pages that use govspeak to generate Content will need to *republished* in order for the new changes to be reflected.
|
35
|
+
|
36
|
+
- Data Labs can help identify which pages need updating by [submitting a request](https://gov-uk.atlassian.net/wiki/spaces/GOVUK/pages/1860075525/GOV.UK+Data+Labs#Submitting-a-data-science-request) and [#govuk-2ndline](https://docs.publishing.service.gov.uk/manual/2nd-line.html) can help with republishing
|
37
|
+
|
21
38
|
# Extensions
|
22
39
|
|
23
40
|
In addition to the [standard Markdown syntax](http://daringfireball.net/projects/markdown/syntax "Markdown syntax"), we have added our own extensions.
|
@@ -106,9 +123,9 @@ Statistic headlines highlight important numbers in content. Displays a statistic
|
|
106
123
|
Creates the following:
|
107
124
|
|
108
125
|
```html
|
109
|
-
<
|
126
|
+
<div class="stat-headline">
|
110
127
|
<p><em>13.8bn</em> years since the big bang</p>
|
111
|
-
</
|
128
|
+
</div>
|
112
129
|
```
|
113
130
|
|
114
131
|
## Points of Contact
|
@@ -598,8 +615,8 @@ will output
|
|
598
615
|
```html
|
599
616
|
<div id="contact_123" class="contact">
|
600
617
|
<div class="content">
|
601
|
-
<h3>Government Digital Service</h3>
|
602
618
|
<div class="vcard contact-inner">
|
619
|
+
<p>Government Digital Service</p>
|
603
620
|
<div class="email-url-number">
|
604
621
|
<p class="email">
|
605
622
|
<span class="type">Email</span>
|
@@ -676,4 +693,4 @@ which outputs
|
|
676
693
|
Start Now
|
677
694
|
<svg class="govuk-button__start-icon" xmlns="http://www.w3.org/2000/svg" width="17.5" height="19" viewBox="0 0 33 40" role="presentation" focusable="false"><path fill="currentColor" d="M0 0h13l20 20-20 20H0l20-20z"></path></svg>
|
678
695
|
</a>
|
679
|
-
```
|
696
|
+
```
|
@@ -30,9 +30,10 @@ module Govspeak
|
|
30
30
|
def find_headers(parent)
|
31
31
|
headers = []
|
32
32
|
|
33
|
-
|
33
|
+
case parent.type
|
34
|
+
when :header
|
34
35
|
headers << build_header(parent)
|
35
|
-
|
36
|
+
when :html_element
|
36
37
|
parent.children.each do |child|
|
37
38
|
if child.type == :header
|
38
39
|
headers << build_header(child)
|
@@ -126,7 +126,7 @@ module Govspeak
|
|
126
126
|
el.content = "[footnote #{footnote_number}]"
|
127
127
|
end
|
128
128
|
document.css("[role='doc-backlink']").map do |el|
|
129
|
-
backlink_number = "
|
129
|
+
backlink_number = " #{el.css('sup')[0].content}" if el.css("sup")[0].present?
|
130
130
|
el["aria-label"] = "go to where this is referenced#{backlink_number}"
|
131
131
|
end
|
132
132
|
end
|
@@ -4,6 +4,7 @@ require "htmlentities"
|
|
4
4
|
module Govspeak
|
5
5
|
class AttachmentPresenter
|
6
6
|
attr_reader :attachment
|
7
|
+
|
7
8
|
include ActionView::Helpers::TagHelper
|
8
9
|
include ActionView::Helpers::NumberHelper
|
9
10
|
include ActionView::Helpers::TextHelper
|
@@ -25,7 +26,7 @@ module Govspeak
|
|
25
26
|
end
|
26
27
|
|
27
28
|
def file_extension
|
28
|
-
#
|
29
|
+
# NOTE: this is a separate parameter rather than being calculated from the
|
29
30
|
# filename because at the time of writing not all apps were using the effects
|
30
31
|
# of this field.
|
31
32
|
attachment[:file_extension]
|
@@ -23,30 +23,30 @@ module Govspeak
|
|
23
23
|
|
24
24
|
def post_addresses
|
25
25
|
@post_addresses ||= begin
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
addresses = contact.dig(:details, :post_addresses) || []
|
27
|
+
filter_post_addresses(addresses)
|
28
|
+
end
|
29
29
|
end
|
30
30
|
|
31
31
|
def email_addresses
|
32
32
|
@email_addresses ||= begin
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
emails = contact.dig(:details, :email_addresses) || []
|
34
|
+
emails.select { |e| e[:email].present? }
|
35
|
+
end
|
36
36
|
end
|
37
37
|
|
38
38
|
def phone_numbers
|
39
39
|
@phone_numbers ||= begin
|
40
|
-
|
41
|
-
|
42
|
-
|
40
|
+
phone_numbers = contact.dig(:details, :phone_numbers) || []
|
41
|
+
phone_numbers.select { |p| p[:number].present? }
|
42
|
+
end
|
43
43
|
end
|
44
44
|
|
45
45
|
def contact_form_links
|
46
46
|
@contact_form_links ||= begin
|
47
|
-
|
48
|
-
|
49
|
-
|
47
|
+
contact_form_links = contact.dig(:details, :contact_form_links) || []
|
48
|
+
contact_form_links.select { |c| c[:link].present? }
|
49
|
+
end
|
50
50
|
end
|
51
51
|
|
52
52
|
private
|
data/lib/govspeak/version.rb
CHANGED
data/lib/govspeak.rb
CHANGED
@@ -62,18 +62,30 @@ module Govspeak
|
|
62
62
|
sanitize: true,
|
63
63
|
syntax_highlighter: nil }.merge(options)
|
64
64
|
@options[:entity_output] = :symbolic
|
65
|
+
@footnote_definition_html = nil
|
66
|
+
@acronyms = []
|
65
67
|
end
|
66
68
|
|
67
69
|
def to_html
|
68
70
|
@to_html ||= begin
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
71
|
+
html = if @options[:sanitize]
|
72
|
+
HtmlSanitizer.new(kramdown_doc.to_html).sanitize(allowed_elements: @allowed_elements)
|
73
|
+
else
|
74
|
+
kramdown_doc.to_html
|
75
|
+
end
|
76
|
+
|
77
|
+
unless @footnote_definition_html.nil?
|
78
|
+
regex = /<div class="footnotes".*[<\/div>]/m
|
79
|
+
|
80
|
+
if html.scan(regex).empty?
|
81
|
+
html << @footnote_definition_html
|
82
|
+
else
|
83
|
+
html.gsub!(regex, @footnote_definition_html)
|
84
|
+
end
|
85
|
+
end
|
74
86
|
|
75
|
-
|
76
|
-
|
87
|
+
Govspeak::PostProcessor.process(html, self)
|
88
|
+
end
|
77
89
|
end
|
78
90
|
|
79
91
|
def to_liquid
|
@@ -110,6 +122,9 @@ module Govspeak
|
|
110
122
|
def preprocess(source)
|
111
123
|
source = Govspeak::BlockquoteExtraQuoteRemover.remove(source)
|
112
124
|
source = remove_forbidden_characters(source)
|
125
|
+
|
126
|
+
legislative_list_footnote_definitions(source)
|
127
|
+
|
113
128
|
self.class.extensions.each do |_, regexp, block|
|
114
129
|
source.gsub!(regexp) do
|
115
130
|
instance_exec(*Regexp.last_match.captures, &block)
|
@@ -118,6 +133,40 @@ module Govspeak
|
|
118
133
|
source
|
119
134
|
end
|
120
135
|
|
136
|
+
def legislative_list_footnote_definitions(source)
|
137
|
+
is_legislative_list = source.scan(/\$LegislativeList.*?\[\^\d\]*.*?\$EndLegislativeList/m).size.positive?
|
138
|
+
footnotes = source.scan(/\[\^(\d+)\]:(.*)/)
|
139
|
+
@acronyms = source.scan(/(?<=\*)\[(.*)\]:(.*)/)
|
140
|
+
|
141
|
+
if is_legislative_list && footnotes.size.positive?
|
142
|
+
list_items = footnotes.map do |footnote|
|
143
|
+
number = footnote[0]
|
144
|
+
text = footnote[1].strip
|
145
|
+
footnote_definition = Govspeak::Document.new(text).to_html[/(?<=<p>).*(?=<\/p>)/]
|
146
|
+
|
147
|
+
<<~HTML_SNIPPET
|
148
|
+
<li id="fn:#{number}" role="doc-endnote">
|
149
|
+
<p>
|
150
|
+
#{footnote_definition}<a href="#fnref:#{number}" class="reversefootnote" role="doc-backlink" aria-label="go to where this is referenced">↩</a>
|
151
|
+
</p>
|
152
|
+
</li>
|
153
|
+
HTML_SNIPPET
|
154
|
+
end
|
155
|
+
|
156
|
+
@footnote_definition_html = <<~HTML_CONTAINER
|
157
|
+
<div class="footnotes" role="doc-endnotes">
|
158
|
+
<ol>
|
159
|
+
#{list_items.join.strip}
|
160
|
+
</ol>
|
161
|
+
</div>
|
162
|
+
HTML_CONTAINER
|
163
|
+
end
|
164
|
+
|
165
|
+
unless @footnote_definition_html.nil? && @acronyms.size.positive?
|
166
|
+
add_acronym_alt_text(@footnote_definition_html)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
121
170
|
def remove_forbidden_characters(source)
|
122
171
|
# These are characters that are not deemed not suitable for
|
123
172
|
# markup: https://www.w3.org/TR/unicode-xml/#Charlist
|
@@ -161,7 +210,7 @@ module Govspeak
|
|
161
210
|
([^)]+) # capture inside of link text markdown
|
162
211
|
\) # match end of link text markdown
|
163
212
|
\s* # any whitespace between opening bracket and link
|
164
|
-
{
|
213
|
+
{/button} # match ending bracket
|
165
214
|
(?:\r|\n|$) # non-capturing match to make sure end of line and linebreak
|
166
215
|
}x) do |attributes, text, href|
|
167
216
|
button_classes = "govuk-button"
|
@@ -185,8 +234,8 @@ module Govspeak
|
|
185
234
|
end
|
186
235
|
|
187
236
|
extension("stat-headline", %r${stat-headline}(.*?){/stat-headline}$m) do |body|
|
188
|
-
%(\n\n<
|
189
|
-
#{Govspeak::Document.new(body.strip).to_html}</
|
237
|
+
%(\n\n<div class="stat-headline">
|
238
|
+
#{Govspeak::Document.new(body.strip).to_html}</div>\n)
|
190
239
|
end
|
191
240
|
|
192
241
|
# FIXME: these surrounded_by arguments look dodgy
|
@@ -295,6 +344,18 @@ module Govspeak
|
|
295
344
|
doc.gsub!("<ul>", "<ol>")
|
296
345
|
doc.gsub!("</ul>", "</ol>")
|
297
346
|
doc.sub!("<ol>", '<ol class="legislative-list">')
|
347
|
+
|
348
|
+
footnotes = body.scan(/\[\^(\d+)\]/).flatten
|
349
|
+
|
350
|
+
footnotes.each do |footnote|
|
351
|
+
html = "<sup id=\"fnref:#{footnote}\" role=\"doc-noteref\">" \
|
352
|
+
"<a href=\"#fn:#{footnote}\" class=\"footnote\" rel=\"footnote\">" \
|
353
|
+
"[footnote #{footnote}]</a></sup>"
|
354
|
+
|
355
|
+
doc.sub!(/(\[\^#{footnote}\])/, html)
|
356
|
+
end
|
357
|
+
|
358
|
+
add_acronym_alt_text(doc) if @acronyms.size.positive?
|
298
359
|
end
|
299
360
|
end
|
300
361
|
end
|
@@ -386,6 +447,12 @@ module Govspeak
|
|
386
447
|
def encode(text)
|
387
448
|
HTMLEntities.new.encode(text)
|
388
449
|
end
|
450
|
+
|
451
|
+
def add_acronym_alt_text(html)
|
452
|
+
@acronyms.each do |acronym|
|
453
|
+
html.gsub!(acronym[0], "<abbr title=\"#{acronym[1].strip}\">#{acronym[0]}</abbr>")
|
454
|
+
end
|
455
|
+
end
|
389
456
|
end
|
390
457
|
end
|
391
458
|
|
@@ -4,8 +4,8 @@
|
|
4
4
|
%>
|
5
5
|
<div id="contact_<%= contact.content_id %>" class="<%= ['contact', extra_class].flatten.join(' ') %>">
|
6
6
|
<div class="content">
|
7
|
-
<h3><%= contact.title %></h3>
|
8
7
|
<div class="vcard contact-inner">
|
8
|
+
<p><%= contact.title %></p>
|
9
9
|
<% contact.post_addresses.each do |address| %>
|
10
10
|
<%= Govspeak::HCardPresenter.new(address).render %>
|
11
11
|
<% end %>
|
@@ -17,7 +17,7 @@ class GovspeakAttachmentTest < Minitest::Test
|
|
17
17
|
}
|
18
18
|
|
19
19
|
rendered = render_govspeak("[Attachment:attachment.pdf]", [attachment])
|
20
|
-
assert_match(/<section class="gem-c-attachment
|
20
|
+
assert_match(/<section class="gem-c-attachment/, rendered)
|
21
21
|
assert_match(/Attachment Title/, rendered)
|
22
22
|
end
|
23
23
|
|
@@ -32,7 +32,7 @@ class GovspeakAttachmentTest < Minitest::Test
|
|
32
32
|
assert_equal("<p>some text [Attachment:attachment.pdf]</p>\n", rendered)
|
33
33
|
|
34
34
|
rendered = render_govspeak("[Attachment:attachment.pdf] some text", [attachment])
|
35
|
-
assert_match(/<section class="gem-c-attachment
|
35
|
+
assert_match(/<section class="gem-c-attachment/, rendered)
|
36
36
|
assert_match(/<p>some text<\/p>/, rendered)
|
37
37
|
end
|
38
38
|
end
|
@@ -7,34 +7,34 @@ class GovspeakTest < Minitest::Test
|
|
7
7
|
include GovspeakTestHelper
|
8
8
|
|
9
9
|
test_given_govspeak "{button start cross-domain-tracking:UA-23066786-5}[Start now](https://www.registertovote.service.gov.uk/register-to-vote/start){/button}" do
|
10
|
-
|
10
|
+
assert_html_selector 'a.gem-c-button.govuk-button--start[data-module="cross-domain-tracking"][data-tracking-code="UA-23066786-5"][href="https://www.registertovote.service.gov.uk/register-to-vote/start"]'
|
11
11
|
assert_text_output "Start now"
|
12
12
|
end
|
13
13
|
|
14
14
|
# The same as above but with line breaks
|
15
15
|
test_given_govspeak "{button start cross-domain-tracking:UA-23066786-5}\n\n\n[Start now](https://www.registertovote.service.gov.uk/register-to-vote/start)\n\n\n{/button}" do
|
16
|
-
|
16
|
+
assert_html_selector 'a.gem-c-button.govuk-button--start[data-module="cross-domain-tracking"][data-tracking-code="UA-23066786-5"][href="https://www.registertovote.service.gov.uk/register-to-vote/start"]'
|
17
17
|
assert_text_output "Start now"
|
18
18
|
end
|
19
19
|
|
20
20
|
test_given_govspeak "{button cross-domain-tracking:UA-23066786-5}[Start now](https://www.registertovote.service.gov.uk/register-to-vote/start){/button}" do
|
21
|
-
|
21
|
+
assert_html_selector 'a.gem-c-button:not(.govuk-button--start)[data-module="cross-domain-tracking"][data-tracking-code="UA-23066786-5"][href="https://www.registertovote.service.gov.uk/register-to-vote/start"]'
|
22
22
|
assert_text_output "Start now"
|
23
23
|
end
|
24
24
|
|
25
25
|
test_given_govspeak "{button start}[Start now](https://www.registertovote.service.gov.uk/register-to-vote/start){/button}" do
|
26
|
-
|
26
|
+
assert_html_selector 'a.gem-c-button.govuk-button--start[href="https://www.registertovote.service.gov.uk/register-to-vote/start"]'
|
27
27
|
assert_text_output "Start now"
|
28
28
|
end
|
29
29
|
|
30
30
|
test_given_govspeak "{button}[Start now](https://www.registertovote.service.gov.uk/register-to-vote/start){/button}" do
|
31
|
-
|
31
|
+
assert_html_selector 'a.gem-c-button:not(.govuk-button--start)[href="https://www.registertovote.service.gov.uk/register-to-vote/start"]'
|
32
32
|
assert_text_output "Start now"
|
33
33
|
end
|
34
34
|
|
35
35
|
# Test other text outputs
|
36
36
|
test_given_govspeak "{button}[Something else](https://www.registertovote.service.gov.uk/register-to-vote/start){/button}" do
|
37
|
-
|
37
|
+
assert_html_selector 'a.gem-c-button[href="https://www.registertovote.service.gov.uk/register-to-vote/start"]'
|
38
38
|
assert_text_output "Something else"
|
39
39
|
end
|
40
40
|
|
@@ -54,22 +54,6 @@ class GovspeakTest < Minitest::Test
|
|
54
54
|
assert_text_output "Text before the button with line breaks Start Now test after the button"
|
55
55
|
end
|
56
56
|
|
57
|
-
# Test README examples
|
58
|
-
test_given_govspeak "{button}[Continue](https://gov.uk/random){/button}" do
|
59
|
-
assert_html_output '<p><a class="gem-c-button govuk-button" role="button" href="https://gov.uk/random">Continue</a></p>'
|
60
|
-
assert_text_output "Continue"
|
61
|
-
end
|
62
|
-
|
63
|
-
test_given_govspeak "{button start}[Start Now](https://gov.uk/random){/button}" do
|
64
|
-
assert_html_output '<p><a class="gem-c-button govuk-button govuk-button--start" role="button" href="https://gov.uk/random"> Start Now <svg class="govuk-button__start-icon" xmlns="http://www.w3.org/2000/svg" width="17.5" height="19" viewbox="0 0 33 40" role="presentation" focusable="false"><path fill="currentColor" d="M0 0h13l20 20-20 20H0l20-20z"></path></svg></a></p>'
|
65
|
-
assert_text_output "Start Now"
|
66
|
-
end
|
67
|
-
|
68
|
-
test_given_govspeak "{button start cross-domain-tracking:UA-XXXXXX-Y}[Start Now](https://example.com/external-service/start-now){/button}" do
|
69
|
-
assert_html_output '<p><a class="gem-c-button govuk-button govuk-button--start" role="button" data-module="cross-domain-tracking" data-tracking-code="UA-XXXXXX-Y" data-tracking-name="govspeakButtonTracker" href="https://example.com/external-service/start-now"> Start Now <svg class="govuk-button__start-icon" xmlns="http://www.w3.org/2000/svg" width="17.5" height="19" viewbox="0 0 33 40" role="presentation" focusable="false"><path fill="currentColor" d="M0 0h13l20 20-20 20H0l20-20z"></path></svg></a></p>'
|
70
|
-
assert_text_output "Start Now"
|
71
|
-
end
|
72
|
-
|
73
57
|
# Test indenting button govspeak results in no render, useful in guides
|
74
58
|
test_given_govspeak " {button start cross-domain-tracking:UA-XXXXXX-Y}[Example](https://example.com/external-service/start-now){/button}" do
|
75
59
|
assert_html_output %{
|
@@ -107,7 +91,7 @@ class GovspeakTest < Minitest::Test
|
|
107
91
|
lorem lorem lorem
|
108
92
|
lorem lorem lorem
|
109
93
|
|
110
|
-
{button
|
94
|
+
{button}[Random page](https://gov.uk/random){/button}
|
111
95
|
|
112
96
|
lorem lorem lorem
|
113
97
|
lorem lorem lorem
|
@@ -120,7 +104,7 @@ class GovspeakTest < Minitest::Test
|
|
120
104
|
<p>lorem lorem lorem
|
121
105
|
lorem lorem lorem</p>
|
122
106
|
|
123
|
-
<p><a class="gem-c-button govuk-button
|
107
|
+
<p><a class="gem-c-button govuk-button" role="button" href="https://gov.uk/random">Random page</a></p>
|
124
108
|
|
125
109
|
<p>lorem lorem lorem
|
126
110
|
lorem lorem lorem</p>
|
@@ -51,7 +51,7 @@ class GovspeakContactsTest < Minitest::Test
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def compress_html(html)
|
54
|
-
html.gsub(/[\n\r]
|
54
|
+
html.gsub(/[\n\r]+\s*/, "")
|
55
55
|
end
|
56
56
|
|
57
57
|
test "contact is rendered when present in options[:contacts]" do
|
@@ -62,8 +62,8 @@ class GovspeakContactsTest < Minitest::Test
|
|
62
62
|
expected_html_output = %(
|
63
63
|
<div id="contact_4f3383e4-48a2-4461-a41d-f85ea8b89ba0" class="contact postal-address">
|
64
64
|
<div class="content">
|
65
|
-
<h3>Government Digital Service</h3>
|
66
65
|
<div class="vcard contact-inner">
|
66
|
+
<p>Government Digital Service</p>
|
67
67
|
<p class="adr">
|
68
68
|
<span class="street-address">125 Kingsway</span><br>
|
69
69
|
<span class="locality">Holborn</span><br>
|
@@ -106,8 +106,8 @@ class GovspeakContactsTest < Minitest::Test
|
|
106
106
|
expected_html_output = %(
|
107
107
|
<div id="contact_4f3383e4-48a2-4461-a41d-f85ea8b89ba0" class="contact">
|
108
108
|
<div class="content">
|
109
|
-
<h3>Government Digital Service</h3>
|
110
109
|
<div class="vcard contact-inner">
|
110
|
+
<p>Government Digital Service</p>
|
111
111
|
<div class="email-url-number">
|
112
112
|
<p class="email">
|
113
113
|
<span class="type">Email</span>
|
@@ -20,13 +20,13 @@ class GovspeakFootnoteTest < Minitest::Test
|
|
20
20
|
[^3]: And then they both point here." do
|
21
21
|
assert_html_output(
|
22
22
|
%(
|
23
|
-
<p>Footnotes can be added<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote">[footnote 1]</a></sup>.</p>
|
23
|
+
<p>Footnotes can be added<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">[footnote 1]</a></sup>.</p>
|
24
24
|
|
25
|
-
<p>Footnotes can be added too<sup id="fnref:2" role="doc-noteref"><a href="#fn:2" class="footnote">[footnote 2]</a></sup>.</p>
|
25
|
+
<p>Footnotes can be added too<sup id="fnref:2" role="doc-noteref"><a href="#fn:2" class="footnote" rel="footnote">[footnote 2]</a></sup>.</p>
|
26
26
|
|
27
|
-
<p>This footnote has a reference number<sup id="fnref:3" role="doc-noteref"><a href="#fn:3" class="footnote">[footnote 3]</a></sup>.</p>
|
27
|
+
<p>This footnote has a reference number<sup id="fnref:3" role="doc-noteref"><a href="#fn:3" class="footnote" rel="footnote">[footnote 3]</a></sup>.</p>
|
28
28
|
|
29
|
-
<p>And this footnote has the same reference number<sup id="fnref:3:1" role="doc-noteref"><a href="#fn:3" class="footnote">[footnote 3]</a></sup>.</p>
|
29
|
+
<p>And this footnote has the same reference number<sup id="fnref:3:1" role="doc-noteref"><a href="#fn:3" class="footnote" rel="footnote">[footnote 3]</a></sup>.</p>
|
30
30
|
|
31
31
|
<div class="footnotes" role="doc-endnotes">
|
32
32
|
<ol>
|
@@ -18,9 +18,7 @@ class GovspeakImagesBangTest < Minitest::Test
|
|
18
18
|
test "!!n syntax renders an image in options[:images]" do
|
19
19
|
given_govspeak "!!1", images: [Image.new] do
|
20
20
|
assert_html_output(
|
21
|
-
|
22
|
-
%(<div class="img"><img src="http://example.com/image.jpg" alt="my alt"></div>) +
|
23
|
-
%(</figure>),
|
21
|
+
"<figure class=\"image embedded\"><div class=\"img\"><img src=\"http://example.com/image.jpg\" alt=\"my alt\"></div></figure>",
|
24
22
|
)
|
25
23
|
end
|
26
24
|
end
|
@@ -28,9 +26,7 @@ class GovspeakImagesBangTest < Minitest::Test
|
|
28
26
|
test "!!n syntax escapes alt text" do
|
29
27
|
given_govspeak "!!1", images: [Image.new(alt_text: %(my alt '&"<>))] do
|
30
28
|
assert_html_output(
|
31
|
-
|
32
|
-
%(<div class="img"><img src="http://example.com/image.jpg" alt="my alt '&"<>"></div>) +
|
33
|
-
%(</figure>),
|
29
|
+
"<figure class=\"image embedded\"><div class=\"img\"><img src=\"http://example.com/image.jpg\" alt=\"my alt '&"<>\"></div></figure>",
|
34
30
|
)
|
35
31
|
end
|
36
32
|
end
|
@@ -48,10 +44,7 @@ class GovspeakImagesBangTest < Minitest::Test
|
|
48
44
|
test "!!n syntax adds image caption if given" do
|
49
45
|
given_govspeak "!!1", images: [Image.new(caption: "My Caption & so on")] do
|
50
46
|
assert_html_output(
|
51
|
-
|
52
|
-
%(<div class="img"><img src="http://example.com/image.jpg" alt="my alt"></div>\n) +
|
53
|
-
%(<figcaption><p>My Caption & so on</p></figcaption>) +
|
54
|
-
%(</figure>),
|
47
|
+
"<figure class=\"image embedded\"><div class=\"img\"><img src=\"http://example.com/image.jpg\" alt=\"my alt\"></div>\n<figcaption><p>My Caption & so on</p></figcaption></figure>",
|
55
48
|
)
|
56
49
|
end
|
57
50
|
end
|
@@ -59,9 +52,7 @@ class GovspeakImagesBangTest < Minitest::Test
|
|
59
52
|
test "!!n syntax ignores a blank caption" do
|
60
53
|
given_govspeak "!!1", images: [Image.new(caption: " ")] do
|
61
54
|
assert_html_output(
|
62
|
-
|
63
|
-
%(<div class="img"><img src="http://example.com/image.jpg" alt="my alt"></div>) +
|
64
|
-
%(</figure>),
|
55
|
+
"<figure class=\"image embedded\"><div class=\"img\"><img src=\"http://example.com/image.jpg\" alt=\"my alt\"></div></figure>",
|
65
56
|
)
|
66
57
|
end
|
67
58
|
end
|
@@ -69,10 +60,7 @@ class GovspeakImagesBangTest < Minitest::Test
|
|
69
60
|
test "¡¡n syntax adds image credit if given" do
|
70
61
|
given_govspeak "!!1", images: [Image.new(credit: "My Credit & so on")] do
|
71
62
|
assert_html_output(
|
72
|
-
|
73
|
-
%(<div class="img"><img src="http://example.com/image.jpg" alt="my alt"></div>\n) +
|
74
|
-
%(<figcaption><p>Image credit: My Credit & so on</p></figcaption>) +
|
75
|
-
%(</figure>),
|
63
|
+
"<figure class=\"image embedded\"><div class=\"img\"><img src=\"http://example.com/image.jpg\" alt=\"my alt\"></div>\n<figcaption><p>Image credit: My Credit & so on</p></figcaption></figure>",
|
76
64
|
)
|
77
65
|
end
|
78
66
|
end
|
@@ -80,9 +68,7 @@ class GovspeakImagesBangTest < Minitest::Test
|
|
80
68
|
test "!!n syntax ignores a blank credit" do
|
81
69
|
given_govspeak "!!1", images: [Image.new(credit: " ")] do
|
82
70
|
assert_html_output(
|
83
|
-
|
84
|
-
%(<div class="img"><img src="http://example.com/image.jpg" alt="my alt"></div>) +
|
85
|
-
%(</figure>),
|
71
|
+
"<figure class=\"image embedded\"><div class=\"img\"><img src=\"http://example.com/image.jpg\" alt=\"my alt\"></div></figure>",
|
86
72
|
)
|
87
73
|
end
|
88
74
|
end
|
@@ -90,13 +76,7 @@ class GovspeakImagesBangTest < Minitest::Test
|
|
90
76
|
test "!!n syntax adds image caption and credit if given" do
|
91
77
|
given_govspeak "!!1", images: [Image.new(caption: "My Caption & so on", credit: "My Credit & so on")] do
|
92
78
|
assert_html_output(
|
93
|
-
|
94
|
-
%(<div class="img"><img src="http://example.com/image.jpg" alt="my alt"></div>\n) +
|
95
|
-
%(<figcaption>) +
|
96
|
-
%(<p>My Caption & so on</p>\n) +
|
97
|
-
%(<p>Image credit: My Credit & so on</p>) +
|
98
|
-
%(</figcaption>) +
|
99
|
-
%(</figure>),
|
79
|
+
"<figure class=\"image embedded\"><div class=\"img\"><img src=\"http://example.com/image.jpg\" alt=\"my alt\"></div>\n<figcaption><p>My Caption & so on</p>\n<p>Image credit: My Credit & so on</p></figcaption></figure>",
|
100
80
|
)
|
101
81
|
end
|
102
82
|
end
|
@@ -14,9 +14,7 @@ class GovspeakImagesTest < Minitest::Test
|
|
14
14
|
test "Image:image-id syntax renders an image in options[:images]" do
|
15
15
|
given_govspeak "[Image:image-id]", images: [build_image] do
|
16
16
|
assert_html_output(
|
17
|
-
|
18
|
-
%(<div class="img"><img src="http://example.com/image.jpg" alt="my alt"></div>) +
|
19
|
-
%(</figure>),
|
17
|
+
"<figure class=\"image embedded\"><div class=\"img\"><img src=\"http://example.com/image.jpg\" alt=\"my alt\"></div></figure>",
|
20
18
|
)
|
21
19
|
end
|
22
20
|
end
|
@@ -24,9 +22,7 @@ class GovspeakImagesTest < Minitest::Test
|
|
24
22
|
test "Image:image-id syntax escapes alt text" do
|
25
23
|
given_govspeak "[Image:image-id]", images: [build_image(alt_text: %(my alt '&"<>))] do
|
26
24
|
assert_html_output(
|
27
|
-
|
28
|
-
%(<div class="img"><img src="http://example.com/image.jpg" alt="my alt '&"<>"></div>) +
|
29
|
-
%(</figure>),
|
25
|
+
"<figure class=\"image embedded\"><div class=\"img\"><img src=\"http://example.com/image.jpg\" alt=\"my alt '&"<>\"></div></figure>",
|
30
26
|
)
|
31
27
|
end
|
32
28
|
end
|
@@ -39,10 +35,7 @@ class GovspeakImagesTest < Minitest::Test
|
|
39
35
|
test "Image:image-id syntax adds image caption if given" do
|
40
36
|
given_govspeak "[Image:image-id]", images: [build_image(caption: "My Caption & so on")] do
|
41
37
|
assert_html_output(
|
42
|
-
|
43
|
-
%(<div class="img"><img src="http://example.com/image.jpg" alt="my alt"></div>\n) +
|
44
|
-
%(<figcaption><p>My Caption & so on</p></figcaption>) +
|
45
|
-
%(</figure>),
|
38
|
+
"<figure class=\"image embedded\"><div class=\"img\"><img src=\"http://example.com/image.jpg\" alt=\"my alt\"></div>\n<figcaption><p>My Caption & so on</p></figcaption></figure>",
|
46
39
|
)
|
47
40
|
end
|
48
41
|
end
|
@@ -50,9 +43,7 @@ class GovspeakImagesTest < Minitest::Test
|
|
50
43
|
test "Image:image-id syntax ignores a blank caption" do
|
51
44
|
given_govspeak "[Image:image-id]", images: [build_image(caption: " ")] do
|
52
45
|
assert_html_output(
|
53
|
-
|
54
|
-
%(<div class="img"><img src="http://example.com/image.jpg" alt="my alt"></div>) +
|
55
|
-
%(</figure>),
|
46
|
+
"<figure class=\"image embedded\"><div class=\"img\"><img src=\"http://example.com/image.jpg\" alt=\"my alt\"></div></figure>",
|
56
47
|
)
|
57
48
|
end
|
58
49
|
end
|
@@ -60,10 +51,7 @@ class GovspeakImagesTest < Minitest::Test
|
|
60
51
|
test "Image:image-id syntax adds image credit if given" do
|
61
52
|
given_govspeak "[Image:image-id]", images: [build_image(credit: "My Credit & so on")] do
|
62
53
|
assert_html_output(
|
63
|
-
|
64
|
-
%(<div class="img"><img src="http://example.com/image.jpg" alt="my alt"></div>\n) +
|
65
|
-
%(<figcaption><p>Image credit: My Credit & so on</p></figcaption>) +
|
66
|
-
%(</figure>),
|
54
|
+
"<figure class=\"image embedded\"><div class=\"img\"><img src=\"http://example.com/image.jpg\" alt=\"my alt\"></div>\n<figcaption><p>Image credit: My Credit & so on</p></figcaption></figure>",
|
67
55
|
)
|
68
56
|
end
|
69
57
|
end
|
@@ -71,9 +59,7 @@ class GovspeakImagesTest < Minitest::Test
|
|
71
59
|
test "Image:image-id syntax ignores a blank credit" do
|
72
60
|
given_govspeak "[Image:image-id]", images: [build_image(credit: " ")] do
|
73
61
|
assert_html_output(
|
74
|
-
|
75
|
-
%(<div class="img"><img src="http://example.com/image.jpg" alt="my alt"></div>) +
|
76
|
-
%(</figure>),
|
62
|
+
"<figure class=\"image embedded\"><div class=\"img\"><img src=\"http://example.com/image.jpg\" alt=\"my alt\"></div></figure>",
|
77
63
|
)
|
78
64
|
end
|
79
65
|
end
|
@@ -81,13 +67,7 @@ class GovspeakImagesTest < Minitest::Test
|
|
81
67
|
test "Image:image-id syntax adds image caption and credit if given" do
|
82
68
|
given_govspeak "[Image:image-id]", images: [build_image(caption: "My Caption & so on", credit: "My Credit & so on")] do
|
83
69
|
assert_html_output(
|
84
|
-
|
85
|
-
%(<div class="img"><img src="http://example.com/image.jpg" alt="my alt"></div>\n) +
|
86
|
-
%(<figcaption>) +
|
87
|
-
%(<p>My Caption & so on</p>\n) +
|
88
|
-
%(<p>Image credit: My Credit & so on</p>) +
|
89
|
-
%(</figcaption>) +
|
90
|
-
%(</figure>),
|
70
|
+
"<figure class=\"image embedded\"><div class=\"img\"><img src=\"http://example.com/image.jpg\" alt=\"my alt\"></div>\n<figcaption><p>My Caption & so on</p>\n<p>Image credit: My Credit & so on</p></figcaption></figure>",
|
91
71
|
)
|
92
72
|
end
|
93
73
|
end
|
@@ -99,18 +79,13 @@ class GovspeakImagesTest < Minitest::Test
|
|
99
79
|
|
100
80
|
given_govspeak "[Image:image-id]", images: [build_image] do
|
101
81
|
assert_html_output(
|
102
|
-
|
103
|
-
%(<div class="img"><img src="http://example.com/image.jpg" alt="my alt"></div>) +
|
104
|
-
%(</figure>),
|
82
|
+
"<figure class=\"image embedded\"><div class=\"img\"><img src=\"http://example.com/image.jpg\" alt=\"my alt\"></div></figure>",
|
105
83
|
)
|
106
84
|
end
|
107
85
|
|
108
86
|
given_govspeak "[Image:image-id] some text", images: [build_image] do
|
109
87
|
assert_html_output(
|
110
|
-
|
111
|
-
%(<div class="img"><img src="http://example.com/image.jpg" alt="my alt"></div>) +
|
112
|
-
%(</figure>\n) +
|
113
|
-
%(<p>some text</p>),
|
88
|
+
"<figure class=\"image embedded\"><div class=\"img\"><img src=\"http://example.com/image.jpg\" alt=\"my alt\"></div></figure>\n<p>some text</p>",
|
114
89
|
)
|
115
90
|
end
|
116
91
|
end
|
data/test/govspeak_test.rb
CHANGED
@@ -30,7 +30,7 @@ class GovspeakTest < Minitest::Test
|
|
30
30
|
|
31
31
|
test "stat-headline block extension" do
|
32
32
|
rendered = Govspeak::Document.new("this \n{stat-headline}*13.8bn* Age of the universe in years{/stat-headline}").to_html
|
33
|
-
assert_equal %(<p>this</p>\n\n<
|
33
|
+
assert_equal %(<p>this</p>\n\n<div class="stat-headline">\n<p><em>13.8bn</em> Age of the universe in years</p>\n</div>\n), rendered
|
34
34
|
end
|
35
35
|
|
36
36
|
test "extracts headers with text, level and generated id" do
|
@@ -591,6 +591,352 @@ Teston
|
|
591
591
|
}
|
592
592
|
end
|
593
593
|
|
594
|
+
test_given_govspeak "
|
595
|
+
$LegislativeList
|
596
|
+
* 1. Item 1[^1]
|
597
|
+
* 2. Item 2[^2]
|
598
|
+
* 3. Item 3
|
599
|
+
$EndLegislativeList
|
600
|
+
|
601
|
+
[^1]: Footnote definition one
|
602
|
+
[^2]: Footnote definition two
|
603
|
+
" do
|
604
|
+
assert_html_output %(
|
605
|
+
<ol class="legislative-list">
|
606
|
+
<li>1. Item 1<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">[footnote 1]</a></sup>
|
607
|
+
</li>
|
608
|
+
<li>2. Item 2<sup id="fnref:2" role="doc-noteref"><a href="#fn:2" class="footnote" rel="footnote">[footnote 2]</a></sup>
|
609
|
+
</li>
|
610
|
+
<li>3. Item 3</li>
|
611
|
+
</ol>
|
612
|
+
|
613
|
+
<div class="footnotes" role="doc-endnotes">
|
614
|
+
<ol>
|
615
|
+
<li id="fn:1" role="doc-endnote">
|
616
|
+
<p>
|
617
|
+
Footnote definition one<a href="#fnref:1" class="reversefootnote" role="doc-backlink" aria-label="go to where this is referenced">↩</a>
|
618
|
+
</p>
|
619
|
+
</li>
|
620
|
+
<li id="fn:2" role="doc-endnote">
|
621
|
+
<p>
|
622
|
+
Footnote definition two<a href="#fnref:2" class="reversefootnote" role="doc-backlink" aria-label="go to where this is referenced">↩</a>
|
623
|
+
</p>
|
624
|
+
</li>
|
625
|
+
</ol>
|
626
|
+
</div>
|
627
|
+
)
|
628
|
+
end
|
629
|
+
|
630
|
+
test_given_govspeak "
|
631
|
+
$LegislativeList
|
632
|
+
* 1. Item 1[^1]
|
633
|
+
* 2. Item 2
|
634
|
+
* 3. Item 3
|
635
|
+
$EndLegislativeList
|
636
|
+
|
637
|
+
This is a paragraph with a footnote[^2].
|
638
|
+
|
639
|
+
$LegislativeList
|
640
|
+
* 1. Item 1
|
641
|
+
* 2. Item 2[^3]
|
642
|
+
* 3. Item 3
|
643
|
+
$EndLegislativeList
|
644
|
+
|
645
|
+
[^1]: Footnote definition one
|
646
|
+
[^2]: Footnote definition two
|
647
|
+
[^3]: Footnote definition two
|
648
|
+
" do
|
649
|
+
assert_html_output %(
|
650
|
+
<ol class="legislative-list">
|
651
|
+
<li>1. Item 1<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">[footnote 1]</a></sup>
|
652
|
+
</li>
|
653
|
+
<li>2. Item 2</li>
|
654
|
+
<li>3. Item 3</li>
|
655
|
+
</ol>
|
656
|
+
|
657
|
+
<p>This is a paragraph with a footnote<sup id="fnref:2" role="doc-noteref"><a href="#fn:2" class="footnote" rel="footnote">[footnote 2]</a></sup>.</p>
|
658
|
+
|
659
|
+
<ol class="legislative-list">
|
660
|
+
<li>1. Item 1</li>
|
661
|
+
<li>2. Item 2<sup id="fnref:3" role="doc-noteref"><a href="#fn:3" class="footnote" rel="footnote">[footnote 3]</a></sup>
|
662
|
+
</li>
|
663
|
+
<li>3. Item 3</li>
|
664
|
+
</ol>
|
665
|
+
|
666
|
+
<div class="footnotes" role="doc-endnotes">
|
667
|
+
<ol>
|
668
|
+
<li id="fn:1" role="doc-endnote">
|
669
|
+
<p>
|
670
|
+
Footnote definition one<a href="#fnref:1" class="reversefootnote" role="doc-backlink" aria-label="go to where this is referenced">↩</a>
|
671
|
+
</p>
|
672
|
+
</li>
|
673
|
+
<li id="fn:2" role="doc-endnote">
|
674
|
+
<p>
|
675
|
+
Footnote definition two<a href="#fnref:2" class="reversefootnote" role="doc-backlink" aria-label="go to where this is referenced">↩</a>
|
676
|
+
</p>
|
677
|
+
</li>
|
678
|
+
<li id="fn:3" role="doc-endnote">
|
679
|
+
<p>
|
680
|
+
Footnote definition two<a href="#fnref:3" class="reversefootnote" role="doc-backlink" aria-label="go to where this is referenced">↩</a>
|
681
|
+
</p>
|
682
|
+
</li>
|
683
|
+
</ol>
|
684
|
+
</div>
|
685
|
+
)
|
686
|
+
end
|
687
|
+
|
688
|
+
test_given_govspeak "
|
689
|
+
$LegislativeList
|
690
|
+
* 1. Item 1[^1]
|
691
|
+
* 2. Item 2[^2]
|
692
|
+
* 3. Item 3[^3]
|
693
|
+
$EndLegislativeList
|
694
|
+
|
695
|
+
This is a paragraph with a footnote[^4].
|
696
|
+
|
697
|
+
$LegislativeList
|
698
|
+
* 1. Item 1[^5]
|
699
|
+
* 2. Item 2[^6]
|
700
|
+
* 3. Item 3[^7]
|
701
|
+
$EndLegislativeList
|
702
|
+
|
703
|
+
This is a paragraph with a footnote[^8].
|
704
|
+
|
705
|
+
$LegislativeList
|
706
|
+
* 1. Item 1[^9]
|
707
|
+
* 2. Item 2[^10]
|
708
|
+
* 3. Item 3[^11]
|
709
|
+
$EndLegislativeList
|
710
|
+
|
711
|
+
This is a paragraph with a footnote[^12].
|
712
|
+
|
713
|
+
[^1]: Footnote definition 1
|
714
|
+
[^2]: Footnote definition 2
|
715
|
+
[^3]: Footnote definition 3
|
716
|
+
[^4]: Footnote definition 4
|
717
|
+
[^5]: Footnote definition 5
|
718
|
+
[^6]: Footnote definition 6
|
719
|
+
[^7]: Footnote definition 7
|
720
|
+
[^8]: Footnote definition 8
|
721
|
+
[^9]: Footnote definition 9
|
722
|
+
[^10]: Footnote definition 10
|
723
|
+
[^11]: Footnote definition 11
|
724
|
+
[^12]: Footnote definition 12
|
725
|
+
" do
|
726
|
+
assert_html_output %(
|
727
|
+
<ol class="legislative-list">
|
728
|
+
<li>1. Item 1<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">[footnote 1]</a></sup>
|
729
|
+
</li>
|
730
|
+
<li>2. Item 2<sup id="fnref:2" role="doc-noteref"><a href="#fn:2" class="footnote" rel="footnote">[footnote 2]</a></sup>
|
731
|
+
</li>
|
732
|
+
<li>3. Item 3<sup id="fnref:3" role="doc-noteref"><a href="#fn:3" class="footnote" rel="footnote">[footnote 3]</a></sup>
|
733
|
+
</li>
|
734
|
+
</ol>
|
735
|
+
|
736
|
+
<p>This is a paragraph with a footnote<sup id="fnref:4" role="doc-noteref"><a href="#fn:4" class="footnote" rel="footnote">[footnote 4]</a></sup>.</p>
|
737
|
+
|
738
|
+
<ol class="legislative-list">
|
739
|
+
<li>1. Item 1<sup id="fnref:5" role="doc-noteref"><a href="#fn:5" class="footnote" rel="footnote">[footnote 5]</a></sup>
|
740
|
+
</li>
|
741
|
+
<li>2. Item 2<sup id="fnref:6" role="doc-noteref"><a href="#fn:6" class="footnote" rel="footnote">[footnote 6]</a></sup>
|
742
|
+
</li>
|
743
|
+
<li>3. Item 3<sup id="fnref:7" role="doc-noteref"><a href="#fn:7" class="footnote" rel="footnote">[footnote 7]</a></sup>
|
744
|
+
</li>
|
745
|
+
</ol>
|
746
|
+
|
747
|
+
<p>This is a paragraph with a footnote<sup id="fnref:8" role="doc-noteref"><a href="#fn:8" class="footnote" rel="footnote">[footnote 8]</a></sup>.</p>
|
748
|
+
|
749
|
+
<ol class="legislative-list">
|
750
|
+
<li>1. Item 1<sup id="fnref:9" role="doc-noteref"><a href="#fn:9" class="footnote" rel="footnote">[footnote 9]</a></sup>
|
751
|
+
</li>
|
752
|
+
<li>2. Item 2<sup id="fnref:10" role="doc-noteref"><a href="#fn:10" class="footnote" rel="footnote">[footnote 10]</a></sup>
|
753
|
+
</li>
|
754
|
+
<li>3. Item 3<sup id="fnref:11" role="doc-noteref"><a href="#fn:11" class="footnote" rel="footnote">[footnote 11]</a></sup>
|
755
|
+
</li>
|
756
|
+
</ol>
|
757
|
+
|
758
|
+
<p>This is a paragraph with a footnote<sup id="fnref:12" role="doc-noteref"><a href="#fn:12" class="footnote" rel="footnote">[footnote 12]</a></sup>.</p>
|
759
|
+
|
760
|
+
<div class="footnotes" role="doc-endnotes">
|
761
|
+
<ol>
|
762
|
+
<li id="fn:1" role="doc-endnote">
|
763
|
+
<p>
|
764
|
+
Footnote definition 1<a href="#fnref:1" class="reversefootnote" role="doc-backlink" aria-label="go to where this is referenced">↩</a>
|
765
|
+
</p>
|
766
|
+
</li>
|
767
|
+
<li id="fn:2" role="doc-endnote">
|
768
|
+
<p>
|
769
|
+
Footnote definition 2<a href="#fnref:2" class="reversefootnote" role="doc-backlink" aria-label="go to where this is referenced">↩</a>
|
770
|
+
</p>
|
771
|
+
</li>
|
772
|
+
<li id="fn:3" role="doc-endnote">
|
773
|
+
<p>
|
774
|
+
Footnote definition 3<a href="#fnref:3" class="reversefootnote" role="doc-backlink" aria-label="go to where this is referenced">↩</a>
|
775
|
+
</p>
|
776
|
+
</li>
|
777
|
+
<li id="fn:4" role="doc-endnote">
|
778
|
+
<p>
|
779
|
+
Footnote definition 4<a href="#fnref:4" class="reversefootnote" role="doc-backlink" aria-label="go to where this is referenced">↩</a>
|
780
|
+
</p>
|
781
|
+
</li>
|
782
|
+
<li id="fn:5" role="doc-endnote">
|
783
|
+
<p>
|
784
|
+
Footnote definition 5<a href="#fnref:5" class="reversefootnote" role="doc-backlink" aria-label="go to where this is referenced">↩</a>
|
785
|
+
</p>
|
786
|
+
</li>
|
787
|
+
<li id="fn:6" role="doc-endnote">
|
788
|
+
<p>
|
789
|
+
Footnote definition 6<a href="#fnref:6" class="reversefootnote" role="doc-backlink" aria-label="go to where this is referenced">↩</a>
|
790
|
+
</p>
|
791
|
+
</li>
|
792
|
+
<li id="fn:7" role="doc-endnote">
|
793
|
+
<p>
|
794
|
+
Footnote definition 7<a href="#fnref:7" class="reversefootnote" role="doc-backlink" aria-label="go to where this is referenced">↩</a>
|
795
|
+
</p>
|
796
|
+
</li>
|
797
|
+
<li id="fn:8" role="doc-endnote">
|
798
|
+
<p>
|
799
|
+
Footnote definition 8<a href="#fnref:8" class="reversefootnote" role="doc-backlink" aria-label="go to where this is referenced">↩</a>
|
800
|
+
</p>
|
801
|
+
</li>
|
802
|
+
<li id="fn:9" role="doc-endnote">
|
803
|
+
<p>
|
804
|
+
Footnote definition 9<a href="#fnref:9" class="reversefootnote" role="doc-backlink" aria-label="go to where this is referenced">↩</a>
|
805
|
+
</p>
|
806
|
+
</li>
|
807
|
+
<li id="fn:10" role="doc-endnote">
|
808
|
+
<p>
|
809
|
+
Footnote definition 10<a href="#fnref:10" class="reversefootnote" role="doc-backlink" aria-label="go to where this is referenced">↩</a>
|
810
|
+
</p>
|
811
|
+
</li>
|
812
|
+
<li id="fn:11" role="doc-endnote">
|
813
|
+
<p>
|
814
|
+
Footnote definition 11<a href="#fnref:11" class="reversefootnote" role="doc-backlink" aria-label="go to where this is referenced">↩</a>
|
815
|
+
</p>
|
816
|
+
</li>
|
817
|
+
<li id="fn:12" role="doc-endnote">
|
818
|
+
<p>
|
819
|
+
Footnote definition 12<a href="#fnref:12" class="reversefootnote" role="doc-backlink" aria-label="go to where this is referenced">↩</a>
|
820
|
+
</p>
|
821
|
+
</li>
|
822
|
+
</ol>
|
823
|
+
</div>
|
824
|
+
)
|
825
|
+
end
|
826
|
+
|
827
|
+
test_given_govspeak "
|
828
|
+
$LegislativeList
|
829
|
+
* 1. Item 1[^1] with a [link](http://www.gov.uk)
|
830
|
+
* 2. Item 2
|
831
|
+
* 3. Item 3
|
832
|
+
$EndLegislativeList
|
833
|
+
|
834
|
+
This is a paragraph with a footnote[^2]
|
835
|
+
|
836
|
+
[^1]: Footnote definition one
|
837
|
+
[^2]: Footnote definition two
|
838
|
+
" do
|
839
|
+
assert_html_output %(
|
840
|
+
<ol class="legislative-list">
|
841
|
+
<li>1. Item 1<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">[footnote 1]</a></sup> with a <a href="http://www.gov.uk">link</a>
|
842
|
+
</li>
|
843
|
+
<li>2. Item 2</li>
|
844
|
+
<li>3. Item 3</li>
|
845
|
+
</ol>
|
846
|
+
|
847
|
+
<p>This is a paragraph with a footnote<sup id="fnref:2" role="doc-noteref"><a href="#fn:2" class="footnote" rel="footnote">[footnote 2]</a></sup></p>
|
848
|
+
|
849
|
+
<div class="footnotes" role="doc-endnotes">
|
850
|
+
<ol>
|
851
|
+
<li id="fn:1" role="doc-endnote">
|
852
|
+
<p>
|
853
|
+
Footnote definition one<a href="#fnref:1" class="reversefootnote" role="doc-backlink" aria-label="go to where this is referenced">↩</a>
|
854
|
+
</p>
|
855
|
+
</li>
|
856
|
+
<li id="fn:2" role="doc-endnote">
|
857
|
+
<p>
|
858
|
+
Footnote definition two<a href="#fnref:2" class="reversefootnote" role="doc-backlink" aria-label="go to where this is referenced">↩</a>
|
859
|
+
</p>
|
860
|
+
</li>
|
861
|
+
</ol>
|
862
|
+
</div>
|
863
|
+
)
|
864
|
+
end
|
865
|
+
|
866
|
+
test_given_govspeak "
|
867
|
+
$LegislativeList
|
868
|
+
* 1. Item 1[^1] with a [link](http://www.gov.uk)
|
869
|
+
* 2. Item 2
|
870
|
+
* 3. Item 3[^2]
|
871
|
+
$EndLegislativeList
|
872
|
+
|
873
|
+
[^1]: Footnote definition one with a [link](http://www.gov.uk) included
|
874
|
+
[^2]: Footnote definition two with an external [link](http://www.google.com)
|
875
|
+
" do
|
876
|
+
assert_html_output %(
|
877
|
+
<ol class="legislative-list">
|
878
|
+
<li>1. Item 1<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">[footnote 1]</a></sup> with a <a href="http://www.gov.uk">link</a>
|
879
|
+
</li>
|
880
|
+
<li>2. Item 2</li>
|
881
|
+
<li>3. Item 3<sup id="fnref:2" role="doc-noteref"><a href="#fn:2" class="footnote" rel="footnote">[footnote 2]</a></sup>
|
882
|
+
</li>
|
883
|
+
</ol>
|
884
|
+
|
885
|
+
<div class="footnotes" role="doc-endnotes">
|
886
|
+
<ol>
|
887
|
+
<li id="fn:1" role="doc-endnote">
|
888
|
+
<p>
|
889
|
+
Footnote definition one with a <a href="http://www.gov.uk">link</a> included<a href="#fnref:1" class="reversefootnote" role="doc-backlink" aria-label="go to where this is referenced">↩</a>
|
890
|
+
</p>
|
891
|
+
</li>
|
892
|
+
<li id="fn:2" role="doc-endnote">
|
893
|
+
<p>
|
894
|
+
Footnote definition two with an external <a rel="external" href="http://www.google.com">link</a><a href="#fnref:2" class="reversefootnote" role="doc-backlink" aria-label="go to where this is referenced">↩</a>
|
895
|
+
</p>
|
896
|
+
</li>
|
897
|
+
</ol>
|
898
|
+
</div>
|
899
|
+
)
|
900
|
+
end
|
901
|
+
|
902
|
+
test_given_govspeak "
|
903
|
+
$LegislativeList
|
904
|
+
* 1. Item 1[^1] with an ACRONYM
|
905
|
+
* 2. Item 2[^2]
|
906
|
+
* 3. Item 3
|
907
|
+
$EndLegislativeList
|
908
|
+
|
909
|
+
[^1]: Footnote definition one
|
910
|
+
[^2]: Footnote definition two with an ACRONYM
|
911
|
+
|
912
|
+
*[ACRONYM]: This is the acronym explanation
|
913
|
+
" do
|
914
|
+
assert_html_output %(
|
915
|
+
<ol class="legislative-list">
|
916
|
+
<li>1. Item 1<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">[footnote 1]</a></sup> with an <abbr title="This is the acronym explanation">ACRONYM</abbr>
|
917
|
+
</li>
|
918
|
+
<li>2. Item 2<sup id="fnref:2" role="doc-noteref"><a href="#fn:2" class="footnote" rel="footnote">[footnote 2]</a></sup>
|
919
|
+
</li>
|
920
|
+
<li>3. Item 3</li>
|
921
|
+
</ol>
|
922
|
+
|
923
|
+
<div class="footnotes" role="doc-endnotes">
|
924
|
+
<ol>
|
925
|
+
<li id="fn:1" role="doc-endnote">
|
926
|
+
<p>
|
927
|
+
Footnote definition one<a href="#fnref:1" class="reversefootnote" role="doc-backlink" aria-label="go to where this is referenced">↩</a>
|
928
|
+
</p>
|
929
|
+
</li>
|
930
|
+
<li id="fn:2" role="doc-endnote">
|
931
|
+
<p>
|
932
|
+
Footnote definition two with an <abbr title="This is the acronym explanation">ACRONYM</abbr><a href="#fnref:2" class="reversefootnote" role="doc-backlink" aria-label="go to where this is referenced">↩</a>
|
933
|
+
</p>
|
934
|
+
</li>
|
935
|
+
</ol>
|
936
|
+
</div>
|
937
|
+
)
|
938
|
+
end
|
939
|
+
|
594
940
|
test_given_govspeak "
|
595
941
|
The quick brown
|
596
942
|
$LegislativeList
|
@@ -26,6 +26,12 @@ module GovspeakTestHelper
|
|
26
26
|
@testcase.assert expected.strip == actual, describe_error(@govspeak, expected.strip, actual)
|
27
27
|
end
|
28
28
|
|
29
|
+
def assert_html_selector(selector)
|
30
|
+
html = document.to_html
|
31
|
+
fragment = Nokogiri::HTML.fragment(html)
|
32
|
+
@testcase.assert fragment.css(selector).any?, "Expected to find #{selector} within #{html}"
|
33
|
+
end
|
34
|
+
|
29
35
|
def remove_indentation(raw)
|
30
36
|
lines = raw.split("\n")
|
31
37
|
if lines.first.empty?
|
@@ -33,7 +39,7 @@ module GovspeakTestHelper
|
|
33
39
|
nonblanks = lines.reject { |l| l.match(/^ *$/) }
|
34
40
|
indentation = nonblanks.map { |line| line.match(/^ */)[0].size }.min
|
35
41
|
unindented = lines.map do |line|
|
36
|
-
line[indentation
|
42
|
+
line[indentation..]
|
37
43
|
end
|
38
44
|
unindented.join "\n"
|
39
45
|
else
|
data/test/test_helper.rb
CHANGED
@@ -17,10 +17,10 @@ class Minitest::Test
|
|
17
17
|
clean_name = name.gsub(/\s+/, "_")
|
18
18
|
method = "test_#{clean_name.gsub(/\s+/, '_')}".to_sym
|
19
19
|
already_defined = begin
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
instance_method(method)
|
21
|
+
rescue StandardError
|
22
|
+
false
|
23
|
+
end
|
24
24
|
raise "#{method} exists" if already_defined
|
25
25
|
|
26
26
|
define_method(method, &block)
|
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.
|
4
|
+
version: 6.7.3
|
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: 2021-
|
11
|
+
date: 2021-09-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionview
|
@@ -216,14 +216,14 @@ dependencies:
|
|
216
216
|
requirements:
|
217
217
|
- - "~>"
|
218
218
|
- !ruby/object:Gem::Version
|
219
|
-
version:
|
219
|
+
version: 4.0.0
|
220
220
|
type: :development
|
221
221
|
prerelease: false
|
222
222
|
version_requirements: !ruby/object:Gem::Requirement
|
223
223
|
requirements:
|
224
224
|
- - "~>"
|
225
225
|
- !ruby/object:Gem::Version
|
226
|
-
version:
|
226
|
+
version: 4.0.0
|
227
227
|
- !ruby/object:Gem::Dependency
|
228
228
|
name: simplecov
|
229
229
|
requirement: !ruby/object:Gem::Requirement
|
@@ -360,14 +360,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
360
360
|
requirements:
|
361
361
|
- - ">="
|
362
362
|
- !ruby/object:Gem::Version
|
363
|
-
version: '
|
363
|
+
version: '2.6'
|
364
364
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
365
365
|
requirements:
|
366
366
|
- - ">="
|
367
367
|
- !ruby/object:Gem::Version
|
368
368
|
version: '0'
|
369
369
|
requirements: []
|
370
|
-
rubygems_version: 3.
|
370
|
+
rubygems_version: 3.0.3
|
371
371
|
signing_key:
|
372
372
|
specification_version: 4
|
373
373
|
summary: Markup language for single domain
|