1

I want to achieve the following:

1) Check every word from a textarea if it is a guitar chord.

To do that, I created an array which contains all characters that guitar chords have (if a word matches the characters from this array it is a guitar chord):

var Regex = /^\s*(?:(A|B|C|D|E|F|G|A#|C#|D#|F#|G#|Ab|Bb|Db|Eb|Gb){1}(?:m|\+|\-|aug|dim|add|b|#|1|2|3|4|5|6|7|8|9|0|\/)*\s*)+$/;

2) If a word matches, I want it to become a link, pointing to an URL customized by the word itself.

e.g. The following line

Am   Bb  C# Dadd9
Song lyrics here

should turn into

<a href="example.com/Am">Am</a>   <a href="example.com/Bb">Bb</a>  <a href="example.com/C#">C#</a> <a href="example.com/Dadd9">Dadd9</a>
Song lyrics here

And here's what I've com up to for step 2:

var link = "http://www.example.com/";
      $.each(chord, function(index, value) {   //append link to chord
        $('.output').append('<a href="' + link + value + '">' + value + '</a> ');
      });

But I need to define "chord". How can I do to check each word, then if it is a chord (matching "Regex" characters) append link?

2 Answers2

1

You can use String.prototype.replace().

For brevity, let's assume we want to target the Am, Bb and C# chords.

// create a map for the chords to the anchors
var chordsAnchorsMap = {
    "Am": "<a href='https://example.com/a-minor'>Am</a>",
    "Bb": "<a href='https://example.com/b-flat'>Bb</a>",
    "C#": "<a href='https://example.com/c-sharp'>C#</a>"
};

// regular expression for the chords
var regex = /(Am|Bb|C#)/g;

var string = "Am    Bb    C#    Bb   M    Bb";

// replace all instances of the chords with their mapped anchors
var result = string.replace(regex,
    function(capturedChord) {
        // if chord is mapped to an anchor, replace it with the appropriate anchor
        if (chordsAnchorsMap.hasOwnProperty(capturedChord)) {
            return chordsAnchorsMap[capturedChord];
        }
        // else, return the just chord itself (in other words - don't replace it)
        return capturedChord;
    }
);

Now result would contain:

<a href='https://example.com/a-minor'>Am</a>    <a href='https://example.com/b-flat'>Bb</a>    <a href='https://example.com/c-sharp'>C#</a>    <a href='https://example.com/b-flat'>Bb</a>   M    <a href='https://example.com/b-flat'>Bb</a>
Guy Waldman
  • 457
  • 3
  • 12
  • Hi, thank you so much. Actually it seems it's not working to me. Do you have any fiddle or codepen to see it in action? I replaced your string var with $('pre').html() which is the content in my preformatted element (containing the whole tab) – Alberto Moneti Sep 19 '17 at 23:05
1

Here is a distilled version of @GuyWaldman's approach.

What this does is to generate the HTML elements dynamically instead of using an object.

var chordPattern = /(?:(A|B|C|D|E|F|G|A#|C#|D#|F#|G#|Ab|Bb|Db|Eb|Gb){1}(?:m|\+|\-|aug|dim|add|b|#|1|2|3|4|5|6|7|8|9|0|\/)+)/g;
var str = `Am   Bb  C# Dadd9
           Song lyrics here`;
var html = str.replace(chordPattern, function(value){
    return "<a href='https://example.com/"+value+"'>"+value+"</a>";
});
document.write(html);

You may need to adjust the regex because I'm not sure if it will match all possible chords or if it matches only chords. You will also have to find a way to deal with the special characters in the URLs

Titus
  • 22,031
  • 1
  • 23
  • 33
  • The link for `C#` isn't going to work correctly, as the `#` is reserved for the URL fragment. I assume that's why @GuyWaldman was using `c-sharp`. – fubar Sep 19 '17 at 23:38
  • @fubar Yes, I've edited my answer to mention that there can be some problems with the URLs. – Titus Sep 19 '17 at 23:39
  • I guess this would work in case I put C# in some data-value instead of link, right? – Alberto Moneti Sep 20 '17 at 00:22
  • @Titus unfortunately this code returns text all in one line, while I got mine put into a preformatted element to preserve spaces and distances. Take a look here https://jsfiddle.net/7s1fLrqj/ could you adjust it? – Alberto Moneti Sep 20 '17 at 00:41
  • @AlbertoMoneti You've forgot to add the jQuery library. This seems to work https://jsfiddle.net/gsnozqhd/1/ I've added jQuery and made a slight modification to the regex. – Titus Sep 20 '17 at 02:04
  • @AlbertoMoneti and this one contain a crude fix for the URLs problem https://jsfiddle.net/g8x29b75/ – Titus Sep 20 '17 at 02:07