Backend for songs.zachdecook.com
* Transposition: Allow it to work without javascript
Zach DeCook 2018-12-26
parent 2e443a1 · commit b34e3db
-rw-r--r--laravel/app/Http/Controllers/SongController.php95
-rw-r--r--laravel/resources/views/song.blade.php6
2 files changed, 97 insertions, 4 deletions
diff --git a/laravel/app/Http/Controllers/SongController.php b/laravel/app/Http/Controllers/SongController.php
index d1d4741..3f68714 100644
--- a/laravel/app/Http/Controllers/SongController.php
+++ b/laravel/app/Http/Controllers/SongController.php
@@ -13,11 +13,16 @@ class SongController extends Controller
$song = Song::where('number', $songNumber )->first();
$lines = explode( "\n", $song['text'] );
$newText = '';
+ $transp = $_GET['transp'] ?? 0;
foreach( $lines as $line ){
$line = htmlspecialchars( $line );
if ( $this->chordline( $line ) ) {
- $transp = 0;
- $class = "tabs chord$transp";
+ if ( $transp != 0) {
+ $line = $this->z_transpose2( $line, $transp );
+ }
+ $class = ! isset( $song['key'] ) ?
+ "tabs chord$transp"
+ : "tabs chord" . $this->transpadd( $song['key'], $transp );
$line = str_replace(
array('{','}'),
array('</b>{', "}<b class='$class'>" ),
@@ -28,7 +33,7 @@ class SongController extends Controller
}
}
$song['escapedText'] = $newText;
- return view('song', ['song' => $song, 'transp' => 0 ] );
+ return view('song', ['song' => $song, 'transp' => $transp ] );
}
/**
@@ -56,5 +61,89 @@ class SongController extends Controller
}
return ($goodtokens *2)+ $ambtokens >= $badtokens;
}
+
+ private function z_transpose2( $line, $transp )
+ {
+ $newchords = $this->z_transparray( $transp );
+ $newline = '';
+ $space = 0; ///@< Spaces that need to be added or removed.
+ $inCurly = 0;
+ for($i = 0; $i < strlen($line); $i++) {
+ $char = $line[$i];
+ $nchar = isset($line[$i+1]) ? $line[$i+1] : '';
+ $upchar = strtoupper($line[$i]);
+ $cval = ord($upchar);
+ if ( $char == '}' && $inCurly ){ $inCurly = 0;}
+ if ( $char == '{' || $inCurly ){ $inCurly = 1; $newline .= $char; continue;}
+ // A-G
+ if( $cval <= 71 && $cval >=65 ) {
+ // Exception for Cmaj7
+ if( $upchar == 'A' && $nchar == 'j' ) {
+ $newline .= $char;
+ } else if( $nchar == 'b' || $nchar =='#') {
+ $i++; //We have read an extra character now.
+ $newchord = $newchords[$upchar . $nchar];
+ if( strlen($newchord) == 1 ) {
+ // Need to insert an extra space.
+ $space += 1;
+ }
+ $newline .= $newchord;
+ } else {
+ $newchord = $newchords[$upchar];
+ if( strlen($newchord) == 2 ) {
+ // Need to remove an extra space.
+ $space -= 1;
+ }
+ $newline .= $newchord;
+ }
+ } else if ( $char == ' ' ) {
+ if( $space >= 0) {
+ for ($j = 0; $j <= $space; $j++) {
+ $newline .= ' ';
+ }
+ $space = 0;
+ } else {
+ // Only balance negative spaces if one will be left remaining
+ if( $nchar == ' ' ) {
+ $i++;
+ $space += 1;
+ }
+ $newline .= ' ';
+ }
+ } else {
+ $newline .= $char;
+ }
+ }
+ return $newline;
+ }
+
+ private function z_transparray( $transp )
+ {
+ $chords =
+ array( "C","C#","D","D#","E","F","F#","G","G#","A","Bb","B" );
+ $newchords = array();
+ // Create array to map old chords to new ones
+ for ($i=0; $i < 12; $i++) {
+ $newchords[$chords[$i]] = $chords[($i+$transp+12)%12];
+ }
+ $newchords["Db"] = $newchords["C#"];
+ $newchords["Eb"] = $newchords["D#"];
+ $newchords["Gb"] = $newchords["F#"];
+ $newchords["Ab"] = $newchords["G#"];
+ $newchords["A#"] = $newchords["Bb"];
+ return $newchords;
+ }
+ private function transpadd( $fromkey, $integer )
+ {
+ $chords = array_flip(array( "C","C#","D","D#","E","F","F#","G","G#","A","A#","B" ));
+ $chords["Db"] = $chords["C#"];
+ $chords["Eb"] = $chords["D#"];
+ $chords["Gb"] = $chords["F#"];
+ $chords["Ab"] = $chords["G#"];
+ $chords["Bb"] = $chords["A#"];
+ $ochords = array( "C","Db","D","Eb","E","F","Gb","G","Ab","A","Bb","B" );
+ $fromkey = trim($fromkey, 'm');
+ return $ochords[($chords[$fromkey] + $integer + 24)%12];
+ }
}
diff --git a/laravel/resources/views/song.blade.php b/laravel/resources/views/song.blade.php
index a1c0f57..0b66195 100644
--- a/laravel/resources/views/song.blade.php
+++ b/laravel/resources/views/song.blade.php
@@ -6,11 +6,11 @@
<div class='container'>
<h2>{{$song['title']}}</h2>
+ <form>
<select name="transp" id="transp"
value = "<?php echo $transp;?>"
>
<?php
- $transp = 0;
for ($i=-6; $i < 12; $i++) {
if (($transp + 24)%12 == $i) $selected = 'selected';
else $selected = '';
@@ -20,6 +20,10 @@
}
?>
</select>
+ <noscript>
+ <button>Transpose</button>
+ </noscript>
+ </form>
<pre>
{!! $song['escapedText'] !!}