Skip to content
This repository was archived by the owner on May 26, 2019. It is now read-only.

Commit f614688

Browse files
committed
Merge pull request #80 from danmcclain/highlighted-code-fences
{WIP} Implements highlighting
2 parents 2d988d4 + 3b28c8c commit f614688

File tree

5 files changed

+219
-43
lines changed

5 files changed

+219
-43
lines changed

Gemfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ gem "redcarpet"
44
gem "activesupport"
55
gem "highline"
66
gem "rake"
7-
gem "coderay", :git => "git://github.com/dgeb/coderay.git", :branch => "handlebars"
7+
gem "coderay"
88
gem "middleman", '~> 3.0'
9+
gem "byebug"
910
gem "thin"
1011
gem "rack"
1112
gem "listen"

Gemfile.lock

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,6 @@ GIT
77
nokogiri
88
swiftype (>= 0.0.4)
99

10-
GIT
11-
remote: git://github.com/dgeb/coderay.git
12-
revision: 1362fd4af63331aed51ce9907ad7295cea228874
13-
branch: handlebars
14-
specs:
15-
coderay (1.1.0.rc1)
16-
1710
GEM
1811
remote: https://rubygems.org/
1912
remote: https://rails-assets.org/
@@ -25,6 +18,9 @@ GEM
2518
thread_safe (~> 0.1)
2619
tzinfo (~> 1.1)
2720
builder (3.2.2)
21+
byebug (4.0.1)
22+
columnize (= 0.9.0)
23+
rb-readline (= 0.5.2)
2824
capybara (2.4.4)
2925
mime-types (>= 1.16)
3026
nokogiri (>= 1.3.3)
@@ -35,10 +31,12 @@ GEM
3531
timers (~> 4.0.0)
3632
chunky_png (1.3.3)
3733
cliver (0.3.2)
34+
coderay (1.1.0)
3835
coffee-script (2.3.0)
3936
coffee-script-source
4037
execjs
4138
coffee-script-source (1.9.0)
39+
columnize (0.9.0)
4240
compass (1.0.3)
4341
chunky_png (~> 1.2)
4442
compass-core (~> 1.0.2)
@@ -142,6 +140,7 @@ GEM
142140
rb-fsevent (0.9.4)
143141
rb-inotify (0.9.5)
144142
ffi (>= 0.5.0)
143+
rb-readline (0.5.2)
145144
redcarpet (3.2.2)
146145
rspec (3.2.0)
147146
rspec-core (~> 3.2.0)
@@ -202,8 +201,9 @@ PLATFORMS
202201
DEPENDENCIES
203202
activesupport
204203
builder
204+
byebug
205205
capybara
206-
coderay!
206+
coderay
207207
hashie
208208
highline
209209
listen

lib/highlighter.rb

Lines changed: 80 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
require "redcarpet"
2+
require "byebug"
23
require "coderay"
4+
require "nokogiri"
5+
6+
class EmberEncoder < CodeRay::Encoders::Div
7+
FILE_EXTENSION = 'ember.html'
8+
register_for :ember
9+
10+
end
311

412
module Highlighter
513
class MissingLanguageError < StandardError; end
@@ -17,47 +25,75 @@ def _highlight(string, language, class_name=nil)
1725

1826
raise MissingLanguageError, error_message if language.nil?
1927

20-
language, file_name = _detect_language_and_filename(language)
28+
language, file_name, changes = _detect_language_filename_and_changes(language)
2129

2230
result = %Q{<div class="highlight #{language} #{class_name}">}
2331
result += '<div class="ribbon"></div>'
2432
result += '<div class="scroller">'
25-
result += _code_table(string, language, file_name)
33+
result += _code_table(string, language, file_name, changes)
2634
result += '</div>'
2735
result += %Q{</div>}
2836
result
2937
end
3038

31-
def _detect_language_and_filename(language)
32-
39+
def _detect_language_filename_and_changes(language)
3340
file_name = nil
41+
changes = []
42+
changes_regex = /\{(.+)\}$/
3443
bare_language_regex = /\A\w+\z/
3544

45+
if change_numbers = changes_regex.match(language)
46+
language = language.sub(changes_regex, '')
47+
48+
changes = _parse_changes(change_numbers[1])
49+
end
50+
3651
unless language =~ bare_language_regex
3752
file_name = language
3853

39-
language = case /\.(\w+)$/.match(language)[1]
40-
when 'hbs'
41-
'handlebars'
42-
when 'js'
43-
'javascript'
44-
when 'html'
45-
'html'
46-
when 'css'
47-
'css'
48-
when 'json'
49-
'json'
50-
end
54+
language = _determine_language(language)
55+
end
56+
[language, file_name, changes]
57+
end
58+
59+
def _determine_language(language)
60+
case /\.(\w+)$/.match(language)[1]
61+
when 'hbs'
62+
'handlebars'
63+
when 'js'
64+
'javascript'
65+
when 'html'
66+
'html'
67+
when 'css'
68+
'css'
69+
when 'json'
70+
'json'
71+
end
72+
end
73+
74+
def _parse_changes(change_numbers)
75+
changes = change_numbers.split(',').map do |change|
76+
state = case change.slice(0)
77+
when '+'
78+
'added'
79+
when '-'
80+
'removed'
81+
else
82+
nil
83+
end
84+
85+
[change.to_i.abs, state]
5186
end
52-
[language, file_name]
5387
end
5488

