feat: typography, toc

This commit is contained in:
enscribe 2024-09-10 16:41:01 -07:00
parent ea68d4f02f
commit 8fe228e243
No known key found for this signature in database
GPG key ID: 9BBD5C4114E25322
16 changed files with 194 additions and 311 deletions

214
README.md
View file

@ -1,213 +1 @@
# Astro-Micro-Academics # erudite
[![Badge with Logo](https://img.shields.io/badge/Astro-Page-blue)
](https://astro.build/themes/details/astro-micro-academics)
[![Badge with Logo](https://img.shields.io/badge/Live-Demo-cyan)](https://astro-micro-academic.vercel.app/)
Astro Micro Academic is an academic version of [Astro-Micro](https://github.com/trevortylerlee/astro-micro) and [Nano](https://astro-nano-demo.vercel.app/).
It is tailored for researchers.
Micro Academics adds features like tags, and blog math support and also inherits [Pagefind](https://pagefind.app/) for search, [Giscus](https://giscus.app/) for comments, from Astro Micro.
Micro Academics still comes with everything great about Micro and Nano — full type safety, a sitemap, an RSS feed, and Markdown + MDX support. Styled with TailwindCSS and preconfigured with system, light, and dark themes.
## News
✨ I've got a detailed blog about building and deploying your website using this template! Check it out [here](https://jingwu2121.github.io/blog/01-build-deploy-website/)
## Install Astro-Micro-Academics
Clone the [repository](https://github.com/jingwu2121/astro-micro-academic).
```sh
git clone https://github.com/jingwu2121/astro-micro-academic.git
```
```sh
cd astro-micro-academic
```
```sh
npm i
```
Run local server
```sh
npm run dev
```
## Update the Homepage
Update your home page in `src/pages/index.astro`.
## CV & About
Update your CV and About page in `src/pages/cv.astro` and `src/pages/about.astro`.
```ts
const works = [
{
company: 'Company A',
time: '2022-Present',
job_title: 'Research Scientist',
location: 'London, UK',
description: 'Your Notes about the job',
},
{
company: 'Company A',
time: '2022-Present',
job_title: 'Research Scientist',
location: 'London, UK',
description: 'Your Notes about the job',
},
]
const educations = [
{
school: 'University 1',
time: '2022-Present',
job_title: 'BEng in Electronic Information Engineering',
location: 'London, UK',
description: 'Your Notes about the study',
},
]
```
## Social Links
Update the social links in `src/components/SocialIcons.astro`, simply replace the `URL`.
## Publications metadata
Metadata is required for each post. Add a new `publication.md` to automartically add a publication on the website. Publications are sorted by date.
```astro
---
title: 'Diffusion Models Beat GANs on Image Synthesis'
description: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestias earum quod quo repellat blanditiis est iste eos dolorem! Voluptatibus corporis totam sed unde est iusto neque iure natus adipisci omnis.'
date: '2024-07-26'
authors: 'John B*, Jon A*, Frank C, John B, Jon A, Frank C'
paperURL: 'Paper: https://astro-sphere-demo.vercel.app'
codeURL: 'Code: '
webURL: 'Web: https://github.com/markhorn-dev/astro-sphere'
dataURL: 'Data: https://github.com/markhorn-dev/astro-sphere'
img: '/rupert-cat.gif'
imgAlt: 'Paper Teaser'
pub: 'ECCV2024'
---
```
| Field | Req | Type | Remarks |
| :--------------------------------- | :-- | :----- | :--------------------------------------------------------------------------------------------------------------- |
| title | Yes | string | Title of the content. Used in SEO and RSS. |
| description | Yes | string | Description of the content. Used in SEO and RSS. |
| date | Yes | string | Must be a valid date string (able to be parsed). |
| authors | Yes | string | A string seperated by comma. |
| paperURL, codeURL, webURL, dataURL | Yes | string | A string seperated by ": ". If you don't have a link to add, leave the link part blank, e.g. `codeURL: "Code: "` |
| img | Yes | string | Path to teaser image. |
| imgAlt | Yes | string | Description of the image. |
| pub | Yes | string | The conference or journal |
## Blog metadata
Metadata is required for each post.
```astro
---
title: 'Blog Collection'
description: 'How to add posts to the blog.'
date: '2024-03-21'
tags: ['guide', 'tutorial']
draft: false
---
```
| Field | Req | Type | Remarks |
| :---------- | :-- | :------ | :----------------------------------------------- |
| title | Yes | string | Title of the content. Used in SEO and RSS. |
| description | Yes | string | Description of the content. Used in SEO and RSS. |
| date | Yes | string | Must be a valid date string (able to be parsed). |
| tags | Yes | list | A list of strings |
| draft | No | boolean | If draft: true, content will not be published. |
## Customize the website metadata and set up RSS
To change the website metadata, edit `src/consts.ts`.
```ts
// src/consts.ts
export const SITE: Site = {
TITLE: 'Astro Micro Academics',
DESCRIPTION: 'Astro Micro Academics is for academic user.',
EMAIL: 'youremial@gmail.com',
NUM_POSTS_ON_HOMEPAGE: 2,
NUM_PUBLICATIONS_ON_HOMEPAGE: 3,
SITEURL: 'https://astro-micro-academic.vercel.app', // Update here to link the RSS icon to your website RSS
}
```
| Field | Req | Description |
| :--------------- | :-- | :--------------------------------------------------- |
| TITLE | Yes | Displayed in header and footer. Used in SEO and RSS. |
| DESCRIPTION | Yes | Used in SEO and RSS. |
| EMAIL | Yes | Displayed in contact section. |
| NUM_POSTS | Yes | Limit number of posts on home page. |
| NUM_PUBLICATIONS | Yes | Limit number of research on home page. |
| SITEURL | Yes | Your website URL |
### RSS Post
Please tag the post of RSS feed with tag `"rss-feed"`, other posts are not included in the RSS.
---
## Custom metadata for highlighted author in your paper
```ts
// src/consts.ts
export const HIGHLIGHTAUTHOR = 'John B'
```
## Customize metadata for individual pages
```ts
// src/consts.ts
export const HOME: Metadata = {
TITLE: 'Home',
DESCRIPTION: 'Astro Micro is an accessible theme for Astro.',
}
export const BLOG: Metadata = {
TITLE: 'Blog',
DESCRIPTION: 'A collection of articles on topics I am passionate about.',
}
export const RESEARCH: Metadata = {
TITLE: 'Publications',
DESCRIPTION:
'A collection of my publications with links to paper, repositories and live demos.',
}
export const CV: Metadata = {
TITLE: 'CV',
DESCRIPTION: 'your cv',
}
export const TAGS: Metadata = {
TITLE: 'TAGS',
DESCRIPTION: 'blog tag filter',
}
export const ABOUT: Metadata = {
TITLE: 'ABOUT',
DESCRIPTION: 'A self-intro',
}
```
| Field | Req | Description |
| :---------- | :-- | :--------------------------------------------- |
| TITLE | Yes | Displayed in browser tab. Used in SEO and RSS. |
| DESCRIPTION | Yes | Used in SEO and RSS. |

View file

@ -4,7 +4,7 @@ import SocialIcons from './SocialIcons.astro'
import { ModeToggle } from '@components/ui/mode-toggle' import { ModeToggle } from '@components/ui/mode-toggle'
--- ---
<footer class="py-8"> <footer class="py-4">
<Container> <Container>
<div class="flex justify-between items-center"> <div class="flex justify-between items-center">
<div class="flex items-center space-x-4"> <div class="flex items-center space-x-4">

View file

@ -1,5 +1,7 @@
--- ---
import '../styles/global.css' import '../styles/global.css'
import '../styles/katex.css'
import '../styles/typography.css'
import '@fontsource/geist-sans' import '@fontsource/geist-sans'
import '@fontsource/geist-mono' import '@fontsource/geist-mono'

View file

@ -11,21 +11,23 @@ const items = [
] ]
--- ---
<header class="sticky top-0 z-10" transition:persist> <header class="sticky top-0 z-10 bg-background/50 backdrop-blur-md" transition:persist>
<Container> <Container>
<div class="flex items-center justify-between py-4"> <div class="flex items-center justify-between py-4">
<Link href="/" underline={false}> <Link href="/" class="text-xl font-semibold hover:text-primary transition-colors duration-300">
{SITE.TITLE}<span class="ml-1">🍄</span> {SITE.TITLE}
</Link> </Link>
<nav class="flex items-center space-x-1 text-sm"> <nav class="flex items-center gap-4 md:gap-6 text-sm">
{ {items.map((item, index) => (
items.map((item, index) => ( <Fragment key={item.href}>
<> <Link
<Link href={item.href}>{item.label}</Link> href={item.href}
{index < items.length - 1 && <span class="text-gray-400">/</span>} class="transition-colors hover:text-foreground/80 text-foreground/60 capitalize"
</> >
)) {item.label}
} </Link>
</Fragment>
))}
</nav> </nav>
</div> </div>
</Container> </Container>

View file

@ -4,21 +4,21 @@ import { cn } from '@lib/utils'
type Props = { type Props = {
href: string href: string
external?: boolean external?: boolean
underline?: boolean class?: string
group?: boolean 'data-heading'?: string
} }
const { href, external, underline = true, group = false, ...rest } = Astro.props const { href, external, class: className, 'data-heading': dataHeading, ...rest } = Astro.props
--- ---
<a <a
href={href} href={href}
target={external ? '_blank' : '_self'} target={external ? '_blank' : '_self'}
class={cn( class={cn(
'inline-block transition-colors duration-300 ease-in-out', 'inline-block transition-colors duration-300 ease-in-out hover:underline underline-offset-[3px]',
underline && 'underline underline-offset-[3px]', className
group && 'group',
)} )}
data-heading={dataHeading}
{...rest} {...rest}
> >
<slot /> <slot />

View file

@ -27,17 +27,17 @@ function buildToc(headings: Heading[]) {
} }
--- ---
<details open class="rounded-lg border"> <details open class="block xl:hidden rounded-lg border p-3 mb-8">
<summary>Table of Contents</summary> <summary class="text-xl font-semibold">Table of Contents</summary>
<nav> <nav>
<ul class="py-3"> <ul class="py-3">
{toc.map((heading) => <TableOfContentsHeading heading={heading} />)} {toc.map((heading) => <TableOfContentsHeading heading={heading} />)}
</ul> </ul>
</nav> </nav>
</details> </details>
<nav class="sticky top-16 hidden xl:block h-0 w-[calc(50vw-50%-4rem)] overflow-wrap-break-word text-xs leading-4 translate-x-[calc(-100%-2em)]">
<style> <h2 class="text-xl font-semibold mb-4">Table of Contents</h2>
summary { <ul class="space-y-2">
@apply cursor-pointer rounded-t-lg px-3 py-1.5 font-medium transition-colors; {toc.map((heading) => <TableOfContentsHeading heading={heading} />)}
} </ul>
</style> </nav>

View file

@ -2,18 +2,16 @@
import type { Heading } from './TableOfContents.astro' import type { Heading } from './TableOfContents.astro'
import Link from './Link.astro' import Link from './Link.astro'
// https://kld.dev/building-table-of-contents/
const { heading } = Astro.props const { heading } = Astro.props
--- ---
<li class="list-inside list-disc px-6 py-1.5 text-sm"> <li class="list-inside list-disc px-6 py-1.5 xl:list-none xl:p-0 text-sm">
<Link href={'#' + heading.slug} underline> <Link href={'#' + heading.slug} class="toc-link" data-heading={heading.slug}>
{heading.text} {heading.text}
</Link> </Link>
{ {
heading.subheadings.length > 0 && ( heading.subheadings.length > 0 && (
<ul class="translate-x-3"> <ul class="translate-x-3 xl:translate-x-0 xl:ml-4 xl:mt-2 xl:space-y-2">
{heading.subheadings.map((subheading: Heading) => ( {heading.subheadings.map((subheading: Heading) => (
<Astro.self heading={subheading} /> <Astro.self heading={subheading} />
))} ))}
@ -21,3 +19,31 @@ const { heading } = Astro.props
) )
} }
</li> </li>
<script>
function updateActiveHeading() {
const headings = document.querySelectorAll('h2, h3, h4, h5, h6');
const tocLinks = document.querySelectorAll('.toc-link');
let currentHeading = '';
headings.forEach(heading => {
const top = heading.getBoundingClientRect().top;
if (top < 100) {
currentHeading = heading.id;
}
});
tocLinks.forEach(link => {
const headingSlug = link.getAttribute('data-heading');
if (headingSlug === currentHeading) {
link.classList.add('underline');
} else {
link.classList.remove('underline');
}
});
}
window.addEventListener('scroll', updateActiveHeading);
window.addEventListener('load', updateActiveHeading);
</script>

View file

@ -28,7 +28,7 @@ export function ModeToggle() {
}, [theme]) }, [theme])
return ( return (
<DropdownMenu> <DropdownMenu modal={false}>
<DropdownMenuTrigger asChild> <DropdownMenuTrigger asChild>
<Button variant="outline" size="icon"> <Button variant="outline" size="icon">
<Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" /> <Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />

View file

@ -1,9 +1,15 @@
import type { Site } from '@types' export type Site = {
TITLE: string
DESCRIPTION: string
EMAIL: string
NUM_POSTS_ON_HOMEPAGE: number
SITEURL: string
}
export const SITE: Site = { export const SITE: Site = {
TITLE: 'Astro Micro Academics', TITLE: 'astro-erudite',
DESCRIPTION: 'Astro Micro Academics is for academic user.', DESCRIPTION: 'astro-erudite is a opinionated, no-frills blogging template. Built with Astro.',
EMAIL: 'youremial@gmail.com', EMAIL: 'youremail@gmail.com',
NUM_POSTS_ON_HOMEPAGE: 2, NUM_POSTS_ON_HOMEPAGE: 2,
SITEURL: 'https://astro-micro-academic.vercel.app', // Update here to link the RSS icon to your website rss SITEURL: 'https://astro-erudite.vercel.app',
} }

View file

@ -5,48 +5,108 @@ date: '2024-07-25'
tags: ['log', 'rss-feed'] tags: ['log', 'rss-feed']
--- ---
:exclamation: Also refer to [Old] posts to see examples and changes. Some changes are removed in this version, which are marked. ## h2 Heading
### h3 Heading
#### h4 Heading
##### h5 Heading
###### h6 Heading
## What is New ## Emphasis
- Add Math support to the blog **This is bold text**
- Add News, Research, Publication, CV sections
- add icon to connect section
- Add tag function to the blog
- add RSS Feed icon
- add tags to post slug and enable tag based search
- add function to RSS feed only posts with rss-feed tags
- Change SOCIALS
- add highlight author
- redo the news section height
- support markdown emoji :blush: :exclamation:
- Clear and rearrange all the posts
- [x] rewrite astro-micro-academics
- [x] astro micro
- [x] get started with astro micro
- [x] blog collection example
--- __This is bold text__
## TODO *This is italic text*
- Add Group Page _This is italic text_
- Add Opening Section
- Add Award Page
- Write a complete personal website setup guide
- screenshot and submit theme to astro
- add progress bar on the top
- show tags on allowcard
- fix news section scroll bar
## Math test ~~Strikethrough~~
This is an inline formula: $a = b+1$, $a = \frac{1}{x_1}$
$$ ## Blockquotes
a = \sum_{n=1}^{22} \sqrt{a+b_n}
$$
## 中文测试
这里是中文测试 > Blockquotes can also be nested...
>> ...by using additional greater-than signs right next to each other...
> > > ...or with spaces between arrows.
## Lists
Unordered
+ Create a list by starting a line with `+`, `-`, or `*`
+ Sub-lists are made by indenting 2 spaces:
- Marker character change forces new list start:
* Ac tristique libero volutpat at
+ Facilisis in pretium nisl aliquet
- Nulla volutpat aliquam velit
+ Very easy!
Ordered
1. Lorem ipsum dolor sit amet
2. Consectetur adipiscing elit
3. Integer molestie lorem at massa
1. You can use sequential numbers...
1. ...or keep all the numbers as `1.`
Start numbering with offset:
57. foo
1. bar
## Code
Inline `code`
Indented code
// Some comments
line 1 of code
line 2 of code
line 3 of code
Block code "fences"
```
Sample text here...
```
Syntax highlighting
``` js
var foo = function (bar) {
return bar++;
};
console.log(foo(5));
```
## Tables
| Option | Description |
| ------ | ----------- |
| data | path to data files to supply the data that will be passed into templates. |
| engine | engine to be used for processing templates. Handlebars is the default. |
| ext | extension to be used for dest files. |
Right aligned columns
| Option | Description |
| ------:| -----------:|
| data | path to data files to supply the data that will be passed into templates. |
| engine | engine to be used for processing templates. Handlebars is the default. |
| ext | extension to be used for dest files. |
## Links
[link text](http://dev.nodeca.com)
[link with title](http://nodeca.github.io/pica/demo/ "title text!")

View file

@ -3,7 +3,6 @@ import Head from '@components/Head.astro'
import Header from '@components/Header.astro' import Header from '@components/Header.astro'
import Footer from '@components/Footer.astro' import Footer from '@components/Footer.astro'
import { SITE } from '@consts' import { SITE } from '@consts'
import '../styles/katex.css'
type Props = { type Props = {
title: string title: string
@ -19,7 +18,7 @@ const { title, description } = Astro.props
<Head title={`${title} | ${SITE.TITLE}`} description={description} /> <Head title={`${title} | ${SITE.TITLE}`} description={description} />
</head> </head>
<body <body
class="box-border flex h-fit min-h-screen flex-col px-4 font-sans bg-background text-foreground antialiased" class="box-border flex h-fit min-h-screen flex-col px-4 font-sans bg-background text-foreground antialiased gap-y-4"
> >
<Header /> <Header />
<main class="flex-grow"> <main class="flex-grow">

View file

@ -5,9 +5,6 @@ import { SITE } from '@consts'
import ArrowCard from '@components/ArrowCard.astro' import ArrowCard from '@components/ArrowCard.astro'
import Link from '@components/Link.astro' import Link from '@components/Link.astro'
import { getCollection } from 'astro:content' import { getCollection } from 'astro:content'
import type { CollectionEntry } from 'astro:content'
import SocialIcons from '@components/SocialIcons.astro'
import { ModeToggle } from '@components/ui/mode-toggle'
const blog = (await getCollection('blog')) const blog = (await getCollection('blog'))
.filter((post) => !post.data.draft) .filter((post) => !post.data.draft)
@ -18,7 +15,6 @@ const blog = (await getCollection('blog'))
<Layout title="Home" description="Home"> <Layout title="Home" description="Home">
<Container> <Container>
<section class="space-y-6"> <section class="space-y-6">
<ModeToggle client:load />
<div class="flex flex-wrap items-center justify-between gap-y-2"> <div class="flex flex-wrap items-center justify-between gap-y-2">
<h2 class="font-semibold">Latest posts</h2> <h2 class="font-semibold">Latest posts</h2>
<Link href="/blog"> See all posts </Link> <Link href="/blog"> See all posts </Link>

View file

@ -84,24 +84,19 @@
--chart-4: 280 65% 60%; --chart-4: 280 65% 60%;
--chart-5: 340 75% 55%; --chart-5: 340 75% 55%;
} }
}
@layer base { *,
* { *::before,
@apply border-border; *::after {
@apply !border-border;
} }
html { html {
color-scheme: light; color-scheme: light;
scrollbar-gutter: stable;
} }
html.dark { html.dark {
color-scheme: dark; color-scheme: dark;
} }
} }
@layer utilities {
.disable-transitions * {
@apply !transition-none;
}
}

16
src/styles/typography.css Normal file
View file

@ -0,0 +1,16 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
article {
@apply prose-h1:scroll-m-20 prose-h1:text-4xl prose-h1:font-extrabold prose-h1:tracking-tight prose-h1:lg:text-5xl;
@apply prose-h2:mt-10 prose-h2:scroll-m-20 prose-h2:border-b prose-h2:pb-2 prose-h2:text-3xl prose-h2:font-semibold prose-h2:tracking-tight prose-h2:transition-colors prose-h2:first:mt-0;
@apply prose-h3:mt-8 prose-h3:scroll-m-20 prose-h3:text-2xl prose-h3:font-semibold prose-h3:tracking-tight;
@apply prose-p:leading-7 prose-p:[&:not(:first-child)]:mt-6;
@apply prose-a:font-medium prose-a:text-primary prose-a:underline prose-a:underline-offset-4;
@apply prose-blockquote:mt-6 prose-blockquote:border-l-2 prose-blockquote:pl-6 prose-blockquote:italic;
@apply prose-ul:my-6 prose-ul:ml-6 prose-ul:list-disc prose-ul:[&>li]:mt-2;
@apply prose-pre:border prose-pre:border-border;
}
}

View file

@ -1,7 +0,0 @@
export type Site = {
TITLE: string
DESCRIPTION: string
EMAIL: string
NUM_POSTS_ON_HOMEPAGE: number
SITEURL: string
}

View file

@ -3,7 +3,7 @@ import defaultTheme from 'tailwindcss/defaultTheme'
const config: Config = { const config: Config = {
darkMode: ['selector'], darkMode: ['selector'],
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'], content: ['./src/**/*.{astro,md,mdx,ts,tsx}'],
theme: { theme: {
extend: { extend: {
fontFamily: { fontFamily: {