Skip to content

Commit 1f59ba7

Browse files
committed
Support and use Sunlight syntax highlighting.
1 parent e35fcee commit 1f59ba7

29 files changed

+564
-149
lines changed

ChangeLog

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
2011-04-16 Oren Ben-Kiki <[email protected]>
2+
3+
* Support and use Sunlight syntax highlighting.
4+
15
2011-04-12 Oren Ben-Kiki <[email protected]>
26

37
* Add chunk visibility control.

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Copyright (c) 2010 Oren Ben-Kiki
1+
Copyright (c) 2010-2011 Oren Ben-Kiki
22

33
Permission is hereby granted, free of charge, to any person obtaining a copy of
44
this software and associated documentation files (the "Software"), to deal in

Rakefile

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,9 @@ end
150150
def ruby_configurations(*additional_configurations)
151151
return [
152152
"classify_source_code:ruby",
153-
"format_code_gvim_css:ruby",
153+
"format_code_sunlight:ruby",
154154
"classify_nested_code:ruby:html",
155-
"format_code_gvim_css:html",
155+
"format_code_sunlight:html",
156156
"classify_shell_comments",
157157
"format_rdoc_comments"
158158
] + additional_configurations
@@ -161,7 +161,7 @@ end
161161
def javascript_configurations
162162
return [
163163
"classify_source_code:javascript",
164-
"format_code_gvim_css:javascript",
164+
"format_code_sunlight:javascript",
165165
"classify_c_comments",
166166
"format_markdown_comments"
167167
]
@@ -170,7 +170,7 @@ end
170170
def css_configurations
171171
return [
172172
"classify_source_code:css",
173-
"format_code_gvim_css:css",
173+
"format_code_sunlight:css",
174174
"classify_c_comments",
175175
"format_markdown_comments"
176176
]

