govspeak 8.3.1 → 8.3.3

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: 330ac68b36870075d83d6cae5223e28d12186d7b9435be02df50829f11d8c27e
4
- data.tar.gz: 3d0b8d3e7b1f98d9e3c814f141319a56a8388ac114b308aba7c3945e5661bbe4
3
+ metadata.gz: 13c63623d2836910a9a3e9c634059dfece9e7eca7a889d142ba006a8b74443db
4
+ data.tar.gz: 3235a49df7e6860a9f2a20b0e55eb92e771df6a5f16bac6ad61776e28494111a
5
5
  SHA512:
6
- metadata.gz: c23c1e930d96b6c67fcc9a46c3fc2b1e048d3c5cf9f741e55de28b94bb334e56a07108326cf5bc96c140764f860a0532ff38df87dbb9e04355576f93ebe7efad
7
- data.tar.gz: ed762ebf793ee83971ddcf4a5102379b2ad0dea4adea3134c8bd818c9c15d1d03e957b2b433549bc0846525bea1fb3a19c3574eafb1ac46dc1b98f27c59009cb
6
+ metadata.gz: 29f02ae12fd4b8388990109ba3c2fec681d85286bcf352fff8d571dd2918343410b1ca1df518a35dd8e9ef3e886e3a306ee185e619d0435b3670c57091da7bbd
7
+ data.tar.gz: 52094b3250537544d50761204701cb2ba5f32c94fd2bd2b32c81eb6ef5fbcfee1812f432f62133afcce2c02730401fd06db9e492ab67c2fea69680eaf525dfd2
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## 8.3.3
2
+
3
+ * Fix single line formatting of call to action component ([#302](https://github.com/alphagov/govspeak/pull/302))
4
+
5
+ ## 8.3.2
6
+
7
+ * Various bug fixes related to legislative list components ([#298](https://github.com/alphagov/govspeak/pull/298))
8
+
1
9
  ## 8.3.1
2
10
 
3
11
  * Bug fixes related to block elements in call to action and legislative list components ([#293](https://github.com/alphagov/govspeak/pull/293))
@@ -167,7 +167,7 @@ module Govspeak
167
167
 
168
168
  def output
169
169
  document = nokogiri_document
170
- self.class.extensions.each do |_, block|
170
+ self.class.extensions.each do |(_, block)|
171
171
  instance_exec(document, &block)
172
172
  end
173
173
  document.to_html
@@ -59,7 +59,7 @@ module Govspeak
59
59
  # Not showing United Kingdom country is a "feature" lifted and shifted
60
60
  # from Whitehall:
61
61
  # https://github.com/alphagov/whitehall/blob/c67d53d80f9856549c2da1941a10dbb9170be494/lib/address_formatter/formatter.rb#L17
62
- (key == "world_location" && value.strip == "United Kingdom" || value == "")
62
+ key == "world_location" && value.strip == "United Kingdom" || value == ""
63
63
  end
64
64
  end
65
65
 
@@ -1,3 +1,3 @@
1
1
  module Govspeak
2
- VERSION = "8.3.1".freeze
2
+ VERSION = "8.3.3".freeze
3
3
  end
data/lib/govspeak.rb CHANGED
@@ -13,7 +13,6 @@ require "govspeak/header_extractor"
13
13
  require "govspeak/structured_header_extractor"
14
14
  require "govspeak/html_validator"
15
15
  require "govspeak/html_sanitizer"
16
- require "govspeak/kramdown_overrides"
17
16
  require "govspeak/blockquote_extra_quote_remover"
18
17
  require "govspeak/post_processor"
19
18
  require "govspeak/link_extractor"
@@ -278,7 +277,9 @@ module Govspeak
278
277
 
279
278
  extension("call-to-action", surrounded_by("$CTA")) do |body|
280
279
  <<~BODY
281
- <div class="call-to-action" markdown="1">#{body}</div>
280
+ <div class="call-to-action" markdown="1">
281
+ #{body.strip}
282
+ </div>
282
283
  BODY
283
284
  end
284
285
 
@@ -298,8 +299,8 @@ module Govspeak
298
299
  end
299
300
 
300
301
  extension("legislative list", /#{NEW_PARAGRAPH_LOOKBEHIND}\$LegislativeList\s*$(.*?)\$EndLegislativeList/m) do |body|
301
- # The surrounding div is neccessary to control flow in `parse_block_html` and
302
- # maintain the same functionality as a previous version of this extension.
302
+ # The surrounding div is neccessary to accurately identify legislative lists
303
+ # in post-processing.
303
304
  <<~BODY
304
305
  {::options ordered_lists_disabled=\"true\" /}
305
306
  <div class="legislative-list-wrapper" markdown="1">#{body}</div>
@@ -53,17 +53,111 @@ module Kramdown
53
53
  def parse_block_html
54
54
  return false if CUSTOM_INLINE_ELEMENTS.include?(@src[1].downcase)
55
55
 
56
+ super
57
+ end
58
+
59
+ # We override the parse_list method with a modified version where ordered lists are
60
+ # disabled (for use with legislative lists). The majority of the method body is copied
61
+ # over (from https://github.com/gettalong/kramdown/blob/REL_2_3_1/lib/kramdown/parser/kramdown/list.rb#L54),
62
+ # only the LIST_START is changed. Previously, we dynamically modified some of the
63
+ # class-scoped variables used in this method; this provides a thread-safe alternative.
64
+ def parse_list
56
65
  return super unless @options[:ordered_lists_disabled]
57
66
 
58
- # Kramdown loads parsers into the instance from `options` which are scoped to
59
- # the class. Because we are changing these options inside an instance, we must
60
- # reconfigure the parser before and after disbaling ordered lists.
61
- Govspeak::KramdownOverrides.with_kramdown_ordered_lists_disabled do
62
- configure_parser
63
- super
67
+ return if @src.check(LIST_START_OL)
68
+
69
+ start_line_number = @src.current_line_number
70
+ type, list_start_re = (@src.check(LIST_START_UL) ? [:ul, LIST_START_UL] : [:ol, LIST_START_OL])
71
+ list = new_block_el(type, nil, nil, location: start_line_number)
72
+
73
+ item = nil
74
+ content_re, lazy_re, indent_re = nil
75
+ eob_found = false
76
+ nested_list_found = false
77
+ last_is_blank = false
78
+ until @src.eos?
79
+ start_line_number = @src.current_line_number
80
+ if last_is_blank && @src.check(HR_START)
81
+ break
82
+ elsif @src.scan(EOB_MARKER)
83
+ eob_found = true
84
+ break
85
+ elsif @src.scan(list_start_re)
86
+ list.options[:first_list_marker] ||= @src[1].strip
87
+ item = Element.new(:li, nil, nil, location: start_line_number)
88
+ item.value, indentation, content_re, lazy_re, indent_re =
89
+ parse_first_list_line(@src[1].length, @src[2])
90
+ list.children << item
91
+
92
+ item.value.sub!(self.class::LIST_ITEM_IAL) do
93
+ parse_attribute_list(::Regexp.last_match(1), item.options[:ial] ||= {})
94
+ ""
95
+ end
96
+
97
+ list_start_re = fetch_pattern(type, indentation)
98
+ nested_list_found = (item.value =~ LIST_START_UL)
99
+ last_is_blank = false
100
+ item.value = [item.value]
101
+ elsif (result = @src.scan(content_re)) || (!last_is_blank && (result = @src.scan(lazy_re)))
102
+ result.sub!(/^(\t+)/) { " " * 4 * ::Regexp.last_match(1).length }
103
+ indentation_found = result.sub!(indent_re, "")
104
+ if !nested_list_found && indentation_found && result =~ LIST_START_UL
105
+ item.value << +""
106
+ nested_list_found = true
107
+ elsif nested_list_found && !indentation_found && result =~ LIST_START_UL
108
+ result = " " * (indentation + 4) << result
109
+ end
110
+ item.value.last << result
111
+ last_is_blank = false
112
+ elsif (result = @src.scan(BLANK_LINE))
113
+ nested_list_found = true
114
+ last_is_blank = true
115
+ item.value.last << result
116
+ else
117
+ break
118
+ end
64
119
  end
65
120
 
66
- configure_parser
121
+ @tree.children << list
122
+
123
+ last = nil
124
+ list.children.each do |it|
125
+ temp = Element.new(:temp, nil, nil, location: it.options[:location])
126
+
127
+ env = save_env
128
+ location = it.options[:location]
129
+ it.value.each do |val|
130
+ @src = ::Kramdown::Utils::StringScanner.new(val, location)
131
+ parse_blocks(temp)
132
+ location = @src.current_line_number
133
+ end
134
+ restore_env(env)
135
+
136
+ it.children = temp.children
137
+ it.value = nil
138
+
139
+ it_children = it.children
140
+ next if it_children.empty?
141
+
142
+ # Handle the case where an EOB marker is inserted by a block IAL for the first paragraph
143
+ it_children.delete_at(1) if it_children.first.type == :p &&
144
+ it_children.length >= 2 && it_children[1].type == :eob && it_children.first.options[:ial]
145
+
146
+ if it_children.first.type == :p &&
147
+ (it_children.length < 2 || it_children[1].type != :blank ||
148
+ (it == list.children.last && it_children.length == 2 && !eob_found)) &&
149
+ (list.children.last != it || list.children.size == 1 ||
150
+ list.children[0..-2].any? { |cit| !cit.children.first || cit.children.first.type != :p || cit.children.first.options[:transparent] })
151
+ it_children.first.children.first.value << "\n" if it_children.size > 1 && it_children[1].type != :blank
152
+ it_children.first.options[:transparent] = true
153
+ end
154
+
155
+ last = (it_children.last.type == :blank ? it_children.pop : nil)
156
+ end
157
+
158
+ @tree.children << last if !last.nil? && !eob_found
159
+
160
+ true
67
161
  end
68
162
  end
69
163
  end
@@ -425,6 +425,48 @@ Teston
425
425
  assert_text_output "Click here to start the tool"
426
426
  end
427
427
 
428
+ test_given_govspeak "
429
+ $CTA Click here to start the program $CTA
430
+
431
+ Here is some text" do
432
+ assert_html_output %(
433
+ <div class="call-to-action">
434
+ <p>Click here to start the program</p>
435
+ </div>
436
+
437
+ <p>Here is some text</p>)
438
+ end
439
+
440
+ test_given_govspeak "
441
+ Some text
442
+
443
+ $CTA Click there to start the program $CTA
444
+
445
+ Here is some text" do
446
+ assert_html_output %(
447
+ <p>Some text</p>
448
+ <div class="call-to-action">
449
+ <p>Click there to start the program</p>
450
+ </div>
451
+
452
+ <p>Here is some text</p>)
453
+ end
454
+
455
+ test_given_govspeak "
456
+ Some text
457
+
458
+ $CTAClick anywhere to start the program$CTA
459
+
460
+ Here is some text" do
461
+ assert_html_output %(
462
+ <p>Some text</p>
463
+ <div class="call-to-action">
464
+ <p>Click anywhere to start the program</p>
465
+ </div>
466
+
467
+ <p>Here is some text</p>)
468
+ end
469
+
428
470
  test_given_govspeak "
429
471
  Here is some text\n
430
472
 
@@ -453,7 +495,6 @@ Teston
453
495
  $CTA" do
454
496
  assert_html_output %(
455
497
  <div class="call-to-action">
456
-
457
498
  <p>This is a test:</p>
458
499
 
459
500
  <ol class="steps">
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: 8.3.1
4
+ version: 8.3.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: 2023-10-18 00:00:00.000000000 Z
11
+ date: 2024-01-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionview
@@ -190,14 +190,14 @@ dependencies:
190
190
  requirements:
191
191
  - - '='
192
192
  - !ruby/object:Gem::Version
193
- version: 4.12.0
193
+ version: 4.13.0
194
194
  type: :development
195
195
  prerelease: false
196
196
  version_requirements: !ruby/object:Gem::Requirement
197
197
  requirements:
198
198
  - - '='
199
199
  - !ruby/object:Gem::Version
200
- version: 4.12.0
200
+ version: 4.13.0
201
201
  - !ruby/object:Gem::Dependency
202
202
  name: simplecov
203
203
  requirement: !ruby/object:Gem::Requirement
@@ -235,7 +235,6 @@ files:
235
235
  - lib/govspeak/header_extractor.rb
236
236
  - lib/govspeak/html_sanitizer.rb
237
237
  - lib/govspeak/html_validator.rb
238
- - lib/govspeak/kramdown_overrides.rb
239
238
  - lib/govspeak/link_extractor.rb
240
239
  - lib/govspeak/post_processor.rb
241
240
  - lib/govspeak/presenters/attachment_image_presenter.rb
@@ -327,7 +326,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
327
326
  - !ruby/object:Gem::Version
328
327
  version: '0'
329
328
  requirements: []
330
- rubygems_version: 3.4.21
329
+ rubygems_version: 3.5.5
331
330
  signing_key:
332
331
  specification_version: 4
333
332
  summary: Markup language for single domain
@@ -1,38 +0,0 @@
1
- module Govspeak
2
- module KramdownOverrides
3
- # This depends on two internal parts of Kramdown.
4
- # 1. Parser registry (kramdown/parser/kramdown.rb#define_parser)
5
- # 2. Kramdown list regexes (kramdown/parser/kramdown/list.rb)
6
- # Updating the Kramdown gem therefore also means updating this file to to
7
- # match Kramdown's internals.
8
-
9
- def self.with_kramdown_ordered_lists_disabled
10
- original_list_start = list_start
11
- redefine_kramdown_const(:LIST_START, list_start_ul)
12
- list_parser = kramdown_parsers.delete(:list)
13
- Kramdown::Parser::Kramdown.define_parser(:list, list_start_ul)
14
-
15
- yield
16
- ensure
17
- redefine_kramdown_const(:LIST_START, original_list_start)
18
- kramdown_parsers[:list] = list_parser
19
- end
20
-
21
- def self.list_start
22
- Kramdown::Parser::Kramdown::LIST_START
23
- end
24
-
25
- def self.list_start_ul
26
- Kramdown::Parser::Kramdown::LIST_START_UL
27
- end
28
-
29
- def self.kramdown_parsers
30
- Kramdown::Parser::Kramdown.class_variable_get("@@parsers")
31
- end
32
-
33
- def self.redefine_kramdown_const(const, value)
34
- Kramdown::Parser::Kramdown.send(:remove_const, const)
35
- Kramdown::Parser::Kramdown.send(:const_set, const, value)
36
- end
37
- end
38
- end