syntax-on 0.1.12

Sign up to get free protection for your applications and to get access to all the features.
data/bin/syntax-on ADDED
@@ -0,0 +1,4 @@
1
+ #! /usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../lib/syntax-on'
3
+ require 'syntax-on/bin'
4
+ SyntaxOn::Bin.new( ARGV ).run
@@ -0,0 +1,173 @@
1
+ require 'optparse'
2
+ require 'simplecli'
3
+
4
+ class SyntaxOn::Bin
5
+ include SimpleCLI
6
+
7
+ def usage *args
8
+ puts <<doco
9
+
10
+ syntax-on == %{ vim-based syntax highlighing }
11
+
12
+ Usage:
13
+ syntax-on -h/--help [Not Implemented Yet]
14
+ syntax-on -v/--version [Not Implemented Yet]
15
+ syntax-on command [options]
16
+
17
+ Examples:
18
+ syntax-on highlight my-file.rb
19
+
20
+ Further help:
21
+ syntax-on commands # list all available commands
22
+ syntax-on help <COMMAND> # show help for COMMAND
23
+ syntax-on help # show this help message
24
+
25
+ doco
26
+ end
27
+
28
+ def themes_help
29
+ <<doco
30
+ Usage: #{ script_name } themes [OPTIONS] [THEME]
31
+
32
+ Options:
33
+ -l, --list List all available themes
34
+ -p, --path Print out the THEME_PATH directories
35
+ -c, --cat Cat (show) a theme
36
+ -n, --names Print out the names of available themes
37
+
38
+ Arguments:
39
+ THEME A theme name, eg. 'default'
40
+
41
+ Summary:
42
+ Command for managing #{ script_name } themes
43
+ end
44
+ doco
45
+ end
46
+ def themes *args
47
+ options = {}
48
+ opts = OptionParser.new do |opts|
49
+ opts.on('-l','--list'){ options[:list] = true }
50
+ opts.on('-p','--path'){ options[:path] = true }
51
+ opts.on('-c','--cat'){ options[:cat] = true }
52
+ opts.on('-n','--names'){ options[:names] = true }
53
+ end
54
+ opts.parse! args
55
+
56
+ theme = args.last
57
+
58
+ puts SyntaxOn::themes.sort.join("\n") if options[:list]
59
+ puts SyntaxOn::theme_directories.join("\n") if options[:path]
60
+ puts SyntaxOn::theme_names.join("\n") if options[:names]
61
+ puts SyntaxOn::theme(theme) if options[:cat] and theme
62
+ end
63
+
64
+ def browser_help
65
+ <<doco
66
+ Usage: #{ script_name } server [DIRECTORY]
67
+
68
+ Options:
69
+ -P, --port Port to run on
70
+ -p, --preview Preview browser in Firefox
71
+
72
+ Arguments:
73
+ DIRECTORY Root directory to browse
74
+
75
+ Requires gems: thin
76
+
77
+ Summary:
78
+ Starts a web server to browse syntax highlighted
79
+ files in the current directory
80
+ doco
81
+ end
82
+ def browser *args
83
+ begin
84
+ require 'thin'
85
+ rescue
86
+ puts "Please install the 'thin' gem to run `#{script_name} server`" ; exit
87
+ end
88
+
89
+ options = { :port => 6789 }
90
+ opts = OptionParser.new do |opts|
91
+ opts.on('-P','--port [PORT]'){ |port| options[:port] = port }
92
+ opts.on('-p','--preview'){ options[:preview] = true }
93
+ end
94
+ opts.parse! args
95
+ dir = args.last
96
+
97
+ Thread.new { sleep 1 ; system(SyntaxOn::PREVIEW_COMMAND.call("http://localhost:#{ options[:port] }")) } if options[:preview]
98
+
99
+ require 'syntax-on/browser'
100
+ Thin::Server.start('0.0.0.0', options[:port].to_i) do
101
+ use Rack::CommonLogger
102
+ use Rack::ShowExceptions
103
+ run SyntaxOn::Browser.new(dir)
104
+ end
105
+ end
106
+
107
+ def highlight_help
108
+ <<doco
109
+ Usage: #{ script_name } highlight [OPTIONS] FILE
110
+
111
+ Options:
112
+ -p, --preview Preview file in Firefox
113
+ -t, --theme THEME Theme to use (default 'remi')
114
+ -s, --syntax SYNTAX Specify syntax to use
115
+ -o, --output FILE Specify name of file to create,
116
+ output is echoed if -o STDOUT
117
+ -c, --code CODE Specify code to use in place of
118
+ a file (also checks STDIN)
119
+ -b,--bash EXPERIMENTAL: use a new bash session
120
+ for vim (requires 'session' gem)
121
+
122
+ Arguments:
123
+ FILE Name of the file to highlight
124
+
125
+ Summary:
126
+ Create a syntax highlighted HTML file
127
+ doco
128
+ end
129
+ def highlight *args
130
+ options = { :theme => :remi }
131
+ opts = OptionParser.new do |opts|
132
+ opts.on('-p','--preview'){ options[:preview] = true }
133
+ opts.on('-t','--theme [THEME]'){ |theme| options[:theme] = theme }
134
+ opts.on('-s','--syntax [SYNTAX]'){ |syntax| options[:syntax] = syntax }
135
+ opts.on('-o','--output [FILE]'){ |file| options[:output] = file }
136
+ opts.on('-c','--code [CODE]'){ |code| options[:code] = (code.nil? ? STDIN.readlines.join('') : code) }
137
+ opts.on('-b','--bash'){ options[:bash] = true }
138
+ end
139
+ opts.parse! args
140
+ file = args.last
141
+ out = File.expand_path( options[:output] || "#{ file }.html" )
142
+
143
+ if options[:code] or ( file and File.file? file )
144
+ css = SyntaxOn::theme options[:theme]
145
+ html = SyntaxOn.new( options[:code], :syntax => options[:syntax], :file => file, :use_session => options[:bash] ).to_html
146
+ html = <<HTML
147
+ <html>
148
+ <head>
149
+ <style type="text/css">
150
+ <!--#{ css }-->
151
+ </style>
152
+ </head>
153
+ <body>
154
+ <pre>
155
+ #{ html }
156
+ </pre>
157
+ </body>
158
+ </html>
159
+ HTML
160
+ unless options[:output] == 'STDOUT'
161
+ File.open(out, 'w') do |f|
162
+ f << html
163
+ end
164
+ system(SyntaxOn::PREVIEW_COMMAND.call(out)) if options[:preview]
165
+ else
166
+ puts html
167
+ end
168
+ else
169
+ help :highlight
170
+ end
171
+ end
172
+
173
+ end
@@ -0,0 +1,98 @@
1
+ class SyntaxOn::Browser
2
+
3
+ attr_accessor :request, :response, :current_theme
4
+
5
+ def initialize directory = '.'
6
+ @directory = directory || '.'
7
+ end
8
+
9
+ def call env
10
+ @pwd = Dir.pwd
11
+ Dir.chdir @directory
12
+
13
+ @response = Rack::Response.new
14
+ @request = Rack::Request.new env
15
+
16
+ @current_theme ||= 'remi' # set default theme to 'remi'
17
+ @current_theme = request['theme'] if request['theme'] and SyntaxOn.theme_names.include? request['theme']
18
+
19
+ if request.path_info[/^\/styles\/(.*)\.css$/]
20
+ response['Content-Type'] = 'text/css'
21
+ response.body = SyntaxOn::theme request.path_info.match(/^\/styles\/(.*)\.css$/)[1]
22
+ else
23
+ response.body = response_for env
24
+ end
25
+
26
+ Dir.chdir @pwd
27
+
28
+ response.finish
29
+ end
30
+
31
+ def response_for env
32
+ path = env['PATH_INFO'].sub '/',''
33
+
34
+ if File.file? path
35
+ code_layout SyntaxOn.new( nil, :file => path ).to_html
36
+ else
37
+ code_layout
38
+ end
39
+ end
40
+
41
+ def file_list
42
+ '<ul>' + Dir['**/*'].map { |file_or_dir| %{<li><a href="/#{file_or_dir}">#{file_or_dir}</a></li>} }.join + '</ul>'
43
+ end
44
+
45
+ def line_number_switcher_link
46
+ <<HTML
47
+ <a href="#" onclick="javascript:for each(var span in document.getElementsByClassName('lnr')){ (span.style.display == 'none') ? span.style.display = 'inline' : span.style.display = 'none'; }">toggle line numbers</a>
48
+ HTML
49
+ end
50
+
51
+ def line_number_remover
52
+ <<HTML
53
+ <a href="#" onclick="javascript:var num_line_numbers = document.getElementsByClassName('lnr').length; for(var i=0; i<num_line_numbers; i++){ document.getElementsByTagName('pre')[0].removeChild( document.getElementsByClassName('lnr')[0] ); }">remove line numbers (for copying)</a>
54
+ HTML
55
+ end
56
+
57
+ def theme_selector
58
+ <<HTML
59
+ <select id="theme-selector" onchange="javascript:window.location = window.location.toString().replace(/\\?.*/,'') + '?theme=' + document.getElementById('theme-selector').value">
60
+ <option>... select a theme ...</option>
61
+ #{ SyntaxOn::theme_names.map { |theme| "<option>#{theme}</option>" } }
62
+ </select>
63
+ HTML
64
+ end
65
+
66
+ def code_layout code = ''
67
+ <<HTML
68
+ <html>
69
+ <head>
70
+ <script src="http://jquery.com/src/jquery-latest.js" type="text/javascript"></script>
71
+ <style type="text/css">
72
+ <!--
73
+ select { position: absolute; top: 5px; right: 5px; }
74
+ -->
75
+ </style>
76
+ <link rel="stylesheet" href="/styles/#{ current_theme }.css" type="text/css" />
77
+ <head>
78
+ <body>
79
+ <h1>#{ @request.path_info }</h1>
80
+ #{ theme_selector }
81
+ #{ line_number_switcher_link }
82
+ #{ line_number_remover }
83
+ <hr />
84
+ <pre>
85
+ #{ code }
86
+ </pre>
87
+ <hr />
88
+ #{ file_list }
89
+ </body>
90
+ </html>
91
+ HTML
92
+ end
93
+
94
+ def css # need to fix this ... can't seem to find the theme directory when running in thin ...
95
+ SyntaxOn::theme :murphy
96
+ end
97
+
98
+ end
data/lib/syntax-on.rb ADDED
@@ -0,0 +1,135 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+
3
+ require 'rubygems'
4
+ require 'fileutils'
5
+
6
+ class Array
7
+ def to_vim_args
8
+ self.map{ |option| %{+"#{ option.gsub('"',"'") }"} }.join ' '
9
+ end
10
+ end
11
+
12
+ class SyntaxOn
13
+
14
+ VIM_BIN = 'vim'
15
+ VIM_OPTIONS = [ "syntax on", "let html_use_css = 1", 'let html_use_encoding = "utf8"', "let use_xhtml = 1" ]
16
+ VIM_RENDER = [ "exe 'normal zR'", "runtime\\! syntax/2html.vim", "wq", "q" ]
17
+ TEMP_DIRECTORY = '/tmp/syntax-on'
18
+ TEMP_FILENAME = lambda { Time.now.strftime '%Y-%d-%m_%Hh-%Mm-%Ss' }
19
+ THEME_PATH = [ '~/.syntaxon/themes' ]
20
+ PREVIEW_COMMAND = lambda { |file| (Gem::Platform.local.os == 'darwin') ? "open -a Firefox '#{file}'" : "firefox '#{file}' &" }
21
+
22
+ attr_accessor :code, :syntax
23
+
24
+ def initialize code_or_options, options = nil
25
+ if code_or_options.is_a?(String)
26
+ options ||= {}
27
+ options[:code] = code_or_options
28
+ else
29
+ options = code_or_options
30
+ end
31
+
32
+ options[:syntax] ||= nil
33
+
34
+ if options[:file] and File.file? options[:file]
35
+ @file = options[:file]
36
+ @code = File.read @file
37
+ end
38
+
39
+ @line_numbers = options[:line_numbers].nil? ? true : options[:line_numbers]
40
+
41
+ @code = options[:code] if @code.nil? and options[:code]
42
+
43
+ @syntax = options[:syntax]
44
+ @use_session = options[:use_session]
45
+ end
46
+
47
+ def to_html options = { :line_numbers => @line_numbers }
48
+ setup_temp_dir
49
+ create_temp_file
50
+ setup_vim_options options
51
+ render
52
+ @html = File.read(@html_file).match(/<pre>(.*)<\/pre>/m)[1].strip
53
+ finish
54
+ end
55
+
56
+ def self.themes
57
+ theme_directories.inject([]){ |all,this| all + Dir[File.join(File.expand_path(this), '*.css')] }
58
+ end
59
+
60
+ def self.theme_names
61
+ themes.map { |theme| File.basename(theme).sub(/\.css$/,'') }.uniq.sort
62
+ end
63
+
64
+ def self.theme name = :remi
65
+ File.read themes.find { |theme| File.basename(theme).downcase == "#{ name }.css".downcase }
66
+ end
67
+
68
+ def self.theme_directory
69
+ File.expand_path( File.join( File.dirname(__FILE__), "/../themes/" ))
70
+ end
71
+
72
+ def self.theme_directories
73
+ SyntaxOn::THEME_PATH << self.theme_directory
74
+ end
75
+
76
+ # add to class, as well, so it can be accessed by THEME_PATH constant
77
+ class << self
78
+ def self.theme_directory
79
+ File.expand_path( File.join( File.dirname(__FILE__), "/../themes/" ))
80
+ end
81
+ end
82
+
83
+ private
84
+
85
+ def finish
86
+ FileUtils.cd @pwd
87
+ @html
88
+ end
89
+
90
+ def setup_temp_dir
91
+ @pwd = FileUtils.pwd
92
+ FileUtils.mkdir_p TEMP_DIRECTORY
93
+ FileUtils.cd TEMP_DIRECTORY
94
+ end
95
+
96
+ def create_temp_file
97
+ @filename = File.join TEMP_DIRECTORY, TEMP_FILENAME.call
98
+ @filename << "_#{ File.basename @file }" if @file
99
+ File.open(@filename, 'w'){|f| f << @code }
100
+ end
101
+
102
+ def setup_vim_options options = {}
103
+ @options = VIM_OPTIONS.clone
104
+ @options << "setfiletype #{ @syntax.to_s }" if @syntax
105
+ (options[:line_numbers]) ? @options << 'set number' : @options << 'set nonumber'
106
+ end
107
+
108
+ def command_string
109
+ "#{ VIM_BIN } #{ @options.to_vim_args } #{ VIM_RENDER.to_vim_args } #{ @filename } 2>/dev/null"
110
+ end
111
+
112
+ def render
113
+ if @use_session
114
+ require 'session'
115
+ puts "using Session"
116
+ bash = Session::Bash.new
117
+ bash.execute "cd '#{ TEMP_DIRECTORY }'"
118
+ puts "cd'd to directory ..."
119
+ bash.execute command_string, :stdout => STDOUT, :stderr => STDERR
120
+ # @output, @error = bash.execute command_string
121
+ puts "ran command string ... should return now ..."
122
+ else
123
+ @output = `#{ command_string }`
124
+ end
125
+ @html_file = "#{ @filename }.html"
126
+ end
127
+
128
+ end
129
+
130
+ rc = File.expand_path '~/.syntaxonrc'
131
+ eval File.read(rc) if File.file? rc
132
+
133
+ unless `which #{ SyntaxOn::VIM_BIN }`.strip =~ /^\/(.*)#{ SyntaxOn::VIM_BIN }$/
134
+ puts "SyntaxOn WARNING: VIM_BIN[#{ SyntaxOn::VIM_BIN.inspect }] not found in PATH"
135
+ end
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: syntax-on
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.12
5
+ platform: ruby
6
+ authors:
7
+ - remi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-01-14 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: simplecli
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ description: Syntax-on is a library/cli/website for highlighting source by automating vim
26
+ email: remi@remitaylor.com
27
+ executables:
28
+ - syntax-on
29
+ extensions: []
30
+
31
+ extra_rdoc_files: []
32
+
33
+ files:
34
+ - lib/syntax-on/browser.rb
35
+ - lib/syntax-on/bin.rb
36
+ - lib/syntax-on.rb
37
+ has_rdoc: true
38
+ homepage: http://github.com/remi/syntax-on
39
+ licenses: []
40
+
41
+ post_install_message:
42
+ rdoc_options: []
43
+
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: "0"
51
+ version:
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ requirements: []
59
+
60
+ rubyforge_project:
61
+ rubygems_version: 1.3.5
62
+ signing_key:
63
+ specification_version: 3
64
+ summary: vim-based syntax highlighting
65
+ test_files: []
66
+