Giter Club home page Giter Club logo

cleaver's Introduction

Cleaver

30-second Slideshows for Hackers. http://jdan.github.io/cleaver/

Travis Build NPM version

Intro

Cleaver turns this:

title: Basic Example
author:
  name: Jordan Scales
  twitter: jdan
  url: http://jordanscales.com
output: basic.html
controls: true

--

# Cleaver 101
## A first look at quick HTML presentations

--

### A textual example

Content can be written in **Markdown!** New lines no longer need two angle brackets.

This will be in a separate paragraph

--

### A list of things

* Item 1
* Item B
* Item gamma

No need for multiple templates!

Into this:

output

Quick Start

Get it on NPM:

npm install -g cleaver
# To update: npm update -g cleaver

And run it like so:

cleaver path/to/something.md

You can also watch for changes on a file and automatically recompile with:

cleaver watch path/to/something-changing.md

# Watching for changes on presentation.md. Ctrl-C to abort.
# Rebuilding: Thu Nov 07 2013 00:15:03 GMT-0500 (EST)
# Rebuilding: Thu Nov 07 2013 00:15:21 GMT-0500 (EST)
# Rebuilding: Thu Nov 07 2013 00:16:01 GMT-0500 (EST)
# Rebuilding: Thu Nov 07 2013 00:16:09 GMT-0500 (EST)

Use the --debug flag to display debug information:

$ cleaver --debug examples/basic.md
  cleaver loaded input document +0ms
  helper read /Users/jordan/Projects/cleaver/templates/layout.mustache +0ms
  helper read /Users/jordan/Projects/cleaver/templates/author.mustache +0ms
  helper read /Users/jordan/Projects/cleaver/templates/default.mustache +0ms
  cleaver loaded templates +3ms
  cleaver parsed metadata +4ms
  helper read /Users/jordan/Projects/cleaver/resources/default.css +13ms
  helper read /Users/jordan/Projects/cleaver/resources/github.css +0ms
  helper read /Users/jordan/Projects/cleaver/resources/script.js +0ms
  cleaver loaded static assets +9ms
  cleaver rendered slides +1ms
  cleaver rendered presentation +1ms

More Info

Cleaver is a one-stop shop for generating HTML presentations in record time. Using some spiced up markdown, you can produce good-looking, interactive presentations with a just a few lines of text.

Slides are written in Markdown, and are separated by two dashes (--).

Options

title: Basic Example
author:
  name: Jordan Scales
  twitter: jdan
  url: http://jordanscales.com
style: basic-style.css
output: basic.html

Cleaver supports several basic options that allow you to further customize the look and feel of your presentation, including author info, stylesheets, and custom templates.

See the documentation on options for more information.

Be sure to check out the wiki as well.

Themes

Check out the themes page on our wiki.

title: Theme Example
output: theme.html
theme: jdan/cleaver-retro

Cleaver has substantial theme support to give you more fine-grained control over your presentation, similar to options. Instead of manually specifying a stylesheet, template, layout, and others, you can specify a single theme containing each of these assets. More specifically, a theme may contain:

  • style.css - styles for your presentation
  • template.mustache - a template used to render the slides in your presentation
  • layout.mustache - a template used to render the entire document of your presentation
  • script.js - javascript to be included in your slideshow

A theme does not need to contain all of these files, only the ones present will be loaded into your slideshow.

Examples

cleaver-retro

cleaver-ribbon

reveal-cleaver-theme

Specifying Themes

Themes may be specified by one of the following options:

  • An absolute or relative path to a directory
  • A URL to a directory
  • A github repository in the form of username/reponame

Overriding Themes

By default, style.css and script.js will be appended to the default stylesheets and javascripts included in cleaver presentations. If you wish to completely override these defaults, you must include another file in your theme - settings.json - corresponding to the following:

{
  "override": true
}

Template files will automatically override the default templates.

More Info

For more information on themes, check out our documentation.

Markup

Cleaver slides are rendered using the following template:

