lib/govspeak.rb in govspeak-3.6.2 vs lib/govspeak.rb in govspeak-4.0.0
- old
+ new
@@ -2,12 +2,17 @@
require 'govspeak/header_extractor'
require 'govspeak/structured_header_extractor'
require 'govspeak/html_validator'
require 'govspeak/html_sanitizer'
require 'govspeak/kramdown_overrides'
+require 'govspeak/blockquote_extra_quote_remover'
+require 'govspeak/post_processor'
require 'kramdown/parser/kramdown_with_automatic_external_links'
require 'htmlentities'
+require 'presenters/attachment_presenter'
+require 'presenters/h_card_presenter'
+require 'erb'
module Govspeak
class Document
@@ -15,34 +20,54 @@
PARSER_CLASS_NAME = Parser.name.split("::").last
@@extensions = []
attr_accessor :images
+ attr_reader :attachments, :contacts, :links, :locale
def self.to_html(source, options = {})
new(source, options).to_html
end
def initialize(source, options = {})
@source = source ? source.dup : ""
@images = options.delete(:images) || []
- @options = {input: PARSER_CLASS_NAME, entity_output: :symbolic}.merge(options)
+ @attachments = Array(options.delete(:attachments))
+ @links = Array(options.delete(:links))
+ @contacts = Array(options.delete(:contacts))
+ @locale = options.fetch(:locale, "en")
+ @options = {input: PARSER_CLASS_NAME}.merge(options)
+ @options[:entity_output] = :symbolic
+ i18n_load_paths
end
+ def i18n_load_paths
+ Dir.glob('locales/*.yml') do |f|
+ I18n.load_path << f
+ end
+ end
+ private :i18n_load_paths
+
def kramdown_doc
@kramdown_doc ||= Kramdown::Document.new(preprocess(@source), @options)
end
private :kramdown_doc
def to_html
- kramdown_doc.to_html
+ @html ||= Govspeak::PostProcessor.process(kramdown_doc.to_html)
end
def to_liquid
to_html
end
+ def t(*args)
+ options = args.last.is_a?(Hash) ? args.last.dup : {}
+ key = args.shift
+ I18n.t(key, options.merge(locale: locale))
+ end
+
def to_sanitized_html
HtmlSanitizer.new(to_html).sanitize
end
def to_sanitized_html_without_images
@@ -64,10 +89,11 @@
def structured_headers
Govspeak::StructuredHeaderExtractor.new(self).call
end
def preprocess(source)
+ source = Govspeak::BlockquoteExtraQuoteRemover.remove(source)
@@extensions.each do |title,regexp,block|
source.gsub!(regexp) {
instance_exec(*Regexp.last_match.captures, &block)
}
end
@@ -103,14 +129,10 @@
def insert_strong_inside_p(body, parser=Govspeak::Document)
parser.new(body.strip).to_html.sub(/^<p>(.*)<\/p>$/,"<p><strong>\\1</strong></p>")
end
- extension('reverse') { |body|
- body.reverse
- }
-
extension('highlight-answer') { |body|
%{\n\n<div class="highlight-answer">
#{Govspeak::Document.new(body.strip).to_html}</div>\n}
}
@@ -135,20 +157,52 @@
extension('helpful', surrounded_by("%")) { |body|
%{\n\n<div role="note" aria-label="Help" class="application-notice help-notice">\n#{Govspeak::Document.new(body.strip).to_html}</div>\n}
}
+ extension('barchart', /{barchart(.*?)}/) do |captures, body|
+ stacked = '.mc-stacked' if captures.include? 'stacked'
+ compact = '.compact' if captures.include? 'compact'
+ negative = '.mc-negative' if captures.include? 'negative'
+
+ [
+ '{:',
+ '.js-barchart-table',
+ stacked,
+ compact,
+ negative,
+ '.mc-auto-outdent',
+ '}'
+ ].join(' ')
+ end
+
extension('attached-image', /^!!([0-9]+)/) do |image_number|
image = images[image_number.to_i - 1]
if image
caption = image.caption rescue nil
render_image(image.url, image.alt_text, caption)
else
""
end
end
+ extension('attachment', /\[embed:attachments:([0-9a-f-]+)\]/) do |content_id, body|
+ attachment = attachments.detect { |a| a.content_id.match(content_id) }
+ next "" unless attachment
+ attachment = AttachmentPresenter.new(attachment)
+ content = File.read('lib/govspeak/extension/attachment.html.erb')
+ ERB.new(content).result(binding)
+ end
+
+ extension('attachment inline', /\[embed:attachments:inline:([0-9a-f-]+)\]/) do |content_id, body|
+ attachment = attachments.detect { |a| a.content_id.match(content_id) }
+ next "" unless attachment
+ attachment = AttachmentPresenter.new(attachment)
+ content = File.read('lib/govspeak/extension/inline_attachment.html.erb')
+ ERB.new(content).result(binding)
+ end
+
def render_image(url, alt_text, caption = nil)
lines = []
lines << '<figure class="image embedded">'
lines << %Q{ <div class="img"><img alt="#{encode(alt_text)}" src="#{encode(url)}" /></div>}
lines << %Q{ <figcaption>#{encode(caption.strip)}</figcaption>} if caption && !caption.strip.empty?
@@ -214,8 +268,30 @@
'<li class="primary-item">'
else
match
end
end
+ end
+
+ extension('embed link', /\[embed:link:([0-9a-f-]+)\]/) do |content_id|
+ link = links.detect { |l| l.content_id.match(content_id) }
+ next "" unless link
+ if link.url
+ %Q{<a href="#{encode(link.url)}">#{encode(link.title)}</a>}
+ else
+ encode(link.title)
+ end
+ end
+
+ def render_hcard_address(contact)
+ HCardPresenter.from_contact(contact).render
+ end
+ private :render_hcard_address
+
+ extension('Contact', /\[Contact:([0-9a-f-]+)\]/) do |content_id|
+ contact = contacts.detect { |c| c.content_id.match(content_id) }
+ next "" unless contact
+ @renderer ||= ERB.new(File.read('lib/templates/contact.html.erb'))
+ @renderer.result(binding)
end
end
end