Textile reader: Add support for link references (#8706)

Textile supports what it calls "link alias", which are analogous to
Markdown's reference-style links.
This commit is contained in:
Stephen Altamirano
2023-06-22 10:53:15 -07:00
committed by GitHub
parent ebcb61fb07
commit 83b69ead81
3 changed files with 62 additions and 2 deletions
+29 -2
View File
@@ -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
+27
View File
@@ -749,6 +749,33 @@ Pandoc
, Space
, Str "spaces."
]
, Para
[ Str "A"
, Space
, Link
( "" , [] , [] ) [ Str "link" ] ( "ftp://example.com" , "" )
, Space
, Str "to"
, Space
, Str "a"
, Space
, Str "named"
, Space
, Str "target"
]
, Para
[ Str "A"
, Space
, Link ( "" , [] , [] ) [ Str "link" ] ( "missing" , "" )
, Space
, Str "to"
, Space
, Str "a"
, Space
, Str "missing"
, Space
, Str "target"
]
, Header 1 ( "tables" , [] , [] ) [ Str "Tables" ]
, Para
[ Str "Textile"
+6
View File
@@ -183,6 +183,10 @@ Automatic linking to "$":http://www.example.com.
A link["with brackets":http://www.example.com]and no spaces.
A "link":link-target to a named target
A "link":missing to a missing target
h1. Tables
Textile allows tables with and without headers :
@@ -277,3 +281,5 @@ h1. Comment blocks
is here.
not a comment.
[link-target]ftp://example.com