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:
Manuel S
2022-04-01 22:46:39 +02:00
committed by GitHub
parent eee86f80cd
commit d86d0a04b5
5 changed files with 56 additions and 40 deletions
+7 -17
View File
@@ -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
View File
@@ -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",
+18 -12
View File
@@ -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>
);
}
});
+6 -6
View File
@@ -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>
+24 -4
View File
@@ -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("");
}