yardstick-themekit 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +112 -0
- data/Rakefile +17 -0
- data/VERSION +1 -0
- data/bin/screenshots +95 -0
- data/bin/themekit +33 -0
- data/bin/webkit2png +278 -0
- data/example_theme/info.yml +12 -0
- data/example_theme/styles.css +32 -0
- data/example_theme/theme.html +37 -0
- data/github-test.rb +22 -0
- data/lib/themekit/data.rb +121 -0
- data/lib/themekit/server.rb +50 -0
- data/lib/themekit/theme.rb +49 -0
- data/lib/themekit.rb +6 -0
- data/pkg/themekit-0.0.7.gem +0 -0
- data/themekit.gemspec +56 -0
- metadata +77 -0
data/README.md
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
# Yardstick ThemeKit
|
2
|
+
|
3
|
+
A tiny app that makes designing Yardstick Measure themes a whole lot more enjoyable.
|
4
|
+
|
5
|
+
## Setup
|
6
|
+
|
7
|
+
After cloning the repo, just install the gem:
|
8
|
+
|
9
|
+
$ sudo gem install themekit-[version].gem
|
10
|
+
|
11
|
+
Then define the environment variable `YS_SYSTEM_CSS`. This tells ThemeKit where on your computer the Yardstick system.css file is located:
|
12
|
+
|
13
|
+
export YS_SYSTEM_CSS="/absolute/path/to/yardstick/screen.css"
|
14
|
+
|
15
|
+
_Tip: Add this line to your ~/.profile_
|
16
|
+
|
17
|
+
## Creating a Theme
|
18
|
+
|
19
|
+
Create a new Theme by passing the name (alphanumeric) to ThemeKit:
|
20
|
+
|
21
|
+
$ themekit my_awesome_theme
|
22
|
+
|
23
|
+
This will create a new directory, `my_awesome_theme`, which is a fully-functioning skeleton Theme that can be customized.
|
24
|
+
|
25
|
+
The first thing you should do is edit your theme's name in `info.yml`.
|
26
|
+
|
27
|
+
The following files are required:
|
28
|
+
|
29
|
+
* `info.yml` - Defines your Theme's name & available variations.
|
30
|
+
* `theme.html` - Theme's markup & template tags.
|
31
|
+
* `styles.css` - Theme's stylesheet. This should contain the styles for all variations.
|
32
|
+
|
33
|
+
## Running the server
|
34
|
+
|
35
|
+
To start ThemeKit, just change into your theme directory and run it:
|
36
|
+
|
37
|
+
$ cd ~/yardstick/themes/my_awesome_theme
|
38
|
+
$ themekit
|
39
|
+
|
40
|
+
Then head to http://localhost:4567/
|
41
|
+
|
42
|
+
## Theme Variations
|
43
|
+
|
44
|
+
To test different **theme variations**, pass in the variations(s) as a space-separated list in the querystring:
|
45
|
+
|
46
|
+
http://localhost:4567/?green people
|
47
|
+
|
48
|
+
or if you've got OCD:
|
49
|
+
|
50
|
+
http://localhost:4567/?green%20people
|
51
|
+
|
52
|
+
These variations will be tacked onto the `<body>` tag:
|
53
|
+
|
54
|
+
<body class="green people">
|
55
|
+
|
56
|
+
If no variation is specified, the value `"default"` will be used. You can use the `body.[variation] [selector]` technique to style elements differently depending on the active variation:
|
57
|
+
|
58
|
+
body.people { background: url(people.jpg); }
|
59
|
+
body.medical { background: url(medical.jpg); }
|
60
|
+
|
61
|
+
body.green h1 { color: green; }
|
62
|
+
body.blue h1 { color: blue; }
|
63
|
+
|
64
|
+
## Supported Tags
|
65
|
+
|
66
|
+
* {{ theme_variation }}
|
67
|
+
* {{ title }}
|
68
|
+
* {{ page.title }}
|
69
|
+
* {% image image\_data\_id [default image path] %}
|
70
|
+
* {% text text\_data\_id [default text] %}
|
71
|
+
* {% page_meta %}
|
72
|
+
* {% menu main %}
|
73
|
+
* {% menu account %}
|
74
|
+
* {{ page.content }}
|
75
|
+
* {{ system_stylesheet_path }}
|
76
|
+
* {{ stylesheet_path }}
|
77
|
+
|
78
|
+
|
79
|
+
## Automatic Screenshots
|
80
|
+
|
81
|
+
**Requires [PyYaML](http://pyyaml.org/wiki/PyYAML)**
|
82
|
+
|
83
|
+
ThemeKit can automatically take screenshots of your Theme, in all its variations. For example, if `info.yml` contains:
|
84
|
+
|
85
|
+
variations:
|
86
|
+
colors:
|
87
|
+
red: Red
|
88
|
+
green: Green
|
89
|
+
grey: Grey
|
90
|
+
blue: Blue
|
91
|
+
industries:
|
92
|
+
industrial: Industrial
|
93
|
+
medical: Medical
|
94
|
+
|
95
|
+
ThemeKit will take 8 screenshots (4 colors x 2 industries).
|
96
|
+
|
97
|
+
### Setup
|
98
|
+
|
99
|
+
You must symlink two executables from ThemeKit into your path:
|
100
|
+
|
101
|
+
$ sudo ln -s ~/yardstick/themekit/bin/webkit2png /usr/bin/webkit2png
|
102
|
+
$ sudo ln -s ~/yardstick/themekit/bin/screenshots /usr/bin/screenshots
|
103
|
+
|
104
|
+
### Taking Screenshots
|
105
|
+
|
106
|
+
From within your Theme directory, just type:
|
107
|
+
|
108
|
+
$ screenshots
|
109
|
+
|
110
|
+
This will read `info.yml` and determine all the possible variations your theme has and save a screenshot of each. Screenshots are saved to a subdirectory of your theme, aptly named `screenshots`.
|
111
|
+
|
112
|
+
**Each time you generate screenshots, existing screenshots will be deleted.**
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
begin
|
2
|
+
require 'jeweler'
|
3
|
+
Jeweler::Tasks.new do |gemspec|
|
4
|
+
gemspec.name = "themekit"
|
5
|
+
gemspec.summary = "Enjoyable theming for Yardstick Measure."
|
6
|
+
gemspec.description = "A tiny app that makes designing Yardstick Measure themes a whole lot more enjoyable."
|
7
|
+
gemspec.email = "kyle@yardsticksoftware.com"
|
8
|
+
gemspec.homepage = "http://github.com/yardstick/themekit"
|
9
|
+
gemspec.authors = ["Yardstick Software"]
|
10
|
+
gemspec.has_rdoc = false
|
11
|
+
gemspec.executables = ['themekit']
|
12
|
+
gemspec.add_dependency('sinatra', '>= 0.9.4')
|
13
|
+
end
|
14
|
+
rescue LoadError
|
15
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
16
|
+
end
|
17
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.8
|
data/bin/screenshots
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
|
3
|
+
import os
|
4
|
+
import sys
|
5
|
+
import urllib2
|
6
|
+
import Image
|
7
|
+
import yaml
|
8
|
+
|
9
|
+
BASE_URL = "http://localhost:4567/"
|
10
|
+
YAML_FILE = 'info.yml'
|
11
|
+
|
12
|
+
class Variation(object):
|
13
|
+
|
14
|
+
def __init__(self, name, labels):
|
15
|
+
self.name = name
|
16
|
+
self.labels = list(labels)
|
17
|
+
|
18
|
+
def __unicode__(self):
|
19
|
+
return self.filename
|
20
|
+
__repr__ = __unicode__
|
21
|
+
|
22
|
+
@property
|
23
|
+
def filename(self):
|
24
|
+
return '_'.join(self.labels)
|
25
|
+
|
26
|
+
@property
|
27
|
+
def url(self):
|
28
|
+
return "%s?%s" % (BASE_URL, "%20".join(self.labels))
|
29
|
+
|
30
|
+
|
31
|
+
def product(*args, **kwds):
|
32
|
+
"Given a list of iterables, calculate the possible combinations."
|
33
|
+
# Based on itertools.product from Python 2.6
|
34
|
+
pools = map(tuple, args) * kwds.get('repeat', 1)
|
35
|
+
result = [[]]
|
36
|
+
for pool in pools:
|
37
|
+
result = [x+[y] for x in result for y in pool]
|
38
|
+
for prod in result:
|
39
|
+
yield tuple(prod)
|
40
|
+
|
41
|
+
|
42
|
+
def load_variations(yaml_path):
|
43
|
+
"Loads a list of Variations from the specified yaml file."
|
44
|
+
data = open(yaml_path).read()
|
45
|
+
parsed = yaml.load(data)
|
46
|
+
variation_name = parsed['name'].lower().replace(r' ', '_')
|
47
|
+
variation_categories = []
|
48
|
+
variations_dict = parsed.get('variations', {})
|
49
|
+
for category_name in sorted(variations_dict.keys()):
|
50
|
+
variation_categories.append(variations_dict[category_name])
|
51
|
+
variations = []
|
52
|
+
for combo in product(*[category.keys() for category in variation_categories]):
|
53
|
+
variations.append(Variation(variation_name, combo))
|
54
|
+
return variations
|
55
|
+
|
56
|
+
|
57
|
+
if __name__ == '__main__':
|
58
|
+
if not os.path.exists(YAML_FILE):
|
59
|
+
print "\n** Can't find %s. This script must be run from the Theme's root directory.\n" % YAML_FILE
|
60
|
+
sys.exit(0)
|
61
|
+
|
62
|
+
try:
|
63
|
+
urllib2.urlopen(BASE_URL)
|
64
|
+
except urllib2.URLError, e:
|
65
|
+
print "\n** Couldn't connect to %s -- are you sure ThemeKit is running?\n" % BASE_URL
|
66
|
+
sys.exit(0)
|
67
|
+
|
68
|
+
# Determine the directory in which to save the screenshots.
|
69
|
+
# If it already exists, clear it's files and remove the directory.
|
70
|
+
dest = os.path.join(os.getcwd(), 'screenshots')
|
71
|
+
if os.path.isdir(dest):
|
72
|
+
print "** Removing existing screenshots..."
|
73
|
+
for path in os.listdir(dest):
|
74
|
+
os.remove(os.path.join(dest, path))
|
75
|
+
os.rmdir(dest)
|
76
|
+
os.mkdir(dest)
|
77
|
+
|
78
|
+
from subprocess import call, PIPE
|
79
|
+
variations = load_variations(YAML_FILE)
|
80
|
+
print '** Grabbing screenshots for %s variations...' % len(variations)
|
81
|
+
count = 1
|
82
|
+
for v in variations:
|
83
|
+
print "** %s) %s \t(%s)" % (count, " ".join(v.labels), v.url)
|
84
|
+
count += 1
|
85
|
+
call(['webkit2png', '--filename=%s' % v.filename, '--dir=%s' % dest, '--width=1024', '--height=768', '-F', v.url], stdout=open(os.devnull, 'w'))
|
86
|
+
|
87
|
+
for img_path in os.listdir(dest):
|
88
|
+
full_path = os.path.join(dest, img_path)
|
89
|
+
img = Image.open(full_path)
|
90
|
+
img = img.crop((0,0,1024,768))
|
91
|
+
img.thumbnail((300,300), Image.ANTIALIAS)
|
92
|
+
img.save(full_path.replace("-full", ""), "JPEG", quality=95)
|
93
|
+
os.remove(full_path)
|
94
|
+
|
95
|
+
print '** Screenshots have been saved in %s' % dest
|
data/bin/themekit
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "rubygems"
|
4
|
+
require "themekit"
|
5
|
+
|
6
|
+
def load_system_stylesheet
|
7
|
+
system_stylesheet = ENV["YS_SYSTEM_CSS"]
|
8
|
+
if system_stylesheet.nil?
|
9
|
+
puts "\n** WHUPS! You need to set the 'YS_SYSTEM_CSS' environment variable."
|
10
|
+
puts "This tells ThemeKit where the Yardstick 'system.css' file is located."
|
11
|
+
puts "Example: export YS_SYSTEM_CSS=\"~/path/to/system.css\"\n\n"
|
12
|
+
Kernel.exit(0)
|
13
|
+
end
|
14
|
+
system_stylesheet
|
15
|
+
end
|
16
|
+
|
17
|
+
if ARGV.empty?
|
18
|
+
# Run the ThemeKit Sinatra app.
|
19
|
+
theme_directory = Dir.pwd
|
20
|
+
puts "** Starting ThemeKit in #{theme_directory}"
|
21
|
+
ThemeKit::Server.run!({
|
22
|
+
:host => 'localhost',
|
23
|
+
:port => 4567,
|
24
|
+
:system_stylesheet => load_system_stylesheet,
|
25
|
+
:theme_directory => theme_directory
|
26
|
+
})
|
27
|
+
else
|
28
|
+
# Create a new theme
|
29
|
+
theme_name = ARGV.first
|
30
|
+
theme = ThemeKit::Theme.new(theme_name, Dir.pwd)
|
31
|
+
theme.create
|
32
|
+
puts "Created #{theme.name} in #{theme.path}"
|
33
|
+
end
|
data/bin/webkit2png
ADDED
@@ -0,0 +1,278 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
|
3
|
+
# webkit2png - makes screenshots of webpages
|
4
|
+
# http://www.paulhammond.org/webkit2png
|
5
|
+
|
6
|
+
__version__ = "0.5"
|
7
|
+
|
8
|
+
# Copyright (c) 2009 Paul Hammond
|
9
|
+
#
|
10
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
11
|
+
# of this software and associated documentation files (the "Software"), to deal
|
12
|
+
# in the Software without restriction, including without limitation the rights
|
13
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
14
|
+
# copies of the Software, and to permit persons to whom the Software is
|
15
|
+
# furnished to do so, subject to the following conditions:
|
16
|
+
#
|
17
|
+
# The above copyright notice and this permission notice shall be included in
|
18
|
+
# all copies or substantial portions of the Software.
|
19
|
+
#
|
20
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
21
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
22
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
23
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
24
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
25
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
26
|
+
# THE SOFTWARE.
|
27
|
+
#
|
28
|
+
|
29
|
+
import sys
|
30
|
+
import optparse
|
31
|
+
|
32
|
+
try:
|
33
|
+
import Foundation
|
34
|
+
import WebKit
|
35
|
+
import AppKit
|
36
|
+
import objc
|
37
|
+
except ImportError:
|
38
|
+
print "Cannot find pyobjc library files. Are you sure it is installed?"
|
39
|
+
sys.exit()
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
class AppDelegate (Foundation.NSObject):
|
44
|
+
# what happens when the app starts up
|
45
|
+
def applicationDidFinishLaunching_(self, aNotification):
|
46
|
+
webview = aNotification.object().windows()[0].contentView()
|
47
|
+
webview.frameLoadDelegate().getURL(webview)
|
48
|
+
|
49
|
+
class WebkitLoad (Foundation.NSObject, WebKit.protocols.WebFrameLoadDelegate):
|
50
|
+
# what happens if something goes wrong while loading
|
51
|
+
def webView_didFailLoadWithError_forFrame_(self,webview,error,frame):
|
52
|
+
print " ... something went wrong"
|
53
|
+
self.getURL(webview)
|
54
|
+
def webView_didFailProvisionalLoadWithError_forFrame_(self,webview,error,frame):
|
55
|
+
print " ... something went wrong"
|
56
|
+
self.getURL(webview)
|
57
|
+
|
58
|
+
def makeFilename(self,URL,options):
|
59
|
+
# make the filename
|
60
|
+
if options.filename:
|
61
|
+
filename = options.filename
|
62
|
+
elif options.md5:
|
63
|
+
try:
|
64
|
+
import md5
|
65
|
+
except ImportError:
|
66
|
+
print "--md5 requires python md5 library"
|
67
|
+
AppKit.NSApplication.sharedApplication().terminate_(None)
|
68
|
+
filename = md5.new(URL).hexdigest()
|
69
|
+
else:
|
70
|
+
import re
|
71
|
+
filename = re.sub('\W','',URL);
|
72
|
+
filename = re.sub('^http','',filename);
|
73
|
+
if options.datestamp:
|
74
|
+
import time
|
75
|
+
now = time.strftime("%Y%m%d")
|
76
|
+
filename = now + "-" + filename
|
77
|
+
import os
|
78
|
+
dir = os.path.abspath(os.path.expanduser(options.dir))
|
79
|
+
return os.path.join(dir,filename)
|
80
|
+
|
81
|
+
def saveImages(self,bitmapdata,filename,options):
|
82
|
+
# save the fullsize png
|
83
|
+
if options.fullsize:
|
84
|
+
bitmapdata.representationUsingType_properties_(AppKit.NSPNGFileType,None).writeToFile_atomically_(filename + "-full.png",objc.YES)
|
85
|
+
|
86
|
+
if options.thumb or options.clipped:
|
87
|
+
# work out how big the thumbnail is
|
88
|
+
width = bitmapdata.pixelsWide()
|
89
|
+
height = bitmapdata.pixelsHigh()
|
90
|
+
thumbWidth = (width * options.scale)
|
91
|
+
thumbHeight = (height * options.scale)
|
92
|
+
|
93
|
+
# make the thumbnails in a scratch image
|
94
|
+
scratch = AppKit.NSImage.alloc().initWithSize_(
|
95
|
+
Foundation.NSMakeSize(thumbWidth,thumbHeight))
|
96
|
+
scratch.lockFocus()
|
97
|
+
AppKit.NSGraphicsContext.currentContext().setImageInterpolation_(
|
98
|
+
AppKit.NSImageInterpolationHigh)
|
99
|
+
thumbRect = Foundation.NSMakeRect(0.0, 0.0, thumbWidth, thumbHeight)
|
100
|
+
clipRect = Foundation.NSMakeRect(0.0,
|
101
|
+
thumbHeight-options.clipheight,
|
102
|
+
options.clipwidth, options.clipheight)
|
103
|
+
bitmapdata.drawInRect_(thumbRect)
|
104
|
+
thumbOutput = AppKit.NSBitmapImageRep.alloc().initWithFocusedViewRect_(thumbRect)
|
105
|
+
clipOutput = AppKit.NSBitmapImageRep.alloc().initWithFocusedViewRect_(clipRect)
|
106
|
+
scratch.unlockFocus()
|
107
|
+
|
108
|
+
# save the thumbnails as pngs
|
109
|
+
if options.thumb:
|
110
|
+
thumbOutput.representationUsingType_properties_(
|
111
|
+
AppKit.NSPNGFileType,None
|
112
|
+
).writeToFile_atomically_(filename + "-thumb.png",objc.YES)
|
113
|
+
if options.clipped:
|
114
|
+
clipOutput.representationUsingType_properties_(
|
115
|
+
AppKit.NSPNGFileType,None
|
116
|
+
).writeToFile_atomically_(filename + "-clipped.png",objc.YES)
|
117
|
+
|
118
|
+
def getURL(self,webview):
|
119
|
+
if self.urls:
|
120
|
+
if self.urls[0] == '-':
|
121
|
+
url = sys.stdin.readline().rstrip()
|
122
|
+
if not url: AppKit.NSApplication.sharedApplication().terminate_(None)
|
123
|
+
else:
|
124
|
+
url = self.urls.pop(0)
|
125
|
+
else:
|
126
|
+
AppKit.NSApplication.sharedApplication().terminate_(None)
|
127
|
+
print "Fetching", url, "..."
|
128
|
+
self.resetWebview(webview)
|
129
|
+
webview.mainFrame().loadRequest_(Foundation.NSURLRequest.requestWithURL_(Foundation.NSURL.URLWithString_(url)))
|
130
|
+
if not webview.mainFrame().provisionalDataSource():
|
131
|
+
print " ... not a proper url?"
|
132
|
+
self.getURL(webview)
|
133
|
+
|
134
|
+
def resetWebview(self,webview):
|
135
|
+
rect = Foundation.NSMakeRect(0,0,self.options.initWidth,self.options.initHeight)
|
136
|
+
webview.window().setContentSize_((self.options.initWidth,self.options.initHeight))
|
137
|
+
webview.setFrame_(rect)
|
138
|
+
|
139
|
+
def resizeWebview(self,view):
|
140
|
+
view.window().display()
|
141
|
+
view.window().setContentSize_(view.bounds().size)
|
142
|
+
view.setFrame_(view.bounds())
|
143
|
+
|
144
|
+
def captureView(self,view):
|
145
|
+
view.lockFocus()
|
146
|
+
bitmapdata = AppKit.NSBitmapImageRep.alloc()
|
147
|
+
bitmapdata.initWithFocusedViewRect_(view.bounds())
|
148
|
+
view.unlockFocus()
|
149
|
+
return bitmapdata
|
150
|
+
|
151
|
+
# what happens when the page has finished loading
|
152
|
+
def webView_didFinishLoadForFrame_(self,webview,frame):
|
153
|
+
# don't care about subframes
|
154
|
+
if (frame == webview.mainFrame()):
|
155
|
+
Foundation.NSTimer.scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_( self.options.delay, self, self.doGrab, webview, False)
|
156
|
+
|
157
|
+
def doGrab(self,timer):
|
158
|
+
webview = timer.userInfo()
|
159
|
+
view = webview.mainFrame().frameView().documentView()
|
160
|
+
|
161
|
+
self.resizeWebview(view)
|
162
|
+
|
163
|
+
URL = webview.mainFrame().dataSource().initialRequest().URL().absoluteString()
|
164
|
+
filename = self.makeFilename(URL, self.options)
|
165
|
+
|
166
|
+
bitmapdata = self.captureView(view)
|
167
|
+
self.saveImages(bitmapdata,filename,self.options)
|
168
|
+
|
169
|
+
print " ... done"
|
170
|
+
self.getURL(webview)
|
171
|
+
|
172
|
+
|
173
|
+
def main():
|
174
|
+
|
175
|
+
# parse the command line
|
176
|
+
usage = """%prog [options] [http://example.net/ ...]
|
177
|
+
|
178
|
+
examples:
|
179
|
+
%prog http://google.com/ # screengrab google
|
180
|
+
%prog -W 1000 -H 1000 http://google.com/ # bigger screengrab of google
|
181
|
+
%prog -T http://google.com/ # just the thumbnail screengrab
|
182
|
+
%prog -TF http://google.com/ # just thumbnail and fullsize grab
|
183
|
+
%prog -o foo http://google.com/ # save images as "foo-thumb.png" etc
|
184
|
+
%prog - # screengrab urls from stdin
|
185
|
+
%prog -h | less # full documentation"""
|
186
|
+
|
187
|
+
cmdparser = optparse.OptionParser(usage,version=("webkit2png "+__version__))
|
188
|
+
# TODO: add quiet/verbose options
|
189
|
+
cmdparser.add_option("-W", "--width",type="float",default=800.0,
|
190
|
+
help="initial (and minimum) width of browser (default: 800)")
|
191
|
+
cmdparser.add_option("-H", "--height",type="float",default=600.0,
|
192
|
+
help="initial (and minimum) height of browser (default: 600)")
|
193
|
+
cmdparser.add_option("--clipwidth",type="float",default=200.0,
|
194
|
+
help="width of clipped thumbnail (default: 200)",
|
195
|
+
metavar="WIDTH")
|
196
|
+
cmdparser.add_option("--clipheight",type="float",default=150.0,
|
197
|
+
help="height of clipped thumbnail (default: 150)",
|
198
|
+
metavar="HEIGHT")
|
199
|
+
cmdparser.add_option("-s", "--scale",type="float",default=0.25,
|
200
|
+
help="scale factor for thumbnails (default: 0.25)")
|
201
|
+
cmdparser.add_option("-m", "--md5", action="store_true",
|
202
|
+
help="use md5 hash for filename (like del.icio.us)")
|
203
|
+
cmdparser.add_option("-o", "--filename", type="string",default="",
|
204
|
+
metavar="NAME", help="save images as NAME-full.png,NAME-thumb.png etc")
|
205
|
+
cmdparser.add_option("-F", "--fullsize", action="store_true",
|
206
|
+
help="only create fullsize screenshot")
|
207
|
+
cmdparser.add_option("-T", "--thumb", action="store_true",
|
208
|
+
help="only create thumbnail sreenshot")
|
209
|
+
cmdparser.add_option("-C", "--clipped", action="store_true",
|
210
|
+
help="only create clipped thumbnail screenshot")
|
211
|
+
cmdparser.add_option("-d", "--datestamp", action="store_true",
|
212
|
+
help="include date in filename")
|
213
|
+
cmdparser.add_option("-D", "--dir",type="string",default="./",
|
214
|
+
help="directory to place images into")
|
215
|
+
cmdparser.add_option("--delay",type="float",default=0,
|
216
|
+
help="delay between page load finishing and screenshot")
|
217
|
+
cmdparser.add_option("--noimages", action="store_true",
|
218
|
+
help="don't load images")
|
219
|
+
cmdparser.add_option("--debug", action="store_true",
|
220
|
+
help=optparse.SUPPRESS_HELP)
|
221
|
+
(options, args) = cmdparser.parse_args()
|
222
|
+
if len(args) == 0:
|
223
|
+
cmdparser.print_usage()
|
224
|
+
return
|
225
|
+
if options.filename:
|
226
|
+
if len(args) != 1 or args[0] == "-":
|
227
|
+
print "--filename option requires exactly one url"
|
228
|
+
return
|
229
|
+
if options.scale == 0:
|
230
|
+
cmdparser.error("scale cannot be zero")
|
231
|
+
# make sure we're outputing something
|
232
|
+
if not (options.fullsize or options.thumb or options.clipped):
|
233
|
+
options.fullsize = True
|
234
|
+
options.thumb = True
|
235
|
+
options.clipped = True
|
236
|
+
# work out the initial size of the browser window
|
237
|
+
# (this might need to be larger so clipped image is right size)
|
238
|
+
options.initWidth = (options.clipwidth / options.scale)
|
239
|
+
options.initHeight = (options.clipheight / options.scale)
|
240
|
+
if options.width>options.initWidth:
|
241
|
+
options.initWidth = options.width
|
242
|
+
if options.height>options.initHeight:
|
243
|
+
options.initHeight = options.height
|
244
|
+
|
245
|
+
app = AppKit.NSApplication.sharedApplication()
|
246
|
+
|
247
|
+
# create an app delegate
|
248
|
+
delegate = AppDelegate.alloc().init()
|
249
|
+
AppKit.NSApp().setDelegate_(delegate)
|
250
|
+
|
251
|
+
# create a window
|
252
|
+
rect = Foundation.NSMakeRect(0,0,100,100)
|
253
|
+
win = AppKit.NSWindow.alloc()
|
254
|
+
win.initWithContentRect_styleMask_backing_defer_ (rect,
|
255
|
+
AppKit.NSBorderlessWindowMask, 2, 0)
|
256
|
+
if options.debug:
|
257
|
+
win.orderFrontRegardless()
|
258
|
+
# create a webview object
|
259
|
+
webview = WebKit.WebView.alloc()
|
260
|
+
webview.initWithFrame_(rect)
|
261
|
+
# turn off scrolling so the content is actually x wide and not x-15
|
262
|
+
webview.mainFrame().frameView().setAllowsScrolling_(objc.NO)
|
263
|
+
|
264
|
+
webview.setPreferencesIdentifier_('webkit2png')
|
265
|
+
webview.preferences().setLoadsImagesAutomatically_(not options.noimages)
|
266
|
+
|
267
|
+
# add the webview to the window
|
268
|
+
win.setContentView_(webview)
|
269
|
+
|
270
|
+
# create a LoadDelegate
|
271
|
+
loaddelegate = WebkitLoad.alloc().init()
|
272
|
+
loaddelegate.options = options
|
273
|
+
loaddelegate.urls = args
|
274
|
+
webview.setFrameLoadDelegate_(loaddelegate)
|
275
|
+
|
276
|
+
app.run()
|
277
|
+
|
278
|
+
if __name__ == '__main__' : main()
|
@@ -0,0 +1,32 @@
|
|
1
|
+
body, .themeContent { font-size: 13px; }
|
2
|
+
|
3
|
+
.container { width: 800px; }
|
4
|
+
|
5
|
+
#header { background: #222; padding: 30px 0;}
|
6
|
+
#header h2 { float: right; font-size: 15px; color: #fff; font-weight: normal; }
|
7
|
+
|
8
|
+
#nav { background: #444; }
|
9
|
+
#nav a { color: #999; font-size: 13px; padding: 0px 15px; line-height: 40px; }
|
10
|
+
#nav a:hover,
|
11
|
+
#nav li.active a { background: #555; color: #fff; }
|
12
|
+
#mainNav { float: left; }
|
13
|
+
#loginNav { float: right; }
|
14
|
+
#loginNav a { font-size: 11px; }
|
15
|
+
|
16
|
+
.themeContentContainer { padding-top: 30px; }
|
17
|
+
|
18
|
+
.themeContent { color: #777; }
|
19
|
+
|
20
|
+
.themeContent h1,
|
21
|
+
.themeContent h2,
|
22
|
+
.themeContent h3,
|
23
|
+
.themeContent h4,
|
24
|
+
.themeContent h5,
|
25
|
+
.themeContent th { color: #444; }
|
26
|
+
.themeContent th { background: #f4f4f4;}
|
27
|
+
|
28
|
+
.themeContent h1 { letter-spacing: -1px; margin-bottom: 30px; }
|
29
|
+
|
30
|
+
.themeContent img { border: 1px solid #ccc; padding: 1px; }
|
31
|
+
|
32
|
+
#footer .container { font-size: 11px; color: #aaa; text-align: center; border-top: 1px solid #eee; padding: 5px 0 15px 0;}
|
@@ -0,0 +1,37 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
3
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
4
|
+
<head>
|
5
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
6
|
+
<link href="{{ system_stylesheet_path }}" media="screen" rel="stylesheet" type="text/css" />
|
7
|
+
<link rel="stylesheet" type="text/css" href="{{ stylesheet_path }}">
|
8
|
+
<title>{{ title }}</title>
|
9
|
+
{% page_meta %}
|
10
|
+
</head>
|
11
|
+
<body class="themeBody {{ theme_variation }}">
|
12
|
+
|
13
|
+
<div id="header"><div class="container">
|
14
|
+
<div id="logo">
|
15
|
+
{% image image_data_id, common/default_image.png %}
|
16
|
+
</div>
|
17
|
+
<h2 id="subheading">{% text text_data_id, Making things more better! %}</h2>
|
18
|
+
</div></div>
|
19
|
+
|
20
|
+
<div id="nav"><div class="container">
|
21
|
+
<div id="mainNav" class="horizontal menu">{% menu main %}</div>
|
22
|
+
<div id="loginNav" class="horizontal menu">{% menu account %}</div>
|
23
|
+
</div></div>
|
24
|
+
|
25
|
+
<div class="themeContentContainer container">
|
26
|
+
<div class="themeContent">
|
27
|
+
<h1 class="pageTitle">{{ page.title }}</h1>
|
28
|
+
{{ page.content }}
|
29
|
+
</div>
|
30
|
+
</div></div>
|
31
|
+
|
32
|
+
<div id="footer"><div class="container">
|
33
|
+
{% text text_data_id, Copyright 2009 Yardstick Software %}
|
34
|
+
</div></div>
|
35
|
+
|
36
|
+
</body>
|
37
|
+
</html>
|
data/github-test.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
if ARGV.size < 1
|
5
|
+
puts "Usage: github-test.rb my-project.gemspec"
|
6
|
+
exit
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'rubygems/specification'
|
10
|
+
data = File.read(ARGV[0])
|
11
|
+
spec = nil
|
12
|
+
|
13
|
+
if data !~ %r{!ruby/object:Gem::Specification}
|
14
|
+
Thread.new { spec = eval("$SAFE = 3\n#{data}") }.join
|
15
|
+
else
|
16
|
+
spec = YAML.load(data)
|
17
|
+
end
|
18
|
+
|
19
|
+
spec.validate
|
20
|
+
|
21
|
+
puts spec
|
22
|
+
puts "OK"
|
@@ -0,0 +1,121 @@
|
|
1
|
+
module ThemeKit
|
2
|
+
module Data
|
3
|
+
|
4
|
+
META_TAGS = <<-EOS
|
5
|
+
<meta name="keywords" content="themes, yardstick, server, design" />
|
6
|
+
<meta name="description" content="This is the Yardstick Measure Theme Server." />
|
7
|
+
EOS
|
8
|
+
|
9
|
+
MAIN_NAV = <<-EOS
|
10
|
+
<ul id="ys-menu_main" class="ys-menu">
|
11
|
+
<li class="active ys-menuItem"><a href="/tincidunt-orci-quis-lectus-nullam">Home</a></li>
|
12
|
+
<li class="ys-menuItem"><a href="#">Products</a></li>
|
13
|
+
<li class="ys-menuItem"><a href="#">Services</a></li>
|
14
|
+
<li class="ys-menuItem"><a href="#">Our Company</a></li>
|
15
|
+
<li class="ys-menuItem"><a href="#">Contact Us</a></li>
|
16
|
+
</ul>
|
17
|
+
EOS
|
18
|
+
|
19
|
+
USER_NAV = <<-EOS
|
20
|
+
<ul id="ys-menu_account" class="ys-menu">
|
21
|
+
<li class="ys-menuItem"><a href="/login">Login</a></li>
|
22
|
+
<li class="ys-menuItem"><a href="/login">Sign up</a></li>
|
23
|
+
</ul>
|
24
|
+
EOS
|
25
|
+
|
26
|
+
DUMMY_HTML = <<-EOS
|
27
|
+
<!-- START DUMMY CONTENT -->
|
28
|
+
<p>Lorem ipsum dolor sit amet, <a href="#">claritas ut aliquam</a> consectetuer magna. Quis per me placerat humanitatis est sed. Usus claritatem habent aliquip te veniam tincidunt adipiscing eu. Blandit minim cum facer nisl in feugiat nihil eleifend. Eua nunc consuetudium non molestie iusto claram eleifend claritas eorum, id.</p>
|
29
|
+
<h2>Heading Level 2</h2>
|
30
|
+
<p>It's time for some <strong>strong</strong> text and some <em>emphasized</em> text.</p>
|
31
|
+
<p>Enim autem littera erat elit ii nihil sequitur molestie dignissim magna. Ad, et, facilisi ex aliquip fiant decima hendrerit habent. Praesent sollemnes tincidunt at. Parum quod, formas imperdiet suscipit te velit. Nunc delenit me est demonstraverunt formas minim non. Eros legunt iriure at lorem notare.</p>
|
32
|
+
<p>Here's a table:</p>
|
33
|
+
<table>
|
34
|
+
<caption>The awesome people of Yardstick</caption>
|
35
|
+
<thead>
|
36
|
+
<tr>
|
37
|
+
<th>Name</th>
|
38
|
+
<th>Languages</th>
|
39
|
+
<th>Awesome Factor</th>
|
40
|
+
</tr>
|
41
|
+
</thead>
|
42
|
+
<tbody>
|
43
|
+
<tr>
|
44
|
+
<th>Kyle</th>
|
45
|
+
<td>Python</td>
|
46
|
+
<td>11</td>
|
47
|
+
</tr>
|
48
|
+
<tr>
|
49
|
+
<th>Paul</th>
|
50
|
+
<td>Ruby</td>
|
51
|
+
<td>10.5</td>
|
52
|
+
</tr>
|
53
|
+
<tr>
|
54
|
+
<th>Nolan</th>
|
55
|
+
<td>Photoshop</td>
|
56
|
+
<td>11</td>
|
57
|
+
</tr>
|
58
|
+
<tr>
|
59
|
+
<th>Ben</th>
|
60
|
+
<td>ColdFusion</td>
|
61
|
+
<td>11</td>
|
62
|
+
</tr>
|
63
|
+
<tr>
|
64
|
+
<th>Don</th>
|
65
|
+
<td>ColdFusion</td>
|
66
|
+
<td>11</td>
|
67
|
+
</tr>
|
68
|
+
</tbody>
|
69
|
+
</table>
|
70
|
+
<p>Here's a quote:</p>
|
71
|
+
<blockquote>
|
72
|
+
<p>Enim autem littera erat elit ii nihil sequitur molestie dignissim magna. Ad, et, facilisi ex aliquip fiant decima hendrerit habent. Praesent sollemnes tincidunt at. Parum quod, formas imperdiet suscipit te velit. Nunc delenit me est demonstraverunt formas minim non. Eros legunt iriure at lorem notare.</p>
|
73
|
+
</blockquote>
|
74
|
+
<h3>Heading Level 3</h3>
|
75
|
+
<p>Lectores, doming quarta, ad possim cum eua esse. Et quod eu quis id aliquip ii liber. In ex te, sequitur sed me feugiat ipsum molestie elit legentis. Lectorum praesent est eros non lorem. At possim soluta illum per ad. Amet tincidunt cum eua nibh mutationem.</p>
|
76
|
+
<h4>Heading Level 4</h4>
|
77
|
+
<p>Et, investigationes nostrud, parum eros assum, claritas lius. Facit facer euismod eu id, nulla. Adipiscing, littera ii consectetuer typi in praesent, aliquam. Mirum erat minim eum duis. Nisl ex delenit te, me velit est typi. Non at hendrerit ad soluta nibh qui cum, eua.</p>
|
78
|
+
<h5>Heading Level 5</h5>
|
79
|
+
<p>Et, investigationes nostrud, parum eros assum, claritas lius. Facit facer euismod eu id, nulla. Adipiscing, littera ii consectetuer typi in praesent, aliquam. Mirum erat minim eum duis. Nisl ex delenit te, me velit est typi. Non at hendrerit ad soluta nibh qui cum, eua.</p>
|
80
|
+
<h6>Heading Level 6</h6>
|
81
|
+
<p>Et, investigationes nostrud, parum eros assum, claritas lius. Facit facer euismod eu id, nulla. Adipiscing, littera ii consectetuer typi in praesent, aliquam. Mirum erat minim eum duis. Nisl ex delenit te, me velit est typi. Non at hendrerit ad soluta nibh qui cum, eua.</p>
|
82
|
+
<ul>
|
83
|
+
<li>Milk</li>
|
84
|
+
<li>Bread</li>
|
85
|
+
<li>Eggs</li>
|
86
|
+
<li>Veggies
|
87
|
+
<ul>
|
88
|
+
<li>Peppers</li>
|
89
|
+
<li>Cucumbers</li>
|
90
|
+
<li>Radishes</li>
|
91
|
+
</ul>
|
92
|
+
</li>
|
93
|
+
<li>Cookies</li>
|
94
|
+
</ul>
|
95
|
+
<p>Lectores, doming quarta, ad possim cum eua esse. Et quod eu quis id aliquip ii liber. In ex te, sequitur sed me feugiat ipsum molestie elit legentis. Lectorum praesent est eros non lorem. At possim soluta illum per ad. Amet tincidunt cum eua nibh mutationem.</p>
|
96
|
+
<ol>
|
97
|
+
<li>Milk</li>
|
98
|
+
<li>Bread</li>
|
99
|
+
<li>Eggs</li>
|
100
|
+
<li>Veggies
|
101
|
+
<ul>
|
102
|
+
<li>Peppers</li>
|
103
|
+
<li>Cucumbers</li>
|
104
|
+
<li>Radishes</li>
|
105
|
+
</ul>
|
106
|
+
</li>
|
107
|
+
<li>Cookies</li>
|
108
|
+
</ol>
|
109
|
+
<p>Lectores, doming quarta, ad possim cum eua esse. Et quod eu quis id aliquip ii liber. In ex te, sequitur sed me feugiat ipsum molestie elit legentis. Lectorum praesent est eros non lorem. At possim soluta illum per ad. Amet tincidunt cum eua nibh mutationem.</p>
|
110
|
+
<h2>A block image followed by an inline image</h2>
|
111
|
+
<p>Lectores, doming quarta, ad possim cum eua esse. Et quod eu quis id aliquip ii liber. In ex te, sequitur sed me feugiat ipsum molestie elit legentis. Lectorum praesent est eros non lorem. At possim soluta illum per ad. Amet tincidunt cum eua nibh mutationem.</p>
|
112
|
+
<p><img alt="none" src="http://farm4.static.flickr.com/3253/2496907243_5efbbab5cd.jpg" /></p>
|
113
|
+
<p>Lectores, doming quarta, ad possim cum eua esse. Et quod eu quis id aliquip ii liber. In ex te, sequitur sed me feugiat ipsum molestie elit legentis. Lectorum praesent est eros non lorem. At possim soluta illum per ad. Amet tincidunt cum eua nibh mutationem.</p>
|
114
|
+
<p>Lectores, doming quarta, ad possim cum eua esse. Et quod eu quis id aliquip ii liber. In ex te, sequitur sed me feugiat ipsum molestie elit legentis. Lectorum praesent est eros non lorem. At possim soluta illum per ad. Amet tincidunt cum eua nibh mutationem.</p>
|
115
|
+
<p><img alt="none" src="http://farm4.static.flickr.com/3253/2496907243_5efbbab5cd_t.jpg" /> This image should be floating, but that's something the user can specify in the WYSIWYG editor, or the theme can define the float. Lectores, doming quarta, ad possim cum eua esse. Et quod eu quis id aliquip ii liber. In ex te, sequitur sed me feugiat ipsum molestie elit legentis. Lectorum praesent est eros non lorem. At possim soluta illum per ad. Amet tincidunt cum eua nibh mutationem.</p>
|
116
|
+
<p>Lectores, doming quarta, ad possim cum eua esse. Et quod eu quis id aliquip ii liber. In ex te, sequitur sed me feugiat ipsum molestie elit legentis. Lectorum praesent est eros non lorem. At possim soluta illum per ad. Amet tincidunt cum eua nibh mutationem.</p>
|
117
|
+
<!-- END DUMMY CONTENT -->
|
118
|
+
EOS
|
119
|
+
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'sinatra/base'
|
3
|
+
|
4
|
+
module ThemeKit
|
5
|
+
|
6
|
+
class Server < Sinatra::Base
|
7
|
+
|
8
|
+
get '/*' do
|
9
|
+
|
10
|
+
system_stylesheet = options.system_stylesheet
|
11
|
+
theme_directory = options.theme_directory
|
12
|
+
|
13
|
+
# Get the path they're requesting.
|
14
|
+
# If the path is empty, ie: "/", default to theme.html
|
15
|
+
path = params[:splat][0]
|
16
|
+
path = "theme.html" if path.length == 0
|
17
|
+
|
18
|
+
if path == "system.css"
|
19
|
+
file_path = system_stylesheet
|
20
|
+
puts "** Rendering system stylesheet: #{file_path}"
|
21
|
+
else
|
22
|
+
file_path = File.join(theme_directory, path)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Everything *except* theme.html can be statically served.
|
26
|
+
return send_file(file_path) unless path == "theme.html"
|
27
|
+
|
28
|
+
# Because sinatra is lame and doesn't keep GET variables when using
|
29
|
+
# a splat in the route.
|
30
|
+
begin
|
31
|
+
variations = request.url.split("?")[1].gsub(/%20/, ' ')
|
32
|
+
rescue
|
33
|
+
variations = 'default'
|
34
|
+
end
|
35
|
+
|
36
|
+
puts "** Rendering theme with variations: #{variations}"
|
37
|
+
|
38
|
+
begin
|
39
|
+
html = File.open(file_path).read()
|
40
|
+
return ThemeKit::Theme.render(html, {:variations => variations})
|
41
|
+
rescue
|
42
|
+
missing = File.join(theme_directory, 'theme.html')
|
43
|
+
return "<strong>Theme file doesn't exist:</strong> #{missing}"
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
#!/usr/bin/env ruby -wKU
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module ThemeKit
|
5
|
+
|
6
|
+
class Theme
|
7
|
+
|
8
|
+
attr_reader :name, :path, :example_path
|
9
|
+
|
10
|
+
def initialize(name, path)
|
11
|
+
@name = name
|
12
|
+
@path = path
|
13
|
+
@example_path = File.join(File.dirname(__FILE__), '../../example_theme')
|
14
|
+
end
|
15
|
+
|
16
|
+
def create
|
17
|
+
FileUtils.cp_r @example_path, File.join(@path, @name)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.render(html, options={})
|
21
|
+
data = {
|
22
|
+
:variations => 'default',
|
23
|
+
:title => "Welcome | CompuGlobal Exams",
|
24
|
+
:meta_tags => ThemeKit::Data::META_TAGS,
|
25
|
+
:main_nav => ThemeKit::Data::MAIN_NAV,
|
26
|
+
:user_nav => ThemeKit::Data::USER_NAV,
|
27
|
+
:page_title => "Welcome to my website",
|
28
|
+
:page_content => "#{ThemeKit::Data::DUMMY_HTML}<p>Yardstick ThemeKit: <strong>#{Time.now}</strong></p>",
|
29
|
+
:system_stylesheet_path => "system.css",
|
30
|
+
:stylesheet_path => "styles.css",
|
31
|
+
:image_path_prefix => "",
|
32
|
+
}.merge(options)
|
33
|
+
html.gsub!(/\{\{\s*theme_variation\s*\}\}/, data[:variations]) # {{ theme_variation }}
|
34
|
+
html.gsub!(/\{\{\s*title\s*\}\}/, data[:title]) # {{ title }}
|
35
|
+
html.gsub!(/\{\{\s*page.title\s*\}\}/, data[:page_title]) # {{ page.title }}
|
36
|
+
html.gsub!(/\{%\s*image image_data_id, (\w.*)\s*%\}/, "<img src=\"#{data[:image_path_prefix]}\\1\" />") # {% image ... %}
|
37
|
+
html.gsub!(/\{%\s*text text_data_id, (\w.*)\s*%\}/, "\\1") # {% text ... %}
|
38
|
+
html.gsub!(/\{%\s*page_meta\s*%\}/, data[:meta_tags]) # {% page_meta %}
|
39
|
+
html.gsub!(/\{%\s*menu main\s*%\}/, data[:main_nav]) # {% menu main %}
|
40
|
+
html.gsub!(/\{%\s*menu account\s*%\}/, data[:user_nav]) # {% menu account %}
|
41
|
+
html.gsub!(/\{\{\s*page.content\s*\}\}/, data[:page_content]) # {{ page.content }}
|
42
|
+
html.gsub!(/\{\{\s*system_stylesheet_path\s*\}\}/, data[:system_stylesheet_path]) # {{ system_stylesheet_path }}
|
43
|
+
html.gsub!(/\{\{\s*stylesheet_path\s*\}\}/, data[:stylesheet_path]) # {{ stylesheet_path }}
|
44
|
+
html
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
data/lib/themekit.rb
ADDED
Binary file
|
data/themekit.gemspec
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{themekit}
|
8
|
+
s.version = "0.0.8"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Yardstick Software"]
|
12
|
+
s.date = %q{2009-08-25}
|
13
|
+
s.default_executable = %q{themekit}
|
14
|
+
s.description = %q{A tiny app that makes designing Yardstick Measure themes a whole lot more enjoyable.}
|
15
|
+
s.email = %q{kyle@yardsticksoftware.com}
|
16
|
+
s.executables = ["themekit"]
|
17
|
+
s.extra_rdoc_files = [
|
18
|
+
"README.md"
|
19
|
+
]
|
20
|
+
s.files = [
|
21
|
+
"README.md",
|
22
|
+
"Rakefile",
|
23
|
+
"VERSION",
|
24
|
+
"bin/screenshots",
|
25
|
+
"bin/themekit",
|
26
|
+
"bin/webkit2png",
|
27
|
+
"example_theme/info.yml",
|
28
|
+
"example_theme/styles.css",
|
29
|
+
"example_theme/theme.html",
|
30
|
+
"github-test.rb",
|
31
|
+
"lib/themekit.rb",
|
32
|
+
"lib/themekit/data.rb",
|
33
|
+
"lib/themekit/server.rb",
|
34
|
+
"lib/themekit/theme.rb",
|
35
|
+
"pkg/themekit-0.0.7.gem",
|
36
|
+
"themekit.gemspec"
|
37
|
+
]
|
38
|
+
s.homepage = %q{http://github.com/yardstick/themekit}
|
39
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
40
|
+
s.require_paths = ["lib"]
|
41
|
+
s.rubygems_version = %q{1.3.3}
|
42
|
+
s.summary = %q{Enjoyable theming for Yardstick Measure.}
|
43
|
+
|
44
|
+
if s.respond_to? :specification_version then
|
45
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
46
|
+
s.specification_version = 3
|
47
|
+
|
48
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
49
|
+
s.add_runtime_dependency(%q<sinatra>, [">= 0.9.4"])
|
50
|
+
else
|
51
|
+
s.add_dependency(%q<sinatra>, [">= 0.9.4"])
|
52
|
+
end
|
53
|
+
else
|
54
|
+
s.add_dependency(%q<sinatra>, [">= 0.9.4"])
|
55
|
+
end
|
56
|
+
end
|
metadata
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: yardstick-themekit
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.8
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Yardstick Software
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-08-25 00:00:00 -07:00
|
13
|
+
default_executable: themekit
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: sinatra
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.9.4
|
24
|
+
version:
|
25
|
+
description: A tiny app that makes designing Yardstick Measure themes a whole lot more enjoyable.
|
26
|
+
email: kyle@yardsticksoftware.com
|
27
|
+
executables:
|
28
|
+
- themekit
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- README.md
|
33
|
+
files:
|
34
|
+
- README.md
|
35
|
+
- Rakefile
|
36
|
+
- VERSION
|
37
|
+
- bin/screenshots
|
38
|
+
- bin/themekit
|
39
|
+
- bin/webkit2png
|
40
|
+
- example_theme/info.yml
|
41
|
+
- example_theme/styles.css
|
42
|
+
- example_theme/theme.html
|
43
|
+
- github-test.rb
|
44
|
+
- lib/themekit.rb
|
45
|
+
- lib/themekit/data.rb
|
46
|
+
- lib/themekit/server.rb
|
47
|
+
- lib/themekit/theme.rb
|
48
|
+
- pkg/themekit-0.0.7.gem
|
49
|
+
- themekit.gemspec
|
50
|
+
has_rdoc: false
|
51
|
+
homepage: http://github.com/yardstick/themekit
|
52
|
+
post_install_message:
|
53
|
+
rdoc_options:
|
54
|
+
- --charset=UTF-8
|
55
|
+
require_paths:
|
56
|
+
- lib
|
57
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: "0"
|
62
|
+
version:
|
63
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: "0"
|
68
|
+
version:
|
69
|
+
requirements: []
|
70
|
+
|
71
|
+
rubyforge_project:
|
72
|
+
rubygems_version: 1.2.0
|
73
|
+
signing_key:
|
74
|
+
specification_version: 3
|
75
|
+
summary: Enjoyable theming for Yardstick Measure.
|
76
|
+
test_files: []
|
77
|
+
|