@@ -1099,7 +1099,7 @@ linkOrImage = explicitOrImageLink
10991099explicitOrImageLink :: OrgParser (F Inlines)
11001100explicitOrImageLink = try $ do
11011101 char '['
1102− srcF <- applyCustomLinkFormat =<< linkTarget
1102+ srcF <- applyCustomLinkFormat =<< possiblyEmptyLinkTarget
11031103 title <- enclosedRaw (char '[') (char ']')
11041104 title' <- parseFromString (mconcat <$> many inline) title
11051105 char ']'
@@ -1132,6 +1132,9 @@ selfTarget = try $ char '[' *> linkTarget <* char ']'
11321132linkTarget :: OrgParser String
11331133linkTarget = enclosedByPair '[' ']' (noneOf "\n\r[]")
11341134
1135+possiblyEmptyLinkTarget :: OrgParser String
1136+possiblyEmptyLinkTarget = try linkTarget <|> ("" <$ string "[]")
1137+
11351138applyCustomLinkFormat :: String -> OrgParser (F String)
11361139applyCustomLinkFormat link = do
11371140 let (linkType, rest) = break (== ':') link
@@ -1139,27 +1142,33 @@ applyCustomLinkFormat link = do
11391142 formatter <- M.lookup linkType <$> asksF orgStateLinkFormatters
11401143 return $ maybe link ($ drop 1 rest) formatter
11411144
1142−
11431145linkToInlinesF :: String -> Inlines -> F Inlines
1144−linkToInlinesF s@('#':_) = pure . B.link s ""
1145−linkToInlinesF s
1146− | isImageFilename s = const . pure $ B.image s "" ""
1147− | isUri s = pure . B.link s ""
1148− | isRelativeUrl s = pure . B.link s ""
1149−linkToInlinesF s = \title -> do
1150− anchorB <- (s `elem`) <$> asksF orgStateAnchorIds
1151− if anchorB
1152− then pure $ B.link ('#':s) "" title
1153− else pure $ B.emph title
1154−
1155−isRelativeUrl :: String -> Bool
1156−isRelativeUrl s = (':' `notElem` s) && ("./" `isPrefixOf` s)
1146+linkToInlinesF s =
1147+ case s of
1148+ "" -> pure . B.link "" ""
1149+ ('#':_) -> pure . B.link s ""
1150+ _ | isImageFilename s -> const . pure $ B.image s "" ""
1151+ _ | isUri s -> pure . B.link s ""
1152+ _ | isRelativeFilePath s -> pure . B.link s ""
1153+ _ | 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
1159+
1160+isRelativeFilePath :: String -> Bool
1161+isRelativeFilePath s = (("./" `isPrefixOf` s) || ("../" `isPrefixOf` s)) &&
1162+ (':' `notElem` s)
11571163
11581164isUri :: String -> Bool
11591165isUri s = let (scheme, path) = break (== ':') s
11601166 in all (\c -> isAlphaNum c || c `elem` ".-") scheme
11611167 && not (null path)
11621168
1169+isAbsoluteFilePath :: String -> Bool
1170+isAbsoluteFilePath = ('/' ==) . head
1171+
11631172isImageFilename :: String -> Bool
11641173isImageFilename filename =
11651174 any (\x -> ('.':x) `isSuffixOf` filename) imageExtensions &&