X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=build.rb;h=82693f10a11f6cccca13e7d51821a288f56c9a36;hb=89e6e9f006efc294c790465acbdcc60355408222;hp=8246d8e88827aa0f8a4c7992bc363e90632364f7;hpb=ae0d367775ab5c30d137f89cb62902d1dccecdf2;p=ardour-manual diff --git a/build.rb b/build.rb old mode 100644 new mode 100755 index 8246d8e..82693f1 --- a/build.rb +++ b/build.rb @@ -1,34 +1,46 @@ +#!/usr/bin/env ruby + require 'pathname' -require 'fileutils' require 'yaml' -require 'liquid' +require 'optparse' -def split_frontmatter(txt) - re = /\A---[ \t\r]*\n(?.*?)^---[ \t\r]*\n(?.*)\z/m - match = re.match txt - match ? [match['frontmatter'], match['content']] : nil +begin require 'liquid' +rescue LoadError + puts "Please install the 'liquid' Ruby gem (available in Debian/Ubuntu as 'ruby-liquid')" + exit 1 end +CONFIG = { + pages_dir: '_manual', + layouts_dir: '_layouts', + static_dir: 'source', + output_dir: '_site' +} + def child_url?(a, b) a.start_with?(b) && b.count('/') + 1 == a.count('/') end class Site - attr_reader :pages + attr_reader :pages, :layouts def initialize() @pages = [] - @config = { - 'pages_dir' => '_manual', - 'layouts_dir' => '_layouts', - 'static_dir' => 'source', - 'output_dir' => '_site' - } @layouts = {} end + def build() + print "Building... " + + read_layouts() + read_pages() + copy_static() + process_pages() + + puts "done." + end + def read_layouts() - layouts_dir = Pathname(@config['layouts_dir']) Pathname.glob(layouts_dir + Pathname('*.html')) do |path| next if !path.file? layout = Layout.new(self, path) @@ -37,12 +49,7 @@ class Site end end - def find_layout(name) - @layouts[name] - end - def read_pages() - pages_dir = Pathname.new(@config['pages_dir']) pages_dir.find do |path| if path.file? && path.extname == '.html' page = Page.new(self, path) @@ -52,33 +59,27 @@ class Site end end - def find_children(url) - @pages.select{ |p| child_url?(p.url, url) }.sort_by{ |p| p.path.basename } - end - def process_pages() @pages.each {|page| page.process} end def copy_static() - # http://ruby-doc.org/stdlib-2.2.1/libdoc/fileutils/rdoc/index.html + unless system("rsync -a --delete --exclude='*~' #{static_dir}/. #{output_dir}") + puts "Couldn't copy static files, is rsync installed?" + end end - def pages_dir() - Pathname(@config['pages_dir']) + def find_children(url) + sorted_pages.select { |p| child_url?(p.url, url) } end - def output_dir() - Pathname(@config['output_dir']) - end + def toplevel() @toplevel_memo ||= find_children('/') end + def sorted_pages() @sorted_pages_memo ||= @pages.sort_by{ |p| p.sort_url } end - def run() - #read_config() - read_layouts() - read_pages() - copy_static() - process_pages() - end + def pages_dir() @pages_dir_memo ||= Pathname(CONFIG[:pages_dir]) end + def layouts_dir() @layouts_dir_memo ||= Pathname(CONFIG[:layouts_dir]) end + def static_dir() @static_dir_memo ||= Pathname(CONFIG[:static_dir]) end + def output_dir() @output_dir_memo ||= Pathname(CONFIG[:output_dir]) end end class Page @@ -88,18 +89,16 @@ class Page @site = site @path = path - canon = canonical - @out_path = @site.output_dir + canon + Pathname("index.html") - @url = '/' + canon + '/' - @sort_url = @path.to_s.sub(/\.html$/, '') - end + relative_path = @path.relative_path_from(@site.pages_dir); + a = relative_path.each_filename.map do |x| + x.sub(/^[0-9]*[-_]/, '') + end + a[-1].sub!(/\.html$/, '') + s = a.join('/') - def canonical() - remove_numbers = lambda {|x| x.sub(/^[0-9]*[-_]/, '') } - path = @path.relative_path_from(@site.pages_dir) - a = path.each_filename.map(&remove_numbers) - a[-1] = a[-1].sub(/\.html$/, '') - a.join('/') + @out_path = @site.output_dir + Pathname(s) + Pathname("index.html") + @url = "/#{s}/" + @sort_url = @path.to_s.sub(/\.html$/, '') end def related_to?(p) @@ -108,27 +107,32 @@ class Page end def title() - if !@page_context - puts 'nil page context: ' + @path.to_s - end @page_context['title'] || "" end + def menu_title() + @page_context['menu_title'] || title + end + def read() content = @path.read - split = split_frontmatter content - split || abort("Not a Jekyll-formatted file: #{@path}") - frontmatter, @content = split + frontmatter, @content = split_frontmatter(content) || abort("File not well-formatted: #{@path}") @page_context = YAML.load(frontmatter) @template = Liquid::Template.parse(@content) end + + def split_frontmatter(txt) + @split_regex ||= /\A---[ \t\r]*\n(?.*?)^---[ \t\r]*\n(?.*)\z/m + match = @split_regex.match txt + match ? [match['frontmatter'], match['content']] : nil + end def find_layout() - @site.find_layout(@page_context['layout'] || 'default') + @site.layouts[@page_context['layout'] || 'default'] end def children() - @site.find_children(@url) + @children ||= @site.find_children(@url) end def render() @@ -175,7 +179,7 @@ class Tag_tree < Liquid::Tag %{ - #{page.title} + #{page.menu_title} #{children_html} @@ -183,7 +187,7 @@ class Tag_tree < Liquid::Tag } end - join(site.find_children('/').map(&format_entry)) + join(site.toplevel.map(&format_entry)) end end @@ -204,30 +208,78 @@ end class Tag_prevnext < Liquid::Tag def render(context) - site = context.registers[:site] current = context.registers[:page] + pages = context.registers[:site].sorted_pages - pages = site.pages.sort_by{ |p| p.sort_url } + index = pages.index { |page| page == current } + return '' if !index - ind = pages.index { |page| page == current } - return '' if !ind - - lnk = lambda do |p, cls, txt| + link = lambda do |p, cls, txt| "
  • #{txt}
  • " end - prev_link = ind > 0 ? lnk.call(pages[ind-1], "previous", " < Previous ") : "" - next_link = ind < pages.length-1 ? lnk.call(pages[ind+1], "next", " Next > ") : "" + prev_link = index > 0 ? link.call(pages[index-1], "previous", " < Previous ") : "" + next_link = index < pages.length-1 ? link.call(pages[index+1], "next", " Next > ") : "" "
      #{prev_link}#{next_link}
    " end end -Liquid::Template.register_tag('tree', Tag_tree) -Liquid::Template.register_tag('children', Tag_children) -Liquid::Template.register_tag('prevnext', Tag_prevnext) +class Server + def start_watcher() + begin require 'listen' + rescue LoadError + puts "To use the --watch function, please install the 'listen' Ruby gem" + puts "(available in Debian/Ubuntu as 'ruby-listen')" + return nil + end + + listener = Listen.to(CONFIG[:pages_dir], wait_for_delay: 1.0, only: /.html$/) do |modified, added, removed| + Site.new.build + end + listener.start + listener + end + + def run(options) + require 'webrick' + listener = options[:watch] && start_watcher + port = options[:port] || 8000 + + puts "Serving at http://localhost:#{port}/ ..." + server = WEBrick::HTTPServer.new :Port => port, :DocumentRoot => CONFIG[:output_dir] + trap 'INT' do + server.shutdown + end + server.start + listener.stop if listener + end +end + +def main + Liquid::Template.register_tag('tree', Tag_tree) + Liquid::Template.register_tag('children', Tag_children) + Liquid::Template.register_tag('prevnext', Tag_prevnext) -if defined? Liquid::Template.error_mode - Liquid::Template.error_mode = :strict + if defined? Liquid::Template.error_mode + Liquid::Template.error_mode = :strict + end + + options = {} + OptionParser.new do |opts| + opts.banner = %{Usage: build.rb [options] + +Use 'build.rb' to build the manual. Use 'build.rb serve' to also +start a web server; setting any web server options implies "serve". +} + opts.on("-w", "--watch", "Watch for changes") { options[:watch] = true } + opts.on("-p", "--port N", Integer, "Specify port for web server") { |p| options[:port] = p } + end.parse! + + Site.new.build + + if options[:watch] || options[:port] || (ARGV.length > 0 && "serve".start_with?(ARGV[0])) + Server.new.run(options) + end end -Site.new.run +main