briefing 0.0.1
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/.gitignore +4 -0
- data/.gitmodules +3 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +95 -0
- data/Rakefile +26 -0
- data/bin/briefing +28 -0
- data/briefing.gemspec +19 -0
- data/lib/briefing/app.rb +20 -0
- data/lib/briefing/public/css/print/paper.css +176 -0
- data/lib/briefing/public/css/print/pdf.css +160 -0
- data/lib/briefing/public/css/reveal.css +1281 -0
- data/lib/briefing/public/css/reveal.min.css +7 -0
- data/lib/briefing/public/css/shaders/tile-flip.fs +64 -0
- data/lib/briefing/public/css/shaders/tile-flip.vs +141 -0
- data/lib/briefing/public/css/theme/README.md +5 -0
- data/lib/briefing/public/css/theme/beige.css +163 -0
- data/lib/briefing/public/css/theme/default.css +163 -0
- data/lib/briefing/public/css/theme/night.css +150 -0
- data/lib/briefing/public/css/theme/serif.css +150 -0
- data/lib/briefing/public/css/theme/simple.css +152 -0
- data/lib/briefing/public/css/theme/sky.css +156 -0
- data/lib/briefing/public/css/theme/source/beige.scss +50 -0
- data/lib/briefing/public/css/theme/source/default.scss +42 -0
- data/lib/briefing/public/css/theme/source/night.scss +35 -0
- data/lib/briefing/public/css/theme/source/serif.scss +33 -0
- data/lib/briefing/public/css/theme/source/simple.scss +38 -0
- data/lib/briefing/public/css/theme/source/sky.scss +41 -0
- data/lib/briefing/public/css/theme/template/mixins.scss +29 -0
- data/lib/briefing/public/css/theme/template/settings.scss +33 -0
- data/lib/briefing/public/css/theme/template/theme.scss +163 -0
- data/lib/briefing/public/js/reveal.js +1634 -0
- data/lib/briefing/public/js/reveal.min.js +8 -0
- data/lib/briefing/public/lib/css/zenburn.css +115 -0
- data/lib/briefing/public/lib/font/league_gothic-webfont.eot +0 -0
- data/lib/briefing/public/lib/font/league_gothic-webfont.svg +230 -0
- data/lib/briefing/public/lib/font/league_gothic-webfont.ttf +0 -0
- data/lib/briefing/public/lib/font/league_gothic-webfont.woff +0 -0
- data/lib/briefing/public/lib/font/league_gothic_license +2 -0
- data/lib/briefing/public/lib/js/classList.js +2 -0
- data/lib/briefing/public/lib/js/head.min.js +8 -0
- data/lib/briefing/public/lib/js/html5shiv.js +7 -0
- data/lib/briefing/public/plugin/highlight/highlight.js +14 -0
- data/lib/briefing/public/plugin/markdown/markdown.js +37 -0
- data/lib/briefing/public/plugin/markdown/showdown.js +62 -0
- data/lib/briefing/public/plugin/notes/notes.html +143 -0
- data/lib/briefing/public/plugin/notes/notes.js +98 -0
- data/lib/briefing/public/plugin/notes-server/client.js +57 -0
- data/lib/briefing/public/plugin/notes-server/index.js +58 -0
- data/lib/briefing/public/plugin/notes-server/notes.html +139 -0
- data/lib/briefing/public/plugin/postmessage/example.html +39 -0
- data/lib/briefing/public/plugin/postmessage/postmessage.js +42 -0
- data/lib/briefing/public/plugin/remotes/remotes.js +19 -0
- data/lib/briefing/public/plugin/zoom-js/zoom.js +251 -0
- data/lib/briefing/slides.rb +37 -0
- data/lib/briefing/version.rb +3 -0
- data/lib/briefing/views/index.erb +79 -0
- data/lib/briefing.rb +5 -0
- data/vendor/.gitkeep +0 -0
- metadata +140 -0
@@ -0,0 +1,37 @@
|
|
1
|
+
// From https://gist.github.com/1343518
|
2
|
+
// Modified by Hakim to handle Markdown indented with tabs
|
3
|
+
(function(){
|
4
|
+
|
5
|
+
if( typeof Showdown === 'undefined' ) {
|
6
|
+
throw 'The reveal.js Markdown plugin requires Showdown to be loaded';
|
7
|
+
}
|
8
|
+
|
9
|
+
var sections = document.querySelectorAll( '[data-markdown]' );
|
10
|
+
|
11
|
+
for( var i = 0, len = sections.length; i < len; i++ ) {
|
12
|
+
var section = sections[i];
|
13
|
+
var notes = section.querySelector( 'aside.notes' );
|
14
|
+
|
15
|
+
var template = section.querySelector( 'script' );
|
16
|
+
|
17
|
+
// strip leading whitespace so it isn't evaluated as code
|
18
|
+
var text = ( template || section ).innerHTML;
|
19
|
+
|
20
|
+
var leadingWs = text.match(/^\n?(\s*)/)[1].length,
|
21
|
+
leadingTabs = text.match(/^\n?(\t*)/)[1].length;
|
22
|
+
|
23
|
+
if( leadingTabs > 0 ) {
|
24
|
+
text = text.replace( new RegExp('\\n?\\t{' + leadingTabs + '}','g'), '\n' );
|
25
|
+
}
|
26
|
+
else if( leadingWs > 1 ) {
|
27
|
+
text = text.replace( new RegExp('\\n? {' + leadingWs + '}','g'), '\n' );
|
28
|
+
}
|
29
|
+
|
30
|
+
section.innerHTML = (new Showdown.converter()).makeHtml(text);
|
31
|
+
|
32
|
+
if( notes ) {
|
33
|
+
section.appendChild( notes );
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
})();
|
@@ -0,0 +1,62 @@
|
|
1
|
+
//
|
2
|
+
// showdown.js -- A javascript port of Markdown.
|
3
|
+
//
|
4
|
+
// Copyright (c) 2007 John Fraser.
|
5
|
+
//
|
6
|
+
// Original Markdown Copyright (c) 2004-2005 John Gruber
|
7
|
+
// <http://daringfireball.net/projects/markdown/>
|
8
|
+
//
|
9
|
+
// Redistributable under a BSD-style open source license.
|
10
|
+
// See license.txt for more information.
|
11
|
+
//
|
12
|
+
// The full source distribution is at:
|
13
|
+
//
|
14
|
+
// A A L
|
15
|
+
// T C A
|
16
|
+
// T K B
|
17
|
+
//
|
18
|
+
// <http://www.attacklab.net/>
|
19
|
+
//
|
20
|
+
//
|
21
|
+
// Wherever possible, Showdown is a straight, line-by-line port
|
22
|
+
// of the Perl version of Markdown.
|
23
|
+
//
|
24
|
+
// This is not a normal parser design; it's basically just a
|
25
|
+
// series of string substitutions. It's hard to read and
|
26
|
+
// maintain this way, but keeping Showdown close to the original
|
27
|
+
// design makes it easier to port new features.
|
28
|
+
//
|
29
|
+
// More importantly, Showdown behaves like markdown.pl in most
|
30
|
+
// edge cases. So web applications can do client-side preview
|
31
|
+
// in Javascript, and then build identical HTML on the server.
|
32
|
+
//
|
33
|
+
// This port needs the new RegExp functionality of ECMA 262,
|
34
|
+
// 3rd Edition (i.e. Javascript 1.5). Most modern web browsers
|
35
|
+
// should do fine. Even with the new regular expression features,
|
36
|
+
// We do a lot of work to emulate Perl's regex functionality.
|
37
|
+
// The tricky changes in this file mostly have the "attacklab:"
|
38
|
+
// label. Major or self-explanatory changes don't.
|
39
|
+
//
|
40
|
+
// Smart diff tools like Araxis Merge will be able to match up
|
41
|
+
// this file with markdown.pl in a useful way. A little tweaking
|
42
|
+
// helps: in a copy of markdown.pl, replace "#" with "//" and
|
43
|
+
// replace "$text" with "text". Be sure to ignore whitespace
|
44
|
+
// and line endings.
|
45
|
+
//
|
46
|
+
//
|
47
|
+
// Showdown usage:
|
48
|
+
//
|
49
|
+
// var text = "Markdown *rocks*.";
|
50
|
+
//
|
51
|
+
// var converter = new Showdown.converter();
|
52
|
+
// var html = converter.makeHtml(text);
|
53
|
+
//
|
54
|
+
// alert(html);
|
55
|
+
//
|
56
|
+
// Note: move the sample code to the bottom of this
|
57
|
+
// file before uncommenting it.
|
58
|
+
//
|
59
|
+
//
|
60
|
+
// Showdown namespace
|
61
|
+
//
|
62
|
+
var Showdown={};Showdown.converter=function(){var a,b,c,d=0;this.makeHtml=function(d){return a=new Array,b=new Array,c=new Array,d=d.replace(/~/g,"~T"),d=d.replace(/\$/g,"~D"),d=d.replace(/\r\n/g,"\n"),d=d.replace(/\r/g,"\n"),d="\n\n"+d+"\n\n",d=F(d),d=d.replace(/^[ \t]+$/mg,""),d=f(d),d=e(d),d=h(d),d=D(d),d=d.replace(/~D/g,"$$"),d=d.replace(/~T/g,"~"),d};var e=function(c){var c=c.replace(/^[ ]{0,3}\[(.+)\]:[ \t]*\n?[ \t]*<?(\S+?)>?[ \t]*\n?[ \t]*(?:(\n*)["(](.+?)[")][ \t]*)?(?:\n+|\Z)/gm,function(c,d,e,f,g){return d=d.toLowerCase(),a[d]=z(e),f?f+g:(g&&(b[d]=g.replace(/"/g,""")),"")});return c},f=function(a){a=a.replace(/\n/g,"\n\n");var b="p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del",c="p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math";return a=a.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del)\b[^\r]*?\n<\/\2>[ \t]*(?=\n+))/gm,g),a=a.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math)\b[^\r]*?.*<\/\2>[ \t]*(?=\n+)\n)/gm,g),a=a.replace(/(\n[ ]{0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g,g),a=a.replace(/(\n\n[ ]{0,3}<!(--[^\r]*?--\s*)+>[ \t]*(?=\n{2,}))/g,g),a=a.replace(/(?:\n\n)([ ]{0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g,g),a=a.replace(/\n\n/g,"\n"),a},g=function(a,b){var d=b;return d=d.replace(/\n\n/g,"\n"),d=d.replace(/^\n/,""),d=d.replace(/\n+$/g,""),d="\n\n~K"+(c.push(d)-1)+"K\n\n",d},h=function(a){a=o(a);var b=t("<hr />");return a=a.replace(/^[ ]{0,2}([ ]?\*[ ]?){3,}[ \t]*$/gm,b),a=a.replace(/^[ ]{0,2}([ ]?\-[ ]?){3,}[ \t]*$/gm,b),a=a.replace(/^[ ]{0,2}([ ]?\_[ ]?){3,}[ \t]*$/gm,b),a=q(a),a=s(a),a=r(a),a=x(a),a=f(a),a=y(a),a},i=function(a){return a=u(a),a=j(a),a=A(a),a=m(a),a=k(a),a=B(a),a=z(a),a=w(a),a=a.replace(/ +\n/g," <br />\n"),a},j=function(a){var b=/(<[a-z\/!$]("[^"]*"|'[^']*'|[^'">])*>|<!(--.*?--\s*)+>)/gi;return a=a.replace(b,function(a){var b=a.replace(/(.)<\/?code>(?=.)/g,"$1`");return b=G(b,"\\`*_"),b}),a},k=function(a){return a=a.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g,l),a=a.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\]\([ \t]*()<?(.*?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g,l),a=a.replace(/(\[([^\[\]]+)\])()()()()()/g,l),a},l=function(c,d,e,f,g,h,i,j){j==undefined&&(j="");var k=d,l=e,m=f.toLowerCase(),n=g,o=j;if(n==""){m==""&&(m=l.toLowerCase().replace(/ ?\n/g," ")),n="#"+m;if(a[m]!=undefined)n=a[m],b[m]!=undefined&&(o=b[m]);else{if(!(k.search(/\(\s*\)$/m)>-1))return k;n=""}}n=G(n,"*_");var p='<a href="'+n+'"';return o!=""&&(o=o.replace(/"/g,"""),o=G(o,"*_"),p+=' title="'+o+'"'),p+=">"+l+"</a>",p},m=function(a){return a=a.replace(/(!\[(.*?)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g,n),a=a.replace(/(!\[(.*?)\]\s?\([ \t]*()<?(\S+?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g,n),a},n=function(c,d,e,f,g,h,i,j){var k=d,l=e,m=f.toLowerCase(),n=g,o=j;o||(o="");if(n==""){m==""&&(m=l.toLowerCase().replace(/ ?\n/g," ")),n="#"+m;if(a[m]==undefined)return k;n=a[m],b[m]!=undefined&&(o=b[m])}l=l.replace(/"/g,"""),n=G(n,"*_");var p='<img src="'+n+'" alt="'+l+'"';return o=o.replace(/"/g,"""),o=G(o,"*_"),p+=' title="'+o+'"',p+=" />",p},o=function(a){function b(a){return a.replace(/[^\w]/g,"").toLowerCase()}return a=a.replace(/^(.+)[ \t]*\n=+[ \t]*\n+/gm,function(a,c){return t('<h1 id="'+b(c)+'">'+i(c)+"</h1>")}),a=a.replace(/^(.+)[ \t]*\n-+[ \t]*\n+/gm,function(a,c){return t('<h2 id="'+b(c)+'">'+i(c)+"</h2>")}),a=a.replace(/^(\#{1,6})[ \t]*(.+?)[ \t]*\#*\n+/gm,function(a,c,d){var e=c.length;return t("<h"+e+' id="'+b(d)+'">'+i(d)+"</h"+e+">")}),a},p,q=function(a){a+="~0";var b=/^(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm;return d?a=a.replace(b,function(a,b,c){var d=b,e=c.search(/[*+-]/g)>-1?"ul":"ol";d=d.replace(/\n{2,}/g,"\n\n\n");var f=p(d);return f=f.replace(/\s+$/,""),f="<"+e+">"+f+"</"+e+">\n",f}):(b=/(\n\n|^\n?)(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/g,a=a.replace(b,function(a,b,c,d){var e=b,f=c,g=d.search(/[*+-]/g)>-1?"ul":"ol",f=f.replace(/\n{2,}/g,"\n\n\n"),h=p(f);return h=e+"<"+g+">\n"+h+"</"+g+">\n",h})),a=a.replace(/~0/,""),a};p=function(a){return d++,a=a.replace(/\n{2,}$/,"\n"),a+="~0",a=a.replace(/(\n)?(^[ \t]*)([*+-]|\d+[.])[ \t]+([^\r]+?(\n{1,2}))(?=\n*(~0|\2([*+-]|\d+[.])[ \t]+))/gm,function(a,b,c,d,e){var f=e,g=b,j=c;return g||f.search(/\n{2,}/)>-1?f=h(E(f)):(f=q(E(f)),f=f.replace(/\n$/,""),f=i(f)),"<li>"+f+"</li>\n"}),a=a.replace(/~0/g,""),d--,a};var r=function(a){return a+="~0",a=a.replace(/(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=~0))/g,function(a,b,c){var d=b,e=c;return d=v(E(d)),d=F(d),d=d.replace(/^\n+/g,""),d=d.replace(/\n+$/g,""),d="<pre><code>"+d+"\n</code></pre>",t(d)+e}),a=a.replace(/~0/,""),a},s=function(a){return a+="~0",a=a.replace(/\n```(.*)\n([^`]+)\n```/g,function(a,b,c){var d=b,e=c;return e=v(e),e=F(e),e=e.replace(/^\n+/g,""),e=e.replace(/\n+$/g,""),e="<pre><code class="+d+">"+e+"\n</code></pre>",t(e)}),a=a.replace(/~0/,""),a},t=function(a){return a=a.replace(/(^\n+|\n+$)/g,""),"\n\n~K"+(c.push(a)-1)+"K\n\n"},u=function(a){return a=a.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm,function(a,b,c,d,e){var f=d;return f=f.replace(/^([ \t]*)/g,""),f=f.replace(/[ \t]*$/g,""),f=v(f),b+"<code>"+f+"</code>"}),a},v=function(a){return a=a.replace(/&/g,"&"),a=a.replace(/</g,"<"),a=a.replace(/>/g,">"),a=G(a,"*_{}[]\\",!1),a},w=function(a){return a=a.replace(/(\*\*|__)(?=\S)([^\r]*?\S[*_]*)\1/g,"<strong>$2</strong>"),a=a.replace(/(\*|_)(?=\S)([^\r]*?\S)\1/g,"<em>$2</em>"),a},x=function(a){return a=a.replace(/((^[ \t]*>[ \t]?.+\n(.+\n)*\n*)+)/gm,function(a,b){var c=b;return c=c.replace(/^[ \t]*>[ \t]?/gm,"~0"),c=c.replace(/~0/g,""),c=c.replace(/^[ \t]+$/gm,""),c=h(c),c=c.replace(/(^|\n)/g,"$1 "),c=c.replace(/(\s*<pre>[^\r]+?<\/pre>)/gm,function(a,b){var c=b;return c=c.replace(/^ /mg,"~0"),c=c.replace(/~0/g,""),c}),t("<blockquote>\n"+c+"\n</blockquote>")}),a},y=function(a){a=a.replace(/^\n+/g,""),a=a.replace(/\n+$/g,"");var b=a.split(/\n{2,}/g),d=new Array,e=b.length;for(var f=0;f<e;f++){var g=b[f];g.search(/~K(\d+)K/g)>=0?d.push(g):g.search(/\S/)>=0&&(g=i(g),g=g.replace(/^([ \t]*)/g,"<p>"),g+="</p>",d.push(g))}e=d.length;for(var f=0;f<e;f++)while(d[f].search(/~K(\d+)K/)>=0){var h=c[RegExp.$1];h=h.replace(/\$/g,"$$$$"),d[f]=d[f].replace(/~K\d+K/,h)}return d.join("\n\n")},z=function(a){return a=a.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g,"&"),a=a.replace(/<(?![a-z\/?\$!])/gi,"<"),a},A=function(a){return a=a.replace(/\\(\\)/g,H),a=a.replace(/\\([`*_{}\[\]()>#+-.!])/g,H),a},B=function(a){return a=a.replace(/<((https?|ftp|dict):[^'">\s]+)>/gi,'<a href="$1">$1</a>'),a=a.replace(/<(?:mailto:)?([-.\w]+\@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi,function(a,b){return C(D(b))}),a},C=function(a){function b(a){var b="0123456789ABCDEF",c=a.charCodeAt(0);return b.charAt(c>>4)+b.charAt(c&15)}var c=[function(a){return"&#"+a.charCodeAt(0)+";"},function(a){return"&#x"+b(a)+";"},function(a){return a}];return a="mailto:"+a,a=a.replace(/./g,function(a){if(a=="@")a=c[Math.floor(Math.random()*2)](a);else if(a!=":"){var b=Math.random();a=b>.9?c[2](a):b>.45?c[1](a):c[0](a)}return a}),a='<a href="'+a+'">'+a+"</a>",a=a.replace(/">.+:/g,'">'),a},D=function(a){return a=a.replace(/~E(\d+)E/g,function(a,b){var c=parseInt(b);return String.fromCharCode(c)}),a},E=function(a){return a=a.replace(/^(\t|[ ]{1,4})/gm,"~0"),a=a.replace(/~0/g,""),a},F=function(a){return a=a.replace(/\t(?=\t)/g," "),a=a.replace(/\t/g,"~A~B"),a=a.replace(/~B(.+?)~A/g,function(a,b,c){var d=b,e=4-d.length%4;for(var f=0;f<e;f++)d+=" ";return d}),a=a.replace(/~A/g," "),a=a.replace(/~B/g,""),a},G=function(a,b,c){var d="(["+b.replace(/([\[\]\\])/g,"\\$1")+"])";c&&(d="\\\\"+d);var e=new RegExp(d,"g");return a=a.replace(e,H),a},H=function(a,b){var c=b.charCodeAt(0);return"~E"+c+"E"}},typeof exports!="undefined"&&(exports=Showdown);
|
@@ -0,0 +1,143 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<html lang="en">
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
|
6
|
+
<title>reveal.js - Slide Notes</title>
|
7
|
+
|
8
|
+
<style>
|
9
|
+
body {
|
10
|
+
font-family: Helvetica;
|
11
|
+
}
|
12
|
+
|
13
|
+
#notes {
|
14
|
+
font-size: 24px;
|
15
|
+
width: 640px;
|
16
|
+
margin-top: 5px;
|
17
|
+
}
|
18
|
+
|
19
|
+
#wrap-current-slide {
|
20
|
+
width: 640px;
|
21
|
+
height: 512px;
|
22
|
+
float: left;
|
23
|
+
overflow: hidden;
|
24
|
+
}
|
25
|
+
|
26
|
+
#current-slide {
|
27
|
+
width: 1280px;
|
28
|
+
height: 1024px;
|
29
|
+
border: none;
|
30
|
+
|
31
|
+
-webkit-transform-origin: 0 0;
|
32
|
+
-moz-transform-origin: 0 0;
|
33
|
+
-ms-transform-origin: 0 0;
|
34
|
+
-o-transform-origin: 0 0;
|
35
|
+
transform-origin: 0 0;
|
36
|
+
|
37
|
+
-webkit-transform: scale(0.5);
|
38
|
+
-moz-transform: scale(0.5);
|
39
|
+
-ms-transform: scale(0.5);
|
40
|
+
-o-transform: scale(0.5);
|
41
|
+
transform: scale(0.5);
|
42
|
+
}
|
43
|
+
|
44
|
+
#wrap-next-slide {
|
45
|
+
width: 448px;
|
46
|
+
height: 358px;
|
47
|
+
float: left;
|
48
|
+
margin: 0 0 0 10px;
|
49
|
+
overflow: hidden;
|
50
|
+
}
|
51
|
+
|
52
|
+
#next-slide {
|
53
|
+
width: 1280px;
|
54
|
+
height: 1024px;
|
55
|
+
border: none;
|
56
|
+
|
57
|
+
-webkit-transform-origin: 0 0;
|
58
|
+
-moz-transform-origin: 0 0;
|
59
|
+
-ms-transform-origin: 0 0;
|
60
|
+
-o-transform-origin: 0 0;
|
61
|
+
transform-origin: 0 0;
|
62
|
+
|
63
|
+
-webkit-transform: scale(0.35);
|
64
|
+
-moz-transform: scale(0.35);
|
65
|
+
-ms-transform: scale(0.35);
|
66
|
+
-o-transform: scale(0.35);
|
67
|
+
transform: scale(0.35);
|
68
|
+
}
|
69
|
+
|
70
|
+
.slides {
|
71
|
+
position: relative;
|
72
|
+
margin-bottom: 10px;
|
73
|
+
border: 1px solid black;
|
74
|
+
border-radius: 2px;
|
75
|
+
background: rgb(28, 30, 32);
|
76
|
+
}
|
77
|
+
|
78
|
+
.slides span {
|
79
|
+
position: absolute;
|
80
|
+
top: 3px;
|
81
|
+
left: 3px;
|
82
|
+
font-weight: bold;
|
83
|
+
font-size: 14px;
|
84
|
+
color: rgba( 255, 255, 255, 0.9 );
|
85
|
+
}
|
86
|
+
</style>
|
87
|
+
</head>
|
88
|
+
|
89
|
+
<body>
|
90
|
+
|
91
|
+
<div id="wrap-current-slide" class="slides">
|
92
|
+
<iframe src="../../index.html" width="1280" height="1024" id="current-slide"></iframe>
|
93
|
+
</div>
|
94
|
+
|
95
|
+
<div id="wrap-next-slide" class="slides">
|
96
|
+
<iframe src="../../index.html" width="640" height="512" id="next-slide"></iframe>
|
97
|
+
<span>UPCOMING:</span>
|
98
|
+
</div>
|
99
|
+
<div id="notes"></div>
|
100
|
+
|
101
|
+
<script src="../../plugin/markdown/showdown.js"></script>
|
102
|
+
<script>
|
103
|
+
window.addEventListener( 'load', function() {
|
104
|
+
|
105
|
+
(function( window, undefined ) {
|
106
|
+
var notes = document.getElementById( 'notes' ),
|
107
|
+
currentSlide = document.getElementById( 'current-slide' ),
|
108
|
+
nextSlide = document.getElementById( 'next-slide' );
|
109
|
+
|
110
|
+
window.addEventListener( 'message', function( event ) {
|
111
|
+
var data = JSON.parse( event.data );
|
112
|
+
// No need for updating the notes in case of fragment changes
|
113
|
+
if ( data.notes !== undefined) {
|
114
|
+
if( data.markdown ) {
|
115
|
+
notes.innerHTML = (new Showdown.converter()).makeHtml( data.notes );
|
116
|
+
}
|
117
|
+
else {
|
118
|
+
notes.innerHTML = data.notes;
|
119
|
+
}
|
120
|
+
}
|
121
|
+
|
122
|
+
// Showing and hiding fragments
|
123
|
+
if( data.fragment === 'next' ) {
|
124
|
+
currentSlide.contentWindow.Reveal.nextFragment();
|
125
|
+
}
|
126
|
+
else if( data.fragment === 'prev' ) {
|
127
|
+
currentSlide.contentWindow.Reveal.prevFragment();
|
128
|
+
}
|
129
|
+
else {
|
130
|
+
// Update the note slides
|
131
|
+
currentSlide.contentWindow.Reveal.slide( data.indexh, data.indexv );
|
132
|
+
nextSlide.contentWindow.Reveal.slide( data.nextindexh, data.nextindexv );
|
133
|
+
}
|
134
|
+
|
135
|
+
}, false );
|
136
|
+
|
137
|
+
})( window );
|
138
|
+
|
139
|
+
}, false );
|
140
|
+
|
141
|
+
</script>
|
142
|
+
</body>
|
143
|
+
</html>
|
@@ -0,0 +1,98 @@
|
|
1
|
+
/**
|
2
|
+
* Handles opening of and synchronization with the reveal.js
|
3
|
+
* notes window.
|
4
|
+
*/
|
5
|
+
var RevealNotes = (function() {
|
6
|
+
|
7
|
+
function openNotes() {
|
8
|
+
var notesPopup = window.open( 'plugin/notes/notes.html', 'reveal.js - Notes', 'width=1120,height=850' );
|
9
|
+
|
10
|
+
// Fires when slide is changed
|
11
|
+
Reveal.addEventListener( 'slidechanged', function( event ) {
|
12
|
+
post('slidechanged');
|
13
|
+
} );
|
14
|
+
|
15
|
+
// Fires when a fragment is shown
|
16
|
+
Reveal.addEventListener( 'fragmentshown', function( event ) {
|
17
|
+
post('fragmentshown');
|
18
|
+
} );
|
19
|
+
|
20
|
+
// Fires when a fragment is hidden
|
21
|
+
Reveal.addEventListener( 'fragmenthidden', function( event ) {
|
22
|
+
post('fragmenthidden');
|
23
|
+
} );
|
24
|
+
|
25
|
+
/**
|
26
|
+
* Posts the current slide data to the notes window
|
27
|
+
*
|
28
|
+
* @param {String} eventType Expecting 'slidechanged', 'fragmentshown'
|
29
|
+
* or 'fragmenthidden' set in the events above to define the needed
|
30
|
+
* slideDate.
|
31
|
+
*/
|
32
|
+
function post( eventType ) {
|
33
|
+
var slideElement = Reveal.getCurrentSlide(),
|
34
|
+
messageData;
|
35
|
+
|
36
|
+
if( eventType === 'slidechanged' ) {
|
37
|
+
var notes = slideElement.querySelector( 'aside.notes' ),
|
38
|
+
indexh = Reveal.getIndices().h,
|
39
|
+
indexv = Reveal.getIndices().v,
|
40
|
+
nextindexh,
|
41
|
+
nextindexv;
|
42
|
+
|
43
|
+
if( slideElement.nextElementSibling && slideElement.parentNode.nodeName == 'SECTION' ) {
|
44
|
+
nextindexh = indexh;
|
45
|
+
nextindexv = indexv + 1;
|
46
|
+
} else {
|
47
|
+
nextindexh = indexh + 1;
|
48
|
+
nextindexv = 0;
|
49
|
+
}
|
50
|
+
|
51
|
+
messageData = {
|
52
|
+
notes : notes ? notes.innerHTML : '',
|
53
|
+
indexh : indexh,
|
54
|
+
indexv : indexv,
|
55
|
+
nextindexh : nextindexh,
|
56
|
+
nextindexv : nextindexv,
|
57
|
+
markdown : notes ? typeof notes.getAttribute( 'data-markdown' ) === 'string' : false
|
58
|
+
};
|
59
|
+
}
|
60
|
+
else if( eventType === 'fragmentshown' ) {
|
61
|
+
messageData = {
|
62
|
+
fragment : 'next'
|
63
|
+
};
|
64
|
+
}
|
65
|
+
else if( eventType === 'fragmenthidden' ) {
|
66
|
+
messageData = {
|
67
|
+
fragment : 'prev'
|
68
|
+
};
|
69
|
+
}
|
70
|
+
|
71
|
+
notesPopup.postMessage( JSON.stringify( messageData ), '*' );
|
72
|
+
}
|
73
|
+
|
74
|
+
// Navigate to the current slide when the notes are loaded
|
75
|
+
notesPopup.addEventListener( 'load', function( event ) {
|
76
|
+
post('slidechanged');
|
77
|
+
}, false );
|
78
|
+
}
|
79
|
+
|
80
|
+
// If the there's a 'notes' query set, open directly
|
81
|
+
if( window.location.search.match( /(\?|\&)notes/gi ) !== null ) {
|
82
|
+
openNotes();
|
83
|
+
}
|
84
|
+
|
85
|
+
// Open the notes when the 's' key is hit
|
86
|
+
document.addEventListener( 'keydown', function( event ) {
|
87
|
+
// Disregard the event if the target is editable or a
|
88
|
+
// modifier is present
|
89
|
+
if ( document.querySelector( ':focus' ) !== null || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey ) return;
|
90
|
+
|
91
|
+
if( event.keyCode === 83 ) {
|
92
|
+
event.preventDefault();
|
93
|
+
openNotes();
|
94
|
+
}
|
95
|
+
}, false );
|
96
|
+
|
97
|
+
return { open: openNotes };
|
98
|
+
})();
|
@@ -0,0 +1,57 @@
|
|
1
|
+
(function() {
|
2
|
+
// don't emit events from inside the previews themselves
|
3
|
+
if ( window.location.search.match( /receiver/gi ) ) { return; }
|
4
|
+
|
5
|
+
var socket = io.connect(window.location.origin);
|
6
|
+
var socketId = Math.random().toString().slice(2);
|
7
|
+
|
8
|
+
console.log('View slide notes at ' + window.location.origin + '/notes/' + socketId);
|
9
|
+
window.open(window.location.origin + '/notes/' + socketId, 'notes-' + socketId);
|
10
|
+
|
11
|
+
// Fires when a fragment is shown
|
12
|
+
Reveal.addEventListener( 'fragmentshown', function( event ) {
|
13
|
+
var fragmentData = {
|
14
|
+
fragment : 'next',
|
15
|
+
socketId : socketId
|
16
|
+
};
|
17
|
+
socket.emit('fragmentchanged', fragmentData);
|
18
|
+
} );
|
19
|
+
|
20
|
+
// Fires when a fragment is hidden
|
21
|
+
Reveal.addEventListener( 'fragmenthidden', function( event ) {
|
22
|
+
var fragmentData = {
|
23
|
+
fragment : 'previous',
|
24
|
+
socketId : socketId
|
25
|
+
};
|
26
|
+
socket.emit('fragmentchanged', fragmentData);
|
27
|
+
} );
|
28
|
+
|
29
|
+
// Fires when slide is changed
|
30
|
+
Reveal.addEventListener( 'slidechanged', function( event ) {
|
31
|
+
var nextindexh;
|
32
|
+
var nextindexv;
|
33
|
+
var slideElement = event.currentSlide;
|
34
|
+
|
35
|
+
if (slideElement.nextElementSibling && slideElement.parentNode.nodeName == 'SECTION') {
|
36
|
+
nextindexh = event.indexh;
|
37
|
+
nextindexv = event.indexv + 1;
|
38
|
+
} else {
|
39
|
+
nextindexh = event.indexh + 1;
|
40
|
+
nextindexv = 0;
|
41
|
+
}
|
42
|
+
|
43
|
+
var notes = slideElement.querySelector('aside.notes');
|
44
|
+
var slideData = {
|
45
|
+
notes : notes ? notes.innerHTML : '',
|
46
|
+
indexh : event.indexh,
|
47
|
+
indexv : event.indexv,
|
48
|
+
nextindexh : nextindexh,
|
49
|
+
nextindexv : nextindexv,
|
50
|
+
socketId : socketId,
|
51
|
+
markdown : notes ? typeof notes.getAttribute('data-markdown') === 'string' : false
|
52
|
+
|
53
|
+
};
|
54
|
+
|
55
|
+
socket.emit('slidechanged', slideData);
|
56
|
+
} );
|
57
|
+
}());
|
@@ -0,0 +1,58 @@
|
|
1
|
+
var express = require('express');
|
2
|
+
var fs = require('fs');
|
3
|
+
var io = require('socket.io');
|
4
|
+
var _ = require('underscore');
|
5
|
+
var Mustache = require('mustache');
|
6
|
+
|
7
|
+
var app = express.createServer();
|
8
|
+
var staticDir = express.static;
|
9
|
+
|
10
|
+
io = io.listen(app);
|
11
|
+
|
12
|
+
var opts = {
|
13
|
+
port : 1947,
|
14
|
+
baseDir : __dirname + '/../../'
|
15
|
+
};
|
16
|
+
|
17
|
+
io.sockets.on('connection', function(socket) {
|
18
|
+
socket.on('slidechanged', function(slideData) {
|
19
|
+
socket.broadcast.emit('slidedata', slideData);
|
20
|
+
});
|
21
|
+
socket.on('fragmentchanged', function(fragmentData) {
|
22
|
+
socket.broadcast.emit('fragmentdata', fragmentData);
|
23
|
+
});
|
24
|
+
});
|
25
|
+
|
26
|
+
app.configure(function() {
|
27
|
+
[ 'css', 'js', 'images', 'plugin', 'lib' ].forEach(function(dir) {
|
28
|
+
app.use('/' + dir, staticDir(opts.baseDir + dir));
|
29
|
+
});
|
30
|
+
});
|
31
|
+
|
32
|
+
app.get("/", function(req, res) {
|
33
|
+
fs.createReadStream(opts.baseDir + '/index.html').pipe(res);
|
34
|
+
});
|
35
|
+
|
36
|
+
app.get("/notes/:socketId", function(req, res) {
|
37
|
+
|
38
|
+
fs.readFile(opts.baseDir + 'plugin/notes-server/notes.html', function(err, data) {
|
39
|
+
res.send(Mustache.to_html(data.toString(), {
|
40
|
+
socketId : req.params.socketId
|
41
|
+
}));
|
42
|
+
});
|
43
|
+
// fs.createReadStream(opts.baseDir + 'notes-server/notes.html').pipe(res);
|
44
|
+
});
|
45
|
+
|
46
|
+
// Actually listen
|
47
|
+
app.listen(opts.port || null);
|
48
|
+
|
49
|
+
var brown = '\033[33m',
|
50
|
+
green = '\033[32m',
|
51
|
+
reset = '\033[0m';
|
52
|
+
|
53
|
+
var slidesLocation = "http://localhost" + ( opts.port ? ( ':' + opts.port ) : '' );
|
54
|
+
|
55
|
+
console.log( brown + "reveal.js - Speaker Notes" + reset );
|
56
|
+
console.log( "1. Open the slides at " + green + slidesLocation + reset );
|
57
|
+
console.log( "2. Click on the link your JS console to go to the notes page" );
|
58
|
+
console.log( "3. Advance through your slides and your notes will advance automatically" );
|
@@ -0,0 +1,139 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<html lang="en">
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
|
6
|
+
<title>reveal.js - Slide Notes</title>
|
7
|
+
|
8
|
+
<style>
|
9
|
+
body {
|
10
|
+
font-family: Helvetica;
|
11
|
+
}
|
12
|
+
|
13
|
+
#notes {
|
14
|
+
font-size: 24px;
|
15
|
+
width: 640px;
|
16
|
+
margin-top: 5px;
|
17
|
+
}
|
18
|
+
|
19
|
+
#wrap-current-slide {
|
20
|
+
width: 640px;
|
21
|
+
height: 512px;
|
22
|
+
float: left;
|
23
|
+
overflow: hidden;
|
24
|
+
}
|
25
|
+
|
26
|
+
#current-slide {
|
27
|
+
width: 1280px;
|
28
|
+
height: 1024px;
|
29
|
+
border: none;
|
30
|
+
|
31
|
+
-webkit-transform-origin: 0 0;
|
32
|
+
-moz-transform-origin: 0 0;
|
33
|
+
-ms-transform-origin: 0 0;
|
34
|
+
-o-transform-origin: 0 0;
|
35
|
+
transform-origin: 0 0;
|
36
|
+
|
37
|
+
-webkit-transform: scale(0.5);
|
38
|
+
-moz-transform: scale(0.5);
|
39
|
+
-ms-transform: scale(0.5);
|
40
|
+
-o-transform: scale(0.5);
|
41
|
+
transform: scale(0.5);
|
42
|
+
}
|
43
|
+
|
44
|
+
#wrap-next-slide {
|
45
|
+
width: 448px;
|
46
|
+
height: 358px;
|
47
|
+
float: left;
|
48
|
+
margin: 0 0 0 10px;
|
49
|
+
overflow: hidden;
|
50
|
+
}
|
51
|
+
|
52
|
+
#next-slide {
|
53
|
+
width: 1280px;
|
54
|
+
height: 1024px;
|
55
|
+
border: none;
|
56
|
+
|
57
|
+
-webkit-transform-origin: 0 0;
|
58
|
+
-moz-transform-origin: 0 0;
|
59
|
+
-ms-transform-origin: 0 0;
|
60
|
+
-o-transform-origin: 0 0;
|
61
|
+
transform-origin: 0 0;
|
62
|
+
|
63
|
+
-webkit-transform: scale(0.35);
|
64
|
+
-moz-transform: scale(0.35);
|
65
|
+
-ms-transform: scale(0.35);
|
66
|
+
-o-transform: scale(0.35);
|
67
|
+
transform: scale(0.35);
|
68
|
+
}
|
69
|
+
|
70
|
+
.slides {
|
71
|
+
position: relative;
|
72
|
+
margin-bottom: 10px;
|
73
|
+
border: 1px solid black;
|
74
|
+
border-radius: 2px;
|
75
|
+
background: rgb(28, 30, 32);
|
76
|
+
}
|
77
|
+
|
78
|
+
.slides span {
|
79
|
+
position: absolute;
|
80
|
+
top: 3px;
|
81
|
+
left: 3px;
|
82
|
+
font-weight: bold;
|
83
|
+
font-size: 14px;
|
84
|
+
color: rgba( 255, 255, 255, 0.9 );
|
85
|
+
}
|
86
|
+
</style>
|
87
|
+
</head>
|
88
|
+
|
89
|
+
<body>
|
90
|
+
|
91
|
+
<div id="wrap-current-slide" class="slides">
|
92
|
+
<iframe src="/?receiver" width="1280" height="1024" id="current-slide"></iframe>
|
93
|
+
</div>
|
94
|
+
|
95
|
+
<div id="wrap-next-slide" class="slides">
|
96
|
+
<iframe src="/?receiver" width="640" height="512" id="next-slide"></iframe>
|
97
|
+
<span>UPCOMING:</span>
|
98
|
+
</div>
|
99
|
+
<div id="notes"></div>
|
100
|
+
|
101
|
+
<script src="/socket.io/socket.io.js"></script>
|
102
|
+
<script src="/plugin/markdown/showdown.js"></script>
|
103
|
+
|
104
|
+
<script>
|
105
|
+
var socketId = '{{socketId}}';
|
106
|
+
var socket = io.connect(window.location.origin);
|
107
|
+
var notes = document.getElementById('notes');
|
108
|
+
var currentSlide = document.getElementById('current-slide');
|
109
|
+
var nextSlide = document.getElementById('next-slide');
|
110
|
+
|
111
|
+
socket.on('slidedata', function(data) {
|
112
|
+
// ignore data from sockets that aren't ours
|
113
|
+
if (data.socketId !== socketId) { return; }
|
114
|
+
|
115
|
+
if (data.markdown) {
|
116
|
+
notes.innerHTML = (new Showdown.converter()).makeHtml(data.notes);
|
117
|
+
}
|
118
|
+
else {
|
119
|
+
notes.innerHTML = data.notes;
|
120
|
+
}
|
121
|
+
|
122
|
+
currentSlide.contentWindow.Reveal.slide(data.indexh, data.indexv);
|
123
|
+
nextSlide.contentWindow.Reveal.slide(data.nextindexh, data.nextindexv);
|
124
|
+
});
|
125
|
+
socket.on('fragmentdata', function(data) {
|
126
|
+
// ignore data from sockets that aren't ours
|
127
|
+
if (data.socketId !== socketId) { return; }
|
128
|
+
|
129
|
+
if (data.fragment === 'next') {
|
130
|
+
currentSlide.contentWindow.Reveal.nextFragment();
|
131
|
+
}
|
132
|
+
else if (data.fragment === 'previous') {
|
133
|
+
currentSlide.contentWindow.Reveal.prevFragment();
|
134
|
+
}
|
135
|
+
});
|
136
|
+
</script>
|
137
|
+
|
138
|
+
</body>
|
139
|
+
</html>
|
@@ -0,0 +1,39 @@
|
|
1
|
+
<html>
|
2
|
+
<body>
|
3
|
+
|
4
|
+
<iframe id="reveal" src="../../index.html" style="border: 0;" width="500" height="500"></iframe>
|
5
|
+
|
6
|
+
<div>
|
7
|
+
<input id="back" type="button" value="go back"/>
|
8
|
+
<input id="ahead" type="button" value="go ahead"/>
|
9
|
+
<input id="slideto" type="button" value="slideto 2-2"/>
|
10
|
+
</div>
|
11
|
+
|
12
|
+
<script>
|
13
|
+
|
14
|
+
(function (){
|
15
|
+
|
16
|
+
var back = document.getElementById( 'back' ),
|
17
|
+
ahead = document.getElementById( 'ahead' ),
|
18
|
+
slideto = document.getElementById( 'slideto' ),
|
19
|
+
reveal = window.frames[0];
|
20
|
+
|
21
|
+
back.addEventListener( 'click', function () {
|
22
|
+
|
23
|
+
reveal.postMessage( JSON.stringify({method: 'prev', args: []}), '*' );
|
24
|
+
}, false );
|
25
|
+
|
26
|
+
ahead.addEventListener( 'click', function (){
|
27
|
+
reveal.postMessage( JSON.stringify({method: 'next', args: []}), '*' );
|
28
|
+
}, false );
|
29
|
+
|
30
|
+
slideto.addEventListener( 'click', function (){
|
31
|
+
reveal.postMessage( JSON.stringify({method: 'slide', args: [2,2]}), '*' );
|
32
|
+
}, false );
|
33
|
+
|
34
|
+
}());
|
35
|
+
|
36
|
+
</script>
|
37
|
+
|
38
|
+
</body>
|
39
|
+
</html>
|