How to pass options via Rake to Yard to Kramdown to use GFM

360 views Asked by At

I've a gem that I've produced with some docs written with Github Flavoured markdown (GFM) to take advantage of their syntax highlighting.

Unfortunately, Github decided to use their own syntax for code block fencing (three backticks) so to get Yardoc to parse that correctly I've chosen Kramdown as the parser, which supports GFM.

On top of that, when I push the code up to Rubygems the documentation will be generated by running the Rake task (as far as I understand). So I need to find a way to tell Yard to use the Kramdown GFM parser, via Rake.

Kramdown selects the parser via the -i switch:

$ bin/kramdown --help

Command line options:

    -i, --input ARG
          Specify the input format: kramdown (default), html, GFM or markdown

But I don't know how to get Yard to pass that, either via the yard binary or through Rake. I suppose this could be possible by creating a Yardoc plugin, but I've never done that and not sure if it would work, and it also seems like things would be getting out of hand at that point!

What I'd really like is a markdown standard for this, but that's not so much a question as an unfulfilled desire… I'm not sure Stack Overflow can help with those so much.

1

There are 1 answers

0
Rob On

I recently ran across this issue and was having trouble finding clear guidance anywhere, so after digging around in Yard’s issues and source I came up with this approach and am pretty happy with it. Hopefully it might be helpful to someone else who comes across this thread.

  1. Add a Ruby file for Yard customizations. If you have additional docs in a docs/ folder, then docs/yard_support.rb might be a good place. In it, add a custom markup provider for Yard.

    # docs/yard_support.rb
    require 'kramdown'
    require 'kramdown-parser-gfm'
    
    # Custom markup provider class that always renders Kramdown using GFM (Github
    # Flavored Markdown). You could add additional customizations here, or even
    # call a different Markdown library altogether, like `commonmarker`.
    # The only requirement is that your class supports:
    #   - `#initialize(markdown_text, options_hash)`
    #   - `#to_html()`, which just returns the converted HTML source
    class KramdownGfmDocument < Kramdown::Document
        def initialize(source, options = {})
            options[:input] = 'GFM' unless options.key?(:input)
            super(source, options)
        end
    end
    
    # Register the new provider as the highest priority option for Markdown.
    # Unfortunately there's no nice interface for registering your provider; you
    # just have to insert it directly at the front of the array. :\
    # See also:
    # - https://github.com/lsegal/yard/issues/1157
    # - https://github.com/lsegal/yard/issues/1017
    # - https://github.com/lsegal/yard/blob/main/lib/yard/templates/helpers/markup_helper.rb
    YARD::Templates::Helpers::MarkupHelper::MARKUP_PROVIDERS[:markdown].insert(
        0,
        { const: 'KramdownGfmDocument' }
    )
    
  2. Use --load <path_to_the_above_file> in your .yardopts file:

    # .yardopts
    --load docs/yard_support.rb