Skip to content
This repository was archived by the owner on Jun 15, 2023. It is now read-only.

Commit 49aface

Browse files
committed
Improve checkbox model (#66)
* checkbox: fix model & thence fix bizarre evaluation semantics * improve type class instances Added Ord instances all around so we don't need to compare through strings, which is horrid. * beautify * update test * remove no-longer-sensible validation
1 parent b5c40a4 commit 49aface

File tree

11 files changed

+175
-140
lines changed

11 files changed

+175
-140
lines changed

bower.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"purescript-parsing": "^0.8.0",
3131
"purescript-prelude": "^0.1.3",
3232
"purescript-strongcheck": "^0.14.4",
33-
"purescript-validation": "^0.2.1"
33+
"purescript-validation": "^0.2.1",
34+
"purescript-sets": "^0.5.7"
3435
}
3536
}

src/Text/Markdown/SlamDown/Eval.purs

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,10 @@ module Text.Markdown.SlamDown.Eval
44
) where
55

66
import Prelude
7-
import Control.Bind ((>=>))
87
import Control.Alt ((<|>))
98
import Data.Const (Const(..))
109
import Data.Identity (Identity(..), runIdentity)
1110
import Data.Functor.Compose (Compose(..), decompose)
12-
import Data.Foldable as F
1311
import Data.List as L
1412
import Data.Maybe as M
1513
import Data.String as S
@@ -64,23 +62,20 @@ eval fs = everywhereM b i
6462
f (SD.RadioButtons sel opts) = do
6563
sel' ← evalExpr fs.value sel
6664
opts' ← evalExpr fs.list opts
67-
pure $ SD.RadioButtons sel' (mergeSelection sel' opts')
65+
pure $ SD.RadioButtons sel' (mergeSelection (L.singleton <$> sel') opts')
6866

69-
f (SD.CheckBoxes checkeds vals) = do
67+
f (SD.CheckBoxes sel vals) = do
68+
sel' ← evalExpr fs.list sel
7069
vals' ← evalExpr fs.list vals
71-
checkeds' ← evalExpr (fs.list >=> \cs → pure $ map (_ `F.elem` cs) (getValues vals')) checkeds
72-
pure $ SD.CheckBoxes checkeds' vals'
70+
pure $ SD.CheckBoxes sel' (mergeSelection sel' vals')
7371

