Skip to content

Instantly share code, notes, and snippets.

@rgchris rgchris/make-scorecard.r
Last active Jul 1, 2019

Embed
What would you like to do?
Softball Scorecard Generator
#!/usr/local/bin/rebol -qs
Rebol [
Title: "Generate a Softball Scorecard"
Date: 30-Jun-2019
Author: "Christopher Ross-Gill"
Target: %Softball%20Scorecard.pdf
Home: https://gist.github.com/rgchris/77e4c6482e4cdf0465603aaf825f7d66
Notes: {
This was needed for some back-pocket scoring for an
intramural softball league.
- The lineups are 10 players per team with a regular
game of seven innings.
- While it may not cover every game outcome, it will
cover the vast majority.
- It is only intended to track runs, on-base and outs.
}
]
;; note that running pdf-maker in place will download the
;; font metrics file you your current directory.
; do http://www.colellachiara.com/soft/PDFM2/pdf-maker.r
do %pdf-maker.r
; PDF Maker uses mm, I need to work in pt.
; We'll translate our working layout block from pts to mm.
pts2mm: func [
value [integer! decimal! block!]
][
either number? value [
round/to value * (25.4 / 72) 0.001
][
collect [
foreach value value [
keep/only switch/default type?/word value [
integer! decimal! block! [pts2mm value]
paren! [to paren! pts2mm to block! value]
][
:value
]
]
]
]
]
write system/script/header/target layout-pdf bind pts2mm [
; Had to be a little creative to get shapes in text to
; generate with arguments. Non-plussed by the built-in XBL/YBL
; naming
define-func 'arrow [
'direction [word!]
/local top bottom
][
box 6 8 0.5 compose/deep [
paint edge width 0 [
move to xbl + 0 ybl + (arrows/:direction/bottom)
line to xbl + 6 ybl + (arrows/:direction/bottom)
line to xbl + 3 ybl + (arrows/:direction/top)
close
]
]
]
; The next four macros operate with respect to the global OFFSET
; value. This permits the main SCORECARD macro to contain only
; coordinates relative to each quadrant. Each also handles flipping
; the Y axis so the main SCORECARD has a TOP LEFT coordinate base.
; This is the LINE generating workhorse. It's a useful abstraction
; as PDF Maker's lines and boxes have different size parameters.
define-func 'grid [
'shape [word!]
x [number!] y [number!] length [number!]
/thin /thick /dotted /local thickness
][
; thickness
thickness: case [
thin [lines/thin]
thick [lines/thick]
/else [lines/regular]
]
; start coords
x: x + offset/x
y: page/height - y - offset/y
switch shape compose/deep [
across [
line width thickness cap square dash solid
x y x + length y
]
down [
line width thickness cap square dash solid
x y x y - length
]
dotted [
line width thickness cap round dash [0.1 3] 0
x y x + length y
]
]
]
; aka. box
define-func 'rectangle [
x [number!] y [number!] width [number!] height [number!]
/thick /thin /local thickness
][
thickness: case [
thin [lines/thin]
thick [lines/thick]
/else [lines/regular]
]
box line width thickness line dash solid
x + offset/x page/height - y - offset/y - height width height
]
; Rudimentary text wrapper.
define-func 'label [
x [number!] y [number!] text [string! block!]
/center /right /local alignment
][
x: x + offset/x
y: page/height - y - offset/y - labels/height
alignment: case [
center [[center]]
right [[right align]]
/else [[left align]]
]
textbox x y labels/width labels/height compose [
(alignment)
font Helvetica labels/medium
(text)
]
]
; our diamonds for tracking on-base movement
define-func 'diamond [x [number!] y [number!]][
x: x + offset/x
y: page/height - y - offset/y
stroke line width lines/thin [
move to x y + 7
line to x + 7 y
line to x y - 7
line to x - 7 y
close
]
]
; this defines each scorecard quadrant. Coordinates are in POINTS and
; are relative to the TOP LEFT corner of each quadrant.
define-func 'scorecard ['team [word!] offset-x [number!] offset-y [number!]][
offset: reduce ['x offset-x 'y offset-y]
switch team [
home [
label 26 18 "field"
label/right 230 36 "home"
label 26 80 ["(" arrow down ") inning"]
]
visitor [
label 26 18 "date"
label 157 18 "time"
label/right 230 36 "visitor"
label 26 80 ["(" arrow up ") inning"]
]
]
; only need '1' labelled as innings can span more than one column
label 94 80 "1"
; lines ACROSS
grid across 21 33 264
grid across 21 73 264
grid across 21 98 264
; at-bats grid goes here
grid across 84 318 201
grid across 84 343 201
; signature line
grid dotted 99 375 186
; scorebox
rectangle/thick 21 318 63 57
; lines DOWN
grid/thin down 42 98 220
grid/thin down 63 98 220
grid down 84 73 245
; at-bats grid goes here
grid down 285 73 270
; the at-bats grid
repeat offset nine [
grid/thin across 21 (22 * offset + 98) 264
]
repeat offset seven [
grid/thin down (offset * 25 + 84) 73 270
]
repeat x eight [
repeat y ten [
diamond (x * 25 + 71.5) (y * 22 + 87)
]
]
]
[
; the four quadrants representing two games (top and bottom halves)
page size page/width page/height
scorecard visitor 0 0
scorecard home 306 0
scorecard visitor 0 396
scorecard home 306 396
]
]
; locals
context [
arrow: grid: rectangle: label: diamond: none
; so our iterators won't think these are mm:
seven: 7
eight: 8
nine: 9
ten: 10
; we'll use this to track the offsets of the four segments
offset: 0x0
page: pts2mm [
width 612
height 792
]
lines: pts2mm [
regular 1.1
thick 2.2
thin 0.1
]
arrows: pts2mm [
up [top 6 bottom 1]
down [top 0 bottom 5]
]
labels: pts2mm [
width 50
height 12
medium 10
]
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.