highlight-code 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+ gem "nokogiri"
3
+ gem "coderay"
@@ -0,0 +1,12 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ coderay (1.0.5)
5
+ nokogiri (1.5.0-x86-mingw32)
6
+
7
+ PLATFORMS
8
+ x86-mingw32
9
+
10
+ DEPENDENCIES
11
+ coderay
12
+ nokogiri
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Philippe Monnet, http://blog.monnet-usa.com/
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,32 @@
1
+ ## highlight-code ##
2
+
3
+ ### Rationale ###
4
+ When I write blog posts and tutorials I include many code samples and apply syntax highlighting to increase readability. For that I use Alex Gorbatchev's excellent [SyntaxHighlighter](http://alexgorbatchev.com/SyntaxHighlighter/) Javascript library. But if I am interested in creating eBooks the challenge is to maintain the highlighting. Since the markup needs to be all inclusive, I need a "pre-processor" to take my markup and apply syntax highlighting so that the final XHTML can be used for the eBook.
5
+
6
+ highlight-code is a small Ruby utility which will take a XHTML document as input and apply syntax highlighting and save the resulting XHTML in an output file.
7
+
8
+ ### Why a new library? ###
9
+ Actually this is really a command line utility built "on the shoulders of giants", i.e. [Nokogiri](http://nokogiri.org/) and [CodeRay](http://coderay.rubychan.de/). "They" do the heavy lift, I am just assembling them into a utility to help me apply syntax highlighting to XHTML markup containing code samples (in pre/code tags).
10
+
11
+ ### Installation ###
12
+
13
+ gem install highlight-code
14
+
15
+ ### Simple Usage ###
16
+
17
+ highligh-code test.xhtml
18
+
19
+ ### Syntax ###
20
+
21
+ highlight-code XHTMLFILEPATH [OPTIONS]
22
+
23
+ XHTMLFILEPATH: The .xhtml file containing the code to highlight
24
+
25
+ OPTIONS:
26
+ -c, --css-path PATH/TO/CSS/FILES path for the coderay.css (default same location as the input file)
27
+ -e, --extension EXTENSION extension for the processed / output file (default: .highlighted.xhtml)
28
+ -t, --tag TAG type of tag (pre or code) containing the code to highlight
29
+ (note: the css class must follow the syntax: brush: language, e.g. brush: ruby)
30
+ (default: both)
31
+ -h, --help help
32
+
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1 @@
1
+ #!/usr/bin/env ruby
2
  opt.banner = "Usage: highlight-code XHTMLFILEPATH [OPTIONS]"
1
3
  opt.separator ""
2
4
  opt.separator "XHTMLFILEPATH: The .xhtml file containing the code to highlight"
3
5
  opt.separator ""
4
6
  opt.separator "Options"
5
7
 
6
8
  opt.on("-c","--css-path PATH/TO/CSS/FILES","path for the coderay.css (default same location as the input file)") do | csspath |
7
9
  options[:csspath] = csspath
8
10
  end
9
11
 
10
12
  opt.on("-e","--extension EXTENSION","extension for the processed / output file (default: .highlighted.xhtml)") do | extension |
11
13
  options[:extension] = extension
12
14
  end
13
15
  opt.on("-t","--tag TAG",
14
16
  options[:tag] = tag
15
17
  end
16
18
 
17
19
  opt.on("-h","--help","help") do
18
20
  puts opt_parser
19
21
  end
@@ -0,0 +1,11 @@
1
+ ## README ##
2
+
3
+ cd examples
4
+ highlight-code test.xhtml
5
+
6
+ This should produce 2 files:
7
+
8
+ * test.xhtml.highlighted.xhtml - the markup has been processed and your code and pre tags have been replaced by divs with styling
9
+ * coderay.css - the basic CSS needed to render the highlighting
10
+
11
+ You should be able to view test.xhtml.highlighted.xhtml in a browser.
@@ -0,0 +1,38 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"[]>
3
+ <html>
4
+ <head>
5
+ <link rel="stylesheet" type="text/css" href="custom.css" />
6
+ <title>Creating Rich Interactive Web Applications With KnockoutJS</title>
7
+ </head>
8
+ <body>
9
+
10
+ <p>This is an example of HTML code:</p>
11
+ <pre class="brush: html">
12
+ &lt;div id='test'&gt;
13
+ &lt;span&gt;Hello&lt;/span&gt;
14
+ &lt;/div&gt;
15
+ </pre>
16
+
17
+ <p>This is an example of Javascript code:</p>
18
+ <code class="brush: javascript">
19
+ function doThis(parm1) {
20
+ return parm1;
21
+ }
22
+ </code>
23
+
24
+ <p>This is an example of Ruby code:</p>
25
+ <code class="brush: ruby">
26
+ def do_this(parm1)
27
+ parm1
28
+ end
29
+ </code>
30
+
31
+ <p>This is an example of unknown code (to be left alone):</p>
32
+ <pre>
33
+ declare doThis(string parm1)
34
+ parm1
35
+ end
36
+ </pre>
37
+ </body>
38
+ </html>
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "highlight-code/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "highlight-code"
7
+ s.version = HighlightCode::VERSION
8
+ s.authors = ["Philippe Monnet"]
9
+ s.email = ["techarch@monnet-usa.com"]
10
+ s.homepage = "http://blog.monnet-usa.com/"
11
+ s.summary = %q{highlight-code is a small Ruby utility which will take a XHTML document as input and apply syntax highlighting and save the resulting XHTML in an output file.}
12
+ s.description = <<-EOF
13
+ highlight-code will help you post-process an XHTML document containing code examples in pre or code tags so that the code is highlighted. The pre and code tags need to follow the class conventions from Alex Gorbatchev's SyntaxHighlighter (http://alexgorbatchev.com/SyntaxHighlighter/) Javascript library. The resulting file can be used for an eBook.
14
+ EOF
15
+ s.licenses = ['MIT']
16
+ s.rubyforge_project = "highlight-code"
17
+
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
+ s.require_paths = ["lib"]
22
+
23
+ s.required_ruby_version = '>= 1.9.1'
24
+ # specify any dependencies here; for example:
25
+ s.add_runtime_dependency "nokogiri"
26
+ s.add_runtime_dependency "coderay"
27
+ end
@@ -0,0 +1,135 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
3
+
4
+ require 'FileUtils'
5
+ require 'nokogiri'
6
+ require 'coderay'
7
+
8
+ class CodeHighlighter
9
+ attr_accessor :doc, :code_nodes, :output_file_path, :options
10
+
11
+ CODERAY_CSS_FILE_NAME = "coderay.css"
12
+ HIGHLIGHTED_EXTENSION = ".highlighted.xhtml"
13
+
14
+ def initialize(options = { })
15
+ self.code_nodes = Array.new
16
+ self.output_file_path = nil
17
+ self.options = options
18
+ return self
19
+ end
20
+
21
+ def self.parse(path, options = { })
22
+ ch = CodeHighlighter.new options
23
+ ch.parse path
24
+ ch
25
+ end
26
+
27
+ def self.highlight(path, options = { })
28
+ ch = CodeHighlighter.parse path, options
29
+ return nil unless ch.doc
30
+
31
+ begin
32
+ ch.highlight
33
+ ch.save
34
+ rescue Object => ex
35
+ puts "Cannot highlight #{path} due to: #{ex}"
36
+ end
37
+
38
+ @output_file_path
39
+ end
40
+
41
+ def parse (path)
42
+ begin
43
+ # get the file contents
44
+ @path = path
45
+ puts "Parsing #{@path}"
46
+ f = File.open(@path)
47
+
48
+ # parse the file
49
+ @doc = Nokogiri::XML(f)
50
+
51
+ # find code/pre or both tag(s)
52
+ tag = @options[:tag] || 'both'
53
+ tag = 'code,pre' if tag == 'both'
54
+ @code_nodes = doc.css(tag)
55
+ puts "Found #{@code_nodes.length} nodes"
56
+ rescue Object => ex
57
+ puts "Cannot open #{path} due to: #{ex}"
58
+ ensure
59
+ f.close
60
+ end
61
+ end
62
+
63
+ def highlight
64
+ puts "Highlight with options: #{@options}"
65
+
66
+ @code_nodes.each do | code_node |
67
+ brush = code_node['class']
68
+ brush_spec = brush ? brush.split(' ') : [ ]
69
+ language_code = (brush_spec.count > 1) ? brush_spec.last : "N/A"
70
+
71
+ if language_code != "N/A"
72
+ puts "Found node #{language_code} #{code_node.text}"
73
+
74
+ # Highlight the code
75
+ highlighted_code = CodeRay.scan(code_node.text.strip, language_code.to_sym).div(:css => :class, :tab_width => 4, :line_numbers => :inline)
76
+
77
+ # Transform the pre node into a div
78
+ code_node.name = "div"
79
+ code_node['class'] = "code"
80
+ code_node.content= ''
81
+
82
+ highlighted_code_node = Nokogiri::XML(highlighted_code)
83
+ code_node.add_child highlighted_code_node.children.first
84
+ else
85
+ puts "Found unrecognizable language in source: #{code_node.text}"
86
+ end #if
87
+ end #each
88
+ end #def
89
+
90
+ def include_css
91
+ code_ray_css_node = @doc.css("link[href*='" + CODERAY_CSS_FILE_NAME + "']")
92
+ return unless code_ray_css_node.count == 0
93
+
94
+ src_css_file_path = File.dirname(__FILE__) + '/../resources/' + CODERAY_CSS_FILE_NAME
95
+
96
+ dest_directory = File.dirname(@path)
97
+ css_path = @options[:csspath] || dest_directory
98
+ dest_css_file_path = dest_directory + '/' + CODERAY_CSS_FILE_NAME
99
+ FileUtils.copy_file(src_css_file_path, dest_css_file_path)
100
+ puts "Created the CSS file: #{dest_css_file_path}"
101
+
102
+ code_ray_css_node = Nokogiri::XML::Node.new "link", @doc
103
+ code_ray_css_node['rel'] = 'stylesheet'
104
+ code_ray_css_node['type'] = 'text/css'
105
+ code_ray_css_node['href'] = CODERAY_CSS_FILE_NAME
106
+
107
+ head_node = @doc.css('head').first
108
+ unless head_node
109
+ head_node = Nokogiri::XML::Node.new "head", @doc
110
+ body_node = @doc.css('body').first
111
+ body_node.add_child head_node
112
+ end
113
+
114
+ head_node.add_child code_ray_css_node
115
+ puts "Added CSS: #{code_ray_css_node}"
116
+ end
117
+
118
+ def save
119
+ include_css
120
+
121
+ begin
122
+ extension = @options[:extension] || HIGHLIGHTED_EXTENSION
123
+ @output_file_path = @path + extension
124
+ puts "Saving result to #{@output_file_path} ..."
125
+ f = File.open(@output_file_path, "w")
126
+ f.write(@doc.to_xhtml)
127
+ rescue Object => ex
128
+ puts "Cannot save the result to #{@path} due to: #{ex}"
129
+ ensure
130
+ f.close
131
+ end
132
+ end
133
+
134
+ end #class
135
+
@@ -0,0 +1,3 @@
1
+ module HighlightCode
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,120 @@
1
+ .CodeRay {
2
+ background-color: hsl(0,0%,95%);
3
+ border: 1px solid silver;
4
+ color: black;
5
+ }
6
+ .CodeRay pre {
7
+ margin: 0px;
8
+ }
9
+
10
+ span.CodeRay { white-space: pre; border: 0px; padding: 2px; }
11
+
12
+ table.CodeRay { border-collapse: collapse; width: 100%; padding: 2px; }
13
+ table.CodeRay td { padding: 2px 4px; vertical-align: top; }
14
+
15
+ .CodeRay .line-numbers {
16
+ background-color: hsl(180,65%,90%);
17
+ color: gray;
18
+ text-align: right;
19
+ -webkit-user-select: none;
20
+ -moz-user-select: none;
21
+ user-select: none;
22
+ }
23
+ .CodeRay .line-numbers a {
24
+ background-color: hsl(180,65%,90%) !important;
25
+ color: gray !important;
26
+ text-decoration: none !important;
27
+ }
28
+ .CodeRay .line-numbers a:target { color: blue !important; }
29
+ .CodeRay .line-numbers .highlighted { color: red !important; }
30
+ .CodeRay .line-numbers .highlighted a { color: red !important; }
31
+ .CodeRay span.line-numbers { padding: 0px 4px; }
32
+ .CodeRay .line { display: block; float: left; width: 100%; }
33
+ .CodeRay .code { width: 100%; }
34
+
35
+ .CodeRay .debug { color: white !important; background: blue !important; }
36
+
37
+ .CodeRay .annotation { color:#007 }
38
+ .CodeRay .attribute-name { color:#b48 }
39
+ .CodeRay .attribute-value { color:#700 }
40
+ .CodeRay .binary { color:#509 }
41
+ .CodeRay .char .content { color:#D20 }
42
+ .CodeRay .char .delimiter { color:#710 }
43
+ .CodeRay .char { color:#D20 }
44
+ .CodeRay .class { color:#B06; font-weight:bold }
45
+ .CodeRay .class-variable { color:#369 }
46
+ .CodeRay .color { color:#0A0 }
47
+ .CodeRay .comment { color:#777 }
48
+ .CodeRay .comment .char { color:#444 }
49
+ .CodeRay .comment .delimiter { color:#444 }
50
+ .CodeRay .complex { color:#A08 }
51
+ .CodeRay .constant { color:#036; font-weight:bold }
52
+ .CodeRay .decorator { color:#B0B }
53
+ .CodeRay .definition { color:#099; font-weight:bold }
54
+ .CodeRay .delimiter { color:black }
55
+ .CodeRay .directive { color:#088; font-weight:bold }
56
+ .CodeRay .doc { color:#970 }
57
+ .CodeRay .doc-string { color:#D42; font-weight:bold }
58
+ .CodeRay .doctype { color:#34b }
59
+ .CodeRay .entity { color:#800; font-weight:bold }
60
+ .CodeRay .error { color:#F00; background-color:#FAA }
61
+ .CodeRay .escape { color:#666 }
62
+ .CodeRay .exception { color:#C00; font-weight:bold }
63
+ .CodeRay .float { color:#60E }
64
+ .CodeRay .function { color:#06B; font-weight:bold }
65
+ .CodeRay .global-variable { color:#d70 }
66
+ .CodeRay .hex { color:#02b }
67
+ .CodeRay .imaginary { color:#f00 }
68
+ .CodeRay .include { color:#B44; font-weight:bold }
69
+ .CodeRay .inline { background-color: hsla(0,0%,0%,0.07); color: black }
70
+ .CodeRay .inline-delimiter { font-weight: bold; color: #666 }
71
+ .CodeRay .instance-variable { color:#33B }
72
+ .CodeRay .integer { color:#00D }
73
+ .CodeRay .key .char { color: #60f }
74
+ .CodeRay .key .delimiter { color: #404 }
75
+ .CodeRay .key { color: #606 }
76
+ .CodeRay .keyword { color:#080; font-weight:bold }
77
+ .CodeRay .label { color:#970; font-weight:bold }
78
+ .CodeRay .local-variable { color:#963 }
79
+ .CodeRay .namespace { color:#707; font-weight:bold }
80
+ .CodeRay .octal { color:#40E }
81
+ .CodeRay .operator { }
82
+ .CodeRay .predefined { color:#369; font-weight:bold }
83
+ .CodeRay .predefined-constant { color:#069 }
84
+ .CodeRay .predefined-type { color:#0a5; font-weight:bold }
85
+ .CodeRay .preprocessor { color:#579 }
86
+ .CodeRay .pseudo-class { color:#00C; font-weight:bold }
87
+ .CodeRay .regexp .content { color:#808 }
88
+ .CodeRay .regexp .delimiter { color:#404 }
89
+ .CodeRay .regexp .modifier { color:#C2C }
90
+ .CodeRay .regexp { background-color:hsla(300,100%,50%,0.06); }
91
+ .CodeRay .reserved { color:#080; font-weight:bold }
92
+ .CodeRay .shell .content { color:#2B2 }
93
+ .CodeRay .shell .delimiter { color:#161 }
94
+ .CodeRay .shell { background-color:hsla(120,100%,50%,0.06); }
95
+ .CodeRay .string .char { color: #b0b }
96
+ .CodeRay .string .content { color: #D20 }
97
+ .CodeRay .string .delimiter { color: #710 }
98
+ .CodeRay .string .modifier { color: #E40 }
99
+ .CodeRay .string { background-color:hsla(0,100%,50%,0.05); }
100
+ .CodeRay .symbol .content { color:#A60 }
101
+ .CodeRay .symbol .delimiter { color:#630 }
102
+ .CodeRay .symbol { color:#A60 }
103
+ .CodeRay .tag { color:#070 }
104
+ .CodeRay .type { color:#339; font-weight:bold }
105
+ .CodeRay .value { color: #088; }
106
+ .CodeRay .variable { color:#037 }
107
+
108
+ .CodeRay .insert { background: hsla(120,100%,50%,0.12) }
109
+ .CodeRay .delete { background: hsla(0,100%,50%,0.12) }
110
+ .CodeRay .change { color: #bbf; background: #007; }
111
+ .CodeRay .head { color: #f8f; background: #505 }
112
+ .CodeRay .head .filename { color: white; }
113
+
114
+ .CodeRay .delete .eyecatcher { background-color: hsla(0,100%,50%,0.2); border: 1px solid hsla(0,100%,45%,0.5); margin: -1px; border-bottom: none; border-top-left-radius: 5px; border-top-right-radius: 5px; }
115
+ .CodeRay .insert .eyecatcher { background-color: hsla(120,100%,50%,0.2); border: 1px solid hsla(120,100%,25%,0.5); margin: -1px; border-top: none; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; }
116
+
117
+ .CodeRay .insert .insert { color: #0c0; background:transparent; font-weight:bold }
118
+ .CodeRay .delete .delete { color: #c00; background:transparent; font-weight:bold }
119
+ .CodeRay .change .change { color: #88f }
120
+ .CodeRay .head .head { color: #f4f }
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: highlight-code
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Philippe Monnet
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-01-16 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: nokogiri
16
+ requirement: &9329364 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *9329364
25
+ - !ruby/object:Gem::Dependency
26
+ name: coderay
27
+ requirement: &9381516 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *9381516
36
+ description: ! " highlight-code will help you post-process an XHTML document containing
37
+ code examples in pre or code tags so that the code is highlighted. The pre and code
38
+ tags need to follow the class conventions from Alex Gorbatchev's SyntaxHighlighter
39
+ (http://alexgorbatchev.com/SyntaxHighlighter/) Javascript library. The resulting
40
+ file can be used for an eBook. \n"
41
+ email:
42
+ - techarch@monnet-usa.com
43
+ executables:
44
+ - highlight-code
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - Gemfile
49
+ - Gemfile.lock
50
+ - MIT-LICENSE
51
+ - README.md
52
+ - Rakefile
53
+ - bin/highlight-code
54
+ - examples/README.md
55
+ - examples/test.xhtml
56
+ - highlight-code.gemspec
57
+ - lib/highlight-code.rb
58
+ - lib/highlight-code/version.rb
59
+ - resources/coderay.css
60
+ homepage: http://blog.monnet-usa.com/
61
+ licenses:
62
+ - MIT
63
+ post_install_message:
64
+ rdoc_options: []
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ! '>='
71
+ - !ruby/object:Gem::Version
72
+ version: 1.9.1
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubyforge_project: highlight-code
81
+ rubygems_version: 1.8.15
82
+ signing_key:
83
+ specification_version: 3
84
+ summary: highlight-code is a small Ruby utility which will take a XHTML document as
85
+ input and apply syntax highlighting and save the resulting XHTML in an output file.
86
+ test_files: []