From c52557f0a969e539138b0fdd4d7dd25f8795b509 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sat, 31 Dec 2016 17:43:33 -0700 Subject: wip --- bin/index | 14 +++++++ bin/index.atom.erb | 25 ++++++++++++ bin/index.md.erb | 13 ++++++ bin/page | 10 +++++ bin/page.html.erb | 32 +++++++++++++++ bin/pandoc.rb | 95 ++++++++++++++++++++++++++++++++++++++++++++ bin/post-commit | 25 ++++++++++++ bin/util.rb | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++ bin/write-atomic | 21 ++++++++++ bin/write-ifchanged | 25 ++++++++++++ 10 files changed, 371 insertions(+) create mode 100755 bin/index create mode 100644 bin/index.atom.erb create mode 100644 bin/index.md.erb create mode 100755 bin/page create mode 100644 bin/page.html.erb create mode 100644 bin/pandoc.rb create mode 100755 bin/post-commit create mode 100644 bin/util.rb create mode 100755 bin/write-atomic create mode 100755 bin/write-ifchanged (limited to 'bin') diff --git a/bin/index b/bin/index new file mode 100755 index 0000000..44cdc35 --- /dev/null +++ b/bin/index @@ -0,0 +1,14 @@ +#!/usr/bin/env ruby +# -*- coding: utf-8 -*- +load 'util.rb' + +template = "index.#{ARGV.shift}.erb" + +@pages = [] +for filename in ARGV do + @pages.push(Page.new(filename)) +end + +erb = ERB.new(File.read(template)); +erb.filename = template +erb.run() diff --git a/bin/index.atom.erb b/bin/index.atom.erb new file mode 100644 index 0000000..a5e1586 --- /dev/null +++ b/bin/index.atom.erb @@ -0,0 +1,25 @@ + + + + Luke Shumaker's Web Log + + + + <%= @pages.map{|p|p.date}.sort.last.rfc3339 %> + <%= Person.new("Luke Shumaker").atom %> + https://lukeshu.com/blog/ + + <% @pages.sort_by{|p| p.date}.reverse.each do |page| %> + + + + https://lukeshu.com/blog/<%= page.slug %>.html + <%= page.date.rfc3339 %> + <%= page.date.rfc3339 %> + <%= page.title %> + <%= html_escape(page.content) %> + <%= page.author.atom %> + <%= html_escape(page.rights) %> + + <% end %> + diff --git a/bin/index.md.erb b/bin/index.md.erb new file mode 100644 index 0000000..4da9a5d --- /dev/null +++ b/bin/index.md.erb @@ -0,0 +1,13 @@ +Web log entries +=============== + +<% @pages.sort_by{|p| p.date}.reverse.each do |a| %> + * - [<%= a.title %>](./<%= a.slug %>.html)<% end %> diff --git a/bin/page b/bin/page new file mode 100755 index 0000000..ca8b5bd --- /dev/null +++ b/bin/page @@ -0,0 +1,10 @@ +#!/usr/bin/env ruby +# -*- coding: utf-8 -*- +load 'util.rb' + +template = "bin/page.#{ARGV[0]}.erb" +@page = Page.new(ARGV[1]) + +erb = ERB.new(File.read(template)); +erb.filename = template +erb.run() diff --git a/bin/page.html.erb b/bin/page.html.erb new file mode 100644 index 0000000..2dee55e --- /dev/null +++ b/bin/page.html.erb @@ -0,0 +1,32 @@ + + + + + <%= @page.title %> + + + <%= @page.head %> + + +
<%= @page.breadcrumbs %>
+
+

Andrew DM

+
+
+

<%= @page.title %>

