Skip to content

Commit cc781eb

Browse files
committed
Add a new flexSelect primitive as a generalization of flexGroup
1 parent 9acf517 commit cc781eb

File tree

4 files changed

+71
-16
lines changed

4 files changed

+71
-16
lines changed

src/Dodo.purs

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ module Dodo
2020
, appendSpaceBreak
2121
, flexAlt
2222
, flexGroup
23+
, flexSelect
2324
, paragraph
2425
, textParagraph
2526
, enclose
@@ -72,11 +73,20 @@ annotate :: forall a. a -> Doc a -> Doc a
7273
annotate = notEmpty <<< Annotate
7374

7475
-- | Attempts to layout the document with flex alternatives, falling back
75-
-- | to defaults if they don't fit the page width.
76+
-- | to defaults if it doesn't fit the page width.
7677
flexGroup :: forall a. Doc a -> Doc a
7778
flexGroup = notEmpty case _ of
78-
doc@(FlexGroup _) -> doc
79-
doc -> FlexGroup doc
79+
doc@(FlexSelect _ a b) | isEmpty a && isEmpty b -> doc
80+
doc -> FlexSelect doc Empty Empty
81+
82+
-- | Attempts to layout the first document with flex alternatives, falling
83+
-- | back to defaults if it doesn't fit the page width. If the flex alternatives
84+
-- | are used then the second document will be appended, otherwise the third
85+
-- | document will be appended.
86+
flexSelect :: forall a. Doc a -> Doc a -> Doc a -> Doc a
87+
flexSelect doc1 doc2 doc3
88+
| isEmpty doc1 = doc2
89+
| otherwise = FlexSelect doc1 doc2 doc3
8090

8191
-- | Attempts to layout the first document when in a flex group, falling back
8292
-- | to the second as a default.
@@ -244,11 +254,11 @@ data DocCmd a
244254
= Doc (Doc a)
245255
| Dedent String Int
246256
| LeaveAnnotation a (List a)
247-
| LeaveFlexGroup
257+
| LeaveFlexGroup (Doc a) (Doc a)
248258

249259
data FlexGroupStatus b a
250260
= NoFlexGroup
251-
| FlexGroupOpen
261+
| FlexGroupPending
252262
| FlexGroupReset (FlexGroupState b a)
253263

254264
type FlexGroupState b a =
@@ -381,12 +391,12 @@ print (Printer printer) opts = flip go initState <<< pure <<< Doc
381391
{ position { nextIndent = state.position.nextIndent + width }
382392
, indentSpaces = state.indentSpaces <> power " " width
383393
}
384-
FlexGroup doc1 -> case state.flexGroup of
394+
FlexSelect doc1 doc2 doc3 -> case state.flexGroup of
385395
NoFlexGroup ->
386-
go (Doc doc1 : LeaveFlexGroup : stk) state
387-
{ flexGroup = FlexGroupOpen
396+
go (Doc doc1 : LeaveFlexGroup doc2 doc3 : stk) state
397+
{ flexGroup = FlexGroupPending
388398
}
389-
FlexGroupOpen | state.position.ribbonWidth > 0 ->
399+
FlexGroupPending | state.position.ribbonWidth > 0 ->
390400
go (Doc doc1 : stk) state
391401
{ flexGroup = FlexGroupReset $ storeState stack state
392402
, buffer = Buffer.branch state.buffer
@@ -396,7 +406,7 @@ print (Printer printer) opts = flip go initState <<< pure <<< Doc
396406
FlexAlt flexDoc doc1 -> case state.flexGroup of
397407
FlexGroupReset _ ->
398408
go (Doc flexDoc : stk) state
399-
FlexGroupOpen | state.position.ribbonWidth > 0 ->
409+
FlexGroupPending | state.position.ribbonWidth > 0 ->
400410
go (Doc flexDoc : stk) state
401411
{ flexGroup = FlexGroupReset $ storeState (Doc doc1 : stk) state
402412
, buffer = Buffer.branch state.buffer
@@ -415,11 +425,16 @@ print (Printer printer) opts = flip go initState <<< pure <<< Doc
415425
}
416426
Empty ->
417427
go stk state
418-
LeaveFlexGroup ->
419-
go stk state
420-
{ flexGroup = NoFlexGroup
421-
, buffer = Buffer.commit state.buffer
422-
}
428+
LeaveFlexGroup doc1 doc2 -> case state.flexGroup of
429+
NoFlexGroup ->
430+
go (Doc doc2 : stk) state
431+
{ buffer = Buffer.commit state.buffer
432+
}
433+
_ ->
434+
go (Doc doc1 : stk) state
435+
{ flexGroup = NoFlexGroup
436+
, buffer = Buffer.commit state.buffer
437+
}
423438
Dedent indSpaces ind ->
424439
go stk state
425440
{ position { nextIndent = ind }

src/Dodo/Internal.purs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ data Doc a
2020
| Indent (Doc a)
2121
| Align Int (Doc a)
2222
| Annotate a (Doc a)
23-
| FlexGroup (Doc a)
23+
| FlexSelect (Doc a) (Doc a) (Doc a)
2424
| FlexAlt (Doc a) (Doc a)
2525
| WithPosition (Position -> Doc a)
2626
| Text Int String

test/snapshots/DodoFlexSelect.output

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
hello true
2+
first
3+
hello false
4+
second
5+
hello whatever
6+
first
7+
hello whatever
8+
second

test/snapshots/DodoFlexSelect.purs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
module DodoFlexSelect where
2+
3+
import Prelude
4+
5+
import Dodo (Doc, break, flexAlt, flexSelect, fourSpaces, indent, plainText, print, text, words)
6+
import Effect (Effect)
7+
import Effect.Class.Console as Console
8+
9+
test1 :: forall a. Doc a
10+
test1 = words
11+
[ text "hello"
12+
, indent $ flexSelect
13+
(flexAlt (text "true") (text "false"))
14+
(break <> text "first")
15+
(break <> text "second")
16+
]
17+
18+
test2 :: forall a. Doc a
19+
test2 = words
20+
[ text "hello"
21+
, indent $ flexSelect
22+
(text "whatever")
23+
(break <> text "first")
24+
(break <> text "second")
25+
]
26+
27+
main :: Effect Unit
28+
main = do
29+
Console.log $ print plainText fourSpaces test1
30+
Console.log $ print plainText (fourSpaces { pageWidth = 1 }) test1
31+
Console.log $ print plainText fourSpaces test2
32+
Console.log $ print plainText (fourSpaces { pageWidth = 1 }) test2

0 commit comments

Comments
 (0)