Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch to Rouge for syntax highlighting and add dark syntax-highlighting theme #500

Merged
merged 4 commits into from
Dec 15, 2020
Merged
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
2 changes: 1 addition & 1 deletion better_errors.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Gem::Specification.new do |s|
# simplecov and coveralls must not be included here. See the Gemfiles instead.

s.add_dependency "erubi", ">= 1.0.0"
s.add_dependency "coderay", ">= 1.0.0"
s.add_dependency "rouge", ">= 1.0.0"
s.add_dependency "rack", ">= 0.9.0"

# optional dependencies:
Expand Down
1 change: 0 additions & 1 deletion lib/better_errors.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
require "pp"
require "erubi"
require "coderay"
require "uri"

require "better_errors/version"
Expand Down
43 changes: 16 additions & 27 deletions lib/better_errors/code_formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,6 @@ class CodeFormatter
require "better_errors/code_formatter/html"
require "better_errors/code_formatter/text"

FILE_TYPES = {
".rb" => :ruby,
"" => :ruby,
".html" => :html,
".erb" => :erb,
".haml" => :haml
}

attr_reader :filename, :line, :context

def initialize(filename, line, context = 5)
Expand All @@ -26,13 +18,21 @@ def output
source_unavailable
end

def formatted_code
formatted_lines.join
def line_range
min = [line - context, 1].max
max = [line + context, source_lines.count].min
min..max
end

def coderay_scanner
ext = File.extname(filename)
FILE_TYPES[ext] || :text
def context_lines
range = line_range
source_lines[(range.begin - 1)..(range.end - 1)] or raise Errno::EINVAL
end

private

def formatted_code
formatted_lines.join
end

def each_line_of(lines, &blk)
Expand All @@ -41,23 +41,12 @@ def each_line_of(lines, &blk)
}
end

def highlighted_lines
CodeRay.scan(context_lines.join, coderay_scanner).html(css: :class).lines
end

def context_lines
range = line_range
source_lines[(range.begin - 1)..(range.end - 1)] or raise Errno::EINVAL
def source
@source ||= File.read(filename)
end

def source_lines
@source_lines ||= File.readlines(filename)
end

def line_range
min = [line - context, 1].max
max = [line + context, source_lines.count].min
min..max
@source_lines ||= source.lines
end
end
end
18 changes: 16 additions & 2 deletions lib/better_errors/code_formatter/html.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
require "rouge"

module BetterErrors
# @private
class CodeFormatter::HTML < CodeFormatter
Expand All @@ -8,7 +10,7 @@ def source_unavailable
def formatted_lines
each_line_of(highlighted_lines) { |highlight, current_line, str|
class_name = highlight ? "highlight" : ""
sprintf '<pre class="CodeRay %s">%s</pre>', class_name, str
sprintf '<pre class="%s">%s</pre>', class_name, str
}
end

Expand All @@ -20,7 +22,19 @@ def formatted_nums
end

def formatted_code
%{<div class="code_linenums">#{formatted_nums.join}</div><div class="code">#{super}</div>}
%{
<div class="code_linenums">#{formatted_nums.join}</div>
<div class="code"><div class='code-wrapper'>#{super}</div></div>
}
end

def rouge_lexer
Rouge::Lexer.guess(filename: filename, source: source) { Rouge::Lexers::Ruby }
end

def highlighted_lines
Rouge::Formatters::HTML.new.format(rouge_lexer.lex(context_lines.join)).lines
end

end
end
3 changes: 2 additions & 1 deletion lib/better_errors/error_page.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
require "cgi"
require "json"
require "securerandom"
require "rouge"
require "better_errors/error_page_style"

module BetterErrors
Expand Down Expand Up @@ -158,7 +159,7 @@ def eval_and_respond(index, code)
result, prompt, prefilled_input = @repls[index].send_input(code)

{
highlighted_input: CodeRay.scan(code, :ruby).div(wrap: nil),
highlighted_input: Rouge::Formatters::HTML.new.format(Rouge::Lexers::Ruby.lex(code)),
prefilled_input: prefilled_input,
prompt: prompt,
result: result
Expand Down
53 changes: 38 additions & 15 deletions lib/better_errors/style/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -487,12 +487,14 @@ p.no-javascript-notice {
}

.code, .be-console, .unavailable {
background: #fff;
padding: 5px;

box-shadow: inset 3px 3px 3px rgba(0, 0, 0, 0.1), inset 0 0 0 1px rgba(0, 0, 0, 0.1);
}

.code, .unavailable {
text-shadow: none;
}

.code_linenums{
background:#f1f1f1;
padding-top:10px;
Expand All @@ -505,16 +507,35 @@ p.no-javascript-notice {
padding:0 12px;
}

.code, .be-console .syntax-highlighted {
text-shadow: none;

@import "syntax_highlighting";
}
.code {
// For now, the syntax-highlighted console only supports light mode.
// Once the entire page has a dark theme, this should change.
@media (prefers-color-scheme: dark) {
@import "syntax_highlighting_dark";
}
}

.code {
margin-bottom: -1px;
border-top-left-radius:2px;
padding: 10px 0;
overflow: auto;
}

.code pre{
padding-left:12px;
min-height:16px;
.code-wrapper {
// This fixes the highlight or other background of the pre not stretching the full scrollable width.
display: inline-block;
min-width: 100%;
}

pre {
padding-left:12px;
min-height:16px;
}
}

/* Source unavailable */
Expand All @@ -537,28 +558,32 @@ p.unavailable:before {
margin-bottom: -10px;
}

$code-highlight-background: rgba(51, 136, 170, 0.15);
$code-highlight-background-flash: adjust-color($code-highlight-background, $alpha: 0.3);

@-webkit-keyframes highlight {
0% { background: rgba(220, 30, 30, 0.3); }
100% { background: rgba(220, 30, 30, 0.1); }
0% { background: $code-highlight-background-flash; }
100% { background: $code-highlight-background; }
}
@-moz-keyframes highlight {
0% { background: rgba(220, 30, 30, 0.3); }
100% { background: rgba(220, 30, 30, 0.1); }
0% { background: $code-highlight-background-flash; }
100% { background: $code-highlight-background; }
}
@keyframes highlight {
0% { background: rgba(220, 30, 30, 0.3); }
100% { background: rgba(220, 30, 30, 0.1); }
0% { background: $code-highlight-background-flash; }
100% { background: $code-highlight-background; }
}

.code .highlight, .code_linenums .highlight {
background: rgba(220, 30, 30, 0.1);
background: $code-highlight-background;
-webkit-animation: highlight 400ms linear 1;
-moz-animation: highlight 400ms linear 1;
animation: highlight 400ms linear 1;
}

/* REPL shell */
.be-console {
background: #fff;
padding: 0 1px 10px 1px;
border-bottom-left-radius: 2px;
border-bottom-right-radius: 2px;
Expand Down Expand Up @@ -719,5 +744,3 @@ nav.sidebar:hover::-webkit-scrollbar-thumb {
.code:hover::-webkit-scrollbar-thumb {
background: #888;
}

@import "syntax_highlighting";
Loading