wip: looking better, almost ready for final cleanup

This commit is contained in:
Dave Kerr
2025-03-10 12:28:45 +00:00
parent 67c135701f
commit 0d001f14e1
5 changed files with 137 additions and 91 deletions

View File

@@ -1,8 +1,9 @@
"""Generate the Hacker Laws website from the Hacker Laws README"""
import argparse
import markdown
import os
import shutil
from jinja2 import Environment, FileSystemLoader
import markdown
from bs4 import BeautifulSoup
@@ -43,19 +44,31 @@ def prepare_markdown(path: str) -> str:
def parse_markdown(markdown_content: str):
(_, remains) = bisect_text(markdown_content, "<!-- vim-markdown-toc GFM -->")
(toc, content) = bisect_text(remains, "<!-- vim-markdown-toc -->")
(_, content) = bisect_text(remains, "<!-- vim-markdown-toc -->")
sections = content.split("\n## ") # Split by Markdown headings
md = markdown.Markdown(extensions=['toc'])
md.convert(content)
toc = md.toc
markdown_sections = content.split("\n#") # Split by Markdown headings
sections = []
laws = []
for section in sections:
if section.strip():
lines = section.split("\n", 1)
for markdown_section in markdown_sections:
if markdown_section.strip():
lines = markdown_section.split("\n", 1)
title = lines[0].strip("# ").strip()
content = markdown.markdown(lines[1] if len(lines) > 1 else "")
law_id = title.lower().replace(" ", "-")
laws.append({"title": title, "content": content, "id": law_id})
content = md.convert(lines[1] if len(lines) > 1 else "")
full_content = md.convert(markdown_section)
id = title.lower().replace(" ", "-")
laws.append({"title": title, "content": content, "id": id})
sections.append({
"title": title,
"content": content,
"id": id,
"full_content": full_content
})
return (markdown.markdown(toc), laws)
return (sections, toc)
def extract_static_files(html_content, output_dir):
@@ -103,13 +116,13 @@ def generate_site(markdown_content: str, output_dir: str):
"""Generate the static HTML file from Markdown and Jinja2 template."""
template = load_template()
(toc, laws) = parse_markdown(markdown_content)
(sections, toc) = parse_markdown(markdown_content)
# Ensure output directory exists
os.makedirs(output_dir, exist_ok=True)
# Render HTML
html_output = template.render(toc=toc, laws=laws)
html_output = template.render(toc=toc, sections=sections)
# Save HTML to output directory
output_file = os.path.join(output_dir, "index.html")

View File

@@ -27,9 +27,9 @@ serve: # 🚀 start local server
python3 -m http.server 8000
.PHONY: watch
watch: # 👀 Watch for changes...
watch: build # 👀 Watch for changes...
@echo "👀 Watching for changes..."
watchmedo shell-command --patterns="$(MARKDOWN_FILE);*.py;./src/*.*" --command="make build" .
watchmedo shell-command --patterns="$(MARKDOWN_FILE);*.py;src/*" --command="make build" .
.PHONY: clean
clean: #🧹 Clean up generated files

View File

@@ -44,21 +44,18 @@
</header>
<main class="container">
<!-- The table of contents. -->
{{ toc }}
<!-- Each of the laws. -->
{% 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 }}
<!-- The table of contents. -->
<!-- Each of the sections - most of which are laws. -->
{% for section in sections %}
<section id="{{ section.id }}" class="law-section">
{{ section.full_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>
<a href="https://twitter.com/share?url=#{{ section.id }}" title="Share on Twitter"><i class="bi bi-twitter"></i></a>
<a href="https://facebook.com/share?url=#{{ section.id }}" title="Share on Facebook"><i class="bi bi-facebook"></i></a>
<a href="#" onclick="navigator.clipboard.writeText(window.location.href + '#{{ section.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>
@@ -69,5 +66,8 @@
<footer class="container text-center my-4">
<p>&copy; 2025 Hacker Laws</p>
</footer>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="script.js"></script>
</body>
</html>

18
.github/website/src/script.js vendored Normal file
View File

@@ -0,0 +1,18 @@
$(document).ready(function() {
$("h1, h2, h3, h4, h5, h6").each(function() {
var $heading = $(this);
var headingId = $heading.attr("id") || $heading.text().trim().toLowerCase().replace(/\s+/g, "-");
// Ensure a unique ID
$heading.attr("id", headingId);
// Create the anchor link
var $anchor = $('<a>')
.attr("href", "#" + headingId)
.addClass("header-link")
.html("#");
// Append to the heading
$heading.append($anchor);
});
});

View File

@@ -1,67 +1,82 @@
body {
font-family: 'Inter', sans-serif;
background-color: #fff;
color: #333;
padding-top: 70px;
}
.container {
max-width: 800px;
}
.navbar-custom {
background-color: #fff;
border-bottom: 1px solid #e5e5e5;
}
.navbar-brand, .nav-link {
font-weight: 700;
}
header {
text-align: center;
margin-bottom: 2rem;
padding: 2rem 0;
border-bottom: 1px solid #e5e5e5;
}
h1, h2 {
font-family: 'Libre Baskerville', serif;
}
.law-section {
margin-bottom: 2rem;
padding: 1.5rem;
background-color: #fff;
border-bottom: 1px solid #e5e5e5;
position: relative;
}
.law-section h2 {
position: relative;
display: flex;
align-items: center;
}
.law-section h2 a.anchor {
text-decoration: none;
color: #999;
margin-left: 0.5rem;
visibility: hidden;
}
.law-section:hover h2 a.anchor {
visibility: visible;
}
a {
color: #0056b3;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
.social-sharing a {
margin-right: 0.75rem;
font-size: 1.2rem;
color: #555;
text-decoration: none;
}
.social-sharing a:hover {
color: #000;
}
.back-to-top {
margin-top: 1rem;
}
body {
font-family: 'Inter', sans-serif;
background-color: #fff;
color: #333;
padding-top: 70px;
}
.container {
max-width: 800px;
}
.navbar-custom {
background-color: #fff;
border-bottom: 1px solid #e5e5e5;
}
.navbar-brand, .nav-link {
font-weight: 700;
}
header {
text-align: center;
margin-bottom: 2rem;
padding: 2rem 0;
border-bottom: 1px solid #e5e5e5;
}
h1, h2 {
font-family: 'Libre Baskerville', serif;
}
.law-section {
margin-bottom: 2rem;
padding: 1.5rem;
background-color: #fff;
border-bottom: 1px solid #e5e5e5;
position: relative;
}
.law-section h2 {
position: relative;
display: flex;
align-items: center;
}
.law-section h2 a.anchor {
text-decoration: none;
color: #999;
margin-left: 0.5rem;
visibility: hidden;
}
.law-section:hover h2 a.anchor {
visibility: visible;
}
a {
color: #0056b3;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
.social-sharing a {
margin-right: 0.75rem;
font-size: 1.2rem;
color: #555;
text-decoration: none;
}
.social-sharing a:hover {
color: #000;
}
.back-to-top {
margin-top: 1rem;
}
/* Initially hide the hash link */
.header-link {
text-decoration: none;
margin-left: 12px; /* Increased left padding */
opacity: 0;
transition: opacity 0.2s;
font-size: inherit; /* Matches the heading size */
}
/* Only show the hash when the whole section is hovered */
section:hover .header-link,
article:hover .header-link,
div:hover .header-link {
opacity: 1;
}