6 def split_frontmatter(txt)
7 re = /\A---[ \t\r]*\n(?<frontmatter>.*?)^---[ \t\r]*\n(?<content>.*)\z/m
9 match ? [match['frontmatter'], match['content']] : nil
13 a.start_with?(b) && b.count('/') + 1 == a.count('/')
22 'pages_dir' => '_manual',
23 'layouts_dir' => '_layouts',
24 'static_dir' => 'source',
25 'output_dir' => '_site'
31 layouts_dir = Pathname(@config['layouts_dir'])
32 Pathname.glob(layouts_dir + Pathname('*.html')) do |path|
34 layout = Layout.new(self, path)
36 @layouts[path.basename('.html').to_s] = layout
45 pages_dir = Pathname.new(@config['pages_dir'])
46 pages_dir.find do |path|
47 if path.file? && path.extname == '.html'
48 page = Page.new(self, path)
55 def find_children(url)
56 @pages.select{ |p| child_url?(p.url, url) }.sort_by{ |p| p.path.basename }
60 @pages.each {|page| page.process}
64 # http://ruby-doc.org/stdlib-2.2.1/libdoc/fileutils/rdoc/index.html
68 Pathname(@config['pages_dir'])
72 Pathname(@config['output_dir'])
85 attr_reader :path, :out_path, :url, :sort_url
87 def initialize(site, path)
92 @out_path = @site.output_dir + canon + Pathname("index.html")
93 @url = '/' + canon + '/'
94 @sort_url = @path.to_s.sub(/\.html$/, '')
98 remove_numbers = lambda {|x| x.sub(/^[0-9]*[-_]/, '') }
99 path = @path.relative_path_from(@site.pages_dir)
100 a = path.each_filename.map(&remove_numbers)
101 a[-1] = a[-1].sub(/\.html$/, '')
106 # should we show p in the index on selfs page?
107 url.start_with?(p.url) || child_url?(url, p.url)
112 puts 'nil page context: ' + @path.to_s
114 @page_context['title'] || ""
119 split = split_frontmatter content
120 split || abort("Not a Jekyll-formatted file: #{@path}")
121 frontmatter, @content = split
122 @page_context = YAML.load(frontmatter)
123 @template = Liquid::Template.parse(@content)
127 @site.find_layout(@page_context['layout'] || 'default')
131 @site.find_children(@url)
135 registers = {page: self, site: @site}
136 context = {'page' => @page_context}
137 content = @template.render!(context, registers: registers)
138 find_layout.render(context.merge({'content' => content}), registers)
144 path.open('w') { |f| f.write(render) }
149 def render(context, registers)
150 context = context.dup
151 context['page'] = @page_context.merge(context['page'])
152 content = @template.render!(context, registers: registers)
153 if @page_context.has_key?('layout')
154 find_layout.render(context.merge({'content' => content}), registers)
161 class Tag_tree < Liquid::Tag
162 def join(children_html)
163 children_html.empty? ? "" : "<dl>\n" + children_html.join + "</dl>\n"
167 current = context.registers[:page]
168 site = context.registers[:site]
170 format_entry = lambda do |page|
171 children = page.children
173 css = (page == current) ? ' class="active"' : ""
174 children_html = current.related_to?(page) ? join(children.map(&format_entry)) : ""
178 <a href='#{page.url}'>#{page.title}</a>
186 join(site.find_children('/').map(&format_entry))
190 class Tag_children < Liquid::Tag
192 children = context.registers[:page].children
193 entries = children.map {|p| "<li><a href='#{p.url}'>#{p.title}</a></li>" }
195 "<div id='subtopics'>
196 <h2>This chapter covers the following topics:</h2>
205 class Tag_prevnext < Liquid::Tag
207 site = context.registers[:site]
208 current = context.registers[:page]
210 pages = site.pages.sort_by{ |p| p.sort_url }
212 ind = pages.index { |page| page == current }
215 lnk = lambda do |p, cls, txt|
216 "<li><a title='#{p.title}' href='#{p.url}' class='#{cls}'>#{txt}</a></li>"
218 prev_link = ind > 0 ? lnk.call(pages[ind-1], "previous", " < Previous ") : ""
219 next_link = ind < pages.length-1 ? lnk.call(pages[ind+1], "next", " Next > ") : ""
221 "<ul class='pager'>#{prev_link}#{next_link}</ul>"
225 Liquid::Template.register_tag('tree', Tag_tree)
226 Liquid::Template.register_tag('children', Tag_children)
227 Liquid::Template.register_tag('prevnext', Tag_prevnext)
229 if defined? Liquid::Template.error_mode
230 Liquid::Template.error_mode = :strict