doc/contents.js

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,29 +29,32 @@ function contents_header() {
2929
function contents_lists() {
3030
var container;
3131
var indices = [];
32-
foreach_h_element(function (h, level) {
32+
var h_elements = all_h_elements();
33+
for (var e in h_elements) {
34+
h = h_elements[e];
35+
var level = h.tagName.substring(1, 2) - 1;
3336
container = pop_container(container, indices, level);
3437
container = push_container(container, indices, level);
3538
var id = indices.join(".");
3639
container.appendChild(list_element(id, h));
3740
h.insertBefore(header_anchor(id), h.firstChild);
38-
});
41+
}
3942
return pop_container(container, indices, 1);
4043
}
4144

4245
/*
43-
* Apply a lambda to all H elements in the DOM. We skip the single H1 element;
46+
* Get a list of all H elements in the DOM. We skip the single H1 element;
4447
* otherwise it would just have the index "1" which would be prefixed to all
4548
* other headers.
4649
*/
47-
function foreach_h_element(lambda) {
50+
function all_h_elements() {
4851
var elements = document.getElementsByTagName("*");
52+
var h_elements = [];
4953
for (var e in elements) {
5054
var h = elements[e];
51-
if (!/^h[2-9]$/i.test(h.tagName)) continue;
52-
var level = h.tagName.substring(1, 2) - 1;
53-
lambda(h, level);
55+
if (/^h[2-9]$/i.test(h.tagName)) h_elements.push(h);
5456
}
57+
return h_elements;
5558
}
5659

5760
/*

doc/control_chunks.js

Lines changed: 44 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,44 @@
1-
/*
2-
* Quick-and-dirty JS for inserting a "+"/"-" control for chunk visibility next
3-
* to each chunk's name. By default, all chunks are hidden.
4-
*/
5-
function inject_chunk_controls() {
6-
var name_div;
7-
foreach_chunk_elements(function(div) {
8-
name_div = div;
9-
}, function(html_div) {
10-
var control_span = document.createElement("span");
11-
var hide = function() {
12-
control_span.innerHTML = "+";
13-
html_div.style.display = "none";
14-
}
15-
var show = function() {
16-
control_span.innerHTML = "&#8211;"; // Vertical bar.
17-
html_div.style.display = "block";
18-
}
19-
name_div.onclick = function() {
20-
html_div.style.display == "block" ? hide() : show();
21-
}
22-
hide(); // Initializes html_div.style.display
23-
control_span.className = "control chunk";
24-
name_div.insertBefore(control_span, name_div.firstChild);
25-
})
26-
}
27-
28-
/*
29-
* Loop on all DIV elements that contain a chunk name, or that contain chunk
30-
* HTML. Assumes that they come in pairs - name first, HTML second.
31-
*/
32-
function foreach_chunk_elements(name_lambda, html_lambda) {
33-
var div_elements = document.getElementsByTagName("div");
34-
for (var e in div_elements) {
35-
var div = div_elements[e];
36-
classes = " " + div.className + " ";
37-
if (!/ chunk /.test(classes)) continue;
38-
if (/ name /.test(classes)) name_lambda(div);
39-
if (/ html /.test(classes)) html_lambda(div);
40-
}
41-
}
42-
43-
/* Only invoke it after all helper functions are defined. */
44-
inject_chunk_controls();
1+
/*
2+
* Quick-and-dirty JS for inserting a "+"/"-" control for chunk visibility next
3+
* to each chunk's name. By default, all chunks are hidden.
4+
*/
5+
function inject_chunk_controls() {
6+
var name_div;
7+
foreach_chunk_elements(function(div) {
8+
name_div = div;
9+
}, function(html_div) {
10+
var control_span = document.createElement("span");
11+
var hide = function() {
12+
control_span.innerHTML = "+";
13+
html_div.style.display = "none";
14+
}
15+
var show = function() {
16+
control_span.innerHTML = "&#8211;"; // Vertical bar.
17+
html_div.style.display = "block";
18+
}
19+
name_div.onclick = function() {
20+
html_div.style.display == "block" ? hide() : show();
21+
}
22+
hide(); // Initializes html_div.style.display
23+
control_span.className = "control chunk";
24+
name_div.insertBefore(control_span, name_div.firstChild);
25+
})
26+
}
27+
28+
/*
29+
* Loop on all DIV elements that contain a chunk name, or that contain chunk
30+
* HTML. Assumes that they come in pairs - name first, HTML second.
31+
*/
32+
function foreach_chunk_elements(name_lambda, html_lambda) {
33+
var div_elements = document.getElementsByTagName("div");
34+
for (var e in div_elements) {
35+
var div = div_elements[e];
36+
classes = " " + div.className + " ";
37+
if (!/ chunk /.test(classes)) continue;
38+
if (/ name /.test(classes)) name_lambda(div);
39+
if (/ html /.test(classes)) html_lambda(div);
40+
}
41+
}
42+
43+
/* Only invoke it after all helper functions are defined. */
44+
inject_chunk_controls();

doc/root.html

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
55
<title>Code narrator - an inverse literate programming tool.</title>
66
<style type="text/css">
7-
<embed src="doc/reset.css" type="x-codnar/file"/>
8-
<embed src="doc/base.css" type="x-codnar/file"/>
7+
<embed src="yui/reset.css" type="x-codnar/file"/>
8+
<embed src="yui/base.css" type="x-codnar/file"/>
99
<embed src="doc/style.css" type="x-codnar/file"/>
10+
<embed src="sunlight/default.css" type="x-codnar/file"/>
1011
</style>
1112
</head>
1213
<body>
@@ -17,6 +18,12 @@
1718
<script type="text/javascript">
1819
<embed src="doc/contents.js" type="x-codnar/file"/>
1920
<embed src="doc/control_chunks.js" type="x-codnar/file"/>
21+
<embed src="sunlight/min.js" type="x-codnar/file"/>
22+
<embed src="sunlight/css-min.js" type="x-codnar/file"/>
23+
<embed src="sunlight/javascript-min.js" type="x-codnar/file"/>
24+
<embed src="sunlight/ruby-min.js" type="x-codnar/file"/>
25+
Sunlight.globalOptions.lineNumbers = false;
26+
Sunlight.highlightAll();
2027
</script>
2128
</body>
2229
</html>

doc/story.markdown

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,11 @@ narrative. Then, when you write the new code itself, it should be easy to
147147
connect it to the narrative at the appropriate point.
148148

149149
In the case of Code Narrator itself, the number of (raw) lines in the code
150-
itself is ~1800 lines, the number of test lines is ~1600 lines, while the
151-
number of narrative documentation lines is ~800 lines. Given narrative
152-
documentation are easier to write than system (or test) code, this indicates
153-
maintaining a narrative is not an unreasonable burden for a well-tested project.
150+
library itself is ~2100 lines, the number of test code lines is ~2200 lines,
151+
and the number of narrative documentation lines is only ~900 lines. Given
152+
narrative documentation are easier to write than system (or test) code, this
153+
indicates maintaining a narrative is not an unreasonable burden for a
154+
well-tested project.
154155

155156
### Code Narrator ###
156157

doc/style.css

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -72,35 +72,23 @@ table.layout td.html {
7272
background-color: Beige;
7373
}
7474

75-
span.Constant {
76-
color: Crimson;
77-
}
78-
span.Identifier {
79-
color: Teal;
80-
}
81-
span.PreProc {
82-
color: Indigo;
83-
}
84-
span.Special {
85-
color: Navy;
86-
}
87-
span.Statement {
88-
color: Maroon;
89-
}
90-
span.Type {
91-
color: Green;
92-
}
93-
span.Comment {
94-
color: Purple;
95-
}
75+
/* Colors for GVim classes */
76+
77+
span.Constant { color: Crimson; }
78+
span.Identifier { color: Teal; }
79+
span.PreProc { color: Indigo; }
80+
span.Special { color: Navy; }
81+
span.Statement { color: Maroon; }
82+
span.Type { color: Green; }
83+
span.Comment { color: Purple; }
9684

9785
/* Fonts */
9886

9987
body {
10088
font-family: Sans-Serif;
10189
}
10290
pre {
103-
font-family: Consolas, Monospace;
91+
font-family: Consolas, Inconsolata, Monaco, "Courier New", Monospace;
10492
}
10593
div.chunk.name {
10694
font-weight: bold;

doc/system.markdown

Lines changed: 52 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -243,12 +243,33 @@ scope; almost any language you can think of has a `gvim` syntax highlighting
243243
definition. Here is a simple test that demonstrates using `gvim` for syntax
244244
highlighting:
245245

246-
[[test/highlight_syntax.rb|named_chunk_with_containers]]
246+
[[test/gvim_highlight_syntax.rb|named_chunk_with_containers]]
247247

248248
And here is the implementation:
249249

250250
[[lib/codnar/gvim.rb|named_chunk_with_containers]]
251251

252+
#### Syntax highlighting using Sunlight ####
253+
254+
[Sunlight](http://sunlightjs.com/) offers a different approach for syntax
255+
highlighting. Instead of pre-processing the code to generate highlighted HTML
256+
while splitting, it provides Javascript files that examine the textual code in
257+
the DOM and convert it to highlighted HTML in the browser. This takes virtually
258+
no time when splitting the code, but requires recomputing highlighting for all
259+
the code chunks every time the HTML file is loaded. This can be pretty slow,
260+
especially if using a browser with a slow Javascript engine, like IE. However,
261+
given how slow GVIM is, this is a reasonable trade-off, at least for small
262+
projects. Since Sunlight is a new project, it doesn't offer the extensive
263+
coverage of different programming languages supported by GVIM.
264+
265+
Here is a simple test that demonstrates using Sunlight for syntax highlighting:
266+
267+
[[test/sunlight_highlight_syntax.rb|named_chunk_with_containers]]
268+
269+
And here is the implementation:
270+
271+
[[lib/codnar/sunlight.rb|named_chunk_with_containers]]
272+
252273
### Putting it all together ###
253274

254275
Now that we have all the separate pieces of functionality for splitting source
@@ -282,8 +303,7 @@ are also supported for code comments. Here is a simple test that demonstrates
282303
The splitting mechanism defined above is pretty generic. To apply it to a
283304
specific system requires providing the appropriate configuration. The system
284305
provides a few specific built-in configurations which may be useful "out of the
285-
box". Currently, these built-in configurations are focused on documenting Ruby
286-
code and GVim.
306+
box".
287307

288308
If one is willing to give up altogether on syntax highlighting and comment
289309
formatting, the system would be applicable as-is to any programming language.
@@ -393,16 +413,27 @@ Here is a simple test demonstrating formatting comment contents:
393413

394414
[[test/format_comment_configurations.rb|named_chunk_with_containers]]
395415

396-
#### Syntax highlighting ####
416+
#### Syntax highlighting using GVim ####
397417

398418
Supporting a specific programming language (other than dealing with comments)
399419
is very easy using GVim for syntax highlighting, as demonstrated here:
400420

401-
[[Syntax highlighting formatting configurations|named_chunk_with_containers]]
421+
[[GVim syntax highlighting formatting configurations|named_chunk_with_containers]]
422+
423+
Here is a simple test demonstrating highlighting code syntax using `gvim`:
402424

403-
Here is a simple test demonstrating highlighting code syntax:
425+
[[test/format_code_gvim_configurations.rb|named_chunk_with_containers]]
404426

405-
[[test/format_code_configurations.rb|named_chunk_with_containers]]
427+
#### Syntax highlighting using Sunlight ####
428+
429+
For small projects in languages supported by Sunlight, you may choose to use
430+
it instead of GVIM
431+
432+
[[Sunlight syntax highlighting formatting configurations|named_chunk_with_containers]]
433+
434+
Here is a simple test demonstrating highlighting code syntax using Sunlight:
435+
436+
[[test/format_code_sunlight_configurations.rb|named_chunk_with_containers]]
406437

407438
#### Chunk splitting ####
408439

@@ -673,23 +704,22 @@ iunjecting a table of content into the generated HTML.
673704

674705
[[doc/contents.js|named_chunk_with_containers]]
675706

676-
### CSS files ###
707+
### CSS style ###
677708

678709
To avoid dealing with the different default styles used by different browsers,
679-
we employ the YUI CSS [reset](http://developer.yahoo.com/yui/reset/) file:
710+
we employ the YUI CSS [reset](http://developer.yahoo.com/yui/reset/) and
711+
[base](http://developer.yahoo.com/yui/base/) files. Resetting and restoring the
712+
default CSS styles is inelegant, but it is the only current way to get a
713+
consistent presentation of HTML. Once this is out of the way, we apply styles
714+
specific to our HTML. Some of these override the default styles established by
715+
the base CSS file above. We do this instead of directly tweaking the base CSS
716+
file, to allow easy upgrade to new versions if/when YUI release any.
680717

681-
[[doc/reset.css|named_chunk_with_containers]]
682-
683-
This requires us to restore the default look and feel of the standard HTML
684-
elements, using the YUI [base](http://developer.yahoo.com/yui/base/) CSS style
685-
file. Resetting and restoring the default CSS styles is inelegant, but it is
686-
the only current way to get a consistent presentation of HTML.
687-
688-
[[doc/base.css|named_chunk_with_containers]]
718+
[[doc/style.css|named_chunk_with_containers]]
689719

690-
Finally, we can apply styles specific to our HTML. Some of these override the
691-
default styles established by the base CSS file above. We do this instead of
692-
directly tweaking the base CSS file, to allow easy upgrade to new versions
693-
if/when YUI release any.
720+
### Using Sunlight ###
694721

695-
[[doc/style.css|named_chunk_with_containers]]
722+
When using Sunlight for syntax highlighting, we also need to include some CSS
723+
and Javascript files to convert the classified `pre` elements into properly
724+
marked-up HTML. We also need to invoke this Javascript code (a one-line
725+
operations). See the last few lines of the `doc/root.html` file for details.

lib/codnar.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
require "codnar/reader"
2727
require "codnar/scanner"
2828
require "codnar/splitter"
29+
require "codnar/sunlight"
2930
require "codnar/weave"
3031
require "codnar/weaver"
3132
require "codnar/writer"

0 commit comments

Comments
 (0)