govspeak 0.8.9 → 0.8.10
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.
- data/README.md +164 -0
- data/lib/govspeak.rb +42 -11
- data/lib/govspeak/version.rb +3 -0
- data/test/govspeak_test.rb +263 -174
- data/test/govspeak_test_helper.rb +74 -0
- metadata +8 -4
data/README.md
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
Govspeak is our markdown-derived mark-up language.
|
2
|
+
|
3
|
+
# Usage
|
4
|
+
|
5
|
+
Install the gem
|
6
|
+
|
7
|
+
gem install govspeak
|
8
|
+
|
9
|
+
or add it to your Gemfile
|
10
|
+
|
11
|
+
gem "govspeak", "~> 0.8.9"
|
12
|
+
|
13
|
+
then create a new document
|
14
|
+
|
15
|
+
require 'rubygems'
|
16
|
+
require 'govspeak'
|
17
|
+
|
18
|
+
doc = Govspeak::Document.new "^Test^"
|
19
|
+
puts doc.to_html
|
20
|
+
|
21
|
+
# Extensions
|
22
|
+
|
23
|
+
In addition to the [standard Markdown syntax](http://daringfireball.net/projects/markdown/syntax "Markdown syntax"), we have added our own extensions.
|
24
|
+
|
25
|
+
## Callouts
|
26
|
+
|
27
|
+
### Information callouts
|
28
|
+
|
29
|
+
^This is an information callout^
|
30
|
+
|
31
|
+
creates a callout with an info (i) icon.
|
32
|
+
|
33
|
+
<div class="application-notice info-notice">
|
34
|
+
<p>This is an information callout</p>
|
35
|
+
</div>
|
36
|
+
|
37
|
+
### Warning callouts
|
38
|
+
|
39
|
+
%This is a warning callout%
|
40
|
+
|
41
|
+
creates a callout with a warning or alert (!) icon
|
42
|
+
|
43
|
+
<div class="application-notice help-notice">
|
44
|
+
<p>This is a warning callout</p>
|
45
|
+
</div>
|
46
|
+
|
47
|
+
### Example callout
|
48
|
+
|
49
|
+
$E
|
50
|
+
**Example**: Open the pod bay doors
|
51
|
+
$E
|
52
|
+
|
53
|
+
creates an example box
|
54
|
+
|
55
|
+
<div class="example">
|
56
|
+
<p><strong>Example:</strong> Open the pod bay doors</p>
|
57
|
+
</div>
|
58
|
+
|
59
|
+
## Highlights
|
60
|
+
|
61
|
+
### Advisory
|
62
|
+
|
63
|
+
@This is a very important message or warning@
|
64
|
+
|
65
|
+
highlights the enclosed text in yellow
|
66
|
+
|
67
|
+
<h3 class="advisory">
|
68
|
+
<span>This is a very important message or warning</span>
|
69
|
+
</h3>
|
70
|
+
|
71
|
+
### Answer
|
72
|
+
|
73
|
+
{::highlight-answer}
|
74
|
+
The VAT rate is *20%*
|
75
|
+
{:/highlight-answer}
|
76
|
+
|
77
|
+
creates a large pink highlight box with optional preamble text and giant text denoted with `**`
|
78
|
+
|
79
|
+
<div class="highlight-answer">
|
80
|
+
<p>The standard VAT rate is <em>20%</em></p>
|
81
|
+
</div>
|
82
|
+
|
83
|
+
## Points of Contact
|
84
|
+
|
85
|
+
### Contact
|
86
|
+
|
87
|
+
$C
|
88
|
+
**Student Finance England**
|
89
|
+
**Telephone:** 0845 300 50 90
|
90
|
+
**Minicom:** 0845 604 44 34
|
91
|
+
$C
|
92
|
+
|
93
|
+
creates an contact box
|
94
|
+
|
95
|
+
<div class="contact">
|
96
|
+
<p><strong>Student Finance England</strong><br><strong>Telephone:</strong> 0845 300 50 90<br><strong>Minicom:</strong> 0845 604 44 34</p>
|
97
|
+
</div>
|
98
|
+
|
99
|
+
### Address
|
100
|
+
|
101
|
+
$A
|
102
|
+
Hercules House
|
103
|
+
Hercules Road
|
104
|
+
London SE1 7DU
|
105
|
+
$A
|
106
|
+
|
107
|
+
creates an address box
|
108
|
+
|
109
|
+
<div class="address vcard"><div class="adr org fn"><p>
|
110
|
+
Hercules House
|
111
|
+
<br>Hercules Road
|
112
|
+
<br>London SE1 7DU
|
113
|
+
<br></p></div></div>
|
114
|
+
|
115
|
+
## Downloads
|
116
|
+
|
117
|
+
$D
|
118
|
+
[An example form download link](http://example.com/ "Example form")
|
119
|
+
|
120
|
+
Something about this form download
|
121
|
+
$D
|
122
|
+
|
123
|
+
creates a file download box
|
124
|
+
|
125
|
+
<div class="form-download">
|
126
|
+
<p><a href="http://example.com/" title="Example form" rel="external">An example form download link.</a></p>
|
127
|
+
</div>
|
128
|
+
|
129
|
+
## Steps
|
130
|
+
|
131
|
+
Steps can be created similar to an ordered list:
|
132
|
+
|
133
|
+
s1. numbers
|
134
|
+
s2. to the start
|
135
|
+
s3. of your list
|
136
|
+
|
137
|
+
Note that steps need an extra line break after the final step (ie. two full blank lines) or other markdown directly afterwards won't work. If you have a subhead after - add a line break after this.
|
138
|
+
|
139
|
+
## Maps
|
140
|
+
|
141
|
+
Static Maps can be embedded by wrapping the URL in double parenthesis.
|
142
|
+
|
143
|
+
((http://maps.google.co.uk/maps?q=Winkfield+Rd,+Windsor,+Berkshire+SL4+4AY&hl=en&sll=53.800651,-4.064941&sspn=17.759517,42.055664&vpsrc=0&z=14))
|
144
|
+
|
145
|
+
## Abbreviations
|
146
|
+
|
147
|
+
Abbreviations can be defined at the end of the document, and any occurrences elswhere in the document will wrapped in an `<abbr>` tag. They are parsed in the order in which they are defined, so `PCSOs` should be defined before `PCSO`, for example.
|
148
|
+
|
149
|
+
Special rules apply if you’re exporting a vehicle outside the EU.
|
150
|
+
|
151
|
+
*[EU]:European Union
|
152
|
+
|
153
|
+
becomes
|
154
|
+
|
155
|
+
<p>Special rules apply if you’re exporting a vehicle outside the <abbr title="European Union">EU</abbr>.</p>
|
156
|
+
|
157
|
+
## Devolved content
|
158
|
+
|
159
|
+
:england:content goes here:england:
|
160
|
+
:scotland:content goes here:scotland:
|
161
|
+
:london:content goes here:london:
|
162
|
+
:wales:content goes here:wales:
|
163
|
+
:northern-ireland:content goes here:northern-ireland:
|
164
|
+
:england-wales:content goes here:england-wales:
|
data/lib/govspeak.rb
CHANGED
@@ -8,19 +8,26 @@ module Govspeak
|
|
8
8
|
|
9
9
|
@@extensions = []
|
10
10
|
|
11
|
+
attr_accessor :images
|
12
|
+
|
11
13
|
def self.to_html(source, options = {})
|
12
14
|
new(source, options).to_html
|
13
15
|
end
|
14
16
|
|
15
17
|
def initialize(source, options = {})
|
16
|
-
source
|
17
|
-
options
|
18
|
-
@
|
18
|
+
@source = source ? source.dup : ""
|
19
|
+
@options = options.merge(entity_output: :symbolic)
|
20
|
+
@images = []
|
19
21
|
super()
|
20
22
|
end
|
21
23
|
|
24
|
+
def kramdown_doc
|
25
|
+
@kramdown_doc ||= Kramdown::Document.new(preprocess(@source), @options)
|
26
|
+
end
|
27
|
+
private :kramdown_doc
|
28
|
+
|
22
29
|
def to_html
|
23
|
-
|
30
|
+
kramdown_doc.to_html
|
24
31
|
end
|
25
32
|
|
26
33
|
def to_text
|
@@ -28,17 +35,22 @@ module Govspeak
|
|
28
35
|
end
|
29
36
|
|
30
37
|
def headers
|
31
|
-
Govspeak::HeaderExtractor.convert(
|
38
|
+
Govspeak::HeaderExtractor.convert(kramdown_doc).first
|
32
39
|
end
|
33
40
|
|
34
41
|
def preprocess(source)
|
35
42
|
@@extensions.each do |title,regexp,block|
|
36
43
|
source.gsub!(regexp) {|match|
|
37
|
-
|
44
|
+
instance_exec($1, &block)
|
38
45
|
}
|
39
46
|
end
|
40
47
|
source
|
41
48
|
end
|
49
|
+
|
50
|
+
def encode(text)
|
51
|
+
HTMLEntities.new.encode(text)
|
52
|
+
end
|
53
|
+
private :encode
|
42
54
|
|
43
55
|
def self.extension(title, regexp = nil, &block)
|
44
56
|
regexp ||= %r${::#{title}}(.*?){:/#{title}}$m
|
@@ -62,7 +74,7 @@ module Govspeak
|
|
62
74
|
}
|
63
75
|
end
|
64
76
|
|
65
|
-
def
|
77
|
+
def insert_strong_inside_p(body, parser=Kramdown::Document)
|
66
78
|
parser.new(body.strip).to_html.sub(/^<p>(.*)<\/p>$/,"<p><strong>\\1</strong></p>")
|
67
79
|
end
|
68
80
|
|
@@ -95,6 +107,25 @@ module Govspeak
|
|
95
107
|
extension('map_link', surrounded_by("((", "))")) { |body|
|
96
108
|
%{<div class="map"><iframe width="200" height="200" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="#{body.strip}&output=embed"></iframe><br /><small><a href="#{body.strip}">View Larger Map</a></small></div>}
|
97
109
|
}
|
110
|
+
|
111
|
+
extension('attached-image', /^!!([0-9]+)/) do |image_number|
|
112
|
+
image = images[image_number.to_i - 1]
|
113
|
+
if image
|
114
|
+
caption = image.caption rescue nil
|
115
|
+
render_image(image.url, image.alt_text, caption)
|
116
|
+
else
|
117
|
+
""
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def render_image(url, alt_text, caption = nil)
|
122
|
+
lines = []
|
123
|
+
lines << '<figure class="image embedded">'
|
124
|
+
lines << %Q{ <div class="img"><img alt="#{encode(alt_text)}" src="#{encode(url)}" /></div>}
|
125
|
+
lines << %Q{ <figcaption>#{encode(caption.strip)}</figcaption>} if caption && !caption.strip.empty?
|
126
|
+
lines << '</figure>'
|
127
|
+
lines.join "\n"
|
128
|
+
end
|
98
129
|
|
99
130
|
wrap_with_div('summary', '$!')
|
100
131
|
wrap_with_div('form-download', '$D')
|
@@ -125,13 +156,13 @@ module Govspeak
|
|
125
156
|
'london' => 'London' }
|
126
157
|
end
|
127
158
|
|
128
|
-
|
129
|
-
|
159
|
+
devolved_options.each do |k,v|
|
160
|
+
extension("devolved-#{k}",/:#{k}:(.*?):#{k}:/m) do |body|
|
130
161
|
%{<div class="devolved-content #{k}">
|
131
162
|
<p class="devolved-header">This section applies to #{v}</p>
|
132
163
|
<div class="devolved-body">#{Kramdown::Document.new(body.strip).to_html}</div>
|
133
164
|
</div>\n}
|
134
|
-
|
135
|
-
|
165
|
+
end
|
166
|
+
end
|
136
167
|
end
|
137
168
|
end
|
data/test/govspeak_test.rb
CHANGED
@@ -7,9 +7,11 @@ SimpleCov.start
|
|
7
7
|
SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
|
8
8
|
|
9
9
|
require 'test_helper'
|
10
|
+
require 'govspeak_test_helper'
|
10
11
|
|
11
12
|
class GovspeakTest < Test::Unit::TestCase
|
12
|
-
|
13
|
+
include GovspeakTestHelper
|
14
|
+
|
13
15
|
test "simple smoke-test" do
|
14
16
|
rendered = Govspeak::Document.new("*this is markdown*").to_html
|
15
17
|
assert_equal "<p><em>this is markdown</em></p>\n", rendered
|
@@ -69,183 +71,270 @@ Teston
|
|
69
71
|
assert_equal %{<div class="address vcard"><div class="adr org fn"><p>\n123 Test Street<br />Testcase Cliffs<br />Teston<br />0123 456 7890 \n</p></div></div>\n}, doc.to_html
|
70
72
|
end
|
71
73
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
<p>I am very informational</p>
|
92
|
-
</div>}
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
}
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
<p>I am very
|
119
|
-
</div>}
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
<div class="application-notice help-notice">
|
126
|
-
<p>I am very helpful</p>
|
127
|
-
</div>
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
}
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
</
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
74
|
+
test_given_govspeak("^ I am very informational ^") do
|
75
|
+
assert_html_output %{
|
76
|
+
<div class="application-notice info-notice">
|
77
|
+
<p>I am very informational</p>
|
78
|
+
</div>}
|
79
|
+
assert_text_output "I am very informational"
|
80
|
+
end
|
81
|
+
|
82
|
+
test "processing an extension does not modify the provided input" do
|
83
|
+
input = "^ I am very informational"
|
84
|
+
Govspeak::Document.new(input).to_html
|
85
|
+
assert_equal "^ I am very informational", input
|
86
|
+
end
|
87
|
+
|
88
|
+
test_given_govspeak "The following is very informational\n^ I am very informational ^" do
|
89
|
+
assert_html_output %{
|
90
|
+
<p>The following is very informational</p>
|
91
|
+
|
92
|
+
<div class="application-notice info-notice">
|
93
|
+
<p>I am very informational</p>
|
94
|
+
</div>}
|
95
|
+
assert_text_output "The following is very informational I am very informational"
|
96
|
+
end
|
97
|
+
|
98
|
+
test_given_govspeak "^ I am very informational" do
|
99
|
+
assert_html_output %{
|
100
|
+
<div class="application-notice info-notice">
|
101
|
+
<p>I am very informational</p>
|
102
|
+
</div>}
|
103
|
+
assert_text_output "I am very informational"
|
104
|
+
end
|
105
|
+
|
106
|
+
test_given_govspeak "@ I am very important @" do
|
107
|
+
assert_html_output %{
|
108
|
+
<div class="advisory"><p><strong>I am very important</strong></p>
|
109
|
+
</div>}
|
110
|
+
assert_text_output "I am very important"
|
111
|
+
end
|
112
|
+
|
113
|
+
test_given_govspeak "
|
114
|
+
The following is very important
|
115
|
+
@ I am very important @
|
116
|
+
" do
|
117
|
+
assert_html_output %{
|
118
|
+
<p>The following is very important</p>
|
119
|
+
|
120
|
+
<div class="advisory"><p><strong>I am very important</strong></p>
|
121
|
+
</div>}
|
122
|
+
assert_text_output "The following is very important I am very important"
|
123
|
+
end
|
124
|
+
|
125
|
+
test_given_govspeak "% I am very helpful %" do
|
126
|
+
assert_html_output %{
|
127
|
+
<div class="application-notice help-notice">
|
128
|
+
<p>I am very helpful</p>
|
129
|
+
</div>}
|
130
|
+
assert_text_output "I am very helpful"
|
131
|
+
end
|
132
|
+
|
133
|
+
test_given_govspeak "The following is very helpful\n% I am very helpful %" do
|
134
|
+
assert_html_output %{
|
135
|
+
<p>The following is very helpful</p>
|
136
|
+
|
137
|
+
<div class="application-notice help-notice">
|
138
|
+
<p>I am very helpful</p>
|
139
|
+
</div>}
|
140
|
+
assert_text_output "The following is very helpful I am very helpful"
|
141
|
+
end
|
142
|
+
|
143
|
+
test_given_govspeak "## Hello ##\n\n% I am very helpful %\r\n### Young Workers ###\n\n" do
|
144
|
+
assert_html_output %{
|
145
|
+
<h2 id="hello">Hello</h2>
|
146
|
+
|
147
|
+
<div class="application-notice help-notice">
|
148
|
+
<p>I am very helpful</p>
|
149
|
+
</div>
|
150
|
+
|
151
|
+
<h3 id="young-workers">Young Workers</h3>}
|
152
|
+
assert_text_output "Hello I am very helpful Young Workers"
|
153
|
+
end
|
154
|
+
|
155
|
+
test_given_govspeak "% I am very helpful" do
|
156
|
+
assert_html_output %{
|
157
|
+
<div class="application-notice help-notice">
|
158
|
+
<p>I am very helpful</p>
|
159
|
+
</div>}
|
160
|
+
assert_text_output "I am very helpful"
|
161
|
+
end
|
162
|
+
|
163
|
+
test_given_govspeak "This is a [link](http://www.google.com) isn't it?" do
|
164
|
+
assert_html_output '<p>This is a <a href="http://www.google.com">link</a> isn’t it?</p>'
|
165
|
+
assert_text_output "This is a link isn’t it?"
|
166
|
+
end
|
167
|
+
|
168
|
+
test_given_govspeak "This is a [link with an at sign in it](http://www.google.com/@dg/@this) isn't it?" do
|
169
|
+
assert_html_output '<p>This is a <a href="http://www.google.com/@dg/@this">link with an at sign in it</a> isn’t it?</p>'
|
170
|
+
assert_text_output "This is a link with an at sign in it isn’t it?"
|
171
|
+
end
|
172
|
+
|
173
|
+
test_given_govspeak "
|
174
|
+
HTML
|
175
|
+
|
176
|
+
*[HTML]: Hyper Text Markup Language" do
|
177
|
+
assert_html_output %{<p><abbr title="Hyper Text Markup Language">HTML</abbr></p>}
|
178
|
+
assert_text_output "HTML"
|
179
|
+
end
|
180
|
+
|
181
|
+
test_given_govspeak "x[a link](http://rubyforge.org)x" do
|
182
|
+
assert_html_output '<p><a href="http://rubyforge.org" rel="external">a link</a></p>'
|
183
|
+
assert_text_output "a link"
|
184
|
+
end
|
185
|
+
|
186
|
+
test_given_govspeak "
|
187
|
+
$!
|
188
|
+
rainbow
|
189
|
+
$!" do
|
190
|
+
assert_html_output %{
|
191
|
+
<div class="summary">
|
192
|
+
<p>rainbow</p>
|
193
|
+
</div>}
|
194
|
+
assert_text_output "rainbow"
|
195
|
+
end
|
196
|
+
|
197
|
+
test_given_govspeak "$C help, send cake $C" do
|
198
|
+
assert_html_output %{
|
199
|
+
<div class="contact">
|
200
|
+
<p>help, send cake</p>
|
201
|
+
</div>}
|
202
|
+
assert_text_output "help, send cake"
|
203
|
+
end
|
204
|
+
|
205
|
+
test_given_govspeak "
|
206
|
+
$A
|
207
|
+
street
|
208
|
+
road
|
209
|
+
$A" do
|
210
|
+
assert_html_output %{
|
211
|
+
<div class="address vcard"><div class="adr org fn"><p>
|
212
|
+
street<br />road<br />
|
213
|
+
</p></div></div>}
|
214
|
+
assert_text_output "street road"
|
215
|
+
end
|
216
|
+
|
217
|
+
test_given_govspeak "
|
218
|
+
$P
|
219
|
+
$I
|
220
|
+
help
|
221
|
+
$I
|
222
|
+
$P" do
|
223
|
+
assert_html_output %{<div class="place">\n<div class="information">\n<p>help</p>\n</div>\n</div>}
|
224
|
+
assert_text_output "help"
|
225
|
+
end
|
226
|
+
|
227
|
+
test_given_govspeak "
|
228
|
+
$D
|
229
|
+
can you tell me how to get to...
|
230
|
+
$D" do
|
231
|
+
assert_html_output %{
|
232
|
+
<div class="form-download">
|
233
|
+
<p>can you tell me how to get to…</p>
|
234
|
+
</div>}
|
235
|
+
assert_text_output "can you tell me how to get to…"
|
236
|
+
end
|
237
|
+
|
238
|
+
test_given_govspeak "
|
239
|
+
1. rod
|
240
|
+
2. jane
|
241
|
+
3. freddy" do
|
242
|
+
assert_html_output "<ol>\n <li>rod</li>\n <li>jane</li>\n <li>freddy</li>\n</ol>"
|
243
|
+
assert_text_output "rod jane freddy"
|
244
|
+
end
|
245
|
+
|
246
|
+
test_given_govspeak "
|
202
247
|
((http://maps.google.co.uk/maps?q=Winkfield+Rd,+Windsor,+Berkshire+SL4+4AY&hl=en&sll=53.800651,-4.064941&sspn=17.759517,42.055664&vpsrc=0&z=14))
|
203
|
-
"
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
<
|
215
|
-
</
|
216
|
-
|
217
|
-
|
218
|
-
|
248
|
+
" do
|
249
|
+
assert_html_output %{<div class="map"><iframe width="200" height="200" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="http://maps.google.co.uk/maps?q=Winkfield+Rd,+Windsor,+Berkshire+SL4+4AY&hl=en&sll=53.800651,-4.064941&sspn=17.759517,42.055664&vpsrc=0&z=14&output=embed"></iframe><br /><small><a href="http://maps.google.co.uk/maps?q=Winkfield+Rd,+Windsor,+Berkshire+SL4+4AY&hl=en&sll=53.800651,-4.064941&sspn=17.759517,42.055664&vpsrc=0&z=14">View Larger Map</a></small></div>}
|
250
|
+
assert_text_output "View Larger Map"
|
251
|
+
end
|
252
|
+
|
253
|
+
test_given_govspeak "
|
254
|
+
s1. zippy
|
255
|
+
s2. bungle
|
256
|
+
s3. george
|
257
|
+
" do
|
258
|
+
assert_html_output %{
|
259
|
+
<ol class="steps">
|
260
|
+
<li><p>zippy</p>
|
261
|
+
</li>
|
262
|
+
<li><p>bungle</p>
|
263
|
+
</li>
|
264
|
+
<li><p>george</p>
|
265
|
+
</li>
|
266
|
+
</ol>}
|
267
|
+
assert_text_output "zippy bungle george"
|
268
|
+
end
|
269
|
+
|
270
|
+
test_given_govspeak ":scotland: I am very devolved\n and very scottish \n:scotland:" do
|
271
|
+
assert_html_output '
|
272
|
+
<div class="devolved-content scotland">
|
273
|
+
<p class="devolved-header">This section applies to Scotland</p>
|
274
|
+
<div class="devolved-body"><p>I am very devolved
|
275
|
+
and very scottish</p>
|
276
|
+
</div>
|
277
|
+
</div>
|
278
|
+
'
|
279
|
+
end
|
219
280
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
281
|
+
test_given_govspeak "@ Message with [a link](http://foo.bar/)@" do
|
282
|
+
assert_html_output %{
|
283
|
+
<div class="advisory"><p><strong>Message with <a href="http://foo.bar/">a link</a></strong></p>
|
284
|
+
</div>
|
285
|
+
}
|
286
|
+
end
|
287
|
+
|
288
|
+
test "can reference attached images using !!n" do
|
289
|
+
images = [OpenStruct.new(alt_text: 'my alt', url: "http://example.com/image.jpg")]
|
290
|
+
given_govspeak "!!1", images do
|
291
|
+
assert_html_output %Q{
|
292
|
+
<figure class="image embedded">
|
293
|
+
<div class="img"><img alt="my alt" src="http://example.com/image.jpg" /></div>
|
294
|
+
</figure>
|
295
|
+
}
|
296
|
+
end
|
224
297
|
end
|
225
298
|
|
226
|
-
|
299
|
+
test "alt text of referenced images is escaped" do
|
300
|
+
images = [OpenStruct.new(alt_text: %Q{my alt '&"<>}, url: "http://example.com/image.jpg")]
|
301
|
+
given_govspeak "!!1", images do
|
302
|
+
assert_html_output %Q{
|
303
|
+
<figure class="image embedded">
|
304
|
+
<div class="img"><img alt="my alt '&"<>" src="http://example.com/image.jpg" /></div>
|
305
|
+
</figure>
|
306
|
+
}
|
307
|
+
end
|
308
|
+
end
|
227
309
|
|
228
|
-
test "
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
'
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
310
|
+
test "silently ignores an image attachment if the referenced image is missing" do
|
311
|
+
doc = Govspeak::Document.new("!!1")
|
312
|
+
doc.images = []
|
313
|
+
|
314
|
+
assert_equal %Q{\n}, doc.to_html
|
315
|
+
end
|
316
|
+
|
317
|
+
test "adds image caption if given" do
|
318
|
+
images = [OpenStruct.new(alt_text: "my alt", url: "http://example.com/image.jpg", caption: 'My Caption & so on')]
|
319
|
+
given_govspeak "!!1", images do
|
320
|
+
assert_html_output %Q{
|
321
|
+
<figure class="image embedded">
|
322
|
+
<div class="img"><img alt="my alt" src="http://example.com/image.jpg" /></div>
|
323
|
+
<figcaption>My Caption & so on</figcaption>
|
324
|
+
</figure>
|
325
|
+
}
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
test "ignores a blank caption" do
|
330
|
+
images = [OpenStruct.new(alt_text: "my alt", url: "http://example.com/image.jpg", caption: ' ')]
|
331
|
+
given_govspeak "!!1", images do
|
332
|
+
assert_html_output %Q{
|
333
|
+
<figure class="image embedded">
|
334
|
+
<div class="img"><img alt="my alt" src="http://example.com/image.jpg" /></div>
|
335
|
+
</figure>
|
336
|
+
}
|
337
|
+
end
|
338
|
+
end
|
250
339
|
|
251
340
|
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module GovspeakTestHelper
|
2
|
+
|
3
|
+
def self.included(base)
|
4
|
+
base.extend(ClassMethods)
|
5
|
+
end
|
6
|
+
|
7
|
+
class GovspeakAsserter
|
8
|
+
def initialize(testcase, govspeak, images = [])
|
9
|
+
@testcase = testcase
|
10
|
+
@govspeak = remove_indentation(govspeak)
|
11
|
+
@images = images
|
12
|
+
end
|
13
|
+
|
14
|
+
def document
|
15
|
+
Govspeak::Document.new(@govspeak).tap do |doc|
|
16
|
+
doc.images = @images
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def assert_text_output(raw_expected)
|
21
|
+
expected = remove_indentation(raw_expected)
|
22
|
+
actual = document.to_text
|
23
|
+
@testcase.assert expected == actual, describe_error(@govspeak, expected, actual)
|
24
|
+
end
|
25
|
+
|
26
|
+
def assert_html_output(raw_expected)
|
27
|
+
expected = remove_indentation(raw_expected)
|
28
|
+
actual = document.to_html.strip
|
29
|
+
@testcase.assert expected.strip == actual, describe_error(@govspeak, expected.strip, actual)
|
30
|
+
end
|
31
|
+
|
32
|
+
def remove_indentation(raw)
|
33
|
+
lines = raw.split("\n")
|
34
|
+
if lines.first.empty?
|
35
|
+
lines.delete_at(0)
|
36
|
+
nonblanks = lines.reject { |l| l.match(/^ *$/) }
|
37
|
+
indentation = nonblanks.map do |line|
|
38
|
+
line.match(/^ */)[0].size
|
39
|
+
end.min
|
40
|
+
unindented = lines.map do |line|
|
41
|
+
line[indentation..-1]
|
42
|
+
end
|
43
|
+
unindented.join "\n"
|
44
|
+
else
|
45
|
+
raw
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def describe_error(govspeak, expected, actual)
|
50
|
+
"Expected:\n#{govspeak}\n\nto produce:\n#{show_linenumbers(expected)}\n\nbut got:\n#{show_linenumbers(actual)}\n"
|
51
|
+
end
|
52
|
+
|
53
|
+
def show_linenumbers(text)
|
54
|
+
lines = text.split "\n"
|
55
|
+
digits = Math.log10(lines.size + 2).ceil
|
56
|
+
lines.map.with_index do |line, i|
|
57
|
+
"%#{digits}d: %s" % [i+1, line]
|
58
|
+
end.join "\n"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def given_govspeak(govspeak, images=[], &block)
|
63
|
+
asserter = GovspeakAsserter.new(self, govspeak, images)
|
64
|
+
asserter.instance_eval(&block)
|
65
|
+
end
|
66
|
+
|
67
|
+
module ClassMethods
|
68
|
+
def test_given_govspeak(govspeak, &block)
|
69
|
+
test "Given #{govspeak}" do
|
70
|
+
given_govspeak(govspeak, &block)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: govspeak
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.8.
|
5
|
+
version: 0.8.10
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Ben Griffiths
|
@@ -11,7 +11,7 @@ autorequire:
|
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
13
|
|
14
|
-
date: 2012-
|
14
|
+
date: 2012-02-15 00:00:00 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: kramdown
|
@@ -60,10 +60,13 @@ extra_rdoc_files: []
|
|
60
60
|
|
61
61
|
files:
|
62
62
|
- lib/govspeak/header_extractor.rb
|
63
|
+
- lib/govspeak/version.rb
|
63
64
|
- lib/govspeak.rb
|
65
|
+
- README.md
|
64
66
|
- Gemfile
|
65
67
|
- Rakefile
|
66
68
|
- test/govspeak_test.rb
|
69
|
+
- test/govspeak_test_helper.rb
|
67
70
|
- test/test_helper.rb
|
68
71
|
homepage: http://github.com/alphagov/govspeak
|
69
72
|
licenses: []
|
@@ -78,7 +81,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
78
81
|
requirements:
|
79
82
|
- - ">="
|
80
83
|
- !ruby/object:Gem::Version
|
81
|
-
hash:
|
84
|
+
hash: -3286011011041893996
|
82
85
|
segments:
|
83
86
|
- 0
|
84
87
|
version: "0"
|
@@ -87,7 +90,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
87
90
|
requirements:
|
88
91
|
- - ">="
|
89
92
|
- !ruby/object:Gem::Version
|
90
|
-
hash:
|
93
|
+
hash: -3286011011041893996
|
91
94
|
segments:
|
92
95
|
- 0
|
93
96
|
version: "0"
|
@@ -100,4 +103,5 @@ specification_version: 3
|
|
100
103
|
summary: Markup language for single domain
|
101
104
|
test_files:
|
102
105
|
- test/govspeak_test.rb
|
106
|
+
- test/govspeak_test_helper.rb
|
103
107
|
- test/test_helper.rb
|