{{#slides}}
  <div class="slide{{#hidden}} hidden{{/hidden}} {{classList}}" id="slide-{{id}}">
    <section class="slide-content">{{{content}}}</section>
  </div>
{{/slides}}

And produce the following markup:

+-------------------------------+
| #slide-N                      |
|     +-------------------+     |
|     | .slide-content    |     |
|     |                   |     |
|     |                   |     |
|     |                   |     |
|     |                   |     |
|     +-------------------+     |
|                               |
|                               |
| (navigation)                  |
+-------------------------------+

#slide-N (for example, #slide-3) allows you to identify a particular full-bleed slide by its position in the slideshow. It extends to the bounds of the page.

.slide-content is a smaller window which holds the actual content of the slide.

Class List

A class list can be placed after each "slice" (denoted --) to help you style individual slides without worrying about their index.

-- bg

This slide will have a class "bg" associated with it

-- bg blink

This one, too, but it will also have the class "blink"

Slide Types

Title slide

# Cleaver 101
## A first look at quick HTML presentations

h1 and h2 elements (prefaced with # and ## respectively), will automatically include padding to render a title slide.

Other slides

### A list of things

* Item 1
* Item B
* Item gamma

No need for multiple templates!

Since slides are written in Markdown, you can include things like lists, images, and arbitrary HTML.

h3 tags (prefaced ###) are automatically given a bottom border to represent a slide title.

Navigation

Cleaver supports keyboard navigation for switching between slides. Alternatively, click the control buttons located below the presentation.

To navigate the slideshow:

  • forward: K, L, UP, RIGHT, PgDn, and Space
  • reverse: H, J, LEFT, DOWN, PgUp, and Backspace

The toggle fullscreen mode, press the ENTER key.

Contributing

  • Fork it
  • Clone it
  • Install dependencies (npm install)
  • Checkout a release branch (git checkout -b feature/cool-wordart)
  • Make changes, commit, and push (npm test and make sure it passes)
  • Open a pull request!

With <3,
@jdan

--

MIT Licensed

cleaver's People

Contributors

agamm avatar alexbeletsky avatar alphagit avatar barneyb avatar bartvds avatar bofrede avatar djblue avatar eddotman avatar gabeboning avatar guifromrio avatar jdan avatar justintbrown avatar kyuumeitai avatar lloydmeta avatar lufengd3 avatar markprzepiora avatar mathiasrw avatar mike-ward avatar natelaws avatar omarkhan avatar peterdavehello avatar redtrumpet avatar sapegin avatar shoorick avatar softlysplinter avatar soyrochus avatar sudodoki avatar twada avatar zhuochun avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cleaver's Issues

Print layout?

It would be useful to have proper print layout available. This would make it easy to export the slides in PDF format (useful for sharing).

Full screen, maybe?

It will be much helpful if you have an option to make the slideshow to be in full screen mode when rendered in browser. It will remove the distraction.

grunt plugin live & node.js module api requests

Had to happen some day, might as well be now: grunt-cleaver

I used the (tiny) api as used in the cli bin. If you like to support module dependants then a little more 'official' module api surface would be nice:

  1. The error fail() promise handle in the modules Cleaver..run() should be moved to the bin code, and the module should let any error bubble to a dependant promise handler (either the bin wrapper or a user like this grunt plugin that needs to fail it's build on error).

  2. Access to the destination path would be handy for reporting and processing (as it is defined in the markup file): it could be promised in a result object by Cleaver..run()

  3. Ideally cleaver should support an options-argument on run(), structured similar to the header of the markdown. Having the options over-ridable could instantly make things more awesome. I see the Cleaver instance variables but unsure of how volatile they are.

  4. If you decide to open module api with options then maybe also allow to pass a source-string instead of a path, for generated code (so we don't have to buffer to disk first).

All fancy sauce of course, nothing critical.

Cheers 👍

Side-note: if you like Q then look at Q-io (same guys as Q, very awesome). It also has a optional mock file-system (for hackery)

Style-sheet includes

External stylesheets should get a nice priority here. As is, the only way to really customize the look of the presentation is to either:

  • edit the in-document CSS code
  • include a <link> tag after the presentation is rendered

I am proposing an extra --style flag upon rendering, which will include external CSS into the document. As far a design decision goes, I'm still keen on keeping the output to a single document, but this is open to suggestion.

cleaver --file=path/to/something.json --style=dark.css

Agenda slide contains duplicate entries

Sometimes a presentation may have two or more consecutive slides of the same title. If agenda: true is set, this causes two identical agenda items to be rendered. Here is our gh-pages presentation, for example:

example

Not loading theme from repo

I had been using Cleaver for a month or so, and when I wanted to load a theme from a repo, I could do it. Today, when I was trying to regenerate some slides, they switched back to the default theme.

This is my theme,

https://github.com/JumpstartLab/cleaver-theme

This is my metadata,

title: Why Heroku
output: why_heroku.html
controls: true
theme: JumpstartLab/cleaver-theme

This is the output,

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
  <title>Why Heroku</title>
  <style type="text/css">
    body {
  font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
  color: #222;
  background-color: #f7f7f7;
  font-size: 100%;
}

.slide {
  position: absolute;
  top: 0; bottom: 0;
  left: 0; right: 0;
}

.slide-content {
  width: 800px;
  height: 600px;
  overflow: hidden;
  margin: 80px auto 0 auto;
  padding: 30px;

  font-weight: 200;
  font-size: 200%;
  line-height: 1.375;
}

.controls {
  position: absolute;
  bottom: 20px;
  left: 20px;
}

.arrow {
  width: 0; height: 0;
  border: 30px solid #333;
  float: left;
  margin-right: 30px;

  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

.prev {
  border-top-color: transparent;
  border-bottom-color: transparent;
  border-left-color: transparent;

  border-left-width: 0;
  border-right-width: 50px;
}

.next {
  border-top-color: transparent;
  border-bottom-color: transparent;
  border-right-color: transparent;

  border-left-width: 50px;
  border-right-width: 0;
}

.prev:hover {
  border-right-color: #888;
  cursor: pointer;
}

.next:hover {
  border-left-color: #888;
  cursor: pointer;
}

h1 {
  font-size: 300%;
  line-height: 1.2;
  text-align: center;
  margin: 170px 0 0;
}

h2 {
  font-size: 100%;
  line-height: 1.2;
  margin: 5px 0;
  text-align: center;
  font-weight: 200;
}

h3 {
  font-size: 140%;
  line-height: 1.2;
  border-bottom: 1px solid #aaa;
  margin: 0;
  padding-bottom: 15px;
}

ul {
  padding: 20px 0 0 60px;
  font-weight: 200;
  line-height: 1.375;
}

.author h1 {
  font-size: 170%;
  font-weight: 200;
  text-align: center;
  margin-bottom: 30px;
}

.author h3 {
  font-weight: 100;
  text-align: center;
  font-size: 95%;
  border: none;
}

a {
  text-decoration: none;
  color: #44a4dd;
}

a:hover {
  color: #66b5ff;
}

pre {
  font-size: 60%;
  line-height: 1.3;
}

.progress {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 3px;
}

.progress-bar {
  width: 0%;
  height: 3px;
  background-color: #b4b4b4;

  -webkit-transition: width 0.05s ease-out;
  -moz-transition: width 0.05s ease-out;
  -o-transition: width 0.05s ease-out;
  transition: width 0.05s ease-out;
}

.hidden {
  display: none;
}

@media (max-width: 850px) {

  body {
    font-size: 70%;
  }

  .slide-content {
    width: auto;
  }

  img {
    width: 100%;
  }

  h1 {
    margin-top: 120px;
  }

  .prev, .prev:hover {
    border-right-color: rgba(135, 135, 135, 0.5);
  }

  .next, .next:hover {
    border-left-color: rgba(135, 135, 135, 0.5);
  }
}

@media (max-width: 480px) {
  body {
    font-size: 50%;
    overflow: hidden;
  }

  .slide-content {
    padding: 10px;
    margin-top: 10px;
    height: 340px;
  }

  h1 {
    margin-top: 50px;
  }

  ul {
    padding-left: 25px;
  }
}

@media print {
  * {
    -webkit-print-color-adjust: exact;
  }

  @page {
    size: letter;
  }

  .hidden {
    display: inline;
  }

  html {
    width: 100%;
    height: 100%;
    overflow: visible;
  }

  body {
    margin: 0 auto !important;
    border: 0;
    padding: 0;
    float: none !important;
    overflow: visible;
    background: none !important;
    font-size: 52%;
  }

  .progress, .controls {
    display: none;
  }

  .slide {
    position: static;
  }

  .slide-content {
    border: 1px solid #222;
    margin-top: 0;
    margin-bottom: 40px;
    height: 3.5in;
    overflow: visible;
  }

  .slide:nth-child(even) {
    /* 2 slides per page */
    page-break-before: always;
  }
}

/*
github.com style (c) Vasily Polovnyov <[email protected]>
*/

code, pre {
  border: 1px solid #ddd;
  border-radius: 3px;
  overflow: auto;
  padding: 6px 10px;
}

code {
  padding: 0 5px;
}

pre>code {
  margin: 0; padding: 0;
  border: none;
  background: transparent;
}

pre .comment,
pre .template_comment,
pre .diff .header,
pre .javadoc {
  color: #998;
  font-style: italic
}

pre .keyword,
pre .css .rule .keyword,
pre .winutils,
pre .javascript .title,
pre .nginx .title,
pre .subst,
pre .request,
pre .status {
  color: #333;
  font-weight: bold
}

pre .number,
pre .hexcolor,
pre .ruby .constant {
  color: #099;
}

pre .string,
pre .tag .value,
pre .phpdoc,
pre .tex .formula {
  color: #d14
}

pre .title,
pre .id {
  color: #900;
  font-weight: bold
}

pre .javascript .title,
pre .lisp .title,
pre .clojure .title,
pre .subst {
  font-weight: normal
}

pre .class .title,
pre .haskell .type,
pre .vhdl .literal,
pre .tex .command {
  color: #458;
  font-weight: bold
}

pre .tag,
pre .tag .title,
pre .rules .property,
pre .django .tag .keyword {
  color: #000080;
  font-weight: normal
}

pre .attribute,
pre .variable,
pre .lisp .body {
  color: #008080
}

pre .regexp {
  color: #009926
}

pre .class {
  color: #458;
  font-weight: bold
}

pre .symbol,
pre .ruby .symbol .string,
pre .lisp .keyword,
pre .tex .special,
pre .prompt {
  color: #990073
}

pre .built_in,
pre .lisp .title,
pre .clojure .built_in {
  color: #0086b3
}

pre .preprocessor,
pre .pi,
pre .doctype,
pre .shebang,
pre .cdata {
  color: #999;
  font-weight: bold
}

pre .deletion {
  background: #fdd
}

pre .addition {
  background: #dfd
}

pre .diff .change {
  background: #0086b3
}

pre .chunk {
  color: #aaa
}


  </style>
</head>
<body>
    <div class="progress">
    <div class="progress-bar"></div>
  </div>

  <div class="slide" id="slide-1">
    <section class="slide-content"><h1 id="why-heroku">Why Heroku</h1>
<p>Heroku claims to be &quot;cloud computing designed and built for developers.&quot; But why do you care?</p>
</section>
  </div>
  <div class="slide hidden" id="slide-2">
    <section class="slide-content"><h2 id="focused-on-ease-of-development">Focused on Ease of Development</h2>
<p>From the beginning Heroku has focused on being easy for developers.</p>
</section>
  </div>
  <div class="slide hidden" id="slide-3">
    <section class="slide-content"><h3 id="just-use-a-vps-">Just Use a VPS?</h3>
<p>Many developers can stumble through setting up a VPS, following a myriad of tutorials and blog posts to setup a functioning web server with:</p>
<ul>
<li>Linux</li>
<li>NGINX or Apache front-end web server</li>
<li>Their application</li>
<li>Application Virtual Machine (JVM, Ruby VM, etc)</li>
<li>Application dependencies</li>
<li>PostgreSQL with user accounts and permissions</li>
<li>Memcached or other secondary data stores</li>
<li>Load balancing</li>
<li>Init.d scripts to handle graceful restart</li>
<li>A deployment system to receive code and restart the application</li>
</ul>
<p>It&#39;ll likely take days to get that configured correctly.</p>
</section>
  </div>
  <div class="slide hidden" id="slide-4">
    <section class="slide-content"><h3 id="fully-managed-platform">Fully Managed Platform</h3>
<p>And now you have a management issue. Each of those components:</p>
<ul>
<li>Has potential security vulnerabilities to keep on top of</li>
<li>Releases new versions and should be upgraded</li>
<li>Can crash/restart and need attention</li>
</ul>
<p>If you&#39;d prefer to spend your time building your application rather than administrating a server, Heroku is for you.</p>
</section>
  </div>
  <div class="slide hidden" id="slide-5">
    <section class="slide-content"><h3 id="quick-to-provision-quick-to-deploy">Quick to Provision, Quick to Deploy</h3>
<p>You can provision a new application on Heroku in seconds. Deploying your code and restarting your processes typically takes just a few minutes.</p>
</section>
  </div>
  <div class="slide hidden" id="slide-6">
    <section class="slide-content"><h3 id="industry-standards">Industry Standards</h3>
<p>And best of all, using Heroku doesn&#39;t mean compromising on your development tools or workflow. Typical Heroku apps rely industry-standard tools:</p>
<ul>
<li>Git for source control</li>
<li>Applications written in a modern, open-source language</li>
<li>A SQL database</li>
<li>UNIX under the hood</li>
</ul>
</section>
  </div>
  <div class="slide hidden" id="slide-7">
    <section class="slide-content"><h3 id="rich-configurability-with-add-ons">Rich Configurability with Add-Ons</h3>
<p>Just because the platform takes care of the administration doesn’t mean you’re locked into a single pattern or set of defaults. In fact, apps that you run on Heroku can just as easily run locally or somewhere else - you need almost no Heroku-specific changes to apps. You can customize your application to:</p>
<ul>
<li>use other databases like MongoDB or Hadoop</li>
<li>integrate with services to send Email, SMS and push notifications to users</li>
<li>shuttle runtime data to a variety of analytics and logging platforms</li>
<li>work with third-party billing systems to handle one-time and subscription payments</li>
</ul>
<p>There are over a hundred add-ons available on the platform with new ones constantly being added. Check out the full list at <a href="https://addons.heroku.com/">https://addons.heroku.com/</a>.</p>
</section>
  </div>
  <div class="slide hidden" id="slide-8">
    <section class="slide-content"><h2 id="use-cases">Use Cases</h2>
<p>Heroku can be put to use in many scenarios.</p>
</section>
  </div>
  <div class="slide hidden" id="slide-9">
    <section class="slide-content"><h3 id="web-applications-of-any-scale">Web Applications of Any Scale</h3>
<p>Thanks to the <strong>dyno</strong> approach, applications running on Heroku scale with ease.</p>
<p>Need to serve just a few requests an hour? Spin up a pair of dynos and you&#39;re good to go.</p>
<p>Need to serve a hundred requests per second? Scale up to fifty dynos and watch the traffic fly.</p>
</section>
  </div>
  <div class="slide hidden" id="slide-10">
    <section class="slide-content"><h3 id="rapid-development-deployment">Rapid Development &amp; Deployment</h3>
<p>Heroku excels in situations where applications need to deploy quickly and often. Teams might individually deploy their latest changes or rely on a Continuous Integration server to deploy continuously. After issuing just a single command, applications typically deploy and are live in seconds. Backed by git, it&#39;s easy to avoid conflicts or rollback changes when something goes wrong.</p>
<p>Long story short, Heroku takes the pain out of running your web applications.</p>
</section>
  </div>
  <div class="slide hidden" id="slide-11">
    <section class="slide-content"><h3 id="getting-started">Getting Started</h3>
<p>Assuming you have an existing Salesforce dataset, your first Heroku applications might include:</p>
<ul>
<li>A one-page application to register people in a sweepstakes, funneling their information into Salesforce</li>
<li>An analytics platform that pulls data out of Salesforce to generate visualizations using Node.js and D3</li>
<li>A content-management system that authenticates users via your Salesforce login/password</li>
<li>A web application that implements Salesforce&#39;s Canvas API, adding functionality into Salesforce itself</li>
</ul>
</section>
  </div>
  <div class="slide hidden" id="slide-12">
    <section class="slide-content"><h2 id="goals-for-today">Goals for Today</h2>
<p>Our plan for today is to explore the platform and experiment with deployment. By the end of the day you will:</p>
<ul>
<li>understand how the platform works and what it can do for you</li>
<li>provision and deploy a live Java-based application</li>
<li>scale the production environment to handle more traffic</li>
<li>install and configure an add-on to support your application</li>
<li>see how Heroku Connect opens huge potential for your Salesforce data</li>
</ul>
</section>
  </div>

  <div class="controls">
    <div class="arrow prev"></div>
    <div class="arrow next"></div>
  </div>


  <script type="text/javascript">
    /**
 * Returns the current page number of the presentation.
 */
function currentPosition() {
  return parseInt(document.querySelector('.slide:not(.hidden)').id.slice(6));
}


/**
 * Navigates forward n pages
 * If n is negative, we will navigate in reverse
 */
function navigate(n) {
  var position = currentPosition();
  var numSlides = document.getElementsByClassName('slide').length;

  /* Positions are 1-indexed, so we need to add and subtract 1 */
  var nextPosition = (position - 1 + n) % numSlides + 1;

  /* Normalize nextPosition in-case of a negative modulo result */
  nextPosition = (nextPosition - 1 + numSlides) % numSlides + 1;

  document.getElementById('slide-' + position).classList.add('hidden');
  document.getElementById('slide-' + nextPosition).classList.remove('hidden');

  updateProgress();
  updateURL();
  updateTabIndex();
}


/**
 * Updates the current URL to include a hashtag of the current page number.
 */
function updateURL() {
  window.history.replaceState({} , null, '#' + currentPosition());
}


/**
 * Sets the progress indicator.
 */
function updateProgress() {
  var progressBar = document.querySelector('.progress-bar');

  if (progressBar !== null) {
    var numSlides = document.getElementsByClassName('slide').length;
    var position = currentPosition() - 1;
    var percent = (numSlides === 1) ? 100 : 100 * position / (numSlides - 1);
    progressBar.style.width = percent.toString() + '%';
  }
}


/**
 * Removes tabindex property from all links on the current slide, sets
 * tabindex = -1 for all links on other slides. Prevents slides from appearing
 * out of control.
 */
function updateTabIndex() {
  var allLinks = document.querySelectorAll('.slide a');
  var position = currentPosition();
  var currentPageLinks = document.getElementById('slide-' + position).querySelectorAll('a');
  var i;

  for (i = 0; i < allLinks.length; i++) {
    allLinks[i].setAttribute('tabindex', -1);
  }

  for (i = 0; i < currentPageLinks.length; i++) {
    currentPageLinks[i].removeAttribute('tabindex');
  }
}

/**
 * Determines whether or not we are currently in full screen mode
 */
function isFullScreen() {
  return document.fullscreenElement ||
         document.mozFullScreenElement ||
         document.webkitFullscreenElement ||
         document.msFullscreenElement;
}

/**
 * Toggle fullScreen mode on document element.
 * Works on chrome (>= 15), firefox (>= 9), ie (>= 11), opera(>= 12.1), safari (>= 5).
 */
function toggleFullScreen() {
  /* Convenient renames */
  var docElem = document.documentElement;
  var doc = document;

  docElem.requestFullscreen =
      docElem.requestFullscreen ||
      docElem.msRequestFullscreen ||
      docElem.mozRequestFullScreen ||
      docElem.webkitRequestFullscreen.bind(docElem, Element.ALLOW_KEYBOARD_INPUT);

  doc.exitFullscreen =
      doc.exitFullscreen ||
      doc.msExitFullscreen ||
      doc.mozCancelFullScreen ||
      doc.webkitExitFullscreen;

  isFullScreen() ? doc.exitFullscreen() : docElem.requestFullscreen();
}

document.addEventListener('DOMContentLoaded', function () {
  // Update the tabindex to prevent weird slide transitioning
  updateTabIndex();

  // If the location hash specifies a page number, go to it.
  var page = window.location.hash.slice(1);
  if (page) {
    navigate(parseInt(page) - 1);
  }

  document.onkeydown = function (e) {
    var kc = e.keyCode;

    // left, down, H, J, backspace, PgUp - BACK
    // up, right, K, L, space, PgDn - FORWARD
    // enter - FULLSCREEN
    if (kc === 37 || kc === 40 || kc === 8 || kc === 72 || kc === 74 || kc === 33) {
      navigate(-1);
    } else if (kc === 38 || kc === 39 || kc === 32 || kc === 75 || kc === 76 || kc === 34) {
      navigate(1);
    } else if (kc === 13) {
      toggleFullScreen();
    }
  };

  if (document.querySelector('.next') && document.querySelector('.prev')) {
    document.querySelector('.next').onclick = function (e) {
      e.preventDefault();
      navigate(1);
    };

    document.querySelector('.prev').onclick = function (e) {
      e.preventDefault();
      navigate(-1);
    };
  }
});


  </script>
</body>
</html>

Replace `cleaver watch` with `cleaver --live`

I would like to phase out cleaver watch and opt-in for something a bit nicer. I'm thinking a --live option which does two things:

  • automatically rebuilds with an associated file is changed (we could just check for js, css, md, and mustache)
  • adds a live-reload functionality to the rendered slideshow

File locations are relative to where cleaver is called from, not the source document

For example, let's say I have a directory test_slides/, which contains a cleaver presentation github_talk.md and several stylesheets/templates/etc.

When calling cleaver on this document, we see the following:

$ ./bin/cleaver test_slides/github_talk.md

/Users/jordan/Projects/cleaver/node_modules/q/q.js:120
                    throw e;
                          ^
Error: ENOENT, open 'github_style.css'

This is because the document specifies style: github_style.css, which cleaver looks for in the current working directory, instead of the directory containing the source document.

To me, this seems like unexpected behavior.

Race Condition on reading CSS

There is a somewhat rare issue where cleaver is unable to finish reading the CSS before it begins to output to a file.

You'll notice that, on occasion, creating a document with cleaver doesn't have external styles included.

To fix this, I think we simply need to place the output code in a callback of the readFile for reading the CSS.

Command/Control progresses slides

A user reported that upon trying to cmd+click, the slideshow progresses 2 slides (two keydown's). To fix this, we should limit the "forward" keys to something like up, right, space, and enter. (K and L as well for vim controls)

Error when trying the example

If I copy the basic.md example from the view-raw and paste it in a new .md file and run it in cleaver I get this error:

YAMLException: JS-YAML: can not read a block mapping entry; a multiline key may not be an implicit key at line 10, column 1:
    # Cleaver 101
    ^

This is cleaver 0.2.0 from npm, on Windows Vista 64 using Node v0.10.17

Add page numbers

It would be great if page numbers were added. Perhaps it can be available as a template variable?

Scale font size to text on slide.

Have the font size scale depending on the amount of text/items on the slide, because right now it just overflows beyond the slide.

Add weibo options for author in default template

I have opened a issue just for add a weibo option in default template at first, but I forget cleaver is for presentation when I modify the template -_-||
I did that because I just watch a slide on others blog at that time...
In my opinion, the default template is pretty good but lack of some options. I hope to add a "weibo" option for we chinese user.
Add such code under the "twitter" field in cleaver / templates / author.mustache

{{#weibo}}
    <h3 class="weibo">
      <a href="http://weibo.com/{{{weibo}}}">{{{weibo}}}</a>
    </h3>
{{/weibo}}

Advanced templating using remote templates from github repos?

I developed Bochar and now I think that exists more efficient way to customize Cleaver. What do you think about method use to setup custom themes from github (user/repo or organization/repo)?

$ cleaver use Shower/Ribbon
$ cleaver use Shower/Bright

And resetted to default theme like this

$ cleaver use default

Provide CLI color options.

For very basic style changes, e.g., changing the background color, have command line options so users don't have to write their own CSS.

Output in same directory as input file

There should be an option (or maybe make it default?) to generate the output file in the same directory as the .md file, rather than the current directory.

No infinite loop

When you keep pressed one of the arrows, you keep cycling through the whole presentation, instead of just stopping at the first (or last) of the slides.

Mobile-friendly

Been fiddling with this all night - can't get anything substantial working. Hoping someone can take a stab at it.

Cleaver not producing the presentation

I installed cleaver using the npm command. I tried cleaver path/to/markdown.m but no results are produced. Infact, bash consumes the command cleaver but doesn't produce any content, like help or anything. Could someone help me here?

Responsive on mobile in landscape mode

The cleaver sideshows look really nice in a mobile device, especially in portrait mode the responsive design works well.

But the landscape view is less well:

I used a Samsung S3: with FireFox Mobile it is a bit crunched-up.

On mobile Chrome the portrait mode works well too, but the landscape mode is a mess: the layout collapses and can't navigate (or it hangs.. not sure :): I seems as if the arrow-controls are behind the content?

Adding possibility to do localization

Suggest adding a feature of using some library to have localized markdown that will only affect pipeline (markdown localizer that creates multiple *.md files -> multiple output presentations created by cleaver).

Leaving out metadata results in an error

Metadata should be optional (if left out, the file should begin with a -- before any slides).

However, if we try to parse a file without metadata, we receive the following error.

$ cleaver 10-01-13.md

/usr/local/lib/node_modules/cleaver/node_modules/q/q.js:120
                    throw e;
                          ^
TypeError: Cannot read property 'author' of null
    at Cleaver._renderSlides (/usr/local/lib/node_modules/cleaver/lib/cleaver.js:65:20)
    at _fulfilled (/usr/local/lib/node_modules/cleaver/node_modules/q/q.js:703:54)
    at self.promiseDispatch.done (/usr/local/lib/node_modules/cleaver/node_modules/q/q.js:732:30)
    at Promise.promise.promiseDispatch (/usr/local/lib/node_modules/cleaver/node_modules/q/q.js:669:13)
    at /usr/local/lib/node_modules/cleaver/node_modules/q/q.js:543:44
    at flush (/usr/local/lib/node_modules/cleaver/node_modules/q/q.js:106:17)
    at process._tickCallback (node.js:415:13)

Set default options from the command line

Dealing with a series of presentations (our all-hands meetings) in a directory, and would love to be able to set option defaults from the top-level so we don't have to declare/change them in each file separately. Right now we have:

/presentations
  /2014-08-11
  /2014-08-18
  /2014-08-25
  ...
index.css

Would love to be able to default our options to:

style: ../../index.css
output: slides.html
controls: false

By doing:

$ cleaver /path/to/slides.md \
    --no-controls \
    --style index.css \
    --output slides.html

Or similar.

Dynamic read-from-url / github feature

Add an online viewer to the github.io pages that can pull markdown from any URL and dynamically generate the presentation.

If this is not possible with cross-domain loading then limit the feature to github.com hosted markdown and use the Github REST API and/or raw.github.com urls to pull the raw files.

Depending on how you rig it up it can be 100% client side.

Multiple template support

In order to accommodate #18 and #19, we should allow the user to specify multiple templates (or render cleaver slides in another template based on parameters).

Speaker notes?

Is there anyway to set up a block in which freeform Markdown text can be added, so that in slideshow form, the text is hidden, but can be visible as HTML/Markdown when viewed on Github (or similar Markdown setup)?

Contributing guidleines

We can add Contributing.md file to the repo with contributing rules and requirements and any notes about creating issues process.

After adding this file Cleaver can link to this file in README.md and one another changes more valueable change is that, when developer will want to create issue or open PR he will see this message like this:

Optional progress indicator

It'd be great to have an optional progress indicator in the controls area, between the left and right arrows. It occurs to me that we can have a numeric index (1/10) and/or percentage (10%), do you think it fits?

Bug/ER: Style option replaces rather than appends to themes

From the docs:

By default, style.css and script.js will be appended to the default stylesheets and javascripts included in cleaver presentations.

title: Custom CSS
style: styles.css

=> Works as expected, appending styles.css to the default theme.

title: Custom theme CSS
theme: matmuchrapna/cleaver-ribbon
style: styles.css

=> Replaces theme styles with styles.css instead of appending them. Not sure if this is a bug or an ER, but it would be really convenient to easily customize themes by appending the CSS/JS.

License field for Cleaver presentations

Received an email today with the following:

In the Author part, at the beginning of the document, an item license will be great. I would like to indicate that my presentation is Creative Commons licensed for example.

I regrettably know very little about item licensing, but I'm thinking users could specify a license in the header which would put a tasteful badge in the left corner or the rendered slideshow.

Usually I direct these kinds of requests and suggest that users create their own layout, but I wonder if this feature is important enough to merit its own setting.

skip slides using links

I need to go from one slide to another using a hyperlink.

I am in basic.html#3 and I want to go to basic.html#7, I added a hyperlink to a text with link './basic.html#7'. On clicking it the address in the address bar changes, but the slide doesn't change. Is there any way to achieve this?

Watch throws an exception

Using cleaver to generate a presentation works, but trying to watch throws an exception:

➜  tmp  cleaver watch present/basic.md
Watching for changes on present/basic.md. Ctrl-C to abort.
fs.js:434
  binding.open(pathModule._makeLong(path),
          ^
TypeError: path must be a string
    at TypeError (native)
    at Object.fs.open (fs.js:434:11)
    at Object.fs.readFile (fs.js:227:6)
    at /Users/matt/.nvm/v0.11.13/lib/node_modules/cleaver/bin/cleaver:15:8
    at Array.forEach (native)
    at createAndSave (/Users/matt/.nvm/v0.11.13/lib/node_modules/cleaver/bin/cleaver:14:9)
    at Object.<anonymous> (/Users/matt/.nvm/v0.11.13/lib/node_modules/cleaver/bin/cleaver:98:3)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:349:32)

I also tried running under node 0.10.x. basic.md is simple the example presentation from the documentation.

--debug produces no additional information.

page number variable

Would like to see a page/slide number variable I can use in my mustache template so I can display the slide number on the screen. Useful when in full screen mode and the URL isn't visible.

Error when Debug not installed

Hi,

Debug is currently a dev dependency but it is required to actually run Cleaver even when debug is not specified in the cmd line option. It might be best to set it as a required dependency so that it is always installed.

Cheers

cleaver.json

A modest proposal

I'd like to start a conversation about this.

Currently, cleaver presentations contain metadata:

title: My presentation
author:
    name: Jordan Scales
    twitter: @jdan
output: talk.html
style: something.css

--

# My presentation
## It has a subtitle

This is, in my opinion, a little weird. I would like to separate documents into two parts: the actual presentation (just markdown) and a new file called cleaver.json, which may look like this:

{
  "title": "My presentation",
  "style": "something.css",
  "author": {
    "name": "Jordan Scales",
    "url": "http://jscal.es",
    "twitter": "@jdan"
  },
  "output": "talk.html"
}

I'd also like to reopen the possibility of handling command-line options (we used to do this)

cleaver presentation.md --style=something.css --output=talk.html

so you could avoid creating a cleaver.json.

Benefits

Separation of presentation content and settings. I feel like having the content and settings tightly coupled is a little counterintuitive. We could keep things more organized, which could open the door to a few new features - plugins, middleware, that sort of thing.

Downsides

No longer one file :(. The whole idea is that cleaver presentations are super portable, both when they're being creating and when they're rendered. You can still have your entire presentation contained in a single file, though, and simply use command-line options to achieve what you can now.

What are your thoughts?

Error loading styles when operating outside of cleaver/ directory

After a normal install (npm install -g cleaver), the user navigates to any folder and attempts to run cleaver [OPTIONS].

Unless the user is inside the cleaver/ source code directory, cleaver will not be able to load styles/default.css.

Instead, we need to figure out where cleaver is installed, and find styles/default.css there. Also, maybe make the alternative style, dark.css globally available as well.

No support for tables?

Is there no support for tables? I'm used to github's Markdown, which, apparently, isn't standard Markdown?

Cannot run example/basic.md

$ ./bin/cleaver examples/basic.md

module.js:340
throw err;
^
Error: Cannot find module 'q'
at Function.Module._resolveFilename (module.js:338:15)
at Function.Module._load (module.js:280:25)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at Object. (/home/data1/protected/Programming/git/cleaver/lib/cleaver.js:2:12)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.