mirror of
https://github.com/dwmkerr/hacker-laws.git
synced 2025-12-17 12:45:20 +01:00
chore: wip on site build
This commit is contained in:
62
.github/pages/generate_site.py
vendored
Normal file
62
.github/pages/generate_site.py
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
import argparse
|
||||
import markdown
|
||||
import os
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
|
||||
# Read environment variables with defaults
|
||||
TEMPLATE_FILE = os.getenv("TEMPLATE_FILE", "template.html")
|
||||
MARKDOWN_FILE = os.getenv("MARKDOWN_FILE", "laws.md")
|
||||
OUTPUT_FILE = os.getenv("OUTPUT_FILE", "output.html")
|
||||
TEMPLATE_DIR = os.getenv("TEMPLATE_DIR", ".")
|
||||
|
||||
|
||||
def load_template():
|
||||
"""Load Jinja2 template from the specified directory."""
|
||||
env = Environment(loader=FileSystemLoader(TEMPLATE_DIR))
|
||||
return env.get_template(TEMPLATE_FILE)
|
||||
|
||||
|
||||
def parse_markdown(md_file):
|
||||
"""Parse a Markdown file and return structured law sections."""
|
||||
with open(md_file, "r", encoding="utf-8") as f:
|
||||
md_content = f.read()
|
||||
|
||||
sections = md_content.split("\n## ") # Split by Markdown headings
|
||||
laws = []
|
||||
for section in sections:
|
||||
if section.strip():
|
||||
lines = section.split("\n", 1)
|
||||
title = lines[0].strip("# ").strip()
|
||||
# Skip sections which do not need to be processed.
|
||||
# print(f"found title: {title}")
|
||||
# if "hacker-laws" in title:
|
||||
# continue
|
||||
content = markdown.markdown(lines[1] if len(lines) > 1 else "")
|
||||
law_id = title.lower().replace(" ", "-")
|
||||
laws.append({"title": title, "content": content, "id": law_id})
|
||||
|
||||
return laws
|
||||
|
||||
|
||||
def generate_site():
|
||||
"""Generate the static HTML file from Markdown and Jinja2 template."""
|
||||
print(f"📝 Loading template from: {TEMPLATE_DIR}/{TEMPLATE_FILE}")
|
||||
print(f"📖 Loading markdown from: {MARKDOWN_FILE}")
|
||||
print(f"💾 Outputting HTML to: {OUTPUT_FILE}")
|
||||
|
||||
template = load_template()
|
||||
laws = parse_markdown(MARKDOWN_FILE)
|
||||
|
||||
with open(OUTPUT_FILE, "w", encoding="utf-8") as f:
|
||||
f.write(template.render(laws=laws))
|
||||
|
||||
print(f"✅ Static site generated: {OUTPUT_FILE}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Generate a static site from Markdown.")
|
||||
parser.add_argument("--build", action="store_true", help="Build the static site.")
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.build:
|
||||
generate_site()
|
||||
72
.github/pages/index.backup.html
vendored
Normal file
72
.github/pages/index.backup.html
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Hacker Laws</title>
|
||||
<!-- Google tag (gtag.js) -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-RGJ5TDHWY9"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
|
||||
gtag('config', 'G-RGJ5TDHWY9');
|
||||
</script>
|
||||
<!-- Google Fonts -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Libre+Baskerville:wght@400;700&family=Inter:wght@400;600&display=swap" rel="stylesheet">
|
||||
<!-- Bootstrap CSS -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" />
|
||||
<!-- Bootstrap Icons -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
</head>
|
||||
<body id="top">
|
||||
<nav class="navbar navbar-expand-lg navbar-custom fixed-top">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="#top">Hacker Laws</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navMenu">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navMenu">
|
||||
<ul class="navbar-nav me-auto">
|
||||
<li class="nav-item"><a class="nav-link" href="#">Effective Shell</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#">Sponsor</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#">Terminal AI</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<header class="container">
|
||||
<h1>Hacker Laws</h1>
|
||||
<p class="lead">Laws, Theories, Principles and Patterns that developers will find useful.</p>
|
||||
</header>
|
||||
|
||||
<main class="container">
|
||||
<section id="introduction" class="law-section">
|
||||
<h2>
|
||||
Introduction
|
||||
<a href="#introduction" class="anchor"><i class="bi bi-link-45deg"></i></a>
|
||||
</h2>
|
||||
<p>There are lots of laws which people discuss when talking about development...</p>
|
||||
<blockquote>“Any code of your own that you haven’t looked at for six or more months might as well have been written by someone else.” – Eagleson's Law</blockquote>
|
||||
<ul>
|
||||
<li><a href="#">Law of Demeter</a></li>
|
||||
<li><a href="#">Pareto Principle</a></li>
|
||||
<li><a href="#">Hofstadter's Law</a></li>
|
||||
</ul>
|
||||
<div class="social-sharing">
|
||||
<a href="#" title="Share on Twitter"><i class="bi bi-twitter"></i></a>
|
||||
<a href="#" title="Share on Facebook"><i class="bi bi-facebook"></i></a>
|
||||
<a href="#" title="Copy Link"><i class="bi bi-clipboard"></i></a>
|
||||
</div>
|
||||
<div class="back-to-top"><a href="#top">↑ Back to Top</a></div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer class="container text-center my-4">
|
||||
<p>© 2025 Hacker Laws</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
1023
.github/pages/index.html
vendored
1023
.github/pages/index.html
vendored
File diff suppressed because it is too large
Load Diff
88
.github/pages/index.html.jinja
vendored
Normal file
88
.github/pages/index.html.jinja
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Hacker Laws</title>
|
||||
<!-- Google tag (gtag.js) -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-RGJ5TDHWY9"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
|
||||
gtag('config', 'G-RGJ5TDHWY9');
|
||||
</script>
|
||||
<!-- Google Fonts -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Libre+Baskerville:wght@400;700&family=Inter:wght@400;600&display=swap" rel="stylesheet">
|
||||
<!-- Bootstrap CSS -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" />
|
||||
<!-- Bootstrap Icons -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
</head>
|
||||
<body id="top">
|
||||
<nav class="navbar navbar-expand-lg navbar-custom fixed-top">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="#top">Hacker Laws</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navMenu">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navMenu">
|
||||
<ul class="navbar-nav me-auto">
|
||||
<li class="nav-item"><a class="nav-link" href="#">Effective Shell</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#">Sponsor</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#">Terminal AI</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<header class="container">
|
||||
<h1>Hacker Laws</h1>
|
||||
<p class="lead">Laws, Theories, Principles and Patterns that developers will find useful.</p>
|
||||
</header>
|
||||
|
||||
<main class="container">
|
||||
<section id="introduction" class="law-section">
|
||||
<h2>
|
||||
Introduction
|
||||
<a href="#introduction" class="anchor"><i class="bi bi-link-45deg"></i></a>
|
||||
</h2>
|
||||
<p>There are lots of laws which people discuss when talking about development...</p>
|
||||
<blockquote>“Any code of your own that you haven’t looked at for six or more months might as well have been written by someone else.” – Eagleson's Law</blockquote>
|
||||
<ul>
|
||||
<li><a href="#">Law of Demeter</a></li>
|
||||
<li><a href="#">Pareto Principle</a></li>
|
||||
<li><a href="#">Hofstadter's Law</a></li>
|
||||
</ul>
|
||||
<div class="social-sharing">
|
||||
<a href="#" title="Share on Twitter"><i class="bi bi-twitter"></i></a>
|
||||
<a href="#" title="Share on Facebook"><i class="bi bi-facebook"></i></a>
|
||||
<a href="#" title="Copy Link"><i class="bi bi-clipboard"></i></a>
|
||||
</div>
|
||||
<div class="back-to-top"><a href="#top">↑ Back to Top</a></div>
|
||||
</section>
|
||||
{% for law in laws %}
|
||||
<section id="{{ law.id }}" class="law-section">
|
||||
<h2>
|
||||
{{ law.title }}
|
||||
<a href="#{{ law.id }}" class="anchor"><i class="bi bi-link-45deg"></i></a>
|
||||
</h2>
|
||||
{{ law.content | safe }}
|
||||
<div class="social-sharing">
|
||||
<a href="https://twitter.com/share?url=#{{ law.id }}" title="Share on Twitter"><i class="bi bi-twitter"></i></a>
|
||||
<a href="https://facebook.com/share?url=#{{ law.id }}" title="Share on Facebook"><i class="bi bi-facebook"></i></a>
|
||||
<a href="#" onclick="navigator.clipboard.writeText(window.location.href + '#{{ law.id }}'); alert('Copied!');" title="Copy Link"><i class="bi bi-clipboard"></i></a>
|
||||
</div>
|
||||
<div class="back-to-top"><a href="#top">↑ Back to Top</a></div>
|
||||
</section>
|
||||
{% endfor %}
|
||||
|
||||
</main>
|
||||
|
||||
<footer class="container text-center my-4">
|
||||
<p>© 2025 Hacker Laws</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
36
.github/pages/makefile
vendored
Normal file
36
.github/pages/makefile
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
SHELL := /bin/bash
|
||||
TEMPLATE_FILE=index.html.jinja
|
||||
MARKDOWN_FILE=../../README.md
|
||||
OUTPUT_FILE=index.html
|
||||
TEMPLATE_DIR=.
|
||||
default: help
|
||||
|
||||
.PHONY: help
|
||||
help: # Show help for each of the Makefile recipes.
|
||||
@grep -E '^[a-zA-Z0-9 -]+:.*#' Makefile | sort | while read -r l; do printf "\033[1;32m$$(echo $$l | cut -f 1 -d':')\033[00m:$$(echo $$l | cut -f 2- -d'#')\n"; done
|
||||
|
||||
.PHONY: install
|
||||
install: # 📦 install dependencies
|
||||
@echo "📦 Installing dependencies..."
|
||||
pip install -r requirements.txt
|
||||
|
||||
.PHONY: build
|
||||
build: #🔨 building static site
|
||||
@echo "🔨 Building static site..."
|
||||
TEMPLATE_FILE=$(TEMPLATE_FILE) MARKDOWN_FILE=$(MARKDOWN_FILE) OUTPUT_FILE=$(OUTPUT_FILE) TEMPLATE_DIR=$(TEMPLATE_DIR) \
|
||||
python generate_site.py --build
|
||||
|
||||
.PHONY: serve
|
||||
serve: # 🚀 start local server
|
||||
@echo "🚀 Starting local server at http://localhost:8000..."
|
||||
python3 -m http.server 8000
|
||||
|
||||
.PHONY: watch
|
||||
watch: # 👀 Watch for changes...
|
||||
@echo "👀 Watching for changes..."
|
||||
watchmedo shell-command --patterns="$(MARKDOWN_FILE);*.py" --command="make build" .
|
||||
|
||||
.PHONY: clean
|
||||
clean: #🧹 Clean up generated files
|
||||
@echo "🧹 Cleaning up generated files..."
|
||||
rm -f $(OUTPUT)
|
||||
3
.github/pages/requirements.txt
vendored
Normal file
3
.github/pages/requirements.txt
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
markdown
|
||||
jinja2
|
||||
watchdog
|
||||
Reference in New Issue
Block a user