) {
if (/^[ \t]*$/) { } # blank line
elsif (/^[ \t]*\%.*$/) { } # comment: ignore
# Variable-setting macros:
elsif (/\\begin\{song/) { begSong($_); } # Song
elsif (/\\subtitle/) { $subtitle = getContent($_); }
elsif (/\\key/) { $key = getContent($_); }
elsif (/\\tags/) { $tags = getContent($_); }
elsif (/\\category/) { $tags = getContent($_); }
elsif (/\\dedication/) { $dedication = getContent($_); }
elsif (/\\license/) { $license = getContent($_); }
elsif (/\\timing/) { $timing = getContent($_); }
elsif (/\\created/) { $created = getContent($_); }
elsif (/\\notice/) { $notice = getContent($_); }
elsif (/\\cvsid/) { $cvsid = getContent($_); }
elsif ($title) { return; }
}
}
########################################################################
###
### Macro handlers:
###
### Each of the following routines handles a LaTeX macro.
###
### Separate verses.
sub sepVerse {
if ($vlines) { endVerse(); }
}
### Handle a blank line.
sub blankLine {
if ($vlines) { endVerse(); }
if ($plain) {
print "\n";
$plines = 0;
}
}
### Begin a song:
### Stash the title, put out the header.
sub begSong {
my ($line) = @_; # input line
$line =~ s/^.*song\}//;
$title = getContent($line);
}
########################################################################
###
### Block conversion:
###
### Each of these routines converts the start or end of a
### delimited block of lines to output format.
###
sub doHeader {
if ($html) { htmlHeader(); }
else { textHeader(); }
$header ++;
}
sub center {
# === need to handle multiple lines ===
my ($text) = @_;
$text =~ s/^[ \t]*//;
$text =~ s/[ \t]*\n$//;
$text =~ s/\\copyright/Copyright/;
my $w = $WIDTH - length($text);
for ( ; $w > 0; $w -= 2) { $text = " " . $text; }
print "$text\n";
}
sub hcenter {
my ($h, $text) = @_;
$text =~ s/^[ \t]*//;
$text =~ s/\\copyright/\©/;
$text =~ s/\n/\
/g;
$text = "$text";
print "$text\n";
}
sub textHeader {
center "$title\n";
if ($subtitle) { center "$subtitle\n"; }
if ($notice) { center "$notice\n"; }
if ($license) { center "$license\n"; }
if ($dedication) { center "$dedication\n"; }
print "\n";
}
sub htmlHeader {
hcenter 1, $title;
if ($subtitle) { hcenter 2, $subtitle; }
if ($notice) { hcenter 3, $notice; }
if ($license) { hcenter 3, $license; }
if ($dedication) { hcenter 3, $dedication; }
print "\n";
}
sub footer {
}
########################################################################
###
### Line conversion:
###
### Each of these routines converts a single line of mixed chords
### and text.
###
### Process the current line:
### Does any necessary dispatching.
sub doLine {
# Put out the header, if this is the very first line.
if (! $header) { doHeader(); }
if ($plain) {
if ($plines == 0) {
if ($html) { print "\n"; }
else { print "\n"; }
}
$_ = deTeX($_);
if ($html) { s/\~/ /g; } else { s/\~/ /g; }
s/\\newline/$NL/g;
s/\\\///g;
indentLine($_, $indent);
$plines ++;
} else {
if ($vlines == 0) { begVerse(); }
if ($tables) { print tableLine($_); }
else { print chordLine($_); }
$vlines ++;
}
}
### Put out a plain line, possibly indented.
sub indentLine {
my ($line, $indent) = @_;
$line =~ s/^[ \t]*//;
while ($indent--) { $line = " ".$line; }
print $line;
}
### Convert an ordinary line to chords + text
# === does not insert indent yet.
sub chordLine {
my ($line) = @_; # input line
my $cline = ""; # chord line
my $dline = ""; # dest. (text) line
my ($scol, $ccol, $dcol, $inchord, $inmacro) = ($indent, 0, 0, 0, 0);
my $c = ''; # current character
my $p = 0; # current position
$line = deTeX($line);
$line =~ s/^[ \t]*//;
$line =~ s/\\sus/sus/g;
$line =~ s/\\min/m/g;
for ($p = 0; $p < length($line); $p++) {
$c = substr($line, $p, 1);
if ($c eq "\n" || $c eq "\r") { break; }
if ($c eq '[') { $inchord ++; }
elsif ($c eq ']') { $inchord --; }
elsif ($c eq ' ') { if (!$inchord) { $scol ++; } }
elsif ($c eq "\t") {
if (!$inchord) { do {$scol ++; } while ($scol % 8); } }
else {
if ($inchord) {
while ($ccol < $scol) { $cline .= ' '; $ccol ++ }
$cline .= $c;
$ccol ++;
} else {
while ($dcol < $scol) { $dline .= ' '; $dcol ++ }
$dline .= $c;
$dcol ++;
$scol++;
}
}
}
# The result has a newline appended to it.
return (($cline eq "")? $dline : $cline . "\n" . $dline);
}
### Convert a line to a table
### When using tables, each line becomes a separate table.
### This, in turn, becomes a row in a table containing the verse.
sub tableLine {
}
### Convert a line to XML
sub xmlLine {
}
### Remove LaTeX constructs.
### This would be easier with a table.
sub deTeX {
my ($txt) = @_; # input line
while ($txt =~ /\%/) { # TeX comments eat the line break, too.
$txt =~ s/\%.*$//;
$txt .= ;
}
while ($txt =~ /\{\\em[ \t\n]/
|| $txt =~ /\{\\tt[ \t\n]/
|| $txt =~ /\{\\bf[ \t\n]/) {
# This will fail if there's a \bf and \em in one line in that order
if ($txt =~ /\{\\em[ \t\n]/) {
$txt =~ s/\{\\em[ \t\n]/$EM/;
while (! $txt =~ /\}/) { $txt .= ; }
$txt =~ s/\}/$_EM/;
}
if ($txt =~ /\{\\tt[ \t\n]/) {
$txt =~ s/\{\\tt[ \t\n]/$TT/;
while (! $txt =~ /\}/) { $txt .= ; }
$txt =~ s/\}/$_TT/;
}
if ($txt =~ /\{\\bf[ \t\n]/) {
$txt =~ s/\{\\bf[ \t\n]/$BF/;
while (! $txt =~ /\}/) { $txt .= ; }
$txt =~ s/\}/$_BF/;
}
if ($txt =~ /\{\\small[ \t\n]/) {
$txt =~ s/\{\\small[ \t\n]/$BF/;
while (! $txt =~ /\}/) { $txt .= ; }
$txt =~ s/\}/$_BF/;
}
}
$txt =~ s/\\small//;
$txt =~ s/\\&/$AMP/g;
$txt =~ s/\\;/$SP/g;
$txt =~ s/\\ /$SP/g;
$txt =~ s/\\ldots/.../g;
$txt =~ s/\\\\/$NL/g;
return $txt
}
### getContent(line): get what's between macro braces.
sub getContent {
my ($line) = @_; # input line
# Throw away everything up to the "{"
$line =~ s/^[^{]*\{//;
$line = deTeX($line);
# Suck in more lines if we haven't seen the closing brace
while ($line !~ /\}/) { $line .= ; $line = deTeX($line); }
# Throw away everything after the "}"
$line =~ s/\}[^}]*$//;
$line =~ s/\n$//;
return $line;
}