enrique
enrique

Reputation: 144

Chord and lyrics format issue

I'll be making a chord and lyrics website. However, the chords cannot be copied because the content is messed up. The desired goal is when the user tries to copy the chord and lyrics and paste it in MS Word or any text editor, the post content (strings, not html) must still be the same without affecting its format which is the chord is on top of the lyrics.

enter image description here

jsfiddle link

var markUpChordLines = function() {
  jQuery('.post-content').html(function(i, html) {
    return html.replace(/\[(.*?)\]/g, '<span class="chord" data-chord="$1"></span>');
  });

  jQuery('.chord').each(function () {
    jQuery(this.nextSibling).wrapAll('<span class="lyric_content"></span>');
    jQuery(this.nextSibling).appendTo(this);
  });
};

markUpChordLines();
span.chord {
  position       : relative;
  display        : inline-flex;
  flex-direction : column;
  vertical-align : bottom;
  }
span.chord:before {
  content     : attr(data-chord);
  position    : relative;
  font-style  : italic;
  font-weight : bold;
  }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="post-content">
  <p style="display: none;">G  D </p>
  <p>Al [G]contrario di [D]te  </p>
  <p>Io[F] non lo s[A]o</p>
  <p>[D] Se è g[G]iusto co[F]sì    </p>
  <p>C[A]omunqu[G]e [D]sia</p>
  <p>Io [G#sus]non mi mu[Fm]ovo</p>
  <p>Io r[Bm]esto qu[E]i</p>
</div>

Upvotes: 2

Views: 439

Answers (2)

Mister Jojo
Mister Jojo

Reputation: 22320

I finally managed to do that, going through html / tables. the rtf format posed too many problems and made me waste time.

const txtP        = document.querySelectorAll('.post-content p')
  ,  rgxCut       = /(?=\[)|(?<=\])/
  ,  zCopyChanged = document.querySelector('#copyChangedZone')
  ;
txtP.forEach(pLine=>pLine.innerHTML = setParagraph_Chord( pLine.textContent ))
  
zCopyChanged.addEventListener('copy', evt => 
  {
  let lines =  (''+document.getSelection()).split('\n').filter(Boolean)

  let tPlain = lines.join('\n')
    , t_html = lines.reduce((a,c)=>a+setTable_chord(c),'')

  evt.clipboardData.setData('text/plain', tPlain )
  evt.clipboardData.setData('text/html', t_html )

  evt.preventDefault()
  })

function setParagraph_Chord (line)
  {
  let newP = line
            .replaceAll('] [',']&emsp;[')
            .split(rgxCut)
            .map(el=>
          {
          if (el[0]!=='[') return el
          let chord = el.substring(1,el.length-1)
          return `<span class="chord" data-chord="${chord}">${el}</span>`
          })
  return  newP.join('')
  }
function setTable_chord( line )
  {
  let tc = []
    , tl = []
    , tx = true
    ;
  line.split(rgxCut).forEach(el=>
    {
    if (el[0]!=='[') 
      {
      if (tx) tc.push('');
      tl.push(el)   
      tx = true     
      }
    else
      {
      tc.push(el.substring(1,el.length-1))
      tx = false
      }
    })
  let rep = '<table style="border-collapse:collapse;white-space:pre;"><tboby>'
          + '<tr><td style="padding:0;font:12px;border:none"><b><i>'
          + tc.join('</td><td style="padding:0;font:12px;border:none"><b><i>')
          + '</td></tr><tr><td style="padding:0;font:15px;border:none">'
          + tl.join('</td><td style="padding:0;font:15px;border:none">')
          + '</td></tr></tboby></table><br>'
  return rep
  }
.post-content {
  line-height : 20px;
  font-size   : 16px;
  font-family : Arial, Helvetica, sans-serif;
  margin      : 2em .7em;
  }
span.chord {
  font-size : 0; 
  position  : relative;
  background: #ca7a6c;
  }
span.chord:after {
  position    : absolute;
  font-size   : 12px;
  top         :  -32px;
  content     : attr(data-chord);
  font-style  : italic;
  font-weight : bold;
  color       : blue;
  transform   : rotate( -30deg );  
  }
p {
  margin : .7em;
  }
h3 { margin-bottom:0; } 
h5 { margin:0 .8em; }  
 
<h3> test a copy here <small>(on lyrics) </small>and past it to :</h3>
<h5> 1 - a simple text editor ( kEdit, notePad...)</h5>
<h5> 2 - a writter editor ( LibreOffice Writer, Word...)</h5>
<hr>
<div id="copyChangedZone">
  <div class="post-content">
    <p>Al [G]contrario di [D]te</p>
    <p>Io[F] non lo s[A]o</p>
    <p>[D] Se è g[G]iusto co[F]sì</p>
    <p>C[A]omunqu[G]e [D]sia</p>
    <p>Io [G#sus]non mi mu[Fm]ovo</p>
    <p>Io r[Bm]esto qu[E]i</p>
  </div>
  <div class="post-content">
    <p>There were [C]bells on a [G°]hill</p>
    <p>[G°]But I [Dm]never heard them [Fm]ringing</p>
    <p>No, I [C]never [Em]heard them [E♭m]at [Dm]all</p>
    <p>[G7]Till there was [C]you [Dm] [G7]</p>
  </div>
  <div class="post-content">
    <p>There were [C]birds in the [G°]sky</p>
    <p>But I [Dm]never saw them [Fm]winging</p>
    <p>No, I [C]never [Em]saw them [E♭m]at [Dm]all</p>
    <p>[G7]Till there was [C]you [F] [C]</p>
  </div>
  <div class="post-content">
    <p>Then there was [F]music and [Fm]wonderful [C]roses</p>
    <p>They [A7]tell me</p>
    <p>In [Dm]sweet fragrant [D7]meadows</p>
    <p>Of [G7]dawn and [G+]dew</p>
  </div>
</div>

Upvotes: 1

Mister Jojo
Mister Jojo

Reputation: 22320

Finaly I have done that:

const txtP  = document.querySelectorAll('.post-content p')
  ,  rgxCut = /(?=\[)|(?<=\])/
  ;
txtP.forEach(pLine=>
  {
  let newP =
    pLine.textContent.split(rgxCut)
        .map(el=>
          {
          if (el[0]!=='[') return el
          let chord = el.substring(1,el.length-1)
          return `<span class="chord" data-chord="${chord}">${el}</span>`
          })
  pLine.innerHTML = newP.join('')
  })
.post-content {
  line-height : 20px;
  font-size   : 16px;
  font-family : Arial, Helvetica, sans-serif;
  margin      : 2em .7em;
  }
span.chord {
  font-size : 0; 
  position  : relative;
  }
span.chord:after {
  position    : absolute;
  font-size   : 12px;
  top         :  -30px;
  content     : attr(data-chord);
  font-style  : italic;
  font-weight : bold;
  color       : blue;
}
<div class="post-content">
  <p style="display: none;">G  D </p>
  <p>Al [G]contrario di [D]te</p>
  <p>Io[F] non lo s[A]o</p>
  <p>[D] Se è g[G]iusto co[F]sì</p>
  <p>C[A]omunqu[G]e [D]sia</p>
  <p>Io [G#sus]non mi mu[Fm]ovo</p>
  <p>Io r[Bm]esto qu[E]i</p>
</div>

Upvotes: 1

Related Questions