black 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +2 -0
- data/README.md +74 -0
- data/Rakefile +23 -0
- data/black.gemspec +23 -0
- data/lib/black.rb +13 -0
- data/lib/black/diff.rb +137 -0
- data/lib/black/git.rb +134 -0
- data/lib/black/html_view.rb +68 -0
- data/lib/black/preview.rb +52 -0
- data/lib/black/stylesheets.rb +35 -0
- data/lib/black/templates/diff.html.erb +22 -0
- data/lib/black/templates/stylesheets/diff.css.scss +432 -0
- data/lib/black/templates/stylesheets/syntax.css.scss +109 -0
- data/lib/black/version.rb +3 -0
- metadata +86 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 99eecfa085e6ccf657becb02d58d2f9f212681ee
|
4
|
+
data.tar.gz: 8a6ee0cfd842e8ea2ec590a8216fca0392d389eb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a5403f9ffed1ee25bc0da3cc94359bc336b5a8b936ec10b32392662c8b40044896d623753dd8727603b73728abe86f6cce8645c3667fa83cacc803b079a267ae
|
7
|
+
data.tar.gz: d5c9c561ac12a0d2e2913d2e908960bf849b1e8de0d1330d01e2e53b8f70a72f6cce6992b3fec0c6535fb0f30475e7890a64871cf661798e1bab2511009fd7a0
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
## Black
|
2
|
+
|
3
|
+
Black parses diff output from `diff` and `git diff` and provides an enumerable ruby interface for lines and metadata.
|
4
|
+
|
5
|
+
Black uses this diff interface to render a syntax-highlighted diff view in HTML.
|
6
|
+
|
7
|
+
## Status
|
8
|
+
|
9
|
+
Black isn't documented yet.
|
10
|
+
|
11
|
+
I'm getting this out for those who are compfortable diving into the source and getting some initial value from it.
|
12
|
+
|
13
|
+
Consider this a work in progress.
|
14
|
+
|
15
|
+
## Usage
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
diff = Black::Diff.new('older string', 'newer string', 'file-name.html')
|
19
|
+
output = Black::HTMLView.render(diff: diff)
|
20
|
+
```
|
21
|
+
|
22
|
+
The filename determines how the content will be highlighted.
|
23
|
+
|
24
|
+
The output is HTML only. To output the css:
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
css = Black::Stylesheets.css({ style: :compressed })
|
28
|
+
```
|
29
|
+
|
30
|
+
Black uses sass, so all options are passed right into sass options. Have a look at `Black::Stylesheets` for more info.
|
31
|
+
|
32
|
+
## Version
|
33
|
+
|
34
|
+
**0.0.1** - Please consider the API alpha and unstable.
|
35
|
+
|
36
|
+
Black adheres to [Semantic Versioning](http://semver.org/)
|
37
|
+
|
38
|
+
## Dependencies
|
39
|
+
|
40
|
+
1. [rouge](https://github.com/jneen/rouge) for syntax highlighting
|
41
|
+
1. [sass](http://sass-lang.com/) for stylesheet management
|
42
|
+
|
43
|
+
|
44
|
+
## Rubies
|
45
|
+
|
46
|
+
Tested with ruby 1.9.3+
|
47
|
+
|
48
|
+
ruby 1.8.x not supported
|
49
|
+
|
50
|
+
## Platforms
|
51
|
+
|
52
|
+
This only supports unix-based systems at the moment.
|
53
|
+
|
54
|
+
But the shell execution is wrapped like so:
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
# Black::Diff.execute()
|
58
|
+
def self.execute(*command_args)
|
59
|
+
`diff #{ command_args.join(' ') }`
|
60
|
+
end
|
61
|
+
```
|
62
|
+
|
63
|
+
So you can reimplement this method to suit your own platform needs:
|
64
|
+
```ruby
|
65
|
+
class Black::Diff
|
66
|
+
def self.execute(*command_args)
|
67
|
+
# do some custom stuff
|
68
|
+
end
|
69
|
+
end
|
70
|
+
```
|
71
|
+
|
72
|
+
## License
|
73
|
+
|
74
|
+
[MIT](http://www.opensource.org/licenses/mit-license.html)
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), *%w[lib]))
|
2
|
+
require 'rubygems'
|
3
|
+
require 'rake'
|
4
|
+
require 'bundler'
|
5
|
+
require 'black/version'
|
6
|
+
|
7
|
+
name = Dir['*.gemspec'].first.split('.').first
|
8
|
+
gemspec_file = "#{name}.gemspec"
|
9
|
+
gem_file = "#{name}-#{ Black::VERSION }.gem"
|
10
|
+
|
11
|
+
task :release => :build do
|
12
|
+
sh "git commit --allow-empty -m 'Release #{Black::VERSION}'"
|
13
|
+
sh "git tag v#{Black::VERSION}"
|
14
|
+
sh "git push origin master --tags"
|
15
|
+
sh "git push origin v#{Black::VERSION}"
|
16
|
+
sh "gem push pkg/#{name}-#{Black::VERSION}.gem"
|
17
|
+
end
|
18
|
+
|
19
|
+
task :build do
|
20
|
+
sh "mkdir -p pkg"
|
21
|
+
sh "gem build #{ gemspec_file }"
|
22
|
+
sh "mv #{ gem_file } pkg"
|
23
|
+
end
|
data/black.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
$LOAD_PATH.unshift 'lib'
|
2
|
+
require 'black/version'
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "black"
|
6
|
+
s.version = Black::Version
|
7
|
+
s.date = Time.now.strftime('%Y-%m-%d')
|
8
|
+
s.license = "http://www.opensource.org/licenses/MIT"
|
9
|
+
s.summary = 'Black parses diff output to render a syntax-highlighted diff view in HTML'
|
10
|
+
s.homepage = "https://github.com/plusjade/black"
|
11
|
+
s.email = "plusjade@gmail.com"
|
12
|
+
s.authors = ['Jade Dominguez']
|
13
|
+
s.description = 'Black parses diff output to render a syntax-highlighted diff view in HTML'
|
14
|
+
|
15
|
+
s.add_dependency 'rouge', "~> 1"
|
16
|
+
s.add_dependency 'sass', "~> 3"
|
17
|
+
|
18
|
+
s.files = `git ls-files`.
|
19
|
+
split("\n").
|
20
|
+
sort.
|
21
|
+
reject { |file| file =~ /^(\.|rdoc|pkg|coverage)/ }
|
22
|
+
end
|
23
|
+
|
data/lib/black.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
Encoding.default_internal = 'UTF-8'
|
3
|
+
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
module Black
|
7
|
+
Root = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
8
|
+
def self.root ; Root ; end
|
9
|
+
end
|
10
|
+
|
11
|
+
FileUtils.cd(path = File.join(File.dirname(__FILE__), 'black')) do
|
12
|
+
Dir[File.join('**', '*.rb')].each { |f| require File.join(path, f) }
|
13
|
+
end
|
data/lib/black/diff.rb
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
module Black
|
2
|
+
class Diff
|
3
|
+
# wrapper to execute `diff` in the shell.
|
4
|
+
# Reimplement this to suit your own platform needs
|
5
|
+
def self.execute(*command_args)
|
6
|
+
`diff #{ command_args.join(' ') }`
|
7
|
+
end
|
8
|
+
|
9
|
+
include Enumerable
|
10
|
+
|
11
|
+
attr_reader :older, :newer, :filename
|
12
|
+
|
13
|
+
def initialize(older, newer, filename=nil)
|
14
|
+
@older = older
|
15
|
+
@newer = newer
|
16
|
+
@filename = filename
|
17
|
+
end
|
18
|
+
|
19
|
+
def each
|
20
|
+
if block_given?
|
21
|
+
diff_parsed.each do |line|
|
22
|
+
yield line
|
23
|
+
end
|
24
|
+
else
|
25
|
+
diff_parsed.enum_for(:each)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# diff two strings using unix 'diff' command
|
30
|
+
def execute
|
31
|
+
files = [Tempfile.new('black'), Tempfile.new('black')]
|
32
|
+
files.first.write(@older)
|
33
|
+
files.last.write(@newer)
|
34
|
+
files.each { |a| a.read }
|
35
|
+
|
36
|
+
args = [files.first.path, files.last.path] + OutputParser.diff_options
|
37
|
+
|
38
|
+
Diff.execute(args)
|
39
|
+
ensure
|
40
|
+
files.each do |file|
|
41
|
+
if file && File.exist?(file.path)
|
42
|
+
file.close
|
43
|
+
file.unlink
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def diff_parsed
|
49
|
+
OutputParser.parse(execute.enum_for(:lines))
|
50
|
+
end
|
51
|
+
|
52
|
+
module OutputParser
|
53
|
+
# `diff` command arguments to format the output
|
54
|
+
def self.diff_options
|
55
|
+
%w(-u)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Parse the diff output
|
59
|
+
def self.parse(diff_enumerator)
|
60
|
+
Enumerator.new do |y|
|
61
|
+
index = 0
|
62
|
+
old_line_number = 1
|
63
|
+
new_line_number = 1
|
64
|
+
|
65
|
+
diff_enumerator.each do |line|
|
66
|
+
type = identify_type(line)
|
67
|
+
next if type == 'file-header'
|
68
|
+
|
69
|
+
if type == "metadata"
|
70
|
+
old_line_number = line.match(/\-[0-9]*/)[0].to_i.abs rescue 0
|
71
|
+
new_line_number = line.match(/\+[0-9]*/)[0].to_i.abs rescue 0
|
72
|
+
end
|
73
|
+
|
74
|
+
d = {
|
75
|
+
"type" => type,
|
76
|
+
"index" => index,
|
77
|
+
"old_line_number" => old_line_number,
|
78
|
+
"new_line_number" => new_line_number,
|
79
|
+
"content" => line
|
80
|
+
}
|
81
|
+
|
82
|
+
y.yield Line.new(d)
|
83
|
+
|
84
|
+
index += 1
|
85
|
+
new_line_number += 1 if %w(addition unchanged).include?(type)
|
86
|
+
old_line_number += 1 if %w(deletion unchanged).include?(type)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def self.identify_type(line)
|
92
|
+
if line.start_with?('---', '+++')
|
93
|
+
"file-header"
|
94
|
+
elsif line[0] == "+"
|
95
|
+
"addition"
|
96
|
+
elsif line[0] == "-"
|
97
|
+
"deletion"
|
98
|
+
elsif line.match(/^@@ -/)
|
99
|
+
"metadata"
|
100
|
+
else
|
101
|
+
"unchanged"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# Nicer line API for views
|
107
|
+
class Line
|
108
|
+
def initialize(line)
|
109
|
+
@line = line
|
110
|
+
end
|
111
|
+
|
112
|
+
def changed?
|
113
|
+
['addition', 'deletion'].include? @line['type']
|
114
|
+
end
|
115
|
+
|
116
|
+
def deletion?
|
117
|
+
type == 'deletion'
|
118
|
+
end
|
119
|
+
|
120
|
+
def content
|
121
|
+
@content ||= @line['content'].slice(/^.{1}/, @line['content'].length)
|
122
|
+
end
|
123
|
+
|
124
|
+
def type
|
125
|
+
@line['type']
|
126
|
+
end
|
127
|
+
|
128
|
+
def new_line_number
|
129
|
+
type == 'deletion' ? nil : @line['new_line_number']
|
130
|
+
end
|
131
|
+
|
132
|
+
def old_line_number
|
133
|
+
type == 'addition' ? nil : @line['old_line_number']
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
data/lib/black/git.rb
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
require './diff'
|
2
|
+
|
3
|
+
module Black
|
4
|
+
module Git
|
5
|
+
# wrapper to execute git in the shell.
|
6
|
+
# Reimplement this to suit your own platform needs
|
7
|
+
def self.execute(path, *command_args)
|
8
|
+
FileUtils.cd(path) do
|
9
|
+
return `git #{ command_args.join(' ') } --no-color`
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Repository
|
14
|
+
def initialize(path)
|
15
|
+
unless File.directory?(path)
|
16
|
+
raise "#{ path } is not a valid directory"
|
17
|
+
end
|
18
|
+
|
19
|
+
@path = path
|
20
|
+
end
|
21
|
+
|
22
|
+
def commits
|
23
|
+
Enumerator.new do |y|
|
24
|
+
commits_dict.each_key do |index|
|
25
|
+
y.yield commit_at(index)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Return a diff object for each file in the given commit
|
31
|
+
def commit_at(index_or_sha)
|
32
|
+
if index_or_sha.is_a?(Integer)
|
33
|
+
index = index_or_sha
|
34
|
+
sha = commits_dict[index_or_sha]
|
35
|
+
else
|
36
|
+
index = commits_dict.key(index_or_sha)
|
37
|
+
sha = index_or_sha
|
38
|
+
end
|
39
|
+
sha_prev = commits_dict[index-1]
|
40
|
+
output = diff_output(sha)
|
41
|
+
|
42
|
+
commands = %w(diff-tree --no-commit-id --name-status -r)
|
43
|
+
commands.push('--root') if index.zero?
|
44
|
+
commands.push(sha)
|
45
|
+
|
46
|
+
Black::Git
|
47
|
+
.execute(@path, commands)
|
48
|
+
.lines
|
49
|
+
.map
|
50
|
+
.with_index do |line, i|
|
51
|
+
status, filename = line.split(/\s+/)
|
52
|
+
status = status.chomp
|
53
|
+
filename = filename.chomp
|
54
|
+
|
55
|
+
Black::Git::Diff.new(@path, sha, sha_prev, output[i], filename, status)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Store a lookup dictionary for all commits
|
60
|
+
def commits_dict
|
61
|
+
return @commits_dict if @commits_dict
|
62
|
+
|
63
|
+
@commits_dict = {}
|
64
|
+
Black::Git
|
65
|
+
.execute(@path, %w(rev-list HEAD --reverse))
|
66
|
+
.each_line
|
67
|
+
.with_index{ |a, i| @commits_dict[i] = a.chomp }
|
68
|
+
|
69
|
+
@commits_dict
|
70
|
+
end
|
71
|
+
|
72
|
+
# Get diff output on all files in each commit rather than one file at a time.
|
73
|
+
def diff_output(sha)
|
74
|
+
output = []
|
75
|
+
marker = 0
|
76
|
+
|
77
|
+
Black::Git
|
78
|
+
.execute(@path, %w(show --format='%b' --no-prefix -U1000).push(sha))
|
79
|
+
.each_line do |line|
|
80
|
+
if line.start_with?('diff --git')
|
81
|
+
marker += 1
|
82
|
+
else
|
83
|
+
if output[marker]
|
84
|
+
output[marker] += line
|
85
|
+
else
|
86
|
+
output[marker] = line
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# there are two empty lines at the top of the git show output
|
92
|
+
output.shift
|
93
|
+
output
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
class Diff
|
98
|
+
include Enumerable
|
99
|
+
|
100
|
+
attr_reader :older, :newer, :filename, :status
|
101
|
+
|
102
|
+
def initialize(path, sha, sha_previous, diff_output, filename, status)
|
103
|
+
@path = path
|
104
|
+
@sha = sha
|
105
|
+
@sha_previous = sha_previous
|
106
|
+
@diff_output = diff_output
|
107
|
+
@filename = filename
|
108
|
+
@status = status
|
109
|
+
end
|
110
|
+
|
111
|
+
def each
|
112
|
+
if block_given?
|
113
|
+
diff_parsed.each do |line|
|
114
|
+
yield line
|
115
|
+
end
|
116
|
+
else
|
117
|
+
diff_parsed.enum_for(:each)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def newer
|
122
|
+
@newer ||= Black::Git.execute(@path, "show", "#{ @sha }:#{ @filename }")
|
123
|
+
end
|
124
|
+
|
125
|
+
def older
|
126
|
+
@older ||= Black::Git.execute(@path, "show", "#{ @sha_prev }:#{ @filename }")
|
127
|
+
end
|
128
|
+
|
129
|
+
def diff_parsed
|
130
|
+
Black::Diff::OutputParser.parse(@diff_output.enum_for(:lines))
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'rouge'
|
3
|
+
|
4
|
+
module Black
|
5
|
+
module HTMLView
|
6
|
+
DefaultData = {
|
7
|
+
template_path: File.join(::Black.root, 'lib/black/templates/diff.html.erb'),
|
8
|
+
}
|
9
|
+
|
10
|
+
def self.render(data={})
|
11
|
+
data = DefaultData.merge(data)
|
12
|
+
context = Context.new(data)
|
13
|
+
template = File.read(data[:template_path])
|
14
|
+
ERB.new(template).result(context.get_binding)
|
15
|
+
end
|
16
|
+
|
17
|
+
class Context
|
18
|
+
def initialize(data)
|
19
|
+
data.each do |name, value|
|
20
|
+
self.class.class_eval do
|
21
|
+
define_method(name) { value }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# return syntax-highlighted version of the line
|
27
|
+
def highlight(line)
|
28
|
+
line.deletion? ?
|
29
|
+
older[line.old_line_number-1] :
|
30
|
+
newer[line.new_line_number-1]
|
31
|
+
end
|
32
|
+
|
33
|
+
def content
|
34
|
+
@content ||= rogueify(diff.newer)
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
def get_binding
|
39
|
+
binding
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
# The source needs to be syntax-highlighted as a whole because it
|
45
|
+
# can have multiple syntax types e.g. index.html contains HTML/CSS/JS.
|
46
|
+
# highlighting lines one-by-one misses the context and doesn't work.
|
47
|
+
#
|
48
|
+
# Both older and newer sources are highlighted. The diffed line in question
|
49
|
+
# then references its old/new line number to grab the correct syntax-highlighted line.
|
50
|
+
|
51
|
+
# Collection of syntax-highlighted lines from older source
|
52
|
+
def older
|
53
|
+
@older ||= rogueify(diff.older).lines.to_a
|
54
|
+
end
|
55
|
+
|
56
|
+
# Collection of syntax-highlighted lines from newer source
|
57
|
+
def newer
|
58
|
+
@newer ||= rogueify(diff.newer).lines.to_a
|
59
|
+
end
|
60
|
+
|
61
|
+
def rogueify(source)
|
62
|
+
lexer = Rouge::Lexer.guess({ filename: diff.filename, source: source })
|
63
|
+
formatter = Rouge::Formatters::HTML.new(wrap: false)
|
64
|
+
formatter.format(lexer.new.lex(source))
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
module Black
|
4
|
+
# rack compatable preview generator
|
5
|
+
# Usage:
|
6
|
+
# Create a new rack application
|
7
|
+
# in config.ru:
|
8
|
+
# require 'rack'
|
9
|
+
# require 'black'
|
10
|
+
#
|
11
|
+
# diff = Black::Diff.new('older string', 'newer string', 'file-name.html')
|
12
|
+
# content = Black::HTMLView.render(diff: diff)
|
13
|
+
# run Black::Preview.new(content)
|
14
|
+
# Then run the rack app:
|
15
|
+
# $ rackup config.ru
|
16
|
+
class Preview
|
17
|
+
Template = <<-TEXT
|
18
|
+
<!doctype html>
|
19
|
+
<html>
|
20
|
+
<head>
|
21
|
+
<style>
|
22
|
+
html, body { margin: 0; padding: 0; }
|
23
|
+
<%= css %>
|
24
|
+
</style>
|
25
|
+
</head>
|
26
|
+
<body>
|
27
|
+
<%= content %>
|
28
|
+
</body>
|
29
|
+
</html>
|
30
|
+
TEXT
|
31
|
+
|
32
|
+
def initialize(content, css=nil)
|
33
|
+
@css = css
|
34
|
+
@content = content
|
35
|
+
end
|
36
|
+
|
37
|
+
def call(env)
|
38
|
+
@css ||= Black::Stylesheets.css({ style: :compressed })
|
39
|
+
|
40
|
+
context = Context.new(@content, @css)
|
41
|
+
output = ::ERB.new(Template).result(context.get_binding)
|
42
|
+
|
43
|
+
[200, {'Content-Type' => 'text/html'}, [output]]
|
44
|
+
end
|
45
|
+
|
46
|
+
class Context < Struct.new(:content, :css)
|
47
|
+
def get_binding
|
48
|
+
binding
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'sass'
|
2
|
+
|
3
|
+
module Black
|
4
|
+
module Stylesheets
|
5
|
+
SyntaxStylesheet = File.join(::Black.root, 'lib/black/templates/stylesheets/syntax.css.scss')
|
6
|
+
DiffStylesheet = File.join(::Black.root, 'lib/black/templates/stylesheets/diff.css.scss')
|
7
|
+
DefaultOptions = {
|
8
|
+
syntax: :scss
|
9
|
+
}
|
10
|
+
|
11
|
+
def self.css(options={})
|
12
|
+
template = File.open(DiffStylesheet).read
|
13
|
+
template += File.open(SyntaxStylesheet).read
|
14
|
+
|
15
|
+
render(template, options)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.syntax(options={})
|
19
|
+
template = File.open(SyntaxStylesheet).read
|
20
|
+
render(template, options)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.diff(options={})
|
24
|
+
template = File.open(SyntaxStylesheet).read
|
25
|
+
render(template, options)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def self.render(template, options={})
|
31
|
+
engine = Sass::Engine.new(template, DefaultOptions.merge(options))
|
32
|
+
engine.render
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<div class="diff-file">
|
2
|
+
<div class="diff-header">
|
3
|
+
<strong><%= diff.filename %></strong>
|
4
|
+
</div>
|
5
|
+
<div class="diff-content">
|
6
|
+
<table class="text-file">
|
7
|
+
<% diff.each do |line| %>
|
8
|
+
<% next if line.type == 'metadata' %>
|
9
|
+
<tr class="line_holder <%= line.type %>">
|
10
|
+
<td class="old_line" data-lnum="<%= line.old_line_number %>"></td>
|
11
|
+
<td class="new_line" data-lnum="<%= line.new_line_number %>"></td>
|
12
|
+
<td class="line_content">
|
13
|
+
<% if line.changed? %>
|
14
|
+
<i class="state"></i>
|
15
|
+
<% end %>
|
16
|
+
<pre class="highlight"><code><%= highlight(line) %></code></pre>
|
17
|
+
</td>
|
18
|
+
</tr>
|
19
|
+
<% end %>
|
20
|
+
</table>
|
21
|
+
</div>
|
22
|
+
</div>
|
@@ -0,0 +1,432 @@
|
|
1
|
+
// Lifted from: https://github.com/gitlabhq/gitlabhq/blob/master/app/assets/stylesheets/sections/diff.scss
|
2
|
+
// Contains edits.
|
3
|
+
$monospace_font : 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;
|
4
|
+
$boder-color: #212121;
|
5
|
+
$deleted : red; // not used
|
6
|
+
$added : green; // not used
|
7
|
+
$old-background-color: #FDD;
|
8
|
+
$new-background-color: #CFD;
|
9
|
+
$code-holder-background-color: #212121;
|
10
|
+
$dark-bg-color: #212121;
|
11
|
+
$lighter-bg-color: #272822;
|
12
|
+
|
13
|
+
.diff-file {
|
14
|
+
margin-bottom: 1em;
|
15
|
+
position: relative;
|
16
|
+
textarea.file-content {
|
17
|
+
display: none;
|
18
|
+
width: 99%;
|
19
|
+
height: 95%;
|
20
|
+
max-height: 500px;
|
21
|
+
position: absolute;
|
22
|
+
top: 30px;
|
23
|
+
background-color: #333;
|
24
|
+
color: #ccc;
|
25
|
+
font-family: $monospace_font;
|
26
|
+
border:1px solid #000;
|
27
|
+
}
|
28
|
+
|
29
|
+
.diff-header {
|
30
|
+
position: relative;
|
31
|
+
padding: 5px 10px;
|
32
|
+
color: #9e9e9e;
|
33
|
+
background-color: $dark-bg-color;
|
34
|
+
> strong {
|
35
|
+
font-family: $monospace_font;
|
36
|
+
font-weight: normal;
|
37
|
+
}
|
38
|
+
.diff-btn-group {
|
39
|
+
float: right;
|
40
|
+
|
41
|
+
.btn {
|
42
|
+
background-color: #EEE;
|
43
|
+
color: #666;
|
44
|
+
font-weight: bolder;
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
.commit-short-id {
|
49
|
+
font-family: $monospace_font;
|
50
|
+
font-size: smaller;
|
51
|
+
}
|
52
|
+
|
53
|
+
.file-mode {
|
54
|
+
font-family: $monospace_font;
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
.diff-content {
|
59
|
+
border: 1px solid $boder-color;
|
60
|
+
border-top: 0;
|
61
|
+
overflow: auto;
|
62
|
+
overflow-y: hidden;
|
63
|
+
background: #212121;
|
64
|
+
color: #616161;
|
65
|
+
font-size: 14px;
|
66
|
+
.old {
|
67
|
+
span.idiff {
|
68
|
+
background-color: #FAA;
|
69
|
+
}
|
70
|
+
}
|
71
|
+
.new {
|
72
|
+
span.idiff {
|
73
|
+
background-color: #AFA;
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
table {
|
78
|
+
width: 100%;
|
79
|
+
font-family: $monospace_font;
|
80
|
+
border: none;
|
81
|
+
margin: 0px;
|
82
|
+
padding: 0px;
|
83
|
+
border-collapse: collapse;
|
84
|
+
tr {
|
85
|
+
td {
|
86
|
+
line-height: 20px;
|
87
|
+
font-size: 14px;
|
88
|
+
background-color: $code-holder-background-color;
|
89
|
+
pre {
|
90
|
+
background-color: $code-holder-background-color;
|
91
|
+
}
|
92
|
+
}
|
93
|
+
&.context {
|
94
|
+
td {
|
95
|
+
//opacity: 0.8;
|
96
|
+
}
|
97
|
+
}
|
98
|
+
&.addition {
|
99
|
+
td {
|
100
|
+
background-color: rgba(0, 200, 83, 0.09);
|
101
|
+
pre {
|
102
|
+
background-color: transparent;
|
103
|
+
}
|
104
|
+
i.state:before {
|
105
|
+
font-style: normal;
|
106
|
+
content: "+";
|
107
|
+
color: #4CAF50;
|
108
|
+
}
|
109
|
+
}
|
110
|
+
}
|
111
|
+
&.deletion {
|
112
|
+
td {
|
113
|
+
background-color: rgba(244, 67, 54, 0.09);
|
114
|
+
pre {
|
115
|
+
background-color: transparent;
|
116
|
+
}
|
117
|
+
i:before {
|
118
|
+
font-style: normal;
|
119
|
+
content: "-";
|
120
|
+
color: #F44336;
|
121
|
+
}
|
122
|
+
}
|
123
|
+
}
|
124
|
+
&:hover {
|
125
|
+
td {
|
126
|
+
background-color: rgba(255, 255, 255, 0.02);
|
127
|
+
pre {
|
128
|
+
background-color: rgba(255, 255, 255, 0.02);
|
129
|
+
}
|
130
|
+
}
|
131
|
+
}
|
132
|
+
}
|
133
|
+
}
|
134
|
+
|
135
|
+
.text-file-parallel div {
|
136
|
+
display: inline-block;
|
137
|
+
padding-bottom: 16px;
|
138
|
+
}
|
139
|
+
.diff-side {
|
140
|
+
overflow-x: scroll;
|
141
|
+
width: 508px;
|
142
|
+
height: 700px;
|
143
|
+
}
|
144
|
+
.diff-side.diff-side-left{
|
145
|
+
overflow-y:hidden;
|
146
|
+
}
|
147
|
+
.diff-side table, td.diff-middle table {
|
148
|
+
height: 700px;
|
149
|
+
}
|
150
|
+
.diff-middle {
|
151
|
+
width: 114px;
|
152
|
+
vertical-align: top;
|
153
|
+
height: 700px;
|
154
|
+
overflow: hidden
|
155
|
+
}
|
156
|
+
.old_line:before, .new_line:before {
|
157
|
+
content: attr(data-lnum);
|
158
|
+
}
|
159
|
+
.old_line, .new_line, .diff_line {
|
160
|
+
margin: 0px;
|
161
|
+
padding: 0px;
|
162
|
+
border: none;
|
163
|
+
padding: 0px 5px;
|
164
|
+
border-right: 1px solid #212121;
|
165
|
+
color: #505050;
|
166
|
+
//background-color: #212121;
|
167
|
+
text-align: right;
|
168
|
+
min-width: 35px;
|
169
|
+
max-width: 50px;
|
170
|
+
width: 35px;
|
171
|
+
font-family: Consolas, "Liberation Mono", Courier, monospace;
|
172
|
+
a {
|
173
|
+
float: left;
|
174
|
+
width: 35px;
|
175
|
+
font-weight: normal;
|
176
|
+
color: #666;
|
177
|
+
&:hover {
|
178
|
+
text-decoration: underline;
|
179
|
+
}
|
180
|
+
}
|
181
|
+
&.new {
|
182
|
+
//background: $new-background-color;
|
183
|
+
color: green;
|
184
|
+
}
|
185
|
+
&.old {
|
186
|
+
background: $old-background-color;
|
187
|
+
}
|
188
|
+
}
|
189
|
+
.diff_line {
|
190
|
+
padding: 0;
|
191
|
+
}
|
192
|
+
.line_holder {
|
193
|
+
&.old .old_line,
|
194
|
+
&.old .new_line {
|
195
|
+
background: #FCC;
|
196
|
+
border-color: #E7BABA;
|
197
|
+
}
|
198
|
+
&.new .old_line,
|
199
|
+
&.new .new_line {
|
200
|
+
background: #CFC;
|
201
|
+
border-color: #B9ECB9;
|
202
|
+
}
|
203
|
+
}
|
204
|
+
.line_content {
|
205
|
+
display: block;
|
206
|
+
position: relative;
|
207
|
+
height: 20px;
|
208
|
+
margin: 0px;
|
209
|
+
padding: 0px;
|
210
|
+
border: none;
|
211
|
+
.state {
|
212
|
+
position: absolute;
|
213
|
+
left: 10px;
|
214
|
+
top: 0;
|
215
|
+
}
|
216
|
+
pre {
|
217
|
+
padding: 0px 30px;
|
218
|
+
margin: 0;
|
219
|
+
}
|
220
|
+
&.new {
|
221
|
+
color: green;
|
222
|
+
}
|
223
|
+
&.old {
|
224
|
+
background: $old-background-color;
|
225
|
+
}
|
226
|
+
&.matched {
|
227
|
+
color: #ccc;
|
228
|
+
background: #fafafa;
|
229
|
+
}
|
230
|
+
&.parallel {
|
231
|
+
display: table-cell;
|
232
|
+
}
|
233
|
+
}
|
234
|
+
}
|
235
|
+
|
236
|
+
.image {
|
237
|
+
background: #ddd;
|
238
|
+
text-align: center;
|
239
|
+
padding: 30px;
|
240
|
+
.wrap{
|
241
|
+
display: inline-block;
|
242
|
+
}
|
243
|
+
|
244
|
+
.frame {
|
245
|
+
display: inline-block;
|
246
|
+
background-color: #fff;
|
247
|
+
line-height: 0;
|
248
|
+
img{
|
249
|
+
border: 1px solid #FFF;
|
250
|
+
background: image-url('trans_bg.gif');
|
251
|
+
max-width: 100%;
|
252
|
+
}
|
253
|
+
&.deleted {
|
254
|
+
border: 1px solid $deleted;
|
255
|
+
}
|
256
|
+
|
257
|
+
&.added {
|
258
|
+
border: 1px solid $added;
|
259
|
+
}
|
260
|
+
}
|
261
|
+
.image-info{
|
262
|
+
font-size: 12px;
|
263
|
+
margin: 5px 0 0 0;
|
264
|
+
color: grey;
|
265
|
+
}
|
266
|
+
|
267
|
+
.view.swipe{
|
268
|
+
position: relative;
|
269
|
+
|
270
|
+
.swipe-frame{
|
271
|
+
display: block;
|
272
|
+
margin: auto;
|
273
|
+
position: relative;
|
274
|
+
}
|
275
|
+
.swipe-wrap{
|
276
|
+
overflow: hidden;
|
277
|
+
border-left: 1px solid #999;
|
278
|
+
position: absolute;
|
279
|
+
display: block;
|
280
|
+
top: 13px;
|
281
|
+
right: 7px;
|
282
|
+
}
|
283
|
+
.frame{
|
284
|
+
top: 0;
|
285
|
+
right: 0;
|
286
|
+
position: absolute;
|
287
|
+
&.deleted{
|
288
|
+
margin: 0;
|
289
|
+
display: block;
|
290
|
+
top: 13px;
|
291
|
+
right: 7px;
|
292
|
+
}
|
293
|
+
}
|
294
|
+
.swipe-bar{
|
295
|
+
display: block;
|
296
|
+
height: 100%;
|
297
|
+
width: 15px;
|
298
|
+
z-index: 100;
|
299
|
+
position: absolute;
|
300
|
+
cursor: pointer;
|
301
|
+
&:hover{
|
302
|
+
.top-handle{
|
303
|
+
background-position: -15px 3px;
|
304
|
+
}
|
305
|
+
.bottom-handle{
|
306
|
+
background-position: -15px -11px;
|
307
|
+
}
|
308
|
+
};
|
309
|
+
.top-handle{
|
310
|
+
display: block;
|
311
|
+
height: 14px;
|
312
|
+
width: 15px;
|
313
|
+
position: absolute;
|
314
|
+
top: 0px;
|
315
|
+
background: image-url('swipemode_sprites.gif') 0 3px no-repeat;
|
316
|
+
}
|
317
|
+
.bottom-handle{
|
318
|
+
display: block;
|
319
|
+
height: 14px;
|
320
|
+
width: 15px;
|
321
|
+
position: absolute;
|
322
|
+
bottom: 0px;
|
323
|
+
background: image-url('swipemode_sprites.gif') 0 -11px no-repeat;
|
324
|
+
}
|
325
|
+
}
|
326
|
+
} //.view.swipe
|
327
|
+
.view.onion-skin{
|
328
|
+
.onion-skin-frame{
|
329
|
+
display: block;
|
330
|
+
margin: auto;
|
331
|
+
position: relative;
|
332
|
+
}
|
333
|
+
.frame.added, .frame.deleted {
|
334
|
+
position: absolute;
|
335
|
+
display: block;
|
336
|
+
top: 0px;
|
337
|
+
left: 0px;
|
338
|
+
}
|
339
|
+
.controls{
|
340
|
+
display: block;
|
341
|
+
height: 14px;
|
342
|
+
width: 300px;
|
343
|
+
z-index: 100;
|
344
|
+
position: absolute;
|
345
|
+
bottom: 0px;
|
346
|
+
left: 50%;
|
347
|
+
margin-left: -150px;
|
348
|
+
|
349
|
+
.drag-track{
|
350
|
+
display: block;
|
351
|
+
position: absolute;
|
352
|
+
left: 12px;
|
353
|
+
height: 10px;
|
354
|
+
width: 276px;
|
355
|
+
background: image-url('onion_skin_sprites.gif') -4px -20px repeat-x;
|
356
|
+
}
|
357
|
+
|
358
|
+
.dragger {
|
359
|
+
display: block;
|
360
|
+
position: absolute;
|
361
|
+
left: 0px;
|
362
|
+
top: 0px;
|
363
|
+
height: 14px;
|
364
|
+
width: 14px;
|
365
|
+
background: image-url('onion_skin_sprites.gif') 0px -34px repeat-x;
|
366
|
+
cursor: pointer;
|
367
|
+
}
|
368
|
+
|
369
|
+
.transparent {
|
370
|
+
display: block;
|
371
|
+
position: absolute;
|
372
|
+
top: 2px;
|
373
|
+
right: 0px;
|
374
|
+
height: 10px;
|
375
|
+
width: 10px;
|
376
|
+
background: image-url('onion_skin_sprites.gif') -2px 0px no-repeat;
|
377
|
+
}
|
378
|
+
|
379
|
+
.opaque {
|
380
|
+
display: block;
|
381
|
+
position: absolute;
|
382
|
+
top: 2px;
|
383
|
+
left: 0px;
|
384
|
+
height: 10px;
|
385
|
+
width: 10px;
|
386
|
+
background: image-url('onion_skin_sprites.gif') -2px -10px no-repeat;
|
387
|
+
}
|
388
|
+
}
|
389
|
+
} //.view.onion-skin
|
390
|
+
}
|
391
|
+
.view-modes{
|
392
|
+
|
393
|
+
padding: 10px;
|
394
|
+
text-align: center;
|
395
|
+
|
396
|
+
background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf));
|
397
|
+
background-image: -webkit-linear-gradient(#eee 6.6%, #dfdfdf);
|
398
|
+
background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf);
|
399
|
+
background-image: -ms-linear-gradient(#eee 6.6%, #dfdfdf);
|
400
|
+
background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf);
|
401
|
+
|
402
|
+
ul, li{
|
403
|
+
list-style: none;
|
404
|
+
margin: 0;
|
405
|
+
padding: 0;
|
406
|
+
display: inline-block;
|
407
|
+
}
|
408
|
+
|
409
|
+
li{
|
410
|
+
color: grey;
|
411
|
+
border-left: 1px solid #c1c1c1;
|
412
|
+
padding: 0 12px 0 16px;
|
413
|
+
cursor: pointer;
|
414
|
+
&:first-child{
|
415
|
+
border-left: none;
|
416
|
+
}
|
417
|
+
&:hover{
|
418
|
+
text-decoration: underline;
|
419
|
+
}
|
420
|
+
&.active{
|
421
|
+
&:hover{
|
422
|
+
text-decoration: none;
|
423
|
+
}
|
424
|
+
cursor: default;
|
425
|
+
color: #333;
|
426
|
+
}
|
427
|
+
&.disabled{
|
428
|
+
display: none;
|
429
|
+
}
|
430
|
+
}
|
431
|
+
}
|
432
|
+
}
|
@@ -0,0 +1,109 @@
|
|
1
|
+
.highlight {
|
2
|
+
margin-bottom: 30px;
|
3
|
+
overflow: auto;
|
4
|
+
background-color: inherit !important;
|
5
|
+
table {
|
6
|
+
border-collapse: collapse;
|
7
|
+
td {
|
8
|
+
&.gutter {
|
9
|
+
padding-right: 10px;
|
10
|
+
color: #505050;
|
11
|
+
font-size: 14px;
|
12
|
+
border-right: 1px solid #333;
|
13
|
+
}
|
14
|
+
&.code {
|
15
|
+
font-size: 14px;
|
16
|
+
pre {
|
17
|
+
margin-left: 10px;
|
18
|
+
}
|
19
|
+
}
|
20
|
+
}
|
21
|
+
}
|
22
|
+
}
|
23
|
+
|
24
|
+
.highlight table td { padding: 5px; }
|
25
|
+
.highlight table pre { margin: 0; }
|
26
|
+
.highlight, .highlight .w {
|
27
|
+
color: #93a1a1;
|
28
|
+
background-color: #002b36;
|
29
|
+
}
|
30
|
+
.highlight .err {
|
31
|
+
color: #151515;
|
32
|
+
background-color: #ac4142;
|
33
|
+
}
|
34
|
+
.highlight .c, .highlight .cd, .highlight .cm, .highlight .c1, .highlight .cs {
|
35
|
+
color: #505050;
|
36
|
+
}
|
37
|
+
.highlight .cp {
|
38
|
+
color: #f4bf75;
|
39
|
+
}
|
40
|
+
.highlight .nt {
|
41
|
+
color: #f4bf75;
|
42
|
+
}
|
43
|
+
.highlight .o, .highlight .ow {
|
44
|
+
color: #d0d0d0;
|
45
|
+
}
|
46
|
+
.highlight .p, .highlight .pi {
|
47
|
+
color: #d0d0d0;
|
48
|
+
}
|
49
|
+
.highlight .gi {
|
50
|
+
color: #90a959;
|
51
|
+
}
|
52
|
+
.highlight .gd {
|
53
|
+
color: #ac4142;
|
54
|
+
}
|
55
|
+
.highlight .gh {
|
56
|
+
color: #6a9fb5;
|
57
|
+
background-color: #151515;
|
58
|
+
font-weight: 600;
|
59
|
+
}
|
60
|
+
.highlight .k, .highlight .kn, .highlight .kp, .highlight .kr, .highlight .kv {
|
61
|
+
color: #aa759f;
|
62
|
+
}
|
63
|
+
.highlight .kc {
|
64
|
+
color: #d28445;
|
65
|
+
}
|
66
|
+
.highlight .kt {
|
67
|
+
color: #d28445;
|
68
|
+
}
|
69
|
+
.highlight .kd {
|
70
|
+
color: #d28445;
|
71
|
+
}
|
72
|
+
.highlight .s, .highlight .sb, .highlight .sc, .highlight .sd, .highlight .s2, .highlight .sh, .highlight .sx, .highlight .s1 {
|
73
|
+
color: #90a959;
|
74
|
+
}
|
75
|
+
.highlight .sr {
|
76
|
+
color: #75b5aa;
|
77
|
+
}
|
78
|
+
.highlight .si {
|
79
|
+
color: #8f5536;
|
80
|
+
}
|
81
|
+
.highlight .se {
|
82
|
+
color: #8f5536;
|
83
|
+
}
|
84
|
+
.highlight .nn {
|
85
|
+
color: #f4bf75;
|
86
|
+
}
|
87
|
+
.highlight .nc {
|
88
|
+
color: #f4bf75;
|
89
|
+
}
|
90
|
+
.highlight .no {
|
91
|
+
color: #f4bf75;
|
92
|
+
}
|
93
|
+
.highlight .na {
|
94
|
+
color: #6a9fb5;
|
95
|
+
}
|
96
|
+
.highlight .m, .highlight .mf, .highlight .mh, .highlight .mi, .highlight .il, .highlight .mo, .highlight .mb, .highlight .mx {
|
97
|
+
color: #90a959;
|
98
|
+
}
|
99
|
+
.highlight .ss {
|
100
|
+
color: #90a959;
|
101
|
+
}
|
102
|
+
|
103
|
+
// overrides
|
104
|
+
|
105
|
+
.highlight {
|
106
|
+
.w {
|
107
|
+
background-color: inherit;
|
108
|
+
}
|
109
|
+
}
|
metadata
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: black
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jade Dominguez
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-01-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rouge
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: sass
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3'
|
41
|
+
description: Black parses diff output to render a syntax-highlighted diff view in
|
42
|
+
HTML
|
43
|
+
email: plusjade@gmail.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- Gemfile
|
49
|
+
- README.md
|
50
|
+
- Rakefile
|
51
|
+
- black.gemspec
|
52
|
+
- lib/black.rb
|
53
|
+
- lib/black/diff.rb
|
54
|
+
- lib/black/git.rb
|
55
|
+
- lib/black/html_view.rb
|
56
|
+
- lib/black/preview.rb
|
57
|
+
- lib/black/stylesheets.rb
|
58
|
+
- lib/black/templates/diff.html.erb
|
59
|
+
- lib/black/templates/stylesheets/diff.css.scss
|
60
|
+
- lib/black/templates/stylesheets/syntax.css.scss
|
61
|
+
- lib/black/version.rb
|
62
|
+
homepage: https://github.com/plusjade/black
|
63
|
+
licenses:
|
64
|
+
- http://www.opensource.org/licenses/MIT
|
65
|
+
metadata: {}
|
66
|
+
post_install_message:
|
67
|
+
rdoc_options: []
|
68
|
+
require_paths:
|
69
|
+
- lib
|
70
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - '>='
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - '>='
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
requirements: []
|
81
|
+
rubyforge_project:
|
82
|
+
rubygems_version: 2.2.2
|
83
|
+
signing_key:
|
84
|
+
specification_version: 4
|
85
|
+
summary: Black parses diff output to render a syntax-highlighted diff view in HTML
|
86
|
+
test_files: []
|