Commit 52c3179be94e857ecb0de2cfa8ecbd484a36d213

Authored by Marin Jankovski
1 parent f4865881

Do not replace links inside code blocks, less code for the same amount of work.

app/helpers/gitlab_markdown_helper.rb
... ... @@ -59,90 +59,59 @@ module GitlabMarkdownHelper
59 59 end
60 60 end
61 61  
62   - # text - whole text from a markdown file
63   - # project_path_with_namespace - namespace/projectname, eg. gitlabhq/gitlabhq
64   - # ref - name of the branch or reference, eg. stable
65   - # requested_path - path of request, eg. doc/api/README.md, used in special case when path is pointing to the .md file were the original request is coming from
66   - def create_relative_links(text, project, ref, requested_path)
67   - @path_to_satellite = project.satellite.path
68   - project_path_with_namespace = project.path_with_namespace
  62 + def create_relative_links(text)
69 63 paths = extract_paths(text)
70   - paths.each do |file_path|
71   - original_file_path = extract(file_path)
72   - new_path = rebuild_path(project_path_with_namespace, original_file_path, requested_path, ref)
73   - if reference_path?(file_path)
74   - # Replacing old string with a new one that contains updated path
75   - # eg. [some document]: document.md will be replaced with [some document] /namespace/project/master/blob/document.md
76   - text.gsub!(file_path, file_path.gsub(original_file_path, "/#{new_path}"))
77   - else
78   - # Replacing old string with a new one with brackets ]() to prevent replacing occurence of a word
79   - # e.g. If we have a markdown like [test](test) this will replace ](test) and not the word test
80   - text.gsub!("](#{file_path})", "](/#{new_path})")
81   - end
82   - end
83   - text
84   - end
85 64  
86   - def extract_paths(markdown_text)
87   - all_markdown_paths = pick_out_paths(markdown_text)
88   - paths = remove_empty(all_markdown_paths)
89   - select_relative(paths)
90   - end
  65 + paths.uniq.each do |file_path|
  66 + new_path = rebuild_path(file_path)
  67 + # Finds quoted path so we don't replace other mentions of the string
  68 + # eg. "doc/api" will be replaced and "/home/doc/api/text" won't
  69 + text.gsub!("\"#{file_path}\"", "\"/#{new_path}\"")
  70 + end
91 71  
92   - # Split the markdown text to each line and find all paths, this will match anything with - ]("some_text") and [some text]: file.md
93   - def pick_out_paths(markdown_text)
94   - inline_paths = markdown_text.split("\n").map { |text| text.scan(/\]\(([^(]+)\)/) }
95   - reference_paths = markdown_text.split("\n").map { |text| text.scan(/\[.*\]:.*/) }
96   - inline_paths + reference_paths
  72 + text
97 73 end
98 74  
99   - # Removes any empty result produced by not matching the regexp
100   - def remove_empty(paths)
101   - paths.reject{|l| l.empty? }.flatten
  75 + def extract_paths(text)
  76 + links = substitute_links(text)
  77 + image_links = substitute_image_links(text)
  78 + links + image_links
102 79 end
103 80  
104   - # If a path is a reference style link we need to omit ]:
105   - def extract(path)
106   - path.split("]: ").last
  81 + def substitute_links(text)
  82 + links = text.scan(/<a href=\"([^"]*)\">/)
  83 + relative_links = links.flatten.reject{ |link| link_to_ignore? link }
  84 + relative_links
107 85 end
108 86  
109   - # Reject any path that contains ignored protocol
110   - # eg. reject "https://gitlab.org} but accept "doc/api/README.md"
111   - def select_relative(paths)
112   - paths.reject{|path| ignored_protocols.map{|protocol| path.include?(protocol)}.any?}
  87 + def substitute_image_links(text)
  88 + links = text.scan(/<img src=\"([^"]*)\"/)
  89 + relative_links = links.flatten.reject{ |link| link_to_ignore? link }
  90 + relative_links
