@@ -7,6 +7,8 @@ import TextFormatter from './text_formatter';
77import Paragraph from '../chord_sheet/paragraph' ;
88import Line from '../chord_sheet/line' ;
99import { ChordLyricsPair , Comment , SoftLineBreak , Tag } from '../index' ;
10+ import Item from '../chord_sheet/item' ;
11+ import { stringSplitReplace } from '../helpers' ;
1012
1113type FontSection = 'title' | 'subtitle' | 'metadata' | 'text' | 'chord' | 'comment' | 'annotation' ;
1214type LayoutSection = 'header' | 'footer' ;
@@ -67,7 +69,7 @@ type LayoutItem = {
6769} ;
6870
6971type MeasuredItem = {
70- item : ChordLyricsPair | Comment | SoftLineBreak ,
72+ item : ChordLyricsPair | Comment | SoftLineBreak | Tag | Item ,
7173 width : number ,
7274 chordHeight ?: number ,
7375} ;
@@ -361,36 +363,88 @@ class PdfFormatter extends Formatter {
361363 const lyricsFont : FontConfiguration = this . getFontConfiguration ( 'text' ) ;
362364 const commentFont : FontConfiguration = this . getFontConfiguration ( 'comment' ) ;
363365
364- const renderedLine = line . items . map ( ( item ) => {
366+ const measuredItems : MeasuredItem [ ] = line . items . flatMap ( ( item : Item ) : MeasuredItem [ ] => {
365367 if ( isChordLyricsPair ( item ) ) {
366- const chordLyricsPair = item as ChordLyricsPair ;
367- const { chords, lyrics } = chordLyricsPair ;
368- const chordWidth = this . getTextDimensions ( chords , chordFont ) . w ;
369- const lyricWidth = this . getTextDimensions ( lyrics , lyricsFont ) . w ;
370-
371- const pairWidth = ( chordWidth > lyricWidth )
372- ? this . getTextDimensions ( `${ chords } ${ this . spaces } ` , chordFont ) . w
373- : lyricWidth ;
374-
375- return {
376- item : chordLyricsPair ,
377- width : pairWidth ,
378- chordHeight : this . getTextDimensions ( chords , chordFont ) . h ,
379- } ;
380- } else if ( isTag ( item ) && isComment ( item as Tag ) ) {
381- const comment = item as Tag ;
382- const commentWidth = this . getTextDimensions ( comment . value , commentFont ) . w ;
368+ const items : Array < ChordLyricsPair | SoftLineBreak > =
369+ this . addSoftLineBreaksToChordLyricsPair ( item as ChordLyricsPair ) ;
383370
384- return {
385- item : comment ,
386- width : commentWidth ,
387- } ;
371+ return items . flatMap ( ( i ) : MeasuredItem [ ] => (
372+ this . measureItem ( i , chordFont , lyricsFont , commentFont )
373+ ) ) ;
374+ } else if ( isTag ( item ) && isComment ( item as Tag ) ) {
375+ return this . measureTag ( item as Tag , commentFont ) ;
388376 } else {
389- return { item, width : 0 } ;
377+ return [ { item, width : 0 } ] ;
390378 }
391379 } ) ;
392380
393- this . renderLineItems ( renderedLine ) ;
381+ this . renderLineItems ( measuredItems ) ;
382+ }
383+
384+ measureItem (
385+ item : ChordLyricsPair | SoftLineBreak ,
386+ chordFont : FontConfiguration ,
387+ lyricFont : FontConfiguration ,
388+ commentFont : FontConfiguration ,
389+ ) : MeasuredItem [ ] {
390+ if ( item instanceof ChordLyricsPair ) {
391+ return this . measureChordLyricsPair ( item , chordFont , lyricFont ) ;
392+ }
393+
394+ if ( item instanceof Tag && isComment ( item ) ) {
395+ return this . measureTag ( item , commentFont ) ;
396+ }
397+
398+ return [ ] ;
399+ }
400+
401+ addSoftLineBreaksToChordLyricsPair ( chordLyricsPair : ChordLyricsPair ) : Array < ChordLyricsPair | SoftLineBreak > {
402+ const { annotation, chords, lyrics } = chordLyricsPair ;
403+
404+ const items : Array < ChordLyricsPair | SoftLineBreak > = stringSplitReplace (
405+ lyrics || '' ,
406+ / , \s * / ,
407+ ( content ) => [ new SoftLineBreak ( ) , new ChordLyricsPair ( '' , content ) ] ,
408+ ( lyric ) => new ChordLyricsPair ( '' , lyric ) ,
409+ ) . flat ( ) ;
410+
411+ let [ first , ...rest ] = items ;
412+ let addedLeadingPair : ChordLyricsPair | null = null ;
413+
414+ if ( chords !== '' || annotation !== '' ) {
415+ if ( ! first || first instanceof SoftLineBreak ) {
416+ addedLeadingPair = new ChordLyricsPair ( chords , lyrics , annotation ) ;
417+ } else {
418+ first = new ChordLyricsPair ( chords , first . lyrics , annotation ) ;
419+ }
420+ }
421+
422+ return [ addedLeadingPair , first , ...rest ] . filter ( ( item ) => item !== null ) ;
423+ }
424+
425+ measureChordLyricsPair (
426+ item : ChordLyricsPair ,
427+ chordFont : FontConfiguration ,
428+ lyricsFont : FontConfiguration ,
429+ ) : MeasuredItem [ ] {
430+ const { chords, lyrics } = item ;
431+ const chordWidth = this . getTextDimensions ( chords , chordFont ) . w ;
432+ const lyricWidth = this . getTextDimensions ( lyrics , lyricsFont ) . w ;
433+
434+ const pairWidth = ( chordWidth > lyricWidth )
435+ ? this . getTextDimensions ( `${ chords } ${ this . spaces } ` , chordFont ) . w
436+ : lyricWidth ;
437+
438+ return [ {
439+ item,
440+ width : pairWidth ,
441+ chordHeight : this . getTextDimensions ( chords , chordFont ) . h ,
442+ } ] ;
443+ }
444+
445+ measureTag ( item : Tag , font : FontConfiguration ) : MeasuredItem [ ] {
446+ const tagWidth = this . getTextDimensions ( item . value , font ) . w ;
447+ return [ { item, width : tagWidth } ] ;
394448 }
395449
396450 get spaces ( ) {
0 commit comments