Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions lib/org-ruby/highlighter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
module Orgmode
# Highlight code
module Highlighter
def self.highlight(code, lang)
highlighter = guess_highlighter
highlighter.highlight(code, lang)
end

def self.guess_highlighter
return RougeHighliter if gem_present?('rouge')
return PygmentsHighliter if gem_present?('pygments.rb')
return CodeRayHighliter if gem_present?('coderay')

DefaultHighliter
end

def self.gem_present?(gem)
Gem::Specification.find_all_by_name(gem).any?
end

# Default highliter does nothing to code
class DefaultHighliter
def self.highlight(buffer, _lang)
buffer
end
end

# Pygments wrapper
class PygmentsHighliter
def self.highlight(buffer, lang)
require 'pygments'
if Pygments::Lexer.find_by_alias(lang)
Pygments.highlight(buffer, lexer: lang)
else
Pygments.highlight(buffer, lexer: 'text')
end
end
end

# CodeRay wrapper
class CodeRayHighliter
def self.highlight(buffer, lang)
require 'coderay'
CodeRay.scan(buffer, lang).html(wrap: nil, css: :style)
rescue ArgumentError => _e
CodeRay.scan(buffer, 'text').html(wrap: nil, css: :style)
end
end

# Rouge wrapper
class RougeHighliter
def self.highlight(buffer, lang)
require 'rouge'
formatter = Rouge::Formatters::HTMLLegacy.new
lexer = Rouge::Lexer.find_fancy(lang, buffer) ||
Rouge::Lexers::PlainText
formatter.format(lexer.lex(buffer.strip))
end
end
end
end
48 changes: 9 additions & 39 deletions lib/org-ruby/html_output_buffer.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module Orgmode

class HtmlOutputBuffer < OutputBuffer

require_relative './highlighter.rb'
HtmlBlockTag = {
:paragraph => "p",
:ordered_list => "ol",
Expand Down Expand Up @@ -37,20 +37,6 @@ def initialize(output, opts = {})
@unclosed_tags = []
@logger.debug "HTML export options: #{@options.inspect}"
@custom_blocktags = {} if @options[:markup_file]

unless @options[:skip_syntax_highlight]
begin
require 'pygments'
rescue LoadError
# Pygments is not supported so we try instead with CodeRay
begin
require 'coderay'
rescue LoadError
# No code syntax highlighting
end
end
end

if @options[:markup_file]
do_custom_markup
end
Expand All @@ -64,7 +50,7 @@ def push_mode(mode, indent, properties={})
super(mode, indent, properties)
if HtmlBlockTag[mode]
unless ((mode_is_table?(mode) and skip_tables?) or
(mode == :src and !@options[:skip_syntax_highlight] and defined? Pygments))
(mode == :src and !@options[:skip_syntax_highlight]))
css_class = case
when (mode == :src and @block_lang.empty?)
" class=\"src\""
Expand Down Expand Up @@ -100,7 +86,7 @@ def pop_mode(mode = nil)
m = super(mode)
if HtmlBlockTag[m]
unless ((mode_is_table?(m) and skip_tables?) or
(m == :src and !@options[:skip_syntax_highlight] and defined? Pygments))
(m == :src and !@options[:skip_syntax_highlight]))
add_paragraph if @new_paragraph
@new_paragraph = true
@logger.debug "</#{HtmlBlockTag[m]}>"
Expand All @@ -110,6 +96,10 @@ def pop_mode(mode = nil)
@list_indent_stack.pop
end

def highlight(code, lang)
Highlighter.highlight code, lang
end

def flush!
return false if @buffer.empty?
case
Expand All @@ -121,29 +111,9 @@ def flush!
case
when (current_mode == :src and @options[:skip_syntax_highlight])
@buffer = escapeHTML @buffer
when (current_mode == :src and defined? Pygments)
when (current_mode == :src)
lang = normalize_lang @block_lang
@output << "\n" unless @new_paragraph == :start
@new_paragraph = true

begin
@buffer = Pygments.highlight(@buffer, :lexer => lang)
rescue
# Not supported lexer from Pygments, we fallback on using the text lexer
@buffer = Pygments.highlight(@buffer, :lexer => 'text')
end
when (current_mode == :src and defined? CodeRay)
lang = normalize_lang @block_lang

# CodeRay might throw a warning when unsupported lang is set,
# then fallback to using the text lexer
silence_warnings do
begin
@buffer = CodeRay.scan(@buffer, lang).html(:wrap => nil, :css => :style)
rescue ArgumentError
@buffer = CodeRay.scan(@buffer, 'text').html(:wrap => nil, :css => :style)
end
end
@buffer = highlight @buffer, lang
when (current_mode == :html or current_mode == :raw_text)
@buffer.gsub!(/\A\n/, "") if @new_paragraph == :start
@new_paragraph = true
Expand Down