summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlbert Krewinkel <albert@zeitkraut.de>2016-08-18 14:32:59 +0200
committerAlbert Krewinkel <albert@zeitkraut.de>2016-08-18 14:32:59 +0200
commitdbf4d77091f8bcde6d43f0945baf4905c18aebfc (patch)
treecf5ffcf28b0d3cf4d6b9470d62a61af681d0e18f /src
parentd6694256404973a3a7675b97261e7a1914e8f059 (diff)
Org writer: ensure link targets are paths or URLs
Org-mode treats links as document internal searches unless the link target looks like a URL or file path, either relative or absolute. This change ensures that this is always the case.
Diffstat (limited to 'src')
-rw-r--r--src/Text/Pandoc/Writers/Org.hs28
1 files changed, 23 insertions, 5 deletions
diff --git a/src/Text/Pandoc/Writers/Org.hs b/src/Text/Pandoc/Writers/Org.hs
index 85b7433e6..431223f7d 100644
--- a/src/Text/Pandoc/Writers/Org.hs
+++ b/src/Text/Pandoc/Writers/Org.hs
@@ -39,8 +39,8 @@ import Text.Pandoc.Shared
import Text.Pandoc.Writers.Shared
import Text.Pandoc.Pretty
import Text.Pandoc.Templates (renderTemplate')
-import Data.Char ( toLower )
-import Data.List ( intersect, intersperse, partition, transpose )
+import Data.Char ( isAlphaNum, toLower )
+import Data.List ( isPrefixOf, intersect, intersperse, partition, transpose )
import Control.Monad.State
data WriterState =
@@ -354,16 +354,34 @@ inlineToOrg (Link _ txt (src, _)) = do
case txt of
[Str x] | escapeURI x == src -> -- autolink
do modify $ \s -> s{ stLinks = True }
- return $ "[[" <> text x <> "]]"
+ return $ "[[" <> text (orgPath x) <> "]]"
_ -> do contents <- inlineListToOrg txt
modify $ \s -> s{ stLinks = True }
- return $ "[[" <> text src <> "][" <> contents <> "]]"
+ return $ "[[" <> text (orgPath src) <> "][" <> contents <> "]]"
inlineToOrg (Image _ _ (source, _)) = do
modify $ \s -> s{ stImages = True }
- return $ "[[" <> text source <> "]]"
+ return $ "[[" <> text (orgPath source) <> "]]"
inlineToOrg (Note contents) = do
-- add to notes in state
notes <- get >>= (return . stNotes)
modify $ \st -> st { stNotes = contents:notes }
let ref = show $ (length notes) + 1
return $ " [" <> text ref <> "]"
+
+orgPath :: String -> String
+orgPath src =
+ case src of
+ [] -> mempty -- wiki link
+ ('#':xs) -> xs -- internal link
+ _ | isUrl src -> src
+ _ | isFilePath src -> src
+ _ -> "file:" <> src
+ where
+ isFilePath :: String -> Bool
+ isFilePath cs = any (`isPrefixOf` cs) ["/", "./", "../", "file:"]
+
+ isUrl :: String -> Bool
+ isUrl cs =
+ let (scheme, path) = break (== ':') cs
+ in all (\c -> isAlphaNum c || c `elem` (".-"::String)) scheme
+ && not (null path)