|
# 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(/<a/, '<a').gsub(/">/, '">').gsub(/<\/a>/, '</a>').gsub(/&/, '&')}</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) |