--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Markdown wikilinks processing
+#
+# Enables parsing of `[[wikilinks]]` syntax.
+module markdown_wikilinks
+
+intrude import markdown_inline_parsing
+intrude import markdown_block_parsing
+
+redef class MdParser
+
+ # Enable wikilinks mode
+ var wikilinks_mode = false is writable
+
+ redef var inline_parser is lazy do
+ var parser = super
+ parser.wikilinks_mode = wikilinks_mode
+ return parser
+ end
+end
+
+redef class MdInlineParser
+
+ # Enable wikilinks mode
+ private var wikilinks_mode = false
+
+ redef fun parse_wikilink do
+ if not wikilinks_mode then return false
+
+ # do we have two opening bracket?
+ var last_bracket = self.last_bracket
+ if last_bracket == null then return false
+ var first_bracket = last_bracket.prev
+ if first_bracket == null then return false
+
+ # was the first bracket an image?
+ if first_bracket.is_image then return false
+
+ # do we have two closing brackets?
+ if index >= input.length or input.chars[index] != ']' then return false
+
+ advance 1 # skip last bracket
+ var start_index = first_bracket.index + 2
+ var end_index = index - 2
+
+ # create wikilink node
+ var content = input.substring(start_index, end_index - start_index)
+ var parts = content.split("|")
+ var title = if parts.length > 1 then parts.first.trim else null
+ var link = parts.last.trim
+
+ var wikilink = new MdWikilink(
+ new MdLocation(
+ first_bracket.node.location.line_start,
+ first_bracket.node.location.column_start - 1,
+ line,
+ column - 1),
+ link, title)
+
+ var node = last_bracket.node.next
+ var in_link = false
+ while node != null do
+ var next = node.next
+ if not in_link then
+ if node isa MdText and node.literal.has("|") then
+ var buf = new Buffer
+ for c in node.literal.chars do
+ if c == '|' then
+ in_link = true
+ break
+ end
+ buf.add c
+ end
+ node.literal = buf.write_to_string.r_trim
+ end
+ wikilink.append_child(node)
+ else
+ node.unlink
+ end
+ node = next
+ end
+
+ append_node(wikilink)
+
+ # Process delimiters such as emphasis inside a link/image
+ process_delimiters(last_bracket.prev_delimiter)
+ merge_child_text_nodes(wikilink)
+
+ # remove brackets
+ first_bracket.node.unlink
+ last_bracket.node.unlink
+
+ return true
+ end
+end
+
+# A Wikilink node
+class MdWikilink
+ super MdNode
+
+ # Wikilink link
+ var link: String is writable
+
+ # Wikilink title
+ var title: nullable String = null is optional, writable
+end
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Tests for markdown Wikilinks mode
+module test_markdown_wikilinks is test
+
+import test_markdown
+import test_markdown_location
+import test_markdown_md
+import test_markdown_man
+import test_markdown_latex
+
+redef class TestMarkdown
+ redef var md_parser do
+ var parser = super
+ parser.wikilinks_mode = true
+ return parser
+ end
+end
+
+class TestWikilinksLocation
+ super TestMarkdownLocation
+ test
+
+ fun test_wikilinks1 is test do
+ var md = """
+A [[wiki link]] and text.
+"""
+ var loc = """
+MdDocument: 1,1--1,25
+ MdParagraph: 1,1--1,25
+ MdText: 1,1--1,2
+ MdWikilink: 1,3--1,15
+ MdText: 1,5--1,13
+ MdText: 1,16--1,25
+"""
+ assert md_to_loc(md) == loc
+ end
+
+ fun test_wikilinks2 is test do
+ var md = """
+A [[wiki: link | with: more, args: end]] and text.
+"""
+ var loc = """
+MdDocument: 1,1--1,50
+ MdParagraph: 1,1--1,50
+ MdText: 1,1--1,2
+ MdWikilink: 1,3--1,40
+ MdText: 1,5--1,38
+ MdText: 1,41--1,50
+"""
+ assert md_to_loc(md) == loc
+ end
+
+end
+
+class TestWikilinksHtml
+ super TestMarkdownHtml
+ test
+
+ fun test_wikilinks1 is test do
+ var md = """[[foo]]\n"""
+ var html = """<p><wiki link="foo">foo</wiki></p>\n"""
+ assert md_to_html(md) == html
+ end
+
+ fun test_wikilinks2 is test do
+ var md = """[[foo | bar baz]]\n"""
+ var html = """<p><wiki link="bar%20baz">foo</wiki></p>\n"""
+ assert md_to_html(md) == html
+ end
+
+ fun test_wikilinks3 is test do
+ var md = """This is a [[link]] and this is another [[one]].\n"""
+ var html = """<p>This is a <wiki link="link">link</wiki> and this is another <wiki link="one">one</wiki>.</p>\n"""
+ assert md_to_html(md) == html
+ end
+
+ fun test_wikilinks4 is test do
+ var md = """[[very: complex | link: with, more: options]]\n"""
+ var html = """<p><wiki link="link:%20with,%20more:%20options">very: complex</wiki></p>\n"""
+ assert md_to_html(md) == html
+ end
+
+ fun test_wikilink_bad1 is test do
+ var md = """Not a [wikilink]].\n"""
+ var html = """<p>Not a [wikilink]].</p>\n"""
+ assert md_to_html(md) == html
+ end
+
+ fun test_wikilink_bad2 is test do
+ var md = """Not a [[wikilink].\n"""
+ var html = """<p>Not a [[wikilink].</p>\n"""
+ assert md_to_html(md) == html
+ end
+
+ fun test_wikilink_bad3 is test do
+ var md = """Not a ![[wikilink]].\n"""
+ var html = """<p>Not a ![[wikilink]].</p>\n"""
+ assert md_to_html(md) == html
+ end
+
+ fun test_wikilink_bad4 is test do
+ var md = """Not a [wikilink].\n"""
+ var html = """<p>Not a [wikilink].</p>\n"""
+ assert md_to_html(md) == html
+ end
+
+ fun test_link is test do
+ var md = """A standard [link](url).\n"""
+ var html = """<p>A standard <a href="url">link</a>.</p>\n"""
+ assert md_to_html(md) == html
+ end
+
+ fun test_image is test do
+ var md = """A standard ![image](url).\n"""
+ var html = """<p>A standard <img src="url" alt="image" />.</p>\n"""
+ assert md_to_html(md) == html
+ end
+
+ fun test_link_ref1 is test do
+ var md = """A standard [link definition].\n\n[link definition]: url\n"""
+ var html = """<p>A standard <a href="url">link definition</a>.</p>\n"""
+ assert md_to_html(md) == html
+ end
+
+ fun test_link_ref2 is test do
+ var md = """[[wikilinks]] are not \n\n[[link definition]]: url\n"""
+ var html = """<p><wiki link="wikilinks">wikilinks</wiki> are not</p>\n<p><wiki link="link%20definition">link definition</wiki>: url</p>\n"""
+ assert md_to_html(md) == html
+ end
+end
+
+class TestWikilinksMd
+ super TestMarkdownMd
+ test
+
+ fun test_wikilinks_md1 is test do
+ var md = """[[foo]]\n"""
+ assert md_to_md(md) == md
+ end
+
+ fun test_wikilinks_md2 is test do
+ var md = """[[foo: bar | baz: b, c: d]]\n"""
+ assert md_to_md(md) == md
+ end
+end
+
+class TestWikilinksMan
+ super TestMarkdownMan
+ test
+
+ fun test_wikilinks_man is test do
+ var md = """[[foo]]\n"""
+ var man = """\n(foo)\n"""
+ assert md_to_man(md) == man
+ end
+end
+
+class TestWikilinksLatex
+ super TestMarkdownLatex
+ test
+
+ fun test_wikilinks_latex is test do
+ var md = """[[foo]]\n"""
+ var tex = """\\texttt{foo}\n"""
+ assert md_to_tex(md) == tex
+ end
+end