From c7a650cdb7af9b9a81f74ace42926437c6b0f010 Mon Sep 17 00:00:00 2001 From: abearxiong Date: Mon, 27 Oct 2025 00:53:06 +0800 Subject: [PATCH] update --- src/components/MdPreview.tsx | 70 ++++++++++++++++++++++++++++++++ src/content.config.ts | 17 ++++++++ src/layouts/blank.astro | 24 +++++++++++ src/layouts/mdx.astro | 60 +++++++++++++++++++++++++++ src/modules/basename.ts | 4 ++ src/pages/docs/[...id].astro | 23 +++++++++++ src/pages/docs/index.astro | 23 +++++++++++ src/styles/theme.css | 79 ++++++++++++++++++++++++++++++++++++ 8 files changed, 300 insertions(+) create mode 100644 src/components/MdPreview.tsx create mode 100644 src/content.config.ts create mode 100644 src/layouts/blank.astro create mode 100644 src/layouts/mdx.astro create mode 100644 src/modules/basename.ts create mode 100644 src/pages/docs/[...id].astro create mode 100644 src/pages/docs/index.astro create mode 100644 src/styles/theme.css diff --git a/src/components/MdPreview.tsx b/src/components/MdPreview.tsx new file mode 100644 index 0000000..b10ddcc --- /dev/null +++ b/src/components/MdPreview.tsx @@ -0,0 +1,70 @@ +import { cn } from '@/lib/utils'; +import { useEffect, useState } from 'react'; +import { Marked } from 'marked'; +import hljs from 'highlight.js'; +import { markedHighlight } from 'marked-highlight'; + +const markedAndHighlight = new Marked( + markedHighlight({ + emptyLangClass: 'hljs', + langPrefix: 'hljs language-', + highlight(code, lang, info) { + const language = hljs.getLanguage(lang) ? lang : 'plaintext'; + return hljs.highlight(code, { language }).value; + }, + }), +); + +export const md2html = async (md: string) => { + const html = markedAndHighlight.parse(md); + return html; +}; + +export const clearMeta = (markdown?: string) => { + if (!markdown) return ''; + // Remove YAML front matter if present + const yamlRegex = /^---\n[\s\S]*?\n---\n/; + return markdown.replace(yamlRegex, ''); +}; +type Props = { + children?: React.ReactNode; + className?: string; + style?: React.CSSProperties; + content?: string; // Optional content prop for markdown text + [key: string]: any; // Allow any additional props +}; +export const MarkdownPreview = (props: Props) => { + return ( +
+ {props.children ? {props.children} : } +
+ ); +}; + +export const WrapperText = (props: { children?: React.ReactNode; html?: string }) => { + if (props.html) { + return
; + } + return
{props.children}
; +}; + +export const MarkdownPreviewWrapper = (props: Props) => { + const [html, setHtml] = useState(''); + useEffect(() => { + init(); + }, [props.content]); + const init = async () => { + if (props.content) { + const htmlContent = await md2html(props.content); + setHtml(htmlContent); + } else { + setHtml(''); + } + }; + return ; +}; diff --git a/src/content.config.ts b/src/content.config.ts new file mode 100644 index 0000000..41dcb49 --- /dev/null +++ b/src/content.config.ts @@ -0,0 +1,17 @@ +// @ts-ignore +import { defineCollection, z } from 'astro:content'; +import { glob, file } from 'astro/loaders'; // 不适用于旧版 API + +const docs = defineCollection({ + // loader: glob({ pattern: '**/*.md', base: './src/data/blogs' }), + loader: glob({ pattern: '**/[^_]*.md', base: './src/data/docs' }), + schema: z.object({ + title: z.string().optional(), + description: z.string().optional(), + // pubDate: z.coerce.date(), + // updatedDate: z.coerce.date().optional(), + }), +}); + + +export const collections = { docs }; diff --git a/src/layouts/blank.astro b/src/layouts/blank.astro new file mode 100644 index 0000000..4a4daa9 --- /dev/null +++ b/src/layouts/blank.astro @@ -0,0 +1,24 @@ +--- +import '../styles/global.css'; +import '../styles/theme.css'; +--- + + + + + + AI Pages + + + + + + diff --git a/src/layouts/mdx.astro b/src/layouts/mdx.astro new file mode 100644 index 0000000..8bb4aef --- /dev/null +++ b/src/layouts/mdx.astro @@ -0,0 +1,60 @@ +--- +export interface Props { + children: any; +} +import '../styles/global.css'; +import '../styles/theme.css'; +export interface Props { + title?: string; + description?: string; + lang?: string; + charset?: string; +} + +const { title = 'Light Code', description = 'A lightweight code editor', lang = 'zh-CN', charset = 'UTF-8' } = Astro.props; +--- + + + + + + Docs + + + + +
+ +
+
+
+ +
+
+
+ +

