diff --git a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/Solfa.kt b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/Solfa.kt index a745b92..4a274e4 100644 --- a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/Solfa.kt +++ b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/Solfa.kt @@ -1,15 +1,9 @@ package mg.dot.feufaro.solfa import SharedScreenModel -import androidx.compose.runtime.remember -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext +import kotlinx.coroutines.* import mg.dot.feufaro.FileRepository import mg.dot.feufaro.SaveSettings -import mg.dot.feufaro.data.GridTUOData import mg.dot.feufaro.launchFilePicker import mg.dot.feufaro.midi.MidiPitch import mg.dot.feufaro.midi.MidiWriterKotlin @@ -450,11 +444,7 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository MODIF NOTES N1 N2 N3 N4 */ // println("taille tA: ${templatArray.size} et le trgt $targetIdx") - val originalBlock = templatArray[targetIdx] - val markerRegex = Regex("""\$\{.*?\}|\$\w+""") - val deleteCount = originalBlock.replace(markerRegex, "").count { it.isLetter() } - - val updatedNotes = updateSourceLines(lines, templatArray, targetIdx, deleteCount, editState) + val updatedNotes = updateSourceLines(lines, templatArray, targetIdx, editState) // RESTAURATION DES TEMPLATES if (templateString != "") { @@ -523,11 +513,10 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository lines: MutableList, fragments: List, targetIdx: Int, - deleteCount: Int, editState: TUOEditState ): MutableList { /* Notes N1 N2 N3 N4 */ - updateNotesInLines(lines, fragments, targetIdx, deleteCount, editState) + updateNotesInLines(lines, fragments, targetIdx, editState) /* MODIF LYRICS */ //updateLyricsInLines(lines, fragments, targetIdx, deleteCount, editState) return lines @@ -632,7 +621,6 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository lines: MutableList, fragments: List, targetIdx: Int, - deleteCount: Int, editState: TUOEditState ) { val notesByVoice = editState.notesByVoice @@ -647,7 +635,7 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository val prefix = currentLine.substringBefore(":") + ":" val noteBody = currentLine.substringAfter(":") val hasAnchor = noteBody.contains("#") - val noteExpanded = expandNotes(noteBody) + val noteExpanded = expandNotes(noteBody.replace(Regex("\\s+"), "")) // println("Notes===>$noteExpanded") val newNot = notesByVoice[voiceNum] ?: "" @@ -666,10 +654,11 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository val cleanNewNote = revertMusicalInput(newNote) - val regex = Regex("#\\S[',]*|\\s#\\S[',]*|/|\\(|\\)|[drmfsltDRFSTzw][0-9'¹²³⁴⁵₁₂₃₄₅,]*|[-.]") - - - val allTokens = regex.findAll(noteExpanded).map { it.value }.toList() + val regex = Regex("#\\S[',]*|\\s#\\S[',]*|/|\\(|\\)|[drmfsltDRFSTzw][0-9'¹²³⁴⁵₁₂₃₄₅,]*|[-.―•]") + val allTokens = regex.findAll(noteExpanded) + .map { it.value } + .filter { it != "." } + .toList() val targetPointer = getNotePointer(fragments, targetIdx, currentLine) @@ -693,7 +682,7 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository val isStructural = token.contains("#") || token == "/" || token == "(" || token == ")" if (isStructural) { -// println(String.format("%-5d | %-10s | %-8s | %-12s | %-10s", i, token, "STRUCT", "-", "Keep")) + println(String.format("%-5d | %-10s | %-8s | %-12s | %-10s", i, token, "STRUCT", "-", "Keep")) resultTokens.add(token) i++ continue @@ -701,65 +690,62 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository if (currentLogicalIdx == targetPointer) { val originalToken = allTokens[i] - var replacement = if (!hasAnchor) { - val (newBase, newLevel) = parseNoteAndOctave(revertMusicalInput(newNot)) - val (oldBase, oldLevel) = parseNoteAndOctave(revertMusicalInput(oldNot)) - val octaveDiff = newLevel - oldLevel - val (tokenBase, tokenLevel) = parseNoteAndOctave(originalToken) - newBase + formatOctave(tokenLevel + octaveDiff) + //println("Insertition Multiples : $newNot") + val rawUserTokens = regex.findAll(revertMusicalInput(newNot)).map { it.value }.toList() + /** Si y a '-' dans template inutile d' ajouter au notes */ + val hasDashInTemplate = editState.templateFragment.contains("-") + val newUserTokens = if (hasDashInTemplate) { + rawUserTokens.filter { it.matches(Regex("[drmfsltDRFSTzw].*")) } } else { - // SI y a '#' - val anchorMatch = Regex("#([drmfsltDRFST])[',]*").find(noteBody) - val anchorLevel = if (anchorMatch != null) { - val anchorStr = anchorMatch.value - anchorStr.count { it == '\'' } - anchorStr.count { it == ',' } - } else 0 + rawUserTokens + } + //val newUserTokens = regex.findAll(revertMusicalInput(newNot)).map { it.value }.toList() + val oldUserTokens = regex.findAll(revertMusicalInput(oldNot)).map { it.value }.toList() - val newNotCleaned = revertMusicalInput(newNot) - val oldNotCleaned = revertMusicalInput(oldNot) + val firstNewNote = newUserTokens.firstOrNull { it.matches(Regex("[drmfsltDRFSTzw].*")) } ?: "" + val firstOldNote = oldUserTokens.firstOrNull { it.matches(Regex("[drmfsltDRFSTzw].*")) } ?: "" - val (newBase, newLevel) = parseNoteAndOctave(newNotCleaned) - val (oldBase, oldLevel) = parseNoteAndOctave(oldNotCleaned) + val (_, newLvl) = parseNoteAndOctave(firstNewNote) + val (_, oldLvl) = parseNoteAndOctave(firstOldNote) + val octaveDiff = newLvl - oldLvl - val sourceLevel = newLevel - anchorLevel - val formattedOctave = formatOctave(sourceLevel) - val finalPureNew = newBase + formattedOctave - val pureOldBase = oldBase + formatOctave(oldLevel - anchorLevel) + val oldTokensForThisFragment = regex.findAll(revertMusicalInput(oldNot)) + .map { it.value } + .filter { it.matches(Regex("[drmfsltDRFSTzw].*|[-―]")) } + .toList() + val dynamicDeleteCount = oldTokensForThisFragment.size -// println("Ancre niveau: $anchorLevel | UI Level: $newLevel -> Source Level: $sourceLevel") -// - if (finalPureNew.startsWith(pureOldBase) && pureOldBase.isNotEmpty()) { - val addedPart = finalPureNew.substring(pureOldBase.length) - originalToken + addedPart + + newUserTokens.forEach { ut -> + val processedToken = if (ut.matches(Regex("[drmfsltDRFSTzw].*"))) { + val (fileBase, fileLvl) = parseNoteAndOctave(allTokens[i]) + val (uBase, _) = parseNoteAndOctave(ut) + uBase + formatOctave(fileLvl + octaveDiff) } else { - finalPureNew + ut + } +// println("j'aoute $processedToken") + + resultTokens.add(processedToken) + + if (processedToken.matches(Regex("[drmfsltDRFSTzw].*|[-―]"))) { + println(String.format("NEW | %-10s | INSERT | %-12d | REPLACE", processedToken, currentLogicalIdx)) + currentLogicalIdx++ } } -// println( -// String.format( -// "%-5s | %-10s | %-8s | %-12s | %-10s", -// "NEW", replacement, "INSERT", currentLogicalIdx, "REPLACE ($originalToken)" -// ) -// ) - resultTokens.add(replacement) - - var notesSkipped = 0 - while (notesSkipped < deleteCount && i < allTokens.size) { - val nextToken = allTokens[i] - val isNextStructural = - nextToken.contains("#") || nextToken == "/" || nextToken == "(" || nextToken == ")" - - if (!isNextStructural) { - notesSkipped++ + var skipped = 0 + while (skipped < dynamicDeleteCount && i < allTokens.size) { + val nextT = allTokens[i] + if (!nextT.contains("#") && nextT != "/" && nextT != "(" && nextT != ")") { + skipped++ } else if (hasAnchor) { - resultTokens.add(nextToken) + resultTokens.add(nextT) // Garder les ancres si on est en mode ancre } i++ } - currentLogicalIdx += deleteCount } else { // AFFICHAGE NOTE NORMALE // println( @@ -804,7 +790,7 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository private fun revertMusicalInput(input: String): String { return input .replace("• ,", "") - .replace("―•", "") + .replace("•", "") .replace("―", "-") .replace("•", "") .replace("³", "'''")