showoff 0.0.7 → 0.1.0
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.
- 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
|