Compare commits
No commits in common. "27201e2be8fb7c58ce159a12f25e4b3a3deffcd7" and "29b1fa4afbdfb3ee6df294b8160af78c344b70c3" have entirely different histories.
27201e2be8
...
29b1fa4afb
7 changed files with 35 additions and 129 deletions
|
@ -3,7 +3,7 @@ import { defineConfig } from 'astro/config';
|
||||||
import sitemap from '@astrojs/sitemap';
|
import sitemap from '@astrojs/sitemap';
|
||||||
|
|
||||||
import mdx from '@astrojs/mdx';
|
import mdx from '@astrojs/mdx';
|
||||||
|
import remarkToc from 'remark-toc';
|
||||||
|
|
||||||
import cloudflare from '@astrojs/cloudflare';
|
import cloudflare from '@astrojs/cloudflare';
|
||||||
|
|
||||||
|
@ -21,6 +21,9 @@ export default defineConfig({
|
||||||
theme: 'nord',
|
theme: 'nord',
|
||||||
wrap: true
|
wrap: true
|
||||||
},
|
},
|
||||||
|
remarkPlugins: [
|
||||||
|
[remarkToc, { heading: 'Contents', maxDepth: 3 }]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
integrations: [sitemap(), mdx()],
|
integrations: [sitemap(), mdx()],
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
"@fontsource-variable/jetbrains-mono": "^5.2.5",
|
"@fontsource-variable/jetbrains-mono": "^5.2.5",
|
||||||
"astro": "^5.2.5",
|
"astro": "^5.2.5",
|
||||||
"ico-endec": "^0.1.6",
|
"ico-endec": "^0.1.6",
|
||||||
|
"remark-toc": "^9.0.0",
|
||||||
"sharp": "^0.34.1",
|
"sharp": "^0.34.1",
|
||||||
"ultrahtml": "^1.6.0"
|
"ultrahtml": "^1.6.0"
|
||||||
},
|
},
|
||||||
|
|
29
pnpm-lock.yaml
generated
29
pnpm-lock.yaml
generated
|
@ -32,6 +32,9 @@ importers:
|
||||||
ico-endec:
|
ico-endec:
|
||||||
specifier: ^0.1.6
|
specifier: ^0.1.6
|
||||||
version: 0.1.6
|
version: 0.1.6
|
||||||
|
remark-toc:
|
||||||
|
specifier: ^9.0.0
|
||||||
|
version: 9.0.0
|
||||||
sharp:
|
sharp:
|
||||||
specifier: ^0.34.1
|
specifier: ^0.34.1
|
||||||
version: 0.34.1
|
version: 0.34.1
|
||||||
|
@ -1022,6 +1025,9 @@ packages:
|
||||||
'@types/tmp@0.0.33':
|
'@types/tmp@0.0.33':
|
||||||
resolution: {integrity: sha512-gVC1InwyVrO326wbBZw+AO3u2vRXz/iRWq9jYhpG4W8LXyIgDv3ZmcLQ5Q4Gs+gFMyqx+viFoFT+l3p61QFCmQ==}
|
resolution: {integrity: sha512-gVC1InwyVrO326wbBZw+AO3u2vRXz/iRWq9jYhpG4W8LXyIgDv3ZmcLQ5Q4Gs+gFMyqx+viFoFT+l3p61QFCmQ==}
|
||||||
|
|
||||||
|
'@types/ungap__structured-clone@1.2.0':
|
||||||
|
resolution: {integrity: sha512-ZoaihZNLeZSxESbk9PUAPZOlSpcKx81I1+4emtULDVmBLkYutTcMlCj2K9VNlf9EWODxdO6gkAqEaLorXwZQVA==}
|
||||||
|
|
||||||
'@types/unist@2.0.11':
|
'@types/unist@2.0.11':
|
||||||
resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==}
|
resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==}
|
||||||
|
|
||||||
|
@ -2124,6 +2130,9 @@ packages:
|
||||||
mdast-util-to-string@4.0.0:
|
mdast-util-to-string@4.0.0:
|
||||||
resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==}
|
resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==}
|
||||||
|
|
||||||
|
mdast-util-toc@7.1.0:
|
||||||
|
resolution: {integrity: sha512-2TVKotOQzqdY7THOdn2gGzS9d1Sdd66bvxUyw3aNpWfcPXCLYSJCCgfPy30sEtuzkDraJgqF35dzgmz6xlvH/w==}
|
||||||
|
|
||||||
mdn-data@2.12.2:
|
mdn-data@2.12.2:
|
||||||
resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==}
|
resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==}
|
||||||
|
|
||||||
|
@ -2622,6 +2631,9 @@ packages:
|
||||||
remark-stringify@11.0.0:
|
remark-stringify@11.0.0:
|
||||||
resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==}
|
resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==}
|
||||||
|
|
||||||
|
remark-toc@9.0.0:
|
||||||
|
resolution: {integrity: sha512-KJ9txbo33GjDAV1baHFze7ij4G8c7SGYoY8Kzsm2gzFpbhL/bSoVpMMzGa3vrNDSWASNd/3ppAqL7cP2zD6JIA==}
|
||||||
|
|
||||||
require-directory@2.1.1:
|
require-directory@2.1.1:
|
||||||
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
|
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
@ -4208,6 +4220,8 @@ snapshots:
|
||||||
|
|
||||||
'@types/tmp@0.0.33': {}
|
'@types/tmp@0.0.33': {}
|
||||||
|
|
||||||
|
'@types/ungap__structured-clone@1.2.0': {}
|
||||||
|
|
||||||
'@types/unist@2.0.11': {}
|
'@types/unist@2.0.11': {}
|
||||||
|
|
||||||
'@types/unist@3.0.3': {}
|
'@types/unist@3.0.3': {}
|
||||||
|
@ -5606,6 +5620,16 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/mdast': 4.0.4
|
'@types/mdast': 4.0.4
|
||||||
|
|
||||||
|
mdast-util-toc@7.1.0:
|
||||||
|
dependencies:
|
||||||
|
'@types/mdast': 4.0.4
|
||||||
|
'@types/ungap__structured-clone': 1.2.0
|
||||||
|
'@ungap/structured-clone': 1.3.0
|
||||||
|
github-slugger: 2.0.0
|
||||||
|
mdast-util-to-string: 4.0.0
|
||||||
|
unist-util-is: 6.0.0
|
||||||
|
unist-util-visit: 5.0.0
|
||||||
|
|
||||||
mdn-data@2.12.2: {}
|
mdn-data@2.12.2: {}
|
||||||
|
|
||||||
merge-stream@2.0.0: {}
|
merge-stream@2.0.0: {}
|
||||||
|
@ -6327,6 +6351,11 @@ snapshots:
|
||||||
mdast-util-to-markdown: 2.1.2
|
mdast-util-to-markdown: 2.1.2
|
||||||
unified: 11.0.5
|
unified: 11.0.5
|
||||||
|
|
||||||
|
remark-toc@9.0.0:
|
||||||
|
dependencies:
|
||||||
|
'@types/mdast': 4.0.4
|
||||||
|
mdast-util-toc: 7.1.0
|
||||||
|
|
||||||
require-directory@2.1.1: {}
|
require-directory@2.1.1: {}
|
||||||
|
|
||||||
requires-port@1.0.0: {}
|
requires-port@1.0.0: {}
|
||||||
|
|
|
@ -1,92 +0,0 @@
|
||||||
---
|
|
||||||
import type { MarkdownHeading } from 'astro';
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
headings: MarkdownHeading[];
|
|
||||||
}
|
|
||||||
|
|
||||||
const { headings } = Astro.props;
|
|
||||||
|
|
||||||
|
|
||||||
const filteredHeadings = headings.filter((heading) => heading.depth <= 3);
|
|
||||||
|
|
||||||
// github.com/rezahedi/rezahedi.dev/blob/main/src/components/TOC.astro
|
|
||||||
function buildHierarchy(headings: MarkdownHeading[]) {
|
|
||||||
const toc: any[] = [];
|
|
||||||
const parentHeadings = new Map();
|
|
||||||
|
|
||||||
if (!headings)
|
|
||||||
return toc;
|
|
||||||
|
|
||||||
headings.forEach((h: any) => {
|
|
||||||
const heading = { ...h, subheadings: [] };
|
|
||||||
parentHeadings.set(heading.depth, heading);
|
|
||||||
// Change 2 to 1 if your markdown includes your <h1>
|
|
||||||
if (heading.depth === 2) {
|
|
||||||
toc.push(heading);
|
|
||||||
} else {
|
|
||||||
parentHeadings.get(heading.depth - 1)?.subheadings.push(heading);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return toc;
|
|
||||||
}
|
|
||||||
|
|
||||||
const toc = buildHierarchy(filteredHeadings);
|
|
||||||
---
|
|
||||||
<details>
|
|
||||||
<summary>Table of Contents</summary>
|
|
||||||
<ul class="toc-list">
|
|
||||||
{
|
|
||||||
toc.map((heading) => (
|
|
||||||
<li class={`depth-${heading.depth}`} style={`margin-left: ${(heading.depth - 1)}rem;`}>
|
|
||||||
<a href={`#${heading.slug}`}>{heading.text}</a>
|
|
||||||
{
|
|
||||||
heading.subheadings.length > 0 && (
|
|
||||||
<ul>
|
|
||||||
{
|
|
||||||
heading.subheadings.map((subheading) => (
|
|
||||||
<li class={`depth-${subheading.depth}`} style={`margin-left: ${(subheading.depth - 1)}rem;`}>
|
|
||||||
<a href={`#${subheading.slug}`}>{subheading.text}</a>
|
|
||||||
{subheading.subheadings.length > 0 && (
|
|
||||||
<ul>
|
|
||||||
{
|
|
||||||
subheading.subheadings.map((subSubheading) => (
|
|
||||||
<li class={`depth-${subSubheading.depth}`} style={`margin-left: ${(subSubheading.depth - 1)}rem;`}>
|
|
||||||
<a href={`#${subSubheading.slug}`}>{subSubheading.text}</a>
|
|
||||||
</li>
|
|
||||||
))
|
|
||||||
}
|
|
||||||
</ul>
|
|
||||||
)}
|
|
||||||
</li>
|
|
||||||
))
|
|
||||||
}
|
|
||||||
</ul>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
</li>
|
|
||||||
))
|
|
||||||
}
|
|
||||||
</ul>
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
details {
|
|
||||||
margin: 0.5rem auto;
|
|
||||||
}
|
|
||||||
.toc-list {
|
|
||||||
list-style-type: none;
|
|
||||||
padding-left: 0;
|
|
||||||
}
|
|
||||||
.depth-1 {
|
|
||||||
font-weight: bold;
|
|
||||||
margin-top: 0.5rem;
|
|
||||||
}
|
|
||||||
.depth-2 {
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
.depth-3 {
|
|
||||||
font-size: 0.95em;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -40,10 +40,4 @@ const { icon, type = 'info'} = Astro.props;
|
||||||
--callout-bg: var(--terminal-red);
|
--callout-bg: var(--terminal-red);
|
||||||
--callout-text: #111;
|
--callout-text: #111;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: light) {
|
|
||||||
:root:not([data-theme="dark"]) .callout-info {
|
|
||||||
--callout-text: #eee;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
|
@ -1,6 +1,5 @@
|
||||||
---
|
---
|
||||||
import Layout from '../../layouts/Layout.astro';
|
import Layout from '../../layouts/Layout.astro';
|
||||||
|
|
||||||
import { getCollection, getEntry } from 'astro:content';
|
import { getCollection, getEntry } from 'astro:content';
|
||||||
import Comments from "../../components/Comments.astro";
|
import Comments from "../../components/Comments.astro";
|
||||||
import {getImage} from "astro:assets";
|
import {getImage} from "astro:assets";
|
||||||
|
@ -8,7 +7,6 @@ import {siteConfig} from "../../config";
|
||||||
import ReplyViaEmail from "../../components/ReplyViaEmail.astro";
|
import ReplyViaEmail from "../../components/ReplyViaEmail.astro";
|
||||||
import { ExtractFirstImage } from '../../plugins/extract-images';
|
import { ExtractFirstImage } from '../../plugins/extract-images';
|
||||||
import AuthorInfo from "../../components/helper/authors/Info.astro";
|
import AuthorInfo from "../../components/helper/authors/Info.astro";
|
||||||
import TableOfContents from "../../components/TableOfContents.astro";
|
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
const blogEntries = await getCollection('posts');
|
const blogEntries = await getCollection('posts');
|
||||||
|
@ -19,8 +17,6 @@ export async function getStaticPaths() {
|
||||||
|
|
||||||
const { entry } = Astro.props;
|
const { entry } = Astro.props;
|
||||||
const { Content } = await entry.render();
|
const { Content } = await entry.render();
|
||||||
const headings = await entry.render().then(rendered => rendered.headings);
|
|
||||||
|
|
||||||
const noscript = siteConfig.noClientJavaScript
|
const noscript = siteConfig.noClientJavaScript
|
||||||
const slug = Astro.params.slug;
|
const slug = Astro.params.slug;
|
||||||
const author = entry.data.author || {collection: 'authors', id: siteConfig.defaultAuthor.id};
|
const author = entry.data.author || {collection: 'authors', id: siteConfig.defaultAuthor.id};
|
||||||
|
@ -52,7 +48,6 @@ const cover = customFeaturedImage || matchedImage_src?.src || firstImageURL || `
|
||||||
<h1 class="title">{entry.data.title}</h1>
|
<h1 class="title">{entry.data.title}</h1>
|
||||||
<AuthorInfo data={authorData} />
|
<AuthorInfo data={authorData} />
|
||||||
<span class="date">{new Date(entry.data.pubDate).toISOString().split('T')[0]}</span>
|
<span class="date">{new Date(entry.data.pubDate).toISOString().split('T')[0]}</span>
|
||||||
{headings.length !== 0 && <TableOfContents headings={headings} />}
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<Content />
|
<Content />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -192,7 +192,7 @@ h1.title {
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
div.content {
|
div.content {
|
||||||
margin: 1rem auto;
|
margin-bottom: 2rem;
|
||||||
span.date {
|
span.date {
|
||||||
color: var(--secondary-text-color);
|
color: var(--secondary-text-color);
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
|
@ -230,35 +230,11 @@ div.content {
|
||||||
background-color: #3b4252 !important;
|
background-color: #3b4252 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
table {
|
|
||||||
border-collapse: collapse;
|
|
||||||
}
|
|
||||||
|
|
||||||
table,
|
|
||||||
th,
|
|
||||||
td {
|
|
||||||
border: 1px dashed var(--secondary-text-color);
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1, h2, h3, h4 {
|
h1, h2, h3, h4 {
|
||||||
margin: 0.5rem 0;
|
margin: 0.5rem 0;
|
||||||
line-height: 1.3;
|
line-height: 1.3;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
|
||||||
text-decoration: underline 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
blockquote {
|
|
||||||
border-left: 1px solid var(--accent-color);
|
|
||||||
color: var(--text-color);
|
|
||||||
padding: 20px;
|
|
||||||
font-style: italic;
|
|
||||||
margin-left: 0;
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Responsive Images */
|
/* Responsive Images */
|
||||||
img {
|
img {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue