From fc6baa1b3bb8b997ddb7e2b13c632f36a1964b7c Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Sat, 21 Feb 2026 15:26:36 +0200 Subject: [PATCH] adjust autolink --- lib/markdown_to_html.rb | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/lib/markdown_to_html.rb b/lib/markdown_to_html.rb index 19e372d2..3d29566a 100644 --- a/lib/markdown_to_html.rb +++ b/lib/markdown_to_html.rb @@ -23,18 +23,32 @@ module MarkdownToHtml ActionController::Base.helpers.sanitize(html, tags: ALLOWED_TAGS, attributes: ALLOWED_ATTRIBUTES) end + BRACKETS = { ')' => '(', ']' => '[', '}' => '{' }.freeze + def auto_link_urls(text) - link_parts = text.split(%r{((?:https?://|www\.)[^\s)]+)}) + link_parts = text.split(%r{((?:https?://|www\.)[^\s<>\u00A0"]+)}) link_parts.map.with_index do |part, index| if part.match?(%r{\A(?:https?://|www\.)}) && !(index > 0 && link_parts[index - 1]&.match?(/\]\(\s*\z/)) - trail = part.match(/([.,;:!?]+)\z/)[1] if part.match?(/[.,;:!?]+\z/) + url_part = part.dup + punctuation = [] + + while url_part.sub!(%r{[^\p{Word}/\-=;]\z}, '') + punctuation.push(::Regexp.last_match(0)) + + opening = BRACKETS[punctuation.last] - clean = trail ? part.chomp(trail) : part + next unless opening && url_part.count(opening) > url_part.count(punctuation.last) - url = clean.start_with?('www.') ? "https://#{clean}" : clean + url_part << punctuation.pop - "[#{clean}](#{url})#{trail}" + break + end + + trail = punctuation.reverse.join + url = url_part.start_with?('www.') ? "https://#{url_part}" : url_part + + "[#{url_part}](#{url})#{trail}" else part end @@ -69,6 +83,7 @@ module MarkdownToHtml tag = lambda do |t| desc = TAGS[t[1] || ''] + return t unless desc is_end = context.last == t