require "active_support" require "active_support/core_ext/hash" require "active_support/core_ext/array" require "erb" require "govuk_publishing_components" require "htmlentities" require "kramdown" require "kramdown/parser/govuk" require "nokogiri" require "rinku" require "sanitize" 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 "govspeak/link_extractor" require "govspeak/template_renderer" require "govspeak/presenters/attachment_presenter" require "govspeak/presenters/contact_presenter" require "govspeak/presenters/h_card_presenter" require "govspeak/presenters/image_presenter" require "govspeak/presenters/attachment_image_presenter" module Govspeak def self.root File.expand_path("..", File.dirname(__FILE__)) end class Document Parser = Kramdown::Parser::Govuk PARSER_CLASS_NAME = Parser.name.split("::").last UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.freeze NEW_PARAGRAPH_LOOKBEHIND = %q{(?<=\A|\n\n|\r\n\r\n)}.freeze @extensions = [] attr_accessor :images attr_reader :attachments, :contacts, :links, :locale def self.to_html(source, options = {}) new(source, options).to_html end class << self attr_reader :extensions end def initialize(source, options = {}) options = options.dup.deep_symbolize_keys @source = source ? source.dup : "" @images = options.delete(:images) || [] @allowed_elements = options.delete(:allowed_elements) || [] @allowed_image_hosts = options.delete(:allowed_image_hosts) || [] @attachments = Array.wrap(options.delete(:attachments)) @links = Array.wrap(options.delete(:links)) @contacts = Array.wrap(options.delete(:contacts)) @locale = options.fetch(:locale, "en") @options = { input: PARSER_CLASS_NAME, sanitize: true, syntax_highlighter: nil }.merge(options) @options[:entity_output] = :symbolic @footnote_definition_html = nil @acronyms = [] end def to_html @to_html ||= begin html = if @options[:sanitize] HtmlSanitizer.new(kramdown_doc.to_html, allowed_image_hosts: @allowed_image_hosts) .sanitize(allowed_elements: @allowed_elements) else kramdown_doc.to_html end unless @footnote_definition_html.nil? regex = /
).*(?=<\/p>)/] <<~HTML_SNIPPET
#{footnote_definition}↩
(.*)<\/p>$/, "
\\1
") end extension("button", %r{ (?:\r|\n|^) # non-capturing match to make sure start of line and linebreak {button(.*?)} # match opening bracket and capture attributes \s* # any whitespace between opening bracket and link \[ # match start of link markdown ([^\]]+) # capture inside of link markdown \] # match end of link markdown \( # match start of link text markdown ([^)]+) # capture inside of link text markdown \) # match end of link text markdown \s* # any whitespace between opening bracket and link {/button} # match ending bracket (?:\r|\n|$) # non-capturing match to make sure end of line and linebreak }x) do |attributes, text, href| button_classes = "govuk-button" /cross-domain-tracking:(?\n#{body.sub("\n", '').gsub("\n", '
')}\n
This section applies to #{v}