Class: JsDuck::Guides

Inherits:
GroupedAsset show all
Defined in:
lib/jsduck/guides.rb

Overview

Reads in guides and converts them to JsonP files

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from GroupedAsset

#[], #build_map_by_name, #each_item, #map_items

Constructor Details

#initialize(filename, formatter, opts) ⇒ Guides

Parses guides config file



26
27
28
29
30
31
32
33
# File 'lib/jsduck/guides.rb', line 26

def initialize(filename, formatter, opts)
  @path = File.dirname(filename)
  @groups = Util::Json.read(filename)
  @formatter = formatter
  @opts = opts
  build_map_by_name
  load_all_guides
end

Class Method Details

.create(filename, formatter, opts) ⇒ Object

Creates Guides object from filename and formatter



17
18
19
20
21
22
23
# File 'lib/jsduck/guides.rb', line 17

def self.create(filename, formatter, opts)
  if filename
    Guides.new(filename, formatter, opts)
  else
    Util::NullObject.new(:to_array => [], :to_html => "", :[] => nil)
  end
end

Instance Method Details

#fix_icon(dir) ⇒ Object

Ensures the guide dir contains icon.png. When there isn’t looks for icon-lg.png and renames it to icon.png. When neither exists, copies over default icon.



145
146
147
148
149
150
151
152
153
# File 'lib/jsduck/guides.rb', line 145

def fix_icon(dir)
  if File.exists?(dir+"/icon.png")
    # All ok
  elsif File.exists?(dir+"/icon-lg.png")
    FileUtils.mv(dir+"/icon-lg.png", dir+"/icon.png")
  else
    FileUtils.cp(@opts.template+"/resources/images/default-guide.png", dir+"/icon.png")
  end
end

#flatten_subgroups(items) ⇒ Object



173
174
175
176
177
178
179
# File 'lib/jsduck/guides.rb', line 173

def flatten_subgroups(items)
  result = []
  each_item(items) do |item|
    result << item
  end
  result
end

#format_guide(guide) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/jsduck/guides.rb', line 77

def format_guide(guide)
  @formatter.doc_context = {:filename => guide[:filename], :linenr => 0}
  @formatter.images = Img::Dir.new(guide[:dir], "guides/#{guide["name"]}")
  html = @formatter.format(Util::IO.read(guide[:filename]))
  html = GuideToc.new(html, guide['name'], @opts.guides_toc_level).inject!
  html = GuideAnchors.transform(html, guide['name'])

  # Report unused images (but ignore the icon files)
  @formatter.images.get("icon.png")
  @formatter.images.get("icon-lg.png")
  @formatter.images.report_unused

  return html
end

#icon_url(guide) ⇒ Object

Extracts guide icon URL from guide hash



182
183
184
# File 'lib/jsduck/guides.rb', line 182

def icon_url(guide)
  "guides/" + guide["name"] + "/icon.png"
end

#js_ident?(str) ⇒ Boolean

True when string is valid JavaScript identifier

Returns:

  • (Boolean)


138
139
140
# File 'lib/jsduck/guides.rb', line 138

def js_ident?(str)
  /\A[$\w]+\z/ =~ str
end

#load_all_guidesObject



41
42
43
44
45
46
47
48
# File 'lib/jsduck/guides.rb', line 41

def load_all_guides
  each_item do |guide|
    guide["url"] = resolve_url(guide)
    guide[:dir] = resolve_dir(guide)
    guide[:filename] = resolve_filename(guide)
    guide[:html] = load_guide(guide)
  end
end

#load_guide(guide) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/jsduck/guides.rb', line 57

def load_guide(guide)
  unless File.exists?(guide[:dir])
    return Logger.warn(:guide, "Guide not found", {:filename => guide[:dir]})
  end
  unless File.exists?(guide[:filename])
    return Logger.warn(:guide, "Guide not found", {:filename => guide[:filename]})
  end
  unless js_ident?(guide["name"])
    # Guide name is also used as JSONP callback method name.
    return Logger.warn(:guide, "Guide name is not valid JS identifier: #{guide["name"]}", {:filename => guide[:filename]})
  end

  begin
    return format_guide(guide)
  rescue
    Logger.fatal_backtrace("Error while reading/formatting guide #{guide[:filename]}", $!)
    exit(1)
  end
end

#resolve_dir(guide) ⇒ Object

Detects guide directory. The URL either points to a file or directory.



119
120
121
122
123
124
125
# File 'lib/jsduck/guides.rb', line 119

def resolve_dir(guide)
  if File.file?(guide["url"])
    File.expand_path("..", guide["url"])
  else
    guide["url"]
  end
end

#resolve_filename(guide) ⇒ Object

Detects guide filename. Either use URL pointing to a file or look up README.md from directory.



129
130
131
132
133
134
135
# File 'lib/jsduck/guides.rb', line 129

def resolve_filename(guide)
  if File.file?(guide["url"])
    guide["url"]
  else
    guide[:dir] + "/README.md"
  end
end

#resolve_url(guide) ⇒ Object

Turns guide URL into full path. If no URL given at all, creates it from guide name.



109
110
111
112
113
114
115
# File 'lib/jsduck/guides.rb', line 109

def resolve_url(guide)
  if guide["url"]
    File.expand_path(guide["url"], @path)
  else
    @path + "/guides/" + guide["name"]
  end
end

#to_arrayObject

Modified to_array that excludes the :html from guide nodes



51
52
53
54
55
# File 'lib/jsduck/guides.rb', line 51

def to_array
  map_items do |item|
    Hash[item.select {|k, v| k != :html }]
  end
end

#to_html(style = "") ⇒ Object

Returns HTML listing of guides



156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/jsduck/guides.rb', line 156

def to_html(style="")
  html = @groups.map do |group|
    [
      "<h3>#{group['title']}</h3>",
      "<ul>",
      flatten_subgroups(group["items"]).map {|g| "<li><a href='#!/guide/#{g['name']}'>#{g['title']}</a></li>" },
      "</ul>",
    ]
  end.flatten.join("\n")

  return <<-EOHTML
    <div id='guides-content' style='#{style}'>
        #{html}
    </div>
  EOHTML
end

#write(dir) ⇒ Object

Writes all guides to given dir in JsonP format



36
37
38
39
# File 'lib/jsduck/guides.rb', line 36

def write(dir)
  FileUtils.mkdir(dir) unless File.exists?(dir)
  each_item {|guide| write_guide(guide, dir) }
end

#write_guide(guide, dir) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/jsduck/guides.rb', line 92

def write_guide(guide, dir)
  return unless guide[:html]

  out_dir = dir + "/" + guide["name"]

  Logger.log("Writing guide", out_dir)
  # Copy the whole guide dir over
  FileUtils.cp_r(guide[:dir], out_dir)

  # Ensure the guide has an icon
  fix_icon(out_dir)

  Util::Json.write_jsonp(out_dir+"/README.js", guide["name"], {:guide => guide[:html], :title => guide["title"]})
end