summaryrefslogtreecommitdiff
path: root/src/Text
diff options
context:
space:
mode:
authorAlbert Krewinkel <albert@zeitkraut.de>2022-12-15 21:19:48 +0100
committerJohn MacFarlane <jgm@berkeley.edu>2023-01-15 10:46:55 -0800
commitca6d4bfa490349e7a4dfeee05119427a1c5ace6c (patch)
tree462ab8e861e5447cb72f68b4d186780514c90f2c /src/Text
parentc71d476fa6126a6fe9095c67838e452956249df4 (diff)
Markdown, CommonMark: add support for wiki links. [API change]
Adds the Markdown/CommonMark extensions `wikilinks_title_after_pipe` and `wikilinks_title_before_pipe`. The former enables links of style `[[Name of page|Title]]` and the latter `[[Title|Name of page]]`. Titles are optional in both variants, so this works for both: `[[https://example.org]]`, `[[Name of page]]`. The writer is modified to render links with title `wikilink` as a wikilink if a respective extension is enabled. Pandoc will use `wikilinks_title_after_pipe` if both extensions are enabled. Closes: #2923
Diffstat (limited to 'src/Text')
-rw-r--r--src/Text/Pandoc/Extensions.hs8
-rw-r--r--src/Text/Pandoc/Readers/CommonMark.hs4
-rw-r--r--src/Text/Pandoc/Readers/Markdown.hs19
-rw-r--r--src/Text/Pandoc/Writers/Markdown/Inline.hs12
4 files changed, 40 insertions, 3 deletions
diff --git a/src/Text/Pandoc/Extensions.hs b/src/Text/Pandoc/Extensions.hs
index 525e96ac6..97ac8e77a 100644
--- a/src/Text/Pandoc/Extensions.hs
+++ b/src/Text/Pandoc/Extensions.hs
@@ -135,6 +135,10 @@ data Extension =
| Ext_tex_math_dollars -- ^ TeX math between $..$ or $$..$$
| Ext_tex_math_double_backslash -- ^ TeX math btw \\(..\\) \\[..\\]
| Ext_tex_math_single_backslash -- ^ TeX math btw \(..\) \[..\]
+ | Ext_wikilinks_title_after_pipe -- ^ Support wikilinks of style
+ -- [[target|title]]
+ | Ext_wikilinks_title_before_pipe -- ^ Support wikilinks of style
+ -- [[title|target]]
| Ext_xrefs_name -- ^ Use xrefs with names
| Ext_xrefs_number -- ^ Use xrefs with numbers
| Ext_yaml_metadata_block -- ^ YAML metadata block
@@ -505,6 +509,8 @@ getAllExtensions f = universalExtensions <> getAll f
, Ext_literate_haskell
, Ext_short_subsuperscripts
, Ext_rebase_relative_paths
+ , Ext_wikilinks_title_after_pipe
+ , Ext_wikilinks_title_before_pipe
]
getAll "markdown_strict" = allMarkdownExtensions
getAll "markdown_phpextra" = allMarkdownExtensions
@@ -557,6 +563,8 @@ getAllExtensions f = universalExtensions <> getAll f
, Ext_implicit_header_references
, Ext_attributes
, Ext_sourcepos
+ , Ext_wikilinks_title_after_pipe
+ , Ext_wikilinks_title_before_pipe
, Ext_yaml_metadata_block
, Ext_rebase_relative_paths
]
diff --git a/src/Text/Pandoc/Readers/CommonMark.hs b/src/Text/Pandoc/Readers/CommonMark.hs
index b19637a3e..6f1e270ba 100644
--- a/src/Text/Pandoc/Readers/CommonMark.hs
+++ b/src/Text/Pandoc/Readers/CommonMark.hs
@@ -157,5 +157,9 @@ specFor opts = foldr ($) defaultSyntaxSpec exts
[ (footnoteSpec <>) | isEnabled Ext_footnotes opts ] ++
[ (definitionListSpec <>) | isEnabled Ext_definition_lists opts ] ++
[ (taskListSpec <>) | isEnabled Ext_task_lists opts ] ++
+ [ (wikilinksSpec TitleAfterPipe <>)
+ | isEnabled Ext_wikilinks_title_after_pipe opts ] ++
+ [ (wikilinksSpec TitleBeforePipe <>)
+ | isEnabled Ext_wikilinks_title_before_pipe opts ] ++
[ (rebaseRelativePathsSpec <>)
| isEnabled Ext_rebase_relative_paths opts ]
diff --git a/src/Text/Pandoc/Readers/Markdown.hs b/src/Text/Pandoc/Readers/Markdown.hs
index 776eecd62..4369c0b2a 100644
--- a/src/Text/Pandoc/Readers/Markdown.hs
+++ b/src/Text/Pandoc/Readers/Markdown.hs
@@ -24,7 +24,6 @@ import Control.Monad
import Control.Monad.Except (throwError)
import Data.Bifunctor (second)
import Data.Char (isAlphaNum, isPunctuation, isSpace)
-import Text.DocLayout (realLength)
import Data.List (transpose, elemIndex, sortOn, foldl')
import qualified Data.Map as M
import Data.Maybe
@@ -35,6 +34,7 @@ import qualified Data.ByteString as BS
import System.FilePath (addExtension, takeExtension, takeDirectory)
import qualified System.FilePath.Windows as Windows
import qualified System.FilePath.Posix as Posix
+import Text.DocLayout (realLength)
import Text.HTML.TagSoup hiding (Row)
import Text.Pandoc.Builder (Blocks, Inlines)
import qualified Text.Pandoc.Builder as B
@@ -1516,7 +1516,7 @@ inline = do
'_' -> strongOrEmph
'*' -> strongOrEmph
'^' -> superscript <|> inlineNote -- in this order bc ^[link](/foo)^
- '[' -> note <|> cite <|> bracketedSpan <|> link
+ '[' -> note <|> cite <|> bracketedSpan <|> wikilink <|> link
'!' -> image
'$' -> math
'~' -> strikeout <|> subscript
@@ -1831,6 +1831,21 @@ source = do
linkTitle :: PandocMonad m => MarkdownParser m Text
linkTitle = quotedTitle '"' <|> quotedTitle '\''
+wikilink :: PandocMonad m => MarkdownParser m (F Inlines)
+wikilink =
+ (guardEnabled Ext_wikilinks_title_after_pipe *> wikilink' swap) <|>
+ (guardEnabled Ext_wikilinks_title_before_pipe *> wikilink' id)
+ where
+ swap (a, b) = (b, a)
+ wikilink' order = try $ do
+ string "[["
+ notFollowedBy' (char '[')
+ raw <- many1TillChar (noneOf "\n\r\f\t") (try $ string "]]")
+ let (title, url) = case T.break (== '|') raw of
+ (before, "") -> (before, before)
+ (before, after) -> order (before, T.drop 1 after)
+ return . pure . B.link url "wikilink" $ B.str title
+
link :: PandocMonad m => MarkdownParser m (F Inlines)
link = try $ do
st <- getState
diff --git a/src/Text/Pandoc/Writers/Markdown/Inline.hs b/src/Text/Pandoc/Writers/Markdown/Inline.hs
index 56970e706..e7be4fc21 100644
--- a/src/Text/Pandoc/Writers/Markdown/Inline.hs
+++ b/src/Text/Pandoc/Writers/Markdown/Inline.hs
@@ -651,6 +651,9 @@ inlineToMarkdown opts lnk@(Link attr@(ident,classes,kvs) txt (src, tit)) = do
case txt of
[Str s] | escapeURI s == srcSuffix -> True
_ -> False
+ let useWikilink = tit == "wikilink" &&
+ (isEnabled Ext_wikilinks_title_after_pipe opts ||
+ isEnabled Ext_wikilinks_title_before_pipe opts)
let useRefLinks = writerReferenceLinks opts && not useAuto
shortcutable <- asks envRefShortcutable
let useShortcutRefLinks = shortcutable &&
@@ -667,7 +670,14 @@ inlineToMarkdown opts lnk@(Link attr@(ident,classes,kvs) txt (src, tit)) = do
| otherwise -> return $ result <> attrsToMarkua attributes
where result = "[" <> linktext <> "](" <> (literal src) <> ")"
attributes = addKeyValueToAttr attr ("title", tit)
- _ | useAuto -> return $ "<" <> literal srcSuffix <> ">"
+ -- Use wikilinks where possible
+ _ | src == stringify txt && useWikilink ->
+ return $ "[[" <> literal (stringify txt) <> "]]"
+ | useAuto -> return $ "<" <> literal srcSuffix <> ">"
+ | useWikilink && isEnabled Ext_wikilinks_title_after_pipe opts -> return $
+ "[[" <> literal src <> "|" <> literal (stringify txt) <> "]]"
+ | useWikilink && isEnabled Ext_wikilinks_title_before_pipe opts -> return $
+ "[[" <> literal (stringify txt) <> "|" <> literal src <> "]]"
| useRefLinks ->
let first = "[" <> linktext <> "]"
second = if getKey linktext == getKey reftext