Skip to content

Commit 93322f7

Browse files
committed
Highlight markdown syntax in .md files using Redcarpet+CodeRay
Currently, there are something like three ways we do syntax highlighting in this app: In .step files, you can have a 'source_code' step that specifies a language parameter. This makes a <pre class='code'> tag that contains the language name as ':::ruby', to be scooped out by Rack::Codehighlighter. In .deck.md files, you can use Github-flavored "```ruby" style 'fenced code blocks', which get parsed by redcarpet into <pre><code> blocks, which inexplicably and briefly have an '@@@ ruby' directive that is picked up by the Rack::Codehighlighter middleware. In .md files (as of this diff) you can do Github-flavored fenced code blocks, which are parsed in the original render time into <pre class='CodeRay'> blocks that have the real syntax highlighting. 'Fenced code blocks' produced in Markdown-aware erector functions (like 'message') don't seem to produce highlighted code. Will probably improve on this in a subsequent diff.
1 parent 7960229 commit 93322f7

File tree

9 files changed

+141
-73
lines changed

9 files changed

+141
-73
lines changed

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ gem 'rack-codehighlighter'
1010
gem 'coderay'
1111
gem "deckrb", ">=0.3.0"
1212
gem "sass"
13+
gem "redcarpet"
1314

1415
group :development do
1516
gem "wrong", ">=0.6.2"

Gemfile.lock

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ GEM
99
ZenTest (4.7.0)
1010
bourbon (1.4.0)
1111
sass (>= 3.1)
12-
coderay (1.0.5)
12+
coderay (1.0.8)
1313
daemons (1.1.8)
1414
deckrb (0.3.0)
1515
coderay
@@ -29,11 +29,11 @@ GEM
2929
tins (~> 0.3)
3030
files (0.3.0)
3131
json (1.6.6)
32-
nokogiri (1.5.2)
33-
nokogiri (1.5.2-x86-mingw32)
32+
nokogiri (1.5.6)
33+
nokogiri (1.5.6-x86-mingw32)
3434
polyglot (0.3.3)
3535
predicated (0.2.6)
36-
rack (1.4.1)
36+
rack (1.5.1)
3737
rack-codehighlighter (0.5.0)
3838
nokogiri (>= 1.4.1)
3939
rack (>= 1.0.0)
@@ -105,6 +105,7 @@ DEPENDENCIES
105105
rack-test
106106
rake
107107
rdiscount
108+
redcarpet
108109
rerun
109110
rspec
110111
sass

config.ru

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
require 'rack/codehighlighter'
22
require 'coderay'
33

