Jump to content

[SOLVED] Convert lyric and chord text to html


oscarale
 Share

Recommended Posts

Hello everyone, I have some lyrics with chords as text, formatted like this:

[Verse]

E             D      G   B
I'll take you for a ride
E       D      G    B
On my garbage truck
B     A
Oh no

Which I write out like this in html:

<div class='lyric'>
  <div class='section' data-section='verse'>
    <p class='line'><span class='chord'>E</span>I'll take you <span class='chord'>D</span>for a r<span class='chord'>G</span>ide<span class='chord'>B</span></p>
    <p class='line'><span class='chord'>E</span>On my ga<span class='chord'>D</span>rbage t<span class='chord'>G</span>ruck<span class='chord'>B</span></p>
    <p class='line'><span class='chord'>B</span>Oh no<span class='chord'>A</span></p>
  </div>
</div>

So that it gets rendered like this:

image.png.6ff6be12a1de2f442aa60b712dae26d3.png

I have a python script which converts my lyric/chord files into the html above, which I then paste into a Textarea field that gets put into my template and rendered out on a page for each song. What I'm wondering is if there's a way to do this through ProcessWire without the python script? So instead of pasting html into the Textarea field, I can type out the lyrics in the field and ProcessWire parses it to output the proper html? I'm thinking I may have to write my own Textformatter but I'm not sure if that's the right solution or where to start.

Thanks!

Edited by oscarale
solved
Link to comment
Share on other sites

You mean, type them in a text area with the spaces, like in the example above? Seems like it would be a pretty complex PHP script, but possible, I guess...

If you don't mind to write something closer to the html code, it would make it really easy. You could simply wrap the notes in an element by making them bold, and make each line a paragraph:

EI'll take you Dfor a rGideB

EOn my gaDrbage tGruckB

BOh noA

And then just add something like this to style it.

p {
  position: relative;
  margin-top: 1.5em;
}

strong {
  position: absolute;
  bottom: 1em;
  color: red;
  font-weight: inherit;
}

Or, if you need exactly the html code from above, do a str_replace in a text formatter  from "<strong>" to "<span class='chord'>" and so on...

  • Like 1
Link to comment
Share on other sites

If you already have a python script that should be quite easy to do with the help of AI

In PW just create a textarea field and make sure to let it use a monospace font so that you can properly paste/write your lyrics. (you can do that in /site/templates/admin.less)

Then just grab that content and use your PHP method/function that your AI wrote for you and generate the html that you output on the frontend.

PS: Nice idea also by @diogo 🙂 

  • Like 1
Link to comment
Share on other sites

Got it working! Thanks for that AI suggestion @bernhard it did a lot of the leg work for me, and thanks @diogo for your suggestion as well, though it is easier to read and write the standard format with the chords above the lyrics. While there is software that will do the parsing to the chords within the lyrics for me (there's one called ChordPro) I was trying to remove the "middle man" so to speak and be able to edit and create lyrics directly and easily in ProcessWire. If anyone else is interested below is the code which creates an array with all the columns, sections and lines

$started_chords = false;
$chord_line = "";
$lyric = [[]];
$column = 0;
$section = -1;
foreach (explode("\n", $page->psalm_lyrics) as $line) {
	$stripped = preg_replace('/\s+/', ' ', trim($line));
	if ($stripped) {
		if (array_key_exists($stripped, $sections)) { // START SECTION
			$section++;
			$lyric[$column][] = [
				"class" => $sections[$stripped],
				"lines" => []
			];
		} elseif (empty(array_diff(explode(" ", $stripped), $chords)) && !$started_chords) {
			$started_chords = true;
			$chord_line = $line;
		} elseif ($stripped === "---") {
			$lyric[] = [];
			$column++;
			$section = -1;
		} else {
			if ($started_chords) {
				$started_chords = false;
				$chord_line = rtrim($chord_line);
				$limit = 0;
				while ($chord_line && $limit < 10) {
					$i = strrpos($chord_line, " ") ? strrpos($chord_line, " ") + 1 : 0;
					$stripped = mb_substr($stripped, 0, $i, 'UTF-8') .
						"<span class='chord'>" . mb_substr($chord_line, $i, null, 'UTF-8') . "</span>" .
						mb_substr($stripped, $i, null, 'UTF-8');
					$chord_line = rtrim(mb_substr($chord_line, 0, $i, 'UTF-8'));
					$limit++;
				}
			}
			$lyric[$column][$section]["lines"][] = $stripped;
		}
	}
}

Where $sections is a ProcessWire repeater field that parses different starts of sections like [VERSE] and [CHORUS] and then translates those to a class, and $chords is an array of available chords to parse. I can then write out the lyric wherever I need it.

<div class="lyrics mt-md">
  <?php foreach($lyric as $c) {
    echo "<div class='column'>";
    foreach($c as $s) {
     echo "<div class='section " . $s['class'] . "'>";
     foreach($s["lines"] as $l) {
      echo "<p class='line'>$l</p>";
     }
     echo "</div>";
    }
    echo "</div>";
   } ?>
</div>

So this lyric for example:

[CHORUS]

E             D      G B
I'll take you for a ride
E       D      G  B
On my garbage truck
B   A
Oh no

---

[VERSE]

E             D      G  B
I'll take you to the dump
E    D      G    B
'Cuz you're my queen
A        C
Take you uptown
A                  C
I'll show you the sights
 C           D
You know you wanna ride

Will render like this

image.png.1e61c8837318f8b058d0cf3188cce009.png

Link to comment
Share on other sites

  On 3/18/2025 at 10:48 PM, bernhard said:

In PW just create a textarea field and make sure to let it use a monospace font so that you can properly paste/write your lyrics. (you can do that in /site/templates/admin.less)

Expand  

I can't figure out how to do this, there's not an admin.less file in site/templates, or if I need to create it I'm not sure how to specify that the specific lyric field should use a monospace font

Link to comment
Share on other sites

  On 3/20/2025 at 4:47 AM, oscarale said:

I can't figure out how to do this, there's not an admin.less file in site/templates, or if I need to create it I'm not sure how to specify that the specific lyric field should use a monospace font

Expand  

That's just regular HTML/CSS stuff. Inspect the backend page where your textarea is. Get the name of the textarea, then add something like this in admin.less:

textarea[name^="your_textarea_field_name"] {
  // for debugging to make it obvious that this code is active
  border: 5px solid red;
  // force a monospace font
  font-family: monospace;
}

The ^= selector makes sure that it will also work for repeaters, where your name would be something like your_field_repeater123

IYHPBJX.png

Link to comment
Share on other sites

Forgive my ignorance, but I'm still not sure how site/templates/admin.less will be able to update the styling on my edit page. I did however find in the source that it is pulling from wire/templates-admin/styles/AdminTheme.css, so I added this line to the end and it changed the font, though I'm not sure if this is the correct way to go about this.

textarea[name^="song_lyrics"] {
	font-family: monospace !important;
}

Thanks for your help!

Link to comment
Share on other sites

You can also use the admin.php file to load any css file (you can find it in the templates directory), for instance an admin.css file next to it. You just need to add the line $config->styles->append($config->urls->templates . "admin.css"); right before require($config->paths->core . "admin.php");

  • Like 2
Link to comment
Share on other sites

  • oscarale changed the title to [SOLVED] Convert lyric and chord text to html

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...