summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Krotscheck <krotscheck@gmail.com>2015-07-15 18:29:20 -0700
committerMichael Krotscheck <krotscheck@gmail.com>2015-07-29 21:52:37 -0700
commit178f5ad1358b7c3e2275ff4340135ea4f8a9a629 (patch)
tree2e91bda8222de04b3529be42d516ebb2950a7611
parent92bca6599bb975e7c695a99e0c053ff8050b71f0 (diff)
Added presentation framework.
-rw-r--r--.editorconfig12
-rw-r--r--.gitignore6
-rw-r--r--README.md28
-rw-r--r--bower.json33
-rw-r--r--gulpfile.js234
-rw-r--r--package.json39
-rw-r--r--src/index.hbs71
-rw-r--r--src/template/index.hbs111
8 files changed, 534 insertions, 0 deletions
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..025b86f
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,12 @@
1root = true
2
3[*]
4end_of_line = lf
5insert_final_newline = true
6charset = utf-8
7indent_style = space
8indent_size = 2
9trim_trailing_whitespace = true
10
11[*.md]
12trim_trailing_whitespace = false
diff --git a/.gitignore b/.gitignore
index 123ae94..c825564 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,3 +25,9 @@ build/Release
25# Dependency directory 25# Dependency directory
26# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 26# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
27node_modules 27node_modules
28bower_components
29
30# IDE things
31.idea
32*.iml
33dist
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..15b2640
--- /dev/null
+++ b/README.md
@@ -0,0 +1,28 @@
1My Convention Presentations
2===========================
3
4If you're interested in my presentations, you can go look at them here:
5https://krotscheck.github.io/presentations/
6
7
8Building your own presentations
9-------------------------------
10
11If you would like to use this repository as a base from which to build your
12own presentation website, you can clone the ``starter`` branch and work from
13there. The following commands will get you started:
14
15 // This will install miscellaneous runtime dependencies.
16 npm install
17
18 // This will start a VERY basic presentation wizard. To modify the
19 // output, make changes in ./src/template/index.hbs
20 npm run new
21
22 // This will create a local webhost, serving all of your presentations.
23 // It will autodetect changes and refresh any applicable pages.
24 npm run serve
25
26 // This will construct your current presentations, and push them to
27 // gh-pages.
28 npm run release
diff --git a/bower.json b/bower.json
new file mode 100644
index 0000000..090f7c2
--- /dev/null
+++ b/bower.json
@@ -0,0 +1,33 @@
1{
2 "name": "presentations",
3 "version": "1.0.0",
4 "homepage": "https://krotscheck.github.com/presentations",
5 "authors": [
6 "Michael Krotscheck <krotscheck@gmail.com>"
7 ],
8 "license": "Apache-2.0",
9 "ignore": [
10 "**/.*",
11 "node_modules",
12 "bower_components",
13 "test",
14 "tests"
15 ],
16 "dependencies": {
17 "font-awesome": "~4.3.0",
18 "font-mfizz": "~2.0.1",
19 "reveal.js": "~3.1.0",
20 "bootstrap": "~3.3.5"
21 },
22 "overrides": {
23 "font-mfizz": {
24 "main": [
25 "css/font-mfizz.css",
26 "fonts/font-mfizz.eot",
27 "fonts/font-mfizz.svg",
28 "fonts/font-mfizz.ttf",
29 "fonts/font-mfizz.woff"
30 ]
31 }
32 }
33}
diff --git a/gulpfile.js b/gulpfile.js
new file mode 100644
index 0000000..4ea26d3
--- /dev/null
+++ b/gulpfile.js
@@ -0,0 +1,234 @@
1(function initializeGulp () {
2 'use strict';
3
4 var fs = require('fs');
5 var cheerio = require('cheerio');
6 var rimraf = require('rimraf');
7 var mainBowerFiles = require('main-bower-files');
8
9 var gulp = require('gulp');
10 var git = require('gulp-git');
11 var filter = require('gulp-filter');
12 var less = require('gulp-less');
13 var webserver = require('gulp-webserver');
14 var streamqueue = require('streamqueue');
15 var ignore = require('gulp-ignore');
16 var prompt = require('gulp-prompt');
17 var handlebars = require('gulp-compile-handlebars');
18 var rename = require('gulp-rename');
19
20 var dir = {
21 'dist': './dist',
22 'src': './src'
23 };
24
25 // List of file paths.
26 var paths = {
27 'html': dir.src + '/**/*.html',
28 'hbs': dir.src + '/index.hbs',
29 'index': dir.src + '/index.hbs'
30 };
31
32 // Contents of all our bower dependencies' main:[] fields.
33 var bowerFiles = mainBowerFiles();
34
35 // The current package.json file.
36 var packageJson = require('./package.json');
37
38 /**
39 * The handlebars configuration object.
40 */
41 var handlebarsConfig = {
42 helpers: {
43 'datetime': function (object) {
44 return object.toLocaleDateString();
45 }
46 }
47 };
48
49 /**
50 * This method parses through discovered presentations, reads their
51 * html metadata, and returns an array of that metadata.
52 */
53 function buildPresentationManifest () {
54 var presentations = [];
55 var files = fs.readdirSync(dir.src);
56
57 for (var i = 0; i < files.length; i++) {
58 var file = dir.src + '/' + files[i] + '/index.html';
59 try {
60 var stat = fs.statSync(file);
61 var $ = cheerio.load(fs.readFileSync(file));
62 presentations.push({
63 'title': $("head title").text(),
64 'description': $("head meta[name='description']").attr('content'),
65 'author': $('head meta[name="author"]').attr('content'),
66 'mtime': stat.mtime,
67 'path': files[i] + '/index.html'
68 });
69 } catch (e) {
70 // Do nothing
71 }
72 }
73 presentations.sort(function (a, b) {
74 return a.mtime >= b.mtime ? 1 : -1;
75 });
76 return presentations;
77 }
78
79 /**
80 * Clean the output directory.
81 *
82 * @param {Function} cb callback.
83 * @return {*} A gulp stream that performs this action.
84 */
85 gulp.task('clean', function (cb) {
86 rimraf(dir.dist, cb);
87 });
88
89 /**
90 * Build the static file structure from our bower dependencies. Reveal.js
91 * is given a special snowflake status, because it doesn't observe the
92 * standard packaging format that bower files like.
93 */
94 gulp.task('package:libs', function (cb) {
95 var resolveCSS = gulp.src(bowerFiles)
96 .pipe(filter('*.css'))
97 .pipe(gulp.dest(dir.dist + '/css'));
98
99 var resolveLESS = gulp.src(bowerFiles)
100 .pipe(filter('*.less'))
101 .pipe(less())
102 .pipe(gulp.dest(dir.dist + '/css'));
103
104 var resolveFonts = gulp.src(bowerFiles)
105 .pipe(filter(['*.otf', '*.eot', '*.svg', '*.ttf', '*.woff', '*.woff2']))
106 .pipe(gulp.dest(dir.dist + '/fonts'));
107
108 var resolveLibs = gulp.src(bowerFiles)
109 .pipe(filter('*.js'))
110 .pipe(gulp.dest(dir.dist + '/js'));
111
112 // Reveal.js is a special snowflake.
113 var resolveReveal = gulp.src('./bower_components/reveal.js/*/**/*.*',
114 {'base': './bower_components/reveal.js/'})
115 .pipe(ignore(['**/test/**', '*.js']))
116 .pipe(filter([
117 '**/*.js',
118 '**/*.css',
119 '**/*.eot',
120 '**/*.ttf',
121 '**/*.woff'
122 ]))
123 .pipe(gulp.dest(dir.dist));
124
125 return streamqueue({'objectMode': true}, resolveCSS, resolveLESS,
126 resolveReveal, resolveLibs, resolveFonts);
127 });
128
129 /**
130 * Package the handlebars files.
131 */
132 gulp.task('package:hbs', function () {
133
134 var templateData = {
135 'presentations': buildPresentationManifest(),
136 'author': packageJson.author
137 };
138
139 // Automatically build the site list.
140 return gulp.src(paths.hbs, {'base': dir.src})
141 .pipe(handlebars(templateData, handlebarsConfig))
142 .pipe(rename(function (path) {
143 path.extname = ".html";
144 }))
145 .pipe(gulp.dest(dir.dist));
146 });
147
148 /**
149 * Copy the HTML files into the dist folder.
150 */
151 gulp.task('package:html', function () {
152 return gulp.src(paths.html, {'base': dir.src})
153 .pipe(gulp.dest(dir.dist));
154 });
155
156 /**
157 * This task builds a new presentation from the base presentation template.
158 */
159 gulp.task('new', function () {
160 var templateData = {
161 author: packageJson.author
162 };
163 var destinationFolder = '';
164 return gulp.src(dir.src + '/template/index.hbs')
165 .pipe(prompt.prompt([
166 {
167 type: 'input',
168 name: 'folderName',
169 message: 'Presentation Folder Name (/^[a-z][a-z_]+$/):',
170 validate: function (value) {
171 var result = value.match(/^([a-z][a-z_]+)$/);
172 return result !== null;
173 }
174 },
175 {
176 type: 'input',
177 name: 'title',
178 message: 'Presentation Title:'
179 },
180 {
181 type: 'input',
182 name: 'description',
183 message: 'Presentation Description:'
184 },
185 {
186 type: 'input',
187 name: 'event',
188 message: 'First presented at:'
189 },
190 {
191 type: 'input',
192 name: 'event',
193 message: 'First presented on (date):'
194 }],
195 function (res) {
196 destinationFolder = res.folderName;
197 templateData.presentation = {
198 'title': res.title,
199 'description': res.description,
200 'event': res.event
201 }
202 }))
203 .pipe(handlebars(templateData, handlebarsConfig))
204 .pipe(rename(function (path) {
205 path.dirname += '/' + destinationFolder;
206 path.basename = "index";
207 path.extname = ".html";
208 }))
209 .pipe(gulp.dest(dir.src))
210 .pipe(git.add());
211 });
212
213 /**
214 * Package the entire site into the dist folder.
215 */
216 gulp.task('package', ['package:html', 'package:hbs', 'package:libs']);
217
218 /**
219 * Start a local server and serve the application code. This is
220 * equivalent to opening index.html in a browser.
221 *
222 * @return {*} A gulp stream that performs this action.
223 */
224 gulp.task('serve', function () {
225 gulp.watch(paths.html, ['package:html']);
226 gulp.watch(paths.hbs, ['package:hbs']);
227
228 return gulp.src(dir.dist)
229 .pipe(webserver({
230 'livereload': true,
231 'open': true
232 }));
233 });
234})();
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..65441f5
--- /dev/null
+++ b/package.json
@@ -0,0 +1,39 @@
1{
2 "name": "presentations",
3 "version": "1.0.0",
4 "description": "My convention presentations.",
5 "main": "index.html",
6 "private": true,
7 "scripts": {
8 "postinstall": "bower install",
9 "start": "gulp serve",
10 "prestart": "gulp package",
11 "prepublish": "gulp package",
12 "new": "gulp new"
13 },
14 "author": {
15 "name": "Michael Krotscheck",
16 "email": "krotscheck@gmail.com",
17 "url": "http://www.krotscheck.net/"
18 },
19 "license": "Apache-2.0",
20 "dependencies": {},
21 "devDependencies": {
22 "bower": "^1.4.1",
23 "cheerio": "^0.19.0",
24 "gulp": "^3.9.0",
25 "gulp-compile-handlebars": "^0.5.0",
26 "gulp-filter": "^3.0.0",
27 "gulp-git": "^1.2.4",
28 "gulp-ignore": "^1.2.1",
29 "gulp-less": "^3.0.3",
30 "gulp-prompt": "^0.1.2",
31 "gulp-rename": "^1.2.2",
32 "gulp-util": "^3.0.6",
33 "gulp-webserver": "^0.9.1",
34 "main-bower-files": "^2.9.0",
35 "rimraf": "^2.4.2",
36 "streamqueue": "^1.1.0"
37 },
38 "repository": "git@github.com:krotscheck/presentations.git"
39}
diff --git a/src/index.hbs b/src/index.hbs
new file mode 100644
index 0000000..c5cbc93
--- /dev/null
+++ b/src/index.hbs
@@ -0,0 +1,71 @@
1<!doctype html>
2<html lang="en">
3
4<head>
5 <meta charset="utf-8">
6 <title>Convention Presentations</title>
7 <link rel="stylesheet"
8 href="css/bootstrap.css">
9 <meta name="description"
10 content="Convention Presentations by {{author.name}}">
11 <meta name="author" content="{{author.name}}">
12 <meta name="viewport"
13 content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui">
14</head>
15
16<body style="margin-top: 70px; margin-bottom: 70px">
17<nav class="navbar navbar-default navbar-fixed-top">
18 <div class="container-fluid">
19 <span class="navbar-brand">Convention Presentations</span>
20 </div>
21</nav>
22<div class="container-fluid">
23 <div class="row">
24 <div class="col-xs-12">
25 <ul class="list-unstyled">
26 <li><strong>Author:</strong> {{author.name}}</li>
27 <li><strong>Website:</strong>
28 <a href="{{author.url}}">{{author.url}}</a>
29 </li>
30 </ul>
31 <br/>
32 <table class="table table-striped table-hover">
33 <thead>
34 <tr>
35 <th class="col-xs-2">Last Updated</th>
36 <th>Title</th>
37 </tr>
38 </thead>
39 <tbody>
40 {{#each presentations}}
41 <tr>
42 <td>{{datetime mtime}}</td>
43 <td>
44 <a href="{{path}}" target="_blank">
45 {{title}}
46 </a>
47 </td>
48 </tr>
49 {{/each}}
50 </tbody>
51 </table>
52 </div>
53 </div>
54</div>
55<nav class="navbar navbar-default navbar-fixed-bottom">
56 <div class="container-fluid">
57 <p class="navbar-text">
58 <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">
59 <img alt="Creative Commons License"
60 src="https://i.creativecommons.org/l/by/4.0/88x31.png"/>
61 </a>
62 This work by <span xmlns:cc="http://creativecommons.org/ns#"
63 property="cc:attributionName">{{author.name}}</span>
64 is licensed under a <a rel="license"
65 href="http://creativecommons.org/licenses/by/4.0/">Creative
66 Commons Attribution 4.0 International License</a>.
67 </p>
68 </div>
69</nav>
70</body>
71</html>
diff --git a/src/template/index.hbs b/src/template/index.hbs
new file mode 100644
index 0000000..1d05d8f
--- /dev/null
+++ b/src/template/index.hbs
@@ -0,0 +1,111 @@
1<!doctype html>
2<html lang="en">
3
4<head>
5 <meta charset="utf-8">
6
7 <title>{{presentation.title}}</title>
8
9 <meta name="description"
10 content="{{presentation.description}}">
11 <meta name="author" content="{{author.name}}">
12
13 <meta name="apple-mobile-web-app-capable" content="yes"/>
14 <meta name="apple-mobile-web-app-status-bar-style"
15 content="black-translucent"/>
16
17 <meta name="viewport"
18 content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui">
19
20 <link rel="stylesheet" href="../css/reveal.css">
21 <link rel="stylesheet" href="../css/font-awesome.css">
22 <link rel="stylesheet" href="../css/font-mfizz.css">
23 <link rel="stylesheet" href="../css/theme/serif.css" id="theme">
24
25 <!-- Code syntax highlighting -->
26 <link rel="stylesheet" href="../lib/css/zenburn.css">
27
28 <!-- Printing and PDF exports -->
29 <script>
30 var link = document.createElement('link');
31 link.rel = 'stylesheet';
32 link.type = 'text/css';
33 link.href =
34 window.location.search.match(/print-pdf/gi) ?
35 '../css/print/pdf.css' :
36 '../css/print/paper.css';
37 document.getElementsByTagName('head')[0].appendChild(link);
38 </script>
39
40 <!--[if lt IE 9]>
41 <script src="../lib/js/html5shiv.js"></script>
42 <![endif]-->
43</head>
44
45<body>
46
47<div class="reveal" data-transition="slide">
48
49 <div class="slides">
50 <section>
51 <h1>{{presentation.title}}</h1>
52
53 <h3>{{presentation.description}}</h3>
54
55 <p>by {{author.name}}</p>
56 </section>
57 </div>
58
59 <script src="../lib/js/head.min.js"></script>
60 <script src="../js/reveal.js"></script>
61
62 <script>
63
64 // Full list of configuration options available at:
65 // https://github.com/hakimel/reveal.js#configuration
66 Reveal.initialize({
67 controls: true,
68 progress: true,
69 history: true,
70 center: true,
71
72 transition: 'slide', // none/fade/slide/convex/concave/zoom
73
74 // Optional reveal.js plugins
75 dependencies: [
76 {
77 src: '../lib/js/classList.js', condition: function () {
78 return !document.body.classList;
79 }
80 },
81 {
82 src: '../plugin/markdown/marked.js',
83 condition: function () {
84 return !!document.querySelector('[data-markdown]');
85 }
86 },
87 {
88 src: '../plugin/markdown/markdown.js',
89 condition: function () {
90 return !!document.querySelector('[data-markdown]');
91 }
92 },
93 {
94 src: '../plugin/highlight/highlight.js',
95 async: true,
96 condition: function () {
97 return !!document.querySelector('pre code');
98 },
99 callback: function () {
100 hljs.initHighlightingOnLoad();
101 }
102 },
103 {src: '../plugin/zoom-js/zoom.js', async: true},
104 {src: '../plugin/notes/notes.js', async: true}
105 ]
106 });
107
108 </script>
109</div>
110</body>
111</html>