Skip to content

Commit 3cb344a

Browse files
Merge pull request #500 from BetterErrors/feature/dark-syntax-highlighing-theme
Switch to Rouge for syntax highlighting and add dark syntax-highlighting theme
2 parents db2086f + 7edd3a2 commit 3cb344a

File tree

12 files changed

+360
-279
lines changed

12 files changed

+360
-279
lines changed

better_errors.gemspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ Gem::Specification.new do |s|
3131
# simplecov and coveralls must not be included here. See the Gemfiles instead.
3232

3333
s.add_dependency "erubi", ">= 1.0.0"
34-
s.add_dependency "coderay", ">= 1.0.0"
34+
s.add_dependency "rouge", ">= 1.0.0"
3535
s.add_dependency "rack", ">= 0.9.0"
3636

3737
# optional dependencies:

lib/better_errors.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
require "pp"
22
require "erubi"
3-
require "coderay"
43
require "uri"
54

65
require "better_errors/version"

lib/better_errors/code_formatter.rb

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,6 @@ class CodeFormatter
44
require "better_errors/code_formatter/html"
55
require "better_errors/code_formatter/text"
66

7-
FILE_TYPES = {
8-
".rb" => :ruby,
9-
"" => :ruby,
10-
".html" => :html,
11-
".erb" => :erb,
12-
".haml" => :haml
13-
}
14-
157
attr_reader :filename, :line, :context
168

179
def initialize(filename, line, context = 5)
@@ -26,13 +18,21 @@ def output
2618
source_unavailable
2719
end
2820

29-
def formatted_code
30-
formatted_lines.join
21+
def line_range
22+
min = [line - context, 1].max
23+
max = [line + context, source_lines.count].min
24+
min..max
3125
end
3226

33-
def coderay_scanner
34-
ext = File.extname(filename)
35-
FILE_TYPES[ext] || :text
27+
def context_lines
28+
range = line_range
29+
source_lines[(range.begin - 1)..(range.end - 1)] or raise Errno::EINVAL
30+
end
31+
32+
private
33+
34+
def formatted_code
35+
formatted_lines.join
3636
end
3737

3838
def each_line_of(lines, &blk)
@@ -41,23 +41,12 @@ def each_line_of(lines, &blk)
4141
}
4242
end
4343

44-
def highlighted_lines
45-
CodeRay.scan(context_lines.join, coderay_scanner).html(css: :class).lines
46-
end
47-
48-
def context_lines
49-
range = line_range
50-
source_lines[(range.begin - 1)..(range.end - 1)] or raise Errno::EINVAL
44+
def source
45+
@source ||= File.read(filename)
5146
end
5247

5348
def source_lines
54-
@source_lines ||= File.readlines(filename)
55-
end
56-
57-
def line_range
58-
min = [line - context, 1].max
59-
max = [line + context, source_lines.count].min
60-
min..max
49+
@source_lines ||= source.lines
6150
end
6251
end
6352
end

lib/better_errors/code_formatter/html.rb

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
require "rouge"
2+
13
module BetterErrors
24
# @private
35
class CodeFormatter::HTML < CodeFormatter
@@ -8,7 +10,7 @@ def source_unavailable
810
def formatted_lines
911
each_line_of(highlighted_lines) { |highlight, current_line, str|
1012
class_name = highlight ? "highlight" : ""
11-
sprintf '<pre class="CodeRay %s">%s</pre>', class_name, str
13+
sprintf '<pre class="%s">%s</pre>', class_name, str
1214
}
1315
end
1416

@@ -20,7 +22,19 @@ def formatted_nums
2022
end
2123

