Commit 5b23a7bbb9cc47cda3111a5213b3433303c3e143

Authored by Marin Jankovski
1 parent 5277ac1b

Cover a special case.

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)