Skip to content

Commit 2abbfa4

Browse files
Recognize stave ending with repeat-begin
by carrying over the repeat to the next stave.
1 parent d8ec981 commit 2abbfa4

File tree

6 files changed

+39
-16
lines changed

6 files changed

+39
-16
lines changed

examples/display-tests/src/Main.purs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ abcContext (Tuple x y) keySignature staveNo =
4040
, isNewTimeSignature : false
4141
, maxWidth : round $ (toNumber canvasWidth / scale)
4242
, pendingGraceKeys : []
43+
, pendingRepeatBegin: false
4344
}
4445

4546
-- | we give each test it's own stave. The downside is that subsequent staves

src/VexFlow/Abc/BarEnd.purs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
module VexFlow.Abc.BarEnd
22
( repositionBarEndRepeats
33
, fillStaveLine
4+
, staveEndsWithRepeatBegin
45
, staveWidth) where
56

67
-- | Routines to handle the disparity between the manner in which ABC descibes
@@ -11,7 +12,7 @@ module VexFlow.Abc.BarEnd
1112
-- | (only attached to the end barline).
1213

1314
import Prelude
14-
import Data.Maybe (Maybe(..))
15+
import Data.Maybe (Maybe(..), maybe)
1516
import Data.Array ((:), last, reverse, snoc)
1617
import Data.Foldable (foldM)
1718
import Control.Monad.State (State, evalState, get, put)
@@ -25,6 +26,7 @@ type BarState = State Boolean (Array BarSpec)
2526
-- | move any bar end repeat marker to the previous bar
2627
-- | i.e. a bar end should belong to the bar it ends not the next one
2728
-- | that it introduces.
29+
-- | remember we're processing the bars backwards
2830
shiftBarEnd :: Array BarSpec -> BarSpec -> BarState
2931
shiftBarEnd acc barSpec = do
3032
lastEndBar <- get
@@ -94,14 +96,21 @@ fillStaveLine maxWidth bs =
9496
Nothing ->
9597
bs
9698

99+
-- | does the stave end with a begin repeat marker?
100+
-- | (to be carried over to the next stave).
101+
staveEndsWithRepeatBegin :: Array BarSpec -> Boolean
102+
staveEndsWithRepeatBegin bs =
103+
let
104+
isBeginVolta b =
105+
((b.startLine.repeat == Just Begin) ||
106+
(b.startLine.repeat == Just BeginAndEnd))
107+
in
108+
maybe false isBeginVolta (last bs)
109+
97110
-- | the current width of the stave's Stave Bars
98111
staveWidth :: Array BarSpec -> Int
99112
staveWidth bs =
100-
case (last bs) of
101-
Just b ->
102-
b.xOffset + b.width
103-
Nothing ->
104-
0
113+
maybe 0 (\b -> b.xOffset + b.width) (last bs)
105114

106115
simpleBarType :: BarType
107116
simpleBarType =

src/VexFlow/Abc/TranslateStateful.purs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,15 @@ import Data.Newtype (unwrap)
2323
import Data.Array ((..), zip)
2424
import Data.Array (length) as Array
2525
import Data.Traversable (traverse)
26-
import Data.Abc (Bar, BodyPart(..), Music(..))
26+
import Data.Abc (Bar, BarType, BodyPart(..), Music(..), Repeat(..))
2727
import Data.Abc.Metadata (isEmptyStave)
2828
import VexFlow.Abc.Utils (applyContextChanges, nextStaveNo, updateAbcContext
2929
,beatsPerBeam, isEmptyMusicSpec)
3030
import VexFlow.Types (AbcContext, BarSpec, MusicSpec(..), StaveSpec
3131
,staveIndentation)
3232
import VexFlow.Abc.TickableContext (NoteCount, TickableContext(..), estimateBarWidth)
33-
import VexFlow.Abc.BarEnd (repositionBarEndRepeats, fillStaveLine, staveWidth)
33+
import VexFlow.Abc.BarEnd (repositionBarEndRepeats, fillStaveLine, staveWidth,
34+
staveEndsWithRepeatBegin)
3435
import VexFlow.Abc.Volta (startVolta, isMidVolta)
3536

