Skip to content

Instantly share code, notes, and snippets.

@thewhodidthis
Last active Jan 17, 2022
Embed
What would you like to do?
Draft SSG

Poor man's static site builder

Basic,

\
redcarpet content.md |          # 1. Parse markdown
mustache - data.yaml.mustache | # 2. Save as unescaped HTML in proxy template
mustache - layout.mustache |    # 3. Fill in page layout
tidy                            # 4. Fix indentation

With custom code highlighting,

cat settings.yaml data.yaml | ruby builder.rb - content.md layout.mustache
# https://bundler.io/guides/bundler_in_a_single_file_ruby_script.html
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'mustache'
gem 'rouge'
gem 'redcarpet'
end
require 'pathname'
require 'rouge/plugins/redcarpet'
# Override default output to remove all those classes and to highlight comments
class CustomFormatter < Rouge::Formatters::HTML
def stream(tokens, &block)
yield "<pre>\n"
tokens.each do |token, value|
yield span(token, value)
end
yield "</pre>"
end
def safe_span(tok, safe_val)
if tok == Rouge::Token::Tokens::Comment or tok == Rouge::Token::Tokens::Comment::Single
# Attempt to re-encode ampersand and anchor tag related chars
"<strong>#{safe_val.gsub(/&lt;a/, '<a').gsub(/"&gt;/, '">').gsub(/&lt;\/a&gt;/, '</a>').gsub(/&amp;/, '&')}</strong>"
else
safe_val
end
end
end
class CHIC < Redcarpet::Render::HTML
include Rouge::Plugins::Redcarpet
def rouge_formatter(lexer)
CustomFormatter.new
end
end
# Read in mustache and markdown content, safe to destructure
# because .md comes before .mustache when sorting
content, template = ARGV
.select { |f| ['.mustache', '.md'].include? File.extname f }
.map { |f| ARGV.delete f }
.compact()
.sort_by { |f| File.extname f }
.group_by { |f| File.extname f }
.map { |_, v| v.first }
.map { |f| File.read f }
# Lifted from mustache/bin
data = YAML.load_stream(ARGF.read).compact.reduce(&:merge)
# Attach `content` inline instead of sourcing from `data.yaml.mustache`
data[:content] = Redcarpet::Markdown.new(CHIC, fenced_code_blocks: true).render(content)
# Make available for redirecting
puts Mustache.new.render(template, data)

Coucou

Hola!

Please wait

alert('coucou');
title: Title
description: Description
title: Hello World!
description: Draft SSG
content: '{{{.}}}'
<!DOCTYPE html>
<html lang="en">
<head>
{{#base}}
<base href="{{base}}">
{{/base}}
<meta charset="utf-8">
{{#description}}
<meta name="description" content="{{description}}">
{{/description}}
<title>{{title}}</title>
</head>
<body>
<main>
{{{content}}}
</main>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment