From 969d1b86975be99b07aa30673a94d14a28a1cd29 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Sko=C5=99epa?= <jakub@skorepa.info>
Date: Wed, 9 Mar 2016 00:28:28 +0100
Subject: [PATCH] Misc feature parity changes

---
 index.js                                      | 169 +++++++++++++-----
 package.json                                  |   1 +
 sitegin/config.js                             |  17 +-
 sitegin/nunjucks.js                           |  31 +---
 sitegin/pipeline.js                           |   1 +
 sitegin/sitegin.js                            |   1 +
 sitegin/tags.js                               |  26 +--
 sitegin/urls.js                               |  15 ++
 theme/templates/article.html.nunj             |   8 +-
 .../{header.html.nunj => base.html.nunj}      |  53 +++++-
 theme/templates/partials/footer.html.nunj     |  44 -----
 theme/templates/partials/list.html.nunj       |   6 +-
 theme/templates/partials/paginator.html.nunj  |   2 +-
 theme/templates/tag.html.nunj                 |   8 +-
 14 files changed, 248 insertions(+), 134 deletions(-)
 create mode 100644 sitegin/urls.js
 rename theme/templates/partials/{header.html.nunj => base.html.nunj} (80%)
 delete mode 100644 theme/templates/partials/footer.html.nunj

diff --git a/index.js b/index.js
index eeadcef6..243f6585 100755
--- a/index.js
+++ b/index.js
@@ -1,49 +1,136 @@
 #!/usr/bin/env node
 var moment = require('moment');
+var cli = require('cli');
+var config = require('./sitegin/config');
 
