diff --git a/app/controllers/articles_controller.rb b/app/controllers/articles_controller.rb index 075a3f79d..30f364274 100644 --- a/app/controllers/articles_controller.rb +++ b/app/controllers/articles_controller.rb @@ -85,7 +85,7 @@ class ArticlesController < ApplicationController authorize Article begin - fixed_body_markdown = MarkdownFixer.fix_for_preview(params[:article_body]) + fixed_body_markdown = MarkdownProcessor::Fixer::FixForPreview.call(params[:article_body]) parsed = FrontMatterParser::Parser.new(:md).call(fixed_body_markdown) parsed_markdown = MarkdownProcessor::Parser.new(parsed.content, source: Article.new, user: current_user) processed_html = parsed_markdown.finalize diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index 1a6372e3e..25f1b8bd2 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -203,7 +203,7 @@ class CommentsController < ApplicationController skip_authorization begin permitted_body_markdown = permitted_attributes(Comment)[:body_markdown] - fixed_body_markdown = MarkdownFixer.fix_for_preview(permitted_body_markdown) + fixed_body_markdown = MarkdownProcessor::Fixer::FixForPreview.call(permitted_body_markdown) parsed_markdown = MarkdownProcessor::Parser.new(fixed_body_markdown, source: Comment.new, user: current_user) processed_html = parsed_markdown.finalize rescue StandardError => e diff --git a/app/labor/markdown_fixer.rb b/app/labor/markdown_fixer.rb deleted file mode 100644 index a1a3cab86..000000000 --- a/app/labor/markdown_fixer.rb +++ /dev/null @@ -1,102 +0,0 @@ -class MarkdownFixer - FRONT_MATTER_DETECTOR = /-{3}.*?-{3}/m.freeze - - class << self - def fix_all(markdown) - methods = %i[ - add_quotes_to_title add_quotes_to_description lowercase_published - modify_hr_tags convert_new_lines split_tags underscores_in_usernames - ] - methods.reduce(markdown) { |acc, elem| public_send(elem, acc) } - end - - def fix_for_preview(markdown) - methods = %i[add_quotes_to_title add_quotes_to_description modify_hr_tags underscores_in_usernames] - methods.reduce(markdown) { |acc, elem| public_send(elem, acc) } - end - - def fix_for_comment(markdown) - methods = %I[modify_hr_tags underscores_in_usernames] - methods.reduce(markdown) { |acc, elem| public_send(elem, acc) } - end - - def add_quotes_to_title(markdown) - add_quotes_to_section(markdown, section: "title") - end - - def add_quotes_to_description(markdown) - add_quotes_to_section(markdown, section: "description") - end - - # This turns --- into ------- after the first two, - # because --- messes with front matter - def modify_hr_tags(markdown) - markdown.gsub(/-{3}.*?-{3}/m) do |front_matter| - front_matter.gsub(/^---/).with_index { |match, i| i > 1 ? "#{match}-----" : match } - end - end - - def lowercase_published(markdown) - markdown.gsub(/-{3}.*?-{3}/m) do |front_matter| - front_matter.gsub(/^published: /i, "published: ") - end - end - - def convert_new_lines(markdown) - markdown.gsub("\r\n", "\n") - end - - def split_tags(markdown) - markdown.gsub(/\ntags:.*\n/) do |tags| - tags.split(" #").join(",").delete("#").gsub(":,", ": ") - end - end - - def underscores_in_usernames(markdown) - return markdown unless markdown.match?(USERNAME_WITH_UNDERSCORE_REGEXP) - - traverser = MarkdownTraverser.new(markdown) - traverser.each do |line| - next if traverser.in_codeblock? - - escape_underscored_username_in_line!(line) - end.join - end - - private - - # Match @_username_ that is not preceded by backtick - USERNAME_WITH_UNDERSCORE_REGEXP = /(?.*?)(\r\n|\n)/m) do |target| - # `content` is the captured group (.*?) - captured_text = Regexp.last_match("content") - # The query below checks if the whole text is wrapped in - # either single or double quotes. - match = captured_text.scan(/(^".*"$|^'.*'$)/) - if match.empty? - # Double quotes that aren't already escaped will get esacped. - # Then the whole text get warped in double quotes. - parsed_text = captured_text.gsub(/(? 1 ? "#{match}-----" : match } + end + + def self.lowercase_published(markdown) + markdown.gsub(/-{3}.*?-{3}/m) do |front_matter| + front_matter.gsub(/^published: /i, "published: ") + end + end + + def self.convert_new_lines(markdown) + markdown.gsub("\r\n", "\n") + end + + def self.split_tags(markdown) + markdown.gsub(/\ntags:.*\n/) do |tags| + tags.split(" #").join(",").delete("#").gsub(":,", ": ") + end + end + + def self.underscores_in_usernames(markdown) + return markdown unless markdown.match?(USERNAME_WITH_UNDERSCORE_REGEXP) + + traverser = MarkdownTraverser.new(markdown) + traverser.each do |line| + next if traverser.in_codeblock? + + escape_underscored_username_in_line!(line) + end.join + end + + # Match @_username_ that is not preceded by backtick + USERNAME_WITH_UNDERSCORE_REGEXP = /(?.*?)(\r\n|\n)/m) do |target| + # `content` is the captured group (.*?) + captured_text = Regexp.last_match("content") + # The query below checks if the whole text is wrapped in + # either single or double quotes. + match = captured_text.scan(/(^".*"$|^'.*'$)/) + if match.empty? + # Double quotes that aren't already escaped will get esacped. + # Then the whole text get warped in double quotes. + parsed_text = captured_text.gsub(/(?