govspeak 0.8.4

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in ..gemspec
4
+ gemspec
5
+
6
+ gem 'simplecov'
7
+ gem 'simplecov-rcov'
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'bundler'
4
+
5
+ Bundler::GemHelper.install_tasks
6
+
7
+ task :default => [:test_units]
8
+
9
+ desc "Run basic tests"
10
+ Rake::TestTask.new("test_units") { |t|
11
+ t.libs << "test"
12
+ t.pattern = 'test/*_test.rb'
13
+ t.verbose = true
14
+ t.warning = true
15
+ }
data/lib/govspeak.rb ADDED
@@ -0,0 +1,118 @@
1
+ require 'kramdown'
2
+
3
+ module Govspeak
4
+
5
+ class Document
6
+
7
+ @@extensions = []
8
+
9
+ def self.to_html(source, options = {})
10
+ new(source, options).to_html
11
+ end
12
+
13
+ def initialize(source, options = {})
14
+ source ||= ""
15
+ options[:entity_output] ||= :symbolic
16
+ @doc = Kramdown::Document.new(preprocess(source), options)
17
+ super()
18
+ end
19
+
20
+ def to_html
21
+ @doc.to_html
22
+ end
23
+
24
+ def preprocess(source)
25
+ @@extensions.each do |title,regexp,block|
26
+ source.gsub!(regexp) {|match|
27
+ block.call($1)
28
+ }
29
+ end
30
+ source
31
+ end
32
+
33
+ def self.extension(title, regexp = nil, &block)
34
+ regexp ||= %r${::#{title}}(.*?){:/#{title}}$m
35
+ @@extensions << [title, regexp, block]
36
+ end
37
+
38
+ def self.surrounded_by(open, close=nil)
39
+ open = Regexp::escape(open)
40
+ if close
41
+ close = Regexp::escape(close)
42
+ %r+(?:\r|\n|^)#{open}(.*?)#{close}(\r|\n|$)?+m
43
+ else
44
+ %r+(?:\r|\n|^)#{open}(.*?)#{open}?(\r|\n|$)+m
45
+ end
46
+ end
47
+
48
+ def self.wrap_with_div(class_name, character, parser=Kramdown::Document)
49
+ extension(class_name, surrounded_by(character)) { |body|
50
+ content = parser ? parser.new("#{body.strip}\n").to_html : body.strip
51
+ %{<div class="#{class_name}">\n#{content}</div>\n}
52
+ }
53
+ end
54
+
55
+ extension('reverse') { |body|
56
+ body.reverse
57
+ }
58
+
59
+ extension('external', surrounded_by("x")) { |body|
60
+ Kramdown::Document.new("#{body.strip}{:rel='external'}").to_html
61
+ }
62
+
63
+ extension('informational', surrounded_by("^")) { |body|
64
+ %{\n\n<div class="application-notice info-notice">
65
+ #{Kramdown::Document.new(body.strip).to_html}</div>\n}
66
+ }
67
+
68
+ extension('important', surrounded_by("@")) { |body|
69
+ %{\n\n<h3 class="advisory"><span>#{body.strip}</span></h3>\n}
70
+ }
71
+
72
+ extension('helpful', surrounded_by("%")) { |body|
73
+ %{\n\n<div class="application-notice help-notice">\n<p>#{body.strip}</p>\n</div>\n}
74
+ }
75
+
76
+ extension('map_link', surrounded_by("((", "))")) { |body|
77
+ %{<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>}
78
+ }
79
+
80
+ wrap_with_div('summary', '$!')
81
+ wrap_with_div('form-download', '$D')
82
+ wrap_with_div('contact', '$C')
83
+ wrap_with_div('place', '$P', Govspeak::Document)
84
+ wrap_with_div('information', '$I', Govspeak::Document)
85
+ wrap_with_div('additional-information', '$AI')
86
+ wrap_with_div('example', '$E', Govspeak::Document)
87
+
88
+ extension('address', surrounded_by("$A")) { |body|
89
+ %{<div class="address vcard"><div class="adr org fn"><p>\n#{body.sub("\n", "").gsub("\n", "<br />")}\n</p></div></div>\n}
90
+ }
91
+
92
+ extension("numbered list", /((s\d+\.\s.*(?:\n|$))+)/) do |body|
93
+ steps ||= 0
94
+ body.gsub!(/s(\d+)\.\s(.*)(?:\n|$)/) do |b|
95
+ "<li>#{Kramdown::Document.new($2.strip).to_html}</li>\n"
96
+ end
97
+ %{<ol class="steps">\n#{body}</ol>}
98
+ end
99
+
100
+ def self.devolved_options
101
+ { 'scotland' => 'Scotland',
102
+ 'england' => 'England',
103
+ 'england-wales' => 'England and Wales',
104
+ 'northern-ireland' => 'Northern Ireland',
105
+ 'wales' => 'Wales',
106
+ 'london' => 'London' }
107
+ end
108
+
109
+ devolved_options.each do |k,v|
110
+ extension("devolved-#{k}",/:#{k}:(.*?):#{k}:/m) do |body|
111
+ %{<div class="devolved-content #{k}">
112
+ <p class="devolved-header">This section applies to #{v}</p>
113
+ <div class="devolved-body">#{Kramdown::Document.new(body.strip).to_html}</div>
114
+ </div>\n}
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,171 @@
1
+ require 'simplecov'
2
+ require 'simplecov-rcov'
3
+
4
+ SimpleCov.start
5
+ SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
6
+
7
+ require 'test_helper'
8
+
9
+ class GovspeakTest < Test::Unit::TestCase
10
+
11
+ test "simple smoke-test" do
12
+ rendered = Govspeak::Document.new("*this is markdown*").to_html
13
+ assert_equal "<p><em>this is markdown</em></p>\n", rendered
14
+ end
15
+
16
+ test "simple smoke-test for simplified API" do
17
+ rendered = Govspeak::Document.to_html("*this is markdown*")
18
+ assert_equal "<p><em>this is markdown</em></p>\n", rendered
19
+ end
20
+
21
+ test "simple block extension" do
22
+ rendered = Govspeak::Document.new("this \n{::reverse}\n*is*\n{:/reverse}\n markdown").to_html
23
+ assert_equal "<p>this </p>\n\n<p><em>si</em></p>\n\n<p>markdown</p>\n", rendered
24
+ end
25
+
26
+ test "govspark extensions" do
27
+ markdown_regression_tests = [
28
+ {
29
+ input: "^ I am very informational ^",
30
+ output: %{<div class="application-notice info-notice">
31
+ <p>I am very informational</p>
32
+ </div>}
33
+ }, {
34
+ input: "The following is very informational\n^ I am very informational ^",
35
+ output: %{<p>The following is very informational</p>
36
+
37
+ <div class="application-notice info-notice">
38
+ <p>I am very informational</p>
39
+ </div>}
40
+ }, {
41
+ input: "^ I am very informational",
42
+ output: %{<div class="application-notice info-notice">
43
+ <p>I am very informational</p>
44
+ </div>}
45
+ }, {
46
+ input: "@ I am very important @",
47
+ output: %{<h3 class="advisory"><span>I am very important</span></h3>}
48
+ }, {
49
+ input: "The following is very important
50
+ @ I am very important @",
51
+ output: %{<p>The following is very important</p>
52
+
53
+ <h3 class="advisory"><span>I am very important</span></h3>}
54
+ }, {
55
+ input: "% I am very helpful %",
56
+ output: %{<div class="application-notice help-notice">
57
+ <p>I am very helpful</p>
58
+ </div>}
59
+ }, {
60
+ input: "The following is very helpful\n% I am very helpful %",
61
+ output: %{<p>The following is very helpful</p>
62
+
63
+ <div class="application-notice help-notice">
64
+ <p>I am very helpful</p>
65
+ </div>}
66
+ }, {
67
+ input: "## Hello ##\n\n% I am very helpful %\r\n### Young Workers ###\n\n",
68
+ output: %{<h2 id="hello">Hello</h2>
69
+
70
+ <div class="application-notice help-notice">
71
+ <p>I am very helpful</p>
72
+ </div>
73
+
74
+ <h3 id="young-workers">Young Workers</h3>}
75
+ }, {
76
+ input: "% I am very helpful",
77
+ output: %{<div class="application-notice help-notice">
78
+ <p>I am very helpful</p>
79
+ </div>}
80
+ }, {
81
+ input: "This is a [link](http://www.google.com) isn't it?",
82
+ output: '<p>This is a <a href="http://www.google.com">link</a> isn&rsquo;t it?</p>'
83
+ }, {
84
+ input: "This is a [link with an at sign in it](http://www.google.com/@dg/@this) isn't it?",
85
+ output: '<p>This is a <a href="http://www.google.com/@dg/@this">link with an at sign in it</a> isn&rsquo;t it?</p>'
86
+ }, {
87
+ input: "HTML
88
+
89
+ *[HTML]: Hyper Text Markup Language",
90
+ output: %{<p><abbr title="Hyper Text Markup Language">HTML</abbr></p>}
91
+ }, {
92
+ input: "x[a link](http://rubyforge.org)x",
93
+ output: '<p><a href="http://rubyforge.org" rel="external">a link</a></p>'
94
+ }, {
95
+ input: "$!
96
+ rainbow
97
+ $!",
98
+ output: %{<div class="summary">
99
+ <p>rainbow</p>
100
+ </div>}
101
+ }, {
102
+ input: "$C help, send cake $C",
103
+ output: %{<div class="contact">
104
+ <p>help, send cake</p>
105
+ </div>}
106
+ }, {
107
+ input: "$A
108
+ street
109
+ road
110
+ $A",
111
+ output: %{<div class="address vcard"><div class="adr org fn"><p>
112
+ street<br />road<br />
113
+ </p></div></div>}
114
+ }, {
115
+ input: "$P
116
+ $I
117
+ help
118
+ $I
119
+ $P",
120
+ output: %{<div class="place">\n<div class="information">\n<p>help</p>\n</div>\n</div>}
121
+ }, {
122
+ input: "$D
123
+ can you tell me how to get to...
124
+ $D",
125
+ output: %{<div class="form-download">
126
+ <p>can you tell me how to get to&hellip;</p>
127
+ </div>}
128
+ }, {
129
+ input: "1. rod
130
+ 2. jane
131
+ 3. freddy",
132
+ output: "<ol>\n <li>rod</li>\n <li>jane</li>\n <li>freddy</li>\n</ol>"
133
+ }, {
134
+ input: "
135
+ ((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))
136
+ ",
137
+ 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&amp;hl=en&amp;sll=53.800651,-4.064941&amp;sspn=17.759517,42.055664&amp;vpsrc=0&amp;z=14&amp;output=embed"></iframe><br /><small><a href="http://maps.google.co.uk/maps?q=Winkfield+Rd,+Windsor,+Berkshire+SL4+4AY&amp;hl=en&amp;sll=53.800651,-4.064941&amp;sspn=17.759517,42.055664&amp;vpsrc=0&amp;z=14">View Larger Map</a></small></div>}
138
+ }, {
139
+ input: "s1. zippy
140
+ s2. bungle
141
+ s3. george
142
+ ",
143
+ output: %{<ol class="steps">
144
+ <li><p>zippy</p>\n</li>
145
+ <li><p>bungle</p>\n</li>
146
+ <li><p>george</p>\n</li>
147
+ </ol>}
148
+ }
149
+ ]
150
+
151
+ markdown_regression_tests.each do |t|
152
+ rendered = Govspeak::Document.new(t[:input]).to_html
153
+ assert_equal t[:output].strip, rendered.strip
154
+ end
155
+
156
+ end
157
+
158
+ test "devolved markdown sections" do
159
+ input = ":scotland: I am very devolved \n and very scottish \n:scotland:"
160
+ output = '<div class="devolved-content scotland">
161
+ <p class="devolved-header">This section applies to Scotland</p>
162
+ <div class="devolved-body"><p>I am very devolved
163
+ and very scottish</p>
164
+ </div>
165
+ </div>
166
+ '
167
+
168
+ assert_equal output, Govspeak::Document.new(input).to_html
169
+ end
170
+
171
+ end
@@ -0,0 +1,20 @@
1
+ $:.unshift(File.expand_path("../lib")) unless $:.include?(File.expand_path("../lib"))
2
+
3
+ require 'bundler'
4
+ Bundler.setup :default, :development, :test
5
+
6
+ require 'test/unit'
7
+
8
+ class Test::Unit::TestCase
9
+ class << self
10
+ def test(name, &block)
11
+ clean_name = name.gsub(/\s+/,'_')
12
+ method = "test_#{clean_name.gsub(/\s+/,'_')}".to_sym
13
+ already_defined = instance_method(method) rescue false
14
+ raise "#{method} exists" if already_defined
15
+ define_method(method, &block)
16
+ end
17
+ end
18
+ end
19
+
20
+ require 'govspeak'
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: govspeak
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.8.4
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ben Griffiths
9
+ - James Stewart
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2011-11-01 00:00:00.000000000Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: kramdown
17
+ requirement: &70159122835620 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: 0.13.3
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *70159122835620
26
+ - !ruby/object:Gem::Dependency
27
+ name: rake
28
+ requirement: &70159122835160 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 0.8.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: *70159122835160
37
+ description: ! "A set of extensions to markdown layered on top of the kramdown \nlibrary
38
+ for use in the UK Government Single Domain project"
39
+ email:
40
+ - ben@alphagov.co.uk
41
+ - james.stewart@digital.cabinet-office.gov.uk
42
+ executables: []
43
+ extensions: []
44
+ extra_rdoc_files: []
45
+ files:
46
+ - lib/govspeak.rb
47
+ - Gemfile
48
+ - Rakefile
49
+ - test/govspeak_test.rb
50
+ - test/test_helper.rb
51
+ homepage: http://github.com/alphagov/govspeak
52
+ licenses: []
53
+ post_install_message:
54
+ rdoc_options: []
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ requirements: []
70
+ rubyforge_project:
71
+ rubygems_version: 1.8.10
72
+ signing_key:
73
+ specification_version: 3
74
+ summary: Markup language for single domain
75
+ test_files:
76
+ - test/govspeak_test.rb
77
+ - test/test_helper.rb