Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisdickinson committed Jun 24, 2012
0 parents commit c82e991
Show file tree
Hide file tree
Showing 5 changed files with 222 additions and 0 deletions.
18 changes: 18 additions & 0 deletions assets/style.css
@@ -0,0 +1,18 @@
.seasons { -webkit-transform:translateZ(0); }
.seasons .seasons-line { -webkit-transition:top 0.5s linear; position:absolute; top:0px; left:20px; }

.seasons-line.active { display:block; }
.seasons-line.inactive { display:none !important; }

.seasons-line:before {
content:attr(data-line);
color:#666;
display:inline-block;
visibility:visible;
width:0px;
left:-20px;
position:relative;
}

.seasons-keyword { color:#336633; }
.seasons-literal { color:#660000; }
73 changes: 73 additions & 0 deletions bin/build_seasons
@@ -0,0 +1,73 @@
#!/bin/bash

pushd `pwd`

file=$1
dir=`dirname $file`
cd $dir

abspath=`pwd`

while [ ! -d ./.git ]; do
cd ..
done

dir=`pwd`
local=`echo $abspath | sed -e "s:$dir:.:g"`/`basename $file`

commits=`git log --pretty=format:%H $local`
i=0
results=""

for commit in $commits; do
data=`git show $commit:$local`
msg=`git log --pretty=format:%B $commit...$commit~1`

result=`echo "$commit:::$msg:::$data:::$i" | node -e "
data = []
process.stdin.on('data', data.push.bind(data))
process.stdin.on('end', ready)
process.stdin.resume()
function ready() {
data = data.join('').split(':::')
commit = data[0]
msg = data[1]
file = data[2]
idx = data[3]
data = {idx:~~idx, commit:commit, msg:msg, data:file.split('\n')}
process.stdout.write(JSON.stringify(data))
}
"`

results="$result,$results"
i=$(($i + 1))
echo $i
done

popd

echo "$results" | node -e "
data = []
process.stdin.on('data', data.push.bind(data))
process.stdin.on('end', ready)
process.stdin.resume()
function ready() {
data = JSON.parse('['+data.join('').slice(0, -2)+']').reverse()
var crypto = require('crypto')
, fs = require('fs')
data.forEach(function(commit) {
var lines = commit.data
commit.data = lines.map(function(line, idx) {
var hash = crypto.createHash('sha1').update(line.slice().trim()).digest('hex')
return {'hash':hash, 'line':line, 'num':idx+1}
})
})
fs.writeFileSync('output.json', JSON.stringify(data))
}
"
111 changes: 111 additions & 0 deletions lib/seasons.js
@@ -0,0 +1,111 @@
if(typeof define === 'undefined')
define = function(fn) { module.exports = fn() }

define(function(require) {
var ddd = require('d3')

if(typeof ddd == 'undefined') {
ddd = window.d3
}

return function(id, data, highlighter) {
var current = 0

id = id.charAt(0) === '#' ? id : '#'+id

on_state(current)

return function() {
if(arguments.length == 0) {
return current
} else {
on_state(current = arguments[0])
return current
}
}

function on_state(idx) {
var pre = ddd.select(id)
, max = data[idx].data.length.toString().length * 10 + 20

// updates
var line = pre
.selectAll('.seasons-line')
.data(data[idx].data, key_fn)
.attr('class', 'active seasons-line')
.attr('data-line', line_no)
.style('top', top_fn)
.html(highlight)

// insertions
line
.enter()
.append('code')
.attr('class', 'active seasons-line')
.attr('data-line', line_no)
.style('top', top_fn)
.html(highlight)

// deletions
line
.exit()
.attr('class', 'inactive seasons-line')
}
}

function key_fn(d) {
return d.hash
}

function line_no(d) {
return d.num
}

function top_fn(d) {
return d.num * 20 + 'px'
}

function highlight(d) {
var out = []
, highlight_rex =
/^(return|function|prototype|class|def|arguments|var|this|import|from|with|if|else|elif|try|catch|except)$/
, len = d.line.length
, content = d.line
, idx = 0
, instr = null
, word = null
, c

while(idx < len) {
c = content.charAt(idx)
if(/['"]/.test(c)) {
if(instr !== null) {
out.splice(instr, 0, '<span class="seasons-literal">')
out.push('</span>')
instr = null
} else {
instr = idx
}
} else if(instr === null && /[^\w\d]/.test(c) && word !== null) {
if(highlight_rex.test(out.slice(word).join(''))) {
out.splice(word, 0, '<span class="seasons-keyword">')
out.push('</span>')
}

word = null
} else if(instr === null && /[\w\d]/.test(c) && word === null) {
word = idx
}

out.push(c.replace(/\&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;'))

++idx
}

return out.join('')+'\n'
}
})
19 changes: 19 additions & 0 deletions package.json
@@ -0,0 +1,19 @@
{
"author": "Chris Dickinson <chris@neversaw.us> (http://github.com/chrisdickinson/)",
"name": "seasons",
"description": "generate and display changes in code across commits",
"version": "0.0.1",
"homepage": "http://github.com/chrisdickinson/seasons/",
"repository": {
"url": "git://github.com/chrisdickinson/seasons.git"
},
"main": "lib/seasons.js",
"dependencies": {
"d3": "~2.9.4"
},
"devDependencies": {},
"optionalDependencies": {},
"engines": {
"node": "*"
}
}
1 change: 1 addition & 0 deletions seasons.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit c82e991

Please sign in to comment.