1use super::{Stream, StreamElement, StreamEvent, StreamKind};
4use crate::bar::{Barline, BarlineType, RepeatDirection};
5use crate::defaults::{FloatType, IntegerType};
6use crate::error::{Error, Result};
7use crate::repeat::RepeatExpressionKind;
8
9impl Stream {
10 pub fn expand_repeats(&self) -> Result<Stream> {
56 if self.kind == StreamKind::Score || self.kind == StreamKind::Opus {
57 let mut expanded = Vec::new();
58 let mut moved: Vec<Option<usize>> = Vec::new();
60 let mut new_count = 0;
61 for event in &self.events {
62 match &event.element {
63 StreamElement::Stream(part)
64 if matches!(part.kind, StreamKind::Part | StreamKind::PartStaff) =>
65 {
66 let (played, part_moved) = part.expand_part()?;
67 let first = new_count;
68 moved.extend(
69 part_moved
70 .into_iter()
71 .map(|place| place.map(|place| place + first)),
72 );
73 new_count += played.leaves().len();
74 expanded.push(StreamEvent::new(
75 event.offset,
76 StreamElement::Stream(Box::new(played)),
77 ));
78 }
79 element => {
80 let count = match element {
81 StreamElement::Stream(inner) => inner.leaves().len(),
82 _ => 1,
83 };
84 moved.extend((new_count..new_count + count).map(Some));
85 new_count += count;
86 expanded.push(StreamEvent::new(event.offset, element.clone()));
87 }
88 }
89 }
90 let mut score = self.with_events(expanded);
91 score.labels.spanners = self.labels.spanners.clone();
92 for spanner in &mut score.labels.spanners {
93 spanner.move_places(&moved);
94 }
95 return Ok(score);
96 }
97 self.expand_part().map(|(played, _)| played)
98 }
99
100 fn expand_part(&self) -> Result<(Stream, Vec<Option<usize>>)> {
103 let measures: Vec<(FloatType, &Stream)> = self
104 .events
105 .iter()
106 .filter_map(|event| match &event.element {
107 StreamElement::Stream(inner) if inner.kind == StreamKind::Measure => {
108 Some((event.offset, inner.as_ref()))
109 }
110 _ => None,
111 })
112 .collect();
113 if measures.is_empty() {
114 return Err(Error::Stream(
115 "cannot process repeats on Stream that does not contain measures".to_string(),
116 ));
117 }
118 let expander = Expander::from_measures(measures.iter().map(|(_, measure)| *measure));
119 let Some(played) = expander.process()? else {
121 return Ok((self.clone(), (0..self.leaves().len()).map(Some).collect()));
122 };
123
124 let mut first_leaf: Vec<usize> = Vec::new();
127 let mut loose: Vec<(StreamEvent, usize)> = Vec::new();
128 let mut seen = 0;
129 for event in &self.events {
130 match &event.element {
131 StreamElement::Stream(inner) => {
132 if inner.kind == StreamKind::Measure {
133 first_leaf.push(seen);
134 } else {
135 loose.push((event.clone(), seen));
136 }
137 seen += inner.leaves().len();
138 }
139 _ => {
140 loose.push((event.clone(), seen));
141 seen += 1;
142 }
143 }
144 }
145
146 let mut held: Vec<(StreamEvent, Origin)> = Vec::new();
150 let mut end: FloatType = 0.0;
151 for working in played {
152 let length = working
153 .appended_length
154 .unwrap_or_else(|| working.measure.end_offset());
155 let at = end;
156 let origin = Origin::Measure {
157 source: working.source,
158 stripped: working.stripped,
159 };
160 held.push((
161 StreamEvent::new(at, StreamElement::Stream(Box::new(working.measure))),
162 origin,
163 ));
164 end = end.max(crate::makenotation::op_frac(at + length));
165 }
166 held.extend(
167 loose
168 .into_iter()
169 .map(|(event, place)| (event, Origin::Loose(place))),
170 );
171 held.sort_by(|left, right| crate::makenotation::event_order(&left.0, &right.0));
172
173 let mut moved: Vec<Option<usize>> = vec![None; seen];
174 let mut placed = 0;
175 for (event, origin) in &held {
176 match origin {
177 Origin::Loose(place) => {
178 let count = match event.element() {
179 StreamElement::Stream(inner) => inner.leaves().len(),
180 _ => 1,
181 };
182 for leaf in 0..count {
183 moved[place + leaf] = Some(placed + leaf);
184 }
185 placed += count;
186 }
187 Origin::Measure { source, stripped } => {
188 let source_measure = measures[*source].1;
189 for (index, (top, _, element)) in
190 source_measure.leaves_under_top().into_iter().enumerate()
191 {
192 let gone = *stripped
195 && matches!(element, StreamElement::RepeatExpression(_))
196 && !matches!(
197 source_measure.events[top].element,
198 StreamElement::Stream(_)
199 );
200 if gone {
201 continue;
202 }
203 let old = first_leaf[*source] + index;
204 if moved[old].is_none() {
205 moved[old] = Some(placed);
206 }
207 placed += 1;
208 }
209 }
210 }
211 }
212 let mut part =
213 self.with_events(held.into_iter().map(|(event, _)| event).collect::<Vec<_>>());
214 part.labels.spanners = self.labels.spanners.clone();
215 for spanner in &mut part.labels.spanners {
216 spanner.move_places(&moved);
217 }
218 Ok((part, moved))
219 }
220}
221
222enum Origin {
224 Measure { source: usize, stripped: bool },
225 Loose(usize),
226}
227
228#[derive(Clone, Debug)]
232struct Working {
233 measure: Stream,
234 original: Option<usize>,
235 source: usize,
237 stripped: bool,
239 appended_length: Option<FloatType>,
243}
244
245impl Working {
246 fn of(measure: &Stream, index: usize) -> Self {
248 Self {
249 measure: measure.clone(),
250 original: Some(index),
251 source: index,
252 stripped: false,
253 appended_length: None,
254 }
255 }
256
257 fn copy(&self) -> Self {
259 Self {
260 original: None,
261 ..self.clone()
262 }
263 }
264
265 fn left_repeat(&self) -> Option<RepeatDirection> {
266 self.measure
267 .left_barline()
268 .and_then(Barline::repeat_direction)
269 }
270
271 fn right_repeat(&self) -> Option<RepeatDirection> {
272 self.measure
273 .right_barline()
274 .and_then(Barline::repeat_direction)
275 }
276
277 fn strip_repeat_barlines(&mut self) {
279 if self.left_repeat().is_some() {
280 self.measure
281 .set_left_barline(Some(Barline::new(BarlineType::Double)));
282 }
283 if self.right_repeat().is_some() {
284 self.measure
285 .set_right_barline(Some(Barline::new(BarlineType::Double)));
286 }
287 }
288
289 fn strip_repeat_expressions(&mut self) {
291 let events: Vec<StreamEvent> = self
292 .measure
293 .events
294 .iter()
295 .filter(|event| !matches!(event.element, StreamElement::RepeatExpression(_)))
296 .cloned()
297 .collect();
298 let spanners = self.measure.labels.spanners.clone();
299 self.measure = self.measure.with_events(events);
300 self.measure.labels.spanners = spanners;
301 self.stripped = true;
302 }
303
304 fn expressions(&self) -> Vec<RepeatExpressionKind> {
306 self.measure
307 .events
308 .iter()
309 .filter_map(|event| match &event.element {
310 StreamElement::RepeatExpression(expression) => Some(expression.kind()),
311 _ => None,
312 })
313 .collect()
314 }
315}
316
317#[derive(Clone, Debug)]
319struct Bracket {
320 numbers: Vec<u32>,
321 measures: Vec<usize>,
322}
323
324impl Bracket {
325 fn is_first(&self, working: &Working) -> bool {
326 working.original.is_some() && working.original == self.measures.first().copied()
327 }
328
329 fn is_last(&self, working: &Working) -> bool {
330 working.original.is_some() && working.original == self.measures.last().copied()
331 }
332
333 fn spans(&self, working: &Working) -> bool {
334 working
335 .original
336 .is_some_and(|original| self.measures.contains(&original))
337 }
338}
339
340#[derive(Clone, Debug, Default)]
343struct Group {
344 brackets: Vec<usize>,
345 indices: Vec<usize>,
346}
347
348#[derive(Clone, Debug)]
378pub struct Expander {
379 source: Vec<Working>,
380 brackets: Vec<Bracket>,
381 counts: std::collections::HashMap<RepeatExpressionKind, usize>,
382}
383
384#[derive(Clone, Copy, Debug, PartialEq, Eq)]
386enum Jump {
387 DaCapo,
388 Segno,
389}
390
391impl Expander {
392 pub fn new(part: &Stream) -> Result<Self> {
395 let measures = part.measures();
396 if measures.is_empty() {
397 return Err(Error::Stream(
398 "no measures found in the source stream to be expanded".to_string(),
399 ));
400 }
401 Ok(Self::from_measures(measures))
402 }
403
404 fn from_measures<'a>(measures: impl IntoIterator<Item = &'a Stream>) -> Self {
405 let source: Vec<Working> = measures
406 .into_iter()
407 .enumerate()
408 .map(|(index, measure)| Working::of(measure, index))
409 .collect();
410 let mut brackets: Vec<Bracket> = Vec::new();
414 let mut open = false;
415 for (index, working) in source.iter().enumerate() {
416 let Some(ending) = working.measure.ending() else {
417 continue;
418 };
419 match brackets.last_mut() {
420 Some(bracket) if open && !ending.starts() => bracket.measures.push(index),
421 _ => brackets.push(Bracket {
422 numbers: ending.numbers().to_vec(),
423 measures: vec![index],
424 }),
425 }
426 open = !ending.stops();
427 }
428 let mut counts = std::collections::HashMap::new();
429 for working in &source {
430 for (_, element) in working.measure.leaves() {
431 if let StreamElement::RepeatExpression(expression) = element {
432 *counts.entry(expression.kind()).or_insert(0) += 1;
433 }
434 }
435 }
436 Self {
437 source,
438 brackets,
439 counts,
440 }
441 }
442
443 fn count(&self, kind: RepeatExpressionKind) -> usize {
444 self.counts.get(&kind).copied().unwrap_or(0)
445 }
446
447 fn process(&self) -> Result<Option<Vec<Working>>> {
450 match self.is_expandable()? {
451 Some(false) => Err(Error::Stream(
452 "cannot expand Stream: badly formed repeats or repeat expressions".to_string(),
453 )),
454 None => Ok(None),
455 Some(true) => match self.da_capo_or_segno() {
456 None => self
457 .process_recursive_repeat_bars(self.source.clone())
458 .map(Some),
459 Some(jump) => self
460 .process_repeat_expression_and_repeats(self.source.clone(), jump)
461 .map(Some),
462 },
463 }
464 }
465
466 fn played_measures(&self) -> Result<Vec<Working>> {
469 Ok(self.process()?.unwrap_or_else(|| self.source.clone()))
470 }
471
472 pub fn measure_map(&self) -> Result<Vec<usize>> {
480 let mut with_suffix = std::collections::HashMap::new();
481 let mut without = std::collections::HashMap::new();
482 for (index, working) in self.source.iter().enumerate() {
483 with_suffix.insert(working.measure.number_with_suffix(), index);
484 without.insert(working.measure.number(), index);
485 }
486 self.played_measures()?
487 .iter()
488 .map(|working| {
489 let measure = &working.measure;
490 with_suffix
491 .get(&measure.number_with_suffix())
492 .or_else(|| without.get(&measure.number()))
493 .copied()
494 .ok_or_else(|| {
495 Error::Stream(format!(
496 "no measure {} in the source stream",
497 measure.number()
498 ))
499 })
500 })
501 .collect()
502 }
503
504 pub fn measure_map_numbers(&self) -> Result<Vec<String>> {
507 Ok(self
508 .played_measures()?
509 .iter()
510 .map(|working| working.measure.number_with_suffix())
511 .collect())
512 }
513
514 pub fn find_innermost_repeat_indices(measures: &Stream) -> Vec<usize> {
519 Self::innermost_of(&Self::measures_of(measures))
520 }
521
522 pub fn process_innermost_repeat_bars(
534 measures: &Stream,
535 repeat_indices: Option<&[usize]>,
536 repeat_times: Option<u32>,
537 expansion_only: bool,
538 ) -> Result<Stream> {
539 let mut source = Self::measures_of(measures);
540 let played =
541 Self::play_innermost(&mut source, repeat_indices, repeat_times, expansion_only)?;
542
543 let mut out = Stream::with_kind(measures.kind());
544 let mut end: FloatType = 0.0;
545 for working in played {
546 let length = working.measure.end_offset();
547 out.insert(end, working.measure);
548 end = crate::makenotation::op_frac(end + length);
549 }
550 Ok(out)
551 }
552
553 pub fn repeat_expression_index(measures: &Stream, kind: RepeatExpressionKind) -> Vec<usize> {
557 Self::measures_of(measures)
558 .iter()
559 .enumerate()
560 .flat_map(|(index, working)| {
561 working
562 .expressions()
563 .into_iter()
564 .filter(move |found| *found == kind)
565 .map(move |_| index)
566 })
567 .collect()
568 }
569
570 fn measures_of(measures: &Stream) -> Vec<Working> {
572 measures
573 .measures()
574 .into_iter()
575 .enumerate()
576 .map(|(index, measure)| Working::of(measure, index))
577 .collect()
578 }
579
580 fn da_capo_or_segno(&self) -> Option<Jump> {
581 use RepeatExpressionKind::*;
582 let da_capo = self.count(DaCapo) + self.count(DaCapoAlFine) + self.count(DaCapoAlCoda);
583 let segno = self.count(DalSegno)
584 + self.count(DalSegnoAlCoda)
585 + self.count(DalSegnoAlFine)
586 + self.count(AlSegno);
587 match (da_capo, segno) {
588 (1, 0) => Some(Jump::DaCapo),
589 (0, 1) => Some(Jump::Segno),
590 _ => None,
591 }
592 }
593
594 pub fn is_expandable(&self) -> Result<Option<bool>> {
600 let jump = self.da_capo_or_segno();
601 if jump.is_none() && !has_repeat(&self.source) {
602 return Ok(None);
603 }
604 if !self.repeat_bars_are_coherent()? || !self.repeat_brackets_are_coherent() {
605 return Ok(Some(false));
606 }
607 Ok(Some(match jump {
608 Some(Jump::DaCapo) => self.da_capo_is_coherent(),
609 Some(Jump::Segno) => self.dal_segno_is_coherent(),
610 None => true,
611 }))
612 }
613
614 pub fn repeat_bars_are_coherent(&self) -> Result<bool> {
619 let (mut starts, mut ends, mut balance) = (0, 0, 0);
620 for working in &self.source {
621 match working.left_repeat() {
622 Some(RepeatDirection::Start) => {
623 starts += 1;
624 balance += 1;
625 }
626 Some(RepeatDirection::End) => {
627 if balance == 0 {
628 starts += 1;
629 balance += 1;
630 }
631 ends += 1;
632 balance -= 1;
633 }
634 None => {}
635 }
636 match working.right_repeat() {
637 Some(RepeatDirection::End) => {
638 if balance == 0 {
639 starts += 1;
640 balance += 1;
641 }
642 ends += 1;
643 balance -= 1;
644 }
645 Some(RepeatDirection::Start) => {
646 return Err(Error::Stream(format!(
647 "a right barline is found that cannot be processed: measure {}",
648 working.measure.number_with_suffix()
649 )));
650 }
651 None => {}
652 }
653 }
654 Ok(matches!(balance, 0 | 1) && (starts == ends || starts + 1 == ends))
655 }
656
657 fn da_capo_is_coherent(&self) -> bool {
658 use RepeatExpressionKind::*;
659 let total = self.count(DaCapo) + self.count(DaCapoAlFine) + self.count(DaCapoAlCoda);
660 if total > 1 {
661 return false;
662 }
663 (self.count(DaCapo) == 1 && self.count(Coda) == 0)
664 || (self.count(DaCapoAlFine) == 1 && self.count(Fine) == 1)
665 || (self.count(DaCapoAlCoda) == 1 && self.count(Coda) == 2)
666 }
667
668 fn dal_segno_is_coherent(&self) -> bool {
669 use RepeatExpressionKind::*;
670 let total = self.count(AlSegno)
671 + self.count(DalSegno)
672 + self.count(DalSegnoAlCoda)
673 + self.count(DalSegnoAlFine);
674 if total > 1 {
675 return false;
676 }
677 let (segnos, codas, fines) = (self.count(Segno), self.count(Coda), self.count(Fine));
678 (self.count(AlSegno) == 1 && segnos == 1 && codas == 0)
679 || (self.count(DalSegno) == 1 && segnos == 1 && codas == 0)
680 || (self.count(DalSegnoAlFine) == 1 && codas == 0 && segnos == 1 && fines == 1)
681 || (self.count(DalSegnoAlCoda) == 1 && codas == 2 && segnos == 1 && fines == 0)
682 }
683
684 fn group_bracket_indices(&self, measures: &[Working]) -> Vec<Group> {
686 let mut groups = Vec::new();
687 let mut found_numbers: Vec<u32> = Vec::new();
688 let mut group = Group::default();
689 for (index, working) in measures.iter().enumerate() {
690 for (bracket_index, bracket) in self.brackets.iter().enumerate() {
691 if !bracket.is_first(working) {
692 continue;
693 }
694 if bracket
695 .numbers
696 .first()
697 .is_some_and(|first| found_numbers.contains(first))
698 {
699 groups.push(std::mem::take(&mut group));
700 found_numbers.clear();
701 }
702 found_numbers.extend(&bracket.numbers);
703 group.brackets.push(bracket_index);
704 for (sub, candidate) in measures.iter().enumerate() {
705 if bracket.is_last(candidate) {
706 group.indices.push(sub);
707 break;
708 }
709 if sub >= index {
710 group.indices.push(sub);
711 }
712 }
713 }
714 }
715 groups.push(group);
717 groups
718 }
719
720 fn repeat_brackets_are_coherent(&self) -> bool {
721 for group in self.group_bracket_indices(&self.source) {
722 if group.brackets.is_empty() {
723 return true;
724 }
725 if group.brackets.len() > 1 {
726 let numbers: Vec<u32> = group
727 .brackets
728 .iter()
729 .flat_map(|index| self.brackets[*index].numbers.clone())
730 .collect();
731 let highest = numbers.iter().copied().max().unwrap_or(0);
732 if numbers != (1..=highest).collect::<Vec<_>>() {
733 return false;
734 }
735 }
736 let mut spanned: Vec<usize> = Vec::new();
737 for (count, index) in group.brackets.iter().enumerate() {
738 let bracket = &self.brackets[*index];
739 for measure in &bracket.measures {
740 if spanned.contains(measure) {
741 return false;
742 }
743 spanned.push(*measure);
744 }
745 let last =
746 &self.source[*bracket.measures.last().expect("an ending spans a measure")];
747 if last.right_repeat().is_none()
748 && (group.brackets.len() == 1 || count + 1 < group.brackets.len())
749 {
750 return false;
751 }
752 }
753 }
754 true
755 }
756
757 fn innermost_of(measures: &[Working]) -> Vec<usize> {
759 let mut starts: Vec<usize> = Vec::new();
760 for (index, working) in measures.iter().enumerate() {
761 match working.left_repeat() {
762 Some(RepeatDirection::Start) => starts.push(index),
763 Some(RepeatDirection::End) => {
764 return (starts.last().copied().unwrap_or(0)..index).collect();
765 }
766 None => {}
767 }
768 if working.right_repeat() == Some(RepeatDirection::End) {
769 return (starts.last().copied().unwrap_or(0)..=index).collect();
770 }
771 }
772 Vec::new()
773 }
774
775 fn end_repeat_bar(measures: &[Working], index: usize) -> Result<(bool, u32)> {
778 let last = &measures[index];
779 if last.right_repeat() == Some(RepeatDirection::End) {
780 let times = last.measure.right_barline().and_then(Barline::repeat_times);
781 return Ok((true, times.unwrap_or(2)));
782 }
783 let Some(after) = measures.get(index + 1) else {
784 return Err(Error::Stream(format!(
785 "cannot find an end Repeat bar after the given end: {index}"
786 )));
787 };
788 if after.left_repeat() == Some(RepeatDirection::End) {
789 let times = after.measure.left_barline().and_then(Barline::repeat_times);
790 return Ok((false, times.unwrap_or(2)));
791 }
792 Err(Error::Stream(
793 "cannot find an end Repeat bar in the expected position".to_string(),
794 ))
795 }
796
797 fn play_innermost(
799 measures: &mut [Working],
800 forced: Option<&[usize]>,
801 times: Option<u32>,
802 expansion_only: bool,
803 ) -> Result<Vec<Working>> {
804 let indices: Vec<usize> = match forced {
805 Some(indices) => indices.to_vec(),
806 None => Self::innermost_of(measures),
807 };
808 if indices.iter().any(|index| *index >= measures.len()) {
809 return Err(Error::Stream(format!(
810 "a repeat index is past the last of {} measures",
811 measures.len()
812 )));
813 }
814 let mut out = Vec::new();
815 let mut strip_next = false;
816 let mut times_given = times;
817 let mut index = 0;
818 while index < measures.len() {
819 let (Some(&first), Some(&last)) = (indices.first(), indices.last()) else {
820 break;
821 };
822 if index == first {
823 let (closes_itself, times_found) = match Self::end_repeat_bar(measures, last) {
824 Ok(found) => found,
825 Err(error) if forced.is_none() => return Err(error),
826 Err(_) => (true, 0),
831 };
832 let times = *times_given.get_or_insert(times_found);
833 for time in 0..times {
834 for &place in &indices {
835 let mut copy = measures[place].copy();
836 if place == first || place == last {
837 copy.strip_repeat_barlines();
838 }
839 if times >= 2 && time < times - 1 {
840 copy.strip_repeat_expressions();
841 }
842 if time != 0 {
843 let letter = char::from(b'a' + ((time - 1) % 26) as u8);
844 copy.measure.set_number_suffix(Some(letter.to_string()));
845 }
846 out.push(copy);
847 }
848 }
849 if !closes_itself {
850 strip_next = true;
851 }
852 index = last + 1;
853 } else {
854 if !expansion_only {
855 if strip_next {
856 measures[index].strip_repeat_barlines();
857 strip_next = false;
858 }
859 out.push(measures[index].clone());
860 }
861 index += 1;
862 }
863 }
864 Ok(out)
865 }
866
867 fn process_innermost_repeats_and_brackets(
869 &self,
870 mut measures: Vec<Working>,
871 done: &mut Vec<usize>,
872 ) -> Result<Vec<Working>> {
873 let groups = self.group_bracket_indices(&measures);
874 let innermost = Self::innermost_of(&measures);
875 let mut focus: Option<Group> = None;
876 if let (Some(&first), Some(&last)) = (innermost.first(), innermost.last()) {
877 for group in &groups {
878 for &bracket in &group.brackets {
879 if done.contains(&bracket) {
880 break;
881 }
882 let spans = &self.brackets[bracket];
883 if spans.spans(&measures[first]) || spans.spans(&measures[last]) {
884 focus = Some(group.clone());
885 break;
886 }
887 }
888 if focus.is_some() {
889 break;
890 }
891 }
892 }
893 let Some(focus) = focus else {
894 return Self::play_innermost(&mut measures, None, None, false);
895 };
896 let start = innermost[0];
897 let mut boundaries: Vec<(usize, Vec<usize>, Vec<usize>)> = Vec::new();
898 for &bracket_index in &focus.brackets {
899 done.push(bracket_index);
900 let bracket = &self.brackets[bracket_index];
901 let mut end = None;
902 let mut bracket_start = None;
903 for (index, working) in measures.iter().enumerate() {
904 if bracket.is_last(working) {
905 end = Some(index);
906 }
907 if bracket.is_first(working) {
908 bracket_start = Some(index);
909 }
910 }
911 let (Some(end), Some(bracket_start)) = (end, bracket_start) else {
912 return Err(Error::Stream(
913 "failed to find start or end index of bracket expansion".to_string(),
914 ));
915 };
916 let mut indices: Vec<usize> = (start..=end).collect();
917 for (_, _, earlier) in &boundaries {
918 indices.retain(|index| !earlier.contains(index));
919 }
920 boundaries.push((bracket_index, indices, (bracket_start..=end).collect()));
921 }
922 let mut repeats: Vec<Vec<Working>> = Vec::new();
923 let mut highest = None;
924 for (bracket_index, indices, _) in &boundaries {
925 let times = self.brackets[*bracket_index].numbers.len() as u32;
926 repeats.push(Self::play_innermost(
927 &mut measures,
928 Some(indices),
929 Some(times),
930 true,
931 )?);
932 highest = indices.iter().copied().max();
933 }
934 let mut out: Vec<Working> = measures[..start].to_vec();
935 for sub in repeats {
936 for mut working in sub {
937 working.strip_repeat_barlines();
938 out.push(working);
939 }
940 }
941 if let Some(highest) = highest {
942 out.extend(measures[highest + 1..].iter().cloned());
943 }
944 Ok(out)
945 }
946
947 fn process_recursive_repeat_bars(&self, mut measures: Vec<Working>) -> Result<Vec<Working>> {
949 let mut done: Vec<usize> = Vec::new();
950 for _ in 0..100 {
951 measures = self.process_innermost_repeats_and_brackets(measures, &mut done)?;
952 if !has_repeat(&measures) {
953 break;
954 }
955 }
956 Ok(measures)
957 }
958
959 fn process_repeat_expression_and_repeats(
963 &self,
964 measures: Vec<Working>,
965 jump: Jump,
966 ) -> Result<Vec<Working>> {
967 use RepeatExpressionKind::*;
968 let command = [
969 DaCapo,
970 DaCapoAlCoda,
971 DaCapoAlFine,
972 AlSegno,
973 DalSegno,
974 DalSegnoAlCoda,
975 DalSegnoAlFine,
976 ]
977 .into_iter()
978 .find(|kind| self.count(*kind) == 1)
979 .ok_or_else(|| Error::Stream("no repeat command found".to_string()))?;
980 let index_of = |kind: RepeatExpressionKind| -> Vec<usize> {
981 measures
982 .iter()
983 .enumerate()
984 .flat_map(|(index, working)| {
985 working
986 .expressions()
987 .into_iter()
988 .filter(move |found| *found == kind)
989 .map(move |_| index)
990 })
991 .collect()
992 };
993 let missing =
994 || Error::Stream("a repeat expression is not where it is expected".to_string());
995 let jump_back = *index_of(command).first().ok_or_else(missing)?;
996 let start = match jump {
997 Jump::DaCapo => 0,
998 Jump::Segno => *index_of(Segno).first().ok_or_else(missing)?,
999 };
1000 let last = measures.len() - 1;
1001 let end = if matches!(command, DaCapoAlFine | DalSegnoAlFine) {
1002 *index_of(Fine).first().ok_or_else(missing)?
1003 } else {
1004 last
1005 };
1006 let mut segments = vec![(0, jump_back)];
1007 if matches!(command, DaCapoAlCoda | DalSegnoAlCoda) {
1008 let codas = index_of(Coda);
1009 let (Some(&jump_from), Some(&resume)) = (codas.first(), codas.get(1)) else {
1010 return Err(missing());
1011 };
1012 segments.push((start, jump_from));
1013 segments.push((resume, last));
1014 } else {
1015 segments.push((start, end));
1016 }
1017
1018 let mut number: IntegerType = measures[0].measure.number();
1019 let mut out = Vec::new();
1020 for (count, (from, to)) in segments.into_iter().enumerate() {
1021 let mut segment: Vec<Working> = Vec::new();
1022 for working in measures.iter().take(to + 1).skip(from) {
1023 let mut copy = working.copy();
1024 copy.measure.set_number(number);
1025 segment.push(copy);
1026 number += 1;
1027 }
1028 if has_repeat(&segment) {
1029 if count != 1 {
1032 segment = self.process_recursive_repeat_bars(segment)?;
1033 number = segment
1034 .last()
1035 .map_or(number, |last| last.measure.number() + 1);
1036 }
1037 for working in &mut segment {
1038 working.strip_repeat_barlines();
1039 }
1040 }
1041 out.extend(segment);
1042 }
1043 for working in &mut out {
1044 working.appended_length = Some(working.measure.end_offset());
1045 working.strip_repeat_expressions();
1046 }
1047 Ok(out)
1048 }
1049}
1050
1051fn has_repeat(measures: &[Working]) -> bool {
1053 measures.iter().any(|working| {
1054 working.left_repeat().is_some() || working.right_repeat() == Some(RepeatDirection::End)
1055 })
1056}
1057
1058#[cfg(test)]
1059mod tests {
1060 use crate::bar::{Barline, Ending, RepeatDirection};
1061 use crate::repeat::{RepeatExpression, RepeatExpressionKind};
1062 use crate::stream::{Expander, Stream, StreamElement, StreamKind};
1063 use crate::{Duration, Note};
1064
1065 fn part(count: i32, shape: impl Fn(i32, &mut Stream)) -> Stream {
1068 let mut part = Stream::with_kind(StreamKind::Part);
1069 for number in 1..=count {
1070 let mut measure = Stream::with_kind(StreamKind::Measure);
1071 measure.set_number(number);
1072 measure.push(
1073 Note::from_name("C4")
1074 .unwrap()
1075 .with_duration(Duration::whole()),
1076 );
1077 shape(number, &mut measure);
1078 part.insert(f64::from(number - 1) * 4.0, measure);
1079 }
1080 part
1081 }
1082
1083 fn played(part: &Stream) -> Vec<String> {
1084 part.expand_repeats()
1085 .unwrap()
1086 .measures()
1087 .iter()
1088 .map(|measure| measure.number_with_suffix())
1089 .collect()
1090 }
1091
1092 #[test]
1093 fn a_passage_between_repeat_barlines_is_played_twice() {
1094 let part = part(4, |number, measure| match number {
1095 2 => measure.set_left_barline(Some(Barline::repeat(RepeatDirection::Start, None))),
1096 3 => measure.set_right_barline(Some(Barline::repeat(RepeatDirection::End, None))),
1097 _ => {}
1098 });
1099 assert_eq!(played(&part), ["1", "2", "3", "2a", "3a", "4"]);
1100 let expanded = part.expand_repeats().unwrap();
1101 assert_eq!(expanded.end_offset(), 24.0);
1103 assert!(
1104 expanded.measures()[2]
1105 .right_barline()
1106 .unwrap()
1107 .repeat_direction()
1108 .is_none()
1109 );
1110 }
1111
1112 #[test]
1113 fn a_first_ending_is_played_then_the_second() {
1114 let part = part(4, |number, measure| match number {
1115 2 => {
1116 measure.set_ending(Some(Ending::new(vec![1], true, true)));
1117 measure.set_right_barline(Some(Barline::repeat(RepeatDirection::End, None)));
1118 }
1119 3 => measure.set_ending(Some(Ending::new(vec![2], true, true))),
1120 _ => {}
1121 });
1122 assert_eq!(played(&part), ["1", "2", "1", "3", "4"]);
1125 }
1126
1127 #[test]
1128 fn da_capo_al_fine_goes_back_to_the_fine() {
1129 let part = part(3, |number, measure| {
1130 let mark = match number {
1131 1 => RepeatExpressionKind::Fine,
1132 3 => RepeatExpressionKind::DaCapoAlFine,
1133 _ => return,
1134 };
1135 measure.insert(
1136 0.0,
1137 StreamElement::RepeatExpression(RepeatExpression::new(mark)),
1138 );
1139 });
1140 assert_eq!(played(&part), ["1", "2", "3", "4"]);
1142 let expanded = part.expand_repeats().unwrap();
1143 assert!(
1144 expanded
1145 .recurse()
1146 .iter()
1147 .all(|(_, element)| !matches!(element, StreamElement::RepeatExpression(_)))
1148 );
1149 }
1150
1151 #[test]
1152 fn repeats_that_do_not_pair_up_are_refused() {
1153 let part = part(3, |number, measure| {
1154 if number != 2 {
1155 measure.set_left_barline(Some(Barline::repeat(RepeatDirection::Start, None)));
1156 }
1157 });
1158 assert!(part.expand_repeats().is_err());
1159 }
1160
1161 fn two_passages() -> Stream {
1164 part(5, |number, measure| match number {
1165 2 => {
1166 measure.set_left_barline(Some(Barline::repeat(RepeatDirection::Start, None)));
1167 measure.set_right_barline(Some(Barline::repeat(RepeatDirection::End, Some(3))));
1168 }
1169 4 => {
1170 measure.set_left_barline(Some(Barline::repeat(RepeatDirection::Start, None)));
1171 measure.set_right_barline(Some(Barline::repeat(RepeatDirection::End, Some(2))));
1172 }
1173 _ => {}
1174 })
1175 }
1176
1177 fn numbers(stream: &Stream) -> Vec<String> {
1178 stream
1179 .measures()
1180 .iter()
1181 .map(|measure| measure.number_with_suffix())
1182 .collect()
1183 }
1184
1185 #[test]
1186 fn the_measure_map_names_the_measure_each_one_plays() {
1187 let expander = Expander::new(&two_passages()).unwrap();
1188 assert_eq!(expander.measure_map().unwrap(), [0, 1, 1, 1, 2, 3, 3, 4]);
1189 assert_eq!(
1190 expander.measure_map_numbers().unwrap(),
1191 ["1", "2", "2a", "2b", "3", "4", "4a", "5"]
1192 );
1193 }
1194
1195 #[test]
1196 fn a_part_with_nothing_to_play_out_maps_to_itself() {
1197 let expander = Expander::new(&part(3, |_, _| {})).unwrap();
1198 assert_eq!(expander.is_expandable().unwrap(), None);
1199 assert_eq!(expander.measure_map().unwrap(), [0, 1, 2]);
1200 }
1201
1202 #[test]
1203 fn repeats_that_do_not_pair_up_are_not_expandable() {
1204 let part = part(3, |number, measure| {
1205 if number != 2 {
1206 measure.set_left_barline(Some(Barline::repeat(RepeatDirection::Start, None)));
1207 }
1208 });
1209 let expander = Expander::new(&part).unwrap();
1210 assert!(!expander.repeat_bars_are_coherent().unwrap());
1211 assert_eq!(expander.is_expandable().unwrap(), Some(false));
1212 assert!(expander.measure_map().is_err());
1213 assert!(
1214 Expander::new(&two_passages())
1215 .unwrap()
1216 .repeat_bars_are_coherent()
1217 .unwrap()
1218 );
1219 }
1220
1221 #[test]
1222 fn a_right_barline_starting_a_repeat_is_refused() {
1223 let part = part(2, |number, measure| {
1224 if number == 1 {
1225 measure.set_right_barline(Some(Barline::repeat(RepeatDirection::Start, None)));
1226 }
1227 });
1228 assert!(
1229 Expander::new(&part)
1230 .unwrap()
1231 .repeat_bars_are_coherent()
1232 .is_err()
1233 );
1234 }
1235
1236 #[test]
1237 fn the_innermost_repeat_runs_from_the_last_start() {
1238 let mut written = two_passages();
1239 assert_eq!(Expander::find_innermost_repeat_indices(&written), [1]);
1240 let StreamElement::Stream(second) = written.events_mut()[1].element_mut() else {
1241 unreachable!()
1242 };
1243 second.set_right_barline(None);
1244 let StreamElement::Stream(fourth) = written.events_mut()[3].element_mut() else {
1245 unreachable!()
1246 };
1247 fourth.set_left_barline(None);
1248 assert_eq!(Expander::find_innermost_repeat_indices(&written), [1, 2, 3]);
1249 assert!(Expander::find_innermost_repeat_indices(&part(2, |_, _| {})).is_empty());
1250 }
1251
1252 #[test]
1253 fn the_innermost_repeat_is_played_out_one_at_a_time() {
1254 let part = two_passages();
1255 let once = Expander::process_innermost_repeat_bars(&part, None, None, false).unwrap();
1256 assert_eq!(numbers(&once), ["1", "2", "2a", "2b", "3", "4", "5"]);
1257 assert_eq!(once.kind(), StreamKind::Part);
1258 assert_eq!(once.events()[4].offset(), 16.0);
1259 assert!(
1261 once.measures()[5]
1262 .left_barline()
1263 .unwrap()
1264 .repeat_direction()
1265 .is_some()
1266 );
1267
1268 let twice = Expander::process_innermost_repeat_bars(&once, None, None, false).unwrap();
1269 assert_eq!(numbers(&twice), ["1", "2", "2a", "2b", "3", "4", "4a", "5"]);
1270 assert_eq!(twice.end_offset(), 32.0);
1271 assert_eq!(numbers(&part), ["1", "2", "3", "4", "5"]);
1273 }
1274
1275 #[test]
1276 fn an_end_with_no_start_repeats_from_the_beginning() {
1277 let part = part(5, |number, measure| {
1278 if number == 2 {
1279 measure.set_right_barline(Some(Barline::repeat(RepeatDirection::End, None)));
1280 }
1281 });
1282 let played = Expander::process_innermost_repeat_bars(&part, None, None, false).unwrap();
1283 assert_eq!(numbers(&played), ["1", "2", "1a", "2a", "3", "4", "5"]);
1284 }
1285
1286 #[test]
1287 fn given_measures_are_played_as_often_as_asked() {
1288 let part = part(3, |_, _| {});
1289 let played =
1290 Expander::process_innermost_repeat_bars(&part, Some(&[1]), Some(2), false).unwrap();
1291 assert_eq!(numbers(&played), ["1", "2", "2a", "3"]);
1292 let only =
1293 Expander::process_innermost_repeat_bars(&part, Some(&[1]), Some(2), true).unwrap();
1294 assert_eq!(numbers(&only), ["2", "2a"]);
1295 let none = Expander::process_innermost_repeat_bars(&part, Some(&[1]), None, false).unwrap();
1297 assert_eq!(numbers(&none), ["1", "3"]);
1298 assert!(Expander::process_innermost_repeat_bars(&part, Some(&[7]), None, false).is_err());
1299 }
1300
1301 #[test]
1302 fn a_repeat_expression_is_found_by_its_measure() {
1303 let part = part(3, |number, measure| {
1304 if number == 3 {
1305 measure.push(StreamElement::RepeatExpression(RepeatExpression::new(
1306 RepeatExpressionKind::Segno,
1307 )));
1308 }
1309 });
1310 assert_eq!(
1311 Expander::repeat_expression_index(&part, RepeatExpressionKind::Segno),
1312 [2]
1313 );
1314 assert!(Expander::repeat_expression_index(&part, RepeatExpressionKind::Coda).is_empty());
1315 }
1316
1317 #[test]
1318 fn an_expander_needs_measures() {
1319 assert!(Expander::new(&Stream::with_kind(StreamKind::Part)).is_err());
1320 }
1321
1322 #[test]
1323 fn a_stream_with_no_measures_is_refused() {
1324 assert!(
1325 Stream::with_kind(StreamKind::Part)
1326 .expand_repeats()
1327 .is_err()
1328 );
1329 }
1330}