preg_replace("(^(X?C?B?\d+)\. )",'',$line) ); $entries[$number]['number'] = $number; } else if( preg_match("/^{.?Verse: ?(.*)}/i", $line, $matches)){ if (isset($entries[$number]['verse'])){ $entries[$number]['verse'] .= ", $matches[1]";} else { $entries[$number]['verse'] = $matches[1];} } else if( preg_match("/^{Key: ?(.*)}/i", $line, $matches)){ $entries[$number]['key'] = $matches[1];} else if( preg_match( "/\{p?\d*\((.+m?)\)\}/", $line, $matches) ){ $entries[$number]['key'] = $matches[1];} else if( preg_match( AUTHOR_REGEX, $line, $matches) ){ $entries[$number]['author'] = $matches[1];} }fclose($handle);} else { //Error } $toc = ''; $toc .= '

Sort by: '; foreach( array( 'default', 'title', 'author', 'verse' ) as $thing ){ $disabled = ($sort == $thing) ? 'disabled' : ''; $toc .="$thing"; } $toc .= '

'; $toc .= '
'; $toc .= ''; return $toc; } function tocentry( $item ){ $class = ''; if ( ! isset( $item['key'] ) ){ $class = 'incomplete'; } $output = "
  • $item[number]. $item[title]"; if ( !empty($item['author']) ){ $output .= "($item[author])";} if ( $item['verse'] ?? false ){ $output .= "($item[verse])"; } if ( $item['key'] ?? false){ $output .= "($item[key])"; } return $output; } /** * @brief load a portion of the text file inputfile.txt starting with * "$number. " * Where $number is an integer, or "X12", etc. */ function load_song( $number, $transp = 0 ) { // Song suggestions are based on the minute you loaded the page mt_srand( time()/60 ); $handle = fopen("inputfile.txt", "r"); if( ! $transp ) $transp = 0; $current_song = 0; $something = 0; $song = ''; $textlines = '';///@< for suggesting songs $allsongs = array(); $suggestedSong = array(); $songKeys = array(); if ($handle) {while (($line = fgets($handle)) !== false) { // Fix weird apostrophe errors $line = stripslashes( mb_convert_encoding( $line, "HTML-ENTITIES", "UTF-8" ) ); // If we see a number, then that is what song we are on. $matches = array(); if ( preg_match("(^(X?C?B?\d+)\. )", $line, $matches) ) { $allsongs[$matches[1]] = $line; $current_song = $matches[1]; if( mt_rand(0,100) < 5 ) { $suggestedSong[$current_song]['title'] = $line; } } if ( preg_match( "/\{p?\d*\((.+m?)\)\}/", $line, $matches) || preg_match("/^{Key: ?([^ ]*).*}/i", $line, $matches) ) { if ( isset( $suggestedSong[$current_song])) { $suggestedSong[$current_song]['key'] = $matches[1]; } if ( $current_song === $number ) { $songKeys[] = $matches[1]; $songKey = $matches[1]; } } if ( isset( $suggestedSong[$current_song] ) ) { if ( preg_match( AUTHOR_REGEX, $line, $matches ) ) { $suggestedSong[$current_song]['author'] = $matches[1]; } } if ( $current_song === $number || $number == "all" ) { if( chordline($line) ) { if ( $transp != 0) { $line = z_transpose2( $line, $transp ); } $class = ! isset( $songKey ) ? "tabs chord$transp" : "tabs chord" . transpadd( $songKey, $transp ); $line = str_replace( array('{','}'), array('{', "}" ), $line ); $song .= "" . $line . ""; } else { $song .= $line; $textlines .= $line; } } }fclose($handle);} else { // error opening the file. } return renderNavButtons( $number ) . renderEasyTransp( $transp, $number, $songKeys ) . renderFavorite( $number ) . "
    " . $song . "
    \n" . renderNavButtons( $number ) . renderSS($suggestedSong, $songKeys, $transp) // If you have gitlab.com/earboxer/VirtualStrummer at this path (and prosongsa at /tabs), // this link will open this song there. . "Play me???" ; } function renderFavorite( $number ) { $number = str_replace( "'", "", $number ); $name = str_replace("'", "", $_COOKIE['name'] ?? '' ); if ( $name ) { $file_db = new SQLite3('db/favs.db'); $favd = $file_db->querySingle( "SELECT name from favorites where name = '$name' AND song = '$number'"); } if ( $favd ) { $favd = strip_tags( $favd ); return "Song in favorites for $favd"; } else { return "
    " . "" . "" . "" . "
    "; } } function renderEasyTransp( $transp, $num, $songKeys = array() ) { $s = ''; //up two semitones $classT = 'btn col-xs-12'; $nsongKey = 'Z'; $words = "Transposed up 2 semitones"; if (isset ( $songKeys[0] ) ) { $classT = 'btn col-xs-4'; $origKey = $songKeys[0]; $pastKey = transpadd( $origKey, $transp - 2 ); $presentKey = transpadd( $origKey, $transp ); $s .= getKeyButton( "Transpose down to", $transp - 2, $pastKey, $num, $classT ); $s .= getKeyButton( "Current Key: ", $transp, $presentKey, $num, $classT ); $nsongKey = transpadd( $presentKey, 2) ?: 'Z'; $words = "Transpose up to "; } $s .= getKeyButton( $words, $transp + 2, $nsongKey, $num, $classT ); return $s; } function getKeyButton( $text, $value, $key, $num, $classT ) { $zkey = $key ?: 'Z'; $key = ($key == 'Z') ? '' : $key; return "" . "$text $key"; } function renderNavButtons( $number ) { $navbuttons = ''; if ( is_numeric($number) ) { $pnumber = $number - 1; $nnumber = $number + 1; $navbuttons .= "previous\n"; $navbuttons .= "next\n"; } return $navbuttons; } /** * @brief Show the suggested songs as buttons with transpositions. * @param $suggestedSong array of songs '25' => ['title'=> 'Majesty', 'key' => 'Bb' ] * @param $songKeys Keys that you want to transpose these songs into. */ function renderSS( $suggestedSong = array(), $songKeys, $transp ) { $ss = array(); $bs = array();// "bad" songs. Songs without transpositions. //shuffle( $suggestedSong ); foreach ($suggestedSong as $songNum => $songarray) { $title = $songarray['title'] . (!empty($songarray['author']) ? "($songarray[author])" : ''); if( isset($songarray['key']) ) { $ok = trim($songarray['key'], 'm'); $n = 2; $bn = 12-($n* count($songKeys)); $smn = count($songKeys) < 3 ? 3 : 12/count($songKeys); $smbn = count($songKeys) < 3 ? 12 - count($songKeys) * $smn : 12; $xsn = count($songKeys) == 1 ? 4 : 12/(count($songKeys) ?: 1); $xsbn = count($songKeys) == 1? 8 : 12; //$xtn = 12/count($songKeys); //$xtbn = 12; $s = "" . "$title ($songarray[key])\n"; $classT = "btn col-md-$n col-sm-$smn col-xs-$xsn"; foreach( $songKeys as $sK ) { $tt = difftransp( $sK, $songarray['key']); if ( is_integer($tt) ); { $tt = ($tt + $transp + 12)%12; $nsongKey = transpadd( $sK, $transp ); $s .= "\t" . "Transposed to $nsongKey\n"; } } $ss[] = $s; } else { $bs[] = "$title\n"; } } shuffle( $ss ); shuffle( $bs ); return implode($ss) . implode($bs); } function normalizechords($line, $space=TRUE) { // Get rid of flats $old = array( "Db", "Eb", "Gb", "Ab", "Bb"); $new = array( "C#", "D#", "F#", "G#", "A#"); $line = str_replace($old, $new, $line); // Uppercase letters A-G $lc = array( "a", "b", "c", "d", "e", "f", "g"); $uc = array( "A", "B", "C", "D", "E", "F", "G"); $line = str_replace($lc, $uc, $line); if ( $space == TRUE ) { // Move space for nonsharp chords that didn't end in one $line = preg_replace("( ([A-G])([^# ]))", "$1 $2", $line); // Trailing space at the end of the line $line = str_replace("\n", " \n", $line ); } return $line; } function difftransp( $fromkey, $tokey ) { $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#"]; $fromkey = trim($fromkey, 'm'); $tokey = trim($tokey, 'm'); return $chords[$fromkey] - $chords[$tokey]; }