Reputation: 144
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.
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
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('] [','] [')
.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
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