* Remove modify_hr_tags method definition this breaks things that call it. * Remove direct uses of modify_hr_tags fixer method Remove from class METHODS lists, remove test cases about this behavior, and remove from methods lists in test cases. * Remove hr tag modification spec Still don't understand what problem this was fixing, but I've removed the test case.
93 lines
3.1 KiB
Ruby
93 lines
3.1 KiB
Ruby
module MarkdownProcessor
|
|
module Fixer
|
|
# Services here in the Fixer module should inherit from this base class.
|
|
# #call is implemented here so other services only need to define a
|
|
# METHODS constant that is an Array of symbols referencing other methods
|
|
# found here.
|
|
#
|
|
# For example
|
|
# METHODS = %i[add_quotes_to_tile add_quotes_to_description]
|
|
class Base
|
|
FRONT_MATTER_DETECTOR = /-{3}.*?-{3}/m
|
|
|
|
def self.call(markdown)
|
|
return unless markdown
|
|
|
|
fix_methods.reduce(markdown) { |acc, elem| public_send(elem, acc) }
|
|
end
|
|
|
|
def self.fix_methods
|
|
self::METHODS
|
|
end
|
|
|
|
def self.add_quotes_to_title(markdown)
|
|
add_quotes_to_section(markdown, section: "title")
|
|
end
|
|
|
|
def self.add_quotes_to_description(markdown)
|
|
add_quotes_to_section(markdown, section: "description")
|
|
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 = MarkdownProcessor::Traverser.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 = /(?<!`)@_\w+_/
|
|
|
|
# Escapes underscored username that is not in code
|
|
def self.escape_underscored_username_in_line!(line)
|
|
line.scan(USERNAME_WITH_UNDERSCORE_REGEXP).each do |to_escape|
|
|
line.sub!(to_escape, to_escape.gsub("_", "\\_"))
|
|
end
|
|
line
|
|
end
|
|
|
|
def self.add_quotes_to_section(markdown, section:)
|
|
# Only add quotes to front matter, or text between triple dashes
|
|
markdown.sub(FRONT_MATTER_DETECTOR) do |front_matter|
|
|
front_matter.gsub(/#{section}: ?(?<content>.*?)(\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 escaped.
|
|
# Then the whole text get warped in double quotes.
|
|
parsed_text = captured_text.gsub(/(?<!\\)"/, "\\\"")
|
|
"#{section}: \"#{parsed_text}\"\n"
|
|
else
|
|
# if the text comes pre-warped in either single or double quotes,
|
|
# no more processing is done
|
|
target
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|