diff --git a/src/include/mx/api/MarkData.h b/src/include/mx/api/MarkData.h
index 4fb831b0..a5489d07 100644
--- a/src/include/mx/api/MarkData.h
+++ b/src/include/mx/api/MarkData.h
@@ -34,7 +34,12 @@ enum class MarkType
doit,
falloff,
breathMark,
- caesura,
+ caesura, // an empty , the common form; renders the same as caesuraNormal
+ caesuraNormal,
+ caesuraThick,
+ caesuraShort,
+ caesuraCurved,
+ caesuraSingle,
stress,
unstress,
softAccent,
diff --git a/src/private/mx/api/MarkData.cpp b/src/private/mx/api/MarkData.cpp
index f5e6bf8d..ca546eb7 100644
--- a/src/private/mx/api/MarkData.cpp
+++ b/src/private/mx/api/MarkData.cpp
@@ -105,8 +105,11 @@ bool isMarkArticulation(MarkType markType)
(markType == MarkType::detachedLegato) || (markType == MarkType::staccatissimo) ||
(markType == MarkType::spiccato) || (markType == MarkType::scoop) || (markType == MarkType::plop) ||
(markType == MarkType::doit) || (markType == MarkType::falloff) || (markType == MarkType::breathMark) ||
- (markType == MarkType::caesura) || (markType == MarkType::stress) || (markType == MarkType::unstress) ||
- (markType == MarkType::softAccent) || (markType == MarkType::otherArticulation);
+ (markType == MarkType::caesura) || (markType == MarkType::caesuraNormal) ||
+ (markType == MarkType::caesuraThick) || (markType == MarkType::caesuraShort) ||
+ (markType == MarkType::caesuraCurved) || (markType == MarkType::caesuraSingle) ||
+ (markType == MarkType::stress) || (markType == MarkType::unstress) || (markType == MarkType::softAccent) ||
+ (markType == MarkType::otherArticulation);
}
bool isMarkOrnament(MarkType markType)
diff --git a/src/private/mx/impl/ArticulationsFunctions.cpp b/src/private/mx/impl/ArticulationsFunctions.cpp
index 4bcdbe16..2e5cdc1c 100644
--- a/src/private/mx/impl/ArticulationsFunctions.cpp
+++ b/src/private/mx/impl/ArticulationsFunctions.cpp
@@ -4,6 +4,7 @@
#include "mx/impl/ArticulationsFunctions.h"
#include "mx/core/generated/ArticulationsChoice.h"
+#include "mx/core/generated/CaesuraValue.h"
#include "mx/impl/Converter.h"
#include "mx/impl/MarkDataFunctions.h"
#include "mx/impl/PositionFunctions.h"
@@ -108,6 +109,27 @@ void ArticulationsFunctions::parseArticulation(const core::ArticulationsChoice &
case core::ArticulationsChoice::Kind::caesura: {
parseMarkDataAttributes(inArticulation.asCaesura(), outMark);
outMark.name = "caesura";
+ switch (inArticulation.asCaesura().value().tag())
+ {
+ case core::CaesuraValue::Tag::empty:
+ outMark.markType = api::MarkType::caesura;
+ break;
+ case core::CaesuraValue::Tag::normal:
+ outMark.markType = api::MarkType::caesuraNormal;
+ break;
+ case core::CaesuraValue::Tag::thick:
+ outMark.markType = api::MarkType::caesuraThick;
+ break;
+ case core::CaesuraValue::Tag::short_:
+ outMark.markType = api::MarkType::caesuraShort;
+ break;
+ case core::CaesuraValue::Tag::curved:
+ outMark.markType = api::MarkType::caesuraCurved;
+ break;
+ case core::CaesuraValue::Tag::single:
+ outMark.markType = api::MarkType::caesuraSingle;
+ break;
+ }
break;
}
case core::ArticulationsChoice::Kind::stress: {
diff --git a/src/private/mx/impl/Converter.cpp b/src/private/mx/impl/Converter.cpp
index 386be73e..299c1422 100644
--- a/src/private/mx/impl/Converter.cpp
+++ b/src/private/mx/impl/Converter.cpp
@@ -174,6 +174,11 @@ const Converter::EnumMap Convert
{core::ArticulationsChoice::Kind::falloff, api::MarkType::falloff},
{core::ArticulationsChoice::Kind::breathMark, api::MarkType::breathMark},
{core::ArticulationsChoice::Kind::caesura, api::MarkType::caesura},
+ {core::ArticulationsChoice::Kind::caesura, api::MarkType::caesuraNormal},
+ {core::ArticulationsChoice::Kind::caesura, api::MarkType::caesuraThick},
+ {core::ArticulationsChoice::Kind::caesura, api::MarkType::caesuraShort},
+ {core::ArticulationsChoice::Kind::caesura, api::MarkType::caesuraCurved},
+ {core::ArticulationsChoice::Kind::caesura, api::MarkType::caesuraSingle},
{core::ArticulationsChoice::Kind::stress, api::MarkType::stress},
{core::ArticulationsChoice::Kind::unstress, api::MarkType::unstress},
{core::ArticulationsChoice::Kind::softAccent, api::MarkType::softAccent},
diff --git a/src/private/mx/impl/NotationsWriter.cpp b/src/private/mx/impl/NotationsWriter.cpp
index cf7312ec..49f1613c 100644
--- a/src/private/mx/impl/NotationsWriter.cpp
+++ b/src/private/mx/impl/NotationsWriter.cpp
@@ -11,6 +11,7 @@
#include "mx/core/generated/ArticulationsChoice.h"
#include "mx/core/generated/BreathMark.h"
#include "mx/core/generated/Caesura.h"
+#include "mx/core/generated/CaesuraValue.h"
#include "mx/core/generated/EmptyLine.h"
#include "mx/core/generated/EmptyPlacement.h"
#include "mx/core/generated/EmptyPlacementSmufl.h"
@@ -542,6 +543,30 @@ void NotationsWriter::addArticulation(const api::MarkData &mark, core::Articulat
case core::ArticulationsChoice::Kind::caesura: {
core::Caesura c;
setAttributesFromPositionData(mark.positionData, c);
+ // MarkType::caesura is the common empty form ; the variants carry an
+ // explicit text value.
+ auto caesuraValue = core::CaesuraValue::empty();
+ if (mark.markType == api::MarkType::caesuraNormal)
+ {
+ caesuraValue = core::CaesuraValue::normal();
+ }
+ else if (mark.markType == api::MarkType::caesuraThick)
+ {
+ caesuraValue = core::CaesuraValue::thick();
+ }
+ else if (mark.markType == api::MarkType::caesuraShort)
+ {
+ caesuraValue = core::CaesuraValue::short_();
+ }
+ else if (mark.markType == api::MarkType::caesuraCurved)
+ {
+ caesuraValue = core::CaesuraValue::curved();
+ }
+ else if (mark.markType == api::MarkType::caesuraSingle)
+ {
+ caesuraValue = core::CaesuraValue::single();
+ }
+ c.setValue(caesuraValue);
outArticulations.addChoice(core::ArticulationsChoice::caesura(c));
break;
}
diff --git a/src/private/mxtest/api/MarkRoundTripTest.cpp b/src/private/mxtest/api/MarkRoundTripTest.cpp
index de76fcc1..191a90e7 100644
--- a/src/private/mxtest/api/MarkRoundTripTest.cpp
+++ b/src/private/mxtest/api/MarkRoundTripTest.cpp
@@ -268,4 +268,24 @@ TEST(NonArpeggiateAttributes, MarkRoundTrip)
T_END;
+TEST(CaesuraEmpty, MarkRoundTrip)
+{
+ // The common empty form must not acquire a "normal" text value on write.
+ const auto marks = roundTripMark(MarkType::caesura);
+ CHECK(hasMark(marks, MarkType::caesura));
+}
+
+T_END;
+
+TEST(CaesuraVariants, MarkRoundTrip)
+{
+ CHECK(hasMark(roundTripMark(MarkType::caesuraNormal), MarkType::caesuraNormal));
+ CHECK(hasMark(roundTripMark(MarkType::caesuraThick), MarkType::caesuraThick));
+ CHECK(hasMark(roundTripMark(MarkType::caesuraShort), MarkType::caesuraShort));
+ CHECK(hasMark(roundTripMark(MarkType::caesuraCurved), MarkType::caesuraCurved));
+ CHECK(hasMark(roundTripMark(MarkType::caesuraSingle), MarkType::caesuraSingle));
+}
+
+T_END;
+
#endif
diff --git a/src/private/mxtest/api/roundtrip-baseline.txt b/src/private/mxtest/api/roundtrip-baseline.txt
index c21fbe8c..70314f43 100644
--- a/src/private/mxtest/api/roundtrip-baseline.txt
+++ b/src/private/mxtest/api/roundtrip-baseline.txt
@@ -407,3 +407,10 @@ synthetic/arpeggiate.3.1.xml
synthetic/arpeggiate.4.0.xml
synthetic/non-arpeggiate.3.0.xml
synthetic/non-arpeggiate.3.1.xml
+
+# Unblocked by the caesura value fix: MarkType::caesura now round-trips the
+# common empty element form, and the caesuraNormal/Thick/Short/Curved/Single
+# variants carry an explicit text value.
+ksuite/k001a_Articulations.xml
+musuite/testNoteAttributes2.xml
+musuite/testNoteAttributes2_ref.xml