From daaf635806fba3ec459da3c2c97301920cea1270 Mon Sep 17 00:00:00 2001
From: Albert Krewinkel <albert@zeitkraut.de>
Date: Wed, 5 Nov 2014 22:27:25 +0100
Subject: [PATCH 1/2] Org reader: absolute, relative paths in links

The org reader was to restrictive when parsing links, some relative
links and links to files given as absolute paths were not recognized
correctly.  The org reader's link parsing function was amended to handle
such cases properly.

This fixes #1741
---
 src/Text/Pandoc/Readers/Org.hs | 31 ++++++++++++++++++-------------
 tests/Tests/Readers/Org.hs     |  8 ++++++++
 2 files changed, 26 insertions(+), 13 deletions(-)

diff --git a/src/Text/Pandoc/Readers/Org.hs b/src/Text/Pandoc/Readers/Org.hs
index 1ddfeab87..2f149765e 100644
--- a/src/Text/Pandoc/Readers/Org.hs
+++ b/src/Text/Pandoc/Readers/Org.hs
@@ -1139,27 +1139,32 @@ applyCustomLinkFormat link = do
     formatter <- M.lookup linkType <$> asksF orgStateLinkFormatters
     return $ maybe link ($ drop 1 rest) formatter
 
-
 linkToInlinesF :: String -> Inlines -> F Inlines
-linkToInlinesF s@('#':_) = pure . B.link s ""
-linkToInlinesF s
-    | isImageFilename s = const . pure $ B.image s "" ""
-    | isUri s           = pure . B.link s ""
-    | isRelativeUrl s   = pure . B.link s ""
-linkToInlinesF s = \title -> do
-  anchorB <- (s `elem`) <$> asksF orgStateAnchorIds
-  if anchorB
-    then pure $ B.link ('#':s) "" title
-    else pure $ B.emph title
+linkToInlinesF s =
+  case s of
+    ('#':_) -> pure . B.link s ""
+    _ | isImageFilename s     -> const . pure $ B.image s "" ""
+    _ | isUri s               -> pure . B.link s ""
+    _ | isRelativeFilePath s  -> pure . B.link s ""
+    _ | isAbsoluteFilePath s  -> pure . B.link ("file://" ++ s) ""
+    _ -> \title -> do
+           anchorB <- (s `elem`) <$> asksF orgStateAnchorIds
+           if anchorB
+             then pure $ B.link ('#':s) "" title
+             else pure $ B.emph title
 
-isRelativeUrl :: String -> Bool
-isRelativeUrl s = (':' `notElem` s) && ("./" `isPrefixOf` s)
+isRelativeFilePath :: String -> Bool
+isRelativeFilePath s = (("./" `isPrefixOf` s) || ("../" `isPrefixOf` s)) &&
+                       (':' `notElem` s)
 
 isUri :: String -> Bool
 isUri s = let (scheme, path) = break (== ':') s
           in all (\c -> isAlphaNum c || c `elem` ".-") scheme
              && not (null path)
 
+isAbsoluteFilePath :: String -> Bool
+isAbsoluteFilePath = ('/' ==) . head
+
 isImageFilename :: String -> Bool
 isImageFilename filename =
   any (\x -> ('.':x)  `isSuffixOf` filename) imageExtensions &&
diff --git a/tests/Tests/Readers/Org.hs b/tests/Tests/Readers/Org.hs
index 392388ec0..fd337f760 100644
--- a/tests/Tests/Readers/Org.hs
+++ b/tests/Tests/Readers/Org.hs
@@ -197,6 +197,14 @@ tests =
           "[[http://zeitlens.com/]]" =?>
           (para $ link "http://zeitlens.com/" "" "http://zeitlens.com/")
 
+      , "Absolute file link" =:
+          "[[/url][hi]]" =?>
+          (para $ link "file:///url" "" "hi")
+
+      , "Link to file in parent directory" =:
+          "[[../file.txt][moin]]" =?>
+          (para $ link "../file.txt" "" "moin")
+
       , "Image link" =:
           "[[sunset.png][dusk.svg]]" =?>
           (para $ link "sunset.png" "" (image "dusk.svg" "" ""))

From e6cd8c907788c083adea5e00def8918b11553f2b Mon Sep 17 00:00:00 2001
From: Albert Krewinkel <albert@zeitkraut.de>
Date: Wed, 5 Nov 2014 22:49:17 +0100
Subject: [PATCH 2/2] Org reader: allow empty links for gitit interop

While empty links are not allowed in Emacs org-mode,  Pandoc org-mode
should support them: gitit relies on empty links as they are used to
create wiki links.

Fixes jgm/gitit#471
---
 src/Text/Pandoc/Readers/Org.hs | 6 +++++-
 tests/Tests/Readers/Org.hs     | 4 ++++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/src/Text/Pandoc/Readers/Org.hs b/src/Text/Pandoc/Readers/Org.hs
index 2f149765e..4c34b7bd5 100644
--- a/src/Text/Pandoc/Readers/Org.hs
+++ b/src/Text/Pandoc/Readers/Org.hs
@@ -1099,7 +1099,7 @@ linkOrImage = explicitOrImageLink
 explicitOrImageLink :: OrgParser (F Inlines)
 explicitOrImageLink = try $ do
   char '['
-  srcF   <- applyCustomLinkFormat =<< linkTarget
+  srcF   <- applyCustomLinkFormat =<< possiblyEmptyLinkTarget
   title  <- enclosedRaw (char '[') (char ']')
   title' <- parseFromString (mconcat <$> many inline) title
   char ']'
@@ -1132,6 +1132,9 @@ selfTarget = try $ char '[' *> linkTarget <* char ']'
 linkTarget :: OrgParser String
 linkTarget = enclosedByPair '[' ']' (noneOf "\n\r[]")
 
+possiblyEmptyLinkTarget :: OrgParser String
+possiblyEmptyLinkTarget = try linkTarget <|> ("" <$ string "[]")
+
 applyCustomLinkFormat :: String -> OrgParser (F String)
 applyCustomLinkFormat link = do
   let (linkType, rest) = break (== ':') link
@@ -1142,6 +1145,7 @@ applyCustomLinkFormat link = do
 linkToInlinesF :: String -> Inlines -> F Inlines
 linkToInlinesF s =
   case s of
+    ""      -> pure . B.link "" ""
     ('#':_) -> pure . B.link s ""
     _ | isImageFilename s     -> const . pure $ B.image s "" ""
     _ | isUri s               -> pure . B.link s ""
diff --git a/tests/Tests/Readers/Org.hs b/tests/Tests/Readers/Org.hs
index fd337f760..e59080bae 100644
--- a/tests/Tests/Readers/Org.hs
+++ b/tests/Tests/Readers/Org.hs
@@ -205,6 +205,10 @@ tests =
           "[[../file.txt][moin]]" =?>
           (para $ link "../file.txt" "" "moin")
 
+      , "Empty link (for gitit interop)" =:
+          "[[][New Link]]" =?>
+          (para $ link "" "" "New Link")
+
       , "Image link" =:
           "[[sunset.png][dusk.svg]]" =?>
           (para $ link "sunset.png" "" (image "dusk.svg" "" ""))