Commit d1d19aec authored by Robert Speicher's avatar Robert Speicher

GFM refactor: Simplify the regex pattern

Makes use of 'extended' patterns to add comments to the groups, and also
reduces the total number of groups to just those that are used.
parent 6ebd360c
module GitlabMarkdownHelper
REFERENCE_PATTERN = %r{
(\W)? # Prefix (1)
( # Reference (2)
@([\w\._]+) | # User name (3)
[#!$](\d+) | # Issue/MR/Snippet ID (4)
[\h]{6,40} # Commit ID (2)
)
(\W)? # Suffix (5)
}x.freeze
def gfm(text, html_options = {})
return text if text.nil?
return text if @project.nil?
......@@ -12,53 +22,21 @@ module GitlabMarkdownHelper
"{gfm-extraction-#{md5}}"
end
# match 1 2 3 4 5 6
text.gsub!(/(\W)?(@([\w\._]+)|[#!$](\d+)|([\h]{6,40}))(\W)?/) do |match|
prefix = $1
reference = $2
user_name = $3
issue_id = $4
merge_request_id = $4
snippet_id = $4
commit_id = $5
suffix = $6
# TODO: add popups with additional information
ref_link = case reference
# team member: @foo
when /^@/
user = @project.users.where(name: user_name).first
member = @project.users_projects.where(user_id: user).first if user
link_to("@#{user_name}", project_team_member_path(@project, member), html_options.merge(class: "gfm gfm-team_member #{html_options[:class]}")) if member
# issue: #123
when /^#/
# avoid HTML entities
unless prefix.try(:end_with?, "&") && suffix.try(:start_with?, ";")
issue = @project.issues.where(id: issue_id).first
link_to("##{issue_id}", project_issue_path(@project, issue), html_options.merge(title: "Issue: #{issue.title}", class: "gfm gfm-issue #{html_options[:class]}")) if issue
end
# merge request: !123
when /^!/
merge_request = @project.merge_requests.where(id: merge_request_id).first
link_to("!#{merge_request_id}", project_merge_request_path(@project, merge_request), html_options.merge(title: "Merge Request: #{merge_request.title}", class: "gfm gfm-merge_request #{html_options[:class]}")) if merge_request
# snippet: $123
when /^\$/
snippet = @project.snippets.where(id: snippet_id).first
link_to("$#{snippet_id}", project_snippet_path(@project, snippet), html_options.merge(title: "Snippet: #{snippet.title}", class: "gfm gfm-snippet #{html_options[:class]}")) if snippet
# commit: 123456...
when /^\h/
commit = @project.commit(commit_id)
link_to(commit_id, project_commit_path(@project, id: commit.id), html_options.merge(title: "Commit: #{commit.author_name} - #{CommitDecorator.new(commit).title}", class: "gfm gfm-commit #{html_options[:class]}")) if commit
end # case
ref_link.nil? ? match : "#{prefix}#{ref_link}#{suffix}"
end # gsub
text.gsub!(REFERENCE_PATTERN) do |match|
vals = {
prefix: $1,
reference: $2,
user_name: $3,
reference_id: $4,
suffix: $5
}
if ref_link = reference_link(vals, html_options)
sprintf('%s%s%s', vals[:prefix], ref_link, vals[:suffix])
else
match
end
end
# Insert pre block extractions
text.gsub!(/\{gfm-extraction-(\h{32})\}/) do
......@@ -93,4 +71,42 @@ module GitlabMarkdownHelper
@__renderer.render(text).html_safe
end
private
def reference_link(vals, html_options)
# TODO: add popups with additional information
case vals[:reference]
# team member: @foo
when /^@/
user = @project.users.where(name: vals[:user_name]).first
member = @project.users_projects.where(user_id: user).first if user
link_to("@#{user.name}", project_team_member_path(@project, member), html_options.merge(class: "gfm gfm-team_member #{html_options[:class]}")) if member
# issue: #123
when /^#/
# avoid HTML entities
unless vals[:prefix].try(:end_with?, "&") && vals[:suffix].try(:start_with?, ";")
issue = @project.issues.where(id: vals[:reference_id]).first
link_to("##{issue.id}", project_issue_path(@project, issue), html_options.merge(title: "Issue: #{issue.title}", class: "gfm gfm-issue #{html_options[:class]}")) if issue
end
# merge request: !123
when /^!/
merge_request = @project.merge_requests.where(id: vals[:reference_id]).first
link_to("!#{merge_request.id}", project_merge_request_path(@project, merge_request), html_options.merge(title: "Merge Request: #{merge_request.title}", class: "gfm gfm-merge_request #{html_options[:class]}")) if merge_request
# snippet: $123
when /^\$/
snippet = @project.snippets.where(id: vals[:reference_id]).first
link_to("$#{snippet.id}", project_snippet_path(@project, snippet), html_options.merge(title: "Snippet: #{snippet.title}", class: "gfm gfm-snippet #{html_options[:class]}")) if snippet
# commit: 123456...
when /^\h/
commit = @project.commit(vals[:reference])
link_to(vals[:reference], project_commit_path(@project, id: commit.id), html_options.merge(title: "Commit: #{commit.author_name} - #{CommitDecorator.new(commit).title}", class: "gfm gfm-commit #{html_options[:class]}")) if commit
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment