diff --git a/source/_layouts/bootstrap.html b/_layouts/bootstrap.html
similarity index 99%
rename from source/_layouts/bootstrap.html
rename to _layouts/bootstrap.html
index b491ae1..dec5312 100644
--- a/source/_layouts/bootstrap.html
+++ b/_layouts/bootstrap.html
@@ -56,6 +56,7 @@ page_title: The Ardour Manual
{{ page.title }}
{{ content }}
+ {% prevnext %}
diff --git a/source/_layouts/default.html b/_layouts/default.html
similarity index 100%
rename from source/_layouts/default.html
rename to _layouts/default.html
diff --git a/_plugins/manual.rb b/_plugins/manual.rb
deleted file mode 100644
index 2a5d905..0000000
--- a/_plugins/manual.rb
+++ /dev/null
@@ -1,262 +0,0 @@
-require 'erb'
-require 'fileutils'
-require 'tmpdir'
-require 'pp'
-
-module Manual
-
- DIRECTORY_ENTRIES = {}
-
- def self.traverse_data(entries, directory_sort = false, paths = [], key_paths = [], &block)
-
- entries.map do |entry|
-
- entry = entry.dup
-
- if entry[:type] == 'directory'
- entry[:children] = traverse_data(entry[:children], directory_sort, paths + [entry[:name]], key_paths + [entry[:key]], &block)
- end
- block_given? ? block.call(entry) : entry
- end
- end
-
- def self.traverse(path, directory_sort = false, paths = [], key_paths = [], &block)
-
- entries = Dir.glob(File.join(path,'*')).sort
-
- entries.sort_by! { |e| File.directory?(e) ? 1 : 0 } if directory_sort
-
- entries.map do |entry|
- is_dir = File.directory?(entry)
-
- data = extract_data(is_dir ? "#{entry}.html" : entry)
-
- short_title = data['menu_title'] || data['title']
-
- name = entry[/[^\/]+$/] # filename
- key = name.sub(/^[0-9]+(\-|_)/,'').sub(/\.[^\.]+$/,'') # slug
- my_paths = paths + [name]
- my_key_paths = key_paths + [key]
- url = '/' + my_key_paths.join('/') + '/'
-
- without_extension = entry.sub(/\.[^\/\/]+$/,'')
-
- h = {
- name: name,
- title: data['title'] || key,
- menu_title: short_title || key,
- key: key,
- filename: entry,
- type: is_dir ? 'directory' : 'file',
- url: url
- }
-
- if is_dir
- h.update \
- children: traverse(entry, directory_sort, my_paths, my_key_paths, &block)
- else
- h.update extension: File.extname(name), has_dir: File.directory?(without_extension)
- end
-
- if is_dir
- DIRECTORY_ENTRIES[url] = h
- end
-
- block_given? ? block.call(h) : h
- end.compact
- end
-
- def self.extract_data(filename)
- if File.exists?(filename) and !File.directory?(filename) and first3 = File.open(filename) { |fd| fd.read(3) } and first3 == '---'
- blah = filename.sub(/^_manual\//,'')
- page = Jekyll::Page.new(@site, '_manual', File.dirname(blah), File.basename(blah))
- page.data
- else
- {}
- end
- end
-
- class ManualPage < Jekyll::Page
- def initialize(*args)
- super
- end
- end
-
- class ManualGenerator < Jekyll::Generator
-
- safe true
-
- def generate(site)
- source = site.config['source']
- destination = site.config['destination']
-
- manual_dir = '_manual'
-
- # now we need to turn our raw input files into something for jekyll to process
- # everything is in a directory with it's name and all content is in index.html files
- # the tmpdir gets removed at the end of this block automatically
-
- Dir.mktmpdir do |tmpdir|
-
- Manual.traverse manual_dir, true do |entry|
- output_filename = File.join(tmpdir, entry[:url], "index#{entry[:extension]}")
-
- FileUtils.mkdir_p File.dirname(output_filename)
-
- next unless entry[:type] == 'file'
-
- File.open(output_filename, 'w+') do |f|
- f << File.read(entry[:filename])
- end
-
- relative_filename = File.join(entry[:url], "index#{entry[:extension]}")
-
- site.pages << Jekyll::Page.new(site, tmpdir, File.dirname(relative_filename), File.basename(relative_filename))
- end
-
- end
- end
-
- end
-
- class ManualChildPageTag < Liquid::Tag
- def render(context)
- current = context['page.url'].sub(/[^\/]+$/,'')
-
- if entry = DIRECTORY_ENTRIES[current]
-
- path = File.join(entry[:filename], '*')
-
- entries = entry[:children].map do |child|
- "#{child[:title]}"
- end.uniq
-
- "
-
This chapter covers the following topics:
-
-
- "
- end
- end
- end
-
- # generates a big list of the manual page stucture
-
- class ManualTOCTag < Liquid::Tag
-
- def process_hierarchy(items_a, items_b)
- current = true
- position = nil
- level = -1
-
- [items_a.length,items_b.length].max.times do |i|
- a = items_a[i]
- b = items_b[i]
-
- current = false if a != b
-
- # start incrementing this when we don't have either a or b
- level += 1 if !a || !b
-
- if a && b
- return [false] if a != b
- elsif a
- position = :parent
- elsif b
- position = :child
- end
- end
- position ? [current, position, level + 1] : [current]
- end
-
- def render(context)
-
- @source = '_manual' #context.registers[:site].source
-
- @@data_tree ||= Manual.traverse(@source)
-
- @site = context.registers[:site]
- current = context['page.url'].sub(/[^\/]+$/,'')
-
- current_a = current.split('/').reject(&:empty?)
-
- tree = Manual.traverse_data(@@data_tree) do |entry|
-
- url = entry[:url]
-
- url_a = url.split('/').reject(&:empty?)
-
- depth = url_a.length
- is_current, position, level = *process_hierarchy(current_a, url_a)
-
- # this massively speeds up build time by not including the whole menu tree for each page
- next if depth > 1 && current_a[0] != url_a[0]
-
- css_classes = []
- css_classes << 'active' if is_current
- css_classes << position.to_s if position
- css_classes << "#{position}-#{level}" if position && level
- css_classes << 'other' unless is_current || position || level
-
- css_classes << "level-#{depth}"
- css_classes = css_classes.join(' ')
-
- if entry[:type] == 'directory'
-
- erb = ::ERB.new <<-HTML
- -
- <%= entry[:menu_title] %>
-
- -
- <% if entry[:children].any? %>
-
- <%= entry[:children].join %>
-
- <% end %>
-
- HTML
-
- erb.result(binding)
- else
-
- directory_filename = entry[:filename].sub(/\.[^\/\.]+$/,'')
-
- unless entry[:has_dir]
-
- erb = ::ERB.new <<-HTML
- -
- <%= entry[:menu_title] %>
-
- -
-
- HTML
-
- erb.result(binding)
- end
- end
-
-
- end
-
- "#{tree.join}
- "
-
- end
-
-
- end
-
-end
-
-Liquid::Template.register_tag('tree', Manual::ManualTOCTag)
-Liquid::Template.register_tag('children', Manual::ManualChildPageTag)
diff --git a/build.rb b/build.rb
new file mode 100644
index 0000000..4932925
--- /dev/null
+++ b/build.rb
@@ -0,0 +1,231 @@
+require 'pathname'
+require 'fileutils'
+require 'yaml'
+require 'liquid'
+
+def split_frontmatter(txt)
+ re = /\A---[ \t\r]*\n(?.*?)^---[ \t\r]*\n(?.*)\z/m
+ match = re.match txt
+ match ? [match['frontmatter'], match['content']] : nil
+end
+
+def child_url?(a, b)
+ a.start_with?(b) && b.count('/') + 1 == a.count('/')
+end
+
+class Site
+ attr_reader :pages
+
+ def initialize()
+ @pages = []
+ @config = {
+ 'pages_dir' => '_manual',
+ 'layouts_dir' => '_layouts',
+ 'static_dir' => 'source',
+ 'output_dir' => '_site'
+ }
+ @layouts = {}
+ 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)
+ layout.read
+ @layouts[path.basename('.html').to_s] = layout
+ 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)
+ page.read
+ @pages << page
+ end
+ 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
+ end
+
+ def pages_dir()
+ Pathname(@config['pages_dir'])
+ end
+
+ def output_dir()
+ Pathname(@config['output_dir'])
+ end
+
+ def run()
+ #read_config()
+ read_layouts()
+ read_pages()
+ copy_static()
+ process_pages()
+ end
+end
+
+class Page
+ attr_reader :path, :out_path, :url, :sort_url
+
+ def initialize(site, path)
+ @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
+
+ 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('/')
+ end
+
+ def related_to?(p)
+ # should we show p in the index on selfs page?
+ url.start_with?(p.url) || child_url?(url, p.url)
+ end
+
+ def title()
+ if !@page_context
+ puts 'nil page context: ' + @path.to_s
+ end
+ @page_context['title'] || ""
+ end
+
+ def read()
+ content = @path.read
+ split = split_frontmatter content
+ split || abort("Not a Jekyll-formatted file: #{@path}")
+ frontmatter, @content = split
+ @page_context = YAML.load(frontmatter)
+ @template = Liquid::Template.parse(@content)
+ end
+
+ def find_layout()
+ @site.find_layout(@page_context['layout'] || 'default')
+ end
+
+ def children()
+ @site.find_children(@url)
+ end
+
+ def render()
+ registers = {page: self, site: @site}
+ context = {'page' => @page_context}
+ content = @template.render!(context, registers: registers)
+ find_layout.render(context.merge({'content' => content}), registers)
+ end
+
+ def process()
+ path = out_path
+ path.dirname.mkpath
+ path.write(render)
+ end
+end
+
+class Layout < Page
+ def render(context, registers)
+ context = context.dup
+ context['page'] = @page_context.merge(context['page'])
+ content = @template.render!(context, registers: registers)
+ if @page_context.has_key?('layout')
+ find_layout.render(context.merge({'content' => content}), registers)
+ else
+ content
+ end
+ end
+end
+
+class Tag_tree < Liquid::Tag
+ def join(children_html)
+ children_html.empty? ? "" : "\n" + children_html.join + "
\n"
+ end
+
+ def render(context)
+ current = context.registers[:page]
+ site = context.registers[:site]
+
+ format_entry = lambda do |page|
+ children = page.children
+
+ css = (page == current) ? ' class="active"' : ""
+ children_html = current.related_to?(page) ? join(children.map(&format_entry)) : ""
+
+ %{
+ -
+ #{page.title}
+
+ -
+ #{children_html}
+
+ }
+ end
+
+ join(site.find_children('/').map(&format_entry))
+ end
+end
+
+class Tag_children < Liquid::Tag
+ def render(context)
+ children = context.registers[:page].children
+ entries = children.map {|p| "- #{p.title}
" }
+
+ "
+
This chapter covers the following topics:
+
+
+ "
+ end
+end
+
+class Tag_prevnext < Liquid::Tag
+ def render(context)
+ site = context.registers[:site]
+ current = context.registers[:page]
+
+ pages = site.pages.sort_by{ |p| p.sort_url }
+
+ ind = pages.index { |page| page == current }
+ return '' if !ind
+
+ lnk = 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 > ") : ""
+
+ ""
+ end
+end
+
+Liquid::Template.register_tag('tree', Tag_tree)
+Liquid::Template.register_tag('children', Tag_children)
+Liquid::Template.register_tag('prevnext', Tag_prevnext)
+
+Liquid::Template.error_mode = :strict
+
+Site.new.run
diff --git a/source/index.html b/source/index.html
index 07dd8c4..2c68f8b 100644
--- a/source/index.html
+++ b/source/index.html
@@ -1,8 +1,3 @@
----
-layout: default
-title: Welcome to Ardour!
----
-