Gotcha.

Added features:
- Indented lines beginning with "+".
- Horizontal rule between unit entries (above every "$Name: ****").
- Linked index of every unit with color-coding according to species, including "Ancient/Ancients" and a special "Other" catch-all, and placed it all in a tidy list.
Clickety-click! $num_tabs = "\t\t\t"; // number of tab stops between a data line and it's comments; default = 3
$table = file("ships.tbl");
$text = '
';
$html_ul_state = "closed";
$html_li_state = "closed";
while (list (, $line) = each ($table)) {
GLOBAL $html_ul_state;
$line = trim($line);
// BEGIN section check (starts with "#")
if (strpos($line, "#") === 0) { // line begins with '#'?
if ($line == "#End") {
$line = '' . $line . "
";
} else {
$tbl_heading1_id++;
if ($html_ul_state == "open") {
$index .= "\n\n";
$html_ul_state = "closed";
}
$index .= '
' . $line . '';
$line = '***** CLASS="tbl_heading1_text">
' . $line . "";
}
// END check for section
// BEGIN check for comments (start with ";")
} elseif (strpos($line, ";") === 0) { // line is commented
if (strchr($line,":")) {
list($entry_type,$entry_value) = explode(":",$line);
$entry_type = trim($entry_type);
$entry_value = trim($entry_value);
$line = "";
} else {
$line = "";
}
// END check for comments
// BEGIN check for subentries (start with "+")
} elseif (strpos($line, "+") === 0) { // line is subentry
if (strchr($line,":")) {
list($entry_type,$entry_value) = explode(":",$line);
$entry_type = trim($entry_type);
$entry_value = trim($entry_value);
$line = "\t
$entry_type:\t$entry_value";
} else {
$line = "\t$line";
}
// END check for subentries
// BEGIN data parsing
} elseif (!strlen($line) == 0) { // not blank line
list($entry_type,$entry_value) = explode(":",$line);
$entry_type = trim($entry_type);
$entry_value = trim($entry_value);
// BEGIN find quoted text
$first_quote = strpos($entry_value, '"');
$last_quote = strrpos($entry_value, '"');
if ($first_quote && $last_quote) {
$quoted = substr($entry_value,$first_quote,$last_quote - $first_quote + 1);
$entry_value_new = trim(substr($entry_value,0,$first_quote));
$tok = strtok($quoted,'"');
while ($tok) {
if (trim($tok) == "") {
// do nothing if token is empty
} else {
$entry_value_new .= "
\"$tok\" ";
}
$tok = strtok('"');
}
$entry_value_new .= trim(substr($entry_value,$last_quote + 1));
$entry_value_old = $entry_value;
$entry_value = $entry_value_new;
}
// END find quoted text
if (strchr($entry_value,";") === FALSE) {
// no comment found
} else {
list($entry_value_data,$entry_value_comment) = explode(";;",$entry_value);
$entry_value_data = trim($entry_value_data);
$entry_value_comment = trim($entry_value_comment);
$entry_value = "$entry_value_data" . $num_tabs . "";
}
$line = "
$entry_type: $entry_value";
// BEGIN check for entry start and name
if ($entry_type == "\$Name") {
if ($html_li_state == "open") {
$index .= "\n\n";
$html_li_state = "closed";
}
if ($html_ul_state == "closed") {
$index .= "\n
\n";
$html_ul_state = "open";
}
$line = "
\n
\n $index .= "\n- \n\t";
$html_li_state = "open";
$index .= "$entry_value";
$entry_list_id++;
}
// END check for entry start and name
// BEGIN check for species
if ($entry_type == "\$Species") {
switch (trim($entry_value)) {
case "Terran":
case "Vasudan":
case "Shivan":
case "Ancient":
case "Ancients":
$index .= "\t($entry_value) ";
break;
default:
$index .= "\t(Other - $entry_value)";
}
$html_li_state = "closed";
}
// END check for species
// END data parsing
} else {
// blank line
}
$text .= $line . "\n";
}
$text .= "\n\n";
echo $index;
echo $text;
?>