Files
textmate/bin/gen_html
Brad Choate 6753f4e3d6 Evaluate embedded ruby in markdown files
This is when generating HTML for the release notes, manual, and, where we actually need this, list of contributions.

Long-term we should probably switch to template tags as we are effectively adding code to the (otherwise declarative) build graph, which means we don’t have any way to tell if the generated HTML is up-to-date or not (as that would require analyzing the embedded ruby code).
2012-11-12 14:34:22 +07:00

106 lines
2.8 KiB
Ruby
Executable File

#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby -wKU
# == Synopsis
#
# gen_html: generates HTML file from markdown and optional template(s)
#
# == Usage
#
# gen_html [OPTION] ... [FILE]
#
# --help:
# show help
#
# -t/--title «title»
# make «title» available to template (as `page_name`)
#
# -h/--header «file»
# prepend «file» as header (erb)
#
# -f/--footer «file»
# append «file» as footer (erb)
#
# FILE: The markdown document to read (defaults to stdin)
require 'getoptlong'
require 'rdoc/usage'
require 'erb'
def expand_tpl(str, binding)
ERB.new(str, 0, '%-<>').result(binding)
end
def expand_tpl_file(path, binding)
expand_tpl(File.read(path), binding)
end
def find_exe(cmd)
dir = ENV['PATH'].split(':').find { |dir| File.executable? File.join(dir, cmd) }
dir ? "#{dir}/#{cmd}" : nil
end
def wrap_key_equivalents(src)
src.gsub(/ `([^`]+⇥)` | \( ([⌃⌥⇧⌘↓↑←→]+) \) | ( [⎋⇥↩⌅⌫⌦] | [⌃⌥⇧⌘]+ ( (?=[ ]|-\w+) | F\d+ | . ) ) /x) do
if $1
"<kbd class='tabTrigger'>#$1</kbd>"
elsif $2
"(<kbd class='keyEquivalent'>#$2</kbd>)"
else
"<kbd class='keyEquivalent'>#$&</kbd>"
end
end
end
def wrap_authors(src)
src.gsub(/ \*\[ (.+?) \]\* /x) do
"<span class='credit'>#$1</span>"
end
end
def wrap_in_article(html)
html.gsub(/<h2\b.*>.*<\/h2>(?m:.*?)(?=\s*<h2|\z)/) do
"<article>\n#$&\n</article>\n"
end
end
opts = GetoptLong.new(
[ '--title', '-t', GetoptLong::REQUIRED_ARGUMENT ],
[ '--header', '-h', GetoptLong::REQUIRED_ARGUMENT ],
[ '--footer', '-f', GetoptLong::REQUIRED_ARGUMENT ],
[ '--help', GetoptLong::NO_ARGUMENT ]
)
title, header, footer = 'untitled', nil, nil
opts.each do |opt, arg|
case opt
when '--help'
RDoc::usage
when '--header'
header = arg
when '--footer'
footer = arg
end
end
MARKDOWN_COMPILERS = %w[ multimarkdown ]
filter = MARKDOWN_COMPILERS.find { |exe| find_exe exe }
abort "Unable to find a markdown compiler" if filter.nil?
filters = "|#{filter} --nosmart"
document = ARGF.read
document = wrap_authors(wrap_key_equivalents(document))
head, body = document.scan(/\A((?:^\w+:\s+.*$\n)*)\n?((?m:.*))\z/).flatten
tmp = head.scan(/^(\w+):\s+(.*)$/).collect { |pair| [pair[0].downcase, pair[1].strip] }
headers = Hash[*tmp.flatten]
page_title = headers['title'] || title
css_files = headers['css'].to_s.split(/,\s*/)
js_files = headers['js'].to_s.split(/,\s*/)
meta_data = Hash[*headers['meta'].to_s.scan(/(.*?)="(.*?)"(?:,\s*)?/).flatten]
STDOUT << expand_tpl_file(header, binding) unless header.nil?
STDOUT << open(filters, 'r+') { |io| io << body; io.close_write; wrap_in_article(expand_tpl(io.read, binding)) }
STDOUT << expand_tpl_file(footer, binding) unless footer.nil?