Builds the manual without Jekyll.
This commit is contained in:
parent
d24eddd604
commit
0d0a1048b8
|
@ -56,6 +56,7 @@ page_title: The Ardour Manual
|
||||||
<div id="content-main">
|
<div id="content-main">
|
||||||
<h1 class="title">{{ page.title }}</h1>
|
<h1 class="title">{{ page.title }}</h1>
|
||||||
{{ content }}
|
{{ content }}
|
||||||
|
{% prevnext %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
|
@ -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|
|
|
||||||
"<li><a href='#{child[:url]}'>#{child[:title]}</a></li>"
|
|
||||||
end.uniq
|
|
||||||
|
|
||||||
"<div id='subtopics'>
|
|
||||||
<h2>This chapter covers the following topics:</h2>
|
|
||||||
<ul>
|
|
||||||
#{entries.join}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# generates a big <dl> 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
|
|
||||||
<dt class="<%= css_classes %>">
|
|
||||||
<a href="<%= entry[:url] %>"><%= entry[:menu_title] %></a>
|
|
||||||
</dt>
|
|
||||||
<dd class="<%= css_classes %>">
|
|
||||||
<% if entry[:children].any? %>
|
|
||||||
<dl>
|
|
||||||
<%= entry[:children].join %>
|
|
||||||
</dl>
|
|
||||||
<% end %>
|
|
||||||
</dd>
|
|
||||||
HTML
|
|
||||||
|
|
||||||
erb.result(binding)
|
|
||||||
else
|
|
||||||
|
|
||||||
directory_filename = entry[:filename].sub(/\.[^\/\.]+$/,'')
|
|
||||||
|
|
||||||
unless entry[:has_dir]
|
|
||||||
|
|
||||||
erb = ::ERB.new <<-HTML
|
|
||||||
<dt class="<%= css_classes %>">
|
|
||||||
<a href="<%= entry[:url] %>"><%= entry[:menu_title] %></a>
|
|
||||||
</dt>
|
|
||||||
<dd class="<%= css_classes %>">
|
|
||||||
</dd>
|
|
||||||
HTML
|
|
||||||
|
|
||||||
erb.result(binding)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
"<dl>#{tree.join}</dl>
|
|
||||||
<script type='text/javascript'>
|
|
||||||
//<![CDATA[
|
|
||||||
offset = document.getElementsByClassName('active')[0].offsetTop;
|
|
||||||
height = document.getElementById('tree').clientHeight;
|
|
||||||
if (offset > (height * .7)) {
|
|
||||||
tree.scrollTop = offset - height * .3;
|
|
||||||
}
|
|
||||||
//]]>
|
|
||||||
</script>"
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
Liquid::Template.register_tag('tree', Manual::ManualTOCTag)
|
|
||||||
Liquid::Template.register_tag('children', Manual::ManualChildPageTag)
|
|
231
build.rb
Normal file
231
build.rb
Normal file
|
@ -0,0 +1,231 @@
|
||||||
|
require 'pathname'
|
||||||
|
require 'fileutils'
|
||||||
|
require 'yaml'
|
||||||
|
require 'liquid'
|
||||||
|
|
||||||
|
def split_frontmatter(txt)
|
||||||
|
re = /\A---[ \t\r]*\n(?<frontmatter>.*?)^---[ \t\r]*\n(?<content>.*)\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? ? "" : "<dl>\n" + children_html.join + "</dl>\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)) : ""
|
||||||
|
|
||||||
|
%{
|
||||||
|
<dt#{css}>
|
||||||
|
<a href='#{page.url}'>#{page.title}</a>
|
||||||
|
</dt>
|
||||||
|
<dd#{css}>
|
||||||
|
#{children_html}
|
||||||
|
</dd>
|
||||||
|
}
|
||||||
|
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| "<li><a href='#{p.url}'>#{p.title}</a></li>" }
|
||||||
|
|
||||||
|
"<div id='subtopics'>
|
||||||
|
<h2>This chapter covers the following topics:</h2>
|
||||||
|
<ul>
|
||||||
|
#{entries.join}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
"
|
||||||
|
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|
|
||||||
|
"<li><a title='#{p.title}' href='#{p.url}' class='#{cls}'>#{txt}</a></li>"
|
||||||
|
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 > ") : ""
|
||||||
|
|
||||||
|
"<ul class='pager'>#{prev_link}#{next_link}</ul>"
|
||||||
|
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
|
|
@ -1,8 +1,3 @@
|
||||||
---
|
|
||||||
layout: default
|
|
||||||
title: Welcome to Ardour!
|
|
||||||
---
|
|
||||||
|
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="refresh" content="0; url=/welcome-to-ardour/"/>
|
<meta http-equiv="refresh" content="0; url=/welcome-to-ardour/"/>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user