examples: added homepage + categories pages + added CSS (similar to wiki)

This commit is contained in:
Nicolas Allemand 2024-12-04 12:12:43 +01:00 committed by Ryan C. Gordon
parent 9784e10a75
commit 56da4e81d8
5 changed files with 532 additions and 33 deletions

View file

@ -71,6 +71,38 @@ sub build_latest {
} }
} }
sub get_categories {
my @categories = ();
opendir(my $dh, $examples_dir) or die("Couldn't opendir '$examples_dir': $!\n");
foreach my $dir (sort readdir $dh) {
next if ($dir eq '.') || ($dir eq '..'); # obviously skip current and parent entries.
next if not -d "$examples_dir/$dir"; # only care about subdirectories.
push @categories, $dir;
}
closedir($dh);
return @categories;
}
sub get_examples_for_category {
my $category = shift;
my @examples = ();
opendir(my $dh, "$examples_dir/$category") or die("Couldn't opendir '$examples_dir/$category': $!\n");
foreach my $dir (sort readdir $dh) {
next if ($dir eq '.') || ($dir eq '..'); # obviously skip current and parent entries.
next if not -d "$examples_dir/$category/$dir"; # only care about subdirectories.
push @examples, $dir;
}
closedir($dh);
return @examples;
}
sub handle_example_dir { sub handle_example_dir {
my $category = shift; my $category = shift;
my $example = shift; my $example = shift;
@ -146,6 +178,11 @@ sub handle_example_dir {
waitpid($pid, 0); waitpid($pid, 0);
my $other_examples_html = "<ul>";
foreach my $example (get_examples_for_category($category)) {
$other_examples_html .= "<li><a href='/$category/$example'>$category/$example</a></li>";
}
$other_examples_html .= "</ul>";
my $html = ''; my $html = '';
open my $htmltemplate, '<', "$examples_dir/template.html" or die("Couldn't open '$examples_dir/template.html': $!\n"); open my $htmltemplate, '<', "$examples_dir/template.html" or die("Couldn't open '$examples_dir/template.html': $!\n");
@ -156,6 +193,7 @@ sub handle_example_dir {
s/\@javascript_file\@/$jsfname/g; s/\@javascript_file\@/$jsfname/g;
s/\@htmlified_source_code\@/$htmlified_source_code/g; s/\@htmlified_source_code\@/$htmlified_source_code/g;
s/\@description\@/$description/g; s/\@description\@/$description/g;
s/\@other_examples_html\@/$other_examples_html/g;
$html .= $_; $html .= $_;
} }
close($htmltemplate); close($htmltemplate);
@ -168,8 +206,6 @@ sub handle_example_dir {
sub handle_category_dir { sub handle_category_dir {
my $category = shift; my $category = shift;
# !!! FIXME: this needs to generate a preview page for all the examples things in the category.
print("Category $category ...\n"); print("Category $category ...\n");
do_mkdir("$output_dir/$category"); do_mkdir("$output_dir/$category");
@ -183,6 +219,35 @@ sub handle_category_dir {
} }
closedir($dh); closedir($dh);
my $examples_list_html = "";
foreach my $example (get_examples_for_category($category)) {
# !!! FIXME: image
my $example_image_url = "https://placehold.co/600x400/png";
$examples_list_html .= "
<a href='/$category/$example'>
<div>
<img src='$example_image_url' />
<div>$category/$example</div>
</div>
</a>";
}
# write category page
my $dst = "$output_dir/$category";
my $html = '';
open my $htmltemplate, '<', "$examples_dir/template-category.html" or die("Couldn't open '$examples_dir/template-category.html': $!\n");
while (<$htmltemplate>) {
s/\@project_name\@/$project/g;
s/\@category_name\@/$category/g;
s/\@examples_list_html\@/$examples_list_html/g;
$html .= $_;
}
close($htmltemplate);
open my $htmloutput, '>', "$dst/index.html" or die("Couldn't open '$dst/index.html': $!\n");
print $htmloutput $html;
close($htmloutput);
} }
@ -210,6 +275,8 @@ do_mkdir($output_dir);
build_latest(); build_latest();
do_copy("$examples_dir/template.css", "$output_dir/examples.css");
opendir(my $dh, $examples_dir) or die("Couldn't opendir '$examples_dir': $!\n"); opendir(my $dh, $examples_dir) or die("Couldn't opendir '$examples_dir': $!\n");
while (readdir($dh)) { while (readdir($dh)) {
@ -221,6 +288,38 @@ while (readdir($dh)) {
closedir($dh); closedir($dh);
# write homepage
my $homepage_list_html = "";
foreach my $category (get_categories()) {
$homepage_list_html .= "<h2>$category</h2>";
$homepage_list_html .= "<div class='list'>";
foreach my $example (get_examples_for_category($category)) {
# !!! FIXME: image
my $example_image_url = "https://placehold.co/600x400/png";
$homepage_list_html .= "
<a href='/$category/$example'>
<div>
<img src='$example_image_url' />
<div>$category/$example</div>
</div>
</a>";
}
$homepage_list_html .= "</div>";
}
my $dst = "$output_dir/";
my $html = '';
open my $htmltemplate, '<', "$examples_dir/template-homepage.html" or die("Couldn't open '$examples_dir/template-category.html': $!\n");
while (<$htmltemplate>) {
s/\@project_name\@/$project/g;
s/\@homepage_list_html\@/$homepage_list_html/g;
$html .= $_;
}
close($htmltemplate);
open my $htmloutput, '>', "$dst/index.html" or die("Couldn't open '$dst/index.html': $!\n");
print $htmloutput $html;
close($htmloutput);
print("All examples built successfully!\n"); print("All examples built successfully!\n");
exit(0); # success! exit(0); # success!

View file

@ -0,0 +1,30 @@
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>@project_name@ Examples: @category_name@</title>
<link rel="stylesheet" type="text/css" href="/examples.css" />
<style>
main > h1 {
margin-top: 0;
}
</style>
</head>
<body>
<header>
<a href="/">SDL Examples</a>
</header>
<main>
<nav class="breadcrumb">
<ul>
<li><a href="/">@project_name@</a></li>
<li><a href="/@category_name@">@category_name@</a></li>
</ul>
</nav>
<h1>@project_name@ examples: @category_name@</h1>
<div class="list">@examples_list_html@</div>
</main>
</body>
</html>

View file

@ -0,0 +1,32 @@
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>@project_name@ Examples</title>
<link rel="stylesheet" type="text/css" href="/examples.css" />
<style>
main > h1 {
margin-top: 0;
}
</style>
</head>
<body>
<header>
<a href="/">SDL Examples</a>
</header>
<main>
<nav class="breadcrumb">
<ul>
<li><a href="/">@project_name@</a></li>
</ul>
</nav>
<h1>@project_name@ examples</h1>
<p>Check out the @project_name@ examples here!</p>
@homepage_list_html@
</main>
</body>
</html>

284
examples/template.css Normal file
View file

@ -0,0 +1,284 @@
/** from ghwikipp.css */
:root {
color-scheme: dark light; /* both supported */
}
body {
background-color: white;
padding: 2vw;
color: #333;
max-width: 1200px;
margin: 0 auto;
font-size: 16px;
line-height: 1.5;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans",
Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
overflow-wrap: break-word;
}
a {
color: #0969da;
/* text-decoration: none; */
}
a:visited {
color: #064998;
}
h1 {
border-bottom: 2px solid #efefef;
}
h2 {
border-bottom: 1px solid #efefef;
}
p {
max-width: 85ch;
}
li {
max-width: 85ch;
}
div.sourceCode {
background-color: #f6f8fa;
max-width: 100%;
padding: 16px;
}
code {
background-color: #f6f8fa;
padding: 0px;
font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
"Liberation Mono", monospace;
}
table {
border: 1px solid #808080;
border-collapse: collapse;
}
td {
border: 1px solid #808080;
padding: 5px;
}
tr:nth-child(even) {
background-color: #f6f8fa;
}
.wikitopbanner {
background-color: #efefef;
padding: 10px;
margin-bottom: 10px;
width: auto;
}
.wikibottombanner {
background-color: #efefef;
padding: 10px;
margin-top: 10px;
width: auto;
}
.alertBox {
background-color: #f8d7da;
border: 1px solid #f5c6cb;
max-width: 60%;
padding: 10;
margin: auto;
}
.anchorImage {
visibility: hidden;
padding-left: 0.2em;
color: #fff;
}
.anchorText:hover .anchorImage {
visibility: visible;
}
hr {
display: block;
height: 1px;
border: 0;
border-top: 1px solid #efefef;
margin: 1em 0;
padding: 0;
}
/* Text and background color for dark mode */
@media (prefers-color-scheme: dark) {
body {
color: #e6edf3;
background-color: #0d1117;
}
h1 {
border-color: rgba(48, 54, 61, 0.7);
}
h2 {
border-color: rgba(48, 54, 61, 0.7);
}
hr {
border-color: rgba(48, 54, 61, 0.7);
}
div.sourceCode {
background-color: #161b22;
}
code {
background-color: #161b22;
}
a {
color: #4493f8;
}
a:visited {
color: #2f66ad;
}
table {
border-color: rgba(48, 54, 61, 0.7);
}
td {
border-color: rgba(48, 54, 61, 0.7);
}
tr:nth-child(even) {
background-color: #161b22;
}
.wikitopbanner {
background-color: #263040;
}
.wikibottombanner {
background-color: #263040;
}
.anchorText:hover .anchorImage {
filter: invert(100%);
}
}
@media print {
body {
font-size: 12px;
}
table {
font-size: inherit;
}
a:visited {
color: #0969da;
}
.wikitopbanner,
.anchorText,
.wikibottombanner {
display: none;
}
}
/** additional (& overrides) for examples */
header {
background-color: #efefef;
padding: 10px;
font-size: 2rem;
}
header > a,
header > a:hover,
header > a:visited {
color: inherit;
text-decoration: none;
}
.breadcrumb {
padding: 0.75rem 0.75rem;
}
.breadcrumb ul {
display: flex;
flex-wrap: wrap;
list-style: none;
margin: 0;
padding: 0;
}
.breadcrumb li:not(:last-child)::after {
display: inline-block;
margin: 0 0.25rem;
content: "»";
}
.list {
display: flex;
flex-flow: row wrap;
gap: 24px;
}
.list > a > div {
width: 200px;
border: 5px solid #efefef;
border-radius: 5px;
background: #efefef;
display: flex;
flex-flow: column nowrap;
transition: border 0.25s;
}
.list > a > div:hover {
border-color: #064998;
}
.list > a > div > img {
width: 100%;
border-radius: 5px;
}
.list > a > div > div {
text-align: center;
}
.list > a,
.list > a:visited {
display: block;
color: inherit;
text-decoration: none;
}
.list > a:hover {
color: #0969da;
}
@media (prefers-color-scheme: dark) {
header {
background-color: #263040;
}
.breadcrumb li:not(:last-child)::after {
color: #efefef;
}
.list > a > div {
border-color: #333;
background: #333;
}
}
@media only screen and (max-width: 992px) {
.list > a > div {
width: 150px;
}
}

View file

@ -3,27 +3,48 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>@project_name@ Example: @category_name@/@example_name@</title> <title>@project_name@ Example: @category_name@/@example_name@</title>
<link rel="stylesheet" type="text/css" href="/examples.css" />
<style> <style>
html, body { main {
width: 100vw; display: flex;
height: 100vh; }
overflow: hidden;
font-family: 'Liberation Sans', sans-serif; main > #sidebar {
flex: 0 1 25%;
border-left: 2px solid #efefef;
padding: 1rem 1rem;
}
main > #content {
flex: 1 1 auto;
margin-bottom: 16px;
}
main > #content > h1 {
margin-top: 0;
}
main > #sidebar ul {
list-style-type: none;
padding: 0;
margin: 0;
}
main > #sidebar li {
padding: 2px 0;
}
#example-description {
max-width: 85ch;
margin-bottom: 16px;
} }
.canvas-container { .canvas-container {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
background: black;
} }
#canvas { #canvas {
@ -31,7 +52,7 @@
} }
#output-container { #output-container {
position: absolute; position: fixed;
top: 100%; top: 100%;
left: 0; left: 0;
right: 0; right: 0;
@ -47,8 +68,8 @@
} }
#output-container::before { #output-container::before {
position: absolute; position: fixed;
bottom: 100%; bottom: 0;
right: 1rem; right: 1rem;
content: 'Console'; content: 'Console';
@ -87,11 +108,12 @@
outline: none; outline: none;
resize: none; resize: none;
font-family: 'Lucida Console', Monaco, monospace; font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
"Liberation Mono", monospace;
} }
#source-code { #source-code {
position: absolute; position: fixed;
top: 100%; top: 100%;
left: 0; left: 0;
right: 0; right: 0;
@ -104,8 +126,8 @@
} }
#source-code::before { #source-code::before {
position: absolute; position: fixed;
bottom: 100%; bottom: 0;
left: 1rem; left: 1rem;
content: 'Source code'; content: 'Source code';
@ -134,21 +156,53 @@
overflow: scroll; overflow: scroll;
} }
#example-description { @media (prefers-color-scheme: dark) {
color: white; main > #sidebar {
text-align: center; border-color: rgba(48, 54, 61, 0.7);
position: relative; /* required for proper positioning */ }
}
@media only screen and (max-width: 992px) {
main {
flex-direction: column;
}
main > #sidebar {
border: none;
}
} }
</style> </style>
<link rel="stylesheet" type="text/css" href="highlight.css"> <link rel="stylesheet" type="text/css" href="highlight.css">
</head> </head>
<body> <body>
<div class="canvas-container"> <header>
<canvas id="canvas" oncontextmenu="event.preventDefault()" tabindex="-1"></canvas> <a href="/">SDL Examples</a>
</div> </header>
<div id="example-description"> <main>
@description@ <div id="content">
</div> <nav class="breadcrumb">
<ul>
<li><a href="/">@project_name@</a></li>
<li><a href="/@category_name@">@category_name@</a></li>
<li><a href="/@category_name@/@example_name@">@example_name@</a></li>
</ul>
</nav>
<h1>@project_name@ example: @category_name@/@example_name@</h1>
<div id="example-description">@description@</div>
<div class="canvas-container">
<canvas
id="canvas"
oncontextmenu="event.preventDefault()"
tabindex="-1"
></canvas>
</div>
</div>
<div id="sidebar">
<h3>Other examples:</h3>
@other_examples_html@
</div>
</main>
<div id="output-container"> <div id="output-container">
<textarea id="output" rows="8" spellcheck="false" readonly></textarea> <textarea id="output" rows="8" spellcheck="false" readonly></textarea>
</div> </div>