diff --git a/README.md b/README.md index 9880fab9..fddd9f50 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,8 @@ to install the dependencies for the formats that you plan to use. * [ASCIIDoc](http://www.methods.co.nz/asciidoc/) -- `brew install asciidoc` * [Creole](http://wikicreole.org/) -- `gem install creole` -* [Markdown](http://daringfireball.net/projects/markdown/) -- `gem install rdiscount` +* [Markdown](http://daringfireball.net/projects/markdown/) -- `gem install redcarpet` +* [GitHub Flavored Markdown](http://github.github.com/github-flavored-markdown/) -- `gem install github-markdown` * [Org](http://orgmode.org/) -- `gem install org-ruby` * [Pod](http://search.cpan.org/dist/perl/pod/perlpod.pod) -- `Pod::Simple::HTML` comes with Perl >= 5.10. Lower versions should install Pod::Simple from CPAN. * [RDoc](http://rdoc.sourceforge.net/) @@ -294,18 +295,19 @@ separately) by using the following syntax: end ``` -The block must start with three backticks (as the first characters on the -line). After that comes the name of the language that is contained by the +The block must start with three backticks, at the beginning of a line or +indented with any number of spaces or tabs. +After that comes the name of the language that is contained by the block. The language must be one of the `short name` lexer strings supported by Pygments. See the [list of lexers](http://pygments.org/docs/lexers/) for valid options. -If the block contents are indented two spaces or one tab, then that whitespace -will be ignored (this makes the blocks easier to read in plaintext). - -The block must end with three backticks as the first characters on a -line. +The block contents should be indented at the same level than the opening backticks. +If the block contents are indented with an additional two spaces or one tab, +then that whitespace will be ignored (this makes the blocks easier to read in plaintext). +The block must end with three backticks indented at the same level than the opening +backticks. ## MATHEMATICAL EQUATIONS diff --git a/lib/gollum/markup.rb b/lib/gollum/markup.rb index b3f2d1b7..97d15c7e 100644 --- a/lib/gollum/markup.rb +++ b/lib/gollum/markup.rb @@ -361,17 +361,29 @@ module Gollum # # Returns the placeholder'd String data. def extract_code(data) - data.gsub!(/^``` ?([^\r\n]+)?\r?\n(.+?)\r?\n```\r?$/m) do - id = Digest::SHA1.hexdigest("#{$1}.#{$2}") + data.gsub!(/^([ \t]*)``` ?([^\r\n]+)?\r?\n(.+?)\r?\n\1```\r?$/m) do + id = Digest::SHA1.hexdigest("#{$2}.#{$3}") cached = check_cache(:code, id) @codemap[id] = cached ? { :output => cached } : - { :lang => $1, :code => $2 } - id + { :lang => $2, :code => $3, :indent => $1 } + "#{$1}#{id}" # print the SHA1 ID with the proper indentation end data end + # Remove the leading space from a code block. Leading space + # is only removed if every single line in the block has leading + # whitespace. + # + # code - The code block to remove spaces from + # regex - A regex to match whitespace + def remove_leading_space(code, regex) + if code.lines.all? { |line| line =~ /\A\r?\n\Z/ || line =~ regex } + code.gsub!(regex, '') + end + end + # Process all code from the codemap and replace the placeholders with the # final HTML. # @@ -387,16 +399,18 @@ module Gollum next if spec[:output] # cached code = spec[:code] - if code.lines.all? { |line| line =~ /\A\r?\n\Z/ || line =~ /^( |\t)/ } - code.gsub!(/^( |\t)/m, '') - end + + remove_leading_space(code, /^#{spec[:indent]}/m) + remove_leading_space(code, /^( |\t)/m) blocks << [spec[:lang], code] end highlighted = begin encoding ||= 'utf-8' - blocks.map { |lang, code| Pygments.highlight(code, :lexer => lang, :options => {:encoding => encoding.to_s}) } + blocks.map { |lang, code| + Pygments.highlight(code, :lexer => lang, :options => {:encoding => encoding.to_s}) + } rescue ::RubyPython::PythonError [] end @@ -471,63 +485,5 @@ module Gollum end end - begin - require 'redcarpet' - - class MarkupGFM < Markup - def render(no_follow = false, encoding = nil) - sanitize = no_follow ? - @wiki.history_sanitizer : - @wiki.sanitizer - - data = extract_tex(@data.dup) - data = extract_code(data) - data = extract_tags(data) - - if Gem::Version.new(Redcarpet::VERSION) > Gem::Version.new("1.17.2") - html_renderer = Redcarpet::Render::HTML.new({ - :autolink => true, - :fenced_code_blocks => true, - :tables => true, - :strikethrough => true, - :lax_htmlblock => true, - :no_intraemphasis => true - }) - markdown = Redcarpet::Markdown.new(html_renderer) - data = markdown.render(data) - else - flags = [ - :autolink, - :fenced_code, - :tables, - :strikethrough, - :lax_htmlblock, - :no_intraemphasis - ] - data = Redcarpet.new(data, *flags).to_html - end - data = process_tags(data) - data = process_code(data, encoding) - - doc = Nokogiri::HTML::DocumentFragment.parse(data) - - doc.search('pre').each do |node| - next unless lang = node['lang'] - next unless lexer = Pygments::Lexer[lang] - text = node.inner_text - html = lexer.highlight(text) - node.replace(html) - end - - doc = sanitize.clean_node!(doc) if sanitize - yield doc if block_given? - - data = doc.to_html - data = process_tex(data) - data - end - end - rescue LoadError - MarkupGFM = Markup - end + MarkupGFM = Markup end diff --git a/test/test_markup.rb b/test/test_markup.rb index 35e8f0d5..263175c1 100644 --- a/test/test_markup.rb +++ b/test/test_markup.rb @@ -456,11 +456,6 @@ np.array([[2,2],[1,3]],np.float) # rendered with Gollum::Markup page, rendered = render_page(content) assert_markup_highlights_code Gollum::Markup, rendered - - if Gollum.const_defined?(:MarkupGFM) - rendered_gfm = Gollum::MarkupGFM.new(page).render - assert_markup_highlights_code Gollum::MarkupGFM, rendered_gfm - end end def assert_markup_highlights_code(markup_class, rendered)