Commit 52c3179be94e857ecb0de2cfa8ecbd484a36d213
1 parent
f4865881
Exists in
spb-stable
and in
2 other branches
Do not replace links inside code blocks, less code for the same amount of work.
Showing
2 changed files
with
43 additions
and
83 deletions
Show diff stats
app/helpers/gitlab_markdown_helper.rb
@@ -59,90 +59,59 @@ module GitlabMarkdownHelper | @@ -59,90 +59,59 @@ module GitlabMarkdownHelper | ||
59 | end | 59 | end |
60 | end | 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 | paths = extract_paths(text) | 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 | end | 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 | end | 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 | end | 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 | end | 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 | end | 95 | end |
119 | 96 | ||
120 | def ignored_protocols | 97 | def ignored_protocols |
121 | ["http://","https://", "ftp://", "mailto:"] | 98 | ["http://","https://", "ftp://", "mailto:"] |
122 | end | 99 | end |
123 | 100 | ||
124 | - def rebuild_path(path_with_namespace, path, requested_path, ref) | 101 | + def rebuild_path(path) |
125 | path.gsub!(/(#.*)/, "") | 102 | path.gsub!(/(#.*)/, "") |
126 | id = $1 || "" | 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 | file_path | 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 | end | 111 | end |
144 | 112 | ||
145 | - def relative_file_path(path, requested_path) | 113 | + def relative_file_path(path) |
114 | + requested_path = @path | ||
146 | nested_path = build_nested_path(path, requested_path) | 115 | nested_path = build_nested_path(path, requested_path) |
147 | return nested_path if file_exists?(nested_path) | 116 | return nested_path if file_exists?(nested_path) |
148 | path | 117 | path |
@@ -166,6 +135,16 @@ module GitlabMarkdownHelper | @@ -166,6 +135,16 @@ module GitlabMarkdownHelper | ||
166 | end | 135 | end |
167 | end | 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 | def file_exists?(path) | 148 | def file_exists?(path) |
170 | return false if path.nil? | 149 | return false if path.nil? |
171 | return @repository.blob_at(current_sha, path).present? || @repository.tree(current_sha, path).entries.any? | 150 | return @repository.blob_at(current_sha, path).present? || @repository.tree(current_sha, path).entries.any? |
@@ -179,10 +158,6 @@ module GitlabMarkdownHelper | @@ -179,10 +158,6 @@ module GitlabMarkdownHelper | ||
179 | return "blob" | 158 | return "blob" |
180 | end | 159 | end |
181 | 160 | ||
182 | - def current_ref | ||
183 | - @commit.nil? ? "master" : @commit.id | ||
184 | - end | ||
185 | - | ||
186 | def current_sha | 161 | def current_sha |
187 | if @commit | 162 | if @commit |
188 | @commit.id | 163 | @commit.id |
@@ -192,7 +167,7 @@ module GitlabMarkdownHelper | @@ -192,7 +167,7 @@ module GitlabMarkdownHelper | ||
192 | end | 167 | end |
193 | 168 | ||
194 | # We will assume that if no ref exists we can point to master | 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 | end | 172 | end |
198 | end | 173 | end |
lib/redcarpet/render/gitlab_html.rb
@@ -45,23 +45,8 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML | @@ -45,23 +45,8 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML | ||
45 | end | 45 | end |
46 | end | 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 | def postprocess(full_document) | 48 | def postprocess(full_document) |
49 | + full_document = h.create_relative_links(full_document) | ||
59 | h.gfm(full_document) | 50 | h.gfm(full_document) |
60 | end | 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 | end | 52 | end |