summaryrefslogtreecommitdiff
path: root/scripts/functions.php
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/functions.php')
-rw-r--r--scripts/functions.php197
1 files changed, 155 insertions, 42 deletions
diff --git a/scripts/functions.php b/scripts/functions.php
index f1f4e1e..50acc22 100644
--- a/scripts/functions.php
+++ b/scripts/functions.php
@@ -18,7 +18,7 @@ function usage(): void
exit(1);
}
-function getSiteMetaData(string $src): array
+function getPages(string $src, string $geminiOutput, string $wwwOutput): array
{
$src = realpath($src);
@@ -27,57 +27,74 @@ function getSiteMetaData(string $src): array
\RecursiveIteratorIterator::SELF_FIRST
);
- $metaData = [];
+ $pages = [];
foreach ($iter as $fileInfo) {
if (!is_file($fileInfo->getRealPath())) {
continue;
}
- $metaData[] = getFileMetaData($src, $fileInfo);
+ $pages[] = getPageMetaData($fileInfo, $src, $geminiOutput, $wwwOutput);
}
- return $metaData;
+ return $pages;
}
-function getFileMetaData(string $src, \SplFileInfo $fileInfo): array
+function getPageMetaData(\SplFileInfo $fileInfo, string $src, string $geminiOutput, string $wwwOutput): array
{
$input = $fileInfo->getRealPath();
- $url = str_replace($src, '', $input);
+ $pathData = parsePath($input);
+
+ $geminiUrl = str_replace($src, '', $input);
+ $wwwUrl = str_replace('.gmi', '.html', $geminiUrl);
- $urlData = parseUrl($url);
$contentData = parseContent(file_get_contents($input));
return [
- 'input' => $input,
- 'url' => $url,
- 'date' => $urlData['date'],
- 'category' => $urlData['category'],
- 'isPost' => $urlData['isPost'],
- 'title' => $contentData['title'],
- 'author' => $contentData['author'],
+ 'input' => $input,
+ 'geminiUrl' => $geminiUrl,
+ 'wwwUrl' => $wwwUrl,
+ 'date' => $pathData['date'],
+ 'tag' => $pathData['tag'],
+ 'isPost' => $pathData['isPost'],
+ 'isTag' => $pathData['isTag'],
+ 'title' => $contentData['title'],
+ 'author' => $contentData['author'],
+ 'html' => gemtext2hmtl(file_get_contents($input)),
+ 'geminiOutput' => "$geminiOutput$geminiUrl",
+ 'wwwOutput' => "$wwwOutput$wwwUrl",
];
}
-function parseUrl(string $url): array
+function parsePath(string $path): array
{
$date = null;
- $category = null;
+ $tag = null;
$isPost = false;
+ $isTag = false;
/**
- * Assume that only posts have both a date and a category.
+ * Assume that only posts have both a date and a tag.
*/
- if (preg_match('/\/posts\/(.+)\/(\d\d\d\d-\d\d-\d\d)\//', $url, $matches) === 1) {
- $date = $matches[2];
- $category = $matches[1];
+ if (preg_match('/\/posts\/(.+)\/(\d\d\d\d-\d\d-\d\d)\//', $path, $matches) === 1) {
+ [, $tag, $date] = $matches;
+
$isPost = true;
}
+ /**
+ * Assume tags have an index file that contains related posts.
+ */
+ if (preg_match('/posts\/(?:[^\/]|\/\/)+\/index/', $path, $matches) === 1) {
+ $tag = explode('/', $matches[0])[1];
+ $isTag = true;
+ }
+
return [
- 'date' => $date,
- 'category' => $category,
- 'isPost' => $isPost,
+ 'date' => $date,
+ 'tag' => $tag,
+ 'isPost' => $isPost,
+ 'isTag' => $isTag,
];
}
@@ -100,28 +117,24 @@ function parseContent(string $content): array
];
}
-function buildGeminiSite(array $siteMetaData, string $output): void
+function buildGeminiSite(array $pages): void
{
- foreach ($siteMetaData as $fileMetaData) {
- $destFile = $output.DIRECTORY_SEPARATOR.$fileMetaData['url'];
-
- $destDirectory = dirname($destFile);
+ foreach ($pages as $page) {
+ $destDirectory = dirname($page['geminiOutput']);
if (!file_exists($destDirectory) && !mkdir($destDirectory, 0777, true)) {
echo "Unable to create Gemini site directory $destDirectory.";
exit(1);
}
- copy($fileMetaData['input'], $destFile);
+ copy($page['input'], $page['geminiOutput']);
}
}
-function buildWWWSite(array $siteMetaData, string $output, string $htmlTemplateDiretory, $assetsDiretory): void
+function buildWWWSite(array $pages, string $hostname, string $htmlTemplateDiretory, $assetsDiretory, string $output): void
{
- foreach ($siteMetaData as $fileMetaData) {
- $destFile = $output.DIRECTORY_SEPARATOR.$fileMetaData['url'];
-
- $destDirectory = dirname($destFile);
+ foreach ($pages as $page) {
+ $destDirectory = dirname($page['wwwOutput']);
if (!file_exists($destDirectory) && !mkdir($destDirectory, 0777, true)) {
echo "Unable to create WWW site directory $destDirectory.";
@@ -129,19 +142,21 @@ function buildWWWSite(array $siteMetaData, string $output, string $htmlTemplateD
}
file_put_contents(
- str_replace('.gmi', '.html', $destFile),
+ $page['wwwOutput'],
buildHtmlFile(
- $fileMetaData,
- gemtext2hmtl(file_get_contents($fileMetaData['input'])),
- $htmlTemplateDiretory
+ $page['title'],
+ $page['html'],
+ file_get_contents($htmlTemplateDiretory.DIRECTORY_SEPARATOR.'default.html')
)
);
}
copyWWWAssets($assetsDiretory, $output);
+
+ generateAtomFeeds($pages, $hostname);
}
-function buildHtmlFile(array $fileMetaData, string $contents, string $htmlTemplateDiretory): string
+function buildHtmlFile(string $title, string $contents, string $template): string
{
return str_replace(
[
@@ -149,10 +164,10 @@ function buildHtmlFile(array $fileMetaData, string $contents, string $htmlTempla
'{{ $contents }}'
],
[
- $fileMetaData['title'],
+ $title,
$contents,
],
- file_get_contents($htmlTemplateDiretory.DIRECTORY_SEPARATOR.'default.html')
+ $template
);
}
@@ -222,7 +237,9 @@ function gemtext2hmtl(string $gemtext): string
} elseif (preg_match(QUOTE, $line($index), $matches) === 1) {
$html[] = "<blockquote>$matches[1]</blockquote>";
} else {
- $html[] = "<p>{$line($index)}</p>";
+ if ($line($index) !== '') {
+ $html[] = "<p>{$line($index)}</p>";
+ }
}
$index++;
@@ -261,3 +278,99 @@ function copyWWWAssets(string $assetsDiretory, string $output): void
}
}
+function generateAtomFeeds(array $pages, string $hostname): void
+{
+ $posts = array_filter($pages, fn ($post) => $post['isPost']);
+
+ $tags = array_filter($pages, fn ($post) => $post['isTag']);
+
+ /**
+ * Sort by latest to previous date.
+ */
+ usort($posts, fn ($a, $b) => $b['date'] <=> $a['date']);
+
+ /**
+ * Group posts by tag.
+ */
+ $groupedPosts = array_reduce($posts, function ($carry, $post) {
+ $carry[$post['tag']][] = $post;
+
+ return $carry;
+ }, []);
+
+ /**
+ * Put posts with their tag page.
+ */
+ $tags = array_map(function ($tag) use ($groupedPosts) {
+ return array_merge($tag, ['posts' => $groupedPosts[$tag['tag']]]);
+ }, $tags);
+
+ foreach ($tags as $tag) {
+ tagToAtomFeed($tag, $hostname);
+ }
+
+ /**
+ * Get the page that lists all posts.
+ */
+ $allPostsIndex = array_values(array_filter($pages, fn ($post) => preg_match('/posts\/index/', $post['wwwUrl']) == 1))[0];
+
+ $allPostsIndex['posts'] = $posts;
+
+ tagToAtomFeed($allPostsIndex, $hostname);
+}
+
+function tagToAtomFeed(array $tag, string $hostname): void
+{
+ file_put_contents(
+ str_replace('index.html', 'atom.xml', $tag['wwwOutput']),
+ buildAtomFeed(
+ $tag['title'],
+ "https://$hostname".str_replace('index.html', 'atom.xml', $tag['wwwUrl']),
+ "https://$hostname".$tag['wwwUrl'],
+ $tag['posts'][0]['date'].'T12:00:00Z',
+ implode('', array_map(fn ($post) => postToAtomEntry($post, $hostname), $tag['posts']))
+ )
+ );
+}
+
+function postToAtomEntry(array $post, string $hostname): string
+{
+ return buildAtomEntry(
+ $post['title'],
+ "https://$hostname{$post['wwwUrl']}",
+ $post['author'],
+ "{$post['date']}T12:00:00Z",
+ $post['html'],
+ );
+}
+
+function buildAtomFeed(string $title, string $href, string $altHref, string $date, string $entries): string
+{
+ return <<<EOF_STR
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">$title</title>
+ <id>$href</id>
+ <link rel="alternate" type="text/html" href="$altHref"/>
+ <link rel="self" type="application/atom+xml" href="$href"/>
+ <updated>$date</updated>
+ $entries
+</feed>
+EOF_STR;
+}
+
+function buildAtomEntry(string $title, string $href, string $author, string $date, string $content): string
+{
+ return <<<EOF_STR
+<entry>
+ <title type="text">$title</title>
+ <id>$href</id>
+ <link rel="alternate" type="text/html" href="$href"/>
+ <author><name>$author</name></author>
+ <published>$date</published>
+ <updated>$date</updated>
+ <content>![CDATA[$content]]</content>
+</entry>
+EOF_STR;
+}
+