Skip to content

Commit

Permalink
Fix position calculations
Browse files Browse the repository at this point in the history
  • Loading branch information
natefaubion committed Aug 22, 2020
1 parent 79ca83c commit ea2b4bd
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 43 deletions.
60 changes: 35 additions & 25 deletions src/Dodo.purs
Original file line number Diff line number Diff line change
Expand Up @@ -250,25 +250,27 @@ type FlexGroupState b a =
{ position :: Position
, buffer :: Buffer b
, annotations :: List a
, indent :: String
, indent :: Int
, indentSpaces :: String
, stack :: List (DocCmd a)
}

type DocState b a =
{ position :: Position
, buffer :: Buffer b
, annotations :: List a
, indent :: String
, indent :: Int
, indentSpaces :: String
, flexGroup :: Maybe (FlexGroupState b a)
}

resetState :: forall a b. FlexGroupState b a -> DocState b a
resetState { position, buffer, annotations, indent: indent' } =
{ position, buffer, annotations, indent: indent', flexGroup: Nothing }
resetState { position, buffer, annotations, indent: indent', indentSpaces } =
{ position, buffer, annotations, indent: indent', indentSpaces, flexGroup: Nothing }

storeState :: forall a b. List (DocCmd a) -> DocState b a -> FlexGroupState b a
storeState stack { position, buffer, annotations, indent: indent' } =
{ position, buffer, annotations, indent: indent', stack }
storeState stack { position, buffer, annotations, indent: indent', indentSpaces } =
{ position, buffer, annotations, indent: indent', indentSpaces, stack }

-- | Prints a documents given a printer and print options.
-- |
Expand Down Expand Up @@ -299,7 +301,8 @@ print (Printer printer) opts = flip go initState <<< pure <<< Doc
}
, buffer: Buffer.new printer.emptyBuffer
, annotations: List.Nil
, indent: ""
, indent: 0
, indentSpaces: ""
, flexGroup: Nothing
}

Expand All @@ -312,10 +315,10 @@ print (Printer printer) opts = flip go initState <<< pure <<< Doc
Append doc1 doc2 ->
go (Doc doc1 : Doc doc2 : stk) state
Text len str
| state.position.column == 0 && state.position.indent > 0 ->
| state.position.column == 0 && state.indent > 0 ->
go stack state
{ position { column = state.position.indent }
, buffer = Buffer.modify (printer.writeIndent state.position.indent state.indent) state.buffer
{ position { column = state.indent }
, buffer = Buffer.modify (printer.writeIndent state.indent state.indentSpaces) state.buffer
}
| otherwise -> do
let nextColumn = state.position.column + len
Expand All @@ -332,27 +335,29 @@ print (Printer printer) opts = flip go initState <<< pure <<< Doc
go frame.stack $ resetState frame
_ ->
go stk state
{ position { line = state.position.line + 1, column = 0 }
{ position
{ line = state.position.line + 1
, column = 0
, indent = state.indent
, ribbonWidth = calcRibbonWidth (opts.pageWidth - state.indent)
}
, buffer = Buffer.modify printer.writeBreak state.buffer
}
Indent doc1
| isJust state.flexGroup ->
go (Doc doc1 : stk) state
| otherwise ->
go (Doc doc1 : Dedent state.indent state.position.indent : stk) state
{ position
{ indent = state.position.indent + opts.indentWidth
, ribbonWidth = calcRibbonWidth (opts.pageWidth - state.position.indent)
}
, indent = state.indent <> opts.indentUnit
go (Doc doc1 : Dedent state.indentSpaces state.indent : stk) state
{ indent = state.indent + opts.indentWidth
, indentSpaces = state.indentSpaces <> opts.indentUnit
}
Align width doc1
| isJust state.flexGroup ->
go (Doc doc1 : stk) state
| otherwise ->
go (Doc doc1 : Dedent state.indent state.position.indent : stk) state
{ position { indent = state.position.indent + width }
, indent = state.indent <> power " " width
go (Doc doc1 : Dedent state.indentSpaces state.indent : stk) state
{ indent = state.indent + width
, indentSpaces = state.indentSpaces <> power " " width
}
FlexGroup doc1
-- We only track the first flex group. This is equivalent to
Expand All @@ -370,8 +375,13 @@ print (Printer printer) opts = flip go initState <<< pure <<< Doc
| otherwise ->
go (Doc doc1 : stk) state
WithPosition k
| state.position.column == 0 && state.position.indent > 0 -> do
let renderPosition = state.position { column = state.position.indent }
| state.position.column == 0 && state.indent > 0 -> do
let
renderPosition = state.position
{ column = state.indent
, indent = state.indent
, ribbonWidth = calcRibbonWidth (opts.pageWidth - state.indent)
}
go (Doc (k renderPosition) : stk) state
| otherwise ->
go (Doc (k state.position) : stk) state
Expand All @@ -387,10 +397,10 @@ print (Printer printer) opts = flip go initState <<< pure <<< Doc
{ flexGroup = Nothing
, buffer = Buffer.commit state.buffer
}
Dedent ind indWidth ->
Dedent indSpaces ind ->
go stk state
{ position { indent = indWidth }
, indent = ind
{ indent = ind
, indentSpaces = indSpaces
}
LeaveAnnotation ann anns ->
go stk state
Expand Down
39 changes: 21 additions & 18 deletions test/snapshots/DodoTextParagraph.output
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
* Quisque finibus tellus non molestie porta. In non posuere metus, vitae tincidunt enim. Nam quis elit pharetra, elementum elit lacinia, efficitur nibh. Cras
lobortis neque sed ante ornare rutrum. Maecenas sed urna nisl. Phasellus aliquam finibus ex vitae iaculis. Vestibulum ante ipsum primis in faucibus orci luctus
et ultrices posuere cubilia curae; Suspendisse eget tortor eget sapien tincidunt vestibulum eu a velit. Pellentesque eu tortor ut lectus sodales ornare.
lobortis neque sed ante ornare rutrum. Maecenas sed urna nisl. Phasellus aliquam finibus ex vitae iaculis. Vestibulum ante ipsum primis in faucibus orci
luctus et ultrices posuere cubilia curae; Suspendisse eget tortor eget sapien tincidunt vestibulum eu a velit. Pellentesque eu tortor ut lectus sodales
ornare.

* Quisque finibus tellus non molestie porta. In non posuere metus, vitae tincidunt
enim. Nam quis elit pharetra, elementum elit lacinia, efficitur nibh. Cras
lobortis neque sed ante ornare rutrum. Maecenas sed urna nisl. Phasellus aliquam
finibus ex vitae iaculis. Vestibulum ante ipsum primis in faucibus orci luctus
et ultrices posuere cubilia curae; Suspendisse eget tortor eget sapien tincidunt
vestibulum eu a velit. Pellentesque eu tortor ut lectus sodales ornare.
* Quisque finibus tellus non molestie porta. In non posuere metus, vitae
tincidunt enim. Nam quis elit pharetra, elementum elit lacinia, efficitur
nibh. Cras lobortis neque sed ante ornare rutrum. Maecenas sed urna nisl.
Phasellus aliquam finibus ex vitae iaculis. Vestibulum ante ipsum primis in
faucibus orci luctus et ultrices posuere cubilia curae; Suspendisse eget
tortor eget sapien tincidunt vestibulum eu a velit. Pellentesque eu tortor ut
lectus sodales ornare.

* Quisque finibus tellus non molestie
porta. In non posuere metus, vitae
tincidunt enim. Nam quis elit pharetra,
elementum elit lacinia, efficitur nibh.
Cras lobortis neque sed ante ornare
rutrum. Maecenas sed urna nisl.
Phasellus aliquam finibus ex vitae
iaculis. Vestibulum ante ipsum primis in
faucibus orci luctus et ultrices posuere
cubilia curae; Suspendisse eget tortor
eget sapien tincidunt vestibulum eu a
velit. Pellentesque eu tortor ut lectus
tincidunt enim. Nam quis elit
pharetra, elementum elit lacinia,
efficitur nibh. Cras lobortis neque
sed ante ornare rutrum. Maecenas sed
urna nisl. Phasellus aliquam finibus
ex vitae iaculis. Vestibulum ante
ipsum primis in faucibus orci luctus
et ultrices posuere cubilia curae;
Suspendisse eget tortor eget sapien
tincidunt vestibulum eu a velit.
Pellentesque eu tortor ut lectus
sodales ornare.

3 changes: 3 additions & 0 deletions test/snapshots/DodoWithPosition.output
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
abcedefg 0 9 0 40 80
abcedefg
1 5 5 3 10
27 changes: 27 additions & 0 deletions test/snapshots/DodoWithPosition.purs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module DodoWithPosition where

import Prelude

import Data.Foldable (intercalate)
import Dodo (Doc, align, paragraph, plainText, print, text, twoSpaces, withPosition)
import Effect (Effect)
import Effect.Class.Console as Console

test1 :: forall a. Doc a
test1 =
paragraph
[ text "abcedefg"
, align 5 $ withPosition \pos ->
text $ intercalate " "
[ show pos.line
, show pos.column
, show pos.indent
, show pos.ribbonWidth
, show pos.pageWidth
]
]

main :: Effect Unit
main = do
Console.log $ print plainText (twoSpaces { ribbonRatio = 0.5 }) test1
Console.log $ print plainText (twoSpaces { ribbonRatio = 0.5, pageWidth = 10 }) test1

0 comments on commit ea2b4bd

Please sign in to comment.