3637
type Translation a = ExceptT String (State AbcContext) a
@@ -81,16 +82,15 @@ bodyPart bp =
8182
})
8283
-- then translate the bars
8384
staveBars <- bars staveNo bs
85+
-- reget the state after processing the bars
86+
abcContext' <- get
8487
let
85-
{-}
86-
-- find the overall width
87-
accumulatedStaveWidth = staveWidth staveBars
88-
-- fill the stave to the end with an empty staveline
89-
filledStaveLine = fillStaveLine abcContext.maxWidth $ repositionBarEndRepeats staveBars
90-
-}
88+
pendingRepeatBegin = staveEndsWithRepeatBegin staveBars
9189
normalisedStaveBars = repositionBarEndRepeats staveBars
9290
accumulatedStaveWidth = staveWidth normalisedStaveBars
9391
filledStaveLine = fillStaveLine abcContext.maxWidth normalisedStaveBars
92+
-- save to state whether we need to carry over a Begin Volta from the last stave
93+
_ <- put (abcContext' { pendingRepeatBegin = pendingRepeatBegin })
9494
-- return the stave specification
9595
pure $ Just { staveNo : staveNo
9696
, staveWidth : accumulatedStaveWidth
@@ -137,7 +137,7 @@ bar staveNumber barNumber abcBar =
137137
{ barNumber : barNumber
138138
, width : width
139139
, xOffset : abcContext.accumulatedStaveWidth
140-
, startLine : abcBar.startLine
140+
, startLine : modifiedStartLine abcContext.pendingRepeatBegin abcBar.startLine
141141
, hasEndLine : true
142142
, endLineRepeat : false
143143
, volta : startVolta abcBar.startLine isEmptyBar abcContext.isMidVolta
@@ -154,6 +154,7 @@ bar staveNumber barNumber abcBar =
154154
newAbcContext = abcContext { accumulatedStaveWidth = newWidth
155155
, isMidVolta = newIsMidVolta
156156
, isNewTimeSignature = false
157+
, pendingRepeatBegin = false
157158
}
158159
_ <- put newAbcContext
159160
withExceptT (\err -> err <> ": bar " <> show barNumber) $ pure barSpec
@@ -205,3 +206,12 @@ music tickablePosition noteIndex m =
205206
newContext = applyContextChanges abcContext spec
206207
_ <- put newContext {pendingGraceKeys = []}
207208
either throwError pure spec
209+
210+
-- | carry over any pending Repeat Begin marker that may have ended the last stave
211+
modifiedStartLine :: Boolean -> BarType -> BarType
212+
modifiedStartLine isPendingRepeatbegin barType =
213+
if isPendingRepeatbegin
214+
then
215+
barType { repeat = Just Begin }
216+
else
217+
barType

src/VexFlow/Abc/Utils.purs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ initialAbcContext tune config =
137137
, maxWidth : Int.round $
138138
(Int.toNumber (config.canvasWidth - staveIndentation)) / config.scale
139139
, pendingGraceKeys : []
140+
, pendingRepeatBegin : false
140141
}
141142

142143

src/VexFlow/Types.purs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ type AbcContext =
4646
, isMidVolta :: Boolean -- we've started but not finished a volta
4747
, isNewTimeSignature :: Boolean -- we need to display a changed time signature
4848
, maxWidth :: Int
49-
, pendingGraceKeys :: Array String -- grace notes to be apended to next note
49+
, pendingGraceKeys :: Array String -- grace notes to be appended to next note
50+
, pendingRepeatBegin :: Boolean -- begin repeat to be appended to next stave
5051
}
5152

5253
type NoteSpec =

test/Samples.purs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ startAbcContext (Tuple x y) =
2222
, isNewTimeSignature : false
2323
, maxWidth : 1200
2424
, pendingGraceKeys : []
25+
, pendingRepeatBegin: false
2526
}
2627

2728
c :: Int -> Music

0 commit comments

Comments
 (0)