chordsheetjs 14.5.1 → 14.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js CHANGED
@@ -923,6 +923,7 @@ const $3d106a0ee348cfa8$export$40141681ebb03523 = {
923
923
  * @param {Chord | null} chordObj Optional pre-parsed Chord object
924
924
  * @param {boolean} isRhythmSymbol Whether this pair represents a rhythm symbol
925
925
  */ constructor(chords = '', lyrics = null, annotation = null, chordObj = null, isRhythmSymbol = false){
926
+ this.parentLine = null;
926
927
  this._chordObj = null;
927
928
  this.chords = chords || '';
928
929
  this.lyrics = lyrics || '';
@@ -4034,8 +4035,9 @@ const $b0c0093f9a3a0967$export$98e6a39c04603d36 = $b0c0093f9a3a0967$var$peg$pars
4034
4035
  * @returns {string} the chord string
4035
4036
  */ toString({ useUnicodeModifier: useUnicodeModifier = false } = {}) {
4036
4037
  let chordString = '';
4037
- const suffix = this.suffix || '';
4038
+ let suffix = this.suffix || '';
4038
4039
  const showMinor = suffix[0] !== 'm';
4040
+ if (useUnicodeModifier) suffix = suffix.replace(/#(?=\d)/g, '\u266f').replace(/b(?=\d)/g, '\u266d');
4039
4041
  if (this.root) chordString = this.root.toString({
4040
4042
  showMinor: showMinor,
4041
4043
  useUnicodeModifier: useUnicodeModifier
@@ -5132,6 +5134,7 @@ var $6c1ed1378c3b5965$export$2e2bcd8739ae039 = $6c1ed1378c3b5965$var$ChordDefini
5132
5134
  * Represents a comment. See https://www.chordpro.org/chordpro/chordpro-file-format-specification/#overview
5133
5135
  */ class $0bd084786477abba$var$Comment {
5134
5136
  constructor(content){
5137
+ this.parentLine = null;
5135
5138
  this.content = content;
5136
5139
  }
5137
5140
  /**
@@ -5156,6 +5159,7 @@ var $0bd084786477abba$export$2e2bcd8739ae039 = $0bd084786477abba$var$Comment;
5156
5159
 
5157
5160
  class $c5ce4fc4f57fe810$var$AstComponent {
5158
5161
  constructor(traceInfo = null){
5162
+ this.parentLine = null;
5159
5163
  this.line = null;
5160
5164
  this.column = null;
5161
5165
  this.offset = null;
@@ -5662,129 +5666,301 @@ const $fb5aa6e96efc0a76$export$ccccd344e69710ef = {
5662
5666
  },
5663
5667
  fonts: {
5664
5668
  title: {
5665
- name: 'NimbusSansL-Bol',
5669
+ name: 'Arial',
5666
5670
  style: 'bold',
5667
- size: 24,
5668
- color: 'black'
5671
+ size: 22,
5672
+ color: '#151515'
5669
5673
  },
5670
5674
  subtitle: {
5671
- name: 'NimbusSansL-Reg',
5675
+ name: 'Arial',
5672
5676
  style: 'normal',
5673
- size: 10,
5674
- color: 100
5677
+ size: 11,
5678
+ color: '#6f6f6f'
5675
5679
  },
5676
5680
  metadata: {
5677
- name: 'NimbusSansL-Reg',
5681
+ name: 'Arial',
5678
5682
  style: 'normal',
5679
5683
  size: 10,
5680
- color: 100
5684
+ color: '#8b8b8b'
5681
5685
  },
5682
5686
  text: {
5683
- name: 'NimbusSansL-Reg',
5687
+ name: 'Arial',
5684
5688
  style: 'normal',
5685
5689
  size: 10,
5686
- color: 'black'
5690
+ color: '#232323'
5687
5691
  },
5688
5692
  chord: {
5689
- name: 'NimbusSansL-Bol',
5693
+ name: 'Arial',
5690
5694
  style: 'bold',
5691
5695
  size: 9,
5692
- color: 'black'
5696
+ color: '#232323'
5693
5697
  },
5694
5698
  comment: {
5695
- name: 'NimbusSansL-Bol',
5699
+ name: 'Arial',
5696
5700
  style: 'bold',
5697
5701
  size: 10,
5698
- color: 'black'
5702
+ color: '#232323'
5699
5703
  },
5700
5704
  sectionLabel: {
5701
- name: 'NimbusSansL-Bol',
5705
+ name: 'Arial',
5702
5706
  style: 'bold',
5703
5707
  size: 10,
5704
- color: 'black'
5708
+ color: '#a1312d'
5705
5709
  },
5706
5710
  annotation: {
5707
- name: 'NimbusSansL-Reg',
5711
+ name: 'Arial',
5708
5712
  style: 'normal',
5709
5713
  size: 10,
5710
- color: 'black'
5714
+ color: '#232323'
5711
5715
  }
5712
5716
  },
5713
5717
  layout: {
5714
5718
  global: {
5715
5719
  margins: {
5716
- top: 35,
5717
- bottom: 10,
5720
+ top: 14,
5721
+ bottom: 12,
5718
5722
  left: 45,
5719
5723
  right: 45
5720
5724
  }
5721
5725
  },
5722
5726
  header: {
5723
- height: 60,
5727
+ height: 72,
5724
5728
  content: [
5725
5729
  {
5726
5730
  type: 'text',
5727
5731
  template: '%{title}',
5728
5732
  style: {
5729
- name: 'NimbusSansL-Bol',
5733
+ name: 'Arial',
5730
5734
  style: 'bold',
5731
- size: 24,
5732
- color: 'black'
5735
+ size: 19,
5736
+ color: '#151515',
5737
+ weight: 700
5733
5738
  },
5734
5739
  position: {
5735
5740
  x: 'left',
5736
- y: 15
5741
+ y: 0,
5742
+ clip: true,
5743
+ ellipsis: true
5744
+ },
5745
+ condition: {
5746
+ page: {
5747
+ first: true
5748
+ }
5737
5749
  }
5738
5750
  },
5739
5751
  {
5740
5752
  type: 'text',
5741
- template: 'Key of %{key} - BPM %{tempo} - Time %{time}',
5753
+ template: '%{artist}',
5742
5754
  style: {
5743
- name: 'NimbusSansL-Reg',
5755
+ name: 'Arial',
5744
5756
  style: 'normal',
5745
- size: 12,
5746
- color: 100
5757
+ size: 11,
5758
+ color: '#6f6f6f'
5747
5759
  },
5748
5760
  position: {
5749
5761
  x: 'left',
5750
- y: 28
5762
+ y: 25,
5763
+ clip: true,
5764
+ ellipsis: true
5765
+ },
5766
+ condition: {
5767
+ page: {
5768
+ first: true
5769
+ }
5751
5770
  }
5752
5771
  },
5753
5772
  {
5754
5773
  type: 'text',
5755
- template: 'By %{artist} %{subtitle}',
5774
+ template: '%{tempo|%{} BPM}%{time| \u00b7 %{}}%{capo| \u00b7 Capo %{}}',
5756
5775
  style: {
5757
- name: 'NimbusSansL-Reg',
5776
+ name: 'Arial',
5758
5777
  style: 'normal',
5759
- size: 10,
5760
- color: 100
5778
+ size: 11,
5779
+ color: '#6f6f6f'
5761
5780
  },
5762
5781
  position: {
5763
5782
  x: 'left',
5764
- y: 38
5783
+ y: 40,
5784
+ width: 240,
5785
+ clip: true,
5786
+ ellipsis: true
5787
+ },
5788
+ condition: {
5789
+ page: {
5790
+ first: true
5791
+ }
5765
5792
  }
5766
- }
5767
- ]
5768
- },
5769
- footer: {
5770
- height: 30,
5771
- content: [
5793
+ },
5794
+ {
5795
+ type: 'line',
5796
+ style: {
5797
+ width: 1,
5798
+ color: '#d7d7d7'
5799
+ },
5800
+ position: {
5801
+ x: 0,
5802
+ y: 60,
5803
+ width: 'auto',
5804
+ height: 0
5805
+ },
5806
+ condition: {
5807
+ page: {
5808
+ first: true
5809
+ }
5810
+ }
5811
+ },
5772
5812
  {
5773
5813
  type: 'text',
5774
- value: "\xa92024 My Music Publishing",
5814
+ template: '%{key}',
5815
+ cssClass: 'measured-html-key-badge',
5816
+ elementStyle: {
5817
+ width: '28px',
5818
+ height: '28px',
5819
+ display: 'flex',
5820
+ alignItems: 'center',
5821
+ justifyContent: 'center',
5822
+ borderRadius: '999px',
5823
+ backgroundColor: '#a1312d',
5824
+ textAlign: 'center',
5825
+ boxSizing: 'border-box'
5826
+ },
5775
5827
  style: {
5776
- name: 'NimbusSansL-Reg',
5828
+ name: 'Arial',
5829
+ style: 'bold',
5830
+ size: 12,
5831
+ color: '#ffffff',
5832
+ weight: 700
5833
+ },
5834
+ position: {
5835
+ x: 'right',
5836
+ y: 12,
5837
+ width: 28,
5838
+ offsetX: -2
5839
+ },
5840
+ condition: {
5841
+ and: [
5842
+ {
5843
+ page: {
5844
+ first: true
5845
+ }
5846
+ },
5847
+ {
5848
+ key: {
5849
+ exists: true
5850
+ }
5851
+ }
5852
+ ]
5853
+ }
5854
+ },
5855
+ {
5856
+ type: 'text',
5857
+ template: '%{title}',
5858
+ style: {
5859
+ name: 'Arial',
5860
+ style: 'bold',
5861
+ size: 12,
5862
+ color: '#151515',
5863
+ weight: 700
5864
+ },
5865
+ position: {
5866
+ x: 'left',
5867
+ y: 0,
5868
+ clip: true,
5869
+ ellipsis: true
5870
+ },
5871
+ condition: {
5872
+ page: {
5873
+ greater_than: 1
5874
+ }
5875
+ }
5876
+ },
5877
+ {
5878
+ type: 'text',
5879
+ template: '%{page}/%{pages}',
5880
+ style: {
5881
+ name: 'Arial',
5777
5882
  style: 'normal',
5778
5883
  size: 10,
5779
- color: 'black'
5884
+ color: '#9a9a9a'
5780
5885
  },
5781
5886
  position: {
5782
- x: 'left',
5783
- y: 0
5887
+ x: 'right',
5888
+ y: 4,
5889
+ offsetX: -38
5890
+ },
5891
+ condition: {
5892
+ page: {
5893
+ greater_than: 1
5894
+ }
5895
+ }
5896
+ },
5897
+ {
5898
+ type: 'text',
5899
+ template: '%{key}',
5900
+ cssClass: 'measured-html-key-badge',
5901
+ elementStyle: {
5902
+ width: '28px',
5903
+ height: '28px',
5904
+ display: 'flex',
5905
+ alignItems: 'center',
5906
+ justifyContent: 'center',
5907
+ borderRadius: '999px',
5908
+ backgroundColor: '#a1312d',
5909
+ textAlign: 'center',
5910
+ boxSizing: 'border-box'
5911
+ },
5912
+ style: {
5913
+ name: 'Arial',
5914
+ style: 'bold',
5915
+ size: 12,
5916
+ color: '#ffffff',
5917
+ weight: 700
5918
+ },
5919
+ position: {
5920
+ x: 'right',
5921
+ y: 2,
5922
+ width: 28,
5923
+ offsetX: -2
5924
+ },
5925
+ condition: {
5926
+ and: [
5927
+ {
5928
+ page: {
5929
+ greater_than: 1
5930
+ }
5931
+ },
5932
+ {
5933
+ key: {
5934
+ exists: true
5935
+ }
5936
+ }
5937
+ ]
5938
+ }
5939
+ },
5940
+ {
5941
+ type: 'line',
5942
+ style: {
5943
+ width: 1,
5944
+ color: '#d7d7d7'
5945
+ },
5946
+ position: {
5947
+ x: 0,
5948
+ y: 32,
5949
+ width: 'auto',
5950
+ height: 0
5951
+ },
5952
+ condition: {
5953
+ page: {
5954
+ greater_than: 1
5955
+ }
5784
5956
  }
5785
5957
  }
5786
5958
  ]
5787
5959
  },
5960
+ footer: {
5961
+ height: 0,
5962
+ content: []
5963
+ },
5788
5964
  sections: {
5789
5965
  global: {
5790
5966
  paragraphSpacing: 10,
@@ -5831,22 +6007,22 @@ const $fb5aa6e96efc0a76$export$ccccd344e69710ef = {
5831
6007
  },
5832
6008
  fonts: {
5833
6009
  title: {
5834
- name: 'NimbusSansL-Bol',
6010
+ name: 'Arial',
5835
6011
  style: 'bold',
5836
6012
  size: 9,
5837
- color: 'black'
6013
+ color: '#232323'
5838
6014
  },
5839
6015
  fingerings: {
5840
- name: 'NimbusSansL-Bol',
6016
+ name: 'Arial',
5841
6017
  style: 'bold',
5842
6018
  size: 6,
5843
- color: 'black'
6019
+ color: '#232323'
5844
6020
  },
5845
6021
  baseFret: {
5846
- name: 'NimbusSansL-Bol',
6022
+ name: 'Arial',
5847
6023
  style: 'bold',
5848
6024
  size: 6,
5849
- color: 'black'
6025
+ color: '#232323'
5850
6026
  }
5851
6027
  }
5852
6028
  }
@@ -6666,7 +6842,11 @@ var $3b7d86e1e1307736$export$2e2bcd8739ae039 = $3b7d86e1e1307736$var$Font;
6666
6842
  if (item instanceof (0, $7251dad5f4a4c35f$export$2e2bcd8739ae039)) this.addTag(item);
6667
6843
  else if (item instanceof (0, $551a223fc13b5c10$export$2e2bcd8739ae039)) this.addChordLyricsPair(item);
6668
6844
  else if (item instanceof (0, $0bd084786477abba$export$2e2bcd8739ae039)) this.addComment(item);
6669
- else this.items.push(item);
6845
+ else {
6846
+ const addedItem = item;
6847
+ addedItem.parentLine = this;
6848
+ this.items.push(addedItem);
6849
+ }
6670
6850
  }
6671
6851
  /**
6672
6852
  * Indicates whether the line contains items that are renderable
@@ -6735,6 +6915,7 @@ var $3b7d86e1e1307736$export$2e2bcd8739ae039 = $3b7d86e1e1307736$var$Font;
6735
6915
  addChordLyricsPair(chords = null, lyrics = null) {
6736
6916
  if (chords instanceof (0, $551a223fc13b5c10$export$2e2bcd8739ae039)) this.currentChordLyricsPair = chords;
6737
6917
  else this.currentChordLyricsPair = new (0, $551a223fc13b5c10$export$2e2bcd8739ae039)(chords || '', lyrics || '');
6918
+ this.currentChordLyricsPair.parentLine = this;
6738
6919
  this.items.push(this.currentChordLyricsPair);
6739
6920
  return this.currentChordLyricsPair;
6740
6921
  }
@@ -6751,11 +6932,13 @@ var $3b7d86e1e1307736$export$2e2bcd8739ae039 = $3b7d86e1e1307736$var$Font;
6751
6932
  }
6752
6933
  addTag(nameOrTag, value = null) {
6753
6934
  const tag = nameOrTag instanceof (0, $7251dad5f4a4c35f$export$2e2bcd8739ae039) ? nameOrTag : new (0, $7251dad5f4a4c35f$export$2e2bcd8739ae039)(nameOrTag, value);
6935
+ tag.parentLine = this;
6754
6936
  this.items.push(tag);
6755
6937
  return tag;
6756
6938
  }
6757
6939
  addComment(content) {
6758
6940
  const comment = content instanceof (0, $0bd084786477abba$export$2e2bcd8739ae039) ? content : new (0, $0bd084786477abba$export$2e2bcd8739ae039)(content);
6941
+ comment.parentLine = this;
6759
6942
  this.items.push(comment);
6760
6943
  return comment;
6761
6944
  }
@@ -7433,6 +7616,7 @@ var $feda9c006f56d800$export$2e2bcd8739ae039 = $feda9c006f56d800$var$SongMapper;
7433
7616
 
7434
7617
 
7435
7618
 
7619
+
7436
7620
  const $e02a17f5a26edf19$var$defaultConstructorOptions = {
7437
7621
  capo: 0,
7438
7622
  contextKey: null,
@@ -8129,7 +8313,7 @@ function $4903bcb4483a26e6$export$9b09a67f52000acf(configuration) {
8129
8313
  });
8130
8314
  }
8131
8315
  if (item instanceof (0, $551a223fc13b5c10$export$2e2bcd8739ae039)) return $c53141c05fae8382$var$Song.transposeChordLyricsPair(item, delta, transposedKey, normalizeChordSuffix, accidental);
8132
- if (item instanceof (0, $11953cb6035032a3$export$2e2bcd8739ae039)) return $c53141c05fae8382$var$Song.transposeLiteral(item, delta, transposedKey, normalizeChordSuffix, accidental);
8316
+ if (item instanceof (0, $11953cb6035032a3$export$2e2bcd8739ae039) && $c53141c05fae8382$var$Song.isMusicalSection(item.parentLine)) return $c53141c05fae8382$var$Song.transposeLiteral(item, delta, transposedKey, normalizeChordSuffix, accidental);
8133
8317
  return item;
8134
8318
  });
8135
8319
  }
@@ -8234,10 +8418,18 @@ function $4903bcb4483a26e6$export$9b09a67f52000acf(configuration) {
8234
8418
  changeChords(func) {
8235
8419
  return this.mapItems((item)=>{
8236
8420
  if (item instanceof (0, $551a223fc13b5c10$export$2e2bcd8739ae039)) return item.changeChord(func);
8237
- if (item instanceof (0, $11953cb6035032a3$export$2e2bcd8739ae039)) return $c53141c05fae8382$var$Song.mapChordsInLiteral(item, func);
8421
+ if (item instanceof (0, $11953cb6035032a3$export$2e2bcd8739ae039) && $c53141c05fae8382$var$Song.isMusicalSection(item.parentLine)) return $c53141c05fae8382$var$Song.mapChordsInLiteral(item, func);
8238
8422
  return item;
8239
8423
  });
8240
8424
  }
8425
+ static isMusicalSection(line) {
8426
+ return line === null || ![
8427
+ (0, $dce48cb70c4120bb$export$92249c36c213e508),
8428
+ (0, $dce48cb70c4120bb$export$6a5a2eab72b6e3d),
8429
+ (0, $dce48cb70c4120bb$export$13f4b12aafeba5d6),
8430
+ (0, $dce48cb70c4120bb$export$5a2cf64ea612936a)
8431
+ ].includes(line.type);
8432
+ }
8241
8433
  static mapChordsInLiteral(item, func) {
8242
8434
  // Handle space-separated chords in grid format (e.g., "|| Am . . | C . |")
8243
8435
  const changedString = item.string.replace(/(\s|^)(\S+)(?=\s|$)/g, (_match, space, token)=>{
@@ -27162,6 +27354,7 @@ class $0594288a7c3f9fa6$export$94eb343ca6d26096 {
27162
27354
  /**
27163
27355
  * Gets conditional CSS styles from font configuration
27164
27356
  */ getConditionalStyles(style) {
27357
+ const normalizedFontStyles = this.getNormalizedFontStyles(style);
27165
27358
  return {
27166
27359
  ...style.name && {
27167
27360
  fontFamily: style.name
@@ -27169,15 +27362,7 @@ class $0594288a7c3f9fa6$export$94eb343ca6d26096 {
27169
27362
  ...style.size && {
27170
27363
  fontSize: `${style.size}px`
27171
27364
  },
27172
- ...style.weight && {
27173
- fontWeight: style.weight
27174
- },
27175
- ...style.style && {
27176
- fontStyle: style.style
27177
- },
27178
- ...style.color && {
27179
- color: style.color
27180
- },
27365
+ ...normalizedFontStyles,
27181
27366
  ...style.underline && {
27182
27367
  textDecoration: 'underline'
27183
27368
  },
@@ -27225,6 +27410,7 @@ class $0594288a7c3f9fa6$export$94eb343ca6d26096 {
27225
27410
  /**
27226
27411
  * Applies font styles to an HTML element
27227
27412
  */ applyFontStyle(element, style) {
27413
+ const normalizedFontStyles = this.getNormalizedFontStyles(style);
27228
27414
  const styles = {
27229
27415
  whiteSpace: 'pre',
27230
27416
  ...style.name && {
@@ -27233,15 +27419,7 @@ class $0594288a7c3f9fa6$export$94eb343ca6d26096 {
27233
27419
  ...style.size && {
27234
27420
  fontSize: `${style.size}px`
27235
27421
  },
27236
- ...style.weight && {
27237
- fontWeight: style.weight
27238
- },
27239
- ...style.style && {
27240
- fontStyle: style.style
27241
- },
27242
- ...style.color && {
27243
- color: style.color
27244
- },
27422
+ ...normalizedFontStyles,
27245
27423
  ...style.underline && {
27246
27424
  textDecoration: 'underline'
27247
27425
  },
@@ -27271,6 +27449,27 @@ class $0594288a7c3f9fa6$export$94eb343ca6d26096 {
27271
27449
  */ getCustomClass(elementType) {
27272
27450
  return this.config.cssClasses?.[elementType];
27273
27451
  }
27452
+ getNormalizedFontStyles(style) {
27453
+ const fontWeight = style.weight ?? (style.style === 'bold' ? 'bold' : undefined);
27454
+ const fontStyle = style.style && style.style !== 'bold' ? style.style : undefined;
27455
+ const color = this.normalizeColor(style.color);
27456
+ return {
27457
+ ...fontWeight && {
27458
+ fontWeight: fontWeight
27459
+ },
27460
+ ...fontStyle && {
27461
+ fontStyle: fontStyle
27462
+ },
27463
+ ...color && {
27464
+ color: color
27465
+ }
27466
+ };
27467
+ }
27468
+ normalizeColor(color) {
27469
+ if (typeof color === 'number') return `rgb(${color}, ${color}, ${color})`;
27470
+ if (typeof color === 'string' && /^\d+$/.test(color)) return `rgb(${color}, ${color}, ${color})`;
27471
+ return color;
27472
+ }
27274
27473
  }
27275
27474
  var $0594288a7c3f9fa6$export$2e2bcd8739ae039 = $0594288a7c3f9fa6$export$94eb343ca6d26096;
27276
27475
 
@@ -27522,7 +27721,14 @@ class $2e404bc796b05dec$export$f1e5feaa438be04f {
27522
27721
  if (!contentItem.condition) return true;
27523
27722
  const { metadata: songMetadata, extraMetadata: extraMetadata } = this.context;
27524
27723
  const metadata = new Proxy({}, {
27525
- get: (_, prop)=>extraMetadata?.[prop] ?? songMetadata.get(prop)
27724
+ get: (_, prop)=>{
27725
+ const value = extraMetadata?.[prop] ?? songMetadata.get(prop);
27726
+ if ((prop === 'page' || prop === 'pages' || prop === 'renderTime') && typeof value === 'string') {
27727
+ const numericValue = Number(value);
27728
+ if (!Number.isNaN(numericValue)) return numericValue;
27729
+ }
27730
+ return value;
27731
+ }
27526
27732
  });
27527
27733
  return new (0, $bdd8c6196670168a$export$2e2bcd8739ae039)(contentItem.condition, metadata).evaluate();
27528
27734
  }
@@ -27536,15 +27742,18 @@ class $2e404bc796b05dec$export$f1e5feaa438be04f {
27536
27742
  this.backend.setFontStyle(style);
27537
27743
  const availableWidth = position.width || this.getAvailableWidth();
27538
27744
  const y = sectionY + position.y;
27539
- if (position.clip) this.renderClippedText(textValue, position, availableWidth, y, style);
27540
- else this.renderMultilineText(textValue, position, availableWidth, y, style);
27745
+ if (position.clip) this.renderClippedText(textValue, textItem, availableWidth, y, style);
27746
+ else this.renderMultilineText(textValue, textItem, availableWidth, y, style);
27541
27747
  }
27542
27748
  /**
27543
27749
  * Renders clipped text with optional ellipsis
27544
- */ renderClippedText(textValue, position, availableWidth, y, style) {
27750
+ */ renderClippedText(textValue, textItem, availableWidth, y, style) {
27751
+ const { position: position } = textItem;
27545
27752
  const clippedText = position.ellipsis ? this.clipTextWithEllipsis(textValue, availableWidth, style) : this.clipText(textValue, availableWidth, style);
27546
27753
  const textWidth = this.backend.getTextWidth(clippedText, style);
27547
- const x = this.calculateX(position.x, textWidth);
27754
+ const alignmentWidth = position.width ?? textWidth;
27755
+ this.backend.setTextItem?.(textItem);
27756
+ const x = this.calculateX(position.x, alignmentWidth, position.offsetX);
27548
27757
  this.backend.text(clippedText, x, y);
27549
27758
  }
27550
27759
  /**
@@ -27563,12 +27772,15 @@ class $2e404bc796b05dec$export$f1e5feaa438be04f {
27563
27772
  }
27564
27773
  /**
27565
27774
  * Renders multiline text
27566
- */ renderMultilineText(textValue, position, availableWidth, y, style) {
27775
+ */ renderMultilineText(textValue, textItem, availableWidth, y, style) {
27776
+ const { position: position } = textItem;
27567
27777
  const lines = this.backend.splitTextToSize(textValue, availableWidth, style);
27568
27778
  let tempY = y;
27569
27779
  lines.forEach((line)=>{
27570
27780
  const lineWidth = this.backend.getTextWidth(line, style);
27571
- const x = this.calculateX(position.x, lineWidth);
27781
+ const alignmentWidth = position.width ?? lineWidth;
27782
+ this.backend.setTextItem?.(textItem);
27783
+ const x = this.calculateX(position.x, alignmentWidth, position.offsetX);
27572
27784
  this.backend.text(line, x, tempY);
27573
27785
  tempY += style.size * (style.lineHeight ?? 1.2);
27574
27786
  });
@@ -27577,7 +27789,7 @@ class $2e404bc796b05dec$export$f1e5feaa438be04f {
27577
27789
  * Renders an image
27578
27790
  */ renderImage(imageItem, sectionY) {
27579
27791
  const { src: src, position: position, size: size, alias: alias, compression: compression, rotation: rotation } = imageItem;
27580
- const x = this.calculateX(position.x, size.width);
27792
+ const x = this.calculateX(position.x, size.width, position.offsetX);
27581
27793
  const y = sectionY + position.y;
27582
27794
  const format = src.split('.').pop()?.toUpperCase();
27583
27795
  this.backend.addImage(src, format, x, y, size.width, size.height, alias, compression, rotation);
@@ -27607,16 +27819,16 @@ class $2e404bc796b05dec$export$f1e5feaa438be04f {
27607
27819
  }
27608
27820
  /**
27609
27821
  * Calculates the X position based on alignment
27610
- */ calculateX(alignment, width = 0) {
27822
+ */ calculateX(alignment, width = 0, offsetX = 0) {
27611
27823
  switch(alignment){
27612
27824
  case 'center':
27613
- return this.backend.pageSize.width / 2 - width / 2;
27825
+ return this.backend.pageSize.width / 2 - width / 2 + offsetX;
27614
27826
  case 'right':
27615
- return this.backend.pageSize.width - this.context.margins.right - width;
27827
+ return this.backend.pageSize.width - this.context.margins.right - width + offsetX;
27616
27828
  case 'left':
27617
27829
  default:
27618
- if (typeof alignment === 'number') return this.context.margins.left + alignment;
27619
- return this.context.margins.left;
27830
+ if (typeof alignment === 'number') return this.context.margins.left + alignment + offsetX;
27831
+ return this.context.margins.left + offsetX;
27620
27832
  }
27621
27833
  }
27622
27834
  /**
@@ -27887,8 +28099,6 @@ var $2e404bc796b05dec$export$2e2bcd8739ae039 = $2e404bc796b05dec$export$f1e5feaa
27887
28099
  */ recordRenderingTime() {
27888
28100
  const endTime = performance.now();
27889
28101
  this.renderTime = (endTime - this.startTime) / 1000;
27890
- // eslint-disable-next-line no-console
27891
- console.log(`Rendered in ${this.renderTime.toFixed(2)} seconds`);
27892
28102
  }
27893
28103
  /**
27894
28104
  * Get the elements for a specific page
@@ -28005,7 +28215,7 @@ var $952711184d4e89d8$export$2e2bcd8739ae039 = $952711184d4e89d8$var$Renderer;
28005
28215
  /**
28006
28216
  * Creates a new HtmlRenderer
28007
28217
  */ constructor(song, container, configuration){
28008
- super(song), this._dimensions = null, this._dimensionCacheKey = null;
28218
+ super(song), this.currentLayoutFontStyle = null, this.currentLayoutSection = null, this.currentLayoutTextItem = null, this.currentLineStyle = null, this._dimensions = null, this._dimensionCacheKey = null;
28009
28219
  this.container = container;
28010
28220
  this.configuration = configuration;
28011
28221
  this.styler = new (0, $0594288a7c3f9fa6$export$2e2bcd8739ae039)({
@@ -28067,44 +28277,73 @@ var $952711184d4e89d8$export$2e2bcd8739ae039 = $952711184d4e89d8$var$Renderer;
28067
28277
  console.log('Chord diagram rendering is stubbed out');
28068
28278
  }
28069
28279
  renderHeadersAndFooters() {
28070
- const layoutRenderer = this.createLayoutRenderer();
28071
- if (this.getHeaderConfig()) this.doc.eachPage(()=>{
28072
- layoutRenderer.renderLayout(this.getHeaderConfig(), 'header');
28073
- });
28074
- if (this.getFooterConfig()) this.doc.eachPage(()=>{
28075
- layoutRenderer.renderLayout(this.getFooterConfig(), 'footer');
28280
+ const headerConfig = this.getHeaderConfig();
28281
+ const footerConfig = this.getFooterConfig();
28282
+ if (headerConfig) this.renderLayoutForEachPage(headerConfig, 'header');
28283
+ if (footerConfig) this.renderLayoutForEachPage(footerConfig, 'footer');
28284
+ this.resetLayoutRenderingState();
28285
+ }
28286
+ renderLayoutForEachPage(layoutConfig, section) {
28287
+ this.doc.eachPage((_page, index)=>{
28288
+ this.currentLayoutSection = section;
28289
+ this.resetLayoutRenderingState(section);
28290
+ this.createLayoutRenderer(index + 1, this.doc.totalPages).renderLayout(layoutConfig, section);
28076
28291
  });
28077
28292
  }
28078
- createLayoutRenderer() {
28079
- const backend = this.createLayoutBackend();
28293
+ resetLayoutRenderingState(section = null) {
28294
+ this.currentLayoutSection = section;
28295
+ this.currentLayoutFontStyle = null;
28296
+ this.currentLayoutTextItem = null;
28297
+ this.currentLineStyle = null;
28298
+ }
28299
+ createLayoutRenderer(page, totalPages) {
28300
+ const backend = this.createLayoutBackend(page, totalPages);
28080
28301
  return new (0, $2e404bc796b05dec$export$2e2bcd8739ae039)(backend, {
28081
28302
  metadata: this.song.metadata,
28082
28303
  margins: this.dimensions.margins,
28083
- extraMetadata: this.getExtraMetadata(this.doc.currentPage, this.doc.totalPages)
28304
+ extraMetadata: this.getExtraMetadata(page, totalPages)
28084
28305
  });
28085
28306
  }
28086
- createLayoutBackend() {
28307
+ createLayoutBackend(page, totalPages) {
28087
28308
  return {
28088
28309
  pageSize: this.doc.pageSize,
28089
- currentPage: this.doc.currentPage,
28090
- totalPages: this.doc.totalPages,
28310
+ currentPage: page,
28311
+ totalPages: totalPages,
28091
28312
  text: (content, x, y)=>this.renderHtmlText(content, x, y),
28092
28313
  getTextWidth: (text, font)=>this.doc.getTextWidth(text, font),
28093
28314
  splitTextToSize: (text, maxWidth, font)=>this.doc.splitTextToSize(text, maxWidth, font),
28094
- setFontStyle: ()=>{},
28315
+ setFontStyle: (style)=>{
28316
+ this.currentLayoutFontStyle = style;
28317
+ },
28318
+ setTextItem: (item)=>{
28319
+ this.currentLayoutTextItem = item;
28320
+ },
28095
28321
  addElement: (element, x, y)=>this.doc.addElement(element, x, y),
28096
28322
  addImage: (src, _format, x, y, width, height)=>this.renderHtmlImage(src, x, y, width, height),
28097
28323
  line: (x1, y1, x2, y2)=>this.renderHtmlLine(x1, y1, x2, y2),
28098
- setLineStyle: ()=>{},
28324
+ setLineStyle: (style)=>{
28325
+ this.currentLineStyle = style;
28326
+ },
28099
28327
  resetDash: ()=>{}
28100
28328
  };
28101
28329
  }
28102
28330
  renderHtmlText(content, x, y) {
28103
28331
  const element = document.createElement('div');
28104
28332
  element.className = `${this.styler.prefix}header-text`;
28333
+ this.applyLayoutTextClasses(element);
28105
28334
  element.textContent = content;
28335
+ this.applyLayoutTextStyles(element);
28106
28336
  this.doc.addElement(element, x, y);
28107
28337
  }
28338
+ applyLayoutTextClasses(element) {
28339
+ const sectionClass = this.currentLayoutSection ? this.styler.getCustomClass(this.currentLayoutSection) : undefined;
28340
+ if (sectionClass) element.classList.add(sectionClass);
28341
+ if (this.currentLayoutTextItem?.cssClass) element.classList.add(this.currentLayoutTextItem.cssClass);
28342
+ }
28343
+ applyLayoutTextStyles(element) {
28344
+ if (this.currentLayoutTextItem?.elementStyle) Object.assign(element.style, this.currentLayoutTextItem.elementStyle);
28345
+ if (this.currentLayoutFontStyle) this.styler.applyFontStyle(element, this.currentLayoutFontStyle);
28346
+ }
28108
28347
  renderHtmlImage(src, x, y, width, height) {
28109
28348
  const img = document.createElement('img');
28110
28349
  img.className = `${this.styler.prefix}image`;
@@ -28116,11 +28355,12 @@ var $952711184d4e89d8$export$2e2bcd8739ae039 = $952711184d4e89d8$var$Renderer;
28116
28355
  renderHtmlLine(x1, y1, x2, _y2) {
28117
28356
  const lineElement = document.createElement('div');
28118
28357
  lineElement.className = `${this.styler.prefix}line`;
28358
+ const lineStyle = this.currentLineStyle;
28119
28359
  lineElement.style.width = `${x2 - x1}px`;
28120
- lineElement.style.height = '1px';
28121
- lineElement.style.borderBottomWidth = '1px';
28122
- lineElement.style.borderBottomStyle = 'solid';
28123
- lineElement.style.borderBottomColor = '#000000';
28360
+ lineElement.style.height = '0';
28361
+ lineElement.style.borderBottomWidth = `${lineStyle?.width ?? 1}px`;
28362
+ lineElement.style.borderBottomStyle = lineStyle?.dash?.length ? 'dashed' : 'solid';
28363
+ lineElement.style.borderBottomColor = lineStyle?.color ?? '#000000';
28124
28364
  this.doc.addElement(lineElement, x1, y1);
28125
28365
  }
28126
28366
  renderParagraphs(paragraphLayouts) {
@@ -37655,7 +37895,7 @@ const $a5a21ced491ea51f$var$endSectionTags = {
37655
37895
  var $a5a21ced491ea51f$export$2e2bcd8739ae039 = $a5a21ced491ea51f$var$UltimateGuitarParser;
37656
37896
 
37657
37897
 
37658
- var $ae92e002ce14f11a$export$2e2bcd8739ae039 = '14.5.1';
37898
+ var $ae92e002ce14f11a$export$2e2bcd8739ae039 = '14.6.1';
37659
37899
 
37660
37900
 
37661
37901