class Playgroundbook::Renderer

A renderer for playground books.

Attributes

chapter_collator[RW]
contents_manifest_generator[RW]
glossary_generator[RW]
page_parser[RW]
ui[RW]
yaml_file_name[RW]

Public Class Methods

new(yaml_file_name, contents_manifest_generator = ContentsManifestGenerator.new, page_parser = PageParser.new, chapter_collator = ChapterCollator.new, glossary_generator = GlossaryGenerator.new, ui = Cork::Board.new) click to toggle source
# File lib/renderer/playgroundbook_renderer.rb, line 24
def initialize(yaml_file_name,
               contents_manifest_generator = ContentsManifestGenerator.new,
               page_parser = PageParser.new,
               chapter_collator = ChapterCollator.new,
               glossary_generator = GlossaryGenerator.new,
               ui = Cork::Board.new)
  @yaml_file_name = yaml_file_name
  @contents_manifest_generator = contents_manifest_generator
  @page_parser = page_parser
  @chapter_collator = chapter_collator
  @glossary_generator = glossary_generator
  @ui = ui
end

Public Instance Methods

render() click to toggle source
# File lib/renderer/playgroundbook_renderer.rb, line 38
def render
  ui.puts "Rendering #{yaml_file_name.green}..."

  book = yaml_contents
  book_dir_name = "#{book['name']}.playgroundbook"
  parsed_chapters = []
  # TODO: Validate YAML contents?
  begin
    parsed_chapters = book["chapters"].map do |chapter|
      source_names = Dir["#{chapter['name']}.playground/Sources/*.swift"]
      resource_names = Dir["#{chapter['name']}.playground/Resources/*"]
      single_page_file = "#{chapter['name']}.playground/Contents.swift"
      if File.exist?(single_page_file)
        c = File.read(single_page_file)
        page_parser.parse_chapter_pages(c, source_names, resource_names)
      elsif !Dir.glob("#{chapter['name']}.playground/Pages/*.xcplaygroundpage").empty?
        page_names = Dir.glob("#{chapter['name']}.playground/Pages/*.xcplaygroundpage").map do |name|
          # Transforms 'Chapter One.playground/Pages/Untitled Page.xcplaygroundpage' into 'Untitled Page'
          name.split('/').last.split('.').first
        end
        pages_data = page_names.map do |p|
          {
            name: p,
            contents: File.read("#{chapter['name']}.playground/Pages/#{p}.xcplaygroundpage/Contents.swift"),
            sources: Dir["#{chapter['name']}.playground/Pages/#{p}.xcplaygroundpage/Sources/*.swift"],
            resources: Dir["#{chapter['name']}.playground/Pages/#{p}.xcplaygroundpage/Resources/*"]
          }
        end
        page_parser.parse_chapter_xcplaygroundpages(pages_data, source_names, resource_names)
      else
        raise "Missing valid playground for #{chapter['name']}."
      end
    end
  rescue => e
    ui.puts "Failed to open and parse playground chapter."
    raise e
  end

  book["chapters"].map do |chapter|
    Dir.glob("Packages/**/Sources/*.swift").each do |file|
       playground_sources_path = "#{chapter['name']}.playground/Sources"
       Dir.mkdir(playground_sources_path) unless Dir.exist?(playground_sources_path)
       FileUtils.cp(file, playground_sources_path)
     end
  end
  Dir.mkdir(book_dir_name) unless Dir.exist?(book_dir_name)
  Dir.chdir(book_dir_name) do
    Dir.mkdir(ContentsDirectoryName) unless Dir.exist?(ContentsDirectoryName)
    Dir.chdir(ContentsDirectoryName) do
      Dir.mkdir(ResourcesDirectoryName) unless Dir.exist?(ResourcesDirectoryName) # Always create a Resources dir, even if empty.
      Dir.mkdir(SourcesDirectoryName) unless Dir.exist?(SourcesDirectoryName)
      Dir.glob("../../Packages/**/Sources/*.swift").each do |file|
        FileUtils.cp(file, SourcesDirectoryName)
      end
      resources_dir = book["resources"]
      unless resources_dir.nil? || resources_dir.empty?
        @ui.puts "Copying resource directory (#{resources_dir.green}) contents."
        Dir.glob("../../#{resources_dir}/*").each do |file|
          FileUtils.cp(file, ResourcesDirectoryName)
        end
      end
      @contents_manifest_generator.generate(book)

      Dir.mkdir(ChaptersDirName) unless Dir.exist?(ChaptersDirName)
      Dir.chdir(ChaptersDirName) do
        # Chapter file name becomes chapter name in playground book.
        book["chapters"].each_with_index do |chapter_file_name, index|
          parsed_chapter = parsed_chapters[index]
          @chapter_collator.collate(chapter_file_name, parsed_chapter, book["imports"] || ["UIKit"])
        end
      end
    end

    unless book["glossary"].nil?
      @ui.puts "Generating glossary."
      @glossary_generator.generate(
        parsed_chapters,
        book["chapters"].map { |c| c["name"] },
        book["glossary"])
    end
  end
end
yaml_contents() click to toggle source
# File lib/renderer/playgroundbook_renderer.rb, line 121
def yaml_contents
  YAML.load(File.open(@yaml_file_name))
end