4-
# Fix Rack bug https://github.com/rack/rack/issues/301
5-
require './lib/rack_static_patch'
6-
74
use Rack::ShowExceptions
85
use Rack::ShowStatus
96
use Rack::Static, :urls => ["/css", "/img"], :root => "public"
@@ -13,7 +10,6 @@ use Rack::Codehighlighter, :coderay,
1310
:markdown => true,
1411
:pattern => /\A[:@]{3}\s?(\w+)\s*(\n|&#x000A;)/i
1512

16-
1713
# require 'thin/logging'
1814
# Thin::Logging.debug = true
1915

lib/markdown_page.rb

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,27 @@
11
require 'erector'
22
require 'doc_page'
3+
require 'redcarpet'
4+
require 'coderay'
5+
6+
class HTMLwithCodeRay < Redcarpet::Render::HTML
7+
def block_code(code, language)
8+
if language
9+
"<pre class='CodeRay'>#{CodeRay.scan(code, language).html}</pre>"
10+
else
11+
"<pre class='CodeRay'>#{CodeRay.scan(code, :text).html}</pre>"
12+
end
13+
end
14+
end
15+
16+
MarkdownRenderer = Redcarpet::Markdown.new(
17+
HTMLwithCodeRay,
18+
:autolink => true,
19+
:space_after_headers => true,
20+
:fenced_code_blocks => true
21+
)
322

423
class MarkdownPage < DocPage
524
def doc_content
6-
rawtext md2html(src)
25+
rawtext MarkdownRenderer.render(src)
726
end
827
end

lib/rack_static_patch.rb

Lines changed: 0 additions & 13 deletions
This file was deleted.
Lines changed: 66 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,94 @@
11
## HTML Skeleton
2-
<!DOCTYPE html>
3-
<html>
4-
<head>
5-
<meta charset="utf-8">
6-
<title>Title</title>
7-
</head>
8-
<body>
9-
10-
</body>
11-
</html>
2+
3+
```html
4+
<!DOCTYPE html>
5+
<html>
6+
<head>
7+
<meta charset="utf-8">
8+
<title>Title</title>
9+
</head>
10+
<body>
11+
12+
</body>
13+
</html>
14+
```
1215

1316
## Headers
14-
<h1>Header</h1>
15-
<h2>Header</h2>
16-
<h2>Header</h2>
17-
<h4>Header</h4>
18-
<h5>Header</h5>
19-
<h6>Header</h6>
17+
```html
18+
<h1>Header</h1>
19+
<h2>Header</h2>
20+
<h2>Header</h2>
21+
<h4>Header</h4>
22+
<h5>Header</h5>
23+
<h6>Header</h6>
24+
```
2025

2126
## Paragraphs and more
22-
<p>Paragraph content.</p>
23-
<em>emphasized content, styled italic by default</em>
24-
<strong>strong content, styled bold by default</strong>
27+
```html
28+
<p>Paragraph content.</p>
29+
<em>emphasized content, styled italic by default</em>
30+
<strong>strong content, styled bold by default</strong>
31+
```
2532

2633
## Images
27-
<img src="name-of-my-image.png">
28-
<img src="http://www.othersite.com/image-name.jpg">
34+
```html
35+
<img src="name-of-my-image.png">
36+
<img src="http://www.othersite.com/image-name.jpg">
37+
```
2938

3039
## Links
31-
<a href="#anchor">Scroll to element on the current page with id "anchor"</a>
32-
<a href="my-other-page.html">Go to a page on my site</a>
33-
<a href="my-other-page.html" target="_blank">Open a new window for a page on my site</a>
34-
<a href="http://www.othersite.com/">Go to a page on some other site</a>
35-
<a href="http://www.othersite.com/" target="_blank">Open a new window for a page on some other site</a>
40+
```html
41+
<a href="#anchor">Scroll to element on the current page with id "anchor"</a>
42+
<a href="my-other-page.html">Go to a page on my site</a>
43+
<a href="my-other-page.html" target="_blank">Open a new window for a page on my site</a>
44+
<a href="http://www.othersite.com/">Go to a page on some other site</a>
45+
<a href="http://www.othersite.com/" target="_blank">Open a new window for a page on some other site</a>
46+
```
3647

3748
## Lists
3849

3950
Lists can be ordered (styled with numbers by default) or unordered (styled with bullets by default). Both contain list items with the actual content of the list.
4051

41-
<ol>
42-
<li>First list item</li>
43-
<li>Second list item</li>
44-
</ol>
52+
```html
53+
<ol>
54+
<li>First list item</li>
55+
<li>Second list item</li>
56+
</ol>
4557

46-
<ul>
47-
<li>One list item</li>
48-
<li>Another list item</li>
49-
</ul>
58+
<ul>
59+
<li>One list item</li>
60+
<li>Another list item</li>
61+
</ul>
62+
```
5063

5164
Lists can be nested.
5265

66+
```html
67+
<ul>
68+
<li>One list item
5369
<ul>
54-
<li>One list item
55-
<ul>
56-
<li>A list item nested under "One list item"</li>
57-
<li>Another nest list item</li>
58-
</ul>
59-
</li>
60-
<li>Another list item</li>
70+
<li>A list item nested under "One list item"</li>
71+
<li>Another nest list item</li>
6172
</ul>
73+
</li>
74+
<li>Another list item</li>
75+
</ul>
76+
```
6277

6378
## Containers
6479

6580
Divs and spans are generic containers used to organize HTML. Often, they are given ids and classes so that they can be given specific styling.
6681

67-
<div>The content in the div</div>
68-
<span>span content</span>
82+
```html
83+
<div>The content in the div</div>
84+
<span>span content</span>
85+
```
6986

7087
## Ids and Classes
7188

72-
Ids and classes provide a way to use CSS to target specific element(s). Many tags can have the same class. Only one tag can have a particular id. Any tag can be gi
73-
an id and classes.</p>
74-
<tagname id="a-name-uniquely-identifying-this-element">content</tagname>
75-
<tagname class="one-class another-class">content</tagname>
89+
Ids and classes provide a way to use CSS to target specific element(s). Many tags can have the same class. Only one tag can have a particular id. Any tag can be given an id and classes.
90+
91+
```html
92+
<tagname id="a-name-uniquely-identifying-this-element">content</tagname>
93+
<tagname class="one-class another-class">content</tagname>
94+
```

spec/markdown_spec.rb

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
here = File.expand_path File.dirname(__FILE__)
2+
require "#{here}/spec_helper"
3+
4+
require "markdown_page"
5+
6+
describe MarkdownPage do
7+
8+
it "renders markdown into html" do
9+
src = <<MARKDOWN
10+
# This is a heading
11+
12+
## This is a subheading
13+
<h2>This text is preformatted and escaped</h2>
14+
15+
```html
16+
This text is preformatted and ready to be <strong>syntax highlighted</strong> as HTML source.
17+
```
18+
MARKDOWN
19+
20+
page = MarkdownPage.new(
21+
src: src,
22+
site_name: "greetings",
23+
page_name: 'hello',
24+
doc_title: "Hello",
25+
doc_path: "/tmp/hello.step"
26+
)
27+
html_doc = Nokogiri.parse(page.to_html)
28+
main_html = html_doc.css(".main").first.serialize(:save_with => 0).chomp
29+
30+
expected = <<HTML
31+
<div class="main">
32+
<h1 class="doc_title">Hello</h1>
33+
<div class="doc">
34+
<h1>This is a heading</h1>
35+
<h2>This is a subheading</h2>
36+
<pre class="CodeRay">&lt;h2&gt;This text is preformatted and escaped&lt;/h2&gt;\n</pre>
37+
<pre class="CodeRay">This text is preformatted and ready to be <span class="tag">&lt;strong&gt;</span>syntax highlighted<span class="tag">&lt;/strong&gt;</span> as HTML source.</pre>
38+
</div>
39+
</div>
40+
HTML
41+
42+
assert_loosely_equal(main_html, expected)
43+
end
44+
end
45+

spec/spec_helper.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
require "wrong/adapters/rspec"
77
require "nokogiri"
88

9+
def assert_loosely_equal lhs, rhs
10+
assert { lhs.gsub(/\n\s*/, '') == rhs.gsub(/\n\s*/, '') }
11+
end
12+
913
require "files"
1014
include Files # todo: include this in an RSpec config block instead
1115

spec/step_spec.rb

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,6 @@
33

44
require "step_page"
55

6-
def assert_loosely_equal lhs, rhs
7-
assert { lhs.gsub(/\n\s*/, '') == rhs.gsub(/\n\s*/, '') }
8-
end
9-
106
describe Step do
117

128
def to_html nokogiri_node

0 commit comments

Comments
 (0)