#!/usr/bin/env ruby # encoding: utf-8 macro :section do max_parameters 1 if raw_attribute(:src) && Glyph.multiple_output_files? then required_attribute :title end @data[:name] = @name h = "" if attr(:title) then level = 1 @node.ascend do |n| break if n.respond_to?(:attribute) && n.attribute(:class) && n.attribute(:class).children.join.strip == "topic" #if n.is_a?(Glyph::MacroNode) && Glyph["system.structure.headers"].include?(n[:name]) then if n.is_a?(Glyph::MacroNode) && n[:name].in?(Glyph.titled_sections) then level+=1 end end ident = (attr(:id) || "h_#{@node[:document].headers.length+1}").to_sym # The bookmark is added when the section is first processed; therefore it will exist already when a topic layout is processed bmk = @node[:document].bookmark?(ident) bmk ||= header :title => attr(:title), :level => level, :id => ident, :toc => !attr(:notoc), :definition => @source_file, :file => (attr(:src) || @source_file) @node[:header] = bmk @data[:toc] = !attr(:notoc) @data[:title] = attr :title @data[:level] = level @data[:id] = bmk.code end if attr(:src) then # Create topic if Glyph.multiple_output_files? topic_id = (attr(:id) || "t_#{@node[:document].topics.length}").to_sym layout = attr(:layout) || Glyph["output.#{Glyph['document.output']}.layouts.topic"] || :topic layout_name = "layout/#{layout}".to_sym macro_error "Layout '#{layout}' not found" unless Glyph::MACROS[layout_name] result = interpret %{#{layout_name}[ @title[#{attr(:title)}] @id[#{topic_id}] @contents[include[@topic[true]#{attr(:src)}]] ]} bmk = @node[:document].bookmark? topic_id if bmk then # Fix file for topic bookmark @node[:document].bookmark?(topic_id).file = attr(:src) else bookmark :title => attr(:title), :id => topic_id, :file => attr(:src), :definition => @source_file end topic_src = attr(:src) topic_src += ".glyph" unless topic_src.match /\..+$/ @node[:document].topics << {:src => topic_src, :title => attr(:title), :id => topic_id, :contents => result} # Process section contents @data[:content] = value else v = raw_value @node.children.delete_if{|c| !c.is_a?(Glyph::AttributeNode)} body = interpret "include[#{attr(:src)}]#{v}" @data[:content] = body end else @data[:content] = value end render end macro :article do exact_parameters 1 head = raw_attr(:head) head ||= %{style[default.css]} pre_title = raw_attr(:"pre-title") post_title = raw_attr(:"post-title") pubdate = @node.attr(:pubdate) ? "pubdate[#{@node.attr(:pubdate).contents}]" : "pubdate[]" halftitlepage = raw_attr(:halftitlepage) halftitlepage ||= %{ #{pre_title} title[] subtitle[] author[] #{pubdate} #{post_title} } interpret %{document[ head[#{head}] body[ halftitlepage[ #{halftitlepage} ] #{@node.value} ] ]} end macro :book do no_parameters head = raw_attr(:head) head ||= %{style[default.css]} pre_title = raw_attr(:"pre-title") post_title = raw_attr(:"post-title") titlepage = raw_attr(:titlepage) pubdate = @node.attr(:pubdate) ? "pubdate[#{@node.attr(:pubdate).contents}]" : "pubdate[]" titlepage ||= %{ #{pre_title} title[] subtitle[] revision[] author[] #{pubdate} #{post_title} } frontmatter = raw_attr(:frontmatter) bodymatter = raw_attr(:bodymatter) backmatter = raw_attr(:backmatter) frontmatter = "frontmatter[\n#{frontmatter}\n]" if frontmatter bodymatter = "bodymatter[\n#{bodymatter}\n]" if bodymatter backmatter = "backmatter[\n#{backmatter}\n]" if backmatter interpret %{document[ head[#{head}] body[ titlepage[ #{titlepage} ] #{frontmatter} #{bodymatter} #{backmatter} ] ]} end macro :document do exact_parameters 1 @data[:content] = value render end macro :head do exact_parameters 1 @data[:author] = Glyph['document.author'].blank? ? "" : render(:meta, :name => "author", :content => Glyph['document.author']) @data[:copyright] = Glyph['document.author'].blank? ? "" : render(:meta, :name => "copyright", :content => Glyph['document.author']) @data[:content] = value render end macro :style do within :head exact_parameters 1 file = Glyph.lite? ? Pathname.new(value) : Glyph::PROJECT/"styles/#{value}" file = Pathname.new Glyph::HOME/'styles'/value unless file.exist? macro_error "Stylesheet '#{value}' not found" unless file.exist? @node[:document].style file @data[:file] = file render end macro :toc do if @node[:document].toc[:contents] then @node[:document].toc[:contents] else max_parameters 1 depth = param(0) toc = placeholder do |document| descend_section = lambda do |n1, added_headers| list = "" added_headers ||= [] n1.descend do |n2, level| if n2.is_a?(Glyph::MacroNode) && n2[:name].in?(Glyph.titled_sections) then if Glyph.multiple_output_files? then # Only consider topics/booklets when building TOC for web/web5 next if !n2.attribute(:src) && n2.child_macros.select{|child| child.attribute(:src)}.blank? end next if n2.find_parent{|node| Glyph['system.structure.special'].include? node[:name] } header_obj = n2[:header] next if depth && header_obj && (header_obj.level-1 > depth.to_i) || header_obj && !header_obj.toc? next if added_headers.include? header_obj added_headers << header_obj # Check if part of frontmatter, bodymatter or backmatter container = n2.find_parent do |node| node.is_a?(Glyph::MacroNode) && node[:name].in?([:frontmatter, :bodymatter, :appendix, :backmatter]) end[:name] rescue nil if header_obj then if (!Glyph.multiple_output_files? || (header_obj.definition != header_obj.file)) then link_header = render(:link, :title => header_obj.title, :target => header_obj.link(@source_file)) else link_header = header_obj.title end list << render(:toc_item, :classes => [container, n2[:name]], :title => link_header) end child_list = "" n2.children.each do |c| child_list << descend_section.call(c, added_headers) end list << render(:toc_sublist, :contents => child_list) unless child_list.blank? end end list end title ||= "Table of Contents" bmk = @node[:document].bookmark?(:toc) || bookmark(:id => :toc, :file => @source_file, :title => title) @data[:toc_id] = bmk.to_s @data[:title] = bmk.title @data[:document] = document @data[:descend_section] = descend_section render end @node[:document].toc[:contents] = toc.to_s toc end end # See: # http://microformats.org/wiki/book-brainstorming # http://en.wikipedia.org/wiki/Book_design (Glyph['system.structure.frontmatter'] + Glyph['system.structure.bodymatter'] + Glyph['system.structure.backmatter']). each {|s| macro_alias s => :section } macro_alias "ยง" => :section macro_alias :frontcover => :section macro_alias :titlepage => :section macro_alias :halftitlepage => :section macro_alias :frontmatter => :section macro_alias :bodymatter => :section macro_alias :backmatter => :section macro_alias :backcover => :section