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 | 60 | end |
| 61 | 61 | |
| 62 | 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 | 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 | 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 | 71 | # Replacing old string with a new one with brackets ]() to prevent replacing occurence of a word |
| 71 | 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 | 74 | end |
| 74 | 75 | text |
| 75 | 76 | end |
| ... | ... | @@ -100,24 +101,46 @@ module GitlabMarkdownHelper |
| 100 | 101 | ["http://","https://", "ftp://", "mailto:"] |
| 101 | 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 | 107 | path_with_namespace, |
| 106 | - path_with_ref(string, ref), | |
| 107 | - string | |
| 108 | + path_with_ref(file_path, ref), | |
| 109 | + file_path | |
| 108 | 110 | ].compact.join("/") |
| 109 | 111 | end |
| 110 | 112 | |
| 111 | 113 | # Checks if the path exists in the repo |
| 112 | 114 | # eg. checks if doc/README.md exists, if it doesn't then it is a wiki link |
| 113 | 115 | def path_with_ref(path, ref) |
| 114 | - if File.exists?(Rails.root.join(path)) | |
| 116 | + if file_exists?(path) | |
| 115 | 117 | "#{local_path(path)}/#{correct_ref(ref)}" |
| 116 | 118 | else |
| 117 | 119 | "wikis" |
| 118 | 120 | end |
| 119 | 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 | 144 | # Check if the path is pointing to a directory(tree) or a file(blob) |
| 122 | 145 | # eg. doc/api is directory and doc/README.md is file |
| 123 | 146 | def local_path(path) | ... | ... |
lib/redcarpet/render/gitlab_html.rb
| ... | ... | @@ -7,6 +7,7 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML |
| 7 | 7 | @template = template |
| 8 | 8 | @project = @template.instance_variable_get("@project") |
| 9 | 9 | @ref = @template.instance_variable_get("@ref") |
| 10 | + @request_path = @template.instance_variable_get("@path") | |
| 10 | 11 | super options |
| 11 | 12 | end |
| 12 | 13 | |
| ... | ... | @@ -34,7 +35,7 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML |
| 34 | 35 | end |
| 35 | 36 | |
| 36 | 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 | 39 | end |
| 39 | 40 | |
| 40 | 41 | def postprocess(full_document) | ... | ... |