#!/usr/bin/perl # # Create the stored music lists # # $Id: mklist,v 1.6 2002/05/26 17:43:34 dds Exp $ # # Use -t option to create a track listing # # (C) Copyright 2000-2002 Diomidis Spinellis # # Permission to use, copy, and distribute this software and its # documentation for any purpose and without fee is hereby granted, # provided that the above copyright notice appear in all copies and that # both that copyright notice and this permission notice appear in # supporting documentation. # # THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF # MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. # open(PLAYLIST, '>/vol/db/playlist') || die; open(HTML, '>/vol/db/playlist.html') || die; open(TEX, '>/vol/db/playlist.tex') || die; htmlhead(); texhead(); # Process bookmarks htmlcontents("Bookmarks", 1); $html .= "
\n"; print TEX ' \section{Bookmarks} \begin{tabular}{rl} '; open(FILE, 'find /vol/db/bookmarks -type f -print | sort |') || die "find: $!\n"; ; while () { chop; $name = $fname = $_; $name =~ s,.*/,,; open(BK, $fname); while () { chop; next if (/^#/); $num = $1 if (/^NU (\d+)/); $bk = $1 if (/^BK (\d+)/); } close(BK); $name = fix($fname); $html .= "
$num
$name\n"; print TEX "{\\em $num} & $name \\\\\n"; $bookmark{$bk} = $num; } $html .= "
\n"; print TEX "\\end{tabular}\n"; # Process index files and create full track list htmlcontents("Disks", 1); print TEX "\\section{Disks}\n"; open(FILE, 'find /vol/music -name index.txt -print | sort |') || die; while () { chop; $dir = $idxname = $_; $dir =~ s,/index.txt$,,; open(IDX, $idxname) || die; while () { chop; next if (/^#/); if (/^DN (.*)/) { $dn = $1; pathheader($dir, $dn, 1, "#DN$dn"); print PLAYLIST "# $dn\n"; print PLAYLIST "# $b\n" if ($b = $bookmark{$dn}); } if (/^TN (\d+)\001(.*)/) { print PLAYLIST "# $b\n" if ($b = $bookmark{$1}); print PLAYLIST "# $1\n$dir/$2\n"; } } close(IDX); } # Process collections if ($ARGV[0] eq '-t') { # Process tracks htmlcontents("Tracks", 1); print TEX "\\section{Tracks}\n"; open(FILE, 'find /vol/music -name index.txt -print | sort |') || die; while () { chop; $dir = $idxname = $_; $dir =~ s,/index.txt$,,; # Try to read track info from info.txt undef %trackname; if (open(INFO, $q = "$dir/info.txt")) { while () { chop; if (/^TR (.*)/) { ($tn, $infoname, $fname) = split(/\001/); $trackname{$fname} = $infoname; } } close(INFO); } open(IDX, $idxname) || die; while () { chop; next if (/^#/); if (/^DN (.*)/) { $html .= " "; } if (/^TN (\d+)\001(.*)/) { $tracknum = $1; $trackfname = $2; if (defined($trackname{$trackfname})) { $trackname = $trackname{$trackfname}; } else { $id3 = id3name("$dir/$trackfname"); $tryname = $trackfname; $tryname =~ s/track-?//i; $simplename = fix($tryname); $trackname = (length($id3) > length($simplename)) ? $id3 : $simplename; } $trackname =~ s,/,:,g; # Not to confuse pathheader # URL in Windows format pathheader("$dir/$trackname", $tracknum, 0, "file:////spiti/$dir/$fname"); } } close(IDX); } } # process tracks $html .= "\n"; print HTML "

Contents

"; print HTML $contents; print HTML "


\n"; print HTML $html; print TEX ' \end{document} '; # Create the text version of the list system(q{lynx -dump /vol/db/playlist.html -width=1024 | sed -n 's/\[[^]]*\]//g;s/ */ /g;/Disks/,/Tracks/p' >/vol/db/playlist.txt}); # Print an HTML head sub htmlhead { print HTML ' MP3 Playlist '; } # Convert a filename to a readable name sub fix { my($name) = @_; $name =~ s,.*/,,; $name =~ s/\.mp3$//; $name =~ s/([A-Z])/ $1/g; $name =~ s/_/ /g; $name =~ s/(\d+)/ $1/g; $name =~ s/\bcd\b/CD/g; $name =~ s/ */ /g; $name =~ s/^ //; return ($name); } # Convert a pathname into headers # Return the last element of the path sub pathheader { my($path, $number, $fixlast, $url) = @_; my($i, $l, $name); $path =~ s,/vol/music/,,; @elements = split(/\//, $path); for ($i = 0; $i <= $#elements; $i++) { if ($elements[$i] ne $oelements[$i]) { $level = $i + 2; if ($i < $#elements) { $name = fix($elements[$i]); if ($level == 2) { print TEX "\n\\subsection*{" . texprotect($name) . "}\n"; print TEX "\n\\addcontentsline{toc}{subsection}{" . texprotect($name) . "}\n"; htmlcontents($name, 2); } elsif ($level == 3) { print TEX "\n\\subsubsection*{" . texprotect($name) . "}\n"; print TEX "\n\\addcontentsline{toc}{subsubsection}{" . texprotect($name) . "}\n"; htmlcontents($name, 3); } else { print TEX "\\hspace*{" . ($level - 4) * 0.3 . "cm}" . texprotect($name) . "\\\\\n"; $html .= (' ' x (($level - 4) * 3)) . htmlprotect($name) . "
"; } } } } @oelements = @elements; $last = $fixlast ? fix($elements[$#elements]) : $elements[$#elements]; $html .= (' ' x ($level * 3)); print TEX "\\hspace*{" . ($level - 4) * 0.3 . "cm}"; print TEX texprotect($last) . ": {\\em $number}\\\\\n"; $number = "$number" if (defined($url)); $html .= htmlprotect($last) . ": $number
\n"; return (); } # Return the ID3 name of a given file sub id3name { my($fname) = @_; $fname =~ s/'/'\\''/g; open(ID3, "id3 -lR '$fname'|") || die; while () { if (/^Title: (.*)/) { $name = $1; close(ID3); $name =~ s/ */ /g; return ($name); } } return (''); } sub texhead { print TEX ' \documentclass[10pt,twocolumn]{article} \textwidth 17cm \oddsidemargin -0.54cm \evensidemargin -0.54cm \textheight 23cm % Margins are 1in more than specified so margin = 4cm / 2 - 1in \topmargin -0.44cm \headheight 0pt \headsep 0pt \usepackage{times} \begin{document} \title{Music Selection Guide} \maketitle \newpage \tableofcontents \clearpage '; } # Protect special TeX characters sub texprotect { my($line) = @_; $line =~ s/\#/\\\#/g; $line =~ s/\$/\\\$/g; $line =~ s/\%/\\\%/g; $line =~ s/\&/\\\&/g; $line =~ s/\~/\\\~/g; $line =~ s/\_/\\\_/g; $line =~ s/\^/\\\^/g; $line =~ s/\{/\\\{/g; $line =~ s/\}/\\\}/g; return ($line); } # Protect special HTML characters sub htmlprotect { my($line) = @_; $line =~ s/\&/\&/g; $line =~ s/\/\>/g; return ($line); } # Add a title to the HTML table of contents at a given level sub htmlcontents { my($title, $level) = @_; $anchor++; $title = htmlprotect($title); $html .= "$title\n"; $contents .= (' ' x (($level - 1) * 3)) . '