1#!/usr/bin/env ruby
2# Copyright (c) 2006-2007, The RubyCocoa Project.
3# All Rights Reserved.
4#
5# RubyCocoa is free software, covered under either the Ruby's license or the 
6# LGPL. See the COPYRIGHT file for more information.
7
8script_dir = File.dirname(File.expand_path(__FILE__))
9require "#{script_dir}/lib/cocoa_ref"
10
11def command( str )
12  $stderr.puts str
13  system str or raise RuntimeError, "'system #{str}' failed"
14end
15
16def ruby( str )
17  command "#{Config::CONFIG["bindir"]}/ruby #{str}"
18end
19
20def rdoc( str )
21  command "#{Config::CONFIG["bindir"]}/rdoc #{str}"
22end
23
24def get_reference_files(framework_path)
25  reference_files = []
26  
27  # Get the Class reference files
28  classes_dir = File.join(framework_path, 'Classes/')
29  Dir.entries(classes_dir).each do |f|
30    class_path = File.join(classes_dir, f)
31    if File.directory?(class_path) and not f == '.' and not f == '..'
32      ref_dir_path = File.join(class_path, 'Reference/')
33      ref_dir_path = File.join(class_path, 'Introduction/') unless File.exists?(ref_dir_path)
34      Dir.entries(ref_dir_path).each do |rf|
35        if File.extname(rf) == '.html'
36          ref_path = File.join(ref_dir_path, rf)
37          reference_files.push({:name => File.basename(class_path), :path => ref_path})
38        end
39      end
40    end
41  end
42  
43  # Get the Protocol reference files
44  protocols_dir = File.join(framework_path, 'Protocols/')
45  if File.exist?(protocols_dir)
46    Dir.entries(protocols_dir).each do |f|
47      protocol_path = File.join(protocols_dir, f)
48      if File.directory?(protocol_path) and not f == '.' and not f == '..'
49        ref_dir_path = File.join(protocol_path, 'Reference/')
50        Dir.entries(ref_dir_path).each do |rf|
51          if File.extname(rf) == '.html'
52            ref_path = File.join(ref_dir_path, rf)
53            reference_files.push({:name => File.basename(protocol_path), :path => ref_path})
54          end
55        end
56      end
57    end
58  end
59  
60  misc_dir = File.join(framework_path, 'Miscellaneous/')
61  if File.exist?(misc_dir)
62    Dir.entries(misc_dir).each do |f|
63      if f.include? 'Constants'
64        # Get the constants reference file
65        ref_dir_path = File.join(misc_dir, f, 'Reference/')
66        Dir.entries(ref_dir_path).each do |rf|
67          if File.extname(rf) == '.html'
68            ref_path = File.join(ref_dir_path, rf)
69            reference_files.push({:name => "#{File.basename(framework_path)}Constants", :path => ref_path})
70          end
71        end
72      end
73    end
74    Dir.entries(misc_dir).each do |f|
75      if f.include? 'Functions'
76        # Get the functions reference file
77        ref_dir_path = File.join(misc_dir, f, 'Reference/')
78        Dir.entries(ref_dir_path).each do |rf|
79          if File.extname(rf) == '.html'
80            ref_path = File.join(ref_dir_path, rf)
81            reference_files.push({:name => "#{File.basename(framework_path)}Functions", :path => ref_path})
82          end
83        end
84      end
85    end
86    Dir.entries(misc_dir).each do |f|
87      if f.include? 'DataTypes'
88        # Get the data types reference file
89        ref_dir_path = File.join(misc_dir, f, 'Reference/')
90        Dir.entries(ref_dir_path).each do |rf|
91          if File.extname(rf) == '.html'
92            ref_path = File.join(ref_dir_path, rf)
93            reference_files.push({:name => "#{File.basename(framework_path)}DataTypes", :path => ref_path})
94          end
95        end
96      end
97    end
98  end
99  
100  return reference_files
101end
102
103$COCOA_REF_DEBUG = false
104output_files_with_errors = false
105framework_path = ''
106output_dir = ''
107
108unless ARGV.empty?
109  ARGV.each do |arg|
110    case arg
111    when '-f'
112      output_files_with_errors = true
113    when '-v'
114      $COCOA_REF_DEBUG = true
115    else
116      if framework_path.empty?
117        framework_path = arg
118      else
119        output_dir = arg
120      end
121    end
122  end
123else
124  puts "Usage:"
125  puts "  #{__FILE__} [options] path/to/the/framework <output dir>"
126  puts ""
127  puts "Options:"
128  puts "  -v Verbose output."
129  puts "  -f Force the output files to be written even if there were errors during parsing."
130  puts ""
131  puts "Example:"
132  puts "  #{__FILE__} /Developer/ADC Reference Library/documentation/Cocoa/Reference/ApplicationKit/ output/"
133  puts "  #{__FILE__} -v /Developer/ADC Reference Library/documentation/Cocoa/Reference/ApplicationKit/"
134  puts "  #{__FILE__} -v -f /Developer/ADC Reference Library/documentation/Cocoa/Reference/ApplicationKit/"
135  puts ""
136  
137  exit
138end
139
140framework_name = File.basename(framework_path)
141# This is a workaround for pdfkit which is in the quartz dir,
142# if it looks like that there are more frameworks that need
143# special treatment than this should be done with a less hacky way.
144framework_name = 'PDFKit' if framework_name == 'QuartzFramework'
145
146puts ""
147puts "Working on: #{framework_name}"
148puts ""
149
150reference_files = get_reference_files(framework_path)
151
152# This is a workaround for pdfkit which is in the quartz dir,
153# if it looks like that there are more frameworks that need
154# special treatment than this should be done with a less hacky way.
155if File.basename(framework_path) == 'QuartzFramework'
156  reference_files.delete_if {|r| ['QCView_Class', 'QCRenderer_Class'].include?(r[:name]) }
157end
158
159unless output_dir.empty?
160  output_dir = File.expand_path(output_dir)
161else
162  output_dir = File.join(script_dir, 'output/')
163end
164
165if not File.exists?(output_dir)
166  command "mkdir -p #{output_dir}"
167end
168
169success = 0
170skipped = 0
171reference_files.each do |ref|
172  puts "Processing reference file: #{ref[:name]}"
173  begin
174    cocoa_ref_parser = CocoaRef::Parser.new(ref[:path], framework_name)
175    if cocoa_ref_parser.empty?
176      skipped = skipped.next
177      puts 'Skipping because there was no info found of our interest in the reference file...'
178    elsif not cocoa_ref_parser.errors? or output_files_with_errors
179      success = success.next
180      puts "      Writing output file: #{cocoa_ref_parser.class_def.output_filename}"
181      cocoa_ref_parser.to_rb_file(output_dir)
182    else
183      skipped = skipped.next
184      puts 'Skipping because there were errors while parsing...'
185    end
186  rescue CocoaRef::HpricotProxy::DeprecatedError
187    skipped = skipped.next
188    puts 'Skipping because this is a deprecated class...'
189  end
190end
191
192puts ''
193puts "Stats for: #{framework_name}"
194puts "  Written: #{success} files"
195puts "  Skipped: #{skipped} files"
196puts ''
197