export type TaskAssignmentData = { id: string, name: string, points: number, description: HTMLElement } type TaskLocation = { /** Relative location of HTML file containing this task */ url: string /** id of the element where the specific task begins */ startElement: string } function getLocation(id: string, solution: boolean): TaskLocation { const m = /^(\d+)-(Z?)(\d)-(\d)$/.exec(id) if (!m) throw new Error(`Invalid task id: ${m}`) const [_, rocnik, z, serie, uloha] = m[1] if (z == 'Z') { const urlX = solution ? "reseni" : "zadani" return { url: `z/ulohy/${rocnik}/${urlX}${serie}.html`, startElement: `task${uloha}` } } else { const urlX = solution ? "solution" : "tasks" return { url: `tasks/${rocnik}/${urlX}${serie}.html`, startElement: `task${uloha}` } } } function parseTask(startElementId: string, html: string, contentType: string): string { const parser = new DOMParser() const doc = parser.parseFromString(html, contentType as any) const titleElement = doc.getElementById(startElementId) if (!titleElement) throw new Error(`Document does not contain ${startElementId}`) const elements = [] let e = titleElement while (e.nextElementSibling && e.nextElementSibling?.tagName.toLowerCase() == "hr") e = e.nextElementSibling as HTMLElement while (!e.classList.contains("story") && // !e.classList.contains("clearfloat") && e.tagName.toLowerCase() != "h3" && e.innerText.trim() != "Řešení" ) { elements.push(e) if (!e.nextElementSibling) break; e = e.nextElementSibling as HTMLElement } let r = "" for (const e of elements) r += e.outerHTML + "\n" return r } async function loadTask({ url, startElement }: TaskLocation) { const r = await fetch(url, { headers: { "Accept": "text/html,application/xhtml+xml" } }) if (r.status >= 400) { throw Error("Bad request") } const rText = await r.text() const contentType = r.headers.get("Content-Type") || "text/html" return parseTask(startElement, rText, contentType) } export function loadAssignment(id: string) { return loadTask(getLocation(id, false)) } export function loadSolution(id: string) { return loadTask(getLocation(id, true)) }