toSolfa(), take 2

This commit is contained in:
dotmg 2025-07-19 00:03:06 +02:00
parent 694292c0cd
commit d1a0d6f00e
12 changed files with 255 additions and 47 deletions

View file

@ -56,7 +56,7 @@ kotlin {
implementation(libs.bundles.voyager) implementation(libs.bundles.voyager)
implementation(libs.cafe.voyager.koin) implementation(libs.cafe.voyager.koin)
implementation(libs.androidx.material.icons.extended) implementation(libs.androidx.material.icons.extended)
implementation(kotlin("stdlib-jdk8"))
} }
commonTest.dependencies { commonTest.dependencies {
implementation(libs.kotlin.test) implementation(libs.kotlin.test)

View file

@ -2,19 +2,19 @@
"themeMode": "DARK", "themeMode": "DARK",
"fontSize": 18.5, "fontSize": 18.5,
"playlist": [ "playlist": [
"assets://ffpm-16.txt", "assets://ffpm-33.txt",
"assets://ff-8.txt",
"assets://ffpm-444-2.txt",
"assets://ffpm-760.txt",
"assets://ews-456.txt",
"assets://ffpm-51.txt",
"assets://ffpm-428.txt", "assets://ffpm-428.txt",
"assets://ffpm-449.txt", "assets://ffpm-449.txt",
"assets://ffpm-489.txt", "assets://ffpm-489.txt",
"assets://ffpm-21.txt", "assets://ffpm-21.txt",
"assets://ffpm-179.txt", "assets://ffpm-179.txt",
"assets://ff-33.txt", "assets://ff-33.txt",
"assets://ffpm-297.txt", "assets://ffpm-297.txt"
"assets://ffpm-33.txt",
"assets://ff-8.txt",
"assets://ffpm-444-2.txt",
"assets://ffpm-760.txt",
"assets://ews-456.txt"
], ],
"buttonContainerColorHex": "#FFFF8855", "buttonContainerColorHex": "#FFFF8855",
"buttonContentColorHex": "#FF000055", "buttonContentColorHex": "#FF000055",

View file

@ -5,5 +5,5 @@ N2:#m,dsdsdtsT/lSlllfm/ssstddd/dtssFs---/dsdsdtsT/lSltlfm/ssstddd/ddsdts
N3:#t,smlmsfm-/d7/dtdrmlm/ssmrdr---/smlmsfm-/d7/dtdrmlm/lsmsfm N3:#t,smlmsfm-/d7/dtdrmlm/ssmrdr---/smlmsfm-/d7/dtdrmlm/lsmsfm
N4:#d,d4ssd-/f6d/mrmsd'lm/dt,drrsfmr/d4ssd-/f6d/mrmsd'lm/fssss,d N4:#d,d4ssd-/f6d/mrmsd'lm/dt,drrsfmr/d4ssd-/f6d/mrmsd'lm/fssss,d
Y1:Tompo ô, tsy takatray/Ny hasoanny antranao;/Zava-mahagaga\ anay/Ny fiti_avanao./He, mpanota izahay/Nefa haso_avinao;/Avotraina azonay;/Misaotra no atao. Y1:Tompo ô, tsy takatray/Ny hasoanny antranao;/Zava-mahagaga\ anay/Ny fiti_avanao./He, mpanota izahay/Nefa haso_avinao;/Avotraina azonay;/Misaotra no atao.
Y2:Tompo ô, Mpanjakanay/Fatratra ny herinao/Tsisy zavatra izay/Ma\hasakana Anao!/Nefa mora fo Hianao/Fa mandefitra\ aminay,/Ko_a dia misaotra\ Anao/Fa afaka izahay. Y2:Tompo ô, Mpanjakanay/Fatratra ny herinao/Tsisy zavatra izay/Ma\hasakana Anao!/Nefa mora fo Hianao/Fa mandefitra\ aminay,/Ko_a dia misaotra\ Anao/Fa afaka\ izahay.
Y3:Tompo Andriamanitray,/Avy izahay izao/Raiso ny fi_ainanay;/Anao, ka anjakao./Tompo ô, tsy takatray/Ny hasoanny antranao;/Zava-mahagaga\ anay/Ny fiti_avanao. Y3:Tompo Andriamanitray,/Avy izahay izao/Raiso ny fi_ainanay;/Anao, ka anjakao./Tompo ô, tsy takatray/Ny hasoanny antranao;/Zava-mahagaga\ anay/Ny fiti_avanao.

View file

@ -4,7 +4,7 @@ N1:s#s,mmdssSldfrmdd #l,sFl'smdlltdmrlr sm--dd--dfmrfm #t,sllllmmrdr smdddfmrfm
N2:#s,sdddssSldltdssdtrdtslltldtlt zzdd--ssTldlrdrdlll ddtlttds sTldtrdslsltdtlld-tt s N2:#s,sdddssSldltdssdtrdtslltldtlt zzdd--ssTldlrdrdlll ddtlttds sTldtrdslsltdtlld-tt s
N3:mssmmmmfmrssmmmRfmsm mmsFFFFszzsm--mmmdmrs ssmDDmFFFFsrsm mmdmrssmfrmfsrmrslsfm N3:mssmmmmfmrssmmmRfmsm mmsFFFFszzsm--mmmdmrs ssmDDmFFFFsrsm mmdmrssmfrmfsrmrslsfm
N4:#r,dddddddfsltd-d d6 llmr4szzdd--d,d,sfslt dtllllr4stddd dsfsltdmfsltdtlfs-ssd N4:#r,dddddddfsltd-d d6 llmr4szzdd--d,d,sfslt dtllllr4stddd dsfsltdmfsltdtlfs-ssd
Y1:Reko i\zao ry Tompo izany antsonao,/Mi_antso izany mpanompo mba ho irakao!${R=}Inty,_3inty_3inty a\ho Jeso/Inty, inty, iraho a\ho Jeso/Ekeko re ny\ ho miaramilanao/Ho vonona hanao ny sitrakao, ka ira\ho! Y1:Reko i\zao ry Tompo izany antsonao,/Mi_antso izany mpanompo mba ho irakao!${R=}Inty,_2inty_2inty a\ho Jeso/Inty, inty, iraho a\ho Jeso/Ekeko re ny\ ho miaramilanao/Ho vonona hanao ny sitrakao, ka ira\ho!
Y2:O di_ovy Tompo izany molotro/Ka ny fo madio hanompo no atolotro! Y2:O di_ovy Tompo izany molotro/Ka ny fo madio hanompo no atolotro!
Y3:Tsy hande\ha irery fa hiaraka\ Aminao/Ka dia mba ome_o ny hery sy Fanahinao! Y3:Tsy hande\ha irery fa hiaraka\ Aminao/Ka dia mba ome_o ny hery sy Fanahinao!
Y4:Reko i\zao ny toky hoe: «Momba a\hy Ianao »/Ry Jesosy Tompo sy Zoky, vonona aho izao! Y4:Reko i\zao ny toky hoe: «Momba a\hy Ianao»/Ry Jesosy Tompo sy Zoky, vonona\ a\ho izao!

View file

@ -0,0 +1,10 @@
M0:|c:C|m:4/4|r:8.7.8.7.4.7.|t:FFPM 49 : Mba jereo ny Tompontsika|a:C. Wesley 1707-1788 Nad. J. Richardson, 1844-1922 (dikany malalaka)|h:H. Smart, 1813-1879
U0:z0:44446244/4444 448/ 444(22)/6244/444(22)448/62446244/44(22)(22)4(22)8
N1:#msmdsm'rds/llsdsfm/smds-m'rdt/dtltdtls/#srrtsmrdl/fmr-d-dt-d
N2:#t,mdsms4/d4rtd/mdssfmfmm/m4-sFs/s5mff/lsf-mfs-fm
N3:#sdssddtdd/ldslsss/ddss-dtlS/lSmrdrdt/ttrtdTld/rsltd-rr-d
N4:ddmdsfmm/#s,ffmltsd/d's'mmrdrmm/l'mdl-rrs/s'4ddff/rmf#dsl-ss,-d
Y1:Mba jereo ny Tompontsika/Avy ao an-danitra/Indro avy amin-kery/Ao aminny rahona./${R=}Halelo_ia! Halelo_ia!/Ambarao ny heriny.
Y2:Zay rehetra fahavalo/Efa resiny tokoa;/Mifali_a, ry anjely!/Mihobia, ry olona!
Y3:Fony mbola teto Izy,/Satro-tsilo nentiny;/Zao ny satro-bolamena/Mendrika ny lohany;
Y4:Vo_a_eso mafy Izy./Be ny fahori_any/Fa izao, asandratra\ Izy/Ambarao ny hajany!/Ao aminny rahona.

View file

@ -0,0 +1,10 @@
M0:|c:Ab|m:4/4 Moderato|r:8.7.8.7.4.7.|t:FFPM 49 : Mba jereo ny Tompontsika|a:C. Wesley 1707-1788 Nad. J. Richardson, 1844-1922 (dikany malalaka)|h:Ch. Rasoanaivo 1876-1966
U0:zC:y 6244 48/y 6244 C/y 6244 48/y 6244 C/y 4yyy 46z2/y 4yyy 48/y 4yyy 46z2/y 6244 C
N1:#m,dddslsfm/mmddttl/#s,ssdrmfs'm/mmrdtls/ssd--d-d4/ssr--r-r3s/ssm#d--f-ssls/ffmmrrd
N2:#d,m4fmrd/ddllSSl/#r,ssstdtdd/ddsssFs/z3ssllssls/z3ssFFl3s/z3TTllTTld/ttdds3
N3:#l,d6td/ddmmrrd/ffms5/s3mrdt/z3mmffmmfm/z3ttlldddt/z3ssffmmfs/s4ffm
N4:#d,d8/ddllmml/#s,ttdsdrmd/ddtlrr,s/z3d8/z3ssr,5sz3/d6fm/rrdm,ssd
Y1:Mba jereo ny Tompontsika/Avy ao an-danitra/Indro avy amin-kery/Ao aminny rahona./${R=}Halelo_3ia!_2Halelo_ia!_Halelo_3ia!_2Halelo_ia!_Halelo_3ia!_2Halelo_ia!_/Ambarao ny heriny.
Y2:Zay rehetra fahavalo/Efa resiny tokoa;/Mifali_a, ry anjely!/Mihobia, ry olona!
Y3:Fony mbola teto Izy,/Satro-tsilo nentiny;/Zao ny satro-bolamena/Mendrika ny lohany;
Y4:Vo_a_eso mafy Izy./Be ny fahori_any/Fa izao, asandratra\ Izy/Ambarao ny hajany!/Ao aminny rahona.

View file

@ -0,0 +1,11 @@
M0:|c:C|m:6/4|r:P.M.|t:FFPM 51 Raha tonga anio ny Tompo|a:Ramasitera 1881-1979|h:Ira D. Sankey 1840-1908
U0:z0:8484 (44)484/ 8484 84C/ 8484 (44)484/ (44)484 (44)4C/ 84(44)4 84(84)/ 84(44)4 84(84)/ 8484 84(44)4/ 8484 (44)4C
N1:#m mfsssltdd/rdtlsr,m/ mfsssltdd/ rdlsdtdrd/ rdtltdlsd/ rdtltdFsf/ mfsm'rdltd/ ssldtdrd
N2:#t,drmmf-sss/ ffffmtd/ drmmf-ssm/ f-fmmrmfm/ fmf-rmfm-/ fmf-rmrr-/ drmsfff-f/ smdrrmfm
N3:#s ssddtdrdd/ l3ds3/ ssddtdrdd/ l-ddss-ss/ tdrds3ds/ tdrdssdt-/ ssdTlldSl/ dddls-td
N4:d4s-fmm/ f4ss, d/d4s-fmd/f-fdds-s,d/ s3-sd3-/ s3-sdrs,-/ d4f3-f/ mdfrs-s,d
Y1:Raha tonga\ anio ny Tompo/Amin-kery lehibe,/Ka arahinny mpanompo/Sy anjely maro be!${R=}Moa ho faly hi_anao/Moa ho faly hi_anao/Ka hidera ny Mpamonjy/I\zay nanavotra\ aina\ anao ?
Y2:He, ho simba sy ho rava/I\zao rehetra àry\ izao!/Ka hifankahita tava/Ny natao sy ny Mpanao/Fiv : Moa ho faly hianao sns…
Y3:Maso maro no hijery/I\lay nijaly fahizay,/Fa ny mino Azy\ ihany/No ho faly ra\hatrizay !/Fiv : Moa ho faly hianao sns…
Y4:Re\hefa tonga re ny Tompo/Mba hitsara\ izay natao,/Hitomany ny tsy mino/Fa hanatrika\ Azy ao !/Fiv : Moa ho faly hianao sns…
Y5:O, avi_a re ry Tompo/Mba hanjaka aminay!/Hahatonga\ anay mpanompo/Hiara-paly Aminao!/${R!}O Avi_a, ô avia, O Avi_a, ô avia,/Fa ny olonao rehetra/Dia maniry\ indrindra\ Anao!

View file

@ -0,0 +1,121 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" encoding="UTF-8"
omit-xml-declaration="no" standalone="no"
doctype-system="http://www.musicxml.org/dtds/partwise.dtd"
doctype-public="-//Recordare//DTD MusicXML 4.0 Partwise//EN"/>
<xsl:template match="/">
<xsl:apply-templates select="./score-partwise"/>
<xsl:apply-templates select="./score-timewise"/>
</xsl:template>
<xsl:template match="score-partwise">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()">
<xsl:value-of select="." />
</xsl:template>
<xsl:template match="backup">
<note>
<backup-duration>
<xsl:value-of select="duration"/>
</backup-duration>
<xsl:if test="voice">
<xsl:copy-of select="voice"/>
</xsl:if>
</note>
</xsl:template>
<xsl:template match="forward">
<note>
<forward-duration>
<xsl:value-of select="duration"/>
</forward-duration>
<xsl:if test="voice">
<xsl:copy-of select="voice"/>
</xsl:if>
</note>
</xsl:template>
<xsl:template match="direction">
<note>
<xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy>
</note>
</xsl:template>
<xsl:template match="*|@*|comment()|processing-instruction()">
<xsl:copy><xsl:apply-templates
select="*|@*|comment()|processing-instruction()|text()"
/></xsl:copy>
</xsl:template>
<xsl:template match="score-timewise">
<xsl:element name="score-partwise">
<xsl:apply-templates select="@version[.!='1.0']"/>
<xsl:apply-templates select="work"/>
<xsl:apply-templates select="movement-number"/>
<xsl:apply-templates select="movement-title"/>
<xsl:apply-templates select="identification"/>
<xsl:apply-templates select="defaults"/>
<xsl:apply-templates select="credit"/>
<xsl:apply-templates select="part-list"/>
<xsl:for-each select="measure[1]/part">
<xsl:variable name="part-id">
<xsl:value-of select="@id"/>
</xsl:variable>
<xsl:element name="part">
<xsl:copy-of select="@id" />
<xsl:for-each select="../../measure/part">
<xsl:if test="@id=$part-id">
<xsl:element name="measure">
<xsl:attribute name="number">
<xsl:value-of select="parent::measure/@number"/>
</xsl:attribute>
<xsl:if test="parent::measure/@text">
<xsl:attribute name="text">
<xsl:value-of select="parent::measure/@text"/>
</xsl:attribute>
</xsl:if>
<xsl:if test="parent::measure/@implicit[. = 'yes']">
<xsl:attribute name="implicit">
<xsl:value-of select="parent::measure/@implicit"/>
</xsl:attribute>
</xsl:if>
<xsl:if test="parent::measure/@non-controlling[. = 'yes']">
<xsl:attribute name="non-controlling">
<xsl:value-of
select="parent::measure/@non-controlling"/>
</xsl:attribute>
</xsl:if>
<xsl:if test="parent::measure/@width">
<xsl:attribute name="width">
<xsl:value-of select="parent::measure/@width"/>
</xsl:attribute>
</xsl:if>
<xsl:apply-templates />
</xsl:element>
</xsl:if>
</xsl:for-each>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:stylesheet>

View file

@ -168,7 +168,6 @@ class MusicXML(private val fileRepository: FileRepository) {
} }
val duration = noteNode.duration // 8 === type==half val duration = noteNode.duration // 8 === type==half
val voiceNumber = 2 - ((noteNode.voice ?: 1) % 2) val voiceNumber = 2 - ((noteNode.voice ?: 1) % 2)
noteNode.lyric.forEach { } // todo number/syllabic/text
val chord = noteNode.chord // !null = accord (same note) val chord = noteNode.chord // !null = accord (same note)
if (chord == null) { if (chord == null) {
voiceAlter = 0 voiceAlter = 0
@ -195,6 +194,9 @@ class MusicXML(private val fileRepository: FileRepository) {
else -> "z" else -> "z"
} }
solfaXML.addNote(voiceNumber+voiceAlter, timePointer, duration ?: 0, nextNote, numPart, beam, dollarMarkers) solfaXML.addNote(voiceNumber+voiceAlter, timePointer, duration ?: 0, nextNote, numPart, beam, dollarMarkers)
noteNode.lyric.forEach {
solfaXML.addLyrics(timePointer, it)
} // todo number/syllabic/text
dollarMarkers = mutableListOf() dollarMarkers = mutableListOf()
/*noteNode.notations?.forEach {notationsNode -> /*noteNode.notations?.forEach {notationsNode ->
}*/ }*/

View file

@ -5,7 +5,7 @@ class SolfaXML {
private var meta: MutableMap<String, String> = mutableMapOf() private var meta: MutableMap<String, String> = mutableMapOf()
var tuo: MutableList<SolfaXMLTuo> = mutableListOf() var tuo: MutableList<SolfaXMLTuo> = mutableListOf()
var currentKey = "C" var currentKey = "C"
var curBeam: MXBeam? = null var curBeam: Pair<Int, MXBeam?> = Pair(-1,null)
var curMarkers: MutableList<String> = mutableListOf() var curMarkers: MutableList<String> = mutableListOf()
var startTuplet = false var startTuplet = false
fun setMeta(key: String, value: String?) { fun setMeta(key: String, value: String?) {
@ -36,38 +36,48 @@ class SolfaXML {
addTuo(new) addTuo(new)
return new return new
} }
fun addTuo(newTuo: SolfaXMLTuo) { fun applyBeam(tuo: SolfaXMLTuo) {
if (curBeam != null) { if (curBeam.second != null) {
if (curBeam?.content == "begin") { if (curBeam.second?.content == "begin") {
newTuo.addMarker("(") tuo.addMarker(curBeam.first, "(")
} }
if (curBeam?.content == "end") { if (curBeam.second?.content == "end") {
newTuo.addMarker(")") tuo.addMarker(curBeam.first, ")")
} }
if (startTuplet) { if (startTuplet) {
newTuo.addMarker("t") tuo.addMarker(curBeam.first, "t")
startTuplet = false startTuplet = false
} }
curBeam = Pair(-1, null)
} }
if (curMarkers.isNotEmpty()) { if (curMarkers.isNotEmpty()) {
curMarkers.forEach { curMarkers.forEach {
newTuo.addMarker("\\$\\{$it\\}") tuo.addMarker(curBeam.first,"\\$\\{$it\\}")
} }
curMarkers = mutableListOf()
} }
curBeam = null }
curMarkers = mutableListOf() fun addTuo(newTuo: SolfaXMLTuo) {
applyBeam(newTuo)
tuo.add(newTuo) tuo.add(newTuo)
} }
fun editTuoNote(tuo: SolfaXMLTuo, voiceNumber: Int, note: String) {
tuo.setNote(voiceNumber, note)
applyBeam(tuo)
}
fun addNote(voiceNumberIn: Int, timePointer: Int, duration: Int, note: String, numPart: Int? = 1, beam: MXBeam? = null, dollarMarkers: MutableList<String> = mutableListOf()) { fun addNote(voiceNumberIn: Int, timePointer: Int, duration: Int, note: String, numPart: Int? = 1, beam: MXBeam? = null, dollarMarkers: MutableList<String> = mutableListOf()) {
curBeam = beam if (duration == 0) {
if (curBeam != null) { return
println(curBeam) }
val voiceNumber = 2 * ((numPart ?: 1) - 1) + (2 - (voiceNumberIn % 2))
curBeam = Pair(voiceNumber, beam)
if (curBeam.second != null) {
println("$timePointer $curBeam")
} }
curMarkers = dollarMarkers curMarkers = dollarMarkers
val tuoEdit: SolfaXMLTuo = tuo.find { foundTuo -> val tuoEdit: SolfaXMLTuo = tuo.find { foundTuo ->
timePointer >= foundTuo.timeLapse && timePointer < (foundTuo.timeLapse + foundTuo.duration) timePointer >= foundTuo.timeLapse && timePointer < (foundTuo.timeLapse + foundTuo.duration)
} ?: newTuo(timePointer, duration) } ?: newTuo(timePointer, duration)
val voiceNumber = 2 * ((numPart ?: 1) - 1) + (2 - (voiceNumberIn % 2))
val lapse1 = tuoEdit.timeLapse val lapse1 = tuoEdit.timeLapse
val lapse2 = timePointer val lapse2 = timePointer
val lapse3 = timePointer + duration val lapse3 = timePointer + duration
@ -81,10 +91,7 @@ class SolfaXML {
if (duration1 > 0) { if (duration1 > 0) {
val newTuo = tuoEdit.clone(lapse1, duration1) val newTuo = tuoEdit.clone(lapse1, duration1)
addTuo(newTuo) addTuo(newTuo)
} tuoEdit.resetMarkers()
if (duration3 > 0) {
val newTuo = tuoEdit.clone(lapse3, duration3, newNote = "+")
addTuo(newTuo)
} }
if (duration2 > 0) { if (duration2 > 0) {
if (duration3 > 0) { if (duration3 > 0) {
@ -92,15 +99,27 @@ class SolfaXML {
} }
if (duration1 > 0) { if (duration1 > 0) {
tuoEdit.oneNote.forEachIndexed { itVoice, itNote -> tuoEdit.oneNote.forEachIndexed { itVoice, itNote ->
tuoEdit.setNote(itVoice, "+") editTuoNote(tuoEdit, itVoice, "+")
} }
} }
tuoEdit.setNote(voiceNumber, note) editTuoNote(tuoEdit, voiceNumber, note)
}
if (duration3 > 0) {
val newTuo = tuoEdit.clone(lapse3, duration3, newNote = "+")
newTuo.resetMarkers()
addTuo(newTuo)
} }
if (duration4 > 0) { if (duration4 > 0) {
println("addNote recursion")
addNote(voiceNumber, lapse4, duration4, "+", numPart) addNote(voiceNumber, lapse4, duration4, "+", numPart)
} }
} }
fun addLyrics(timePointer: Int, lyric: MXLyric) {
val tuoEdit: SolfaXMLTuo? = tuo.find { foundTuo ->
timePointer == foundTuo.timeLapse
}
tuoEdit?.addLyrics(lyric)
}
fun toSolfa(measureLength: Int, firstMeasureLength: Int) { fun toSolfa(measureLength: Int, firstMeasureLength: Int) {
val metaString = "M0:|" + meta.map { (key, value) -> val metaString = "M0:|" + meta.map { (key, value) ->
"$key:" + value.replace('|', '!') "$key:" + value.replace('|', '!')
@ -121,6 +140,27 @@ class SolfaXML {
uString += ":" uString += ":"
println(metaString) println(metaString)
var curTimeLapse = 0
val tuoIterator = tuo.iterator()
while (tuoIterator.hasNext()) {
val currentTuo = tuoIterator.next()
var tuoSelect: SolfaXMLTuo? = currentTuo
while (currentTuo.timeLapse >= curTimeLapse) {
if (currentTuo.timeLapse > curTimeLapse) {
tuoSelect = tuo.find { foundTuo ->
foundTuo.timeLapse == curTimeLapse
}
if (tuoSelect == null) {
curTimeLapse ++
break
}
}
if (tuoSelect!!.duration in (0..32)) {
uString += letters[tuoSelect.duration]
}
curTimeLapse += tuoSelect.duration
}
}
println(uString) println(uString)
} }
} }

View file

@ -3,12 +3,18 @@ package mg.dot.feufaro.musicXML
data class SolfaXMLTuo ( data class SolfaXMLTuo (
var timeLapse: Int = 0, var timeLapse: Int = 0,
var duration: Int = 0, var duration: Int = 0,
var markers: MutableList<String> = mutableListOf(), var markers: MutableList<MutableList<String>> = mutableListOf(),
var oneNote: MutableList<String> = mutableListOf(), var oneNote: MutableList<String> = mutableListOf(),
val lyrics: MutableList<String> = mutableListOf() val lyrics: MutableList<String> = mutableListOf()
) { ) {
fun addMarker(marker: String) { fun resetMarkers() {
markers += marker markers = mutableListOf()
}
fun addMarker(voiceNumber: Int, marker: String) {
while (markers.size <= voiceNumber) {
markers.add(mutableListOf())
}
markers[voiceNumber].add(marker)
} }
fun setTime(newTimeLapse: Int?, newDuration: Int?): SolfaXMLTuo { fun setTime(newTimeLapse: Int?, newDuration: Int?): SolfaXMLTuo {
if (newTimeLapse != null) timeLapse = newTimeLapse if (newTimeLapse != null) timeLapse = newTimeLapse
@ -28,7 +34,7 @@ data class SolfaXMLTuo (
fun clone( fun clone(
timeLapse: Int = this.timeLapse, timeLapse: Int = this.timeLapse,
duration: Int = this.duration, duration: Int = this.duration,
markers: MutableList<String> = this.markers.toMutableList(), markers: MutableList<MutableList<String>> = this.markers.toMutableList(),
oneNote: MutableList<String> = this.oneNote.toMutableList(), oneNote: MutableList<String> = this.oneNote.toMutableList(),
newNote: String? = null newNote: String? = null
): SolfaXMLTuo { ): SolfaXMLTuo {
@ -42,10 +48,13 @@ data class SolfaXMLTuo (
} }
fun addLyrics(mxLyrics: MXLyric) { fun addLyrics(mxLyrics: MXLyric) {
val number = mxLyrics.number ?: -1 val number = mxLyrics.number ?: -1
val text = mxLyrics.text ?: "" var text = mxLyrics.text ?: ""
while(lyrics.size <= number) { while(lyrics.size <= number) {
lyrics.add(lyrics.size, "") lyrics.add(lyrics.size, "")
} }
if (mxLyrics.syllabic in listOf("begin", "middle")) {
text += "-"
}
lyrics[number] = text lyrics[number] = text
} }
} }

View file

@ -23,13 +23,12 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository
val REGEX_TEMPLATE_COMMENT = Regex("(\\$[A-Z]|\\$\\{[^\\}]*\\})") val REGEX_TEMPLATE_COMMENT = Regex("(\\$[A-Z]|\\$\\{[^\\}]*\\})")
val REGEX_REPETITION = Regex("([zdrmfslt-](?>[',]*))([1-9][0-9]*)", RegexOption.IGNORE_CASE) val REGEX_REPETITION = Regex("([zdrmfslt-](?>[',]*))([1-9][0-9]*)", RegexOption.IGNORE_CASE)
val REGEX_PARSE_META = Regex("\\|(?=[a-z]:)") val REGEX_PARSE_META = Regex("\\|(?=[a-z]:)")
val REGEX_LYRICS_COMMENT = Regex("\\$\\{([^\\}]:[^\\}]*)\\}") val REGEX_LYRICS_COMMENT = Regex("\\$\\{([^\\}]:[^\\}]*)\\}|\\$\\{R!\\}")
val REGEX_LYRICS_REPETITION = Regex("_(\\d)") val REGEX_LYRICS_REPETITION = Regex("_(\\d)")
val REGEX_VOWELS_STAGE1 = Regex("[aeiouyòàéỳ,;\\.\\-:!\\)](?![ aeiouyòàéỳ,;\\.\\-:!\\)])", RegexOption.IGNORE_CASE) val REGEX_VOWELS_STAGE1 = Regex("[aeiouyòàéỳ](?![,;\\.\\-:!\\?\\}»_]*([ aeiouyòàéỳ/]|_[1-9]))", RegexOption.IGNORE_CASE)
val REGEX_VOWELS_STAGE2 = Regex("([aeiouyòàéỳ,;\\.\\-:!])__", RegexOption.IGNORE_CASE) val REGEX_VOWELS_STAGE2 = Regex("(?<=[aeiouyòàéỳ])_([,;\\.\\-:!\\?\\}»_]+)", RegexOption.IGNORE_CASE)
val REGEX_VOWELS_STAGE3 = Regex("_([\\?\\!:,;\\\\)]+)") val REGEX_VOWELS_STAGE3 = Regex("_([\\?\\!:,;\\\\)]+)")
val REGEX_MALAGASY_MN = Regex("([aeio])_([nm])([tdjkbp])") val REGEX_MALAGASY_MN = Regex("([aeio])_([nm])([tdjkbp])")
val REGEX_MALAGASY_MN_DASHED = Regex("([aeio][nm])\\-([tdjkbp])")
val REGEX_MALAGASY_MN_STAGE2 = Regex("_([mn])-") val REGEX_MALAGASY_MN_STAGE2 = Regex("_([mn])-")
} }
var nextTIndex: Int = -1 var nextTIndex: Int = -1
@ -118,6 +117,7 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository
T.clear() T.clear()
N.clear() N.clear()
L.clear() L.clear()
refrainBeginsAt = -1
unparsedNote.clear() unparsedNote.clear()
templateString = "" templateString = ""
nextTIndex = -1 nextTIndex = -1
@ -417,7 +417,7 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository
private fun loadL(stanzaNumber: Int, lyrics: String) { private fun loadL(stanzaNumber: Int, lyrics: String) {
try { try {
getLyricsComments(lyrics) getLyricsComments(lyrics)
var loadedLyrics = lyrics.replace(REGEX_LYRICS_COMMENT, "") val loadedLyrics = lyrics.replace(REGEX_LYRICS_COMMENT, "")
.replace(REGEX_LYRICS_REPETITION) { matchResult -> .replace(REGEX_LYRICS_REPETITION) { matchResult ->
val repeating = matchResult.destructured.match.groupValues[1] val repeating = matchResult.destructured.match.groupValues[1]
"_".repeat(repeating.toString().toInt()) "_".repeat(repeating.toString().toInt())
@ -428,7 +428,7 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository
arrayLyrics.forEachIndexed { i, lyricsItem -> arrayLyrics.forEachIndexed { i, lyricsItem ->
addLyricsItem(stanzaNumber, i, lyricsItem) addLyricsItem(stanzaNumber, i, lyricsItem)
} }
if (refrainBeginsAt > 0 && stanzaNumber > 1) { if (refrainBeginsAt > 0 && stanzaNumber > 1 && !lyrics.contains($$"${R!}")) {
copyRefrainToStanza(stanzaNumber) copyRefrainToStanza(stanzaNumber)
} }
@ -451,14 +451,19 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository
if (stanzaNumber > sharedScreenModel.nbStanzas.value) { if (stanzaNumber > sharedScreenModel.nbStanzas.value) {
sharedScreenModel.setNbStanzas(stanzaNumber) sharedScreenModel.setNbStanzas(stanzaNumber)
} }
lyricsComment.clear()
} }
// loadY is a smart lyrics parser for Malagasy language // loadY is a smart lyrics parser for Malagasy language
private fun loadY(intKey: Int, lyrics: String) { private fun loadY(intKey: Int, lyrics: String) {
lyricsComment.clear()
val loadedLyrics = lyrics val loadedLyrics = lyrics
.replace(REGEX_MALAGASY_MN_DASHED, "$1-\\\\$2") .also { println(it)}
.replace(REGEX_VOWELS_STAGE1, "$0_") .replace(REGEX_VOWELS_STAGE1, "$0_")
.also { println(it)}
.replace(REGEX_VOWELS_STAGE2, "$1_") .replace(REGEX_VOWELS_STAGE2, "$1_")
.also { println(it)}
.replace(REGEX_VOWELS_STAGE3, "$1_") .replace(REGEX_VOWELS_STAGE3, "$1_")
.also { println(it)}
.replace(" ", " _") .replace(" ", " _")
.replace("_\\ _", " ") .replace("_\\ _", " ")
.replace("_\\", "") .replace("_\\", "")
@ -468,7 +473,7 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository
.replace(REGEX_MALAGASY_MN_STAGE2, "$1-_") .replace(REGEX_MALAGASY_MN_STAGE2, "$1-_")
.replace("_n'", "n'_") .replace("_n'", "n'_")
getLyricsComments(loadedLyrics) getLyricsComments(loadedLyrics)
loadL(intKey, loadedLyrics.replace(REGEX_LYRICS_COMMENT, "")) loadL(intKey, loadedLyrics)
} }
// loadE is a smart Lyrics parser for English language // loadE is a smart Lyrics parser for English language
private fun loadE(intKey: Int, lyrics: String) { private fun loadE(intKey: Int, lyrics: String) {