govspeak 10.6.5 → 10.7.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/CHANGELOG.md +5 -0
- data/lib/govspeak/header_extractor.rb +6 -2
- data/lib/govspeak/post_processor.rb +36 -0
- data/lib/govspeak/structured_header_extractor.rb +9 -0
- data/lib/govspeak/version.rb +1 -1
- data/lib/govspeak.rb +2 -1
- data/test/govspeak_structured_headers_test.rb +30 -2
- data/test/govspeak_test.rb +22 -0
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4b1efcb5cc3a8435cb52e7eb9a87539a1cf9a8fc3a000adfe75e0321b2f37a98
|
|
4
|
+
data.tar.gz: 9360c67b0ff42e408f30a7613e9b6388dc2cff57d3e9eef41022ad85daf265ca
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d2e4582880a1156af68977a09bb84a1f6b7846fa13b8b01501ae79f6fc6fbe1a3ca4f9284395801b4fc29899d04b3ebf7b2a12b91b2588e295d6ec60979503fe
|
|
7
|
+
data.tar.gz: 7a13a22a339c51c3847a43a4468ede4201ddb537bd0edabe8cd8641de025dfaa62e20a3bdfb92827ad9509ea5356950c3434c59d41168510b9a2c22ea95188cf
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 10.7.0
|
|
4
|
+
|
|
5
|
+
* feature: Add auto-numbered headers option [PR #449](https://github.com/alphagov/govspeak/pull/449)
|
|
6
|
+
* fix: When finding/returning headers, filter links from header titles [PR #439](https://github.com/alphagov/govspeak/pull/439)
|
|
7
|
+
|
|
3
8
|
## 10.6.5
|
|
4
9
|
|
|
5
10
|
* Update dependencies
|
|
@@ -20,11 +20,15 @@ module Govspeak
|
|
|
20
20
|
private
|
|
21
21
|
|
|
22
22
|
def id(element)
|
|
23
|
-
element.attr.fetch("id", generate_id(element
|
|
23
|
+
element.attr.fetch("id", generate_id(text_with_links(element)))
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
def build_header(element)
|
|
27
|
-
Header.new(element
|
|
27
|
+
Header.new(text_with_links(element), element.options[:level], id(element))
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def text_with_links(element)
|
|
31
|
+
element.options[:raw_text].gsub(/\[(.+)\]\((.*)\)/, '\1')
|
|
28
32
|
end
|
|
29
33
|
|
|
30
34
|
def find_headers(parent)
|
|
@@ -160,6 +160,42 @@ module Govspeak
|
|
|
160
160
|
end
|
|
161
161
|
end
|
|
162
162
|
|
|
163
|
+
extension("use auto-numbered headers") do |document|
|
|
164
|
+
if govspeak_document.auto_numbered_headers
|
|
165
|
+
h2, h3, h4, h5, h6 = 0, 0, 0, 0, 0, 0
|
|
166
|
+
|
|
167
|
+
document.css("h2,h3,h4,h5,h6").map do |el|
|
|
168
|
+
case el.name
|
|
169
|
+
when "h2"
|
|
170
|
+
h2 += 1
|
|
171
|
+
h3 = 0
|
|
172
|
+
h4 = 0
|
|
173
|
+
h5 = 0
|
|
174
|
+
h6 = 0
|
|
175
|
+
el.inner_html = "#{h2}. #{el.inner_html}"
|
|
176
|
+
when "h3"
|
|
177
|
+
h3 += 1
|
|
178
|
+
h4 = 0
|
|
179
|
+
h5 = 0
|
|
180
|
+
h6 = 0
|
|
181
|
+
el.inner_html = "#{h2}.#{h3} #{el.inner_html}"
|
|
182
|
+
when "h4"
|
|
183
|
+
h4 += 1
|
|
184
|
+
h5 = 0
|
|
185
|
+
h6 = 0
|
|
186
|
+
el.inner_html = "#{h2}.#{h3}.#{h4} #{el.inner_html}"
|
|
187
|
+
when "h5"
|
|
188
|
+
h5 += 1
|
|
189
|
+
h6 = 0
|
|
190
|
+
el.inner_html = "#{h2}.#{h3}.#{h4}.#{h5} #{el.inner_html}"
|
|
191
|
+
when "h6"
|
|
192
|
+
h6 += 1
|
|
193
|
+
el.inner_html = "#{h2}.#{h3}.#{h4}.#{h5}.#{h6} #{el.inner_html}"
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
163
199
|
attr_reader :input, :govspeak_document
|
|
164
200
|
|
|
165
201
|
def initialize(html, govspeak_document)
|
|
@@ -41,6 +41,8 @@ module Govspeak
|
|
|
41
41
|
stack.push(header)
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
+
add_auto_numbering(structured_headers) if doc.auto_numbered_headers
|
|
45
|
+
|
|
44
46
|
structured_headers
|
|
45
47
|
end
|
|
46
48
|
|
|
@@ -96,6 +98,13 @@ module Govspeak
|
|
|
96
98
|
@stack = []
|
|
97
99
|
end
|
|
98
100
|
|
|
101
|
+
def add_auto_numbering(structured_headers, prefix: "")
|
|
102
|
+
structured_headers.each.with_index(1) do |header, index|
|
|
103
|
+
header[:text] = "#{prefix}#{index}#{'.' if prefix == ''} #{header[:text]}"
|
|
104
|
+
add_auto_numbering(header[:headers], prefix: "#{prefix}#{index}.")
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
99
108
|
private
|
|
100
109
|
|
|
101
110
|
attr_reader :doc, :stack, :structured_headers
|
data/lib/govspeak/version.rb
CHANGED
data/lib/govspeak.rb
CHANGED
|
@@ -38,7 +38,7 @@ module Govspeak
|
|
|
38
38
|
@extensions = []
|
|
39
39
|
|
|
40
40
|
attr_accessor :images
|
|
41
|
-
attr_reader :attachments, :contacts, :links, :locale, :log_snapshots
|
|
41
|
+
attr_reader :attachments, :auto_numbered_headers, :contacts, :links, :locale, :log_snapshots
|
|
42
42
|
|
|
43
43
|
def self.to_html(source, options = {})
|
|
44
44
|
new(source, options).to_html
|
|
@@ -60,6 +60,7 @@ module Govspeak
|
|
|
60
60
|
@allowed_elements = options.delete(:allowed_elements) || []
|
|
61
61
|
@allowed_image_hosts = options.delete(:allowed_image_hosts) || []
|
|
62
62
|
@attachments = Array.wrap(options.delete(:attachments))
|
|
63
|
+
@auto_numbered_headers = options.fetch(:auto_numbered_headers, false)
|
|
63
64
|
@links = Array.wrap(options.delete(:links))
|
|
64
65
|
@contacts = Array.wrap(options.delete(:contacts))
|
|
65
66
|
@locale = options.fetch(:locale, "en")
|
|
@@ -21,14 +21,16 @@ class GovspeakStructuredHeadersTest < Minitest::Test
|
|
|
21
21
|
|
|
22
22
|
### Sub heading 4.1
|
|
23
23
|
|
|
24
|
-
#### Sub heading 4.1.1
|
|
24
|
+
#### Sub sub heading 4.1.1
|
|
25
25
|
|
|
26
|
-
##### Sub heading 4.1.1.1
|
|
26
|
+
##### Sub sub sub heading 4.1.1.1
|
|
27
27
|
|
|
28
28
|
### Sub heading 4.2
|
|
29
29
|
|
|
30
30
|
## Heading 5
|
|
31
31
|
|
|
32
|
+
### [Sub heading 5.1](https://www.example.com)
|
|
33
|
+
|
|
32
34
|
)
|
|
33
35
|
end
|
|
34
36
|
|
|
@@ -67,6 +69,11 @@ class GovspeakStructuredHeadersTest < Minitest::Test
|
|
|
67
69
|
assert_equal "Sub heading 4.2", structured_headers[3].headers[1].text
|
|
68
70
|
end
|
|
69
71
|
|
|
72
|
+
test "headers that are links are based on the link text not the link" do
|
|
73
|
+
assert_equal "Sub heading 5.1", structured_headers[4].headers[0].text
|
|
74
|
+
assert_equal "sub-heading-51", structured_headers[4].headers[0].id
|
|
75
|
+
end
|
|
76
|
+
|
|
70
77
|
test "structured headers serialize to hashes recursively serializing sub headers" do
|
|
71
78
|
serialized_headers = structured_headers[1].to_h
|
|
72
79
|
|
|
@@ -138,4 +145,25 @@ class GovspeakStructuredHeadersTest < Minitest::Test
|
|
|
138
145
|
test "document with single h1 produces no headers" do
|
|
139
146
|
assert_equal [], Govspeak::Document.new("# Heading\n").structured_headers
|
|
140
147
|
end
|
|
148
|
+
|
|
149
|
+
test "auto-numbered headers are generated when the option is set on the document" do
|
|
150
|
+
doc = Govspeak::Document.new(document_body, auto_numbered_headers: true)
|
|
151
|
+
|
|
152
|
+
headers = doc.structured_headers
|
|
153
|
+
|
|
154
|
+
assert_equal "1. Heading 1", headers[0][:text]
|
|
155
|
+
assert_equal "2. Heading 2", headers[1][:text]
|
|
156
|
+
assert_equal "2.1 Sub heading 2.1", headers[1][:headers][0][:text]
|
|
157
|
+
assert_equal "2.2 Sub heading 2.2", headers[1][:headers][1][:text]
|
|
158
|
+
assert_equal "2.2.1 Sub sub heading 2.2.1", headers[1][:headers][1][:headers][0][:text]
|
|
159
|
+
assert_equal "2.3 Sub heading 2.3", headers[1][:headers][2][:text]
|
|
160
|
+
assert_equal "3. Heading 3", headers[2][:text]
|
|
161
|
+
assert_equal "4. Heading 4", headers[3][:text]
|
|
162
|
+
assert_equal "4.1 Sub heading 4.1", headers[3][:headers][0][:text]
|
|
163
|
+
assert_equal "4.1.1 Sub sub heading 4.1.1", headers[3][:headers][0][:headers][0][:text]
|
|
164
|
+
assert_equal "4.1.1.1 Sub sub sub heading 4.1.1.1", headers[3][:headers][0][:headers][0][:headers][0][:text]
|
|
165
|
+
assert_equal "4.2 Sub heading 4.2", headers[3][:headers][1][:text]
|
|
166
|
+
assert_equal "5. Heading 5", headers[4][:text]
|
|
167
|
+
assert_equal "5.1 Sub heading 5.1", headers[4][:headers][0][:text]
|
|
168
|
+
end
|
|
141
169
|
end
|
data/test/govspeak_test.rb
CHANGED
|
@@ -99,6 +99,28 @@ class GovspeakTest < Minitest::Test
|
|
|
99
99
|
assert_equal "foo bar baz", doc.to_text
|
|
100
100
|
end
|
|
101
101
|
|
|
102
|
+
test "adds auto-numbered headings when the auto_numbered_headings option is on" do
|
|
103
|
+
input = %(
|
|
104
|
+
## H2 One
|
|
105
|
+
|
|
106
|
+
### H3 One
|
|
107
|
+
|
|
108
|
+
### H3 Two
|
|
109
|
+
|
|
110
|
+
## H2 Two
|
|
111
|
+
|
|
112
|
+
### H3 Three
|
|
113
|
+
|
|
114
|
+
#### H4 One
|
|
115
|
+
|
|
116
|
+
##### H5 One
|
|
117
|
+
|
|
118
|
+
###### H6 One
|
|
119
|
+
)
|
|
120
|
+
doc = Govspeak::Document.new(input, auto_numbered_headers: true)
|
|
121
|
+
assert_equal %(\n<h2 id="h2-one">1. H2 One</h2>\n\n<h3 id="h3-one">1.1 H3 One</h3>\n\n<h3 id="h3-two">1.2 H3 Two</h3>\n\n<h2 id="h2-two">2. H2 Two</h2>\n\n<h3 id="h3-three">2.1 H3 Three</h3>\n\n<h4 id="h4-one">2.1.1 H4 One</h4>\n\n<h5 id="h5-one">2.1.1.1 H5 One</h5>\n\n<h6 id="h6-one">2.1.1.1.1 H6 One</h6>\n), doc.to_html
|
|
122
|
+
end
|
|
123
|
+
|
|
102
124
|
test "trailing space after the address should not prevent parsing" do
|
|
103
125
|
input = %($A
|
|
104
126
|
123 Test Street
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: govspeak
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 10.
|
|
4
|
+
version: 10.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- GOV.UK Dev
|
|
@@ -18,7 +18,7 @@ dependencies:
|
|
|
18
18
|
version: '6'
|
|
19
19
|
- - "<"
|
|
20
20
|
- !ruby/object:Gem::Version
|
|
21
|
-
version: 8.
|
|
21
|
+
version: 8.1.2
|
|
22
22
|
type: :runtime
|
|
23
23
|
prerelease: false
|
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -28,7 +28,7 @@ dependencies:
|
|
|
28
28
|
version: '6'
|
|
29
29
|
- - "<"
|
|
30
30
|
- !ruby/object:Gem::Version
|
|
31
|
-
version: 8.
|
|
31
|
+
version: 8.1.2
|
|
32
32
|
- !ruby/object:Gem::Dependency
|
|
33
33
|
name: addressable
|
|
34
34
|
requirement: !ruby/object:Gem::Requirement
|