Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Markdown, CommonMark: add support for wiki links. [API change] #7705

Merged
merged 1 commit into from
Jan 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/Text/Pandoc/Extensions.hs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,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
Expand Down Expand Up @@ -495,6 +499,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
Expand Down Expand Up @@ -547,6 +553,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
]
Expand Down
4 changes: 4 additions & 0 deletions src/Text/Pandoc/Readers/CommonMark.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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 ]
19 changes: 17 additions & 2 deletions src/Text/Pandoc/Readers/Markdown.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -1505,7 +1505,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
Expand Down Expand Up @@ -1820,6 +1820,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
Expand Down
12 changes: 11 additions & 1 deletion src/Text/Pandoc/Writers/Markdown/Inline.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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 &&
Expand All @@ -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
Expand Down
24 changes: 22 additions & 2 deletions test/Tests/Readers/Markdown.hs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ markdownCDL = purely $ readMarkdown def { readerExtensions = enableExtension
Ext_compact_definition_lists pandocExtensions }

markdownGH :: Text -> Pandoc
markdownGH = purely $ readMarkdown def {
readerExtensions = githubMarkdownExtensions }
markdownGH = purely $ readMarkdown def {readerExtensions = enableExtension
Ext_wikilinks_title_before_pipe githubMarkdownExtensions }

markdownMMD :: Text -> Pandoc
markdownMMD = purely $ readMarkdown def {
Expand Down Expand Up @@ -309,6 +309,26 @@ tests = [ testGroup "inline code"
"[https://example.org(](url)" =?>
para (link "url" "" (text "https://example.org("))
]
, testGroup "Github wiki links"
[ test markdownGH "autolink" $
"[[https://example.org]]" =?>
para (link "https://example.org" "wikilink" (str "https://example.org"))
, test markdownGH "link with title" $
"[[title|https://example.org]]" =?>
para (link "https://example.org" "wikilink" (str "title"))
, test markdownGH "bad link with title" $
"[[title|random string]]" =?>
para (link "random string" "wikilink" (str "title"))
, test markdownGH "autolink not being a link" $
"[[Name of page]]" =?>
para (link "Name of page" "wikilink" (str "Name of page"))
, test markdownGH "autolink not being a link with a square bracket" $
"[[Name of ]page]]" =?>
para (link "Name of ]page" "wikilink" (str "Name of ]page"))
, test markdownGH "link with inline start should be a link" $
"[[t`i*t_le|https://example.org]]" =?>
para (link "https://example.org" "wikilink" (str "t`i*t_le"))
]
, testGroup "Headers"
[ "blank line before header" =:
"\n# Header\n"
Expand Down
73 changes: 73 additions & 0 deletions test/command/wikilinks_title_after_pipe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# CommonMark

## Reader
```
% pandoc --from commonmark_x+wikilinks_title_after_pipe -t html --columns 90
[[https://example.org]]

[[https://example.org|title]]

[[name of page]]

[[name of page|title]]
^D
<p><a href="https://example.org" title="wikilink">https://example.org</a></p>
<p><a href="https://example.org" title="wikilink">title</a></p>
<p><a href="name of page" title="wikilink">name of page</a></p>
<p><a href="name of page" title="wikilink">title</a></p>
```

## Writer

```
% pandoc -t commonmark_x+wikilinks_title_after_pipe -f html
<p><a href="https://example.org" title="wikilink">https://example.org</a></p>
<p><a href="https://example.org" title="wikilink">title</a></p>
<p><a href="Home" title="wikilink">Home</a></p>
<p><a href="Name of page" title="wikilink">Title</a></p>
^D
[[https://example.org]]

[[https://example.org|title]]

[[Home]]

[[Name%20of%20page|Title]]
```

# Markdown
## Reader

```
% pandoc --from markdown+wikilinks_title_after_pipe -t html --columns 90
[[https://example.org]]

[[https://example.org|title]]

[[name of page]]

[[name of page|title]]
^D
<p><a href="https://example.org" title="wikilink">https://example.org</a></p>
<p><a href="https://example.org" title="wikilink">title</a></p>
<p><a href="name of page" title="wikilink">name of page</a></p>
<p><a href="name of page" title="wikilink">title</a></p>
```

## Writer

```
% pandoc -t markdown+wikilinks_title_after_pipe -f html
<p><a href="https://example.org" title="wikilink">https://example.org</a></p>
<p><a href="https://example.org" title="wikilink">title</a></p>
<p><a href="Home" title="wikilink">Home</a></p>
<p><a href="Name of page" title="wikilink">Title</a></p>
^D
[[https://example.org]]

[[https://example.org|title]]

[[Home]]

[[Name%20of%20page|Title]]
```
84 changes: 84 additions & 0 deletions test/command/wikilinks_title_before_pipe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# CommonMark

## Reader

```
% pandoc -f commonmark+wikilinks_title_before_pipe -t html --columns 90
[[https://example.org]]

[[title|https://example.org]]

[[Name of page]]

[[Title|Name of page]]
^D
<p><a href="https://example.org" title="wikilink">https://example.org</a></p>
<p><a href="https://example.org" title="wikilink">title</a></p>
<p><a href="Name of page" title="wikilink">Name of page</a></p>
<p><a href="Name of page" title="wikilink">Title</a></p>
```

## Writer

```
% pandoc -t commonmark_x+wikilinks_title_before_pipe -f html
<p><a href="https://example.org" title="wikilink">https://example.org</a></p>
<p><a href="https://example.org" title="wikilink">title</a></p>
<p><a href="Home" title="wikilink">Home</a></p>
<p><a href="Name of page" title="wikilink">Title</a></p>
^D
[[https://example.org]]

[[title|https://example.org]]

[[Home]]

[[Title|Name%20of%20page]]
```

## Regular links should still work

```
% pandoc -f commonmark+wikilinks_title_before_pipe -t html
[Title](Name%20of%20page)
^D
<p><a href="Name%20of%20page">Title</a></p>
```

# Markdown

## Reader

```
% pandoc -f markdown+wikilinks_title_before_pipe -t html --columns 90
[[https://example.org]]

[[title|https://example.org]]

[[Name of page]]

[[Title|Name of page]]
^D
<p><a href="https://example.org" title="wikilink">https://example.org</a></p>
<p><a href="https://example.org" title="wikilink">title</a></p>
<p><a href="Name of page" title="wikilink">Name of page</a></p>
<p><a href="Name of page" title="wikilink">Title</a></p>
```

## Writer

```
% pandoc -t markdown+wikilinks_title_before_pipe -f html
<p><a href="https://example.org" title="wikilink">https://example.org</a></p>
<p><a href="https://example.org" title="wikilink">title</a></p>
<p><a href="Home" title="wikilink">Home</a></p>
<p><a href="Name of page" title="wikilink">Title</a></p>
^D
[[https://example.org]]

[[title|https://example.org]]

[[Home]]

[[Title|Name%20of%20page]]
```