rrob
rrob

Reputation: 407

Guitar chords custom tag simple parser

Im using markdown for storing lyrics with chords and it works great. https://codepen.io/rrob/pen/GxYgOP Using * for tag <em> for chords and positionig it with css.

But now I want it in presentation and markdown parsing is complicated there. I try to insert tag with str.replace but I cant close tag.

text text *chord* text text 

is replaced with:

text text <em>chord<em> text text 

and I of course need:

text text <em>chord</em> text text 

Pls do you know some simple solution for parsing custom tags like this? Javascript / Jquery.

Upvotes: 5

Views: 795

Answers (2)

Mohit
Mohit

Reputation: 1295

Look at the following function. It iterates each character in the string and replaces the the '*' with <em> or </em> where needed.

/**
 * parse function parse the input raw string and replaces the
 * the star(*) with <em> and </em> where needed.
 * @returns Returns the replaced string.
 */
function parse(str) {
    var ret = ""; // initialize the string.

    for (var x = 0; x < str.length; ++x) {
        if (str[x] == '*') { // The opening.
            ret += "<em>";
            ++x;

            for(; x < str.length; ++x) {
                if (str[x] == '*') { // and the ending is here.
                    ret += "</em>";
                    break;
                } else {
                    ret += str[x];
                }
            }
        } else {
            ret += str[x];
        }
    }

    return ret;
}

console.log(parse("Hello *JS*")); // outputs 'Hello <em>JS</em>

var element = document.querySelector('.chords');
element.innerHTML = parse(element.innerText);

Upvotes: 2

Rory McCrossan
Rory McCrossan

Reputation: 337580

You can use Regex to achieve what you require. You can capture the * characters along with the characters between them and then replace the * with <em> tags. Something like this:

var input = 'text text *chord* text text *chord* text';
var output = input.replace(/\*(.*?)\*/g, '<em>$1</em>');

console.log(output);

Given your Codepen example, the complete thing would look something like this:

$('.chords').html(function(i, html) {
  return html.replace(/\*(.*?)\*/g, '<em>$1</em>');
});
body {
  white-space: pre-line
}

em {
  line-height: 2.3em;
  position: relative;
  color: red;
  top: -1em;
  display: inline-block;
  width: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div class="chords">
  You *Emi*stood before creation
  Eternity within *A*Your hands
  You *G*spoke all li*D*fe into motion
  My *A*soul now to *Fdur*stand
</div>
<div class="chords">
  My *A*soul now to *Fdur*stand
  You *G*spoke all li*D*fe into motion
  Eternity within *A*Your hands
  You *Emi*stood before creation
</div>

Upvotes: 5

Related Questions