govspeak 3.6.2 → 4.0.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 +16 -0
- data/lib/govspeak.rb +82 -6
- data/lib/govspeak/blockquote_extra_quote_remover.rb +19 -0
- data/lib/govspeak/extension/attachment.html.erb +65 -0
- data/lib/govspeak/extension/inline_attachment.html.erb +4 -0
- data/lib/govspeak/post_processor.rb +42 -0
- data/lib/govspeak/version.rb +1 -1
- data/lib/presenters/attachment_presenter.rb +241 -0
- data/lib/presenters/h_card_presenter.rb +69 -0
- data/lib/templates/contact.html.erb +42 -0
- data/test/blockquote_extra_quote_remover_test.rb +91 -0
- data/test/govspeak_contacts_test.rb +112 -0
- data/test/govspeak_test.rb +168 -35
- data/test/presenters/h_card_presenter_test.rb +153 -0
- metadata +66 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6e737eca62f51b5b954bc37b5fc55d2ba680bb8b
|
4
|
+
data.tar.gz: bf6f399b9badf4708ee7f4f9c6ca50a157493ac5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9363e23283391abf19861ce9522b7cf30874aeecf37b7274dd19411a7539f1956ba3043218601fbc694acde33f2c062fc71f8bd1f113ce9884ca2e7938f1784f
|
7
|
+
data.tar.gz: efe6a7cda89d313ef06470fa0a5e71acc40d85b16ebe8ab95928865e4f20295e7663a4fa43a1e428a5edd2943a6949a96cbc9ec7c31bac28c2322f3a5ba5f353
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
## 4.0.0
|
2
|
+
|
3
|
+
* Drop support for Ruby 1.9.3
|
4
|
+
* Update Ruby to 2.3.1
|
5
|
+
* Adds support for the following items for feature parity with [whitehall](https://github.com/alphagov/whitehall):
|
6
|
+
* `{barchart}`
|
7
|
+
* `[embed:attachments:%content_id%]`
|
8
|
+
* `[embed:attachments:inline:%content_id%]`
|
9
|
+
* `[embed:link:%content_id%]`
|
10
|
+
* `[Contact:%content_id%]`
|
11
|
+
* Changes blockquote rendering to match whitehall [#81](https://github.com/alphagov/govspeak/pull/81)
|
12
|
+
|
13
|
+
## 3.7.0
|
14
|
+
|
15
|
+
* Update Addressable version from 2.3.8 to 2.4.0
|
16
|
+
|
1
17
|
## 3.6.2
|
2
18
|
|
3
19
|
* Fix bug with link parsing introduced in Kramdown 1.6.0 with the "inline attribute lists" feature which clashed with our monkey patch [#75](https://github.com/alphagov/govspeak/pull/75)
|
data/lib/govspeak.rb
CHANGED
@@ -4,8 +4,13 @@ require 'govspeak/structured_header_extractor'
|
|
4
4
|
require 'govspeak/html_validator'
|
5
5
|
require 'govspeak/html_sanitizer'
|
6
6
|
require 'govspeak/kramdown_overrides'
|
7
|
+
require 'govspeak/blockquote_extra_quote_remover'
|
8
|
+
require 'govspeak/post_processor'
|
7
9
|
require 'kramdown/parser/kramdown_with_automatic_external_links'
|
8
10
|
require 'htmlentities'
|
11
|
+
require 'presenters/attachment_presenter'
|
12
|
+
require 'presenters/h_card_presenter'
|
13
|
+
require 'erb'
|
9
14
|
|
10
15
|
module Govspeak
|
11
16
|
|
@@ -17,6 +22,7 @@ module Govspeak
|
|
17
22
|
@@extensions = []
|
18
23
|
|
19
24
|
attr_accessor :images
|
25
|
+
attr_reader :attachments, :contacts, :links, :locale
|
20
26
|
|
21
27
|
def self.to_html(source, options = {})
|
22
28
|
new(source, options).to_html
|
@@ -25,22 +31,41 @@ module Govspeak
|
|
25
31
|
def initialize(source, options = {})
|
26
32
|
@source = source ? source.dup : ""
|
27
33
|
@images = options.delete(:images) || []
|
28
|
-
@
|
34
|
+
@attachments = Array(options.delete(:attachments))
|
35
|
+
@links = Array(options.delete(:links))
|
36
|
+
@contacts = Array(options.delete(:contacts))
|
37
|
+
@locale = options.fetch(:locale, "en")
|
38
|
+
@options = {input: PARSER_CLASS_NAME}.merge(options)
|
39
|
+
@options[:entity_output] = :symbolic
|
40
|
+
i18n_load_paths
|
29
41
|
end
|
30
42
|
|
43
|
+
def i18n_load_paths
|
44
|
+
Dir.glob('locales/*.yml') do |f|
|
45
|
+
I18n.load_path << f
|
46
|
+
end
|
47
|
+
end
|
48
|
+
private :i18n_load_paths
|
49
|
+
|
31
50
|
def kramdown_doc
|
32
51
|
@kramdown_doc ||= Kramdown::Document.new(preprocess(@source), @options)
|
33
52
|
end
|
34
53
|
private :kramdown_doc
|
35
54
|
|
36
55
|
def to_html
|
37
|
-
kramdown_doc.to_html
|
56
|
+
@html ||= Govspeak::PostProcessor.process(kramdown_doc.to_html)
|
38
57
|
end
|
39
58
|
|
40
59
|
def to_liquid
|
41
60
|
to_html
|
42
61
|
end
|
43
62
|
|
63
|
+
def t(*args)
|
64
|
+
options = args.last.is_a?(Hash) ? args.last.dup : {}
|
65
|
+
key = args.shift
|
66
|
+
I18n.t(key, options.merge(locale: locale))
|
67
|
+
end
|
68
|
+
|
44
69
|
def to_sanitized_html
|
45
70
|
HtmlSanitizer.new(to_html).sanitize
|
46
71
|
end
|
@@ -66,6 +91,7 @@ module Govspeak
|
|
66
91
|
end
|
67
92
|
|
68
93
|
def preprocess(source)
|
94
|
+
source = Govspeak::BlockquoteExtraQuoteRemover.remove(source)
|
69
95
|
@@extensions.each do |title,regexp,block|
|
70
96
|
source.gsub!(regexp) {
|
71
97
|
instance_exec(*Regexp.last_match.captures, &block)
|
@@ -105,10 +131,6 @@ module Govspeak
|
|
105
131
|
parser.new(body.strip).to_html.sub(/^<p>(.*)<\/p>$/,"<p><strong>\\1</strong></p>")
|
106
132
|
end
|
107
133
|
|
108
|
-
extension('reverse') { |body|
|
109
|
-
body.reverse
|
110
|
-
}
|
111
|
-
|
112
134
|
extension('highlight-answer') { |body|
|
113
135
|
%{\n\n<div class="highlight-answer">
|
114
136
|
#{Govspeak::Document.new(body.strip).to_html}</div>\n}
|
@@ -137,6 +159,22 @@ module Govspeak
|
|
137
159
|
%{\n\n<div role="note" aria-label="Help" class="application-notice help-notice">\n#{Govspeak::Document.new(body.strip).to_html}</div>\n}
|
138
160
|
}
|
139
161
|
|
162
|
+
extension('barchart', /{barchart(.*?)}/) do |captures, body|
|
163
|
+
stacked = '.mc-stacked' if captures.include? 'stacked'
|
164
|
+
compact = '.compact' if captures.include? 'compact'
|
165
|
+
negative = '.mc-negative' if captures.include? 'negative'
|
166
|
+
|
167
|
+
[
|
168
|
+
'{:',
|
169
|
+
'.js-barchart-table',
|
170
|
+
stacked,
|
171
|
+
compact,
|
172
|
+
negative,
|
173
|
+
'.mc-auto-outdent',
|
174
|
+
'}'
|
175
|
+
].join(' ')
|
176
|
+
end
|
177
|
+
|
140
178
|
extension('attached-image', /^!!([0-9]+)/) do |image_number|
|
141
179
|
image = images[image_number.to_i - 1]
|
142
180
|
if image
|
@@ -147,6 +185,22 @@ module Govspeak
|
|
147
185
|
end
|
148
186
|
end
|
149
187
|
|
188
|
+
extension('attachment', /\[embed:attachments:([0-9a-f-]+)\]/) do |content_id, body|
|
189
|
+
attachment = attachments.detect { |a| a.content_id.match(content_id) }
|
190
|
+
next "" unless attachment
|
191
|
+
attachment = AttachmentPresenter.new(attachment)
|
192
|
+
content = File.read('lib/govspeak/extension/attachment.html.erb')
|
193
|
+
ERB.new(content).result(binding)
|
194
|
+
end
|
195
|
+
|
196
|
+
extension('attachment inline', /\[embed:attachments:inline:([0-9a-f-]+)\]/) do |content_id, body|
|
197
|
+
attachment = attachments.detect { |a| a.content_id.match(content_id) }
|
198
|
+
next "" unless attachment
|
199
|
+
attachment = AttachmentPresenter.new(attachment)
|
200
|
+
content = File.read('lib/govspeak/extension/inline_attachment.html.erb')
|
201
|
+
ERB.new(content).result(binding)
|
202
|
+
end
|
203
|
+
|
150
204
|
def render_image(url, alt_text, caption = nil)
|
151
205
|
lines = []
|
152
206
|
lines << '<figure class="image embedded">'
|
@@ -217,5 +271,27 @@ module Govspeak
|
|
217
271
|
end
|
218
272
|
end
|
219
273
|
end
|
274
|
+
|
275
|
+
extension('embed link', /\[embed:link:([0-9a-f-]+)\]/) do |content_id|
|
276
|
+
link = links.detect { |l| l.content_id.match(content_id) }
|
277
|
+
next "" unless link
|
278
|
+
if link.url
|
279
|
+
%Q{<a href="#{encode(link.url)}">#{encode(link.title)}</a>}
|
280
|
+
else
|
281
|
+
encode(link.title)
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
def render_hcard_address(contact)
|
286
|
+
HCardPresenter.from_contact(contact).render
|
287
|
+
end
|
288
|
+
private :render_hcard_address
|
289
|
+
|
290
|
+
extension('Contact', /\[Contact:([0-9a-f-]+)\]/) do |content_id|
|
291
|
+
contact = contacts.detect { |c| c.content_id.match(content_id) }
|
292
|
+
next "" unless contact
|
293
|
+
@renderer ||= ERB.new(File.read('lib/templates/contact.html.erb'))
|
294
|
+
@renderer.result(binding)
|
295
|
+
end
|
220
296
|
end
|
221
297
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Govspeak
|
2
|
+
module BlockquoteExtraQuoteRemover
|
3
|
+
QUOTE = '"\u201C\u201D\u201E\u201F\u2033\u2036'
|
4
|
+
LINE_BREAK = '\r\n?|\n'
|
5
|
+
|
6
|
+
# used to remove quotes from a markdown blockquote, as these will be inserted
|
7
|
+
# as part of the rendering
|
8
|
+
#
|
9
|
+
# for example:
|
10
|
+
# > "test"
|
11
|
+
#
|
12
|
+
# will be formatted to:
|
13
|
+
# > test
|
14
|
+
def self.remove(source)
|
15
|
+
return if source.nil?
|
16
|
+
source.gsub(/^>[ \t]*[#{QUOTE}]*([^ \t\n].+?)[#{QUOTE}]*[ \t]*(#{LINE_BREAK}?)$/, '> \1\2')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
<section class="attachment <%= attachment.section_class %>">
|
2
|
+
<div class="attachment-thumb">
|
3
|
+
<%= attachment.thumbnail_link %>
|
4
|
+
</div>
|
5
|
+
<div class="attachment-details">
|
6
|
+
<h2 class="title"><%= attachment.attachement_details %></h2>
|
7
|
+
<p class="metadata">
|
8
|
+
<% if attachment.references? %>
|
9
|
+
<span class="references">
|
10
|
+
<%= t('attachment.headings.reference') %>: <%= attachment.references %>
|
11
|
+
</span>
|
12
|
+
<% end %>
|
13
|
+
<% if attachment.unnumbered_paper? %>
|
14
|
+
<span class="unnumbered-paper">
|
15
|
+
<% if attachment.unnumbered_command_paper? %>
|
16
|
+
<%= t('attachment.headings.unnumbered_command_paper') %>
|
17
|
+
<% else %>
|
18
|
+
<%= t('attachment.headings.unnumbered_hoc_paper') %>
|
19
|
+
<% end %>
|
20
|
+
</span>
|
21
|
+
<% end %>
|
22
|
+
<% if attachment.previewable? %>
|
23
|
+
<span class="preview">
|
24
|
+
<strong>
|
25
|
+
<%= attachment.link("View online", attachment.preview_url) %>
|
26
|
+
</strong>
|
27
|
+
</span>
|
28
|
+
<span class="download">
|
29
|
+
attachment.download_link
|
30
|
+
</span>
|
31
|
+
<% else %>
|
32
|
+
<%= attachment.attachment_attributes %>
|
33
|
+
<% end %>
|
34
|
+
</p>
|
35
|
+
<% if attachment.order_url.present? %>
|
36
|
+
<p>
|
37
|
+
<%= attachment.link t('attachment.headings.order_a_copy'), attachment.order_url,
|
38
|
+
class: "order_url", title: t('attachment.headings.order_a_copy_full') %>
|
39
|
+
<% if attachment.price %>
|
40
|
+
(<span class="price"><%= attachment.price %></span>)
|
41
|
+
<% end %>
|
42
|
+
</p>
|
43
|
+
<% end %>
|
44
|
+
|
45
|
+
<% if attachment.opendocument? %>
|
46
|
+
<p class="opendocument-help">
|
47
|
+
<%= t('attachment.opendocument.help_html') %>
|
48
|
+
</p>
|
49
|
+
<% end %>
|
50
|
+
|
51
|
+
<% unless attachment.accessible? %>
|
52
|
+
<div data-module="toggle" class="accessibility-warning" id="<%= attachment.help_block_id %>">
|
53
|
+
<h2><%= t('attachment.accessibility.heading') %>
|
54
|
+
<a class="toggler" href="#<%= attachment.help_block_toggle_id %>" data-controls="<%= attachment.help_block_toggle_id %>" data-expanded="false"><%= t('attachment.accessibility.request_a_different_format') %></a>
|
55
|
+
</h2>
|
56
|
+
<p id="<%= attachment.help_block_toggle_id %>" class="js-hidden">
|
57
|
+
<%= t('attachment.accessibility.full_help_html',
|
58
|
+
email: attachment.alternative_format_order_link,
|
59
|
+
title: attachment.title,
|
60
|
+
references: attachment.references) %>
|
61
|
+
</p>
|
62
|
+
</div>
|
63
|
+
<% end %>
|
64
|
+
</div>
|
65
|
+
</section>
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
module Govspeak
|
4
|
+
class PostProcessor
|
5
|
+
attr_reader :input
|
6
|
+
|
7
|
+
@@extensions = []
|
8
|
+
|
9
|
+
def initialize(html)
|
10
|
+
@input = html
|
11
|
+
end
|
12
|
+
|
13
|
+
def nokogiri_document
|
14
|
+
doc = Nokogiri::HTML::Document.new
|
15
|
+
doc.encoding = "UTF-8"
|
16
|
+
doc.fragment(input)
|
17
|
+
end
|
18
|
+
private :nokogiri_document
|
19
|
+
|
20
|
+
def self.process(html)
|
21
|
+
new(html).output
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.extension(title, &block)
|
25
|
+
@@extensions << [title, block]
|
26
|
+
end
|
27
|
+
|
28
|
+
def output
|
29
|
+
document = nokogiri_document
|
30
|
+
@@extensions.each do |_, block|
|
31
|
+
instance_exec(document, &block)
|
32
|
+
end
|
33
|
+
document.to_html
|
34
|
+
end
|
35
|
+
|
36
|
+
extension("add class to last p of blockquote") do |document|
|
37
|
+
document.css("blockquote p:last-child").map do |el|
|
38
|
+
el[:class] = "last-child"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/govspeak/version.rb
CHANGED
@@ -0,0 +1,241 @@
|
|
1
|
+
require "action_view"
|
2
|
+
require "money"
|
3
|
+
|
4
|
+
class AttachmentPresenter
|
5
|
+
attr_reader :attachment
|
6
|
+
include ActionView::Helpers::TagHelper
|
7
|
+
include ActionView::Helpers::NumberHelper
|
8
|
+
include ActionView::Helpers::AssetTagHelper
|
9
|
+
|
10
|
+
def initialize(attachment)
|
11
|
+
@attachment = attachment
|
12
|
+
end
|
13
|
+
|
14
|
+
def id
|
15
|
+
attachment.id
|
16
|
+
end
|
17
|
+
|
18
|
+
def order_url
|
19
|
+
attachment.order_url
|
20
|
+
end
|
21
|
+
|
22
|
+
def opendocument?
|
23
|
+
attachment.opendocument?
|
24
|
+
end
|
25
|
+
|
26
|
+
def url
|
27
|
+
attachment.url
|
28
|
+
end
|
29
|
+
|
30
|
+
def external?
|
31
|
+
attachment.external?
|
32
|
+
end
|
33
|
+
|
34
|
+
def price
|
35
|
+
return unless attachment.price
|
36
|
+
Money.from_amount(attachment.price, 'GBP').format
|
37
|
+
end
|
38
|
+
|
39
|
+
def accessible?
|
40
|
+
attachment.accessible?
|
41
|
+
end
|
42
|
+
|
43
|
+
def thumbnail_link
|
44
|
+
return if hide_thumbnail?
|
45
|
+
return if previewable?
|
46
|
+
link(attachment_thumbnail, url, "aria-hidden=true class=#{attachment_class}")
|
47
|
+
end
|
48
|
+
|
49
|
+
def help_block_toggle_id
|
50
|
+
"attachment-#{attachment.id}-accessibility-request"
|
51
|
+
end
|
52
|
+
|
53
|
+
def section_class
|
54
|
+
attachment.external? ? "hosted-externally" : "embedded"
|
55
|
+
end
|
56
|
+
|
57
|
+
def mail_to(email_address, name, options = {})
|
58
|
+
"<a href='mailto:#{email_address}?Subject=#{options[:subject]}&body=#{options[:body]}'>#{name}</a>"
|
59
|
+
end
|
60
|
+
|
61
|
+
def alternative_format_order_link
|
62
|
+
attachment_info = []
|
63
|
+
attachment_info << " Title: #{attachment.title}"
|
64
|
+
attachment_info << " Original format: #{attachment.file_extension}"
|
65
|
+
attachment_info << " ISBN: #{attachment.isbn}" if attachment.isbn.present?
|
66
|
+
attachment_info << " Unique reference: #{attachment.unique_reference}" if attachment.unique_reference.present?
|
67
|
+
attachment_info << " Command paper number: #{attachment.command_paper_number}" if attachment.command_paper_number.present?
|
68
|
+
if attachment.hoc_paper_number.present?
|
69
|
+
attachment_info << " House of Commons paper number: #{attachment.hoc_paper_number}"
|
70
|
+
attachment_info << " Parliamentary session: #{attachment.parliamentary_session}"
|
71
|
+
end
|
72
|
+
|
73
|
+
options = {
|
74
|
+
subject: "Request for '#{attachment.title}' in an alternative format",
|
75
|
+
body: body_for_mail(attachment_info)
|
76
|
+
}
|
77
|
+
|
78
|
+
mail_to(alternative_format_contact_email, alternative_format_contact_email, options)
|
79
|
+
end
|
80
|
+
|
81
|
+
def body_for_mail(attachment_info)
|
82
|
+
<<-END
|
83
|
+
Details of document required:
|
84
|
+
|
85
|
+
#{attachment_info.join("\n")}
|
86
|
+
|
87
|
+
Please tell us:
|
88
|
+
|
89
|
+
1. What makes this format unsuitable for you?
|
90
|
+
2. What format you would prefer?
|
91
|
+
END
|
92
|
+
end
|
93
|
+
|
94
|
+
def alternative_format_contact_email
|
95
|
+
"govuk-feedback@digital.cabinet-office.gov.uk"
|
96
|
+
end
|
97
|
+
|
98
|
+
def attachment_thumbnail
|
99
|
+
if attachment.pdf?
|
100
|
+
image_tag(attachment.file.thumbnail.url)
|
101
|
+
elsif attachment.html?
|
102
|
+
image_tag('pub-cover-html.png')
|
103
|
+
elsif %w{doc docx odt}.include? attachment.file_extension
|
104
|
+
image_tag('pub-cover-doc.png')
|
105
|
+
elsif %w{xls xlsx ods csv}.include? attachment.file_extension
|
106
|
+
image_tag('pub-cover-spreadsheet.png')
|
107
|
+
else
|
108
|
+
image_tag('pub-cover.png')
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def references
|
113
|
+
references = []
|
114
|
+
references << "ISBN: #{attachment.isbn}" if attachment.isbn.present?
|
115
|
+
references << "Unique reference: #{attachment.unique_reference}" if attachment.unique_reference.present?
|
116
|
+
references << "Command paper number: #{attachment.command_paper_number}" if attachment.command_paper_number.present?
|
117
|
+
references << "HC: #{attachment.hoc_paper_number} #{attachment.parliamentary_session}" if attachment.hoc_paper_number.present?
|
118
|
+
prefix = references.size == 1 ? "and its reference" : "and its references"
|
119
|
+
references.any? ? ", #{prefix} (" + references.join(", ") + ")" : ""
|
120
|
+
end
|
121
|
+
|
122
|
+
def references?
|
123
|
+
!attachment.isbn.to_s.empty? || !attachment.unique_reference.to_s.empty? || !attachment.command_paper_number.to_s.empty? || !attachment.hoc_paper_number.to_s.empty?
|
124
|
+
end
|
125
|
+
|
126
|
+
def attachment_class
|
127
|
+
attachment.external? ? "hosted-externally" : "embedded"
|
128
|
+
end
|
129
|
+
|
130
|
+
def unnumbered_paper?
|
131
|
+
attachment.unnumbered_command_paper? || attachment.unnumbered_hoc_paper?
|
132
|
+
end
|
133
|
+
|
134
|
+
def unnumbered_command_paper?
|
135
|
+
attachment.unnumbered_command_paper?
|
136
|
+
end
|
137
|
+
|
138
|
+
def download_link
|
139
|
+
link(attachment.preview_url, "<strong>Download #{attachment.file_extension.upcase}</strong>", number_to_human_size(attachment.file_size))
|
140
|
+
end
|
141
|
+
|
142
|
+
def attachment_attributes
|
143
|
+
attributes = []
|
144
|
+
if attachment.html?
|
145
|
+
attributes << content_tag(:span, 'HTML', class: 'type')
|
146
|
+
elsif attachment.external?
|
147
|
+
attributes << content_tag(:span, url, class: 'url')
|
148
|
+
else
|
149
|
+
attributes << content_tag(:span, humanized_content_type(attachment.file_extension), class: 'type')
|
150
|
+
attributes << content_tag(:span, number_to_human_size(attachment.file_size), class: 'file-size')
|
151
|
+
attributes << content_tag(:span, pluralize(attachment.number_of_pages, "page") , class: 'page-length') if attachment.number_of_pages.present?
|
152
|
+
end
|
153
|
+
attributes.join(', ').html_safe
|
154
|
+
end
|
155
|
+
|
156
|
+
def preview_url
|
157
|
+
url << '/preview'
|
158
|
+
end
|
159
|
+
|
160
|
+
MS_WORD_DOCUMENT_HUMANIZED_CONTENT_TYPE = "MS Word Document"
|
161
|
+
MS_EXCEL_SPREADSHEET_HUMANIZED_CONTENT_TYPE = "MS Excel Spreadsheet"
|
162
|
+
MS_POWERPOINT_PRESENTATION_HUMANIZED_CONTENT_TYPE = "MS Powerpoint Presentation"
|
163
|
+
|
164
|
+
def file_abbr_tag(abbr, title)
|
165
|
+
content_tag(:abbr, abbr, title: title)
|
166
|
+
end
|
167
|
+
|
168
|
+
def humanized_content_type(file_extension)
|
169
|
+
file_extension_vs_humanized_content_type = {
|
170
|
+
"chm" => file_abbr_tag('CHM', 'Microsoft Compiled HTML Help'),
|
171
|
+
"csv" => file_abbr_tag('CSV', 'Comma-separated Values'),
|
172
|
+
"diff" => file_abbr_tag('DIFF', 'Plain text differences'),
|
173
|
+
"doc" => MS_WORD_DOCUMENT_HUMANIZED_CONTENT_TYPE,
|
174
|
+
"docx" => MS_WORD_DOCUMENT_HUMANIZED_CONTENT_TYPE,
|
175
|
+
"dot" => file_abbr_tag('DOT', 'MS Word Document Template'),
|
176
|
+
"dxf" => file_abbr_tag('DXF', 'AutoCAD Drawing Exchange Format'),
|
177
|
+
"eps" => file_abbr_tag('EPS', 'Encapsulated PostScript'),
|
178
|
+
"gif" => file_abbr_tag('GIF', 'Graphics Interchange Format'),
|
179
|
+
"gml" => file_abbr_tag('GML', 'Geography Markup Language'),
|
180
|
+
"html" => file_abbr_tag('HTML', 'Hypertext Markup Language'),
|
181
|
+
"ics" => file_abbr_tag('ICS', 'iCalendar file'),
|
182
|
+
"jpg" => "JPEG",
|
183
|
+
"odp" => file_abbr_tag('ODP', 'OpenDocument Presentation'),
|
184
|
+
"ods" => file_abbr_tag('ODS', 'OpenDocument Spreadsheet'),
|
185
|
+
"odt" => file_abbr_tag('ODT', 'OpenDocument Text document'),
|
186
|
+
"pdf" => file_abbr_tag('PDF', 'Portable Document Format'),
|
187
|
+
"png" => file_abbr_tag('PNG', 'Portable Network Graphic'),
|
188
|
+
"ppt" => MS_POWERPOINT_PRESENTATION_HUMANIZED_CONTENT_TYPE,
|
189
|
+
"pptx" => MS_POWERPOINT_PRESENTATION_HUMANIZED_CONTENT_TYPE,
|
190
|
+
"ps" => file_abbr_tag('PS', 'PostScript'),
|
191
|
+
"rdf" => file_abbr_tag('RDF', 'Resource Description Framework'),
|
192
|
+
"rtf" => file_abbr_tag('RTF', 'Rich Text Format'),
|
193
|
+
"sch" => file_abbr_tag('SCH', 'XML based Schematic'),
|
194
|
+
"txt" => "Plain text",
|
195
|
+
"wsdl" => file_abbr_tag('WSDL', 'Web Services Description Language'),
|
196
|
+
"xls" => MS_EXCEL_SPREADSHEET_HUMANIZED_CONTENT_TYPE,
|
197
|
+
"xlsm" => file_abbr_tag('XLSM', 'MS Excel Macro-Enabled Workbook'),
|
198
|
+
"xlsx" => MS_EXCEL_SPREADSHEET_HUMANIZED_CONTENT_TYPE,
|
199
|
+
"xlt" => file_abbr_tag('XLT', 'MS Excel Spreadsheet Template'),
|
200
|
+
"xsd" => file_abbr_tag('XSD', 'XML Schema'),
|
201
|
+
"xslt" => file_abbr_tag('XSLT', 'Extensible Stylesheet Language Transformation'),
|
202
|
+
"zip" => file_abbr_tag('ZIP', 'Zip archive'),
|
203
|
+
}
|
204
|
+
file_extension_vs_humanized_content_type.fetch(file_extension.to_s.downcase, '')
|
205
|
+
end
|
206
|
+
|
207
|
+
def previewable?
|
208
|
+
attachment.csv?
|
209
|
+
end
|
210
|
+
|
211
|
+
def title
|
212
|
+
attachment.title
|
213
|
+
end
|
214
|
+
|
215
|
+
def hide_thumbnail?
|
216
|
+
defined?(hide_thumbnail) && hide_thumbnail
|
217
|
+
end
|
218
|
+
|
219
|
+
def attachement_details
|
220
|
+
return if previewable?
|
221
|
+
link(attachment.title, url, title_link_options)
|
222
|
+
end
|
223
|
+
|
224
|
+
def title_link_options
|
225
|
+
title_link_options = ''
|
226
|
+
title_link_options << "rel=external" if attachment.external?
|
227
|
+
title_link_options << "aria-describedby=#{help_block_id}" unless attachment.accessible?
|
228
|
+
end
|
229
|
+
|
230
|
+
def help_block_id
|
231
|
+
"attachment-#{attachment.id}-accessibility-help"
|
232
|
+
end
|
233
|
+
|
234
|
+
def link(body, url, options={})
|
235
|
+
<<-END
|
236
|
+
<a href="#{url} #{options}">
|
237
|
+
#{body}
|
238
|
+
</a>
|
239
|
+
END
|
240
|
+
end
|
241
|
+
end
|