class ApiBlueprint::Compile::Compile

Attributes

partials[R]
source[R]
target[R]

Public Class Methods

new(options) click to toggle source
# File lib/api_blueprint/compile/compile.rb, line 4
def initialize(options)
  @source = options[:source]
  @target = options[:target]
  @logger = options[:logger]

  @partials = []
end

Public Instance Methods

compile() click to toggle source
# File lib/api_blueprint/compile/compile.rb, line 12
def compile
  layout = load_layout
  insert_content(layout)
  insert_stylesheets(layout)

  layout_html = layout.to_html
  insert_javascripts(layout_html)

  layout_doc = load_document(layout_html)
  insert_title(layout_doc)
  insert_host(layout_doc)
  insert_copyright(layout_doc)

  write_html(layout_doc.to_html)
end

Private Instance Methods

insert_content(layout) click to toggle source
# File lib/api_blueprint/compile/compile.rb, line 48
def insert_content(layout)
  container = layout.at_css("#blueprint-document")

  if container
    content = render_markdown(@source)
    content = prepend_toc(content)

    container.add_child(content)
  end

  log " - compiled #{(container/'h1').length} chapter(s)"
end
insert_host(doc) click to toggle source
# File lib/api_blueprint/compile/compile.rb, line 104
def insert_host(doc)
  host_node = doc.at('p:contains("Host: ")')

  if host_node
    @host_text = host_node.text.strip.sub("Host: ", '')

    host_node['id'] = 'host'
    host_node.content = @host_text
  end
end
insert_javascripts(layout_html) click to toggle source
# File lib/api_blueprint/compile/compile.rb, line 75
def insert_javascripts(layout_html)
  return unless layout_html.include?('<script id="blueprint-script"></script>');

  text = ApiBlueprint::Compile::Storage.javascripts.collect do |file|
    Uglifier.compile(File.read(file))
  end.join("\n\n")

  layout_html.sub!('<script id="blueprint-script"></script>',
    '<script id="blueprint-script">' + text + '</script>')

  log " - compiled #{ApiBlueprint::Compile::Storage.stylesheets.count} javascript(s)"
end
insert_stylesheets(layout) click to toggle source
# File lib/api_blueprint/compile/compile.rb, line 61
def insert_stylesheets(layout)
  style = layout.at_css("#blueprint-style")

  if style
    text = ApiBlueprint::Compile::Storage.stylesheets.collect do |file|
      Sass::Engine.new(File.read(file), :syntax => :scss, :style => :compressed).render
    end.join("\n\n")

    style.add_child(text)

    log " - compiled #{ApiBlueprint::Compile::Storage.stylesheets.count} stylesheet(s)"
  end
end
insert_title(doc) click to toggle source
# File lib/api_blueprint/compile/compile.rb, line 88
def insert_title(doc)
  title_node = doc.at('p:contains("Title: ")')

  if title_node
    @title_text = title_node.text.strip.sub("Title: ", '')
    title_tag   = doc.at('title')

    title_node['id'] = 'title'
    title_node.content = @title_text

    if title_tag
      title_tag.content = @title_text
    end
  end
end
load_document(html) click to toggle source
# File lib/api_blueprint/compile/compile.rb, line 36
def load_document(html)
  Nokogiri::HTML(html)
end
load_layout() click to toggle source
# File lib/api_blueprint/compile/compile.rb, line 30
def load_layout
  log "Rendering '#{@source}' within the blueprint layout..."

  Nokogiri::HTML(File.read(ApiBlueprint::Compile::Storage.index_html))
end
log(message) click to toggle source
# File lib/api_blueprint/compile/compile.rb, line 215
def log(message)
  if @logger.to_s == 'stdout'
    puts message
  end
end
next_all(element, options = {}) click to toggle source
# File lib/api_blueprint/compile/compile.rb, line 192
def next_all(element, options = {})
  doc = element.document

  selector = options[:where]
  rejector = options[:until]
  results  = Nokogiri::XML::NodeSet.new(doc)
  element  = element.next_element

  while element
    set = Nokogiri::XML::NodeSet.new(doc, [element])

    if rejector && (set/rejector).any?
      break
    elsif ! selector || (set/selector).any?
      results << element
    end

    element = element.next_element
  end

  return results
end
prepend_toc(doc) click to toggle source
# File lib/api_blueprint/compile/compile.rb, line 152
def prepend_toc(doc)
  doc = Nokogiri::HTML(doc)
  headers = []

  (doc/"h1").each_with_index do |header, header_index|
    subheaders = []
    header['id'] = header.text.sub('Resource: ', '').parameterize
    headers << { :title => header.text.sub('Resource: ', ''), :id => header['id'], :subheaders => subheaders }

    next_all(header, :where => "h2", :until => 'h1').each_with_index do |action_header, action_index|
      action_header['id'] = header['id'] + "-" + action_header.text.sub('Action: ', '').parameterize
      subheaders << { :title => action_header.text.sub('Action: ', ''), :id => action_header['id'] }
    end
  end

  toc = "<h1>Table Of Contents</h1>"
  toc += "<ul>"

  headers.collect do |header|
    toc += "<li>"
    toc += "<a href='##{header[:id]}'>#{header[:title]}</a>"

    if header[:subheaders].any?
      toc += "<ul>"
      header[:subheaders].each do |subheader|
        toc += "<li><a href='##{subheader[:id]}'>#{subheader[:title]}</a></li>"
      end
      toc += "</ul>"
    end

    toc += '</li>'
  end

  toc += "</ul>"

  doc.at('h1').before(toc)

  doc.to_html
end
render_markdown(input_file) click to toggle source
# File lib/api_blueprint/compile/compile.rb, line 132
def render_markdown(input_file)
  markdown  = Redcarpet::Markdown.new(Redcarpet::Render::HTML, :tables => true, :no_intra_emphasis => true)
  content   = markdown.render(File.read(input_file))
  doc       = Nokogiri::HTML(content)
  requires  = (doc/'a:contains("require:")')

  requires.each do |require_link|
    file = require_link['href'].split(':').last
    file = input_file.split('/')[0..-2].join('/') + '/' + file + '.md'
    file = render_markdown(file)

    require_link.after(file)
    require_link.remove
  end

  partials << input_file unless partials.include?(input_file)

  doc.to_html
end
write_html(layout_html) click to toggle source
# File lib/api_blueprint/compile/compile.rb, line 40
def write_html(layout_html)
  return unless @target

  File.write(@target, layout_html)

  log "Wrote #{@title_text || "document"} into '#{@target}'"
end