summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStephen Altamirano <stephen@evilrobotstuff.com>2023-06-22 10:53:15 -0700
committerGitHub <noreply@github.com>2023-06-22 10:53:15 -0700
commit83b69ead8123a3483ec79a9df5be85612c3b564e (patch)
treefc6a4943ef4727d2d3ae0ca40e76b7f2565901b4 /src
parentebcb61fb07e9d89a5a7a21cf7264b6852c3f5a8d (diff)
Textile reader: Add support for link references (#8706)
Textile supports what it calls "link alias", which are analogous to Markdown's reference-style links.
Diffstat (limited to 'src')
-rw-r--r--src/Text/Pandoc/Readers/Textile.hs31
1 files changed, 29 insertions, 2 deletions
diff --git a/src/Text/Pandoc/Readers/Textile.hs b/src/Text/Pandoc/Readers/Textile.hs
index 0cfe49c4f..154a4906d 100644
--- a/src/Text/Pandoc/Readers/Textile.hs
+++ b/src/Text/Pandoc/Readers/Textile.hs
@@ -40,6 +40,7 @@ import Control.Monad.Except (throwError)
import Data.Char (digitToInt, isUpper)
import Data.List (intersperse, transpose, foldl')
import Data.List.NonEmpty (NonEmpty(..), nonEmpty)
+import qualified Data.Map as M
import Data.Text (Text)
import qualified Data.Text as T
import Text.HTML.TagSoup (Tag (..), fromAttrib)
@@ -49,6 +50,7 @@ import qualified Text.Pandoc.Builder as B
import Text.Pandoc.Class.PandocMonad (PandocMonad (..))
import Text.Pandoc.CSS
import Text.Pandoc.Definition
+import Text.Pandoc.Logging
import Text.Pandoc.Options
import Text.Pandoc.Parsing
import Text.Pandoc.Readers.HTML (htmlTag, isBlockTag, isInlineTag)
@@ -79,7 +81,7 @@ parseTextile = do
-- docMinusKeys is the raw document with blanks where the keys/notes were...
let firstPassParser = do
pos <- getPosition
- t <- noteBlock <|> lineClump
+ t <- noteBlock <|> referenceKey <|> lineClump
return (pos, t)
manyTill firstPassParser eof >>= setInput . Sources
setPosition startPos
@@ -109,6 +111,27 @@ noteBlock = try $ do
-- return blanks so line count isn't affected
return $ T.replicate (sourceLine endPos - sourceLine startPos) "\n"
+referenceKey :: PandocMonad m => TextileParser m Text
+referenceKey = try $ do
+ pos <- getPosition
+ char '['
+ refName <- T.pack <$> many1Till nonspaceChar (char ']')
+ refDestination <- T.pack <$> many1Till anyChar newline
+ st <- getState
+ let oldKeys = stateKeys st
+ let key = toKey refName
+ -- Textile doesn't support link titles on the reference
+ -- definition, so use the empty string
+ let target = (refDestination, "")
+ case M.lookup key oldKeys of
+ Just (t, _) | not (t == target) ->
+ -- similar to Markdown, only warn when the targets
+ -- for matching named references differ
+ logMessage $ DuplicateLinkReference refName pos
+ _ -> return ()
+ updateState $ \s -> s {stateKeys = M.insert key (target, nullAttr) oldKeys }
+ return "\n"
+
-- | Parse document blocks
parseBlocks :: PandocMonad m => TextileParser m Blocks
parseBlocks = mconcat <$> manyTill block eof
@@ -624,7 +647,11 @@ linkUrl bracketed = do
else lookAhead $ space <|> eof' <|> oneOf "[]" <|>
try (oneOf "!.,;:*" *>
(space <|> newline <|> eof'))
- T.pack <$> many1Till nonspaceChar stop
+ rawLink <- T.pack <$> many1Till nonspaceChar stop
+ st <- getState
+ return $ case M.lookup (toKey rawLink) (stateKeys st) of
+ Nothing -> rawLink
+ Just ((src, _), _) -> src
-- | image embedding
image :: PandocMonad m => TextileParser m Inlines