From 7a0dc34cad955fecba8072f5ed3c179ba5a3fd98 Mon Sep 17 00:00:00 2001 From: multiple creatures Date: Sat, 18 May 2019 13:03:36 -0500 Subject: reimplement monsterpit bbcode and markdown extensions on top of new glitch-soc formatting system + bbcode feature parity + new `i:am` footer + set content type from `format` bangtag --- app/lib/formatter.rb | 178 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 175 insertions(+), 3 deletions(-) (limited to 'app/lib/formatter.rb') diff --git a/app/lib/formatter.rb b/app/lib/formatter.rb index cb9ca8336..42911b52a 100644 --- a/app/lib/formatter.rb +++ b/app/lib/formatter.rb @@ -30,6 +30,141 @@ class Formatter include ActionView::Helpers::TextHelper + BBCODE_TAGS = { + :url => { + :html_open => '', :html_close => '', + :description => '', :example => '', + :allow_quick_param => true, :allow_between_as_param => false, + :quick_param_format => /(\S+)/, + :quick_param_format_description => 'The size parameter \'%param%\' is incorrect, a number is expected', + :param_tokens => [{:token => :url}] + }, + :ul => { + :html_open => '', + :description => '', :example => '', + }, + :ol => { + :html_open => '
    ', :html_close => '
', + :description => '', :example => '', + }, + :li => { + :html_open => '
  • ', :html_close => '
  • ', + :description => '', :example => '', + }, + :sub => { + :html_open => '', :html_close => '', + :description => '', :example => '', + }, + :sup => { + :html_open => '', :html_close => '', + :description => '', :example => '', + }, + :h1 => { + :html_open => '

    ', :html_close => '

    ', + :description => '', :example => '', + }, + :h2 => { + :html_open => '

    ', :html_close => '

    ', + :description => '', :example => '', + }, + :h3 => { + :html_open => '

    ', :html_close => '

    ', + :description => '', :example => '', + }, + :h4 => { + :html_open => '

    ', :html_close => '

    ', + :description => '', :example => '', + }, + :h5 => { + :html_open => '
    ', :html_close => '
    ', + :description => '', :example => '', + }, + :h6 => { + :html_open => '
    ', :html_close => '
    ', + :description => '', :example => '', + }, + :abbr => { + :html_open => '', :html_close => '', + :description => '', :example => '', + }, + :hr => { + :html_open => '
    ', :html_close => '', + :description => '', :example => '', + }, + :b => { + :html_open => '', :html_close => '', + :description => '', :example => '', + }, + :i => { + :html_open => '', :html_close => '', + :description => '', :example => '', + }, + :flip => { + :html_open => '', :html_close => '', + :description => '', :example => '', + :allow_quick_param => true, :allow_between_as_param => false, + :quick_param_format => /(h|v)/, + :quick_param_format_description => 'The size parameter \'%param%\' is incorrect, a number is expected', + :param_tokens => [{:token => :direction}] + }, + :size => { + :html_open => '', :html_close => '', + :description => '', :example => '', + :allow_quick_param => true, :allow_between_as_param => false, + :quick_param_format => /([1-6])/, + :quick_param_format_description => 'The size parameter \'%param%\' is incorrect, a number is expected', + :param_tokens => [{:token => :size}] + }, + :quote => { + :html_open => '
    ', :html_close => '
    ', + :description => '', :example => '', + }, + :kbd => { + :html_open => '
    ', :html_close => '
    ', + :description => '', :example => '', + }, + :code => { + :html_open => '
    ', :html_close => '
    ', + :description => '', :example => '', + }, + :u => { + :html_open => '', :html_close => '', + :description => '', :example => '', + }, + :s => { + :html_open => '', :html_close => '', + :description => '', :example => '', + }, + :del => { + :html_open => '', :html_close => '', + :description => '', :example => '', + }, + :left => { + :html_open => '', :html_close => '', + :description => '', :example => '', + }, + :center => { + :html_open => '', :html_close => '', + :description => '', :example => '', + }, + :right => { + :html_open => '', :html_close => '', + :description => '', :example => '', + }, + :lfloat => { + :html_open => '', :html_close => '', + :description => '', :example => '', + }, + :rfloat => { + :html_open => '', :html_close => '', + :description => '', :example => '', + }, + :spoiler => { + :html_open => '', :html_close => '', + :description => '', :example => '', + }, + } + def format(status, **options) if status.reblog? prepend_reblog = status.reblog.account.acct @@ -57,15 +192,26 @@ class Formatter html = raw_content html = "RT @#{prepend_reblog} #{html}" if prepend_reblog - html = format_markdown(html) if status.content_type == 'text/markdown' - html = encode_and_link_urls(html, linkable_accounts, keep_html: %w(text/markdown text/html).include?(status.content_type)) + + case status.content_type + when 'text/markdown' + html = format_markdown(html) + when 'text/x-bbcode' + html = format_bbcode(html) + when 'text/x-bbcode+markdown' + html = format_bbdown(html) + end + + html = encode_and_link_urls(html, linkable_accounts, keep_html: %w(text/markdown text/x-bbcode text/x-bbcode+markdown text/html).include?(status.content_type)) html = encode_custom_emojis(html, status.emojis, options[:autoplay]) if options[:custom_emojify] - unless %w(text/markdown text/html).include?(status.content_type) + unless %w(text/markdown text/x-bbcode text/x-bbcode+markdown text/html).include?(status.content_type) html = simple_format(html, {}, sanitize: false) html = html.delete("\n") end + html = append_footer(html, status.footer) + html.html_safe # rubocop:disable Rails/OutputSafety end @@ -74,6 +220,19 @@ class Formatter html.delete("\r").delete("\n") end + def format_bbcode(html, sanitize = true) + html = bbcode_formatter(html) + html = html.gsub(/
    .*<\/hr>/im, '
    ') + return html unless sanitize + html = reformat(html) + html.delete("\n") + end + + def format_bbdown(html) + html = format_bbcode(html, false) + format_markdown(html) + end + def reformat(html) sanitize(html, Sanitize::Config::MASTODON_STRICT) end @@ -134,6 +293,19 @@ class Formatter private + def append_footer(html, footer) + return html if footer.blank? + "#{html.strip}

    — #{encode(footer)}

    " + end + + def bbcode_formatter(html) + begin + html = html.bbcode_to_html(false, BBCODE_TAGS, :enable, *BBCODE_TAGS.keys) + rescue Exception => e + end + html + end + def markdown_formatter return @markdown_formatter if defined?(@markdown_formatter) -- cgit