From 44ef5a61731d780365993e08161a3f1200c484d9 Mon Sep 17 00:00:00 2001
From: KMY
Date: Sat, 4 Mar 2023 15:25:24 +0900
Subject: [PATCH] Add markdown support
---
app/javascript/styles/application.scss | 1 +
app/javascript/styles/mastodon/rich_text.scss | 97 +++++++++++++++++++
app/lib/text_formatter.rb | 50 +++++++++-
3 files changed, 147 insertions(+), 1 deletion(-)
create mode 100644 app/javascript/styles/mastodon/rich_text.scss
diff --git a/app/javascript/styles/application.scss b/app/javascript/styles/application.scss
index 81a040108e..1b2969c234 100644
--- a/app/javascript/styles/application.scss
+++ b/app/javascript/styles/application.scss
@@ -23,3 +23,4 @@
@import 'mastodon/dashboard';
@import 'mastodon/rtl';
@import 'mastodon/accessibility';
+@import 'mastodon/rich_text';
diff --git a/app/javascript/styles/mastodon/rich_text.scss b/app/javascript/styles/mastodon/rich_text.scss
new file mode 100644
index 0000000000..a8258ee8cb
--- /dev/null
+++ b/app/javascript/styles/mastodon/rich_text.scss
@@ -0,0 +1,97 @@
+.account__header__bio,
+.status__content__text,
+.e-content,
+.reply-indicator__content {
+ pre,
+ blockquote {
+ margin-bottom: 20px;
+ white-space: pre-wrap;
+ unicode-bidi: plaintext;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+
+ code, pre {
+ border: 1px solid $ui-primary-color;
+ font-family: monospace;
+ }
+
+ code {
+ margin: 0 4px;
+ }
+
+ pre {
+ padding: 4px 8px;
+
+ span.ellipsis::after {
+ content: "";
+ }
+
+ span.invisible {
+ display: inline;
+ font-size: inherit;
+ line-height: inherit;
+ width: inherit;
+ height: inherit;
+ position: static;
+ }
+ }
+
+ blockquote {
+ padding-left: 10px;
+ border-left: 3px solid $darker-text-color;
+ color: $darker-text-color;
+ white-space: normal;
+
+ p:last-child {
+ margin-bottom: 0;
+ }
+ }
+
+ & > ul,
+ & > ol {
+ margin-bottom: 20px;
+ }
+
+ b,
+ strong {
+ font-weight: 700;
+ }
+
+ em,
+ i {
+ font-style: italic;
+ }
+
+ ul,
+ ol {
+ margin-left: 2em;
+
+ p {
+ margin: 0;
+ }
+ }
+
+ ul {
+ list-style-type: disc;
+ }
+
+ ol {
+ list-style-type: decimal;
+ }
+
+ mark {
+ background-color: $ui-highlight-color;
+ color: $ui-secondary-color;
+ padding: 0 2px;
+ }
+}
+
+.reply-indicator__content {
+ blockquote {
+ border-left-color: $inverted-text-color;
+ color: $inverted-text-color;
+ }
+}
diff --git a/app/lib/text_formatter.rb b/app/lib/text_formatter.rb
index 48e2fc2338..8513b1f4ca 100644
--- a/app/lib/text_formatter.rb
+++ b/app/lib/text_formatter.rb
@@ -43,7 +43,9 @@ class TextFormatter
end
end
- html = simple_format(html, {}, sanitize: false).delete("\n") if multiline?
+ html = markdownify(html)
+
+ # html = simple_format(html, {}, sanitize: false).delete("\n") if multiline?
html.html_safe # rubocop:disable Rails/OutputSafety
end
@@ -155,4 +157,50 @@ class TextFormatter
def preloaded_accounts?
preloaded_accounts.present?
end
+
+ def markdownify(html)
+ # not need filter_html because escape is already done
+ @htmlobj ||= MyMarkdownHTML.new(
+ filter_html: false,
+ hard_wrap: false,
+ no_styles: true
+ )
+ @markdown ||= Redcarpet::Markdown.new(@htmlobj,
+ autolink: false,
+ tables: false,
+ underline: true,
+ disable_indented_code_blocks: false,
+ fenced_code_blocks: true,
+ highlight: false
+ )
+ @markdown.render(html)
+ end
+
+ class MyMarkdownHTML < Redcarpet::Render::HTML
+ def link(link, title, content)
+ nil
+ end
+
+ def linebreak
+ nil
+ end
+
+ def block_code(code, language)
+ "#{code}
"
+ end
+
+ def codespan(code)
+ "#{escape_tags(code)}
"
+ end
+
+ def header(text, header_level)
+ "
#{text}
" + end + + private + + def escape_tags(code) + code.gsub(/, '<').gsub(/>/, '>') + end + end end