-require('./sitegin/sitegin')({
-  watch: require('./sitegin/config').watch
-})
-.then(function onLoad(jobs) {
-  var sass = require('node-sass');
-  var fs = require('fs');
+cli.main(function(args, options) {
+  console.log(options);
+  config()
+  .then(function(obj) {
+    sitegin(obj.config);
+  })
+  .catch(function(e) {
+    console.log(e.stack);
+    process.exit();
+  });
+});
 
-  var isRunning = false;
-  var runAgain = false;
+var sitegin = function(config) {
+  var options = config.options;
+  require('./sitegin/sitegin')({
+    watch: !options.noserver
+  })
+  .then(function onLoad(jobs) {
+    var sass = require('node-sass');
+    var fs = require('fs');
 
-  function run() {
-    var startTime = moment();
-    runAgain = false;
-    if(isRunning) {
-      console.log("Generator is still running. Queing another run after it finishes.")
-      runAgain = true;
-      return;
+    // Main builder function
+    // If builder is not running - run it
+    // If it is running - schedule rerun after it finishes
+    var isRunning = false;
+    var runAgain = false;
+    var doSync = function(){}
+    function run() {
+      var startTime = moment();
+      runAgain = false;
+      if(isRunning) {
+        console.log("Generator is still running. Queing another run after it finishes.")
+        runAgain = true;
+        return;
+      }
+      console.log("================================================================================")
+      console.log("Running generator")
+      isRunning = true;
+      jobs.run('pipeline',jobs)
+      .then(function() {
+        isRunning = false;
+        console.log("Generator finished in",moment().diff(startTime,'seconds'),'seconds')
+        doSync();
+        if(runAgain) run();
+      })
+      .catch(function(e) {
+        isRunning = false;
+        console.log("Generator crashed in",moment().diff(startTime,'seconds'),'seconds')
+        if(runAgain) run();
+        if(e.stack)
+          console.log(e.stack)
+        else
+          console.log(e)
+      });
     }
-    console.log("================================================================================")
-    console.log("Running generator")
-    isRunning = true;
-    jobs.run('pipeline',jobs)
-    .then(function() {
-      isRunning = false;
-      console.log("Generator finished in",moment().diff(startTime,'seconds'),'seconds')
-      if(runAgain) run();
-    })
-    .catch(function(e) {
-      isRunning = false;
-      console.log("Generator crashed in",moment().diff(startTime,'seconds'),'seconds')
-      if(runAgain) run();
-      console.log(e.stack)
-    });
-  }
-
-  console.log('Sitegin successfully loaded');
-  jobs.onReload(function() {
-    console.log("Sitegin reloaded");
+
+    console.log('Sitegin successfully loaded');
     run();
+    copyStaticFiles(config.builddir);
+    rendersass(config.builddir);
+
+    if(!options.noserver) {
+      var sync = require('browser-sync').create();
+      doSync = function() {
+        sync.reload('*')
+      }
+      sync.init({
+        server: {
+          baseDir: config.builddir
+        },
+        ui: {
+          port: options.port+1
+        },
+        port: options.port
+      });
+
+      var chokidar = require('chokidar');
+      // article or theme reload
+      chokidar.watch(['content/','theme/'], {ignoreInitial: true})
+      .on('all', function(event, path) {
+        console.log('Content or theme changed. Rebuilding...');
+        run();
+      })
+
+      // sitegin reload
+      jobs.onReload(function() {
+        console.log("Sitegin reloaded");
+        run();
+      })
+    }
   })
-  run();
-})
-.catch(function(e) {
-  console.log(e.stack);
-  process.exit();
-});
+  .catch(function(e) {
+    console.log(e.stack);
+    process.exit();
+  });
+}
+
+var copyStaticFiles = function(builddir) {
+  // STATIC FILES
+  var fsextra = require('node-fs-extra');
+  fsextra.copy(
+      'static',
+      builddir,
+      function(file){ return !(file.match(".git") || file.match("static/articles")); },
+      function(){console.log("copy static done");}
+    );
+  fsextra.copy(
+      'static/articles',
+      builddir+"/clanek",
+      function(){console.log("copy static/articles done");}
+    );
+  fsextra.copy(
+      'theme/static',
+      builddir,
+      function(file){ return !file.match("\\.git") },
+      function(){console.log("copy theme/static done");}
+    );
+}
+
+var rendersass = function(builddir) {
+  // SASS
+  var sass = require('node-sass');
+  var fs = require('fs');
+
+  sass.render ({file: "theme/sass/style.scss"},function(err, result) {
+    if(err == null) {
+      console.log("compiled sass");
+      fs.writeFile(builddir+"/theme/style.css",result.css);
+    } else console.log("error ", err);
+  });
+};
diff --git a/package.json b/package.json
index 46762494..5be70aa4 100644
--- a/package.json
+++ b/package.json
@@ -11,6 +11,7 @@
   "dependencies": {
     "browser-sync": "^2.11.1",
     "chokidar": "^1.4.3",
+    "cli": "^0.11.2",
     "highlight.js": "^9.2.0",
     "jsesc": "^1.0.0",
     "marked": "^0.3.5",
diff --git a/sitegin/config.js b/sitegin/config.js
index 3edcef8f..02378ba8 100644
--- a/sitegin/config.js
+++ b/sitegin/config.js
@@ -5,13 +5,24 @@
  * (or write config reader which would replace this file - I'd appreciate
  * merge request for this feature ;) )
  */
+var cli = require('cli');
+var options = cli.parse({
+ noserver: ['n', 'Dont run server'],
+ port: ['p', 'Port on which server should run', 'number', 1337],
+ uiport: [null, 'BrowserSync UI port', 'number', 'port+1']
+});
 
 module.exports = function() {
   var builddir = "build";
-  if(process.argv[2] !== "compileonly") builddir = "build-debug";
+  if(!options.noserver) builddir = "build-debug";
+
+  if(options.uiport == 'port+1') {
+    options.uiport = options.port+1;
+  }
 
   return Promise.resolve({
     config: {
+      options: options,
       builddir: builddir,
       sourceDir: 'content',
       articlesLocation: 'articles',
@@ -19,6 +30,4 @@ module.exports = function() {
     }
   })
 }
-
- // This is only non-reloadable property since it controls reloading itself :P
-module.exports.watch = process.argv[2] !== "compileonly";
+module.exports.watch = !options.noserver;
diff --git a/sitegin/nunjucks.js b/sitegin/nunjucks.js
index c32bd21c..ee354284 100644
--- a/sitegin/nunjucks.js
+++ b/sitegin/nunjucks.js
@@ -7,19 +7,11 @@ var fs = require('fs');
 var dateFilter = require('nunjucks-date-filter');
 var util = require('util');
 
-var MyLoader = nunjucks.Loader.extend({
-    fileSystemLoader: {},
-    init: function(searchPaths, opts) {
-        fileSystemLoader = new nunjucks.FileSystemLoader(searchPaths, opts);
-    },
-
-    getSource: function(name) {
-        return fileSystemLoader.getSource(name+".nunj");
-    }
-});
-
-var templates = {};
-var env = new nunjucks.Environment(new MyLoader('theme/templates',{watch: require('./config').watch}));
+var watch = require('./config').watch;
+console.log('watch: '+watch);
+var env = new nunjucks.Environment(
+  new nunjucks.FileSystemLoader('theme/templates',{watch: watch})
+);
 
 env.addFilter('date', dateFilter);
 
@@ -48,15 +40,10 @@ env.addFilter('inspect', function(obj) {
 
 module.exports = function(data, type) {
   return new Promise(function(resolve, reject) {
-    if(templates[type] == undefined) {
-      env.getTemplate(type+'.html', true, function(err, tmpl) {
-        if(err) reject('Failed to load template '+type+'.html');
-        templates[type] = tmpl;
-        resolve(tmpl);
-      });
-    } else {
-      resolve(templates[type]);
-    }
+    env.getTemplate(type+'.html.nunj', true, function(err, tmpl) {
+      if(err) reject(new Error('Failed to load template '+type+'.html.nunj'));
+      resolve(tmpl);
+    });
   }).then(function(tmpl) {
     return tmpl.render(data);
   });
diff --git a/sitegin/pipeline.js b/sitegin/pipeline.js
index b1efcffa..7bc89858 100644
--- a/sitegin/pipeline.js
+++ b/sitegin/pipeline.js
@@ -8,6 +8,7 @@ module.exports = function(jobs) {
     'readFiles',
     'parseHugo',
     'gitInfo',
+    'urls',
     'markdown',
     'tags',
     'theme',
diff --git a/sitegin/sitegin.js b/sitegin/sitegin.js
index bf5a0e51..97bb02aa 100644
--- a/sitegin/sitegin.js
+++ b/sitegin/sitegin.js
@@ -13,6 +13,7 @@ module.exports = function(config) {
     ['tags', './tags'],
     ['nunjucks', './nunjucks'],
     ['theme', './theme'],
+    ['urls', './urls'],
     ['writeFiles', './writeFiles'],
 
     ['pipeline','./pipeline']
diff --git a/sitegin/tags.js b/sitegin/tags.js
index 2e6d6215..2e27c8dc 100644
--- a/sitegin/tags.js
+++ b/sitegin/tags.js
@@ -10,17 +10,21 @@ module.exports = function(obj) {
     var tags = new Array();
     var tagPages = {};
     obj.pages.forEach(function(article) {
-      if(article.metadata.tags)
-      article.metadata.tags.forEach(function(tag) {
-        tag = {
-          text: tag,
-          url: toURL(tag)
-        }
-        if(tags.map(function(e) { return e.url; }).indexOf(tag.url) < 0)
-          tags.push(tag)
-        if(tagPages[tag.url] == undefined) tagPages[tag.url] = new Array();
-        tagPages[tag.url].push(article)
-      })
+      if(article.metadata.tags) {
+        var ntags = [];
+        article.metadata.tags.forEach(function(tag) {
+          tag = {
+            text: tag,
+            url: toURL(tag)
+          }
+          ntags.push(tag);
+          if(tags.map(function(e) { return e.url; }).indexOf(tag.url) < 0)
+            tags.push(tag)
+          if(tagPages[tag.url] == undefined) tagPages[tag.url] = new Array();
+          tagPages[tag.url].push(article)
+        })
+        article.metadata.tags = ntags;
+      }
     });
 
     obj.tags = [];
diff --git a/sitegin/urls.js b/sitegin/urls.js
new file mode 100644
index 00000000..d8c0f62b
--- /dev/null
+++ b/sitegin/urls.js
@@ -0,0 +1,15 @@
+/*
+ * This jobs translates files to resulting URL
+ */
+
+module.exports = function(obj) {
+  return new Promise(function(resolve, reject) {
+    obj.pages.forEach(function(page) {
+      var file = page.file;
+      file = file.replace(/\\.md$/,'');
+      file = file.replace(/^articles/,'clanek');
+      page.file = file;
+    })
+    resolve(obj)
+  });
+}
diff --git a/theme/templates/article.html.nunj b/theme/templates/article.html.nunj
index db1cf955..afca50de 100644
--- a/theme/templates/article.html.nunj
+++ b/theme/templates/article.html.nunj
@@ -1,4 +1,8 @@
-{% include "partials/header.html" %}
+{% extends "partials/base.html.nunj" %}
+
+{% block bodyattr %} class="type-article"{% endblock %}
+
+{% block content %}
   <div class="section container" id="content">
     <div class="metadata">
       <h2 id="title">{{ metadata.title }}</h2>
@@ -30,4 +34,4 @@
       </p>
     </article>
   </div>
-{% include "partials/footer.html" %}
+{% endblock %}
diff --git a/theme/templates/partials/header.html.nunj b/theme/templates/partials/base.html.nunj
similarity index 80%
rename from theme/templates/partials/header.html.nunj
rename to theme/templates/partials/base.html.nunj
index 6c9d1a6c..83d92a22 100644
--- a/theme/templates/partials/header.html.nunj
+++ b/theme/templates/partials/base.html.nunj
@@ -38,8 +38,8 @@
   {% endif %}
   {{ metadata.headerextra | safe }}
 </head>
-<body {{ "class=type-article" if type=="article" }}>
-  {% import "partials/svgs.html" as svgs %}
+<body{% block bodyattr %}{% endblock %}>
+  {% import "partials/svgs.html.nunj" as svgs %}
   <div id="all">
     <!-- Top nav -->
     <nav class="supernav" role="navigation" style="z-index:5;position:absolute;">
@@ -141,4 +141,51 @@
         </ul>
       </div>
     </nav>
-    {% include "partials/search.html" %}
+    {% include "partials/search.html.nunj" %}
+
+    {% block content %}
+    {% endblock %}
+
+    <footer class="page-footer blue">
+        <div class="container s6">
+          <a class="orange-text text-lighten-3" href="https://git.ok1kvk.cz/">Gitlab</a> |
+          <a class="orange-text text-lighten-3" href="https://ok1kvk.cz/forum">Fórum</a> |
+          <a class="orange-text text-lighten-3">Webkamera</a>
+          {% if type=="article" %}
+          | <a class="orange-text text-lighten-3" href="https://git.ok1kvk.cz/ok1kvk.cz/content/tree/master/articles/{{file | replace("clanek/","")}}.md">Zdroják tohoto článku</a>
+          {% endif %}
+        </div>
+        <div class="container s6">
+        Stránky pro OK1KVK vytvořil <a class="orange-text text-lighten-3">Jakub Skořepa</a> 2015-2016
+        </div>
+    </footer>
+
+    <script src="{{ config.baseurl }}/theme/js/materialize.js"></script>
+    <script src="{{ config.baseurl }}/theme/js/init.js"></script>
+
+    <script>
+      (function($) {
+      var onresize = function(){
+        $("footer").height("auto");
+        $("#content").css("margin-bottom",$("footer").height());
+      };
+      $(window).resize(onresize);
+      $(document).load(onresize);
+      $(document).ready(onresize);
+    })(jQuery);
+    </script>
+    {% if not config.debug %}
+      <script>
+        (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+        (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+        m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+        })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+        ga('create', 'UA-74646565-1', 'auto');
+        ga('send', 'pageview');
+
+      </script>
+    {% endif %}
+    <script src="{{ config.baseurl }}/theme/lightbox2/dist/js/lightbox.min.js"></script>
+  </body>
+</html>
diff --git a/theme/templates/partials/footer.html.nunj b/theme/templates/partials/footer.html.nunj
deleted file mode 100644
index 2b2c3734..00000000
--- a/theme/templates/partials/footer.html.nunj
+++ /dev/null
@@ -1,44 +0,0 @@
-      <footer class="page-footer blue">
-          <div class="container s6">
-            <a class="orange-text text-lighten-3" href="https://git.ok1kvk.cz/">Gitlab</a> |
-            <a class="orange-text text-lighten-3" href="https://ok1kvk.cz/forum">Fórum</a> |
-            <a class="orange-text text-lighten-3">Webkamera</a>
-            {% if type=="article" %} 
-            | <a class="orange-text text-lighten-3" href="https://git.ok1kvk.cz/ok1kvk.cz/content/tree/master/articles/{{file | replace("clanek/","")}}.md">Zdroják tohoto článku</a>
-            {% endif %}
-          </div>
-          <div class="container s6">
-          Stránky pro OK1KVK vytvořil <a class="orange-text text-lighten-3">Jakub Skořepa</a> 2015-2016
-          </div>
-      </footer>
-
-      <script src="{{ config.baseurl }}/theme/js/materialize.js"></script>
-      <script src="{{ config.baseurl }}/theme/js/init.js"></script>
-
-    </div> <!-- #wrapper -->
-    <script>
-      (function($) {
-      var onresize = function(){
-        $("footer").height("auto");
-        $("#content").css("margin-bottom",$("footer").height());
-      };
-      $(window).resize(onresize);
-      $(document).load(onresize);
-      $(document).ready(onresize);
-    })(jQuery);
-    </script>
-    {% if not config.debug %}
-      <script>
-        (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
-        (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
-        m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
-        })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
-
-        ga('create', 'UA-74646565-1', 'auto');
-        ga('send', 'pageview');
-
-      </script>
-    {% endif %}
-    <script src="{{ config.baseurl }}/theme/lightbox2/dist/js/lightbox.min.js"></script>
-  </body>
-</html>
diff --git a/theme/templates/partials/list.html.nunj b/theme/templates/partials/list.html.nunj
index 350be36b..fa30d58f 100644
--- a/theme/templates/partials/list.html.nunj
+++ b/theme/templates/partials/list.html.nunj
@@ -1,4 +1,4 @@
-{% import "partials/svgs.html" as svgs %}
+{% import "partials/svgs.html.nunj" as svgs %}
   <div id=content class=container>
     <div class="section">
       <div class="row">
@@ -8,7 +8,7 @@
             <div class="block article" style="">
               <a href="{{ config.baseurl }}/{{ page.file }}">
                 <div style="height:120px;
-                  {% if page.metadata.image %}background-image: url('{{config.baseurl}}/{{ page.metadata.image }}'){% endif %}
+                  {% if page.metadata.image %}background-image: url('{{ page.file }}/{{ page.metadata.image }}'){% endif %}
                   " class="leadimage light-blue darken-2"></div>
               </a>
               <div class="head-title">
@@ -36,7 +36,7 @@
         {% endfor %}
       </div>
 
-      {% include "partials/paginator.html" %}
+      {% include "partials/paginator.html.nunj" %}
     </div>
 
     <div class="hide-on-small-only">
diff --git a/theme/templates/partials/paginator.html.nunj b/theme/templates/partials/paginator.html.nunj
index ab8dd69e..f81ce3a5 100644
--- a/theme/templates/partials/paginator.html.nunj
+++ b/theme/templates/partials/paginator.html.nunj
@@ -1,4 +1,4 @@
-{% import "partials/svgs.html" as svgs %}
+{% import "partials/svgs.html.nunj" as svgs %}
 
 <ul class="pagination">
   <li><a {{ (" href=\""+config.baseurl +"/"+ metadata.firstpage.file +"\"") | safe if metadata.firstpage.file != file }}>
diff --git a/theme/templates/tag.html.nunj b/theme/templates/tag.html.nunj
index fb0913d0..b086b5c7 100644
--- a/theme/templates/tag.html.nunj
+++ b/theme/templates/tag.html.nunj
@@ -1,3 +1,5 @@
-{% include "partials/header.html" %}
-{% include "partials/list.html" %}
-{% include "partials/footer.html" %}
+{% extends "partials/base.html.nunj" %}
+
+{% block content %}
+    {% include "partials/list.html.nunj" %}
+{% endblock %}
-- 
GitLab