Commit 93d2aebb authored by abyxcos's avatar abyxcos
Browse files

Import smallblog.pl

parent 08e1af8e
#!/bin/sh
# Copyright (c) 2013, Aaron Fineman <abyxcos@mnetic.ch>
#
# Permission to use, copy, modify, and/or distribute this software for
# any purpose with or without fee is hereby granted, provided that the
# above copyright notice and this permission notice appear in all
# copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS
# ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
# USE OR PERFORMANCE OF THIS SOFTWARE.
## Config file
. ./smallblog.conf # Default conf file
## HTML templates
blog_header="
<!-- HTML generated by smallblog <https://github.com/abyxcos/smallblog> -->
<!DOCTYPE html>
<html>
<head>
<title>%TITLE%</title>
<link rel=\"stylesheet\" href=\"${PREFIX}/main.css\">
<link rel=\"stylesheet\" href=\"${PREFIX}/local.css\">
<link rel=\"stylesheet\" href=\"main.css\">
<link rel=\"stylesheet\" href=\"local.css\">
</head>
<body>
<div class=\"container\">
<div class=\"site\">
<div class=\"header\">
<h1 class=\"title\"><a href=\"${PREFIX}\">${title}</a></h1>
<a class=\"extra\" href=\"${PREFIX}/archive.html\">all posts</a>
${menu}
</div>"
blog_footer="
<div class=\"footer\"><p />
<div class=\"contact\">
${name}<br />
${footer2_text}
</div>
<div class=\"contact\">
<a href=\"mailto:${email}\">${email}</a><br />
<a href=\"${footer2_link}\">${footer2_link}</a>
</div>
</div>
</div>
</div>
</body>
</html>"
## Supporting functions
# make_post filename.md
make_post(){
_title=`head -n1 $1 | sed 's/^#* //'`
_date=${1%/*}
echo "<h1 class=\"title\"><a href='${PREFIX}/$1.html'>${_title}</a></h1>"
echo "<p class=\"meta\">Date: ${_date//\//-}</p>"
echo "<div class=\"post\">"
tail -n +2 "$1" | markdown | sed 's/^<p>tags: /<p class=\"meta\">tags: /'
echo "</div><br/>"
echo ""
}
# make_index folder title
make_index(){
echo "${blog_header/\%TITLE\%/$2}"
echo "<h2>$2:</h2>"
echo "<ul class=\"posts\">"
# Sort by time and dereference symmlinks
for post in `ls -Ht ${1}/*.md`; do
_title=`head -n 1 "${post}" | sed 's/#* //'`
echo "<li><span>${post%/*}</span> &raquo; <a href=\"${PREFIX}/${post}.html\">${_title}</a></li>"
done
echo "</ul>"
echo "${blog_footer}"
}
# make_date_index folder title
make_date_index(){
echo "${blog_header/\%TITLE\%/$2}"
echo "<h2>$2:</h2>"
echo "<ul class=\"posts\">"
for post in `ls -r ${1}/*.md`; do
_title=`head -n 1 "${post}" | sed 's/#* //'`
_time=${post%/*}
_month=`echo ${_time} | cut -d/ -f2`
if [ "${_oldmonth-"00"}" != "${_month}" ]; then
_oldmonth="${_month}"
echo "<h3>${_time%%/*} - ${_month}:</h3>"
fi
echo "<li><span>${_time//\//-}</span> &raquo; <a href=\"${PREFIX}/${post}.html\">${_title}</a></li>"
done
echo "</ul>"
echo "${blog_footer}"
}
## Start of the main logic
# Generate the individual posts
for post in `ls -r */*/*/*.md`; do
_title=`head -n1 ${post} | sed 's/^#* //'`
echo "${blog_header/\%TITLE\%/${_title}} `make_post "${post}"` ${blog_footer}" > "${post}.html"
done
# Generate the blog front page (index.html)
echo "" > index.html
echo "${blog_header/\%TITLE\%/${title}}" >> index.html
for post in `ls -r */*/*/*.md | head -n ${max_posts}`; do
make_post "${post}" >> index.html
done
echo "<h3><a class=\"extra\" href=\"${PREFIX}/archive.html\">all posts</a></h3>" >> index.html
echo "${blog_footer}" >> index.html
# Generate the archive page of all posts
make_date_index "*/*/*" "Archives" > archive.html
# Run all user specified plugins
# Only load plugins from the execution path
# Do not run arbitrary files in the web directory
for plugin in ${plugins}; do
[ ${1-""} = "-v" ] && echo "Running plugin: ${plugin}"
. ${0%/*}/plugins/${plugin}.sh
done
# Program configuration
PREFIX=/blog # Root folder for your blog
max_posts=5 # Maximum posts on the front page
plugins="tags rss" # List of plugins to run
prefix: /emc/finema/src/playground/smallblog2/blog
max_posts: 5
# User configuarion
title="mnetic.ch/blog" # The title of your blog
site="http://mnetic.ch" # The address of your site
name="Aaron Fineman" # Name for footer
email="abyxcos@mnetic.ch" # Email for footer
footer2_text="github:" # Second line for footer
footer2_link="https://github.com/abyxcos/" # Second link for footer
menu="<a class=\"extra\" href=\"${PREFIX}/tags/\">tags</a>
<a class=\"extra\" href=\"${PREFIX}/feed.rss\">rss</a>"
# User configuration
title: "mnetic.ch/blog"
name: "Aaron Fineman"
email: "abyxcos@mnetic.ch"
footer2_text: "github:"
footer2_link: "https://github.com/abyxcos"
#!/usr/bin/perl
use strict;
use warnings;
use Template;
use YAML::Tiny;
use File::Slurp;
use Text::Markdown::Discount qw(markdown);
use File::stat;
use POSIX qw(strftime);
my $yaml = YAML::Tiny->read('smallblog.conf');
my $site = $yaml->[0];
my $tt = Template->new({
INCLUDE_PATH => 'templates',
INTERPOLATE => 1, # Shell style ${...} variables
#PRE_CHOMP => 1,
POST_CHOMP => 1,
}) || die "$Template::ERROR\n";
# Takes a path to a post.md and returns a $vars hash
sub parse_post {
my $path = shift;
my $text = read_file($path);
my $title;
my @tags;
my $date;
my $edit_date;
my $html;
# Grab title
$text =~ s/^# (?<title>.+)//;
$title = $+{title};
# Grab tags into an array
$text =~ s/^tags: (?<tags>.+?)\n//ms;
@tags = split(" ", $+{tags});
# Update the global tags list
$site->{tags}{$_} = 1 foreach (@tags);
# Grab date from path and reformat slashes to dashes
my ($year,$month,$day) = ($path =~ m/(.*)\/(.*)\/(.*)\/.*.md/);
$date = "$year-$month-$day";
# Grab the file mtime with stat as edited time
my $st = stat($path);
my $fdt = strftime("%Y-%m-%d", localtime($st->mtime));
$edit_date = $fdt if ($date ne $fdt);
$html = markdown($text);
# Local (post-specific) variables
return {
path => $path,
title => $title,
tags => \@tags,
date => $date,
edit_date => $edit_date,
html => $html,
};
}
# Grab markdown files from a YYYY/MM/DD/post.md structure
my @paths = split("\n", qx(ls -r */*/*/*.md));
# Prase the files into an array to save filesystem lookups
my @posts = map {parse_post($_)} @paths;
# Generate posts.md.html
foreach my $post (@posts) {
my $vars = {
site => $site,
post => $post,
};
$tt->process('post_page.tmpl', $vars, "$post->{path}.html")
|| die "Generating $post->{path} failed: ", $tt->error(), "\n";
}
# Generate index.html
{
my $vars = {
site => $site,
posts => [@posts[0 .. $site->{max_posts}-1]],
};
$tt->process('index.tmpl', $vars, "index.html")
|| die "index.html failed: ", $tt->error(), "\n";
}
# Generate archive.html
{
my $vars = {
site => $site,
posts => \@posts,
title => 'Archives',
};
$tt->process('archive_page.tmpl', $vars, "archive.html")
|| die "archive.html failed: ", $tt->error(), "\n";
}
# Generate tags/index.html
{
my $vars = {
site => $site,
title => 'Tags',
};
$tt->process('tag_index.tmpl', $vars, "tags.html")
|| die "tags/index.html failed: ", $tt->error(), "\n";
}
# Generate tags/$tag.html
foreach my $tag (keys $site->{tags}) {
my @tag_posts = map {grep(/$tag/, @{$_->{tags}}) ? $_ : ()} @posts;
my $vars = {
site => $site,
posts => \@tag_posts,
title => $tag,
};
$tt->process('tag_page.tmpl', $vars, "tags/$tag.html")
|| die "tags/$tag.html failed: ", $tt->error(), "\n";
}
# Generate feed.rss
{
my $vars = {
site => $site,
posts => \@posts,
};
$tt->process('rss.tmpl', $vars, "feed.rss")
|| die "feed.rss failed: ", $tt->error(), "\n";
}
.meta a { text-decoration: none; }
.meta a:hover { color: #000; }
/*.meta a:visited { color: #aaa; }*/
/*
(The MIT License)
Copyright (c) 2008 Tom Preston-Werner
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the 'Software'), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
/*
* Default main.css from the jekyll project <jekyllrb.com>
* https://github.com/mojombo/jekyll/blob/master/lib/site_template/css/main.css
*/
/*****************************************************************************/
/*
/* Common
/*
/*****************************************************************************/
/* Global Reset */
* {
margin: 0;
padding: 0;
}
html, body { height: 100%; }
body {
background-color: #FFF;
font: 13.34px Helvetica, Arial, sans-serif;
font-size: small;
text-align: center;
}
h1, h2, h3, h4, h5, h6 {
font-size: 100%; }
h1 { margin-bottom: 1em; }
p { margin: 1em 0; }
a { color: #00a; }
a:hover { color: #000; }
a:visited { color: #a0a; }
/*****************************************************************************/
/*
/* Home
/*
/*****************************************************************************/
ul.posts {
list-style-type: none;
margin-bottom: 2em;
}
ul.posts li {
line-height: 1.75em;
}
ul.posts span {
color: #aaa;
font-family: Monaco, "Courier New", monospace;
font-size: 80%;
}
/*****************************************************************************/
/*
/* Site
/*
/*****************************************************************************/
.site {
font-size: 115%;
text-align: justify;
width: 42em;
margin: 3em auto 2em;
line-height: 1.5em;
}
.site .header a {
font-weight: bold;
text-decoration: none;
}
.site .header h1.title {
display: inline-block;
margin-bottom: 2em;
}
.site .header h1.title a {
color: #a00;
}
.site .header h1.title a:hover {
color: #000;
}
.site .header a.extra {
color: #aaa;
margin-left: 1em;
}
.site .header a.extra:hover {
color: #000;
}
.site .meta {
color: #aaa;
}
.site .footer {
font-size: 80%;
color: #666;
border-top: 4px solid #eee;
margin-top: 2em;
overflow: hidden;
}
.site .footer .contact {
float: left;
margin-right: 3em;
}
.site .footer .contact a {
color: #8085C1;
}
.site .footer .rss {
margin-top: 1.1em;
margin-right: -.2em;
float: right;
}
.site .footer .rss img {
border: 0;
}
/*****************************************************************************/
/*
/* Posts
/*
/*****************************************************************************/
/* standard */
.post pre {
border: 1px solid #ddd;
background-color: #eef;
padding: 0 .4em;
}
.post ul, .post ol {
margin-left: 1.35em;
}
.post code {
border: 1px solid #ddd;
background-color: #eef;
padding: 0 .2em;
}
.post pre code {
border: none;
}
/* terminal */
.post pre.terminal {
border: 1px solid #000;
background-color: #333;
color: #FFF;
}
.post pre.terminal code {
background-color: #333;
}
[% INCLUDE site_header.tmpl title=title %]
<h1>${title}:</h1>
<ul class="posts">
[% FOREACH post=posts %]
[% # Print a YYYY-MM heading at a month granularity %]
[% SET post.short_date = post.date.remove('-..$') %]
[% IF post.short_date != date %]
[% SET date = post.short_date %]
<h3>${date}</h3>
[% END %]
<li><span>${post.date}</span> &raquo; <a href="${site.prefix}/${post.path}.html">${post.title}</a></li>
[% END %]
</ul>
[% INCLUDE site_footer.tmpl %]
[% INCLUDE site_header.tmpl title=site.title %]
[% FOREACH post=posts %]
[% INCLUDE post.tmpl %]
<br />
[% END %]
<h3><a class="extra" href="${site.prefix}/archive.html">all posts</a></h3>
[% INCLUDE site_footer.tmpl %]
<h1 class="title"><a href="${site.prefix}/${post.path}.html">${post.title}</a></h1>
<p class="meta">Date: ${post.date}</p>
<div class="post">
${post.html}
[% IF post.edit_date %]
<p class="meta">Last edited: ${post.edit_date}</p>
[% END %]
<p class="meta">tags:
[% FOREACH tag=post.tags %]
<a class="meta" href="${site.prefix}/tags/${tag}.html">${tag}</a>
[% END %]
</p>
</div>
[% INCLUDE site_header.tmpl title=post.title %]
[% INCLUDE post.tmpl %]
<br />
[% INCLUDE site_footer.tmpl %]
<?xml version="1.0" ?>
<rss version="2.0" >
<channel>
<title>${site.title}</title>
<link>${site.prefix}</link>
<description>${site.title}</description>
[% FOREACH post=posts %]
<item>
<title>${post.title}</title>
<link>${site.prefix}/${post.path}</link>
[% # FIXME: Hardcode a time and timezone into the pubDate %]
[% # Use mtime (post.edit_date) over ctime (post.date) %]
<pubDate>${post.edit_date}</pubDate>
<description>
tags: [% FOREACH tag=post.tags %]${tag} [% END %]
</description>
</item>
[% END %]
</channel>
</rss>
<div class="footer">
<div class="contact">
<p>
${site.name}<br />
${site.footer2_text}<br />
</p>
</div>
<div class="contact">
<p>
<a href="mailto:${site.email}">${site.email}</a><br />
<a href="${site.footer2_link}">${site.footer2_link}</a><br />
</p>
</div>
</div>
</div>
</body>
</html>
<!-- HTML generated by smallblog <https://github.com/abyxcos/smallblog> -->
<!DOCTYPE html>
<html>
<head>
<title>${title}</title>
<link rel="stylesheet" href="${site.prefix}/static/main.css">
<link rel="stylesheet" href="${site.prefix}/static/local.css">
<link rel="stylesheet" href="static/main.css">
<link rel="stylesheet" href="static/local.css">
</head>
<body>
<div class="site">
<div class="header">
<h1 class="title"><a href="${site.prefix}">${site.title}</a></h1>
<a class="extra" href="${site.prefix}/archive.html">all posts</a>
<a class="extra" href="${site.prefix}/tags.html">tags</a>
<a class="extra" href="${site.prefix}/feed.rss">rss</a>
</div>
[% INCLUDE site_header.tmpl title=title %]
<h1>${title}:</h1>
<ul class="posts">
[% FOREACH tag=site.tags %]
<li><a href="${site.prefix}/tags/${tag.key}.html">${tag.key}</a></li>
[% END %]
</ul>
[% INCLUDE site_footer.tmpl %]
[% INCLUDE site_header.tmpl title=title %]
<h2>${title}:</h2>
<ul class="posts">
[% FOREACH post=posts %]
<li><span>${post.date}</span> &raquo; <a href="${site.prefix}/${post.path}.html">${post.title}</a></li>
[% END %]
</ul>
[% INCLUDE site_footer.tmpl %]
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment