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 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 12 def gfm(text, html_options = {})
3 13 return text if text.nil?
4 14 return text if @project.nil?
... ... @@ -12,53 +22,21 @@ module GitlabMarkdownHelper
12 22 "{gfm-extraction-#{md5}}"
13 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 41 # Insert pre block extractions
64 42 text.gsub!(/\{gfm-extraction-(\h{32})\}/) do
... ... @@ -93,4 +71,42 @@ module GitlabMarkdownHelper
93 71  
94 72 @__renderer.render(text).html_safe
95 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 112 end
... ...