baseball_scorecard 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +4 -0
  3. data/Rakefile +1 -0
  4. data/baseball_scorecard.gemspec +30 -0
  5. data/bin/scorecard +3 -0
  6. data/gameday_copyright.txt +6 -0
  7. data/lib/baseball_scorecard.rb +114 -0
  8. data/lib/baseball_scorecard/card_generator.rb +368 -0
  9. data/lib/baseball_scorecard/images/baseball.png +0 -0
  10. data/lib/baseball_scorecard/images/bases-1-2-3.png +0 -0
  11. data/lib/baseball_scorecard/images/bases-1-2.png +0 -0
  12. data/lib/baseball_scorecard/images/bases-1-3.png +0 -0
  13. data/lib/baseball_scorecard/images/bases-1.png +0 -0
  14. data/lib/baseball_scorecard/images/bases-2-3.png +0 -0
  15. data/lib/baseball_scorecard/images/bases-2.png +0 -0
  16. data/lib/baseball_scorecard/images/bases-3.png +0 -0
  17. data/lib/baseball_scorecard/images/bases.png +0 -0
  18. data/lib/baseball_scorecard/images/bases_bg.png +0 -0
  19. data/lib/baseball_scorecard/images/bases_no_ba.png +0 -0
  20. data/lib/baseball_scorecard/images/error.png +0 -0
  21. data/lib/baseball_scorecard/images/grass.jpg +0 -0
  22. data/lib/baseball_scorecard/images/hit_1B.png +0 -0
  23. data/lib/baseball_scorecard/images/hit_2B.png +0 -0
  24. data/lib/baseball_scorecard/images/hit_3B.png +0 -0
  25. data/lib/baseball_scorecard/images/hit_BB.png +0 -0
  26. data/lib/baseball_scorecard/images/hit_HBP.png +0 -0
  27. data/lib/baseball_scorecard/images/hit_HR.png +0 -0
  28. data/lib/baseball_scorecard/images/hit_IBB.png +0 -0
  29. data/lib/baseball_scorecard/images/out_called.png +0 -0
  30. data/lib/baseball_scorecard/images/out_double-play.png +0 -0
  31. data/lib/baseball_scorecard/images/out_fly.png +0 -0
  32. data/lib/baseball_scorecard/images/out_force.png +0 -0
  33. data/lib/baseball_scorecard/images/out_ground.png +0 -0
  34. data/lib/baseball_scorecard/images/out_line.png +0 -0
  35. data/lib/baseball_scorecard/images/out_pop.png +0 -0
  36. data/lib/baseball_scorecard/images/out_strikes.png +0 -0
  37. data/lib/baseball_scorecard/images/out_triple-play.png +0 -0
  38. data/lib/baseball_scorecard/images/outs_1.png +0 -0
  39. data/lib/baseball_scorecard/images/outs_2.png +0 -0
  40. data/lib/baseball_scorecard/images/outs_3.png +0 -0
  41. data/lib/baseball_scorecard/images/team_images/ana.png +0 -0
  42. data/lib/baseball_scorecard/images/team_images/ari.png +0 -0
  43. data/lib/baseball_scorecard/images/team_images/atl.png +0 -0
  44. data/lib/baseball_scorecard/images/team_images/bal.png +0 -0
  45. data/lib/baseball_scorecard/images/team_images/bos.png +0 -0
  46. data/lib/baseball_scorecard/images/team_images/cha.png +0 -0
  47. data/lib/baseball_scorecard/images/team_images/chn.png +0 -0
  48. data/lib/baseball_scorecard/images/team_images/cin.png +0 -0
  49. data/lib/baseball_scorecard/images/team_images/cle.png +0 -0
  50. data/lib/baseball_scorecard/images/team_images/col.png +0 -0
  51. data/lib/baseball_scorecard/images/team_images/det.png +0 -0
  52. data/lib/baseball_scorecard/images/team_images/flo.png +0 -0
  53. data/lib/baseball_scorecard/images/team_images/hou.png +0 -0
  54. data/lib/baseball_scorecard/images/team_images/kca.png +0 -0
  55. data/lib/baseball_scorecard/images/team_images/lan.png +0 -0
  56. data/lib/baseball_scorecard/images/team_images/mil.png +0 -0
  57. data/lib/baseball_scorecard/images/team_images/min.png +0 -0
  58. data/lib/baseball_scorecard/images/team_images/nya.png +0 -0
  59. data/lib/baseball_scorecard/images/team_images/nyn.png +0 -0
  60. data/lib/baseball_scorecard/images/team_images/oak.png +0 -0
  61. data/lib/baseball_scorecard/images/team_images/phi.png +0 -0
  62. data/lib/baseball_scorecard/images/team_images/pit.png +0 -0
  63. data/lib/baseball_scorecard/images/team_images/sdn.png +0 -0
  64. data/lib/baseball_scorecard/images/team_images/sea.png +0 -0
  65. data/lib/baseball_scorecard/images/team_images/sfn.png +0 -0
  66. data/lib/baseball_scorecard/images/team_images/sln.png +0 -0
  67. data/lib/baseball_scorecard/images/team_images/tba.png +0 -0
  68. data/lib/baseball_scorecard/images/team_images/tex.png +0 -0
  69. data/lib/baseball_scorecard/images/team_images/tor.png +0 -0
  70. data/lib/baseball_scorecard/images/team_images/was.png +0 -0
  71. data/lib/baseball_scorecard/scorecard_away.html +28 -0
  72. data/lib/baseball_scorecard/scorecard_home.html +34 -0
  73. data/lib/baseball_scorecard/version.rb +3 -0
  74. data/readme.txt +55 -0
  75. metadata +175 -0
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in baseball_scorecard.gemspec
4
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "baseball_scorecard/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "baseball_scorecard"
7
+ s.version = BaseballScorecard::VERSION
8
+ s.authors = ["j. kaiden"]
9
+ s.email = ["jakekaiden@gmail.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{Baseball scorecard generator}
12
+ s.description = %q{Baseball scorecard generator}
13
+
14
+ # s.rubyforge_project = "baseball_scorecard"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ # s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.executables << 'scorecard'
20
+ s.require_paths = ["lib"]
21
+
22
+ # specify any dependencies here; for example:
23
+ # s.add_development_dependency "rspec"
24
+ # s.add_runtime_dependency "rest-client"
25
+ s.add_dependency "markaby"
26
+ s.add_dependency "hpricot"
27
+ s.add_dependency "green_shoes"
28
+ s.add_dependency "gameday_api"
29
+ s.add_dependency "launchy"
30
+ end
data/bin/scorecard ADDED
@@ -0,0 +1,3 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ load "baseball_scorecard.rb"
@@ -0,0 +1,6 @@
1
+
2
+ All documents fetched by the gameday API clearly state: Copyright 2012 MLB Advanced Media, L.P. Use of any content on this page acknowledges agreement to the terms posted here gdx.mlb.com/components/copyright.txt
3
+
4
+ Which furthermore states: The accounts, descriptions, data and presentation in the referring page (the “Materials”) are proprietary content of MLB Advanced Media, L.P (“MLBAM”).<br />Only individual, non-commercial, non-bulk use of the Materials is permitted and any other use of the Materials is prohibited without prior written authorization from MLBAM.<br />Authorized users of the Materials are prohibited from using the Materials in any commercial manner other than as expressly authorized by MLBAM.
5
+
6
+ Naturally, these terms are passed on to any who use this application. It is your responsibility to abide by them.
@@ -0,0 +1,114 @@
1
+ require 'markaby'
2
+ require 'green_shoes'
3
+ require 'gameday'
4
+ require 'team'
5
+ require 'batter'
6
+ require 'launchy'
7
+ require File.join(File.dirname(__FILE__), "baseball_scorecard", "card_generator")
8
+
9
+ module BaseballScorecard
10
+
11
+ Shoes.app width: 300, height: 225, title: "Scorecard Generator" do
12
+
13
+ Shoes::App.class_eval{include CardGenerator}
14
+
15
+ background(image "#{File.join(File.dirname(__FILE__), "baseball_scorecard", "images", "baseball.png")}")
16
+
17
+ teams = Team.teams
18
+ team_list = ["Select Team"]
19
+ teams.each{|t|
20
+ team_list << t[1][0..1].join(' ')
21
+ }
22
+
23
+ team_lbox = list_box(width: 250, items: team_list){|list| @team = list.text}
24
+ team_lbox.choose("Select Team")
25
+ team_lbox.move(25, 25)
26
+
27
+ yesterday = (Time.now - 86400).strftime("%B %d %Y").split
28
+
29
+ month_lbox = list_box(width: 120, items: %w[January February March April May June July August September October November December]){|list|
30
+ @month = list.text
31
+ }
32
+ month_lbox.choose(yesterday[0])
33
+ month_lbox.move(25, 65)
34
+
35
+ day_lbox = list_box(width: 50, items: (1..31).to_a){|list|
36
+ @day = list.text
37
+ }
38
+ day_lbox.choose(yesterday[1].to_i)
39
+ day_lbox.move(149, 65)
40
+
41
+ year_lbox = list_box(width: 72, items: (1926..(yesterday[2].to_i)).to_a){|list|
42
+ @year = list.text
43
+ }
44
+ year_lbox.choose(yesterday[2].to_i)
45
+
46
+ year_lbox.move(275 - year_lbox.width, 65)
47
+
48
+ find_btn = button("find games"){
49
+ unless @team == "Select Team"
50
+ @status_line.text = "searching for games..."
51
+ p "fetching game..."###
52
+ @games = nil
53
+
54
+ Thread.new do
55
+ teams.each{|t|
56
+ @team.split.each{|w|
57
+ if t[1].include?(w); selected = true; else selected = false; end
58
+ @team_abrev = t[0] if selected
59
+ }
60
+ }
61
+
62
+ GamedayUtil.set_fetcher('remote')
63
+ team = Team.new(@team_abrev)
64
+
65
+ sel_date = "#{@year} #{@month} #{@day}"
66
+ date = Time.parse(sel_date).strftime("%Y %m %d").split
67
+
68
+ begin
69
+ @games = team.games_for_date(date[0], date[1], date[2])
70
+ rescue ArgumentError
71
+ @status_line.text = "no games found for team and date"
72
+ p "no games found"
73
+ rescue Exception => e
74
+ @status_line.text = "error finding games"; p e
75
+ end
76
+
77
+ if @games
78
+ times = []
79
+ @games.each{|g|
80
+ time = Time.parse(g.time).strftime("%I:%M %p")
81
+ time.slice!(0) if time[0] == "0"
82
+ times << time
83
+ }
84
+
85
+ games_lbox = list_box(width: 250, items: times){|list| @game = @games[times.index(list.text)]}
86
+ games_lbox.choose(times[0])
87
+ games_lbox.move(25, 105)
88
+
89
+ b_btn = button("build scorecards"){init_cards(@game)}
90
+ b_btn.style(width: 120)
91
+ b_btn.move(155, 145)
92
+ @status_line.text = "games(s) found"
93
+ else
94
+ p "now what do i do?"
95
+ end #if
96
+ end #Thread
97
+ else
98
+ @status_line.text = "Select a Team"
99
+ end #unless
100
+ } #find_btn
101
+ find_btn.style(width: 120)
102
+ find_btn.move(25, 145)
103
+
104
+ flow width: 300 do
105
+ nofill
106
+ @status_box = flow{
107
+ fill white
108
+ rect(25, 190, 250, 20, curve: 5)
109
+ @status_line = inscription "Select Team and Date", top: 191, align: "center"
110
+ }
111
+ end
112
+
113
+ end #Shoes.app
114
+ end #module
@@ -0,0 +1,368 @@
1
+ class Array #makes green_shoes play nice with gameday_api ;)
2
+ def clear; _clear end
3
+ end
4
+
5
+ module CardGenerator
6
+ attr_accessor :home_team, :visiting_team, :home_batters, :visiting_batters,
7
+ :home_pitchers, :visiting_pitchers, :visiting_abrev, :home_abrev,
8
+ :visiting_score, :home_score, :date, :elements, :fldg, :imagedir
9
+
10
+ def init_cards(game)
11
+ @@parent = self
12
+ #@imagedir = "images"
13
+ @imagedir = File.join(File.dirname(__FILE__), "images")
14
+ Thread.new{init_batting_arrays(game)}
15
+ end
16
+
17
+ def init_batting_arrays(game)
18
+ @game = game
19
+ @gid = @game.gid
20
+ @status_line.text = "getting lineups..."
21
+ p "fetching lineups..."###
22
+ begin
23
+ @home = @game.get_batters("home")
24
+ @visitors = @game.get_batters("away")
25
+ @home_pitchers = @game.get_pitchers("home")
26
+ @visiting_pitchers = @game.get_pitchers("away")
27
+ rescue Exception => e
28
+ @status_line.text = "Error getting lineups"; p e
29
+ end
30
+ @status_line.text = "getting innings..."
31
+ p "fetching innings..."###
32
+ begin
33
+ innings = @game.get_innings
34
+ rescue Exception => e
35
+ @status_line.text = "Error getting innings"; p e
36
+ end
37
+ @status_line.text = "getting atbats..."
38
+ p "fetching atbats..."
39
+ begin
40
+ @atbats = @game.get_atbats
41
+ rescue Exception => e
42
+ @status_line.text = "Error getting atbats"; p e
43
+ end
44
+ @status_line.text = "getting team info..."
45
+ p "getting team info..."###
46
+ begin
47
+ teams = Team.get_teams_for_gid(@gid)
48
+ @visiting_team = "#{teams[0].city} #{teams[0].name}"
49
+ @visiting_abrev = teams[0].abrev.upcase
50
+ @home_team = "#{teams[1].city} #{teams[1].name}"
51
+ @home_abrev = teams[1].abrev.upcase
52
+ rescue Exception => e
53
+ @status_line.text = "Error getting team info"; p e
54
+ end
55
+
56
+ @date = "#{Date::MONTHNAMES[@game.month.to_i]} #{@game.day}, #{@game.year}"
57
+ box = @game.boxscore
58
+ line = box.linescore
59
+ @visiting_score = line.away_team_runs
60
+ @home_score = line.home_team_runs
61
+
62
+ @visiting_batters = []
63
+ @home_batters = []
64
+
65
+ @status_line.text = "building cards..."
66
+ p "building arrays..."##
67
+
68
+ Struct.new("Batter", :name, :number, :position, :id, :batting_order, :innings, :stats)
69
+ @total = (@home.length + @visitors.length).to_f
70
+ @processed = 0.0
71
+
72
+ def build_array(home_or_away)
73
+ case home_or_away
74
+ when 'home'; batters = @home; batting_array = @home_batters
75
+ when 'away'; batters = @visitors; batting_array = @visiting_batters
76
+ end
77
+
78
+ batters.each{|ba|
79
+ @processed += 1.0
80
+ @status_line.text = "#{((@processed/ @total) * 100).round.to_s}%"##
81
+
82
+ b = Batter.new; b.load_from_id(@gid, ba.pid)
83
+ xd = b.instance_variable_get("@xml_data")
84
+
85
+ xd.split("<").each{|entry|
86
+ if entry.include?("season")
87
+ @season_stats = entry.delete('/>').delete('"').gsub('season', 'SEASON:').gsub('=', ': ')
88
+ elsif entry.include?("career")
89
+ @career_stats = entry.delete('/>').delete('"').gsub('career', 'CAREER:').gsub('=', ': ')
90
+ end
91
+ }
92
+ stats = "#{@season_stats}\n#{@career_stats}"
93
+
94
+ number = b.jersey_number
95
+ inning_arrays = []
96
+ @game.innings.length.times{
97
+ inning_arrays << []
98
+ }
99
+ batter = Struct::Batter.new(ba.batter_name, number, ba.pos, ba.pid, (ba.bo.to_i / 100).round, inning_arrays, stats)
100
+ batting_array << batter
101
+ } #batters.each
102
+ end #build_array
103
+
104
+ begin
105
+ build_array('home')
106
+ build_array('away')
107
+ rescue Exception => e
108
+ @status_line.text = "Error building arrays"; p e
109
+ end
110
+
111
+ def set_inning(home_or_away, ab)
112
+ case home_or_away
113
+ when 'home'; batting_array = @home_batters
114
+ when 'away'; batting_array = @visiting_batters
115
+ end
116
+
117
+ inning = ab.inning.to_i
118
+ player_id = ab.batter_id
119
+
120
+ batting_array.each{|batter|
121
+ if batter.id == player_id
122
+ batter.innings[inning - 1] << ab
123
+ end
124
+ }
125
+ end #set_inning
126
+
127
+ begin
128
+ innings.each{|i|
129
+ i.top_atbats.each{|ab| set_inning('away', ab)}
130
+ i.bottom_atbats.each{|ab| set_inning('home', ab)}
131
+ }
132
+ rescue Exception => e
133
+ @status_line.text = "Error setting innings"; p e
134
+ end
135
+
136
+ @status_line.text = "arrays built"
137
+ p "arrays built"##
138
+ init_html('home')
139
+ init_html('away')
140
+
141
+ end #init_batting_arrays
142
+
143
+ def get_elements(home_or_away, batter_index, inning_index)
144
+ @elements = []
145
+ @fldg = nil
146
+
147
+ if home_or_away == 'home'
148
+ batting_array = @home_batters
149
+ else
150
+ batting_array = @visiting_batters
151
+ end
152
+ atbat = batting_array[batter_index].innings[inning_index][-1]
153
+ next_atbat = @atbats[atbat.num.to_i]
154
+ last_atbat = @atbats[atbat.num.to_i - 2]
155
+
156
+ bases = []
157
+ if next_atbat
158
+ bases << next_atbat.pitches[0].on_1b << next_atbat.pitches[0].on_2b << next_atbat.pitches[0].on_3b
159
+ else
160
+ bases << atbat.pitches[0].on_1b << atbat.pitches[0].on_2b << atbat.pitches[0].on_3b
161
+ end
162
+ bases_file = File.join(@imagedir, "bases")
163
+ bases.each_with_index{|b, i|
164
+ if b
165
+ bases_file << "-#{(i+1).to_s}"
166
+ end
167
+ }
168
+ bases_file += ".png"
169
+ @elements << bases_file #[0]
170
+
171
+ case atbat.event
172
+ when "Single"
173
+ event_image = File.join(@imagedir, "hit_1B.png")
174
+ get_fldg(atbat.des)
175
+ when "Double"
176
+ event_image = File.join(@imagedir, "hit_2B.png")
177
+ get_fldg(atbat.des)
178
+ when "Triple"
179
+ event_image = File.join(@imagedir, "hit_3B.png")
180
+ get_fldg(atbat.des)
181
+ when "Home Run"
182
+ event_image = File.join(@imagedir, "hit_HR.png")
183
+ get_fldg(atbat.des)
184
+ when "Walk"
185
+ event_image = File.join(@imagedir, "hit_BB.png")
186
+ when "Intent Walk"
187
+ event_image = File.join(@imagedir, "hit_IBB.png")
188
+ when "Hit By Pitch"
189
+ event_image = File.join(@imagedir, "hit_HBP.png")
190
+ when "Strikeout"
191
+ if atbat.des.include?("called")
192
+ event_image = File.join(@imagedir, "out_called.png")
193
+ else
194
+ event_image = File.join(@imagedir, "out_strikes.png")
195
+ end
196
+ when "Flyout"
197
+ event_image = File.join(@imagedir, "out_fly.png")
198
+ get_fldg(atbat.des)
199
+ when "Groundout"
200
+ event_image = File.join(@imagedir, "out_ground.png")
201
+ get_fldg(atbat.des)
202
+ when "Pop Out"
203
+ event_image = File.join(@imagedir, "out_pop.png")
204
+ get_fldg(atbat.des)
205
+ when "Lineout"
206
+ event_image = File.join(@imagedir, "out_line.png")
207
+ get_fldg(atbat.des)
208
+ when "Forceout"
209
+ event_image = File.join(@imagedir, "out_force.png")
210
+ get_fldg(atbat.des)
211
+ when "Field Error"
212
+ event_image = File.join(@imagedir, "error.png")
213
+ get_fldg(atbat.des)
214
+ end #case
215
+ if atbat.event.include?("DP")
216
+ event_image = File.join(@imagedir, "out_double-play.png")
217
+ get_fldg(atbat.des)
218
+ end
219
+ if atbat.event.include?("TP")
220
+ event_image = File.join(@imagedir, "out_triple-play.png")
221
+ get_fldg(atbat.des)
222
+ end
223
+
224
+ @elements << event_image #[1]
225
+
226
+ outs_image = nil
227
+ unless atbat.o == "0" || atbat.o == last_atbat.o
228
+ outsfile = "outs_#{atbat.o}.png"
229
+ outs_image = File.join(@imagedir, outsfile)
230
+ end
231
+ @elements << outs_image #[2]
232
+
233
+ @elements.insert(3, @fldg) if @fldg #[3]
234
+
235
+ rbi = atbat.des.scan(/scores/).length
236
+ @elements.insert(4, rbi) unless rbi == 0 #[4]
237
+
238
+ end #get_elements
239
+
240
+ def get_fldg(des)
241
+ fldg = []
242
+ fldg.insert(des.index("pitcher"), "1") if des.include?("pitcher")
243
+ fldg.insert(des.index("catcher"), "2") if des.include?("catcher")
244
+ fldg.insert(des.index("first baseman"), "3") if des.include?("first baseman")
245
+ fldg.insert(des.index("second baseman"), "4") if des.include?("second baseman")
246
+ fldg.insert(des.index("third baseman"), "5") if des.include?("third baseman")
247
+ fldg.insert(des.index("shortstop"), "6") if des.include?("shortstop")
248
+ fldg.insert(des.index("left field"), "7") if des.include?("left field")
249
+ fldg.insert(des.index("center field"), "8") if des.include?("center field")
250
+ fldg.insert(des.index("right field"), "9") if des.include?("right field")
251
+ @fldg = fldg.compact.join("-")
252
+ end
253
+
254
+ def init_html(home_or_away)
255
+ @status_line.text = "building html"
256
+ p "building html"###
257
+
258
+ html_builder = Markaby::Builder.new
259
+ html_builder.html do
260
+ imagedir = @@parent.imagedir
261
+ case home_or_away
262
+ when 'home'
263
+ batters = @@parent.home_batters; pitchers = @@parent.home_pitchers; team_abrev = @@parent.home_abrev
264
+ when 'away'
265
+ batters = @@parent.visiting_batters; pitchers = @@parent.visiting_pitchers; team_abrev = @@parent.visiting_abrev
266
+ end
267
+
268
+ head {title "#{team_abrev} Scorecard"}
269
+ body :style => "background-image: url(#{File.join(imagedir, 'grass.jpg')})" do
270
+
271
+ h1 :style => "padding-top: 5"
272
+ pre "#{@@parent.visiting_team} #{@@parent.visiting_score} - #{@@parent.home_team} #{@@parent.home_score}", :style => "color: white; font-family: arial; text-align: center"
273
+ h2
274
+ pre @@parent.date, :style => "color: white; font-family: arial; text-align: center"
275
+ img :src => File.join(imagedir, "team_images", "#{team_abrev.downcase}.png"),
276
+ :style => "position: absolute; left: 20; top: 85"
277
+
278
+ table do
279
+
280
+ tr
281
+ td; inning_num = 1
282
+ 9.times{
283
+ td inning_num, :style => "color: white; font-family: arial; font-size: 125%; text-align: center"
284
+ inning_num += 1
285
+ }
286
+
287
+ batters.each_with_index{|batter, batter_index|
288
+ unless batter.batting_order == 0
289
+ tr
290
+ td :width => 150, :title => batter.stats
291
+ pre "#{batter.batting_order}\n#{batter.name}\n##{batter.number} #{batter.position}",
292
+ :style => "color: white; font-family: arial; font-size: 125%; text-align: right; padding-right: 20"
293
+
294
+ batter.innings.each_with_index{|inning, inning_index|
295
+ if inning.empty?
296
+ td
297
+ img :src => File.join(imagedir, "bases_no_ba.png"), :style => "position: relative; top: 0; left: 0"
298
+ else
299
+ atbat = batter.innings[inning_index][-1]
300
+ @@parent.get_elements(home_or_away, batter_index, inning_index)
301
+ description = ""#
302
+ if batter.innings[inning_index].length > 1#
303
+ batter.innings[inning_index].each_with_index{|ab, ab_index|#
304
+ description << "At Bat #{ab_index + 1}: #{ab.des}\n"#
305
+ }#
306
+ else
307
+ description = atbat.des
308
+ end
309
+ td :style => "position: relative; top: 0; left: 0", :title => description
310
+ img :src => File.join(imagedir, "bases_bg.png"), :style => "position: absolute; top: 0; left: 0"
311
+ img :src => @@parent.elements[1], :style => "position: absolute; top: 0; left: 0" if @@parent.elements[1]
312
+ img :src => @@parent.elements[0], :style => "position: absolute; top: 0; left: 0"
313
+ img :src => @@parent.elements[2], :style => "position: absolute; top: 69; left: 69" if @@parent.elements[2]
314
+ pre "#{atbat.b}-#{atbat.s}",
315
+ :style => "position: absolute; top: -7; left: 7; font-family: arial; font-size: small"
316
+ pre @@parent.fldg,
317
+ :style => "position: absolute; top: 60; left: 7; font-family: arial; font-size: small" if @@parent.fldg
318
+ pre "#{@@parent.elements[4]}",
319
+ :style => "position: absolute; top: -7; left: 65; font-family: arial; font-size: small" if @@parent.elements[4]
320
+ pre "RBI",
321
+ :style => "position: absolute; top: -1; left: 72; font-family: arial; font-size: x-small" if @@parent.elements[4]
322
+ if batter.innings[inning_index].length > 1
323
+ pre "+AB", :style => "position: absolute; top: 43; left: 33; font-family: arial; font-weight: bold; font-size: small"
324
+ end
325
+ if atbat.des.include?('steals')
326
+ pre "SB", :style => "position: absolute; top: 6; left: 37; font-family: arial; font-weight: bold"
327
+ end
328
+ end #if inning.empty?
329
+ } #batter.innings.each_with_index
330
+ end #unless
331
+ } #batters.each_with_index
332
+ end #table
333
+
334
+ hr :style => "padding-top: 10"##
335
+ h2 "Pitching", :style => "color: white; font-family: arial; text-align: center"
336
+ table do
337
+ tr
338
+ td; %w[W-L ERA IP AB K BB H R ER].each{|entry|
339
+ td entry, :width => 150, :style => "color: white; font-family: arial; font-size: 125%; text-align: center"
340
+ }
341
+ pitchers.each{|pitcher|
342
+ tr :style => "color: white; font-family: arial"
343
+ td pitcher.pitcher_name, :style => "font-size: 125%; text-align: right; padding-right: 20"
344
+ td "#{pitcher.w}-#{pitcher.l}", :width => 150, :style => "text-align: center"
345
+ td pitcher.era, :width => 150, :style => "text-align: center"
346
+ td pitcher.inn, :width => 150, :style => "text-align: center"
347
+ td pitcher.bf, :width => 150, :style => "text-align: center"
348
+ td pitcher.so, :width => 150, :style => "text-align: center"
349
+ td pitcher.bb, :width => 150, :style => "text-align: center"
350
+ td pitcher.h, :width => 150, :style => "text-align: center"
351
+ td pitcher.r, :width => 150, :style => "text-align: center"
352
+ td pitcher.er, :width => 150, :style => "text-align: center"
353
+ } #pitchers.each
354
+ end #table
355
+
356
+ end #body
357
+ end #html_builder
358
+
359
+ File.open("scorecard_#{home_or_away}.html", "w"){|f|
360
+ f.puts(html_builder.to_s)
361
+ }
362
+
363
+ @status_line.text = "html built"
364
+ p "html built"##
365
+ Launchy.open("scorecard_#{home_or_away}.html")
366
+ end #init_html
367
+
368
+ end #module CardGenerator