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

View File

@@ -27,9 +27,9 @@ serve: # 🚀 start local server
python3 -m http.server 8000 python3 -m http.server 8000
.PHONY: watch .PHONY: watch
watch: # 👀 Watch for changes... watch: build # 👀 Watch for changes...
@echo "👀 Watching 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 .PHONY: clean
clean: #🧹 Clean up generated files clean: #🧹 Clean up generated files

View File

@@ -44,21 +44,18 @@
</header> </header>
<main class="container"> <main class="container">
<!-- The table of contents. -->
{{ toc }} {{ toc }}
<!-- Each of the laws. --> <!-- The table of contents. -->
{% for law in laws %}
<section id="{{ law.id }}" class="law-section"> <!-- Each of the sections - most of which are laws. -->
<h2> {% for section in sections %}
{{ law.title }} <section id="{{ section.id }}" class="law-section">
<a href="#{{ law.id }}" class="anchor"><i class="bi bi-link-45deg"></i></a> {{ section.full_content | safe }}
</h2>
{{ law.content | safe }}
<div class="social-sharing"> <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://twitter.com/share?url=#{{ section.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="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 + '#{{ law.id }}'); alert('Copied!');" title="Copy Link"><i class="bi bi-clipboard"></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>
<div class="back-to-top"><a href="#top">↑ Back to Top</a></div> <div class="back-to-top"><a href="#top">↑ Back to Top</a></div>
</section> </section>
@@ -69,5 +66,8 @@
<footer class="container text-center my-4"> <footer class="container text-center my-4">
<p>&copy; 2025 Hacker Laws</p> <p>&copy; 2025 Hacker Laws</p>
</footer> </footer>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="script.js"></script>
</body> </body>
</html> </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

@@ -65,3 +65,18 @@
margin-top: 1rem; 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;
}