-
-
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?