From 94aef563b9abbc449028f44c4aac84ef2e072d89 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Sun, 12 May 2019 20:20:05 +0200 Subject: Add support for markdown-formatted toots --- app/lib/formatter.rb | 50 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 6 deletions(-) (limited to 'app/lib') diff --git a/app/lib/formatter.rb b/app/lib/formatter.rb index 8a1aad41a..fe5b5b7b7 100644 --- a/app/lib/formatter.rb +++ b/app/lib/formatter.rb @@ -36,14 +36,52 @@ class Formatter html = raw_content html = "RT @#{prepend_reblog} #{html}" if prepend_reblog - html = encode_and_link_urls(html, linkable_accounts) + html = format_markdown(html) if status.content_type == 'text/markdown' + html = encode_and_link_urls(html, linkable_accounts, keep_html: status.content_type == 'text/markdown') html = encode_custom_emojis(html, status.emojis, options[:autoplay]) if options[:custom_emojify] - html = simple_format(html, {}, sanitize: false) + html = simple_format(html, {}, sanitize: false) unless status.content_type == 'text/markdown' html = html.delete("\n") html.html_safe # rubocop:disable Rails/OutputSafety end + def format_markdown(html) + extensions = { + autolink: false, + no_intra_emphasis: true, + fenced_code_blocks: true, + disable_indented_code_blocks: true, + strikethrough: true, + lax_spacing: true, + space_after_headers: true, + superscript: true, + underline: true, + highlight: true, + footnotes: true + } + + renderer = Redcarpet::Render::HTML.new({ + filter_html: false, + no_images: true, + no_styles: true, + safe_links_only: true, + hard_wrap: true, + link_attributes: { target: '_blank', rel: 'nofollow noopener' }, + }) + + markdown = Redcarpet::Markdown.new(renderer, extensions) + + html = reformat(markdown.render(html)) + html = html.gsub("\r\n", "\n").gsub("\r", "\n") + code_safe_strip(html) + end + + def code_safe_strip(html, char="\n") + html = html.split(/(].*?\/code>)/m) + html.each_slice(2) { |part| part[0].delete!(char) } + html.join + end + def reformat(html) sanitize(html, Sanitize::Config::MASTODON_STRICT) end @@ -116,7 +154,7 @@ class Formatter accounts = nil end - rewrite(html.dup, entities) do |entity| + rewrite(html.dup, entities, options[:keep_html]) do |entity| if entity[:url] link_to_url(entity, options) elsif entity[:hashtag] @@ -186,7 +224,7 @@ class Formatter html end - def rewrite(text, entities) + def rewrite(text, entities, keep_html = false) text = text.to_s # Sort by start index @@ -199,12 +237,12 @@ class Formatter last_index = entities.reduce(0) do |index, entity| indices = entity.respond_to?(:indices) ? entity.indices : entity[:indices] - result << encode(text[index...indices.first]) + result << (keep_html ? text[index...indices.first] : encode(text[index...indices.first])) result << yield(entity) indices.last end - result << encode(text[last_index..-1]) + result << (keep_html ? text[last_index..-1] : encode(text[last_index..-1])) result.flatten.join end -- cgit