+ <%= @page.content %> +
+ + + diff --git a/bin/pandoc.rb b/bin/pandoc.rb new file mode 100644 index 0000000..155ddde --- /dev/null +++ b/bin/pandoc.rb @@ -0,0 +1,95 @@ +require 'open3' +require 'json' + +module Pandoc + def self.prog + @prog ||= 'pandoc' + end + def self.prog=(val) + @prog = val + end + def self.load(fmt, input) + cmd = Pandoc::prog + " -t json" + unless fmt.nil? + cmd += " -f " + fmt + end + str = input + if str.respond_to? :read + str = str.read + end + json = '' + errors = '' + Open3::popen3(cmd) do |stdin, stdout, stderr| + stdin.puts(str) + stdin.close + json = stdout.read + errors = stderr.read + end + unless errors.empty? + raise errors + end + return Pandoc::AST::new(json) + end + + class AST + def initialize(json) + @js = JSON::parse(json) + end + + def [](key) + Pandoc::AST::js2sane(@js["meta"][key]) + end + + def js + @js + end + + def to(format) + cmd = Pandoc::prog + " -f json -t " + format.to_s + output = '' + errors = '' + Open3::popen3(cmd) do |stdin, stdout, stderr| + stdin.puts @js.to_json + stdin.close + output = stdout.read + errors = stderr.read + end + unless errors.empty? + raise errors + end + return output + end + + def self.js2sane(js) + if js.nil? + return js + end + case js["t"] + when "MetaMap" + Hash[js["c"].map{|k,v| [k, js2sane(v)]}] + when "MetaList" + js["c"].map{|c| js2sane(c)} + when "MetaBool" + js["c"] + when "MetaString" + js["c"] + when "MetaInlines" + js["c"].map{|c| js2sane(c)}.join() + when "MetaBlocks" + js["c"].map{|c| js2sane(c)}.join("\n") + when "Str" + js["c"] + when "Space" + " " + when "RawInline" + js["c"][1] + when "RawBlock" + js["c"][1] + when "Para" + js["c"].map{|c| js2sane(c)}.join() + else + throw js["t"] + end + end + end +end diff --git a/bin/post-commit b/bin/post-commit new file mode 100755 index 0000000..6b72bd2 --- /dev/null +++ b/bin/post-commit @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +branch=$(git name-rev --name-only HEAD) +if [[ $branch == master ]]; then + + stash=false + if [[ -n "$(git status --porcelain)" ]]; then + stash=true + git add . + git stash + fi + + git checkout pre-generated + git merge master -m 'bogus' + rm -rf out + make --always-make -j12 + git add . + git commit --amend -m "make: $(git log -n1 master --pretty=format:%B)" + git checkout master + + if $stash; then + git stash pop + fi + +fi diff --git a/bin/util.rb b/bin/util.rb new file mode 100644 index 0000000..ce91007 --- /dev/null +++ b/bin/util.rb @@ -0,0 +1,111 @@ +# coding: utf-8 +load 'pandoc.rb' +require 'erb' +require 'date' + +$license_urls = { + "CC BY-SA-3.0" => 'https://creativecommons.org/licenses/by-sa/3.0/', + 'WTFPL-2' => "http://www.wtfpl.net/txt/copying/", +} +$person_uris = { + "Luke Shumaker" => "https://lukeshu.com/", + "Andrew Murrell" => "https://andrewdm.me/", +} +$person_emails = { + "Luke Shumaker" => "lukeshu@parabola.nu", + "Andrew Murrell" => "ImFromNASA@gmail.com", +} + +class Person + def initialize(name) + @name = name + end + def name + @name + end + def uri + $person_uris[@name] + end + def email + $person_emails[@name] + end + def html + if not email.nil? + return "#{name}" + elsif not uri.nil? + return "#{name}" + else + return @name + end + end + def atom + ret = "" + ret += "#{name}" unless name.nil? + ret += "#{uri}" unless uri.nil? + ret += "#{email}" unless email.nil? + end +end + +class License + def initialize(name) + @name = name + end + def name + @name + end + def url + $license_urls[@name] + end + def html + "#{name}" + end +end + +class Page + def initialize(infile) + @infile = infile + end + + def infile ; @infile ; end + def input ; @input ||= File.read(infile) ; end + def pandoc + if @pandoc.nil? + types = { + 'md' => 'markdown' + } + + ext = File.extname(infile).gsub(/^[.]/, '') + type = types[ext] || ext + @pandoc = Pandoc::load(type, input) + + if @pandoc['pandoc_format'] + @pandoc = Pandoc::load(@pandoc['pandoc_format'], input) + end + end + @pandoc + end + + def title ; @title ||= pandoc['title'] || input.split("\n",2).first ; end + def author ; @author ||= Person.new( pandoc['author'] || "Andrew Murrell") ; end + def license ; @license ||= License.new(pandoc['license'] || "CC BY-SA-3.0") ; end + def date ; @date ||= Date.parse(pandoc['date']) unless pandoc['date'].nil? ; end + def slug ; @slug ||= infile.sub(/\..*$/,'').sub(/^.*\//,'') ; end + def content ; @content ||= pandoc.to('html5 '+(pandoc['pandoc_flags']||'')) ; end + def head ; @head ||= pandoc['html_head_extra'] ; end + + def rights + @rights ||= "

The content of this page is Copyright © #{date.year unless date.nil?} #{author.html}.

\n" + + "

This page is licensed under the #{license.html} license.

" + end + + def breadcrumbs + @breadcrumbs ||= 'Andrew Murrell » ' + ( (slug == 'index') ? "blog" : "blog » #{slug}" ) + end +end + +def html_escape(html) + html + .gsub('&', '&') + .gsub('>', '>') + .gsub('<', '<') +end diff --git a/bin/write-atomic b/bin/write-atomic new file mode 100755 index 0000000..efb2551 --- /dev/null +++ b/bin/write-atomic @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +# Copyright (C) 2015-2016 Luke Shumaker +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +outfile=$1 +tmpfile="$(dirname "$outfile")/.tmp${outfile##*/}" + +cat > "$tmpfile" || { r=$?; rm -f "$tmpfile"; exit $r; } +mv -f "$tmpfile" "$outfile" diff --git a/bin/write-ifchanged b/bin/write-ifchanged new file mode 100755 index 0000000..185ceb0 --- /dev/null +++ b/bin/write-ifchanged @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +# Copyright (C) 2015 Luke Shumaker +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +outfile=$1 +tmpfile="$(dirname "$outfile")/.tmp${outfile##*/}" + +cat > "$tmpfile" || exit $? +if cmp -s "$tmpfile" "$outfile"; then + rm -f "$tmpfile" || : +else + mv -f "$tmpfile" "$outfile" +fi -- cgit v1.2.3-54-g00ecf