mirror of
https://github.com/AnimeThemes/animethemes-web.git
synced 2026-07-11 01:24:31 +02:00
fix: Fixed links in TOC of document pages (#110)
* Fixed "FAQ" and "Donate" links in footer. * Fixed bottom margin of code blocks. * Invalid language for syntax highlighting now yields a warning instead of crashing the page build.
This commit is contained in:
Generated
+7
-17
@@ -14,12 +14,12 @@
|
||||
"@fortawesome/react-fontawesome": "^0.1.14",
|
||||
"@graphql-tools/merge": "^8.2.1",
|
||||
"@graphql-tools/schema": "^8.2.0",
|
||||
"@graphql-tools/utils": "^8.6.5",
|
||||
"@next/bundle-analyzer": "^12.0.3",
|
||||
"@reach/listbox": "^0.16.2",
|
||||
"@reach/menu-button": "^0.16.2",
|
||||
"common-tags": "^1.8.0",
|
||||
"framer-motion": "^6.2.1",
|
||||
"github-slugger": "^1.4.0",
|
||||
"graphql": "^15.6.1",
|
||||
"graphql-tag": "^2.12.6",
|
||||
"knex": "^0.95.11",
|
||||
@@ -474,9 +474,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@graphql-tools/utils": {
|
||||
"version": "8.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.5.3.tgz",
|
||||
"integrity": "sha512-HDNGWFVa8QQkoQB0H1lftvaO1X5xUaUDk1zr1qDe0xN1NL0E/CrQdJ5UKLqOvH4hkqVUPxQsyOoAZFkaH6rLHg==",
|
||||
"version": "8.6.5",
|
||||
"resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.6.5.tgz",
|
||||
"integrity": "sha512-mjOtaWiS2WIqRz/cq5gaeM3sVrllcu2xbtHROw1su1v3xWa3D3dKgn8Lrl7+tvWs5WUVySsBss/VZ3WdoPkCrA==",
|
||||
"dependencies": {
|
||||
"tslib": "~2.3.0"
|
||||
},
|
||||
@@ -2332,11 +2332,6 @@
|
||||
"resolved": "https://registry.npmjs.org/getopts/-/getopts-2.2.5.tgz",
|
||||
"integrity": "sha512-9jb7AW5p3in+IiJWhQiZmmwkpLaR/ccTWdWQCtZM66HJcHHLegowh4q4tSD7gouUyeNvFWRavfK9GXosQHDpFA=="
|
||||
},
|
||||
"node_modules/github-slugger": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.4.0.tgz",
|
||||
"integrity": "sha512-w0dzqw/nt51xMVmlaV1+JRzN+oCa1KfcgGEWhxUG16wbdA+Xnt/yoFO8Z8x/V82ZcZ0wy6ln9QDup5avbhiDhQ=="
|
||||
},
|
||||
"node_modules/glob": {
|
||||
"version": "7.1.7",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
|
||||
@@ -5116,9 +5111,9 @@
|
||||
}
|
||||
},
|
||||
"@graphql-tools/utils": {
|
||||
"version": "8.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.5.3.tgz",
|
||||
"integrity": "sha512-HDNGWFVa8QQkoQB0H1lftvaO1X5xUaUDk1zr1qDe0xN1NL0E/CrQdJ5UKLqOvH4hkqVUPxQsyOoAZFkaH6rLHg==",
|
||||
"version": "8.6.5",
|
||||
"resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.6.5.tgz",
|
||||
"integrity": "sha512-mjOtaWiS2WIqRz/cq5gaeM3sVrllcu2xbtHROw1su1v3xWa3D3dKgn8Lrl7+tvWs5WUVySsBss/VZ3WdoPkCrA==",
|
||||
"requires": {
|
||||
"tslib": "~2.3.0"
|
||||
}
|
||||
@@ -6469,11 +6464,6 @@
|
||||
"resolved": "https://registry.npmjs.org/getopts/-/getopts-2.2.5.tgz",
|
||||
"integrity": "sha512-9jb7AW5p3in+IiJWhQiZmmwkpLaR/ccTWdWQCtZM66HJcHHLegowh4q4tSD7gouUyeNvFWRavfK9GXosQHDpFA=="
|
||||
},
|
||||
"github-slugger": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.4.0.tgz",
|
||||
"integrity": "sha512-w0dzqw/nt51xMVmlaV1+JRzN+oCa1KfcgGEWhxUG16wbdA+Xnt/yoFO8Z8x/V82ZcZ0wy6ln9QDup5avbhiDhQ=="
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.7",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
|
||||
|
||||
+1
-1
@@ -15,12 +15,12 @@
|
||||
"@fortawesome/react-fontawesome": "^0.1.14",
|
||||
"@graphql-tools/merge": "^8.2.1",
|
||||
"@graphql-tools/schema": "^8.2.0",
|
||||
"@graphql-tools/utils": "^8.6.5",
|
||||
"@next/bundle-analyzer": "^12.0.3",
|
||||
"@reach/listbox": "^0.16.2",
|
||||
"@reach/menu-button": "^0.16.2",
|
||||
"common-tags": "^1.8.0",
|
||||
"framer-motion": "^6.2.1",
|
||||
"github-slugger": "^1.4.0",
|
||||
"graphql": "^15.6.1",
|
||||
"graphql-tag": "^2.12.6",
|
||||
"knex": "^0.95.11",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import Link from "next/link";
|
||||
import { Column, Row, Solid } from "components/box";
|
||||
import { Container } from "components/container";
|
||||
import { Text } from "components/text";
|
||||
@@ -6,6 +7,7 @@ import { faDiscord, faGithub, faReddit, faTwitter } from "@fortawesome/free-bran
|
||||
import { Button } from "components/button";
|
||||
import styled from "styled-components";
|
||||
import theme from "theme";
|
||||
import { forwardRef } from "react";
|
||||
|
||||
const StyledFooter = styled(Solid)`
|
||||
margin-top: auto;
|
||||
@@ -46,12 +48,16 @@ export function Footer() {
|
||||
<FooterTextLink href="https://staging.animethemes.moe/transparency">
|
||||
Transparency
|
||||
</FooterTextLink>
|
||||
<FooterTextLink href="https://staging.animethemes.moe/donate">
|
||||
Donate
|
||||
</FooterTextLink>
|
||||
<FooterTextLink href="https://staging.animethemes.moe/faq">
|
||||
FAQ
|
||||
</FooterTextLink>
|
||||
<Link href="/page/donate" passHref>
|
||||
<FooterTextLink target="_self">
|
||||
Donate
|
||||
</FooterTextLink>
|
||||
</Link>
|
||||
<Link href="/page/faq" passHref>
|
||||
<FooterTextLink target="_self">
|
||||
FAQ
|
||||
</FooterTextLink>
|
||||
</Link>
|
||||
</StyledLinkList>
|
||||
<StyledLinkList>
|
||||
<FooterTextLink href="https://staging.animethemes.moe/terms-of-service">
|
||||
@@ -91,18 +97,18 @@ export function Footer() {
|
||||
);
|
||||
}
|
||||
|
||||
function FooterLink({ children, ...props }) {
|
||||
const FooterLink = forwardRef(function FooterLink({ children, ...props }, ref) {
|
||||
return (
|
||||
<Text as="a" target="_blank" rel="noopener" {...props}>
|
||||
<Text ref={ref} as="a" target="_blank" rel="noopener" {...props}>
|
||||
{children}
|
||||
</Text>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
function FooterTextLink({ children, ...props }) {
|
||||
const FooterTextLink = forwardRef(function FooterTextLink({ children, ...props }, ref) {
|
||||
return (
|
||||
<FooterLink link block color="text-muted" noWrap {...props}>
|
||||
<FooterLink ref={ref} link block color="text-muted" noWrap {...props}>
|
||||
{children}
|
||||
</FooterLink>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -7,7 +7,6 @@ import { Text } from "components/text";
|
||||
import { createElement, Fragment, useEffect, useState } from "react";
|
||||
import rehypeParse from "rehype-parse";
|
||||
import styled from "styled-components";
|
||||
import { slug } from "github-slugger";
|
||||
import { motion } from "framer-motion";
|
||||
import theme from "theme";
|
||||
import { SEO } from "components/seo";
|
||||
@@ -99,6 +98,7 @@ const StyledMarkdown = styled.div`
|
||||
}
|
||||
|
||||
& pre {
|
||||
margin-bottom: 16px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ export default function DocumentPage({ page }) {
|
||||
}
|
||||
|
||||
function TableOfContents({ headings }) {
|
||||
const [currentHeading, setCurrentHeading] = useState();
|
||||
const [currentSlug, setCurrentSlug] = useState();
|
||||
|
||||
useEffect(() => {
|
||||
function onScroll() {
|
||||
@@ -193,7 +193,7 @@ function TableOfContents({ headings }) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
setCurrentHeading(currentHeading?.id);
|
||||
setCurrentSlug(currentHeading?.id);
|
||||
}
|
||||
|
||||
window.addEventListener("scroll", onScroll);
|
||||
@@ -203,12 +203,12 @@ function TableOfContents({ headings }) {
|
||||
|
||||
return (
|
||||
<StyledTableOfContents>
|
||||
{headings.map(({ text }) => (
|
||||
{headings.map(({ text, slug }) => (
|
||||
<li key={text}>
|
||||
{slug(text) === currentHeading && (
|
||||
{slug === currentSlug && (
|
||||
<StyledDot layoutId="dot"/>
|
||||
)}
|
||||
<Text as="a" link color={slug(text) === currentHeading ? "text-muted" : "text-disabled"} href={`#${slug(text)}`}>{text}</Text>
|
||||
<Text as="a" link color={slug === currentSlug ? "text-muted" : "text-disabled"} href={`#${slug}`}>{text}</Text>
|
||||
</li>
|
||||
))}
|
||||
</StyledTableOfContents>
|
||||
|
||||
@@ -6,16 +6,32 @@ import "prismjs/components/prism-json";
|
||||
export default function markdownToHtml(markdown) {
|
||||
const headings = [];
|
||||
|
||||
const html = marked.parse(markdown, {
|
||||
const slugger = new marked.Slugger();
|
||||
|
||||
const html = marked(markdown, {
|
||||
highlight(code, lang) {
|
||||
if (lang) {
|
||||
return Prism.highlight(code, Prism.languages[lang], lang);
|
||||
if (lang in Prism.languages) {
|
||||
return Prism.highlight(code, Prism.languages[lang], lang);
|
||||
}
|
||||
return `[!] Unknown syntax highlighting language: ${lang}\n${code}`;
|
||||
}
|
||||
return code;
|
||||
},
|
||||
walkTokens(token) {
|
||||
if (token.type === "heading" && token.depth === 2) {
|
||||
headings.push({ text: token.text, level: token.depth });
|
||||
if (token.type === "heading") {
|
||||
// To remove links and other markdown entities from the text we join only the text parts together.
|
||||
const text = joinTextDeep(token.tokens);
|
||||
// Slugger keeps track of seen slugs, so we have to generate a slug for every heading.
|
||||
// This way links will work in the table of contents later.
|
||||
const slug = slugger.slug(text);
|
||||
if (token.depth === 2) {
|
||||
headings.push({
|
||||
text: text,
|
||||
level: token.depth,
|
||||
slug
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -25,3 +41,7 @@ export default function markdownToHtml(markdown) {
|
||||
headings
|
||||
};
|
||||
}
|
||||
|
||||
function joinTextDeep(tokens) {
|
||||
return tokens.map((token) => token.tokens ? joinTextDeep(token.tokens) : token.text).join("");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user