showoff 0.0.7 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/princely.rb +84 -0
- data/lib/showoff.rb +73 -18
- data/public/css/onepage.css +11 -0
- data/public/css/pdf.css +12 -0
- data/public/css/sh_style.css +1 -1
- data/public/css/showoff.css +0 -1
- data/public/js/onepage.js +10 -0
- data/views/onepage.erb +37 -0
- metadata +6 -1
data/lib/princely.rb
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
# PrinceXML Ruby interface.
|
2
|
+
# http://www.princexml.com
|
3
|
+
#
|
4
|
+
# Library by Subimage Interactive - http://www.subimage.com
|
5
|
+
#
|
6
|
+
#
|
7
|
+
# USAGE
|
8
|
+
# -----------------------------------------------------------------------------
|
9
|
+
# princely = Princely.new()
|
10
|
+
# html_string = render_to_string(:template => 'some_document')
|
11
|
+
# send_data(
|
12
|
+
# princely.pdf_from_string(html_string),
|
13
|
+
# :filename => 'some_document.pdf'
|
14
|
+
# :type => 'application/pdf'
|
15
|
+
# )
|
16
|
+
#
|
17
|
+
$:.unshift(File.dirname(__FILE__))
|
18
|
+
|
19
|
+
class Princely
|
20
|
+
VERSION = "1.0.0" unless const_defined?("VERSION")
|
21
|
+
|
22
|
+
attr_accessor :exe_path, :style_sheets, :log_file
|
23
|
+
|
24
|
+
# Initialize method
|
25
|
+
#
|
26
|
+
def initialize()
|
27
|
+
# Finds where the application lives, so we can call it.
|
28
|
+
@exe_path = `which prince`.chomp
|
29
|
+
raise "Cannot find prince command-line app in $PATH" if @exe_path.length == 0
|
30
|
+
@style_sheets = ''
|
31
|
+
@log_file = "/tmp/prince.log"
|
32
|
+
end
|
33
|
+
|
34
|
+
# Sets stylesheets...
|
35
|
+
# Can pass in multiple paths for css files.
|
36
|
+
#
|
37
|
+
def add_style_sheets(*sheets)
|
38
|
+
for sheet in sheets do
|
39
|
+
@style_sheets << " -s #{sheet} "
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Returns fully formed executable path with any command line switches
|
44
|
+
# we've set based on our variables.
|
45
|
+
#
|
46
|
+
def exe_path
|
47
|
+
# Add any standard cmd line arguments we need to pass
|
48
|
+
@exe_path << " --input=html --server --log=#{@log_file} "
|
49
|
+
@exe_path << @style_sheets
|
50
|
+
return @exe_path
|
51
|
+
end
|
52
|
+
|
53
|
+
# Makes a pdf from a passed in string.
|
54
|
+
#
|
55
|
+
# Returns PDF as a stream, so we can use send_data to shoot
|
56
|
+
# it down the pipe using Rails.
|
57
|
+
#
|
58
|
+
def pdf_from_string(string, output_file = '-')
|
59
|
+
path = self.exe_path()
|
60
|
+
# Don't spew errors to the standard out...and set up to take IO
|
61
|
+
# as input and output
|
62
|
+
path << ' --silent - -o -'
|
63
|
+
|
64
|
+
# Actually call the prince command, and pass the entire data stream back.
|
65
|
+
pdf = IO.popen(path, "w+")
|
66
|
+
pdf.puts(string)
|
67
|
+
pdf.close_write
|
68
|
+
result = pdf.gets(nil)
|
69
|
+
pdf.close_read
|
70
|
+
return result
|
71
|
+
end
|
72
|
+
|
73
|
+
def pdf_from_string_to_file(string, output_file)
|
74
|
+
path = self.exe_path()
|
75
|
+
# Don't spew errors to the standard out...and set up to take IO
|
76
|
+
# as input and output
|
77
|
+
path << " --silent - -o '#{output_file}' >> '#{@log_file}' 2>> '#{@log_file}'"
|
78
|
+
|
79
|
+
# Actually call the prince command, and pass the entire data stream back.
|
80
|
+
pdf = IO.popen(path, "w+")
|
81
|
+
pdf.puts(string)
|
82
|
+
pdf.close
|
83
|
+
end
|
84
|
+
end
|
data/lib/showoff.rb
CHANGED
@@ -4,6 +4,13 @@ require 'json'
|
|
4
4
|
require 'nokogiri'
|
5
5
|
require 'showoff_utils'
|
6
6
|
|
7
|
+
begin
|
8
|
+
require 'prawn'
|
9
|
+
require 'princely'
|
10
|
+
rescue LoadError
|
11
|
+
puts 'pdf generation disabled - install prawn'
|
12
|
+
end
|
13
|
+
|
7
14
|
begin
|
8
15
|
require 'rdiscount'
|
9
16
|
rescue LoadError
|
@@ -45,7 +52,7 @@ class ShowOff < Sinatra::Application
|
|
45
52
|
Dir.glob("#{options.pres_dir}/*.js").map { |path| File.basename(path) }
|
46
53
|
end
|
47
54
|
|
48
|
-
def process_markdown(name, content)
|
55
|
+
def process_markdown(name, content, wrap = false)
|
49
56
|
slides = content.split(/^!SLIDE/)
|
50
57
|
slides.delete('')
|
51
58
|
final = ''
|
@@ -57,6 +64,7 @@ class ShowOff < Sinatra::Application
|
|
57
64
|
lines = slide.split("\n")
|
58
65
|
classes = lines.shift
|
59
66
|
slide = lines.join("\n")
|
67
|
+
md += '<div class="' + wrap + '">' if wrap
|
60
68
|
if seq
|
61
69
|
md += "<div class=\"slide #{classes}\" ref=\"#{name}/#{seq.to_s}\">\n"
|
62
70
|
seq += 1
|
@@ -67,6 +75,7 @@ class ShowOff < Sinatra::Application
|
|
67
75
|
sl = update_image_paths(name, sl)
|
68
76
|
md += sl
|
69
77
|
md += "</div>\n"
|
78
|
+
md += "</div>\n" if wrap
|
70
79
|
final += update_commandline_code(md)
|
71
80
|
end
|
72
81
|
final
|
@@ -114,6 +123,55 @@ class ShowOff < Sinatra::Application
|
|
114
123
|
end
|
115
124
|
html.root.to_s
|
116
125
|
end
|
126
|
+
|
127
|
+
def get_slides_html(wrap = false)
|
128
|
+
index = File.join(options.pres_dir, 'showoff.json')
|
129
|
+
files = []
|
130
|
+
if File.exists?(index)
|
131
|
+
order = JSON.parse(File.read(index))
|
132
|
+
order = order.map { |s| s['section'] }
|
133
|
+
order.each do |section|
|
134
|
+
files << load_section_files(section)
|
135
|
+
end
|
136
|
+
files = files.flatten
|
137
|
+
files = files.select { |f| f =~ /.md/ }
|
138
|
+
data = ''
|
139
|
+
files.each do |f|
|
140
|
+
fname = f.gsub(options.pres_dir + '/', '').gsub('.md', '')
|
141
|
+
data += process_markdown(fname, File.read(f), wrap)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
data
|
145
|
+
end
|
146
|
+
|
147
|
+
def inline_css(csses, pre = nil)
|
148
|
+
css_content = '<style type="text/css">'
|
149
|
+
csses.each do |css_file|
|
150
|
+
if pre
|
151
|
+
css_file = File.join(File.dirname(__FILE__), '..', pre, css_file)
|
152
|
+
else
|
153
|
+
css_file = File.join(options.pres_dir, css_file)
|
154
|
+
end
|
155
|
+
css_content += File.read(css_file)
|
156
|
+
end
|
157
|
+
css_content += '</style>'
|
158
|
+
css_content
|
159
|
+
end
|
160
|
+
|
161
|
+
def inline_js(jses, pre = nil)
|
162
|
+
js_content = '<script type="text/javascript">'
|
163
|
+
jses.each do |js_file|
|
164
|
+
if pre
|
165
|
+
js_file = File.join(File.dirname(__FILE__), '..', pre, js_file)
|
166
|
+
else
|
167
|
+
js_file = File.join(options.pres_dir, js_file)
|
168
|
+
end
|
169
|
+
js_content += File.read(js_file)
|
170
|
+
end
|
171
|
+
js_content += '</script>'
|
172
|
+
js_content
|
173
|
+
end
|
174
|
+
|
117
175
|
end
|
118
176
|
|
119
177
|
get '/' do
|
@@ -127,24 +185,21 @@ class ShowOff < Sinatra::Application
|
|
127
185
|
end
|
128
186
|
|
129
187
|
get '/slides' do
|
130
|
-
|
131
|
-
|
132
|
-
if File.exists?(index)
|
133
|
-
order = JSON.parse(File.read(index))
|
134
|
-
order = order.map { |s| s['section'] }
|
135
|
-
order.each do |section|
|
136
|
-
files << load_section_files(section)
|
188
|
+
get_slides_html
|
189
|
+
end
|
137
190
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
191
|
+
get '/onepage' do
|
192
|
+
@slides = get_slides_html('preso')
|
193
|
+
erb :onepage
|
194
|
+
end
|
195
|
+
|
196
|
+
get '/pdf' do
|
197
|
+
@slides = get_slides_html('preso')
|
198
|
+
@no_js = true
|
199
|
+
html = erb :onepage
|
200
|
+
p = Princely.new
|
201
|
+
p.pdf_from_string_to_file(html, '/tmp/preso.pdf')
|
202
|
+
send_file '/tmp/preso.pdf'
|
148
203
|
end
|
149
204
|
|
150
205
|
end
|
data/public/css/pdf.css
ADDED
data/public/css/sh_style.css
CHANGED
@@ -14,7 +14,7 @@ pre.sh_sourceCode .sh_specialchar { color: pink; font-family: monospace; } /* e
|
|
14
14
|
pre.sh_sourceCode .sh_comment { color: brown; font-style: italic; } /* comments */
|
15
15
|
pre.sh_sourceCode .sh_number { color: purple; } /* literal numbers */
|
16
16
|
pre.sh_sourceCode .sh_preproc { color: darkblue; font-weight: bold; } /* e.g., #include, import */
|
17
|
-
pre.sh_sourceCode .sh_symbol { color: darkred; } /*
|
17
|
+
pre.sh_sourceCode .sh_symbol { color: darkred; } /* */
|
18
18
|
pre.sh_sourceCode .sh_function { color: black; font-weight: bold; } /* function calls and declarations */
|
19
19
|
pre.sh_sourceCode .sh_cbracket { color: red; } /* block brackets (e.g., {, }) */
|
20
20
|
pre.sh_sourceCode .sh_todo { font-weight: bold; background-color: cyan; } /* TODO and FIXME */
|
data/public/css/showoff.css
CHANGED
@@ -0,0 +1,10 @@
|
|
1
|
+
function setupOnePage() {
|
2
|
+
sh_highlightDocument('/js/sh_lang/', '.min.js')
|
3
|
+
|
4
|
+
$(".preso > .slide").each(function(s, elem) {
|
5
|
+
var slide_height = $(elem).height()
|
6
|
+
var mar_top = (0.5 * parseFloat($(elem).parent().height())) - (0.5 * parseFloat(slide_height))
|
7
|
+
$(elem).css('margin-top', mar_top)
|
8
|
+
})
|
9
|
+
|
10
|
+
}
|
data/views/onepage.erb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
3
|
+
|
4
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
5
|
+
<head>
|
6
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
7
|
+
|
8
|
+
<title>Presentation</title>
|
9
|
+
|
10
|
+
<% if @no_js %>
|
11
|
+
<%= inline_css(['pdf.css'], 'public/css') %>
|
12
|
+
<% else %>
|
13
|
+
<%= inline_css(['onepage.css'], 'public/css') %>
|
14
|
+
<% end %>
|
15
|
+
<%= inline_css(['showoff.css', 'theme/ui.all.css', 'sh_style.css'], 'public/css') %>
|
16
|
+
<% css_files.each do |css_file| %>
|
17
|
+
<%= inline_css(css_file) %>
|
18
|
+
<% end %>
|
19
|
+
|
20
|
+
<% if !@no_js %>
|
21
|
+
<%= inline_js(['jquery-1.4.min.js', 'jquery-print.js', 'showoff.js', 'onepage.js', 'sh_main.min.js'], 'public/js') %>
|
22
|
+
<script type="text/javascript">
|
23
|
+
$(function(){
|
24
|
+
setupOnePage()
|
25
|
+
});
|
26
|
+
</script>
|
27
|
+
<% end %>
|
28
|
+
</head>
|
29
|
+
|
30
|
+
<body>
|
31
|
+
|
32
|
+
<div id="slides">
|
33
|
+
<%= @slides %>
|
34
|
+
</div>
|
35
|
+
|
36
|
+
</body>
|
37
|
+
</html>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: showoff
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Scott Chacon
|
@@ -65,10 +65,14 @@ files:
|
|
65
65
|
- Rakefile
|
66
66
|
- LICENSE
|
67
67
|
- bin/showoff
|
68
|
+
- lib/princely.rb
|
68
69
|
- lib/showoff.rb
|
69
70
|
- lib/showoff_utils.rb
|
70
71
|
- views/index.erb
|
72
|
+
- views/onepage.erb
|
71
73
|
- public/css/fg.menu.css
|
74
|
+
- public/css/onepage.css
|
75
|
+
- public/css/pdf.css
|
72
76
|
- public/css/sh_style.css
|
73
77
|
- public/css/showoff.css
|
74
78
|
- public/css/theme/images/ui-bg_diagonals-small_100_f0efea_40x40.png
|
@@ -101,6 +105,7 @@ files:
|
|
101
105
|
- public/js/jquery-1.4.min.js
|
102
106
|
- public/js/jquery-print.js
|
103
107
|
- public/js/jTypeWriter.js
|
108
|
+
- public/js/onepage.js
|
104
109
|
- public/js/sh_lang/sh_bison.min.js
|
105
110
|
- public/js/sh_lang/sh_c.min.js
|
106
111
|
- public/js/sh_lang/sh_caml.min.js
|