-
-
Save DivineDominion/83feb20f7a1fa059b915d6e5c412e1b9 to your computer and use it in GitHub Desktop.
require 'kramdown/parser/kramdown' | |
require 'kramdown-parser-gfm' | |
# Based on the API doc comment: https://github.com/gettalong/kramdown/blob/master/lib/kramdown/parser/kramdown.rb | |
class Kramdown::Parser::GFMWikiLink < Kramdown::Parser::GFM | |
def initialize(source, options) | |
super | |
# Override existing Table parser to use our own start Regex which adds a check for wikilinks | |
@@parsers.delete(:table) #Data(:table, TABLE_START, nil, "parse_table") | |
self.class.define_parser(:table, TABLE_START) | |
@span_parsers.unshift(:wikilinks) | |
end | |
# Override Kramdown table pipe check so we can write `[[pagename|Anchor Text]]`. | |
# https://github.com/gettalong/kramdown/blob/master/lib/kramdown/parser/kramdown/table.rb | |
# Regex test suite: https://regexr.com/5rb9q | |
TABLE_PIPE_CHECK = /^(?:\|(?!\[\[)|[^\[]*?(?!\[\[)[^\[]*?\||.*?(?:\[\[[^\]]+\]\]).*?\|)/.freeze # Fail for wikilinks in same line | |
TABLE_LINE = /#{TABLE_PIPE_CHECK}.*?\n/.freeze # Unchanged | |
TABLE_START = /^#{OPT_SPACE}(?=\S)#{TABLE_LINE}/.freeze # Unchanged | |
WIKILINKS_MATCH = /\[\[(.*?)\]\]/.freeze | |
define_parser(:wikilinks, WIKILINKS_MATCH, '\[\[') | |
def parse_wikilinks | |
line_number = @src.current_line_number | |
# Advance parser position | |
@src.pos += @src.matched_size | |
wikilink = Wikilink.parse(@src[1]) | |
el = Element.new(:a, nil, {'href' => wikilink.url, 'title' => wikilink.title}, location: line_number) | |
add_text(wikilink.title, el) | |
@tree.children << el | |
el | |
end | |
# [[page_name|Optional title]] | |
# For a converter that uses the available pages, see: <https://github.com/metala/jekyll-wikilinks-plugin/blob/master/wikilinks.rb> | |
class Wikilink | |
def self.parse(text) | |
name, title = text.split('|', 2) | |
title = name if title.nil? | |
self.new(name, title) | |
end | |
attr_accessor :name, :title | |
attr_reader :match | |
def initialize(name, title) | |
@name = name.strip.gsub(/ +/, '-') | |
@title = title | |
end | |
def title | |
@title || @name | |
end | |
def url | |
"/wiki/#{@name.downcase}" | |
end | |
end | |
end |
I'm using this in a nanoc statically built website.
filter :kramdown, KRAMDOWN_OPTS.merge({input: 'GFMWikiLink'})
That option to select the flavor GFMWikiLink
is all I needed to do.
Didn't actually write anything on the wiki since figuring this out, but it's at https://christiantietze.de/wiki/ :)
The website repo isn't public so I don't have to worry if I ever committed a password -- but if you want to see anything, send me an email.
Thanks! Question -- do you really need to redefine the Table regexes? Is there not a way to force the wikilinks regex match to happen first?
@rathboma I think no; but I'd be happy if you find a better way :) The table parser is block-level, the wikilink parser span level. You'd need to add a block level parser that detect a non-table block with wikilink inside and then prevent the table, maybe 🤔
Fair enough! FYI I got this working. It's great. thank you for posting!
Hey! This looks like just what I need. Are you using this in a production environment? Any tweaks needed?