55-
def _code_table(string, language, file_name)
89+
def _code_table(string, language, file_name, changes)
5690
code = CodeRay.scan(string, language)
5791

58-
table = code.div css: :class,
92+
# debugger
93+
table = code.ember css: :class,
5994
line_numbers: :table,
60-
line_number_anchors: false
95+
line_number_anchors: false,
96+
highlight_lines: [1,3]
6197

6298
if file_name.present?
6399

@@ -71,7 +107,30 @@ def _code_table(string, language, file_name)
71107
HEADER
72108
end
73109

74-
table
110+
_highlight_lines(table, changes)
111+
end
112+
113+
def _highlight_lines(table, highlights)
114+
return table if highlights.empty?
115+
116+
table_xml = Nokogiri.XML(table)
117+
118+
numbers_node = table_xml.at_xpath('//td[@class="line-numbers"]/pre')
119+
code_node = table_xml.at_xpath('//td[@class="code"]/pre')
120+
121+
numbers_contents = numbers_node.inner_html.split("\n")
122+
code_contents = code_node.inner_html.split("\n")
123+
124+
highlights.each do |line_number, state|
125+
index = line_number - 1
126+
numbers_contents[index] = "<span class=\"highlight-line #{state}\">#{numbers_contents[index]}</span>"
127+
code_contents[index] = "<span class=\"highlight-line #{state}\">#{code_contents[index]}</span>"
128+
end
129+
130+
numbers_node.inner_html = numbers_contents.join("\n")
131+
code_node.inner_html = code_contents.join("\n")
132+
133+
table_xml.to_xml
75134
end
76135

77136
def highlight(language, class_name, &block)

source/stylesheets/highlight.css.scss

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,19 @@
44
$border-radius: 5px;
55

66
$blue: #1f58ce;
7-
$gray: #777777;
8-
$green: #007700;
7+
$gray: #545454;
8+
$textColor: #222;
9+
$green: #005f00;
10+
$orange: #8f4a2c;
11+
12+
$highlight-yellow: #f8eec7;
13+
$highlight-green: #E8F4E5;
14+
$highlight-red: #ffecec;
915

1016
body.guides .highlight {
1117
@include border-radius($border-radius);
1218
border: 1px solid #d1d1d1;
19+
color: $textColor;
1320
}
1421

1522
#content .highlight {
@@ -46,6 +53,45 @@ body.guides .highlight {
4653
&.handlebars .ribbon {
4754
@include hidpi('handlebars-ribbon', png);
4855
}
56+
57+
.highlight-line {
58+
display: inline-block;
59+
margin: 0 -10px;
60+
background-color: $highlight-yellow;
61+
border-right: $highlight-yellow solid 5px;
62+
border-left: $highlight-yellow solid 5px;
63+
box-sizing: content-box;
64+
65+
&.added {
66+
border-color: $highlight-green;
67+
background-color: $highlight-green;
68+
}
69+
70+
&.removed {
71+
border-color: $highlight-red;
72+
background-color: $highlight-red;
73+
}
74+
}
75+
76+
.code .highlight-line {
77+
width: 613px;
78+
margin: 0 -13px;
79+
border-left-width: 13px;
80+
border-right-width: 13px;
81+
}
82+
83+
.line-numbers .highlight-line {
84+
width: 28px;
85+
border-right-color: darken($highlight-yellow, 20%);
86+
87+
&.added {
88+
border-right-color: darken($highlight-green, 20%);
89+
}
90+
91+
&.removed {
92+
border-right-color: darken($highlight-red, 20%);
93+
}
94+
}
4995
}
5096

5197
.CodeRay {
@@ -55,7 +101,7 @@ body.guides .highlight {
55101
text-align: center;
56102
border-right: 1px solid #d1d1d1;
57103
background-color: #f6f6f6;
58-
color: #b4b4b4;
104+
color: $gray;
59105
@include border-top-left-radius($border-radius);
60106
@include border-bottom-left-radius($border-radius);
61107
}
@@ -71,7 +117,7 @@ body.guides .highlight {
71117
}
72118

73119
.comment {
74-
color: $gray;
120+
color: $green;
75121
}
76122

77123
.attribute-name {
@@ -87,7 +133,7 @@ body.guides .highlight {
87133
}
88134

89135
.keyword {
90-
color: #ce791f;
136+
color: $orange;
91137
}
92138

93139
.key, .function {

0 commit comments

Comments
 (0)