mhulse / picard

Make it so.
http://mhulse.github.io/picard/dev/
Other
1 stars 0 forks source link

PRE and CODE madness! #116

Closed mhulse closed 10 years ago

mhulse commented 10 years ago

Jekyll outputs <pre> with <code> as a direct child that wraps the whole code block.

This "feature" was added via:

jekyll/jekyll#91

With a reference to code examples found on WHATWG:

http://www.whatwg.org/specs/web-apps/current-work/multipage/grouping-content.html#the-pre-element

Unfortunately, having <pre> wrap <code> makes styling these tags kinda a pain in the arse.

The problem is my <code> styles override my <pre> styles when nested.

Need to make it so I can use inline code without having to apply a class (I don't think MarkDown adds classes to inline <code> anyway).

mhulse commented 10 years ago

GFDI. I was thinking I could override/extend the code highlight tag:

module Jekyll
  class HighlightBlockMod < Jekyll::Tags::HighlightBlock
    def initialize(tag_name, markup, tokens)
      super
    end
    def render(context)
      '<figure class="code"><figcaption></figcaption>' + super + '</figure>'
    end
    def add_code_tags(code, lang)
      # Add nested <code> tags to code blocks
      # code = code.sub(/<pre>/,'<pre><code class="' + lang + '">')
      # code = code.sub(/<\/pre>/,"</code></pre>")
      code
    end
  end
end

Liquid::Template.register_tag('highlight', Jekyll::HighlightBlockMod)

https://gist.github.com/realchaseadams/6093506 http://thanpol.as/jekyll/jekyll-code-highlight-and-line-numbers-problem-solved/

I noticed the above was not working using fences. I then dug deeper and found:

https://github.com/jekyll/jekyll/blob/master/lib/jekyll/converters/markdown/redcarpet_parser.rb#L7-L10

Frustrating, because the HTML5 docs don't demand that <code> lives inside <pre>.

Anyway, looks like I'm just going to re-work my <code> and <pre> styles. Annoying because I'll probably have to get jiggy with funky selectors.

mhulse commented 10 years ago

Damn, hellz yah! I just realized that this plugin is a perfect example of how to override the RedCarpetParser class.

A few mins of minimal tweaking of code:

# http://zpao.com/posts/adding-line-highlights-to-markdown-code-fences/
# http://pygments.org/docs/formatters/
#
# Replace Jekyll's handling of the Redcarpet code_block (which already adds
# support for highlighting, but needs support for the very non-standard
# "code fences with line highlights" extension).
# Since this is currently depending on Redcarpet to cooperate, we are going to
# be naive, and only allow line highlighting when a language is specified. If
# you don't want any syntax highlighting but want to highlight lines, then you
# need to specify text as your language (or it will break), like:
# ```text{4}

module Jekyll
  module Converters
    class Markdown
      class RedcarpetParser
        module WithPygments
          def block_code(code, lang)
            require 'pygments'
            lang_parts = lang && lang.split('{')
            lang = lang_parts && !lang_parts[0].empty? && lang_parts[0] || 'text'
            hl_lines = ''
            if lang_parts && lang_parts.size >= 2
              hl_lines = lang_parts[1].gsub(/[{}]/, '').split(',').map do |ln|
                if matches = /(\d+)-(\d+)/.match(ln)
                  ln = Range.new(matches[1], matches[2]).to_a.join(' ')
                end
                ln
              end.join(' ')
            end
            output = Pygments.highlight(code,
              :lexer => lang,
              :options => {
                :encoding => 'utf-8',
                :hl_lines => hl_lines,
                :cssclass => 'pygments',
                :codetag => false,
              }
            )
          end
        end
      end
    end
  end
end

And no more <code> tags!

While I "get" why <code> "could" be used, it's just not practical.

Note: If I ever use the Jekyll code tag (not fences) then I will probably have to override that class too.

For now, closing!