mirror of
https://github.com/thiloho/archtika.git
synced 2025-11-22 10:51:36 +01:00
Differentiate blog and docs and sectionize headings
This commit is contained in:
@@ -17,44 +17,50 @@
|
||||
</svelte:head>
|
||||
|
||||
<nav>
|
||||
{#if logoType === "text"}
|
||||
<p>
|
||||
<strong>{logo}</strong>
|
||||
</p>
|
||||
{:else}
|
||||
<img src={logo} alt="" />
|
||||
{/if}
|
||||
<div class="container">
|
||||
{#if logoType === "text"}
|
||||
<p>
|
||||
<strong>{logo}</strong>
|
||||
</p>
|
||||
{:else}
|
||||
<img src={logo} alt="" />
|
||||
{/if}
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<header>
|
||||
<h1>{title}</h1>
|
||||
<div class="container">
|
||||
<h1>{title}</h1>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<section>
|
||||
<div class="container">
|
||||
{@html mainContent}
|
||||
</section>
|
||||
{#if articles.length > 0}
|
||||
<section>
|
||||
<h2>Articles</h2>
|
||||
{#if articles.length > 0}
|
||||
<section>
|
||||
<h2>Articles</h2>
|
||||
|
||||
{#each articles as article}
|
||||
{@const articleFileName = article.title.toLowerCase().split(" ").join("-")}
|
||||
{#each articles as article}
|
||||
{@const articleFileName = article.title.toLowerCase().split(" ").join("-")}
|
||||
|
||||
<article>
|
||||
<p>{article.publication_date}</p>
|
||||
<h3>
|
||||
<a href="./articles/{articleFileName}.html">{article.title}</a>
|
||||
</h3>
|
||||
{#if article.meta_description}
|
||||
<p>{article.meta_description}</p>
|
||||
{/if}
|
||||
</article>
|
||||
{/each}
|
||||
</section>
|
||||
{/if}
|
||||
<article>
|
||||
<p>{article.publication_date}</p>
|
||||
<h3>
|
||||
<a href="./articles/{articleFileName}.html">{article.title}</a>
|
||||
</h3>
|
||||
{#if article.meta_description}
|
||||
<p>{article.meta_description}</p>
|
||||
{/if}
|
||||
</article>
|
||||
{/each}
|
||||
</section>
|
||||
{/if}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
{footerAdditionalText}
|
||||
<div class="container">
|
||||
{footerAdditionalText}
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
45
web-app/src/lib/templates/docs/DocsEntry.svelte
Normal file
45
web-app/src/lib/templates/docs/DocsEntry.svelte
Normal file
@@ -0,0 +1,45 @@
|
||||
<script lang="ts">
|
||||
const { title, logoType, logo, mainContent, coverImage, publicationDate, footerAdditionalText } =
|
||||
$props<{
|
||||
title: string;
|
||||
logoType: "text" | "image";
|
||||
logo: string;
|
||||
mainContent: string;
|
||||
coverImage: string;
|
||||
publicationDate: string;
|
||||
footerAdditionalText: string;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<head>
|
||||
<title>{title}</title>
|
||||
<link rel="stylesheet" href="../styles.css" />
|
||||
</head>
|
||||
</svelte:head>
|
||||
|
||||
<nav>
|
||||
{#if logoType === "text"}
|
||||
<p>
|
||||
<strong>{logo}</strong>
|
||||
</p>
|
||||
{:else}
|
||||
<img src={logo} alt="" />
|
||||
{/if}
|
||||
</nav>
|
||||
|
||||
<header>
|
||||
{#if coverImage}
|
||||
<img src={coverImage} alt="" />
|
||||
{/if}
|
||||
<h1>{title}</h1>
|
||||
<p>{publicationDate}</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
{@html mainContent}
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
{footerAdditionalText}
|
||||
</footer>
|
||||
60
web-app/src/lib/templates/docs/DocsIndex.svelte
Normal file
60
web-app/src/lib/templates/docs/DocsIndex.svelte
Normal file
@@ -0,0 +1,60 @@
|
||||
<script lang="ts">
|
||||
const { title, logoType, logo, mainContent, articles, footerAdditionalText } = $props<{
|
||||
title: string;
|
||||
logoType: "text" | "image";
|
||||
logo: string;
|
||||
mainContent: string;
|
||||
articles: any[];
|
||||
footerAdditionalText: string;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<head>
|
||||
<title>{title}</title>
|
||||
<link rel="stylesheet" href="./styles.css" />
|
||||
</head>
|
||||
</svelte:head>
|
||||
|
||||
<nav>
|
||||
{#if logoType === "text"}
|
||||
<p>
|
||||
<strong>{logo}</strong>
|
||||
</p>
|
||||
{:else}
|
||||
<img src={logo} alt="" />
|
||||
{/if}
|
||||
</nav>
|
||||
|
||||
<header>
|
||||
<h1>{title}</h1>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<section>
|
||||
{@html mainContent}
|
||||
</section>
|
||||
{#if articles.length > 0}
|
||||
<section>
|
||||
<h2>Articles</h2>
|
||||
|
||||
{#each articles as article}
|
||||
{@const articleFileName = article.title.toLowerCase().split(" ").join("-")}
|
||||
|
||||
<article>
|
||||
<p>{article.publication_date}</p>
|
||||
<h3>
|
||||
<a href="./documents/{articleFileName}.html">{article.title}</a>
|
||||
</h3>
|
||||
{#if article.meta_description}
|
||||
<p>{article.meta_description}</p>
|
||||
{/if}
|
||||
</article>
|
||||
{/each}
|
||||
</section>
|
||||
{/if}
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
{footerAdditionalText}
|
||||
</footer>
|
||||
@@ -1,5 +1,6 @@
|
||||
import markdownit from "markdown-it";
|
||||
import hljs from "highlight.js";
|
||||
import type { StateCore } from "markdown-it/index.js";
|
||||
import { dev } from "$app/environment";
|
||||
|
||||
export const sortOptions = [
|
||||
@@ -14,15 +15,86 @@ export const ALLOWED_MIME_TYPES = ["image/jpeg", "image/png", "image/svg+xml", "
|
||||
export const md = markdownit({
|
||||
linkify: true,
|
||||
typographer: true,
|
||||
highlight: (str, lang) => {
|
||||
highlight: (str: string, lang: string) => {
|
||||
if (lang && hljs.getLanguage(lang)) {
|
||||
try {
|
||||
return hljs.highlight(str, { language: lang }).value;
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
}).use((md) => {
|
||||
const addSections = (state: StateCore) => {
|
||||
const tokens = [];
|
||||
const Token = state.Token;
|
||||
const sections: { header: number; nesting: number }[] = [];
|
||||
let nestedLevel = 0;
|
||||
|
||||
const openSection = (attrs: [string, string][] | null) => {
|
||||
const t = new Token("section_open", "section", 1);
|
||||
t.block = true;
|
||||
t.attrs = attrs ? attrs.map((attr) => [attr[0], attr[1]]) : null;
|
||||
return t;
|
||||
};
|
||||
|
||||
const closeSection = () => {
|
||||
const t = new Token("section_close", "section", -1);
|
||||
t.block = true;
|
||||
return t;
|
||||
};
|
||||
|
||||
const closeSections = (section: { header: number; nesting: number }) => {
|
||||
while (sections.length && section.header <= sections[sections.length - 1].header) {
|
||||
sections.pop();
|
||||
tokens.push(closeSection());
|
||||
}
|
||||
};
|
||||
|
||||
const closeSectionsToCurrentNesting = (nesting: number) => {
|
||||
while (sections.length && nesting < sections[sections.length - 1].nesting) {
|
||||
sections.pop();
|
||||
tokens.push(closeSection());
|
||||
}
|
||||
};
|
||||
|
||||
const closeAllSections = () => {
|
||||
while (sections.pop()) {
|
||||
tokens.push(closeSection());
|
||||
}
|
||||
};
|
||||
|
||||
for (const token of state.tokens) {
|
||||
if (token.type.search("heading") !== 0) {
|
||||
nestedLevel += token.nesting;
|
||||
}
|
||||
if (sections.length && nestedLevel < sections[sections.length - 1].nesting) {
|
||||
closeSectionsToCurrentNesting(nestedLevel);
|
||||
}
|
||||
|
||||
if (token.type === "heading_open") {
|
||||
const section: { header: number; nesting: number } = {
|
||||
header: parseInt(token.tag.charAt(1)),
|
||||
nesting: nestedLevel
|
||||
};
|
||||
if (sections.length && section.header <= sections[sections.length - 1].header) {
|
||||
closeSections(section);
|
||||
}
|
||||
tokens.push(openSection(token.attrs));
|
||||
const idIndex = token.attrIndex("id");
|
||||
if (idIndex !== -1) {
|
||||
token.attrs?.splice(idIndex, 1);
|
||||
}
|
||||
sections.push(section);
|
||||
}
|
||||
|
||||
tokens.push(token);
|
||||
}
|
||||
closeAllSections();
|
||||
|
||||
state.tokens = tokens;
|
||||
};
|
||||
|
||||
md.core.ruler.push("header_sections", addSections);
|
||||
});
|
||||
|
||||
export const API_BASE_PREFIX = dev ? "http://localhost:3000" : "/api";
|
||||
|
||||
Reference in New Issue
Block a user