diff --git a/package-lock.json b/package-lock.json index 651ca12c..686eeb4c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "naadan-chords", - "version": "0.80.5", + "version": "0.80.6", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "naadan-chords", - "version": "0.80.5", + "version": "0.80.6", "dependencies": { "@fortawesome/fontawesome-svg-core": "^1.2.34", "@fortawesome/free-brands-svg-icons": "^5.15.2", diff --git a/package.json b/package.json index 6715c666..c7204222 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "naadan-chords", - "version": "0.80.5", + "version": "0.80.6", "homepage": "https://www.naadanchords.com/", "private": true, "dependencies": { diff --git a/src/containers/ContentParser.js b/src/containers/ContentParser.js index d70c8da8..33d68606 100644 --- a/src/containers/ContentParser.js +++ b/src/containers/ContentParser.js @@ -2,7 +2,7 @@ import React, { Component } from "react"; import ReactDOM from "react-dom"; import { LinkContainer } from "react-router-bootstrap"; import { Tab, Nav } from "react-bootstrap"; -import { parseLinksToHtml, slugify } from "../libs/utils"; +import { getNthOccurenceIndex, parseLinksToHtml, slugify } from "../libs/utils"; import YouTubeEmbed from "../components/YouTubeEmbed"; import ChordControls from "./ChordControls"; import ChordsPopup from "./ChordsPopup"; @@ -130,10 +130,26 @@ export default class ContentParser extends Component { //Chords regex const notes = "[CDEFGAB]"; const tabBeginning = "(?!\\|)"; + const fretNumbers = [ + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "11", + "12", + ]; const chords = - "(maj7|maj|min7|min|sus2|sus4|m7|m6add9|m7sus2|6sus2|7sus4|add9|add4|m|5|6|7|dim)?"; + "(maj7|maj|min7|min|sus2|sus4|m7|m6add9|m7sus2|6sus2|7sus4|add9|add4|5add14|m|5|6|7|dim)?"; const flat = "(b)?"; const sharp = "(#)?"; + const tabNumbers = "([-/hps])([0-9]+)"; const chordsPattern = "\\b" + notes + flat + chords + "\\b" + sharp + chords; const chordsWithSlashPattern = @@ -148,9 +164,49 @@ export default class ContentParser extends Component { chords; const chordsRegex = new RegExp(chordsWithSlashPattern + tabBeginning, "g"); const chordsOnlyRegex = new RegExp(chords, "g"); + const tabsFretNumbersOnlyRegex = new RegExp(tabNumbers, "g"); //replace tabs content = content.replace(tabRegExp, (match, p1) => { + const tabLineStrings = p1.split("\n"); + let longestTabLineLength = 0; + for (let i = 0; i < tabLineStrings.length; i++) { + let tabLine = tabLineStrings[i].trim(); + if (tabLine.includes("-") && tabLine.includes("|")) { + tabLineStrings[i] = tabLineStrings[i].replace( + tabsFretNumbersOnlyRegex, + (match, p1, originalFretPosition) => { + const i = + (Number(originalFretPosition) + this.state.transposeAmount) % + fretNumbers.length; + let newFretPosition = `${ + fretNumbers[i < 0 ? i + fretNumbers.length : i] + }`; + return p1 + newFretPosition; + } + ); + tabLine = tabLineStrings[i]; + let tabLineLength = getNthOccurenceIndex(tabLine, "|", 2) + 1; + if (tabLineLength > longestTabLineLength) { + longestTabLineLength = tabLineLength; + } + } + } + for (let i = 0; i < tabLineStrings.length; i++) { + let tabLine = tabLineStrings[i].trim(); + if (tabLine.includes("-") && tabLine.includes("|")) { + let tabLineLength = getNthOccurenceIndex(tabLine, "|", 2) + 1; + if (tabLineLength < longestTabLineLength) { + const diff = longestTabLineLength - tabLineLength; + const filler = "-".repeat(diff); + tabLineStrings[i] = + tabLine.slice(0, tabLineLength - 2) + + filler + + tabLine.slice(tabLineLength - 2); + } + } + } + p1 = tabLineStrings.join("\n"); return `