Skip to content

Commit 4661462

Browse files
authored
Ch12 canvas anchors and misc cleanup (#251)
* Note on no tests and no intro for next chapter * Add anchors * move LSystem code outside of let block where possible * Remove outdated references to Async chapter * Remove intented anchors in script too * Check helper scripts in CI Make sure anchor removal script always works and doesn't break tests. Also check solution reset script. * Build book before testing anchor removal
1 parent 85504e2 commit 4661462

File tree

10 files changed

+109
-121
lines changed

10 files changed

+109
-121
lines changed

.travis.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,15 @@ script:
1515
- travis_fold end "test"
1616
- ./mdbook build
1717
- cp CNAME book/
18+
- travis_fold start "remove anchors"
19+
- ./scripts/removeAnchors.sh
20+
- travis_fold end "remove anchors"
21+
- travis_fold start "test again"
22+
- ./scripts/testAll.sh
23+
- travis_fold end "test again"
24+
- travis_fold start "reset solutions"
25+
- ./scripts/resetSolutions.sh
26+
- travis_fold end "reset solutions"
1827
before_deploy:
1928
openssl aes-256-cbc -K $encrypted_189e52c2c347_key -iv $encrypted_189e52c2c347_iv -in deploy_key.enc -out deploy_key -d
2029
deploy:

exercises/chapter12/src/Example/LSystem.purs

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,54 +10,84 @@ import Graphics.Canvas (strokePath, setStrokeStyle, lineTo, moveTo,
1010
import Math as Math
1111
import Partial.Unsafe (unsafePartial)
1212

13-
lsystem :: forall a m s. Monad m =>
14-
Array a ->
15-
(a -> Array a) ->
16-
(s -> a -> m s) ->
17-
Int ->
18-
s -> m s
13+
-- ANCHOR: lsystem_anno
14+
lsystem :: forall a m s
15+
. Monad m
16+
=> Array a
17+
-> (a -> Array a)
18+
-> (s -> a -> m s)
19+
-> Int
20+
-> s
21+
-> m s
22+
-- ANCHOR_END: lsystem_anno
23+
-- ANCHOR: lsystem_impl
1924
lsystem init prod interpret n state = go init n
2025
where
26+
-- ANCHOR_END: lsystem_impl
27+
-- ANCHOR: lsystem_go_s_0
2128
go s 0 = foldM interpret state s
22-
go s m = go (concatMap prod s) (m - 1)
29+
-- ANCHOR_END: lsystem_go_s_0
30+
-- ANCHOR: lsystem_go_s_i
31+
go s i = go (concatMap prod s) (i - 1)
32+
-- ANCHOR_END: lsystem_go_s_i
2333

34+
-- ANCHOR: letter
2435
data Letter = L | R | F
36+
-- ANCHOR_END: letter
2537

38+
-- ANCHOR: sentence
2639
type Sentence = Array Letter
40+
-- ANCHOR_END: sentence
2741

42+
-- ANCHOR: state
2843
type State =
2944
{ x :: Number
3045
, y :: Number
3146
, theta :: Number
3247
}
48+
-- ANCHOR_END: state
49+
50+
-- ANCHOR: initial
51+
initial :: Sentence
52+
initial = [F, R, R, F, R, R, F, R, R]
53+
-- ANCHOR_END: initial
54+
55+
-- ANCHOR: productions
56+
productions :: Letter -> Sentence
57+
productions L = [L]
58+
productions R = [R]
59+
productions F = [F, L, F, R, R, F, L, F]
60+
-- ANCHOR_END: productions
61+
62+
-- ANCHOR: initialState
63+
initialState :: State
64+
initialState = { x: 120.0, y: 200.0, theta: 0.0 }
65+
-- ANCHOR_END: initialState
3366

3467
main :: Effect Unit
3568
main = void $ unsafePartial do
3669
Just canvas <- getCanvasElementById "canvas"
3770
ctx <- getContext2D canvas
3871

3972
let
40-
initial :: Sentence
41-
initial = [F, R, R, F, R, R, F, R, R]
42-
43-
productions :: Letter -> Sentence
44-
productions L = [L]
45-
productions R = [R]
46-
productions F = [F, L, F, R, R, F, L, F]
47-
73+
-- ANCHOR: interpret_anno
4874
interpret :: State -> Letter -> Effect State
75+
-- ANCHOR_END: interpret_anno
76+
-- ANCHOR: interpretLR
4977
interpret state L = pure $ state { theta = state.theta - Math.tau / 6.0 }
5078
interpret state R = pure $ state { theta = state.theta + Math.tau / 6.0 }
79+
-- ANCHOR_END: interpretLR
80+
-- ANCHOR: interpretF
5181
interpret state F = do
5282
let x = state.x + Math.cos state.theta * 1.5
5383
y = state.y + Math.sin state.theta * 1.5
5484
moveTo ctx state.x state.y
5585
lineTo ctx x y
5686
pure { x, y, theta: state.theta }
57-
58-
initialState :: State
59-
initialState = { x: 120.0, y: 200.0, theta: 0.0 }
87+
-- ANCHOR_END: interpretF
6088

6189
setStrokeStyle ctx "#000"
6290

91+
-- ANCHOR: strokePath
6392
strokePath ctx $ lsystem initial productions interpret 5 initialState
93+
-- ANCHOR_END: strokePath

exercises/chapter12/src/Example/Random.purs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,21 @@ main = void $ unsafePartial do
1717
Just canvas <- getCanvasElementById "canvas"
1818
ctx <- getContext2D canvas
1919

20+
-- ANCHOR: style
2021
setFillStyle ctx "#F00"
2122
setStrokeStyle ctx "#000"
23+
-- ANCHOR_END: style
2224

25+
-- ANCHOR: for
2326
for_ (1 .. 100) \_ -> do
27+
-- ANCHOR_END: for
28+
-- ANCHOR: random
2429
x <- random
2530
y <- random
2631
r <- random
32+
-- ANCHOR_END: random
2733

34+
-- ANCHOR: path
2835
let path = arc ctx
2936
{ x : x * 600.0
3037
, y : y * 600.0
@@ -35,3 +42,4 @@ main = void $ unsafePartial do
3542

3643
fillPath ctx path
3744
strokePath ctx path
45+
-- ANCHOR_END: path

exercises/chapter12/src/Example/Rectangle.purs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,22 @@ import Graphics.Canvas (rect, fillPath, setFillStyle, getContext2D,
88
getCanvasElementById)
99
import Partial.Unsafe (unsafePartial)
1010

11+
-- ANCHOR: main
1112
main :: Effect Unit
1213
main = void $ unsafePartial do
1314
Just canvas <- getCanvasElementById "canvas"
1415
ctx <- getContext2D canvas
16+
-- ANCHOR_END: main
1517

18+
-- ANCHOR: setFillStyle
1619
setFillStyle ctx "#00F"
20+
-- ANCHOR_END: setFillStyle
1721

22+
-- ANCHOR: fillPath
1823
fillPath ctx $ rect ctx
1924
{ x: 250.0
2025
, y: 250.0
2126
, width: 100.0
2227
, height: 100.0
2328
}
29+
-- ANCHOR_END: fillPath

exercises/chapter12/src/Example/Refs.purs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ render ctx count = void do
2828

2929
setFillStyle ctx "#0F0"
3030

31+
-- ANCHOR: withContext
3132
withContext ctx do
3233
let scaleX = Math.sin (toNumber count * Math.tau / 8.0) + 1.5
3334
let scaleY = Math.sin (toNumber count * Math.tau / 12.0) + 1.5
@@ -43,18 +44,23 @@ render ctx count = void do
4344
, width: 200.0
4445
, height: 200.0
4546
}
47+
-- ANCHOR_END: withContext
4648

4749
main :: Effect Unit
4850
main = void $ unsafePartial do
4951
Just canvas <- getCanvasElementById "canvas"
5052
ctx <- getContext2D canvas
5153

54+
-- ANCHOR: clickCount
5255
clickCount <- Ref.new 0
56+
-- ANCHOR_END: clickCount
5357

5458
render ctx 0
5559

5660
node <- querySelector "#canvas"
5761
for_ node $ addEventListener "click" $ void do
5862
logShow "Mouse clicked!"
63+
-- ANCHOR: count
5964
count <- Ref.modify (\count -> count + 1) clickCount
65+
-- ANCHOR_END: count
6066
render ctx count

exercises/chapter12/src/Example/Shapes.purs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import Graphics.Canvas (closePath, lineTo, moveTo, fillPath,
1010
import Math as Math
1111
import Partial.Unsafe (unsafePartial)
1212

13+
-- ANCHOR: translate
1314
translate
1415
:: forall r
1516
. Number
@@ -20,6 +21,7 @@ translate dx dy shape = shape
2021
{ x = shape.x + dx
2122
, y = shape.y + dy
2223
}
24+
-- ANCHOR_END: translate
2325

2426
main :: Effect Unit
2527
main = void $ unsafePartial do
@@ -45,10 +47,12 @@ main = void $ unsafePartial do
4547
, end: Math.tau * 2.0 / 3.0
4648
}
4749

50+
-- ANCHOR: path
4851
setFillStyle ctx "#F00"
4952

5053
fillPath ctx $ do
5154
moveTo ctx 300.0 260.0
5255
lineTo ctx 260.0 340.0
5356
lineTo ctx 340.0 340.0
5457
closePath ctx
58+
-- ANCHOR_END: path

scripts/removeAnchors.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ ALL_PURS=$(find exercises \( ! -regex '.*/\..*' \) -type f -name '*.purs')
77

88
for f in $ALL_PURS; do
99
# Delete lines starting with an '-- ANCHOR' comment
10-
perl -ni -e 'print if !/^-- ANCHOR/' $f
10+
perl -ni -e 'print if !/^\s*-- ANCHOR/' $f
1111
done

text/chapter11.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1022,4 +1022,3 @@ We have seen how monad transformers allow us to write safe code in an imperative
10221022

10231023
Monad transformers are an excellent demonstration of the sort of expressive code that can be written by relying on advanced type system features such as higher-kinded polymorphism and multi-parameter type classes.
10241024

1025-
In the next chapter, we will see how monad transformers can be used to give an elegant solution to a common complaint when working with asynchronous JavaScript code - the problem of _callback hell_.

0 commit comments

Comments
 (0)