mirror of
https://github.com/System-End/riceathon.git
synced 2026-04-19 22:05:16 +00:00
229 lines
8.2 KiB
HTML
229 lines
8.2 KiB
HTML
<!doctype html>
|
||
<html>
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<title>Riceathon Guide</title>
|
||
<link rel="stylesheet" href="https://css.hackclub.com/theme.css" />
|
||
<link rel="stylesheet" href="../style.css" />
|
||
<link rel="icon" href="/favicon.ico" />
|
||
<meta property="og:title" content="Riceathon Guide" />
|
||
<meta name="twitter:title" content="Riceathon Guide" />
|
||
<meta
|
||
name="description"
|
||
content="Learn how to rice your Linux desktop"
|
||
/>
|
||
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
||
<link
|
||
rel="stylesheet"
|
||
href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github-dark.min.css"
|
||
/>
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
||
</head>
|
||
|
||
<body>
|
||
<a class="banner" target="_blank" href="https://hackclub.com/">
|
||
<img src="../images/flag-orpheus-top.png" />
|
||
</a>
|
||
|
||
<header class="guide-header">
|
||
<a href="../" class="back-link">← Back to Home</a>
|
||
<h1 class="title">Ricing Guide</h1>
|
||
</header>
|
||
|
||
<div class="guide-layout">
|
||
<nav class="guide-nav">
|
||
<h3>Contents</h3>
|
||
<ul>
|
||
<li>
|
||
<a href="?part=1" class="nav-link" data-part="1"
|
||
>Part 1: Installing Linux</a
|
||
>
|
||
</li>
|
||
<li>
|
||
<a href="?part=2" class="nav-link" data-part="2"
|
||
>Part 2: Additional Packages</a
|
||
>
|
||
</li>
|
||
<li>
|
||
<a href="?part=3" class="nav-link" data-part="3"
|
||
>Part 3: Ricing Your Desktop</a
|
||
>
|
||
</li>
|
||
</ul>
|
||
<h3>Resources</h3>
|
||
<ul>
|
||
<li>
|
||
<a href="https://wiki.archlinux.org" target="_blank"
|
||
>Arch Wiki</a
|
||
>
|
||
</li>
|
||
<li>
|
||
<a
|
||
href="https://www.reddit.com/r/unixporn/"
|
||
target="_blank"
|
||
>r/unixporn</a
|
||
>
|
||
</li>
|
||
<li>
|
||
<a
|
||
href="https://github.com/fosslife/awesome-ricing"
|
||
target="_blank"
|
||
>awesome-ricing</a
|
||
>
|
||
</li>
|
||
</ul>
|
||
</nav>
|
||
|
||
<main class="guide-content">
|
||
<div id="markdown-content">
|
||
<p>Loading guide...</p>
|
||
</div>
|
||
|
||
<div class="guide-pagination">
|
||
<a
|
||
href="#"
|
||
id="prev-btn"
|
||
class="pagination-btn"
|
||
style="visibility: hidden"
|
||
>← Previous</a
|
||
>
|
||
<a href="#" id="next-btn" class="pagination-btn">Next →</a>
|
||
</div>
|
||
</main>
|
||
</div>
|
||
|
||
<script>
|
||
marked.setOptions({
|
||
breaks: true,
|
||
gfm: true,
|
||
});
|
||
|
||
const guides = {
|
||
1: {
|
||
file: "./part-1/en-US.md",
|
||
title: "Part 1: Installing Linux",
|
||
},
|
||
2: {
|
||
file: "./part-2/en-US.md",
|
||
title: "Part 2: Additional Packages",
|
||
},
|
||
3: {
|
||
file: "./part-3/en-US.md",
|
||
title: "Part 3: Ricing Your Desktop",
|
||
},
|
||
};
|
||
|
||
function getPartFromURL() {
|
||
const params = new URLSearchParams(window.location.search);
|
||
const part = parseInt(params.get("part")) || 1;
|
||
return Math.min(Math.max(part, 1), 3);
|
||
}
|
||
|
||
function updateNavigation(part) {
|
||
document.querySelectorAll(".nav-link").forEach((link) => {
|
||
link.classList.remove("active");
|
||
if (parseInt(link.dataset.part) === part) {
|
||
link.classList.add("active");
|
||
}
|
||
});
|
||
|
||
const prevBtn = document.getElementById("prev-btn");
|
||
const nextBtn = document.getElementById("next-btn");
|
||
|
||
if (part > 1) {
|
||
prevBtn.style.visibility = "visible";
|
||
prevBtn.href = `?part=${part - 1}`;
|
||
} else {
|
||
prevBtn.style.visibility = "hidden";
|
||
}
|
||
|
||
if (part < 3) {
|
||
nextBtn.style.visibility = "visible";
|
||
nextBtn.href = `?part=${part + 1}`;
|
||
} else {
|
||
nextBtn.style.visibility = "hidden";
|
||
}
|
||
}
|
||
|
||
function processMarkdown(md, basePath) {
|
||
md = md.replace(
|
||
/!\[([^\]]*)\]\(\.\/([^)]+)\)/g,
|
||
``,
|
||
);
|
||
|
||
md = md.replace(
|
||
/>\s*\[!(IMPORTANT|CAUTION|TIP|NOTE|WARNING)\]\s*\n((?:>.*\n?)*)/g,
|
||
(match, type, content) => {
|
||
const cleanContent = content
|
||
.replace(/^>\s*/gm, "")
|
||
.trim();
|
||
const icons = {
|
||
IMPORTANT: "ℹ️",
|
||
CAUTION: "⚠️",
|
||
TIP: "💡",
|
||
NOTE: "📝",
|
||
WARNING: "⚠️",
|
||
};
|
||
return `<div class="alert alert-${type.toLowerCase()}"><strong>${icons[type]} ${type}</strong><br>${marked.parse(cleanContent)}</div>\n`;
|
||
},
|
||
);
|
||
|
||
md = md.replace(
|
||
/\[([^\]]+)\]\(\.\.\/part-(\d)\/en-US\.md\)/g,
|
||
"[$1](?part=$2)",
|
||
);
|
||
|
||
return md;
|
||
}
|
||
|
||
async function loadGuide(part) {
|
||
const guide = guides[part];
|
||
if (!guide) return;
|
||
|
||
const contentEl = document.getElementById("markdown-content");
|
||
contentEl.innerHTML = "<p>Loading guide...</p>";
|
||
|
||
try {
|
||
const response = await fetch(guide.file);
|
||
if (!response.ok) throw new Error("Failed to load guide");
|
||
|
||
let markdown = await response.text();
|
||
const basePath = guide.file.replace("en-US.md", "");
|
||
markdown = processMarkdown(markdown, basePath);
|
||
|
||
contentEl.innerHTML = marked.parse(markdown);
|
||
|
||
document.querySelectorAll("pre code").forEach((block) => {
|
||
hljs.highlightElement(block);
|
||
});
|
||
|
||
window.scrollTo(0, 0);
|
||
updateNavigation(part);
|
||
} catch (error) {
|
||
contentEl.innerHTML = `<p class="error">Failed to load guide. Please try again.</p>`;
|
||
console.error(error);
|
||
}
|
||
}
|
||
|
||
document.addEventListener("click", (e) => {
|
||
const link = e.target.closest('a[href^="?part="]');
|
||
if (link) {
|
||
e.preventDefault();
|
||
const part = parseInt(
|
||
new URLSearchParams(link.getAttribute("href")).get(
|
||
"part",
|
||
),
|
||
);
|
||
history.pushState({}, "", `?part=${part}`);
|
||
loadGuide(part);
|
||
}
|
||
});
|
||
|
||
window.addEventListener("popstate", () => {
|
||
loadGuide(getPartFromURL());
|
||
});
|
||
|
||
loadGuide(getPartFromURL());
|
||
</script>
|
||
</body>
|
||
</html>
|