lib/lookbook/code_formatter.rb in lookbook-0.9.8 vs lib/lookbook/code_formatter.rb in lookbook-1.0.0.beta.0
- old
+ new
@@ -1,44 +1,68 @@
require "rouge"
require "htmlbeautifier"
+require 'htmlentities'
module Lookbook
module CodeFormatter
class << self
- def highlight(source, language, opts = {})
- source&.strip! unless opts[:strip] == false
- source&.gsub!(">", ">")&.gsub!("<", "<")
- language ||= "ruby"
- formatter = Formatter.new(opts)
+ def highlight(source, **opts)
+ coder = HTMLEntities.new
+ source = coder.decode source
+ language = opts[:language] || "ruby"
+ formatter = Formatter.new(**opts)
lexer = Rouge::Lexer.find(language.to_s) || Rouge::Lexer.find("plaintext")
formatter.format(lexer.lex(source)).html_safe
end
- def beautify(source, language = "html")
+ def beautify(source, **opts)
+ language = opts[:language] || "html"
source = source.strip
result = language.downcase == "html" ? HtmlBeautifier.beautify(source) : source
result.strip.html_safe
end
end
end
class Formatter < Rouge::Formatters::HTML
- def initialize(opts = {})
+ def initialize(**opts)
@opts = opts
@highlight_lines = opts[:highlight_lines].to_a || []
- @start_line = opts[:start_line] || 0
+ @start_line = opts[:start_line] || 1
+ @language = opts[:language]
end
def stream(tokens, &block)
- token_lines(tokens).each_with_index do |line_tokens, i|
- yield "<div class='line #{"highlighted-line" if @highlight_lines.include?(i + 1)}'>"
- yield "<span class='line-number'>#{@start_line + i}</span>" if @opts[:line_numbers]
- yield "<span class='line-content'>"
+ lines = token_lines(tokens)
+
+ yield "<div class='wrapper'>"
+
+ if @opts[:line_numbers]
+ yield "<div class='line-numbers'>"
+ lines.each.with_index do |line, i|
+ yield "<div class='line #{"highlighted" if highlighted?(i)}'><span class='line-number'>#{line_number(i)}</span></div>"
+ end
+ yield "</div>"
+ end
+
+ yield "<pre class='code highlight' data-lang='#{@language}'><code>"
+ lines.each.with_index do |line_tokens, i|
+ yield "<div class='line#{" highlighted" if highlighted?(i)}'>"
line_tokens.each do |token, value|
yield span(token, value)
end
- yield "</span>"
yield "</div>"
end
+ yield "</code></pre>"
+
+ yield "</div>"
+ end
+
+ def highlighted?(i)
+ @highlight_lines.include?(i + 1)
+ end
+
+ def line_number(i)
+ @start_line + i
end
end
end