Commit 5b23a7bbb9cc47cda3111a5213b3433303c3e143
1 parent
5277ac1b
Exists in
master
and in
4 other branches
Cover a special case.
Showing
2 changed files
with
35 additions
and
11 deletions
Show diff stats
app/helpers/gitlab_markdown_helper.rb
@@ -60,16 +60,17 @@ module GitlabMarkdownHelper | @@ -60,16 +60,17 @@ module GitlabMarkdownHelper | ||
60 | end | 60 | end |
61 | 61 | ||
62 | # text - whole text from a markdown file | 62 | # text - whole text from a markdown file |
63 | - # project_path_with_namespace - namespace/projectname | ||
64 | - # ref - name of the branch or reference | 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 | ||
65 | # wiki - whether the markdown is from wiki or not | 66 | # wiki - whether the markdown is from wiki or not |
66 | - def create_relative_links(text, project_path_with_namespace, ref, wiki = false) | 67 | + def create_relative_links(text, project_path_with_namespace, ref, requested_path, wiki = false) |
67 | paths = extract_paths(text) | 68 | paths = extract_paths(text) |
68 | - paths.each do |path| | ||
69 | - new_path = rebuild_path(project_path_with_namespace, path, ref) | 69 | + paths.each do |file_path| |
70 | + new_path = rebuild_path(project_path_with_namespace, file_path, requested_path, ref) | ||
70 | # Replacing old string with a new one with brackets ]() to prevent replacing occurence of a word | 71 | # Replacing old string with a new one with brackets ]() to prevent replacing occurence of a word |
71 | # e.g. If we have a markdown like [test](test) this will replace ](test) and not the word test | 72 | # e.g. If we have a markdown like [test](test) this will replace ](test) and not the word test |
72 | - text.gsub!("](#{path})", "](/#{new_path})") | 73 | + text.gsub!("](#{file_path})", "](/#{new_path})") |
73 | end | 74 | end |
74 | text | 75 | text |
75 | end | 76 | end |
@@ -100,24 +101,46 @@ module GitlabMarkdownHelper | @@ -100,24 +101,46 @@ module GitlabMarkdownHelper | ||
100 | ["http://","https://", "ftp://", "mailto:"] | 101 | ["http://","https://", "ftp://", "mailto:"] |
101 | end | 102 | end |
102 | 103 | ||
103 | - def rebuild_path(path_with_namespace, string, ref) | 104 | + def rebuild_path(path_with_namespace, path, requested_path, ref) |
105 | + file_path = relative_file_path(path, requested_path) | ||
104 | [ | 106 | [ |
105 | path_with_namespace, | 107 | path_with_namespace, |
106 | - path_with_ref(string, ref), | ||
107 | - string | 108 | + path_with_ref(file_path, ref), |
109 | + file_path | ||
108 | ].compact.join("/") | 110 | ].compact.join("/") |
109 | end | 111 | end |
110 | 112 | ||
111 | # Checks if the path exists in the repo | 113 | # Checks if the path exists in the repo |
112 | # eg. checks if doc/README.md exists, if it doesn't then it is a wiki link | 114 | # eg. checks if doc/README.md exists, if it doesn't then it is a wiki link |
113 | def path_with_ref(path, ref) | 115 | def path_with_ref(path, ref) |
114 | - if File.exists?(Rails.root.join(path)) | 116 | + if file_exists?(path) |
115 | "#{local_path(path)}/#{correct_ref(ref)}" | 117 | "#{local_path(path)}/#{correct_ref(ref)}" |
116 | else | 118 | else |
117 | "wikis" | 119 | "wikis" |
118 | end | 120 | end |
119 | end | 121 | end |
120 | 122 | ||
123 | + def relative_file_path(path, requested_path) | ||
124 | + nested_path = build_nested_path(path, requested_path) | ||
125 | + return nested_path if file_exists?(nested_path) | ||
126 | + path | ||
127 | + end | ||
128 | + | ||
129 | + # Covering a special case, when the link is referencing file in the same directory eg: | ||
130 | + # If we are at doc/api/README.md and the README.md contains relative links like [Users](users.md) | ||
131 | + # this takes the request path(doc/api/README.md), and replaces the README.md with users.md so the path looks like doc/api/users.md | ||
132 | + def build_nested_path(path, request_path) | ||
133 | + return path unless request_path | ||
134 | + base = request_path.split("/") | ||
135 | + base.pop | ||
136 | + (base + [path]).join("/") | ||
137 | + end | ||
138 | + | ||
139 | + def file_exists?(path) | ||
140 | + return false if path.nil? || path.empty? | ||
141 | + File.exists?(Rails.root.join(path)) | ||
142 | + end | ||
143 | + | ||
121 | # Check if the path is pointing to a directory(tree) or a file(blob) | 144 | # Check if the path is pointing to a directory(tree) or a file(blob) |
122 | # eg. doc/api is directory and doc/README.md is file | 145 | # eg. doc/api is directory and doc/README.md is file |
123 | def local_path(path) | 146 | def local_path(path) |
lib/redcarpet/render/gitlab_html.rb
@@ -7,6 +7,7 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML | @@ -7,6 +7,7 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML | ||
7 | @template = template | 7 | @template = template |
8 | @project = @template.instance_variable_get("@project") | 8 | @project = @template.instance_variable_get("@project") |
9 | @ref = @template.instance_variable_get("@ref") | 9 | @ref = @template.instance_variable_get("@ref") |
10 | + @request_path = @template.instance_variable_get("@path") | ||
10 | super options | 11 | super options |
11 | end | 12 | end |
12 | 13 | ||
@@ -34,7 +35,7 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML | @@ -34,7 +35,7 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML | ||
34 | end | 35 | end |
35 | 36 | ||
36 | def preprocess(full_document) | 37 | def preprocess(full_document) |
37 | - h.create_relative_links(full_document, @project.path_with_namespace, @ref, is_wiki?) | 38 | + h.create_relative_links(full_document, @project.path_with_namespace, @ref, @request_path, is_wiki?) |
38 | end | 39 | end |
39 | 40 | ||
40 | def postprocess(full_document) | 41 | def postprocess(full_document) |