git.iko.soy/typeable/pandoc
on master help sign in
Org reader: properly handle links to `file:target`

Org links like `[[file:target][title]]` were not handled correctly, parsing the link target verbatim. The org reader is changed such that the leading `file:` is dropped from the link target. This is related to issues #756 and #1812.

commit4d85b17fc5aa007cb2870fa9904af3fedf4a537e authorAlbert Krewinkel <albert@zeitkraut.de> dateSun 14 Dec 2014, 18:25 (12 years ago) parent4ffa709
2 files changed+26−7
src/Text/Pandoc/Readers/Org.hs+18−6 tests/Tests/Readers/Org.hs+8−1
src/Text/Pandoc/Readers/Org.hs+18−6
@@ -1142,20 +1142,25 @@ applyCustomLinkFormat link = do
11421142 formatter <- M.lookup linkType <$> asksF orgStateLinkFormatters
11431143 return $ maybe link ($ drop 1 rest) formatter
11441144
1145+-- TODO: might be a lot smarter/cleaner to use parsec and ADTs for this kind
1146+-- of parsing.
11451147linkToInlinesF :: String -> Inlines -> F Inlines
11461148linkToInlinesF s =
11471149 case s of
11481150 "" -> pure . B.link "" ""
11491151 ('#':_) -> pure . B.link s ""
11501152 _ | isImageFilename s -> const . pure $ B.image s "" ""
1153+ _ | isFileLink s -> pure . B.link (dropLinkType s) ""
11511154 _ | isUri s -> pure . B.link s ""
1152− _ | isRelativeFilePath s -> pure . B.link s ""
11531155 _ | isAbsoluteFilePath s -> pure . B.link ("file://" ++ s) ""
1154− _ -> \title -> do
1155− anchorB <- (s `elem`) <$> asksF orgStateAnchorIds
1156− if anchorB
1157− then pure $ B.link ('#':s) "" title
1158− else pure $ B.emph title
1156+ _ | isRelativeFilePath s -> pure . B.link s ""
1157+ _ -> internalLink s
1158+
1159+isFileLink :: String -> Bool
1160+isFileLink s = ("file:" `isPrefixOf` s) && not ("file://" `isPrefixOf` s)
1161+
1162+dropLinkType :: String -> String
1163+dropLinkType = tail . snd . break (== ':')
11591164
11601165isRelativeFilePath :: String -> Bool
11611166isRelativeFilePath s = (("./" `isPrefixOf` s) || ("../" `isPrefixOf` s)) &&
@@ -1178,6 +1183,13 @@ isImageFilename filename =
11781183 imageExtensions = [ "jpeg" , "jpg" , "png" , "gif" , "svg" ]
11791184 protocols = [ "file", "http", "https" ]
11801185
1186+internalLink :: String -> Inlines -> F Inlines
1187+internalLink link title = do
1188+ anchorB <- (link `elem`) <$> asksF orgStateAnchorIds
1189+ if anchorB
1190+ then return $ B.link ('#':link) "" title
1191+ else return $ B.emph title
1192+
11811193-- | Parse an anchor like @<<anchor-id>>@ and return an empty span with
11821194-- @anchor-id@ set as id. Legal anchors in org-mode are defined through
11831195-- @org-target-regexp@, which is fairly liberal. Since no link is created if
tests/Tests/Readers/Org.hs+8−1
@@ -4,7 +4,6 @@ module Tests.Readers.Org (tests) where
44import Text.Pandoc.Definition
55import Test.Framework
66import Tests.Helpers
7−import Tests.Arbitrary()
87import Text.Pandoc.Builder
98import Text.Pandoc
109import Data.List (intersperse)
@@ -227,6 +226,14 @@ tests =
227226 , "for", "fnords."
228227 ])
229228
229+ , "Absolute file link" =:
230+ "[[file:///etc/passwd][passwd]]" =?>
231+ (para $ link "file:///etc/passwd" "" "passwd")
232+
233+ , "File link" =:
234+ "[[file:target][title]]" =?>
235+ (para $ link "target" "" "title")
236+
230237 , "Anchor" =:
231238 "<<anchor>> Link here later." =?>
232239 (para $ spanWith ("anchor", [], []) mempty <>