mirror of
https://github.com/dwmkerr/hacker-laws.git
synced 2025-12-18 13:14:55 +01:00
chore: slightly better markdown
This commit is contained in:
24
.github/pages/ideas.md
vendored
24
.github/pages/ideas.md
vendored
@@ -1,24 +0,0 @@
|
|||||||
https://mmistakes.github.io/so-simple-theme/
|
|
||||||
|
|
||||||
TODO
|
|
||||||
|
|
||||||
- heading link markdown anchor style
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
I'm going to paste two links. One is an index of blog posts, one is a specific blog post:
|
|
||||||
|
|
||||||
1. Index: https://mmistakes.github.io/so-simple-theme/
|
|
||||||
2. Specific: https://mmistakes.github.io/so-simple-theme/markup-syntax-highlighting/
|
|
||||||
|
|
||||||
We're going to take this and create a single page, with the markdown at the end of this message as the template. Requirements:
|
|
||||||
|
|
||||||
1. Simplify the top bar, sticky. Title is 'Hacker Laws', next button is 'Effective Shell [book icon]' then 'Sponsor [coffee icon]' then 'Terminal AI [brain icon]' then 'GitHub [github icon, this item right aligned]'
|
|
||||||
2. Use bootstrap and bootstrap icons so that we have a CSS starting point eg. for the grid
|
|
||||||
3. Use the social sharing icons below each 'law'
|
|
||||||
4. There is no need to link to any content pages - this is a single page
|
|
||||||
5. Below each law we need a 'back to top' button, choose 3-5 options so that I can pick the one I prefer, think about common patterns used to visually indicate 'go to top'
|
|
||||||
6. No need for disqus
|
|
||||||
7. Theme should be soft pastel colors, prefer a paper colored background perhaps very slightly yellow like parchment
|
|
||||||
8. No logo at the top, but Hacker Laws in slightly larger text with the subtitle
|
|
||||||
```
|
|
||||||
1
.github/website/build/.gitignore
vendored
1
.github/website/build/.gitignore
vendored
@@ -0,0 +1 @@
|
|||||||
|
*
|
||||||
|
|||||||
73
.github/website/generate.py
vendored
73
.github/website/generate.py
vendored
@@ -5,10 +5,22 @@ import shutil
|
|||||||
from jinja2 import Environment, FileSystemLoader
|
from jinja2 import Environment, FileSystemLoader
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
|
|
||||||
# Read environment variables with defaults
|
|
||||||
TEMPLATE_FILE = os.getenv("TEMPLATE_FILE", "template.html")
|
def bisect_text(content: str, bisect_line: str) -> tuple[str, str]:
|
||||||
MARKDOWN_FILE = os.getenv("MARKDOWN_FILE", "laws.md")
|
lines = content.splitlines()
|
||||||
TEMPLATE_DIR = os.getenv("TEMPLATE_DIR", ".") # Directory where template is stored
|
head = []
|
||||||
|
tail = []
|
||||||
|
found = False
|
||||||
|
for line in lines:
|
||||||
|
if found is False and line == bisect_line:
|
||||||
|
found = True
|
||||||
|
continue
|
||||||
|
if found:
|
||||||
|
tail.append(line)
|
||||||
|
else:
|
||||||
|
head.append(line)
|
||||||
|
|
||||||
|
return ("\n".join(head), "\n".join(tail))
|
||||||
|
|
||||||
|
|
||||||
def load_template():
|
def load_template():
|
||||||
@@ -17,12 +29,23 @@ def load_template():
|
|||||||
return env.get_template(TEMPLATE_FILE)
|
return env.get_template(TEMPLATE_FILE)
|
||||||
|
|
||||||
|
|
||||||
def parse_markdown(md_file):
|
def prepare_markdown(path: str) -> str:
|
||||||
"""Parse a Markdown file and return structured law sections."""
|
"""
|
||||||
with open(md_file, "r", encoding="utf-8") as f:
|
Pre-process the README markdown by removing content we will not show in
|
||||||
md_content = f.read()
|
the final website.
|
||||||
|
"""
|
||||||
|
|
||||||
sections = md_content.split("\n## ") # Split by Markdown headings
|
# Load the markdown content.
|
||||||
|
with open(path, "r", encoding="utf-8") as f:
|
||||||
|
content = f.read()
|
||||||
|
return content
|
||||||
|
|
||||||
|
|
||||||
|
def parse_markdown(markdown_content: str):
|
||||||
|
(_, remains) = bisect_text(markdown_content, "<!-- vim-markdown-toc GFM -->")
|
||||||
|
(toc, content) = bisect_text(remains, "<!-- vim-markdown-toc -->")
|
||||||
|
|
||||||
|
sections = content.split("\n## ") # Split by Markdown headings
|
||||||
laws = []
|
laws = []
|
||||||
for section in sections:
|
for section in sections:
|
||||||
if section.strip():
|
if section.strip():
|
||||||
@@ -32,11 +55,14 @@ def parse_markdown(md_file):
|
|||||||
law_id = title.lower().replace(" ", "-")
|
law_id = title.lower().replace(" ", "-")
|
||||||
laws.append({"title": title, "content": content, "id": law_id})
|
laws.append({"title": title, "content": content, "id": law_id})
|
||||||
|
|
||||||
return laws
|
return (markdown.markdown(toc), laws)
|
||||||
|
|
||||||
|
|
||||||
def extract_static_files(html_content, output_dir):
|
def extract_static_files(html_content, output_dir):
|
||||||
"""Extract linked CSS, JS, and image files and copy them to the output directory."""
|
"""
|
||||||
|
Extract linked CSS, JS, and image files and copy them to the output
|
||||||
|
directory.
|
||||||
|
"""
|
||||||
soup = BeautifulSoup(html_content, "html.parser")
|
soup = BeautifulSoup(html_content, "html.parser")
|
||||||
files_to_copy = []
|
files_to_copy = []
|
||||||
|
|
||||||
@@ -73,20 +99,17 @@ def extract_static_files(html_content, output_dir):
|
|||||||
return files_to_copy
|
return files_to_copy
|
||||||
|
|
||||||
|
|
||||||
def generate_site(output_dir):
|
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."""
|
||||||
print(f"📝 Loading template from: {TEMPLATE_DIR}/{TEMPLATE_FILE}")
|
|
||||||
print(f"📖 Loading markdown from: {MARKDOWN_FILE}")
|
|
||||||
print(f"💾 Outputting files to: {output_dir}")
|
|
||||||
|
|
||||||
template = load_template()
|
template = load_template()
|
||||||
laws = parse_markdown(MARKDOWN_FILE)
|
(toc, laws) = 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(laws=laws)
|
html_output = template.render(toc=toc, laws=laws)
|
||||||
|
|
||||||
# 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")
|
||||||
@@ -104,4 +127,18 @@ if __name__ == "__main__":
|
|||||||
parser.add_argument("-o", "--output-dir", default="build", help="Directory to save the generated site.")
|
parser.add_argument("-o", "--output-dir", default="build", help="Directory to save the generated site.")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
generate_site(args.output_dir)
|
# Read environment variables with defaults
|
||||||
|
TEMPLATE_FILE = os.getenv("TEMPLATE_FILE", "template.html")
|
||||||
|
TEMPLATE_DIR = os.getenv("TEMPLATE_DIR", ".")
|
||||||
|
template_path = f"{TEMPLATE_DIR}/{TEMPLATE_FILE}"
|
||||||
|
markdown_path = os.getenv("MARKDOWN_FILE", "laws.md")
|
||||||
|
output_dir = args.output_dir
|
||||||
|
print(f"📝 Loading template from: {template_path}")
|
||||||
|
print(f"📖 Loading markdown from: {markdown_path}")
|
||||||
|
print(f"💾 Outputting files to: {output_dir}")
|
||||||
|
|
||||||
|
# First, extract that markdown that we want to process.
|
||||||
|
markdown_content = prepare_markdown(markdown_path)
|
||||||
|
|
||||||
|
# Generate the site from the markdown.
|
||||||
|
generate_site(markdown_content, args.output_dir)
|
||||||
|
|||||||
2
.github/website/makefile
vendored
2
.github/website/makefile
vendored
@@ -29,7 +29,7 @@ serve: # 🚀 start local server
|
|||||||
.PHONY: watch
|
.PHONY: watch
|
||||||
watch: # 👀 Watch for changes...
|
watch: # 👀 Watch for changes...
|
||||||
@echo "👀 Watching for changes..."
|
@echo "👀 Watching for changes..."
|
||||||
watchmedo shell-command --patterns="$(MARKDOWN_FILE);*.py" --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
|
||||||
|
|||||||
23
.github/website/src/index.html.jinja
vendored
23
.github/website/src/index.html.jinja
vendored
@@ -44,25 +44,10 @@
|
|||||||
</header>
|
</header>
|
||||||
|
|
||||||
<main class="container">
|
<main class="container">
|
||||||
<section id="introduction" class="law-section">
|
<!-- The table of contents. -->
|
||||||
<h2>
|
{{ toc }}
|
||||||
Introduction
|
|
||||||
<a href="#introduction" class="anchor"><i class="bi bi-link-45deg"></i></a>
|
<!-- Each of the laws. -->
|
||||||
</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 %}
|
{% for law in laws %}
|
||||||
<section id="{{ law.id }}" class="law-section">
|
<section id="{{ law.id }}" class="law-section">
|
||||||
<h2>
|
<h2>
|
||||||
|
|||||||
4
.github/workflows/pages.yaml
vendored
4
.github/workflows/pages.yaml
vendored
@@ -31,6 +31,10 @@ jobs:
|
|||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
- name: Setup Pages
|
- name: Setup Pages
|
||||||
uses: actions/configure-pages@v5
|
uses: actions/configure-pages@v5
|
||||||
|
- name: Build Website
|
||||||
|
run: |
|
||||||
|
cd .github/website
|
||||||
|
make build
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-pages-artifact@v3
|
uses: actions/upload-pages-artifact@v3
|
||||||
with:
|
with:
|
||||||
|
|||||||
Reference in New Issue
Block a user