Copyrignt © 2025

+
+
+ + diff --git a/src/modules/basename.ts b/src/modules/basename.ts new file mode 100644 index 0000000..e647be9 --- /dev/null +++ b/src/modules/basename.ts @@ -0,0 +1,4 @@ +// @ts-ignore +export const basename = BASE_NAME; + +console.log(basename); \ No newline at end of file diff --git a/src/pages/docs/[...id].astro b/src/pages/docs/[...id].astro new file mode 100644 index 0000000..9e7ca81 --- /dev/null +++ b/src/pages/docs/[...id].astro @@ -0,0 +1,23 @@ +--- +import { getCollection, render } from 'astro:content'; +import Main from '@/layouts/mdx.astro'; +// 1. 为每个集合条目生成一个新路径 +export async function getStaticPaths() { + const posts = await getCollection('docs'); + return posts.map((post) => ({ + params: { id: post.id }, + props: { post }, + })); +} +type Post = { + data: { title: string }; +}; +// 2. 对于你的模板,你可以直接从 prop 获取条目 +const { post } = Astro.props as { post: Post }; +const { Content } = await render(post); +--- + +
+ + +
diff --git a/src/pages/docs/index.astro b/src/pages/docs/index.astro new file mode 100644 index 0000000..2d4e4ab --- /dev/null +++ b/src/pages/docs/index.astro @@ -0,0 +1,23 @@ +--- +import { getCollection } from 'astro:content'; +const posts = await getCollection('docs'); +console.log('post', posts); +import { basename } from '@/modules/basename'; +import Blank from '@/layouts/blank.astro'; +--- + + +
+

My posts

+ +
+
diff --git a/src/styles/theme.css b/src/styles/theme.css new file mode 100644 index 0000000..55fc55c --- /dev/null +++ b/src/styles/theme.css @@ -0,0 +1,79 @@ +@import 'tailwindcss'; + +@theme { + /* --color-primary: #ffc107; + --color-secondary: #ffa000; + --color-text-primary: #000000; + --color-text-secondary: #000000; + --color-success: #28a745; */ + + --color-scrollbar-thumb: #999999; + --color-scrollbar-track: rgba(0, 0, 0, 0.1); + --color-scrollbar-thumb-hover: #666666; + --scrollbar-color: #ffc107; +} + +html, +body { + width: 100%; + height: 100%; + font-size: 16px; + font-family: 'Montserrat', sans-serif; +} +/* font-family */ +@utility font-family-mon { + font-family: 'Montserrat', sans-serif; +} +@utility font-family-rob { + font-family: 'Roboto', sans-serif; +} +@utility font-family-int { + font-family: 'Inter', sans-serif; +} +@utility font-family-orb { + font-family: 'Orbitron', sans-serif; +} +@utility font-family-din { + font-family: 'DIN', sans-serif; +} + +@utility flex-row-center { + @apply flex flex-row items-center justify-center; +} +@utility flex-col-center { + @apply flex flex-col items-center justify-center; +} + +@utility scrollbar { + overflow: auto; + /* 整个滚动条 */ + &::-webkit-scrollbar { + width: 3px; + height: 3px; + } + &::-webkit-scrollbar-track { + background-color: var(--color-scrollbar-track); + } + /* 滚动条有滑块的轨道部分 */ + &::-webkit-scrollbar-track-piece { + background-color: transparent; + border-radius: 1px; + } + + /* 滚动条滑块(竖向:vertical 横向:horizontal) */ + &::-webkit-scrollbar-thumb { + cursor: pointer; + background-color: var(--color-scrollbar-thumb); + border-radius: 5px; + } + + /* 滚动条滑块hover */ + &::-webkit-scrollbar-thumb:hover { + background-color: var(--color-scrollbar-thumb-hover); + } + + /* 同时有垂直和水平滚动条时交汇的部分 */ + &::-webkit-scrollbar-corner { + display: block; /* 修复交汇时出现的白块 */ + } +}