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 +4 -0
- data/lib/syntax-on/bin.rb +173 -0
- data/lib/syntax-on/browser.rb +98 -0
- data/lib/syntax-on.rb +135 -0
- metadata +66 -0
data/bin/syntax-on
ADDED
@@ -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
|
+
|