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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b55c7097bba63f4d11e694c6cd683e13dddb4e4e444b61c3035e313c7836b4e5
4
- data.tar.gz: 1aa8619222200af1e482598ffc53573cd862ac406369f4e15fbd954d7c85d34a
3
+ metadata.gz: 4b1efcb5cc3a8435cb52e7eb9a87539a1cf9a8fc3a000adfe75e0321b2f37a98
4
+ data.tar.gz: 9360c67b0ff42e408f30a7613e9b6388dc2cff57d3e9eef41022ad85daf265ca
5
5
  SHA512:
6
- metadata.gz: 8c0718694838de516cbb9583e599883422b0605ff150022e670c31fbe9896a376abaa92174053ab49ecff4e3a3c71da49a18a5ef3151eb24868282a4e2acf754
7
- data.tar.gz: cb7f5f0b6a29154d4d9d0675ca72fa29d9c30f4b42f989365c33df81e76d0577b9d2d96577c72fdb626a543763c82d16e09ff459b37fd9801062d172f563b9e1
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.options[:raw_text]))
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.options[:raw_text], element.options[:level], id(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
@@ -1,3 +1,3 @@
1
1
  module Govspeak
2
- VERSION = "10.6.5".freeze
2
+ VERSION = "10.7.0".freeze
3
3
  end
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
@@ -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.6.5
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.0.4
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.0.4
31
+ version: 8.1.2
32
32
  - !ruby/object:Gem::Dependency
33
33
  name: addressable
34
34
  requirement: !ruby/object:Gem::Requirement