#!/usr/bin/php getPathName()); $src = $node_info->getPathname(); if (str_starts_with($src, SITE . '/target')) continue; $target = str_replace(SITE, SITE . '/target', $src); $path_parts = pathinfo($target); if (strstr($src, '/.') !== false) // Skip hidden nodes continue; if ($node_info->getType() !== 'file') continue; if (!file_exists($path_parts['dirname'])) // Create parent directory if needed mkdir($path_parts['dirname'], 0755, true); copy($src, $target); if ($node_info->getExtension() !== 'md') continue; $files_dates[$src] = $node_info->getMTime(); if (in_array('draft', explode('.', $path_parts['basename']), true)) continue; $base_filepath = $path_parts['dirname'] . '/' . $path_parts['filename']; $content = file_get_contents($src); preg_match('/^# (?.*)$/Dm', $content, $matches); $title = $matches['title'] ?? NULL; if (!file_exists($base_filepath . '.html') OR (filemtime($src) > filemtime($base_filepath . '.html')) OR $opt['force']) { echo 'Compiling ' . $src . ' ' . date("Y-m-d H:i:s", $node_info->getMTime()) . LF; // Execute PHP code ob_start(); eval('?>' . $content); $content = ob_get_clean(); // Convert Gemtext to Markdown if ($path_parts['extension'] === 'gmi' OR $path_parts['extension'] === 'md') { $content = preg_replace_callback( '/^=>\h*(?<addr>\S+)(:?\h+(?<title>\V+))?$/m', function ($matches) { if (!str_contains($matches['addr'], ':') AND str_ends_with($matches['addr'], '.gmi')) $matches['addr'] = substr($matches['addr'], 0, -3) . 'md'; return '[' . ($matches['title'] ?? $matches['addr']) . '](' . $matches['addr'] . ')'; }, $content, ); } // Compile Markdown to HTML $process = proc_open('pandoc --fail-if-warnings --section-divs -f markdown-citations-native_divs-native_spans+abbreviations+hard_line_breaks+lists_without_preceding_blankline+multiline_tables+fenced_divs+bracketed_spans+markdown_attribute -t html --wrap none', [ 0 => ['pipe', 'r'], 1 => ['pipe', 'w'], ], $pipes); if (is_resource($process) !== true) exit('Can\'t spawn pandoc.' . PHP_EOL); fwrite($pipes[0], $content); fclose($pipes[0]); $content = stream_get_contents($pipes[1]); fclose($pipes[1]); if (proc_close($process) !== 0) exit('pandoc failed.' . PHP_EOL); // .md > .html for local links $content = preg_replace('/ href="([^:"]+)\.md"/', ' href="$1.html"', $content); $relative_root_path = str_repeat('../', substr_count(str_replace(SITE . '/target', '', $path_parts['dirname']), '/')); ob_start(); ?> <!DOCTYPE html> <html lang="<?php preg_match('#\.([a-zA-Z-]{2,5})\.#', $path_parts['basename'], $file_lang); if (isset($file_lang[1])) { $lang = $file_lang[1]; } else { preg_match('#/([a-z]{2})(/|$)#', $path_parts['dirname'], $dir_lang); $lang = $dir_lang[1] ?? $config['default-lang']; } echo $lang ?? ''; ?>"> <head> <meta charset="utf-8"> <?php if (isset($title) AND isset($config['title'])) echo '<title>' . $title . ' ยท ' . $config['title'] . ''; else if (isset($title)) echo '' . $title . ''; else if (isset($config['title'])) echo '' . $config['title'] . ''; ?> '; if ($config['announce-feed']) echo '' . LF; if ($config['announce-css']) { if (file_exists(SITE . '/style.css')) echo '' . LF; echo '' . LF; } if (file_exists(SITE . '/head.inc.html')) echo file_get_contents(SITE . '/head.inc.html'); ?> ' . file_get_contents(SITE . '/header.inc.php')); if ($config['center-index'] AND $path_parts['filename'] === 'index') echo '
' . $content . '
'; else echo '
' . $content . '
'; if (file_exists(SITE . '/end.inc.html')) require SITE . '/end.inc.html'; echo ''; $content = ob_get_clean(); if (extension_loaded('tidy')) { $content = tidy_repair_string($content, [ 'indent' => true, 'indent-spaces' => 4, 'output-xhtml' => true, 'wrap' => 0, ]); $content = str_replace(' ', ' ', $content); } file_put_contents($base_filepath . '.html', $content); // Gzip compression exec('gzip --keep --fast --force ' . $base_filepath . '.html'); } $relative_addr = substr_replace($base_filepath . '.html', '', strpos($base_filepath, SITE), strlen(SITE)); // As of RFC 3151: A URN Namespace for Public Identifiers $public_id = 'urn:publicid:' . $config['id'] . str_replace('/', '%2F', $relative_addr); preg_match('#\(?.*)\#s', file_get_contents($base_filepath . '.html'), $match); $atom_entry_content = $match['content']; // Make relative links absolute $atom_entry_content = preg_replace_callback('# href=\"(?[^:"]+)\"#', function ($matches) { global $config; global $path_parts; return ' href="' . ($config['base-url'][0] ?? '') . substr($path_parts['dirname'], strlen(SITE)) . '/' . $matches['relative_url'] . '"'; }, $atom_entry_content); ob_start(); ?> <?= $title ?> getMTime()) ?> ' . LF; ?> <?= $config['title'] ?? '' ?> urn:publicid: ' . LF; ?> ' . LF); if ($config['announce-css']) copy(ROOT . '/style.css', SITE . '/target/mkht-php.css');