Commit d1d19aecdeb73069357885b91dcc0b9f31cde4ba

Authored by Robert Speicher
1 parent 6ebd360c

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.
Showing 1 changed file with 63 additions and 47 deletions   Show diff stats
app/helpers/gitlab_markdown_helper.rb
1 module GitlabMarkdownHelper 1 module GitlabMarkdownHelper
  2 + REFERENCE_PATTERN = %r{
  3 + (\W)? # Prefix (1)
  4 + ( # Reference (2)
  5 + @([\w\._]+) | # User name (3)
  6 + [#!$](\d+) | # Issue/MR/Snippet ID (4)
  7 + [\h]{6,40} # Commit ID (2)
  8 + )
  9 + (\W)? # Suffix (5)
  10 + }x.freeze
  11 +
2 def gfm(text, html_options = {}) 12 def gfm(text, html_options = {})
3 return text if text.nil? 13 return text if text.nil?
4 return text if @project.nil? 14 return text if @project.nil?
@@ -12,53 +22,21 @@ module GitlabMarkdownHelper @@ -12,53 +22,21 @@ module GitlabMarkdownHelper
12 "{gfm-extraction-#{md5}}" 22 "{gfm-extraction-#{md5}}"
13 end 23 end
14 24
15 - # match 1 2 3 4 5 6  
16 - text.gsub!(/(\W)?(@([\w\._]+)|[#!$](\d+)|([\h]{6,40}))(\W)?/) do |match|  
17 - prefix = $1  
18 - reference = $2  
19 - user_name = $3  
20 - issue_id = $4  
21 - merge_request_id = $4  
22 - snippet_id = $4  
23 - commit_id = $5  
24 - suffix = $6  
25 -  
26 - # TODO: add popups with additional information  
27 - ref_link = case reference  
28 -  
29 - # team member: @foo  
30 - when /^@/  
31 - user = @project.users.where(name: user_name).first  
32 - member = @project.users_projects.where(user_id: user).first if user  
33 - link_to("@#{user_name}", project_team_member_path(@project, member), html_options.merge(class: "gfm gfm-team_member #{html_options[:class]}")) if member  
34 -  
35 - # issue: #123  
36 - when /^#/  
37 - # avoid HTML entities  
38 - unless prefix.try(:end_with?, "&") && suffix.try(:start_with?, ";")  
39 - issue = @project.issues.where(id: issue_id).first  
40 - 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  
41 - end  
42 -  
43 - # merge request: !123  
44 - when /^!/  
45 - merge_request = @project.merge_requests.where(id: merge_request_id).first  
46 - 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  
47 -  
48 - # snippet: $123  
49 - when /^\$/  
50 - snippet = @project.snippets.where(id: snippet_id).first  
51 - 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  
52 -  
53 - # commit: 123456...  
54 - when /^\h/  
55 - commit = @project.commit(commit_id)  
56 - 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  
57 -  
58 - end # case  
59 -  
60 - ref_link.nil? ? match : "#{prefix}#{ref_link}#{suffix}"  
61 - end # gsub 25 + text.gsub!(REFERENCE_PATTERN) do |match|
  26 + vals = {
  27 + prefix: $1,
  28 + reference: $2,
  29 + user_name: $3,
  30 + reference_id: $4,
  31 + suffix: $5
  32 + }
  33 +
  34 + if ref_link = reference_link(vals, html_options)
  35 + sprintf('%s%s%s', vals[:prefix], ref_link, vals[:suffix])
  36 + else
  37 + match
  38 + end
  39 + end
62 40
63 # Insert pre block extractions 41 # Insert pre block extractions
64 text.gsub!(/\{gfm-extraction-(\h{32})\}/) do 42 text.gsub!(/\{gfm-extraction-(\h{32})\}/) do
@@ -93,4 +71,42 @@ module GitlabMarkdownHelper @@ -93,4 +71,42 @@ module GitlabMarkdownHelper
93 71
94 @__renderer.render(text).html_safe 72 @__renderer.render(text).html_safe
95 end 73 end
  74 +
  75 + private
  76 +
  77 + def reference_link(vals, html_options)
  78 + # TODO: add popups with additional information
  79 + case vals[:reference]
  80 +
  81 + # team member: @foo
  82 + when /^@/
  83 + user = @project.users.where(name: vals[:user_name]).first
  84 + member = @project.users_projects.where(user_id: user).first if user
  85 + link_to("@#{user.name}", project_team_member_path(@project, member), html_options.merge(class: "gfm gfm-team_member #{html_options[:class]}")) if member
  86 +
  87 + # issue: #123
  88 + when /^#/
  89 + # avoid HTML entities
  90 + unless vals[:prefix].try(:end_with?, "&") && vals[:suffix].try(:start_with?, ";")
  91 + issue = @project.issues.where(id: vals[:reference_id]).first
  92 + 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
  93 + end
  94 +
  95 + # merge request: !123
  96 + when /^!/
  97 + merge_request = @project.merge_requests.where(id: vals[:reference_id]).first
  98 + 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
  99 +
  100 + # snippet: $123
  101 + when /^\$/
  102 + snippet = @project.snippets.where(id: vals[:reference_id]).first
  103 + 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
  104 +
  105 + # commit: 123456...
  106 + when /^\h/
  107 + commit = @project.commit(vals[:reference])
  108 + 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
  109 +
  110 + end
  111 + end
96 end 112 end