Class: CodeHighlighter

Inherits:
Object
  • Object
show all
Defined in:
lib/highlight-code.rb

Constant Summary collapse

CODERAY_CSS_FILE_NAME =
"coderay.css"
HIGHLIGHTED_EXTENSION =
".highlighted.xhtml"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = { }) ⇒ CodeHighlighter

Returns a new instance of CodeHighlighter.



14
15
16
17
18
19
# File 'lib/highlight-code.rb', line 14

def initialize(options = { })
	self.code_nodes = Array.new
	self.output_file_path = nil
	self.options = options
	return self
end

Instance Attribute Details

#code_nodesObject

Returns the value of attribute code_nodes.



9
10
11
# File 'lib/highlight-code.rb', line 9

def code_nodes
  @code_nodes
end

#docObject

Returns the value of attribute doc.



9
10
11
# File 'lib/highlight-code.rb', line 9

def doc
  @doc
end

#optionsObject

Returns the value of attribute options.



9
10
11
# File 'lib/highlight-code.rb', line 9

def options
  @options
end

#output_file_pathObject

Returns the value of attribute output_file_path.



9
10
11
# File 'lib/highlight-code.rb', line 9

def output_file_path
  @output_file_path
end

Class Method Details

.highlight(path, options = { }) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/highlight-code.rb', line 27

def self.highlight(path, options = { })
	ch = CodeHighlighter.parse path, options
	return nil unless ch.doc
	
	begin
		ch.highlight
		ch.save
	rescue Object => ex
		puts "Cannot highlight #{path} due to: #{ex}"
	end
	
	@output_file_path
end

.parse(path, options = { }) ⇒ Object



21
22
23
24
25
# File 'lib/highlight-code.rb', line 21

def self.parse(path, options = { })
	ch = CodeHighlighter.new options
	ch.parse path
	ch
end

Instance Method Details

#highlightObject



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/highlight-code.rb', line 63

def highlight
	puts "Highlight with options: #{@options}"
	
	@code_nodes.each do | code_node |
		brush = code_node['class']
		brush_spec = brush ? brush.split(' ') : [ ]
		language_code = (brush_spec.count > 1) ? brush_spec.last : "N/A"
		
		if language_code != "N/A"
			puts "Found node #{language_code} #{code_node.text}"
			
			# Highlight the code 
			highlighted_code = CodeRay.scan(code_node.text.strip, language_code.to_sym).div(:css => :class, :tab_width => 4, :line_numbers => :inline)

			# Transform the pre node into a div
			code_node.name = "div"
			code_node['class'] = "code"
			code_node.content=  ''
			
			highlighted_code_node = Nokogiri::XML(highlighted_code)
			code_node.add_child highlighted_code_node.children.first
		else
			puts "Found unrecognizable language in source: #{code_node.text}"				
		end #if
	end #each
end

#include_cssObject

def



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/highlight-code.rb', line 90

def include_css
	code_ray_css_node = @doc.css("link[href*='" + CODERAY_CSS_FILE_NAME + "']")
	return unless code_ray_css_node.count == 0
	
	src_css_file_path	= File.dirname(__FILE__) + '/../resources/' + CODERAY_CSS_FILE_NAME

	dest_directory			= File.dirname(@path)
	css_path = @options[:csspath] || dest_directory
	dest_css_file_path	= dest_directory + '/' + CODERAY_CSS_FILE_NAME
	FileUtils.copy_file(src_css_file_path, dest_css_file_path)
	puts "Created the CSS file: #{dest_css_file_path}"
	
	code_ray_css_node = Nokogiri::XML::Node.new "link", @doc
	code_ray_css_node['rel'] = 'stylesheet'
	code_ray_css_node['type'] = 'text/css'
	code_ray_css_node['href'] = CODERAY_CSS_FILE_NAME
	
	head_node = @doc.css('head').first
	unless head_node
		head_node = Nokogiri::XML::Node.new "head", @doc
		body_node = @doc.css('body').first
		body_node.add_child head_node
	end
	
	head_node.add_child code_ray_css_node
	puts "Added CSS: #{code_ray_css_node}"
end

#parse(path) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/highlight-code.rb', line 41

def parse (path)
	begin
		# get the file contents
		@path = path
		puts "Parsing #{@path}"
		f = File.open(@path)
		
		# parse the file
		@doc = Nokogiri::XML(f)
		
		# find code/pre or both tag(s)
		tag = @options[:tag] || 'both'
		tag = 'code,pre' if tag == 'both'
		@code_nodes = doc.css(tag)
		puts "Found #{@code_nodes.length} nodes"
	rescue Object => ex
		puts "Cannot open #{path} due to: #{ex}"
	ensure
		f.close
	end
end

#saveObject



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/highlight-code.rb', line 118

def save
	include_css
	
	begin
		extension = @options[:extension] || HIGHLIGHTED_EXTENSION
		@output_file_path = @path + extension
		puts "Saving result to #{@output_file_path} ..."
		f = File.open(@output_file_path, "w")
		f.write(@doc.to_xhtml)
	rescue Object => ex
		puts "Cannot save the result to #{@path} due to: #{ex}"
	ensure
		f.close
	end
end