Markdown: Fix relative links in README.md presentation

Relative links in a README.md file are rendered inline in a
repository index page, a commit, or a tree. Relative links in these
files are written relative to the README.md file itself, including
its revision, which may not be present current in the GitilesView.

Change-Id: Iea72c69336f76ac9bc51c92b9d0308ba950a603e
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/ReadmeHelper.java b/gitiles-servlet/src/main/java/com/google/gitiles/ReadmeHelper.java
index 07e21f9..7013918 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/ReadmeHelper.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/ReadmeHelper.java
@@ -105,6 +105,7 @@
 
       return new MarkdownToHtml(view, cfg)
         .setImageLoader(img)
+        .setReadme(true)
         .toSoyHtml(root);
     } catch (LargeObjectException | IOException e) {
       log.error(String.format("error rendering %s/%s",
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/RepositoryIndexServlet.java b/gitiles-servlet/src/main/java/com/google/gitiles/RepositoryIndexServlet.java
index 21bf1bf..46ab655 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/RepositoryIndexServlet.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/RepositoryIndexServlet.java
@@ -142,7 +142,10 @@
       return null;
     }
 
-    ReadmeHelper readme = new ReadmeHelper(walk.getObjectReader(), view, cfg, rootTree);
+    ReadmeHelper readme = new ReadmeHelper(
+        walk.getObjectReader(),
+        GitilesView.path().copyFrom(view).setRevision(Revision.HEAD).setPathPart("/").build(),
+        cfg, rootTree);
     readme.scanTree(rootTree);
     if (readme.isPresent()) {
       return ImmutableMap.<String, Object> of("readmeHtml", readme.render());
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/doc/MarkdownToHtml.java b/gitiles-servlet/src/main/java/com/google/gitiles/doc/MarkdownToHtml.java
index a9d19df..6687720 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/doc/MarkdownToHtml.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/doc/MarkdownToHtml.java
@@ -75,6 +75,7 @@
   private final GitilesView view;
   private final Config cfg;
   private ImageLoader imageLoader;
+  private boolean readme;
   private TableState table;
 
   public MarkdownToHtml(GitilesView view, Config cfg) {
@@ -87,6 +88,11 @@
     return this;
   }
 
+  public MarkdownToHtml setReadme(boolean readme) {
+    this.readme = readme;
+    return this;
+  }
+
   /** Render the document AST to sanitized HTML. */
   public SanitizedContent toSoyHtml(RootNode node) {
     if (node == null) {
@@ -298,8 +304,22 @@
   }
 
   private String href(String url) {
+    if (HtmlBuilder.isValidHttpUri(url)) {
+      return url;
+    }
     if (MarkdownUtil.isAbsolutePathToMarkdown(url)) {
-      return GitilesView.doc().copyFrom(view).setPathPart(url).build().toUrl();
+      return GitilesView.path().copyFrom(view).setPathPart(url).build().toUrl();
+    }
+    if (readme && !url.startsWith("../") && !url.startsWith("./")) {
+      String dir = "";
+      if (view.getPathPart() != null && view.getPathPart().endsWith("/")) {
+        dir = view.getPathPart();
+      } else if (view.getPathPart() != null) {
+        dir = view.getPathPart() + '/';
+      }
+      return GitilesView.path().copyFrom(view)
+          .setPathPart(dir + url)
+          .build().toUrl();
     }
     return url;
   }