src/markup/htdocs/docs/source-code/index.jade

extends ../../../templates/main

block stylesheets
  link(rel='stylesheet', href='/assets/styles/base.css')
  link(rel='stylesheet', href='/assets/styles/lib/solarized-pygments.css')
  style
    #wrapper {width: 1200px;}
    .highlight {font-size: 1em;}
    .highlight>pre {background-color: #fdf6e3;}
    .dark .highlight {background-color: #e2e2e2;}
    .dark .highlight>pre {background-color: #073642; color: #93a1a1;}

block headScripts
  script(src='/assets/scripts/vendor/modernizr-2.6.2.min.js')

block beforeWrapper
  | 

block header
  include ../../../includes/header
  a.github(href="https://github.com/simshanith/simshanith.github.io")
    img(src="https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png",
        alt="Fork me on GitHub")

block mainContent
  p
    button#theme Switch to Light
  include ../../../../../docs/source-code/source-code.html

src/markup/htdocs/index.jade

extends ../templates/main

block header
  include ../includes/header
  :markdown
    ## Jade+Stylus+Grunt = amazing.

block mainContent
  p
    button#theme Switch to Light
  :markdown
    Node.JS provides a powerful platform for programming the generation of static HTML files.
    This site is the result of an example build system.

    #### [Source Code Birds-eye](./docs/source-code/)

  #features
    h3 Features
    #current
      +includeMarkdown('src/markup/htdocs/docs/features.markdown')

    #planned
      +includeMarkdown('src/markup/htdocs/docs/addendum.markdown') 

src/markup/includes/endScripts.jade

//-
	MODERNIZR / YEPNOPE SCRIPT LOADING
	Jade currently doesn't wrap included JS files properly,
	so we have to do so manually with unescaped function output.
+includeJs('yepnope') 

src/markup/includes/footer.jade

:markdown
	###### Copyright © 2013 Shane Daniel

src/markup/includes/header.jade

:markdown
	# [Hello World.](/)

src/markup/includes/mixins.jade

//-
	Mixins for use throughout. Interfaces for Jade Locals helper functions.

mixin includeMarkdown(file)
	| 
	!= includeMarkdown(file)
	| 

mixin includeJs(file)
	| 
	!= includeJs(file)
	| 

src/markup/templates/main.jade

include ../includes/mixins

!!! 5
//if lt IE 7
  <html class="no-js lt-ie9 lt-ie8 lt-ie7">
//if IE 7
  <html class="no-js lt-ie9 lt-ie8">
//if IE 8
  <html class="no-js lt-ie9">
//[if gt IE 8]><!
html.no-js
  | <!--<![endif]-->
  head
    meta(charset='utf-8')
    meta(http-equiv='X-UA-Compatible', content='IE=edge,chrome=1')
    title Shane Daniel Github.io
    meta(name='description', content='')
    meta(name='keywords', content='')
    meta(name='HandheldFriendly', content='true')
    meta(name='MobileOptimized', content='width')
    meta(name='format-detection', content='telephone=no')
    block stylesheets
      link(rel='stylesheet', href='assets/styles/base.css')
    block favicons
      link(rel='apple-touch-icon', sizes='144x144', href='assets/images/touch/apple-touch-icon-144x144-precomposed.png')
      link(rel='apple-touch-icon', sizes='114x114', href='assets/images/touch/apple-touch-icon-114x114-precomposed.png')
      link(rel='apple-touch-icon', sizes='72x72', href='assets/images/touch/apple-touch-icon-72x72-precomposed.png')
      link(rel='apple-touch-icon', href='assets/images/touch/apple-touch-icon-57x57-precomposed.png')
      link(rel='shortcut icon', href='assets/images/touch/apple-touch-icon.png')
    meta(name='viewport', content='width=device-width, maximum-scale=1.0, target-densityDpi=320dpi')
    block headScripts
      script(src='assets/scripts/vendor/modernizr-2.6.2.min.js')
  body
    block beforeWrapper
      a.github(href="https://github.com/simshanith/simshanith.github.io")
        img(src="https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png",
            alt="Fork me on GitHub")
    #wrapper
      header#header
        block header
          include ../includes/header
      section#mainContent
        block mainContent
      footer#footer
        block footer
          include ../includes/footer
    block afterWrapper
    block endScripts
      include ../includes/endScripts

src/markup/templates/markdown.jade

extends main

block stylesheets
  link(rel='stylesheet', href='/assets/styles/base.css')

block headScripts
  script(src='/assets/scripts/vendor/modernizr-2.6.2.min.js')

block mainContent
  p
    button#theme Switch to Light 
    +includeMarkdown

src/scripts/jade/helpers/jade_locals.js

var marked = require('marked');

module.exports = function(grunt) {
  // Grunt loaded for utilities; do not configure here. 
  // Reading from configuration may not work either,
  // unless done at task runtime; e.g. in a function.
  var _ = grunt.util._;

  var jadeLocals = {};

  ///////////////////////////////////////////////////////////////////////////////////////
  // Expose grunt & _ to Jade.
  //
  // Done this way because grunt.log / grunt.verbose "or" functionality blows the stack
  // when attempting to simply `jadeLocals.grunt = grunt`
  //
  // Also, I would not advocate getting too complicated in template logic.
  // Most template scripts should be wrapped up as helper functions here,
  // rather than calling grunt directly from the template.
  //
  // Still, `!= grunt.file.read('relative/to/gruntfile.js')`
  // provides an awesome way for variable includes with absolute (project) paths,
  // and `grunt.task.current.name` may be handy.
  //
  //
  // _ + _.str just makes sense.
  //
  ///////////////////////////////////////////////////////////////////////////////////////
  var gruntOmissions       = ['log', 'verbose'];
  var gruntLogExports      = ['write','writeln','error','errorlns','ok','oklns','subhead','writeflags','debug'];

  jadeLocals.grunt         = _.omit(grunt, gruntOmissions);
  jadeLocals.grunt.log     = _.pick(grunt.log, gruntLogExports);
  jadeLocals.grunt.verbose = _.pick(grunt.verbose, gruntLogExports);
  jadeLocals._             = _;



  jadeLocals.includeJs = function(name) {
    if(!_.isString(name) || !name) {
      grunt.log.error('No script name included.');
      return;
    }

    function wrapScript(js){
      js = _.isString(js) && js || '';
      return ['<script type="text/javascript">',js,'</script>'].join('\n');
    }

    var build = grunt.config('build'),
        piece = (_.isString(build) && build != 'default') ? '.'+build : '';

    var baseDir    = 'src/markup/includes/scripts/',
        scriptPath = [baseDir, name, piece, '.js'].join(''),
        script     = grunt.file.read(scriptPath); // will fail task on error

    return wrapScript(script);
  };

  jadeLocals.includeMarkdown = function(markdownPath) {
    marked.setOptions({smartLists: true});

    markdownPath = markdownPath || grunt.config('markdownPath');

    var src  = markdownPath && _.isString(markdownPath) && grunt.file.read(markdownPath),
        output = src && marked(src);

    return output || '';
  };

  grunt.verbose.subhead('Loading Jade Locals module...').ok().writeln('Exports:');
  grunt.verbose.oklns(_.keys(jadeLocals).join('\n'));

  return jadeLocals;
};

src/scripts/jade/includes/yepnope.dev.js

////////////////////////////////////////////////////////////////////////////////
//
// ## Grunt Build Notes
// ### Main front-end script loader. Should be included inline in HTML.
//
// The Jade helper file, `src/scripts/jade/helpers/jade_locals.js`,
// exposes a `scriptLoader` function that returns script injecting JavaScript
// read from the filesystem.
// 
// The Jade include, `src/markup/includes/endScripts.jade`,
// calls `scriptLoader()` and wraps the unescaped return value
// in a `<script type="text/javascript"> tag.
//
// The `scriptLoader` function can be modified in the helper file
// to include different JavaScript based on the build.
//
// ## Script Notes
//  
// Development convenience script loader.
//
// ### jQuery
//
// Checks for online status, then attempts to download jQuery via CDN.
// Then, it checks for jQuery and falls back to a local copy.
//
// ### Scripts
// 
// Loads individual site scipts. Logs complete message.
//
////////////////////////////////////////////////////////////////////////////////
window.yepnope.complete = yepnope.complete || function (){};

yepnope([{ // ### jQuery (CDN)
    test: !window.jQuery && window.navigator && navigator.onLine,
    yep: '//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js',
    complete : function() {
      yepnope({ // ### jQuery (local fallback)
        test: !window.jQuery,
        yep: '/assets/scripts/vendor/jquery.min.js'
      });
    }
  }, { // ### Scripts
    load: ['/assets/scripts/main.js'],
    complete: function() {
      window.console && console.log && console.log('All scripts loaded.');
      window.yepnope.complete();
      window.yepnope.COMPLETED = true;
    }
  }]);

src/scripts/jade/includes/yepnope.js

////////////////////////////////////////////////////////////////////////////////
//
// ## Grunt Build Notes
// ### Main front-end script loader. Should be included inline in HTML.
//
// The Jade helper file, `src/scripts/jade/helpers/jade_locals.js`,
// exposes a `includeJS` function that returns script injecting JavaScript
// read from the filesystem, based on the build configuration.
// 
// The Jade include, `src/markup/includes/endScripts.jade`,
// uses the unescaped return value of `includeJs('yepnope')`
//
//
// ## Script Notes
//  
// Development convenience script loader.
//
// ### jQuery
//
// Checks for online status, then attempts to download jQuery via CDN.
// Then, it checks for jQuery and falls back to a local copy.
//
// ### Main Script
// 
// Loads site payload. Logs complete message.
//
////////////////////////////////////////////////////////////////////////////////
window.yepnope.complete = yepnope.complete || function (){};

yepnope([{ // ### jQuery (CDN)
    test: !window.jQuery && window.navigator && navigator.onLine,
    yep: '//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js',
    complete : function() {
      yepnope({ // ### jQuery (local fallback)
        test: !window.jQuery,
        yep: '/assets/scripts/vendor/jquery.min.js'
      });
    }
  }, { // ## Main Script
    load: ['/assets/scripts/main.min.js'],
    complete: function() {
      window.console && console.log && console.log('All scripts loaded.');
      yepnope.complete();
    }
  }]);

src/scripts/lib/main.js

;(function($, window, undefined){
  window.console && console.log('Welcome to main.js.');

  var $body = $('body'),
    $button = $('#theme'),
    dark = $button.text(),
    light = dark.replace('Light', 'Dark');

  function toggleTheme() {
    $body.toggleClass('light dark');
    var text = $body.hasClass('light') ? light : dark;
    $button.text(text);
  }

  window.toggleTheme = toggleTheme;

  function bindButton() {
    $body.addClass('dark');
    $button.click(toggleTheme);
  }

  $(bindButton);

})(jQuery, this);