Skip to content

Commit 7257448

Browse files
refactor: optimize hints page module rendering
1 parent 74cd375 commit 7257448

2 files changed

Lines changed: 83 additions & 92 deletions

File tree

website/result.css

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -91,28 +91,6 @@ body {
9191
line-height: 1.2;
9292
}
9393

94-
.module-intro {
95-
margin: 1rem 0 1.5rem;
96-
}
97-
98-
.module-section-heading {
99-
margin: 0 0 0.5rem;
100-
font-size: 1.15rem;
101-
line-height: 1.2;
102-
color: #e7e7e7;
103-
}
104-
105-
.module-intro ul {
106-
margin: 0 0 1rem;
107-
padding-left: 1.5rem;
108-
}
109-
110-
#page-title {
111-
margin: 0.15rem 0 0;
112-
font-size: clamp(2rem, 4vw, 3.5rem);
113-
line-height: 1.1;
114-
}
115-
11694
a {
11795
text-decoration: none;
11896
color: inherit;

website/result.html

Lines changed: 83 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -38,78 +38,90 @@
3838
.replaceAll("/", "");
3939
}
4040

41-
function filterToModule(markdownContainer, moduleSlug) {
42-
if (!moduleSlug) {
43-
return null;
44-
}
45-
46-
const headings = [...markdownContainer.querySelectorAll("h3")];
47-
const targetHeading = headings.find(
48-
(heading) => normalizeModuleSlug(heading.textContent) === moduleSlug
41+
function parseModuleHeadingText(line) {
42+
const linkedHeadingMatch = line.match(
43+
/^###\s+\[([^\]]+)\]\([^)]*\)\s*$/u
4944
);
50-
51-
if (!targetHeading) {
52-
return null;
53-
}
54-
55-
const section = [targetHeading];
56-
let node = targetHeading.nextElementSibling;
57-
while (node && node.tagName !== "H3") {
58-
section.push(node);
59-
node = node.nextElementSibling;
45+
if (linkedHeadingMatch) {
46+
return linkedHeadingMatch[1];
6047
}
6148

62-
markdownContainer.replaceChildren(...section);
63-
return targetHeading.textContent;
49+
const plainHeadingMatch = line.match(/^###\s+(.+)$/u);
50+
return plainHeadingMatch ? plainHeadingMatch[1].trim() : "";
6451
}
6552

66-
function extractGeneralNotes(markdownContainer) {
67-
const heading = [...markdownContainer.querySelectorAll("h2")].find(
68-
(node) => node.textContent === "General notes"
53+
function extractGeneralNotesMarkdown(lines) {
54+
const startIndex = lines.findIndex(
55+
(line) => line.trim() === "## General notes"
6956
);
70-
71-
if (!heading) {
57+
if (startIndex === -1) {
7258
return [];
7359
}
7460

7561
const notes = [];
76-
let node = heading.nextElementSibling;
77-
while (node && node.tagName !== "H2") {
78-
notes.push(node.cloneNode(true));
79-
const nextNode = node.nextElementSibling;
80-
node.remove();
81-
node = nextNode;
62+
for (let i = startIndex + 1; i < lines.length; i++) {
63+
if (/^##\s+/u.test(lines[i])) {
64+
break;
65+
}
66+
notes.push(lines[i]);
8267
}
8368

84-
heading.remove();
8569
return notes;
8670
}
8771

88-
function injectModuleIntroSections(markdownContainer, notes) {
89-
if (notes.length === 0) {
90-
return;
91-
}
72+
function extractModuleSectionMarkdown(lines, moduleSlug) {
73+
let startIndex = -1;
9274

93-
const headings = [...markdownContainer.querySelectorAll("h3")];
94-
for (const heading of headings) {
95-
const introSection = document.createElement("section");
96-
introSection.className = "module-intro";
75+
for (let i = 0; i < lines.length; i++) {
76+
if (!lines[i].startsWith("### ")) {
77+
continue;
78+
}
9779

98-
const notesHeading = document.createElement("h4");
99-
notesHeading.className = "module-section-heading";
100-
notesHeading.textContent = "General notes";
80+
const headingText = parseModuleHeadingText(lines[i]);
81+
if (normalizeModuleSlug(headingText) === moduleSlug) {
82+
startIndex = i;
83+
break;
84+
}
85+
}
10186

102-
const findingsHeading = document.createElement("h4");
103-
findingsHeading.className = "module-section-heading";
104-
findingsHeading.textContent = "Findings";
87+
if (startIndex === -1) {
88+
return null;
89+
}
10590

106-
introSection.appendChild(notesHeading);
107-
for (const note of notes) {
108-
introSection.appendChild(note.cloneNode(true));
91+
let endIndex = lines.length;
92+
for (let i = startIndex + 1; i < lines.length; i++) {
93+
if (lines[i].startsWith("### ")) {
94+
endIndex = i;
95+
break;
10996
}
110-
introSection.appendChild(findingsHeading);
111-
heading.insertAdjacentElement("afterend", introSection);
11297
}
98+
99+
return {
100+
bodyLines: lines.slice(startIndex + 1, endIndex),
101+
title: parseModuleHeadingText(lines[startIndex])
102+
};
103+
}
104+
105+
function buildFilteredModuleMarkdown(markdownText, moduleSlug) {
106+
const lines = markdownText.split("\n");
107+
const moduleSection = extractModuleSectionMarkdown(lines, moduleSlug);
108+
if (!moduleSection) {
109+
return null;
110+
}
111+
112+
const generalNotes = extractGeneralNotesMarkdown(lines);
113+
const outputLines = [];
114+
115+
if (generalNotes.length > 0) {
116+
outputLines.push("## General notes", "", ...generalNotes, "");
117+
}
118+
119+
outputLines.push("## Findings", "", ...moduleSection.bodyLines);
120+
121+
return {
122+
markdown: outputLines.join("\n").trim(),
123+
title: moduleSection.title
124+
};
113125
}
114126

115127
function setPageTitle(title) {
@@ -136,23 +148,28 @@
136148
);
137149
}
138150
const markdownText = await response.text();
139-
markdownContainer.innerHTML = marked.parse(markdownText);
151+
140152
if (moduleSlug) {
141-
const generalNotes = extractGeneralNotes(markdownContainer);
142-
injectModuleIntroSections(markdownContainer, generalNotes);
143-
}
144-
const moduleTitle = filterToModule(markdownContainer, moduleSlug);
145-
if (moduleTitle) {
146-
setPageTitle(moduleTitle);
147-
fullResultsLink.href = "result.html";
148-
fullResultsLink.textContent = "Full hints list";
149-
} else if (moduleSlug) {
150-
markdownContainer.innerHTML =
151-
"<p>No hints found for this module.</p>";
152-
setPageTitle("Module hints");
153-
fullResultsLink.href = "result.html";
154-
fullResultsLink.textContent = "Full hints list";
153+
const filtered = buildFilteredModuleMarkdown(
154+
markdownText,
155+
moduleSlug
156+
);
157+
if (!filtered) {
158+
markdownContainer.innerHTML =
159+
"<p>No hints found for this module.</p>";
160+
setPageTitle("Module hints");
161+
fullResultsLink.href = "result.html";
162+
fullResultsLink.textContent = "Full hints list";
163+
} else {
164+
markdownContainer.innerHTML = marked.parse(filtered.markdown);
165+
setPageTitle(filtered.title);
166+
fullResultsLink.href = "result.html";
167+
fullResultsLink.textContent = "Full hints list";
168+
}
169+
} else {
170+
markdownContainer.innerHTML = marked.parse(markdownText);
155171
}
172+
156173
addHeadingAnchors();
157174
} catch (error) {
158175
console.error("Error loading markdown:", error);
@@ -165,10 +182,6 @@
165182
const markdownContainer = document.getElementById("markdown-container");
166183
const headings = markdownContainer.querySelectorAll("h1, h2, h3, h4");
167184
headings.forEach((heading) => {
168-
if (heading.classList.contains("module-section-heading")) {
169-
return;
170-
}
171-
172185
const anchorId = normalizeModuleSlug(heading.textContent);
173186
const anchor = document.createElement("a");
174187
anchor.id = anchorId;

0 commit comments

Comments
 (0)