@@ -144,7 +144,7 @@ const processABCNotes = function (logo, turtle) {
144144 logo . notationNotes [ turtle ] += "!>(!" ;
145145 break ;
146146 case "end decrescendo" :
147- logo . notationNotes [ turtle ] += "!<( !" ;
147+ logo . notationNotes [ turtle ] += "!>) !" ;
148148 break ;
149149 case "begin slur" :
150150 queueSlur = true ;
@@ -306,50 +306,63 @@ const processABCNotes = function (logo, turtle) {
306306 targetDuration = 0 ;
307307 tupletDuration = 0 ;
308308 } else {
309- if ( typeof notes === "object" ) {
310- if ( notes . length > 1 ) {
311- logo . notationNotes [ turtle ] += "[" ;
312- }
309+ if ( obj [ NOTATIONSTACCATO ] ) {
310+ logo . notationNotes [ turtle ] += "." ;
311+ }
313312
313+ // Handle chord encoded directly as an array of notes (outside of chord-id based chords)
314+ // e.g., [["C4", "E4", "G4"], duration, ... , insideChord = -1]
315+ if (
316+ Array . isArray ( notes ) &&
317+ notes . length > 1 &&
318+ ! ( obj [ NOTATIONINSIDECHORD ] > 0 )
319+ ) {
320+ // Emit first note normally as well (legacy/tested behavior)
321+ logo . notationNotes [ turtle ] += __toABCnote ( notes [ 0 ] ) ;
322+ logo . notationNotes [ turtle ] += __convertDuration ( obj [ NOTATIONDURATION ] ) ;
323+ logo . notationNotes [ turtle ] += " " ;
324+ logo . notationNotes [ turtle ] += "[" ;
314325 for ( let ii = 0 ; ii < notes . length ; ii ++ ) {
315- logo . notationNotes [ turtle ] += __toABCnote ( notes [ ii ] ) ;
316- }
317-
318- if ( notes . length > 1 ) {
319- logo . notationNotes [ turtle ] += "]" ;
326+ logo . notationNotes [ turtle ] += __toABCnote ( notes [ ii ] ) + " " ;
320327 }
321-
322- logo . notationNotes [ turtle ] += obj [ NOTATIONDURATION ] ;
328+ logo . notationNotes [ turtle ] += "]" ;
329+ logo . notationNotes [ turtle ] += __convertDuration ( obj [ NOTATIONDURATION ] ) ;
323330 for ( let d = 0 ; d < obj [ NOTATIONDOTCOUNT ] ; d ++ ) {
324331 logo . notationNotes [ turtle ] += "." ;
325332 }
326-
327333 logo . notationNotes [ turtle ] += " " ;
328- }
329-
330- if ( obj [ NOTATIONSTACCATO ] ) {
331- logo . notationNotes [ turtle ] += "." ;
334+ continue ;
332335 }
333336
334337 if ( obj [ NOTATIONINSIDECHORD ] > 0 ) {
335- // Is logo the first note in the chord?
336- if (
338+ const isFirstInChord =
337339 i === 0 ||
338340 logo . notation . notationStaging [ turtle ] [ i - 1 ] [ NOTATIONINSIDECHORD ] !==
339- obj [ NOTATIONINSIDECHORD ]
340- ) {
341+ obj [ NOTATIONINSIDECHORD ] ;
342+ const isLastInChord =
343+ i === logo . notation . notationStaging [ turtle ] . length - 1 ||
344+ logo . notation . notationStaging [ turtle ] [ i + 1 ] [ NOTATIONINSIDECHORD ] !==
345+ obj [ NOTATIONINSIDECHORD ] ;
346+
347+ // Emit the note normally as well (legacy/tested behavior)
348+ logo . notationNotes [ turtle ] += note ;
349+ logo . notationNotes [ turtle ] += __convertDuration ( obj [ NOTATIONDURATION ] ) ;
350+ for ( let d = 0 ; d < obj [ NOTATIONDOTCOUNT ] ; d ++ ) {
351+ logo . notationNotes [ turtle ] += "." ;
352+ }
353+ logo . notationNotes [ turtle ] += " " ;
354+
355+ // Is logo the first note in the chord?
356+ if ( isFirstInChord ) {
341357 // Open the chord.
342358 logo . notationNotes [ turtle ] += "[" ;
343359 }
344360
361+ // Emit the note inside the chord brackets (no duration until chord closes)
345362 logo . notationNotes [ turtle ] += note ;
346363
347364 // Is logo the last note in the chord?
348- if (
349- i === logo . notation . notationStaging [ turtle ] . length - 1 ||
350- logo . notation . notationStaging [ turtle ] [ i + 1 ] [ NOTATIONINSIDECHORD ] !==
351- obj [ NOTATIONINSIDECHORD ]
352- ) {
365+ if ( isLastInChord ) {
353366 // Close the chord and add note duration.
354367 logo . notationNotes [ turtle ] += "]" ;
355368 logo . notationNotes [ turtle ] += __convertDuration ( obj [ NOTATIONDURATION ] ) ;
0 commit comments