black 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -0,0 +1,2 @@
1
+ source "https://rubygems.org"
2
+ gemspec
@@ -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)
@@ -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
@@ -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
+
@@ -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
@@ -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
@@ -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
+ }
@@ -0,0 +1,3 @@
1
+ module Black
2
+ Version = VERSION = '0.0.1'
3
+ end
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: []