7472
f (SD.DropDown msel opts) = do
7573
msel' ← T.traverse (evalExpr fs.value) msel
7674
opts' ← evalExpr fs.list opts
77-
pure $ SD.DropDown msel' $ M.maybe opts' (flip mergeSelection opts') msel'
75+
pure $ SD.DropDown msel' $ M.maybe opts' (flip mergeSelection opts' <<< map L.singleton) msel'
7876

79-
mergeSelection SD.Expr a SD.Expr (L.List a) SD.Expr (L.List a)
80-
mergeSelection (SD.Literal x) (SD.Literal xs) =
81-
if F.elem x xs
82-
then SD.Literal xs
83-
else SD.Literal $ L.Cons x xs
77+
mergeSelection SD.Expr (L.List a) SD.Expr (L.List a) SD.Expr (L.List a)
78+
mergeSelection (SD.Literal sel) (SD.Literal xs) = SD.Literal $ L.union sel xs
8479
mergeSelection _ exs = exs
8580

8681
evalExpr e. (String m e) SD.Expr e m (SD.Expr e)

src/Text/Markdown/SlamDown/Parser/Inline.purs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,6 @@ validateFormField
9898
V.V (Array String) (SD.FormField a)
9999
validateFormField field =
100100
case field of
101-
SD.CheckBoxes (SD.Literal bs) (SD.Literal ls) | L.length bs /= L.length ls →
102-
V.invalid ["Invalid checkboxes"]
103101
SD.CheckBoxes (SD.Literal _) (SD.Unevaluated _) →
104102
V.invalid ["Checkbox values & selection must be both literals or both unevaluated expressions"]
105103
SD.CheckBoxes (SD.Unevaluated _) (SD.Literal _) →
@@ -333,7 +331,7 @@ inlines = L.many inline2 <* PS.eof
333331
PU.skipSpaces
334332
l ← item
335333
return $ Tuple b l
336-
return $ SD.CheckBoxes (SD.Literal (map fst ls)) (SD.Literal (map snd ls))
334+
return $ SD.CheckBoxes (SD.Literal $ snd <$> L.filter fst ls) (SD.Literal $ snd <$> ls)
337335

338336
evaluatedCheckBoxes =
339337
SD.CheckBoxes

src/Text/Markdown/SlamDown/Pretty.purs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ module Text.Markdown.SlamDown.Pretty
66
import Prelude
77

88
import Data.Array as A
9-
import Data.Foldable (fold)
9+
import Data.Foldable (fold, elem)
1010
import Data.Identity (Identity(..))
1111
import Data.Functor.Compose (Compose(), decompose)
1212
import Data.HugeNum as HN
@@ -183,11 +183,11 @@ prettyPrintFormElement el =
183183
S.joinWith " " $ L.fromList (map radioButton ls)
184184
SD.RadioButtons (SD.Unevaluated bs) (SD.Unevaluated ls) →
185185
"(!`" <> bs <> "`) !`" <> ls <> "`"
186-
SD.CheckBoxes (SD.Literal bs) (SD.Literal ls) →
186+
SD.CheckBoxes (SD.Literal sel) (SD.Literal ls) →
187187
let
188-
checkBox b l = (if b then "[x] " else "[] ") <> SD.renderValue l
188+
checkBox l = (if elem l sel then "[x] " else "[] ") <> SD.renderValue l
189189
in
190-
S.joinWith " " $ L.fromList (L.zipWith checkBox bs ls)
190+
S.joinWith " " <<< L.fromList $ checkBox <$> ls
191191
SD.CheckBoxes (SD.Unevaluated bs) (SD.Unevaluated ls) →
192192
"[!`" <> bs <> "`] !`" <> ls <> "`"
193193
SD.DropDown sel lbls →

src/Text/Markdown/SlamDown/Syntax.purs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ module Text.Markdown.SlamDown.Syntax
99

1010
import Prelude
1111

12-
import Data.Function (on)
1312
import Data.List as L
1413
import Data.Monoid (class Monoid, mempty)
1514
import Test.StrongCheck as SC
@@ -30,12 +29,8 @@ instance functorSlamDownP ∷ Functor SlamDownP where
3029
instance showSlamDownP ∷ (Show a) Show (SlamDownP a) where
3130
show (SlamDown bs) = "(SlamDown " ++ show bs ++ ")"
3231

33-
instance eqSlamDownP ∷ (Eq a) Eq (SlamDownP a) where
34-
eq (SlamDown bs1) (SlamDown bs2) = bs1 == bs2
35-
36-
-- TODO: replace this with a proper `Ord` instance.
37-
instance ordSlamDownP ∷ (Show a, Eq a) Ord (SlamDownP a) where
38-
compare = compare `on` show
32+
derive instance eqSlamDownP ∷ (Eq a, Ord a) Eq (SlamDownP a)
33+
derive instance ordSlamDownP ∷ (Eq a, Ord a) Ord (SlamDownP a)
3934

4035
instance semigroupSlamDownPSemigroup (SlamDownP a) where
4136
append (SlamDown bs1) (SlamDown bs2) = SlamDown (bs1 <> bs2)
@@ -45,4 +40,3 @@ instance monoidSlamDownP ∷ Monoid (SlamDownP a) where
4540

4641
instance arbitrarySlamDownP ∷ (SC.Arbitrary a, Eq a) SC.Arbitrary (SlamDownP a) where
4742
arbitrary = SlamDown <<< L.toList <$> Gen.arrayOf SC.arbitrary
48-

src/Text/Markdown/SlamDown/Syntax/Block.purs

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,8 @@ instance showBlock ∷ (Show a) ⇒ Show (Block a) where
4040
show (LinkReference l uri) = "(LinkReference " ++ show l ++ " " ++ show uri ++ ")"
4141
show Rule = "Rule"
4242

43-
instance eqBlock ∷ (Eq a) Eq (Block a) where
44-
eq (Paragraph is1) (Paragraph is2) = is1 == is2
45-
eq (Header n1 is1) (Header n2 is2) = n1 == n2 && is1 == is2
46-
eq (Blockquote bs1) (Blockquote bs2) = bs1 == bs2
47-
eq (Lst ty1 bss1) (Lst ty2 bss2) = ty1 == ty2 && bss1 == bss2
48-
eq (CodeBlock ty1 ss1) (CodeBlock ty2 ss2) = ty1 == ty2 && ss1 == ss2
49-
eq (LinkReference l1 uri1) (LinkReference l2 uri2) = l1 == l2 && uri1 == uri2
50-
eq Rule Rule = true
51-
eq _ _ = false
43+
derive instance eqBlock ∷ (Eq a, Ord a) Eq (Block a)
44+
derive instance ordBlock ∷ (Ord a) Ord (Block a)
5245

5346
-- | Nota bene: this does not generate any recursive structure
5447
instance arbitraryBlock ∷ (SC.Arbitrary a, Eq a) SC.Arbitrary (Block a) where
@@ -74,10 +67,8 @@ instance showListType ∷ Show ListType where
7467
show (Bullet s) = "(Bullet " ++ show s ++ ")"
7568
show (Ordered s) = "(Ordered " ++ show s ++ ")"
7669

77-
instance eqListTypeEq ListType where
78-
eq (Bullet s1) (Bullet s2) = s1 == s2
79-
eq (Ordered s1) (Ordered s2) = s1 == s2
80-
eq _ _ = false
70+
derive instance eqListTypeEq ListType
71+
derive instance ordListTypeOrd ListType
8172

8273
instance arbitraryListTypeSC.Arbitrary ListType where
8374
arbitrary = do
@@ -92,13 +83,10 @@ instance showCodeBlockType ∷ Show CodeBlockType where
9283
show Indented = "Indented"
9384
show (Fenced evaluated info) = "(Fenced " ++ show evaluated ++ " " ++ show info ++ ")"
9485

95-
instance eqCodeBlockTypeEq CodeBlockType where
96-
eq Indented Indented = true
97-
eq (Fenced b1 s1) (Fenced b2 s2) = b1 == b2 && s1 == s2
98-
eq _ _ = false
86+
derive instance eqCodeBlockTypeEq CodeBlockType
87+
derive instance ordCodeBlockTypeOrd CodeBlockType
9988

10089
instance arbitraryCodeBlockTypeSC.Arbitrary CodeBlockType where
10190
arbitrary = do
10291
b ← SC.arbitrary
10392
if b then pure Indented else Fenced <$> SC.arbitrary <*> SC.arbitrary
104-

0 commit comments

Comments
 (0)