index.phps

<?
header('Content-type: text/html; charset=utf-8');

define('STATE_PERIOD', 0);
define('STATE_SPACE', 1);

function U_build_helper($m) {
    return join(',', range($m[1], $m[2]));
}

function U_build($name)
{
    if (!file_exists($name)) {
        header('HTTP/1.0 404 Not found');
        exit;
    }

    $head   = null;
    $years = $people = array();

    foreach (file($name, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $line) {
        if ($line[0] === '[') {
            $head = substr($line, 1, -1);
            continue;
        }

        if ($line[0] === '#') continue;

        list($ystr, $title) = preg_split('/\s*:\s*/s', $line);
        $ystr = preg_replace_callback('/(\d+)\s*[-—]\s*(\d+)/s', 'U_build_helper', $ystr);

        if ($ystr < 0) {
            if (isset($people[-$ystr])) {
                $people[-$ystr][] = $title;
            } else {
                $people[-$ystr] = array($title);
            }
        } else {
            $years += array_fill_keys(
                preg_split('/\s*,\s*/s', $ystr),
                $title
            );
        }
    }

    $fullyears = array_merge(array_keys($years), array_keys($people));
    sort($fullyears);

    $min = min($fullyears);
    $max = max($fullyears);

    // вывод людей перед списком
    for ($year = $min; $year <= $max; $year++) {
        if (isset($years[$year])) break;

        if (isset($people[$year])) {
            foreach ($people[$year] as $person) {
                echo "<div class=mark><div>{$person}<span>$year</span></div><div></div></div>\n";
            }
        }
    }

    $state = STATE_PERIOD;

    while ($year <= $max) {
        $persons = array();
        $start   = $year;

        for (; $year <= $max; $year++) {
            if (STATE_PERIOD === $state) {
                if (!isset($years[$year])) {
                    $state = STATE_SPACE;
                    break;
                }

                if ($years[$start] !== $years[$year]) break;
            } else {
                if (isset($years[$year])) {
                    $state = STATE_PERIOD;
                    break;
                }
            }

            if (isset($people[$year])) {
                foreach ($people[$year] as $person) {
                    $persons[] = array($year, $person); 
                }
            }
        }

        $mark = $start === $year - 1 ? $start : $start . '…' . ($year - 1);
        $title = isset($years[$start]) ? $years[$start] : '';

        if ($persons) {
            reset($persons);
            list(,$person) = each($persons);

            echo "<div class=mark><div>{$person[1]}<span>{$person[0]}</span></div>",
                 "<div><span>$mark</span>$title</div></div>\n";

            while (list(,$person) = each($persons)) {
                echo "<div class=mark><div>{$person[1]}<span>{$person[0]}</span></div><div></div></div>\n";
            }
        } else {
            echo "<div class=mark><div></div><div><span>$mark</span>$title</div></div>\n";
        }
    }

    return $head;
}

ob_start();
$head = U_build('data/' . basename(@$_GET['file']));
$content = ob_get_clean();
?>
<head>
    <link rel="stylesheet" href="screen.css" type="text/css" media="screen">
    <meta charset="utf-8">
    <title><?=$head?></title>
</head>
<body>
    <h3><?=$head?></h3>
    <div id="timeline"><?=$content?></div>
</body>
</html>