Commit 06d1c811 authored by Rene Saarsoo's avatar Rene Saarsoo
Browse files

Add [] lookup method to examples/guides/videos.

For this create a base class GroupedAsset that deals with
building the map of names.  To make the base class work, all
classes now use @groups instead of @examples/@videos/@guides
so they can be treated the same in GroupedAsset class.

The base class also has #each_item method to more easily iterate
over items in all groups.

For examples we are now also creating the "name" field into all
of its items.
parent 0145bcc3
Loading
Loading
Loading
Loading
+13 −16
Original line number Diff line number Diff line
require 'jsduck/json_duck'
require 'jsduck/null_object'
require 'jsduck/grouped_asset'

module JsDuck

  # Reads in examples JSON file
  class Examples
  class Examples < GroupedAsset
    # Creates Examples object from filename.
    def self.create(filename, opts)
      if filename
        Examples.new(filename, opts)
      else
        NullObject.new(:to_array => [])
        NullObject.new(:to_array => [], :[] => nil)
      end
    end

    # Parses examples config file
    def initialize(filename, opts)
      @examples = JsonDuck.read(filename)
      @groups = JsonDuck.read(filename)
      @opts = opts
      prefix_urls
      fix_examples_data
      build_map_by_name("Two examples have the same name")
    end

    # Prefix all relative URL-s in examples list with path given in --examples-base-url
    def prefix_urls
      @examples.each do |group|
        group["items"].each do |ex|
    # Create names for each example when not present
    def fix_examples_data
      each_item do |ex|
        unless ex["url"] =~ /^https?:\/\//
          ex["url"] = @opts.examples_base_url + ex["url"]
          end
          ex["name"] = ex["url"] unless ex["name"]
        end
      end
    end
@@ -37,12 +39,7 @@ module JsDuck
      FileUtils.mkdir(dir) unless File.exists?(dir)
      # Write the JSON to output dir, so it's available in released
      # version of docs and people can use it with JSDuck by themselves.
      JsonDuck.write_json(dir+"/examples.json", @examples)
    end

    # Returns all examples as array
    def to_array
      @examples
      JsonDuck.write_json(dir+"/examples.json", @groups)
    end

  end
+41 −0
Original line number Diff line number Diff line
require 'jsduck/logger'

module JsDuck

  # Parent class for assets that consist of groups.
  # That is: guides, vides, examples.
  #
  # Subclasses must initialize @groups before calling any of the
  # methods in this class.
  class GroupedAsset
    # Should be called from constructor after @groups have been read in,
    # and after it's been ensured that all items in groupes have names.
    def build_map_by_name(warning_msg)
      @map_by_name = {}
      each_item do |item|
        if @map_by_name[item["name"]]
          Logger.instance.warn(nil, "#{warning_msg} '#{item['name']}'")
        end
        @map_by_name[item["name"]] = item
      end
    end

    # Accesses item by name
    def [](name)
      @map_by_name[name]
    end

    # Iterates over all items in all groups
    def each_item
      @groups.each do |group|
        group["items"].each {|item| yield item }
      end
    end

    # Returns all groups as array
    def to_array
      @groups
    end
  end

end
+9 −11
Original line number Diff line number Diff line
require 'jsduck/logger'
require 'jsduck/json_duck'
require 'jsduck/null_object'
require 'jsduck/logger'
require 'jsduck/grouped_asset'
require 'fileutils'

module JsDuck

  # Reads in guides and converts them to JsonP files
  class Guides
  class Guides < GroupedAsset
    # Creates Guides object from filename and formatter
    def self.create(filename, formatter)
      if filename
        Guides.new(filename, formatter)
      else
        NullObject.new(:to_array => [], :to_html => "")
        NullObject.new(:to_array => [], :to_html => "", :[] => nil)
      end
    end

    # Parses guides config file
    def initialize(filename, formatter)
      @path = File.dirname(filename)
      @guides = JsonDuck.read(filename)
      @groups = JsonDuck.read(filename)
      build_map_by_name("Two guides have the same name")
      @formatter = formatter
    end

    # Writes all guides to given dir in JsonP format
    def write(dir)
      FileUtils.mkdir(dir) unless File.exists?(dir)
      @guides.each {|group| group["items"].each {|g| write_guide(g, dir) } }
      each_item {|guide| write_guide(guide, dir) }
      # Write the JSON to output dir, so it's available in released
      # version of docs and people can use it with JSDuck by themselves.
      JsonDuck.write_json(dir+"/guides.json", @guides)
      JsonDuck.write_json(dir+"/guides.json", @groups)
    end

    def write_guide(guide, dir)
@@ -89,14 +92,9 @@ module JsDuck
      end
    end

    # Returns all guides as array
    def to_array
      @guides
    end

    # Returns HTML listing of guides
    def to_html
      html = @guides.map do |group|
      html = @groups.map do |group|
        [
          "<h3>#{group['title']}</h3>",
          "<ul>",
+9 −21
Original line number Diff line number Diff line
require 'jsduck/json_duck'
require 'jsduck/null_object'
require 'jsduck/logger'
require 'jsduck/grouped_asset'

module JsDuck

  # Reads in videos JSON file
  class Videos
  class Videos < GroupedAsset
    # Parses videos config file
    def self.create(filename)
      if filename
        Videos.new(filename)
      else
        NullObject.new(:to_array => [])
        NullObject.new(:to_array => [], :[] => nil)
      end
    end

    def initialize(filename)
      @videos = JsonDuck.read(filename)
      @groups = JsonDuck.read(filename)
      add_names_if_missing
      build_map_by_name("Two videos have the same name")
    end

    # Each video should have a name, which is used in URL to reference the video.
    # For backwards compatibility, when name is missing, we turn the "id" (that must exist)
    # into a name.  Additionally check that no two videos have the same name.
    # into a name.
    def add_names_if_missing
      uniq_names = {}
      @videos.each do |group|
        group["items"].each do |video|
      each_item do |video|
        video["name"] = video["id"] unless video["name"]

          if uniq_names[video["name"]]
            Logger.instance.warn(nil, "Two videos have the same name '#{video['name']}'")
          end
          uniq_names[video["name"]] = true
        end
      end
    end

@@ -42,12 +35,7 @@ module JsDuck
      FileUtils.mkdir(dir) unless File.exists?(dir)
      # Write the JSON to output dir, so it's available in released
      # version of docs and people can use it with JSDuck by themselves.
      JsonDuck.write_json(dir+"/videos.json", @videos)
    end

    # Returns all videos as array
    def to_array
      @videos
      JsonDuck.write_json(dir+"/videos.json", @groups)
    end

  end