113 91 end
114 92  
115   - # Check whether a path is a reference-style link
116   - def reference_path?(path)
117   - path.include?("]: ")
  93 + def link_to_ignore?(link)
  94 + ignored_protocols.map{ |protocol| link.include?(protocol) }.any?
118 95 end
119 96  
120 97 def ignored_protocols
121 98 ["http://","https://", "ftp://", "mailto:"]
122 99 end
123 100  
124   - def rebuild_path(path_with_namespace, path, requested_path, ref)
  101 + def rebuild_path(path)
125 102 path.gsub!(/(#.*)/, "")
126 103 id = $1 || ""
127   - file_path = relative_file_path(path, requested_path)
  104 + file_path = relative_file_path(path)
128 105 [
129   - path_with_namespace,
130   - path_with_ref(file_path, ref),
  106 + Gitlab.config.gitlab.relative_url_root,
  107 + @project.path_with_namespace,
  108 + path_with_ref(file_path),
131 109 file_path
132   - ].compact.join("/").gsub(/\/*$/, '') + id
133   - end
134   -
135   - # Checks if the path exists in the repo
136   - # eg. checks if doc/README.md exists, if not then link to blob
137   - def path_with_ref(path, ref)
138   - if file_exists?(path)
139   - "#{local_path(path)}/#{correct_ref(ref)}"
140   - else
141   - "blob/#{correct_ref(ref)}"
142   - end
  110 + ].compact.join("/").gsub(/^\/*|\/*$/, '') + id
143 111 end
144 112  
145   - def relative_file_path(path, requested_path)
  113 + def relative_file_path(path)
  114 + requested_path = @path
146 115 nested_path = build_nested_path(path, requested_path)
147 116 return nested_path if file_exists?(nested_path)
148 117 path
... ... @@ -166,6 +135,16 @@ module GitlabMarkdownHelper
166 135 end
167 136 end
168 137  
  138 + # Checks if the path exists in the repo
  139 + # eg. checks if doc/README.md exists, if not then link to blob
  140 + def path_with_ref(path)
  141 + if file_exists?(path)
  142 + "#{local_path(path)}/#{correct_ref}"
  143 + else
  144 + "blob/#{correct_ref}"
  145 + end
  146 + end
  147 +
169 148 def file_exists?(path)
170 149 return false if path.nil?
171 150 return @repository.blob_at(current_sha, path).present? || @repository.tree(current_sha, path).entries.any?
... ... @@ -179,10 +158,6 @@ module GitlabMarkdownHelper
179 158 return "blob"
180 159 end
181 160  
182   - def current_ref
183   - @commit.nil? ? "master" : @commit.id
184   - end
185   -
186 161 def current_sha
187 162 if @commit
188 163 @commit.id
... ... @@ -192,7 +167,7 @@ module GitlabMarkdownHelper
192 167 end
193 168  
194 169 # We will assume that if no ref exists we can point to master
195   - def correct_ref(ref)
196   - ref ? ref : "master"
  170 + def correct_ref
  171 + @ref ? @ref : "master"
197 172 end
198 173 end
... ...
lib/redcarpet/render/gitlab_html.rb
... ... @@ -45,23 +45,8 @@ class Redcarpet::Render::GitlabHTML &lt; Redcarpet::Render::HTML
45 45 end
46 46 end
47 47  
48   - def preprocess(full_document)
49   - if is_wiki?
50   - full_document
51   - elsif @project
52   - h.create_relative_links(full_document, @project, @ref, @request_path)
53   - else
54   - full_document
55   - end
56   - end
57   -
58 48 def postprocess(full_document)
  49 + full_document = h.create_relative_links(full_document)
59 50 h.gfm(full_document)
60 51 end
61   -
62   - def is_wiki?
63   - if @template.instance_variable_get("@project_wiki")
64   - @template.instance_variable_get("@page")
65   - end
66   - end
67 52 end
... ...