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