2224
def formatted_code
23-
%{<div class="code_linenums">#{formatted_nums.join}</div><div class="code">#{super}</div>}
25+
%{
26+
<div class="code_linenums">#{formatted_nums.join}</div>
27+
<div class="code"><div class='code-wrapper'>#{super}</div></div>
28+
}
29+
end
30+
31+
def rouge_lexer
32+
Rouge::Lexer.guess(filename: filename, source: source) { Rouge::Lexers::Ruby }
2433
end
34+
35+
def highlighted_lines
36+
Rouge::Formatters::HTML.new.format(rouge_lexer.lex(context_lines.join)).lines
37+
end
38+
2539
end
2640
end

lib/better_errors/error_page.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
require "cgi"
22
require "json"
33
require "securerandom"
4+
require "rouge"
45
require "better_errors/error_page_style"
56

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

160161
{
161-
highlighted_input: CodeRay.scan(code, :ruby).div(wrap: nil),
162+
highlighted_input: Rouge::Formatters::HTML.new.format(Rouge::Lexers::Ruby.lex(code)),
162163
prefilled_input: prefilled_input,
163164
prompt: prompt,
164165
result: result

lib/better_errors/style/main.scss

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -487,12 +487,14 @@ p.no-javascript-notice {
487487
}
488488

489489
.code, .be-console, .unavailable {
490-
background: #fff;
491490
padding: 5px;
492-
493491
box-shadow: inset 3px 3px 3px rgba(0, 0, 0, 0.1), inset 0 0 0 1px rgba(0, 0, 0, 0.1);
494492
}
495493

494+
.code, .unavailable {
495+
text-shadow: none;
496+
}
497+
496498
.code_linenums{
497499
background:#f1f1f1;
498500
padding-top:10px;
@@ -505,16 +507,35 @@ p.no-javascript-notice {
505507
padding:0 12px;
506508
}
507509

510+
.code, .be-console .syntax-highlighted {
511+
text-shadow: none;
512+
513+
@import "syntax_highlighting";
514+
}
515+
.code {
516+
// For now, the syntax-highlighted console only supports light mode.
517+
// Once the entire page has a dark theme, this should change.
518+
@media (prefers-color-scheme: dark) {
519+
@import "syntax_highlighting_dark";
520+
}
521+
}
522+
508523
.code {
509524
margin-bottom: -1px;
510525
border-top-left-radius:2px;
511526
padding: 10px 0;
512527
overflow: auto;
513-
}
514528

515-
.code pre{
516-
padding-left:12px;
517-
min-height:16px;
529+
.code-wrapper {
530+
// This fixes the highlight or other background of the pre not stretching the full scrollable width.
531+
display: inline-block;
532+
min-width: 100%;
533+
}
534+
535+
pre {
536+
padding-left:12px;
537+
min-height:16px;
538+
}
518539
}
519540

520541
/* Source unavailable */
@@ -537,28 +558,32 @@ p.unavailable:before {
537558
margin-bottom: -10px;
538559
}
539560

561+
$code-highlight-background: rgba(51, 136, 170, 0.15);
562+
$code-highlight-background-flash: adjust-color($code-highlight-background, $alpha: 0.3);
563+
540564
@-webkit-keyframes highlight {
541-
0% { background: rgba(220, 30, 30, 0.3); }
542-
100% { background: rgba(220, 30, 30, 0.1); }
565+
0% { background: $code-highlight-background-flash; }
566+
100% { background: $code-highlight-background; }
543567
}
544568
@-moz-keyframes highlight {
545-
0% { background: rgba(220, 30, 30, 0.3); }
546-
100% { background: rgba(220, 30, 30, 0.1); }
569+
0% { background: $code-highlight-background-flash; }
570+
100% { background: $code-highlight-background; }
547571
}
548572
@keyframes highlight {
549-
0% { background: rgba(220, 30, 30, 0.3); }
550-
100% { background: rgba(220, 30, 30, 0.1); }
573+
0% { background: $code-highlight-background-flash; }
574+
100% { background: $code-highlight-background; }
551575
}
552576

553577
.code .highlight, .code_linenums .highlight {
554-
background: rgba(220, 30, 30, 0.1);
578+
background: $code-highlight-background;
555579
-webkit-animation: highlight 400ms linear 1;
556580
-moz-animation: highlight 400ms linear 1;
557581
animation: highlight 400ms linear 1;
558582
}
559583

560584
/* REPL shell */
561585
.be-console {
586+
background: #fff;
562587
padding: 0 1px 10px 1px;
563588
border-bottom-left-radius: 2px;
564589
border-bottom-right-radius: 2px;
@@ -719,5 +744,3 @@ nav.sidebar:hover::-webkit-scrollbar-thumb {
719744
.code:hover::-webkit-scrollbar-thumb {
720745
background: #888;
721746
}
722-
723-
@import "syntax_highlighting";

0 commit comments

Comments
 (0)