feat: add tag navigation
This commit is contained in:
parent
3a40c63d5e
commit
ff1fc96a5c
@ -2,6 +2,7 @@
|
||||
import dayjs from "dayjs";
|
||||
import utc from "dayjs/plugin/utc.js";
|
||||
import type { BlogParsedContent } from "@/shared/types";
|
||||
import { calcReadingTime } from "@/shared/readingTime";
|
||||
|
||||
dayjs.extend(utc);
|
||||
|
||||
@ -26,33 +27,28 @@ const prettyDate = latestDate.format("DD MMM YYYY");
|
||||
>
|
||||
<h2 class="m-0 mt-4 mb-1">{{ latest.title }}</h2>
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400 m-0">
|
||||
{{ prettyDate }} · {{ latest.readingTime.text }}
|
||||
{{ prettyDate }} · {{ calcReadingTime(latest).minutes }} min read
|
||||
</p>
|
||||
<div class="tag-list mt-1">
|
||||
<Tag
|
||||
v-for="(tag, index) in latest.tags"
|
||||
:key="index"
|
||||
:dest="`/blog/tags/${tag}`"
|
||||
:dest="`/tags/blog/${tag}`"
|
||||
>
|
||||
{{ tag }}
|
||||
</Tag>
|
||||
</div>
|
||||
<!--
|
||||
<ContentRenderer
|
||||
tag="article"
|
||||
:value="latest"
|
||||
:excerpt="true"
|
||||
class="pt-0 w-full"
|
||||
class="text-gray-600 dark:text-gray-300 text-base m-0 mt-5"
|
||||
>
|
||||
<ContentRendererMarkdown :value="latest" :excerpt="true" />
|
||||
<template #empty>
|
||||
<p>No description found.</p>
|
||||
</template>
|
||||
</ContentRenderer>
|
||||
-->
|
||||
<p class="excerpt text-gray-600 dark:text-gray-300 text-base m-0 mt-5">
|
||||
{{ latest.description }} …
|
||||
</p>
|
||||
</HomeStatBox>
|
||||
</div>
|
||||
</template>
|
||||
|
69
components/PostPreviewCard.vue
Normal file
69
components/PostPreviewCard.vue
Normal file
@ -0,0 +1,69 @@
|
||||
<script setup lang="ts">
|
||||
import type { StoryParsedContent, BlogParsedContent } from "@/shared/types";
|
||||
import { calcReadingTime } from "@/shared/readingTime";
|
||||
import dayjs from "dayjs";
|
||||
import utc from "dayjs/plugin/utc.js";
|
||||
|
||||
dayjs.extend(utc);
|
||||
|
||||
const { post, type, highlighttags } = defineProps<{
|
||||
post: StoryParsedContent | BlogParsedContent;
|
||||
type: "stories" | "blog";
|
||||
highlighttags?: string[];
|
||||
}>();
|
||||
|
||||
const getPrettyDate = (story: StoryParsedContent) => {
|
||||
const date = dayjs(story.date).utc();
|
||||
return date.format("DD MMM YYYY");
|
||||
};
|
||||
|
||||
const readingTime = calcReadingTime(post);
|
||||
const descText =
|
||||
type === "stories"
|
||||
? `${readingTime.words.total} words`
|
||||
: `${readingTime.minutes} min read`;
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="story-card p-4">
|
||||
<h3 class="m-0">
|
||||
<a
|
||||
:href="post._path"
|
||||
class="no-underline text-left text-2xl sm:text-2xl font-bold hover:text-blue-700 dark:hover:text-blue-400 leading-tight transition"
|
||||
>
|
||||
{{ post.title }}
|
||||
</a>
|
||||
</h3>
|
||||
<p class="my-1 text-sm">{{ getPrettyDate(post) }} · {{ descText }}</p>
|
||||
<div class="flex flex-wrap">
|
||||
<Tag
|
||||
:dest="`/tags/${type}/${tag}`"
|
||||
v-for="(tag, index) in post.tags"
|
||||
:key="index"
|
||||
:highlight="highlighttags?.includes(tag)"
|
||||
>
|
||||
{{ tag }}
|
||||
</Tag>
|
||||
</div>
|
||||
<ContentRenderer :value="post" :excerpt="true" tag="article">
|
||||
<template #empty>No excerpt available.</template>
|
||||
</ContentRenderer>
|
||||
<div class="text-right">
|
||||
<a
|
||||
:href="post._path"
|
||||
class="no-underline hover:underline font-semibold text-blue-700 dark:text-blue-400"
|
||||
>
|
||||
Continue reading →
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.story-card {
|
||||
border: 0.1rem solid gray;
|
||||
max-width: 100%;
|
||||
border-radius: 0.5rem;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
</style>
|
@ -2,6 +2,7 @@
|
||||
import dayjs from "dayjs";
|
||||
import utc from "dayjs/plugin/utc.js";
|
||||
import { type StoryParsedContent } from "@/shared/types";
|
||||
import { calcReadingTime } from "@/shared/readingTime";
|
||||
|
||||
dayjs.extend(utc);
|
||||
|
||||
@ -26,35 +27,28 @@ const prettyDate = latestDate.format("DD MMM YYYY");
|
||||
>
|
||||
<h2 class="m-0 mt-4 mb-1">{{ latest.title }}</h2>
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400 m-0">
|
||||
{{ prettyDate }} · {{ latest.readingTime.words }} words
|
||||
{{ prettyDate }} · {{ calcReadingTime(latest).words.total }} words
|
||||
</p>
|
||||
<div class="tag-list mt-1">
|
||||
<Tag
|
||||
v-for="(tag, index) in latest.tags"
|
||||
:key="index"
|
||||
:dest="`/stories/tags/${tag}`"
|
||||
:dest="`/tags/stories/${tag}`"
|
||||
>
|
||||
{{ tag }}
|
||||
</Tag>
|
||||
</div>
|
||||
<!--
|
||||
<ContentRenderer
|
||||
tag="article"
|
||||
:value="latest"
|
||||
:excerpt="true"
|
||||
class="pt-0 w-full"
|
||||
class="text-gray-600 dark:text-gray-300 text-base m-0 mt-5 text-ellipsis"
|
||||
>
|
||||
<ContentRendererMarkdown :value="latest" :excerpt="true" />
|
||||
<template #empty>
|
||||
<p>No description found.</p>
|
||||
</template>
|
||||
</ContentRenderer>
|
||||
-->
|
||||
<p
|
||||
class="excerpt text-gray-600 dark:text-gray-300 text-base m-0 mt-5 text-ellipsis"
|
||||
>
|
||||
{{ latest.description }} ...
|
||||
</p>
|
||||
</HomeStatBox>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -1,11 +1,17 @@
|
||||
<script setup lang="ts">
|
||||
const { dest } = defineProps<{ dest: string }>();
|
||||
const { dest, highlight = false } = defineProps<{
|
||||
dest: string;
|
||||
highlight?: boolean;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a :href="dest">
|
||||
<div
|
||||
class="inline-block text-xs rounded-full py-1 px-2 mt-1 mr-1 bg-gray-300 dark:bg-gray-500 transition"
|
||||
:class="[
|
||||
'inline-block text-xs rounded-full py-1 px-2 mt-1 mr-1 bg-gray-300 dark:bg-gray-500 transition',
|
||||
{ 'bg-yellow-200 dark:bg-yellow-700 shadow-lg': highlight },
|
||||
]"
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
|
@ -10,6 +10,8 @@ SPOILERS if you haven't completed it.
|
||||
|
||||
Assume all part 1 commands here are run in the home directory. Assume all part 2 commands are run in the `part2` directory.
|
||||
|
||||
<!-- more -->
|
||||
|
||||
## Clue 1
|
||||
|
||||
#### Solution
|
||||
|
@ -9,12 +9,12 @@ tags:
|
||||
|
||||
Hello?
|
||||
|
||||
<!-- excerpt -->
|
||||
|
||||
Oh, Blue! I almost didn't recognise your voice; it's been forever since we chatted! How've you been doing?
|
||||
|
||||
Yeah, I know you have work and all, but…it's been, what, a year since we last played League together and it'd be great to get together again — remember that time when you were killed by a minion at bottom —
|
||||
|
||||
<!-- more -->
|
||||
|
||||
You don't play anymore? That's…a shame. Right, work and everything. So, uh, what'd you want to talk about?
|
||||
|
||||
A favour? Sure! What is it?
|
||||
|
@ -9,13 +9,13 @@ Renge Academy\
|
||||
No address\
|
||||
Biyori, Asvyn
|
||||
|
||||
<!-- more -->
|
||||
|
||||
Hina Asvyn\
|
||||
Empress\
|
||||
1 Kansei Road\
|
||||
Emina, Asvyn
|
||||
|
||||
<!-- more -->
|
||||
|
||||
Empress,
|
||||
|
||||
With all due respect, as one of Your Majesty's principal advisors, the mass annexation of Enigmatic territories is not only in grave violation of Section 2 of the Enigma Agreement, but has also led to Empire forces being stretched far too thin across the nation. The Principal of Intelligence informs me that they are unable to conduct adequate surveillance to prevent uprising. Combined with the Favonius resistance and ongoing struggle against Asvish control from the previously Enigmatic territories, I urge you to reconsider the attack on further Enigmatic territories lest they fully commit to war — a war we will be unable to defend against.
|
||||
|
@ -10,6 +10,8 @@ tags:
|
||||
|
||||
I let out a loud exhale as my fingers twitched in front of the keyboard. Someone else walked by.
|
||||
|
||||
<!--more-->
|
||||
|
||||
“Um, Siava, are you all right?”
|
||||
|
||||
I fought to keep my hands under control as they strained for something, anything to latch onto and ruin. *Bad hands. Do not strangle her. She is your friend. Friends are good. Friends are helpful. Friends are calming.*
|
||||
|
31
data/tagInfo.ts
Normal file
31
data/tagInfo.ts
Normal file
@ -0,0 +1,31 @@
|
||||
export interface TagData {
|
||||
name?: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export const tagInfo: Record<string, TagData> = {
|
||||
barin: { name: "Barin" },
|
||||
bsscc: {
|
||||
name: "BSSCC",
|
||||
description: "Posts related to Bayview's Computer Club.",
|
||||
},
|
||||
ibia: { name: "Ibia" },
|
||||
misc: { name: "Miscellaneous" },
|
||||
poetry: {
|
||||
name: "Poetry",
|
||||
description:
|
||||
"Poetry is interesting in that there is a lot of implied stuff that is normally said directly in prose.",
|
||||
},
|
||||
primoprod: {
|
||||
name: "Primoprod",
|
||||
description:
|
||||
'Reports following the development of <a href="https://github.com/potatoeggy/primoprod>Primoprod</a>.',
|
||||
},
|
||||
tech: { name: "Technology" },
|
||||
unstagnation: {
|
||||
name: "Unstagnation Short",
|
||||
description:
|
||||
"A collection of very short stories written to do something productive during June–August 2020 and August 2021.",
|
||||
},
|
||||
};
|
||||
export default tagInfo;
|
@ -30,7 +30,13 @@ export default defineNuxtConfig({
|
||||
meta: [
|
||||
{ name: "viewport", content: " width=device-width,initial-scale=1" },
|
||||
],
|
||||
link: [{ rel: "icon", type: "image/x-icon", href: "/favicon.ico" }],
|
||||
link: [
|
||||
{ rel: "icon", type: "image/x-icon", href: "/favicon.ico" },
|
||||
{
|
||||
rel: "stylesheet",
|
||||
href: "https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/katex.min.css",
|
||||
},
|
||||
],
|
||||
},
|
||||
content: {
|
||||
documentDriven: false,
|
||||
@ -38,7 +44,8 @@ export default defineNuxtConfig({
|
||||
theme: "dracula",
|
||||
},
|
||||
markdown: {
|
||||
remarkPlugins: ["remark-reading-time"],
|
||||
remarkPlugins: ["remark-math"],
|
||||
rehypePlugins: [["rehype-katex", { output: "html" }]],
|
||||
},
|
||||
},
|
||||
experimental: {
|
||||
|
@ -13,9 +13,12 @@
|
||||
"@nuxtjs/tailwindcss": "^5.3.0",
|
||||
"@tailwindcss/typography": "^0.5.2",
|
||||
"nuxt": "npm:nuxt3@latest",
|
||||
"remark-reading-time": "^2.0.1",
|
||||
"reading-time": "^2.0.0-1",
|
||||
"rehype-katex": "^6.0.2",
|
||||
"remark-math": "^5.1.1",
|
||||
"sitemap": "^7.1.1",
|
||||
"typescript": "^4.7.4",
|
||||
"unist-util-visit": "^4.1.0",
|
||||
"vite-svg-loader": "^3.4.0"
|
||||
},
|
||||
"dependencies": {
|
||||
|
@ -1,5 +1,25 @@
|
||||
<script setup lang="ts">
|
||||
import type { BlogParsedContent } from "@/shared/types";
|
||||
|
||||
useTitle("Blog");
|
||||
|
||||
// TODO: paginate stories
|
||||
const docs = await queryContent<BlogParsedContent>("/blog")
|
||||
.sort({ date: -1 })
|
||||
.where({ _draft: false })
|
||||
.find();
|
||||
</script>
|
||||
|
||||
<template></template>
|
||||
<template>
|
||||
<main
|
||||
class="flex flex-col grow prose dark:prose-invert max-w-3xl gap-6 transition"
|
||||
>
|
||||
<h1 class="mb-0">Blog</h1>
|
||||
<PostPreviewCard
|
||||
v-for="(post, index) in docs"
|
||||
:key="index"
|
||||
:post="post"
|
||||
type="blog"
|
||||
/>
|
||||
</main>
|
||||
</template>
|
||||
|
@ -1,22 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
import type { StoryParsedContent } from "@/shared/types";
|
||||
import dayjs from "dayjs";
|
||||
import utc from "dayjs/plugin/utc.js";
|
||||
|
||||
dayjs.extend(utc);
|
||||
|
||||
useTitle("Stories");
|
||||
|
||||
// TODO: paginate stories
|
||||
const docs = await queryContent<StoryParsedContent>("/stories")
|
||||
.sort({ date: 1 })
|
||||
.sort({ date: -1 })
|
||||
.where({ _draft: false })
|
||||
.find();
|
||||
|
||||
const getPrettyDate = (story: StoryParsedContent) => {
|
||||
const date = dayjs(story.date).utc();
|
||||
return date.format("DD MMM YYYY");
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -24,48 +15,11 @@ const getPrettyDate = (story: StoryParsedContent) => {
|
||||
class="flex flex-col grow prose dark:prose-invert max-w-3xl gap-6 transition"
|
||||
>
|
||||
<h1 class="mb-0">Stories</h1>
|
||||
<div
|
||||
class="story-card p-4 pb-2"
|
||||
<PostPreviewCard
|
||||
v-for="(story, index) in docs"
|
||||
:key="index"
|
||||
>
|
||||
<h3 class="m-0">
|
||||
<a
|
||||
:href="story._path"
|
||||
class="no-underline text-left text-2xl sm:text-2xl font-bold hover:text-blue-700 dark:hover:text-blue-400 leading-tight transition"
|
||||
>
|
||||
{{ story.title }}</a
|
||||
>
|
||||
</h3>
|
||||
<p class="my-1 text-sm">
|
||||
{{ getPrettyDate(story) }} · {{ story.readingTime.text }}
|
||||
</p>
|
||||
<div class="flex flex-wrap">
|
||||
<Tag
|
||||
:dest="`/stories/tags/${tag}`"
|
||||
v-for="(tag, index) in story.tags"
|
||||
:key="index"
|
||||
>
|
||||
{{ tag }}
|
||||
</Tag>
|
||||
</div>
|
||||
<p class="mb-1">{{ story.description }} ...</p>
|
||||
<div class="text-right">
|
||||
<a
|
||||
:href="story._path"
|
||||
class="no-underline hover:underline font-semibold text-blue-700 dark:text-blue-400"
|
||||
>
|
||||
Continue reading →
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
:post="story"
|
||||
type="stories"
|
||||
/>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.story-card {
|
||||
border: 0.1rem solid gray;
|
||||
max-width: 100%;
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
</style>
|
||||
|
38
pages/tags/blog/[tag].vue
Normal file
38
pages/tags/blog/[tag].vue
Normal file
@ -0,0 +1,38 @@
|
||||
<script setup lang="ts">
|
||||
import { tagInfo, type TagData } from "@/data/tagInfo";
|
||||
import type { BlogParsedContent } from "@/shared/types";
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
const tag =
|
||||
typeof route.params.tag === "string" ? route.params.tag : route.params.tag[0];
|
||||
|
||||
const details: TagData = tagInfo[tag] ?? {};
|
||||
|
||||
const docs = await queryContent<BlogParsedContent>("/blog")
|
||||
.sort({ date: -1 })
|
||||
.where({ _draft: false, tags: { $contains: tag } })
|
||||
.find();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main
|
||||
class="prose dark:prose-invert max-w-3xl flex flex-col grow gap-6 transition"
|
||||
>
|
||||
<div>
|
||||
<h1 class="mb-0">{{ details.name ?? `"${tag}"` }} Posts</h1>
|
||||
<p
|
||||
v-if="details.description"
|
||||
v-html="details.description"
|
||||
class="mt-2"
|
||||
></p>
|
||||
</div>
|
||||
<PostPreviewCard
|
||||
v-for="(post, index) in docs"
|
||||
:key="index"
|
||||
:post="post"
|
||||
:highlighttags="[tag]"
|
||||
type="blog"
|
||||
/>
|
||||
</main>
|
||||
</template>
|
38
pages/tags/stories/[tag].vue
Normal file
38
pages/tags/stories/[tag].vue
Normal file
@ -0,0 +1,38 @@
|
||||
<script setup lang="ts">
|
||||
import { tagInfo, type TagData } from "@/data/tagInfo";
|
||||
import type { StoryParsedContent } from "@/shared/types";
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
const tag =
|
||||
typeof route.params.tag === "string" ? route.params.tag : route.params.tag[0];
|
||||
|
||||
const details: TagData = tagInfo[tag] ?? {};
|
||||
|
||||
const docs = await queryContent<StoryParsedContent>("/stories")
|
||||
.sort({ date: -1 })
|
||||
.where({ _draft: false, tags: { $contains: tag } })
|
||||
.find();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main
|
||||
class="prose dark:prose-invert max-w-3xl flex flex-col grow gap-6 transition"
|
||||
>
|
||||
<div>
|
||||
<h1 class="mb-0">{{ details.name ?? `"${tag}"` }} Stories</h1>
|
||||
<p
|
||||
v-if="details.description"
|
||||
v-html="details.description"
|
||||
class="mt-2"
|
||||
></p>
|
||||
</div>
|
||||
<PostPreviewCard
|
||||
v-for="(story, index) in docs"
|
||||
:key="index"
|
||||
:post="story"
|
||||
:highlighttags="[tag]"
|
||||
type="stories"
|
||||
/>
|
||||
</main>
|
||||
</template>
|
30
shared/readingTime.ts
Normal file
30
shared/readingTime.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import type { BlogParsedContent, StoryParsedContent } from "./types";
|
||||
import readingTime from "reading-time";
|
||||
|
||||
function countWords(str: string) {
|
||||
let words = 0;
|
||||
for (const c of str) {
|
||||
if (c === " " || c === "/") {
|
||||
words++;
|
||||
}
|
||||
}
|
||||
return words;
|
||||
}
|
||||
|
||||
function search(obj: Record<string, any>, results: string[] = []) {
|
||||
if (obj.value) {
|
||||
results.push(obj.value);
|
||||
}
|
||||
|
||||
if (obj.children) {
|
||||
for (const el of obj.children) {
|
||||
search(el, results);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
export function calcReadingTime(doc: BlogParsedContent | StoryParsedContent) {
|
||||
let body: string[] = search(doc.body);
|
||||
return readingTime(body.join(" "));
|
||||
}
|
152
yarn.lock
152
yarn.lock
@ -794,6 +794,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3"
|
||||
integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==
|
||||
|
||||
"@types/katex@^0.11.0":
|
||||
version "0.11.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/katex/-/katex-0.11.1.tgz#34de04477dcf79e2ef6c8d23b41a3d81f9ebeaf5"
|
||||
integrity sha512-DUlIj2nk0YnJdlWgsFuVKcX27MLW0KbKmGVoUHmFr+74FYYNUDAaj9ZqTADvsbE8rfxuVmSFc7KczYn5Y09ozg==
|
||||
|
||||
"@types/mdast@^3.0.0":
|
||||
version "3.0.10"
|
||||
resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.10.tgz#4724244a82a4598884cbbe9bcfd73dff927ee8af"
|
||||
@ -2252,18 +2257,6 @@ escape-string-regexp@^5.0.0:
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz#4683126b500b61762f2dbebace1806e8be31b1c8"
|
||||
integrity sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==
|
||||
|
||||
estree-util-is-identifier-name@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/estree-util-is-identifier-name/-/estree-util-is-identifier-name-2.0.1.tgz#cf07867f42705892718d9d89eb2d85eaa8f0fcb5"
|
||||
integrity sha512-rxZj1GkQhY4x1j/CSnybK9cGuMFQYFPLq0iNyopqf14aOVLFtMv7Esika+ObJWPWiOHuMOAHz3YkWoLYYRnzWQ==
|
||||
|
||||
estree-util-value-to-estree@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/estree-util-value-to-estree/-/estree-util-value-to-estree-1.3.0.tgz#1d3125594b4d6680f666644491e7ac1745a3df49"
|
||||
integrity sha512-Y+ughcF9jSUJvncXwqRageavjrNPAI+1M/L3BI3PyLp1nmgYTGUXU6t5z1Y7OWuThoDdhPME07bQU+d5LxdJqw==
|
||||
dependencies:
|
||||
is-plain-obj "^3.0.0"
|
||||
|
||||
estree-walker@2.0.2, estree-walker@^2.0.1, estree-walker@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
|
||||
@ -2759,6 +2752,15 @@ hast-util-to-string@^2.0.0:
|
||||
dependencies:
|
||||
"@types/hast" "^2.0.0"
|
||||
|
||||
hast-util-to-text@^3.1.0:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/hast-util-to-text/-/hast-util-to-text-3.1.1.tgz#b7699a75f7a61af6e0befb67660cd78460d96dc6"
|
||||
integrity sha512-7S3mOBxACy8syL45hCn3J7rHqYaXkxRfsX6LXEU5Shz4nt4GxdjtMUtG+T6G/ZLUHd7kslFAf14kAN71bz30xA==
|
||||
dependencies:
|
||||
"@types/hast" "^2.0.0"
|
||||
hast-util-is-element "^2.0.0"
|
||||
unist-util-find-after "^4.0.0"
|
||||
|
||||
hastscript@^7.0.0:
|
||||
version "7.0.2"
|
||||
resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-7.0.2.tgz#d811fc040817d91923448a28156463b2e40d590a"
|
||||
@ -3059,11 +3061,6 @@ is-number@^7.0.0:
|
||||
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
|
||||
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
|
||||
|
||||
is-plain-obj@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7"
|
||||
integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==
|
||||
|
||||
is-plain-obj@^4.0.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz#d65025edec3657ce032fd7db63c97883eaed71f0"
|
||||
@ -3197,6 +3194,20 @@ jsonfile@^6.0.1:
|
||||
optionalDependencies:
|
||||
graceful-fs "^4.1.6"
|
||||
|
||||
katex@^0.13.0:
|
||||
version "0.13.24"
|
||||
resolved "https://registry.yarnpkg.com/katex/-/katex-0.13.24.tgz#fe55455eb455698cb24b911a353d16a3c855d905"
|
||||
integrity sha512-jZxYuKCma3VS5UuxOx/rFV1QyGSl3Uy/i0kTJF3HgQ5xMinCQVF8Zd4bMY/9aI9b9A2pjIBOsjSSm68ykTAr8w==
|
||||
dependencies:
|
||||
commander "^8.0.0"
|
||||
|
||||
katex@^0.15.0:
|
||||
version "0.15.6"
|
||||
resolved "https://registry.yarnpkg.com/katex/-/katex-0.15.6.tgz#c4e2f6ced2ac4de1ef6f737fe7c67d3026baa0e5"
|
||||
integrity sha512-UpzJy4yrnqnhXvRPhjEuLA4lcPn6eRngixW7Q3TJErjg3Aw2PuLFBzTkdUb89UtumxjhHTqL3a5GDGETMSwgJA==
|
||||
dependencies:
|
||||
commander "^8.0.0"
|
||||
|
||||
keygrip@~1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/keygrip/-/keygrip-1.1.0.tgz#871b1681d5e159c62a445b0c74b615e0917e7226"
|
||||
@ -3577,6 +3588,15 @@ mdast-util-gfm@^2.0.0:
|
||||
mdast-util-gfm-task-list-item "^1.0.0"
|
||||
mdast-util-to-markdown "^1.0.0"
|
||||
|
||||
mdast-util-math@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/mdast-util-math/-/mdast-util-math-2.0.1.tgz#141b8e7e43731d2a7423c5eb8c0335c05d257ad2"
|
||||
integrity sha512-ZZtjyRwobsiVg4bY0Q5CzAZztpbjRIA7ZlMMb0PNkwTXOnJTUoHvzBhVG95LIuek5Mlj1l2P+jBvWviqW7G+0A==
|
||||
dependencies:
|
||||
"@types/mdast" "^3.0.0"
|
||||
longest-streak "^3.0.0"
|
||||
mdast-util-to-markdown "^1.3.0"
|
||||
|
||||
mdast-util-to-hast@^12.1.0, mdast-util-to-hast@^12.1.2:
|
||||
version "12.1.2"
|
||||
resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-12.1.2.tgz#5c793b04014746585254c7ce0bc2d117201a5d1d"
|
||||
@ -3752,6 +3772,19 @@ micromark-extension-gfm@^2.0.0:
|
||||
micromark-util-combine-extensions "^1.0.0"
|
||||
micromark-util-types "^1.0.0"
|
||||
|
||||
micromark-extension-math@^2.0.0:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/micromark-extension-math/-/micromark-extension-math-2.0.2.tgz#bb7d28b907b17f1813dd3d0df2a6df6bb1a4d0e1"
|
||||
integrity sha512-cFv2B/E4pFPBBFuGgLHkkNiFAIQv08iDgPH2HCuR2z3AUgMLecES5Cq7AVtwOtZeRrbA80QgMUk8VVW0Z+D2FA==
|
||||
dependencies:
|
||||
"@types/katex" "^0.11.0"
|
||||
katex "^0.13.0"
|
||||
micromark-factory-space "^1.0.0"
|
||||
micromark-util-character "^1.0.0"
|
||||
micromark-util-symbol "^1.0.0"
|
||||
micromark-util-types "^1.0.0"
|
||||
uvu "^0.5.0"
|
||||
|
||||
micromark-factory-destination@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/micromark-factory-destination/-/micromark-factory-destination-1.0.0.tgz#fef1cb59ad4997c496f887b6977aa3034a5a277e"
|
||||
@ -4995,10 +5028,10 @@ readdirp@~3.6.0:
|
||||
dependencies:
|
||||
picomatch "^2.2.1"
|
||||
|
||||
reading-time@^1.3.0:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/reading-time/-/reading-time-1.5.0.tgz#d2a7f1b6057cb2e169beaf87113cc3411b5bc5bb"
|
||||
integrity sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==
|
||||
reading-time@^2.0.0-1:
|
||||
version "2.0.0-1"
|
||||
resolved "https://registry.yarnpkg.com/reading-time/-/reading-time-2.0.0-1.tgz#fe7a94e1d9199700f166b744925681cdb8851d06"
|
||||
integrity sha512-5Eoo17ZGqH2L0jmMZUNKARiGAX3NCC0LR+mDHTX+nMPqFSRwMQrsxhI9NOSEfzH8E1W5vGAKFcyQAk3Rla1WuA==
|
||||
|
||||
redis-errors@^1.0.0, redis-errors@^1.2.0:
|
||||
version "1.2.0"
|
||||
@ -5024,6 +5057,30 @@ rehype-external-links@^1.0.1:
|
||||
unified "^10.0.0"
|
||||
unist-util-visit "^4.0.0"
|
||||
|
||||
rehype-katex@^6.0.2:
|
||||
version "6.0.2"
|
||||
resolved "https://registry.yarnpkg.com/rehype-katex/-/rehype-katex-6.0.2.tgz#20197bbc10bdf79f6b999bffa6689d7f17226c35"
|
||||
integrity sha512-C4gDAlS1+l0hJqctyiU64f9CvT00S03qV1T6HiMzbSuLBgWUtcqydWHY9OpKrm0SpkK16FNd62CDKyWLwV2ppg==
|
||||
dependencies:
|
||||
"@types/hast" "^2.0.0"
|
||||
"@types/katex" "^0.11.0"
|
||||
hast-util-to-text "^3.1.0"
|
||||
katex "^0.15.0"
|
||||
rehype-parse "^8.0.0"
|
||||
unified "^10.0.0"
|
||||
unist-util-remove-position "^4.0.0"
|
||||
unist-util-visit "^4.0.0"
|
||||
|
||||
rehype-parse@^8.0.0:
|
||||
version "8.0.4"
|
||||
resolved "https://registry.yarnpkg.com/rehype-parse/-/rehype-parse-8.0.4.tgz#3d17c9ff16ddfef6bbcc8e6a25a99467b482d688"
|
||||
integrity sha512-MJJKONunHjoTh4kc3dsM1v3C9kGrrxvA3U8PxZlP2SjH8RNUSrb+lF7Y0KVaUDnGH2QZ5vAn7ulkiajM9ifuqg==
|
||||
dependencies:
|
||||
"@types/hast" "^2.0.0"
|
||||
hast-util-from-parse5 "^7.0.0"
|
||||
parse5 "^6.0.0"
|
||||
unified "^10.0.0"
|
||||
|
||||
rehype-raw@^6.1.1:
|
||||
version "6.1.1"
|
||||
resolved "https://registry.yarnpkg.com/rehype-raw/-/rehype-raw-6.1.1.tgz#81bbef3793bd7abacc6bf8335879d1b6c868c9d4"
|
||||
@ -5084,6 +5141,16 @@ remark-gfm@^3.0.1:
|
||||
micromark-extension-gfm "^2.0.0"
|
||||
unified "^10.0.0"
|
||||
|
||||
remark-math@^5.1.1:
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/remark-math/-/remark-math-5.1.1.tgz#459e798d978d4ca032e745af0bac81ddcdf94964"
|
||||
integrity sha512-cE5T2R/xLVtfFI4cCePtiRn+e6jKMtFDR3P8V3qpv8wpKjwvHoBA4eJzvX+nVrnlNy0911bdGmuspCSwetfYHw==
|
||||
dependencies:
|
||||
"@types/mdast" "^3.0.0"
|
||||
mdast-util-math "^2.0.0"
|
||||
micromark-extension-math "^2.0.0"
|
||||
unified "^10.0.0"
|
||||
|
||||
remark-mdc@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/remark-mdc/-/remark-mdc-1.0.1.tgz#006a17672161b4edc3746b49bed8f38fbba91d9c"
|
||||
@ -5113,16 +5180,6 @@ remark-parse@^10.0.1:
|
||||
mdast-util-from-markdown "^1.0.0"
|
||||
unified "^10.0.0"
|
||||
|
||||
remark-reading-time@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/remark-reading-time/-/remark-reading-time-2.0.1.tgz#fe8bb8e420db7678dc749385167adb4fc99318f7"
|
||||
integrity sha512-fy4BKy9SRhtYbEHvp6AItbRTnrhiDGbqLQTSYVbQPGuRCncU1ubSsh9p/W5QZSxtYcUXv8KGL0xBgPLyNJA1xw==
|
||||
dependencies:
|
||||
estree-util-is-identifier-name "^2.0.0"
|
||||
estree-util-value-to-estree "^1.3.0"
|
||||
reading-time "^1.3.0"
|
||||
unist-util-visit "^3.1.0"
|
||||
|
||||
remark-rehype@^10.1.0:
|
||||
version "10.1.0"
|
||||
resolved "https://registry.yarnpkg.com/remark-rehype/-/remark-rehype-10.1.0.tgz#32dc99d2034c27ecaf2e0150d22a6dcccd9a6279"
|
||||
@ -5925,6 +5982,14 @@ unist-builder@^3.0.0:
|
||||
dependencies:
|
||||
"@types/unist" "^2.0.0"
|
||||
|
||||
unist-util-find-after@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/unist-util-find-after/-/unist-util-find-after-4.0.0.tgz#1101cebf5fed88ae3c6f3fa676e86fd5772a4f32"
|
||||
integrity sha512-gfpsxKQde7atVF30n5Gff2fQhAc4/HTOV4CvkXpTg9wRfQhZWdXitpyXHWB6YcYgnsxLx+4gGHeVjCTAAp9sjw==
|
||||
dependencies:
|
||||
"@types/unist" "^2.0.0"
|
||||
unist-util-is "^5.0.0"
|
||||
|
||||
unist-util-generated@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-2.0.0.tgz#86fafb77eb6ce9bfa6b663c3f5ad4f8e56a60113"
|
||||
@ -5942,6 +6007,14 @@ unist-util-position@^4.0.0, unist-util-position@^4.0.3:
|
||||
dependencies:
|
||||
"@types/unist" "^2.0.0"
|
||||
|
||||
unist-util-remove-position@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-4.0.1.tgz#d5b46a7304ac114c8d91990ece085ca7c2c135c8"
|
||||
integrity sha512-0yDkppiIhDlPrfHELgB+NLQD5mfjup3a8UYclHruTJWmY74je8g+CIFr79x5f6AkmzSwlvKLbs63hC0meOMowQ==
|
||||
dependencies:
|
||||
"@types/unist" "^2.0.0"
|
||||
unist-util-visit "^4.0.0"
|
||||
|
||||
unist-util-remove@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/unist-util-remove/-/unist-util-remove-3.1.0.tgz#8042577e151dac989b7517976bfe4bac58f76ccd"
|
||||
@ -5958,14 +6031,6 @@ unist-util-stringify-position@^3.0.0:
|
||||
dependencies:
|
||||
"@types/unist" "^2.0.0"
|
||||
|
||||
unist-util-visit-parents@^4.0.0:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-4.1.1.tgz#e83559a4ad7e6048a46b1bdb22614f2f3f4724f2"
|
||||
integrity sha512-1xAFJXAKpnnJl8G7K5KgU7FY55y3GcLIXqkzUj5QF/QVP7biUm0K0O2oqVkYsdjzJKifYeWn9+o6piAK2hGSHw==
|
||||
dependencies:
|
||||
"@types/unist" "^2.0.0"
|
||||
unist-util-is "^5.0.0"
|
||||
|
||||
unist-util-visit-parents@^5.0.0, unist-util-visit-parents@^5.1.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-5.1.0.tgz#44bbc5d25f2411e7dfc5cecff12de43296aa8521"
|
||||
@ -5974,15 +6039,6 @@ unist-util-visit-parents@^5.0.0, unist-util-visit-parents@^5.1.0:
|
||||
"@types/unist" "^2.0.0"
|
||||
unist-util-is "^5.0.0"
|
||||
|
||||
unist-util-visit@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-3.1.0.tgz#9420d285e1aee938c7d9acbafc8e160186dbaf7b"
|
||||
integrity sha512-Szoh+R/Ll68QWAyQyZZpQzZQm2UPbxibDvaY8Xc9SUtYgPsDzx5AWSk++UUt2hJuow8mvwR+rG+LQLw+KsuAKA==
|
||||
dependencies:
|
||||
"@types/unist" "^2.0.0"
|
||||
unist-util-is "^5.0.0"
|
||||
unist-util-visit-parents "^4.0.0"
|
||||
|
||||
unist-util-visit@^4.0.0, unist-util-visit@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-4.1.0.tgz#f41e407a9e94da31594e6b1c9811c51ab0b3d8f5"
|
||||
|
Loading…
Reference in New Issue
Block a user