chore: remove junk

This commit is contained in:
enscribe 2024-09-10 10:36:58 -07:00
parent f6dcc302d4
commit 8f6872f739
No known key found for this signature in database
GPG key ID: 9BBD5C4114E25322
96 changed files with 1002 additions and 2485 deletions

View file

@ -1,17 +0,0 @@
// .prettierrc.mjs
/** @type {import("prettier").Config} */
export default {
plugins: [
"prettier-plugin-astro",
"prettier-plugin-organize-imports",
"prettier-plugin-tailwindcss",
],
overrides: [
{
files: "*.astro",
options: {
parser: "astro",
},
},
],
};

162
README.md
View file

@ -1,11 +1,11 @@
# Astro-Micro-Academics
# Astro-Micro-Academics
[![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.
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.
@ -14,9 +14,10 @@ Micro Academics still comes with everything great about Micro and Nano — full
![teaser](./assets/teaser-1.png)
## 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
✨ 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).
@ -33,6 +34,7 @@ npm i
```
Run local server
```sh
npm run dev
```
@ -41,55 +43,72 @@ npm run dev
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"},
{
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"},
{
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`.
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.
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"
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 |
| 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
@ -97,11 +116,11 @@ Metadata is required for each post.
```astro
---
title: "Blog Collection";
description: "How to add posts to the blog.";
date: "2024-03-21";
title: 'Blog Collection'
description: 'How to add posts to the blog.'
date: '2024-03-21'
tags: ['guide', 'tutorial']
draft: false;
draft: false
---
```
@ -110,10 +129,10 @@ draft: false;
| 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 |
| 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
## Customize the website metadata and set up RSS
To change the website metadata, edit `src/consts.ts`.
@ -121,27 +140,27 @@ To change the website metadata, edit `src/consts.ts`.
// src/consts.ts
export const SITE: Site = {
TITLE: "Astro Micro Academics",
DESCRIPTION: "Astro Micro Academics is for academic user.",
EMAIL: "youremial@gmail.com",
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
};
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. |
| 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 |
| 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.
Please tag the post of RSS feed with tag `"rss-feed"`, other posts are not included in the RSS.
---
@ -150,7 +169,7 @@ Please tag the post of RSS feed with tag `"rss-feed"`, other posts are not inclu
```ts
// src/consts.ts
export const HIGHLIGHTAUTHOR = "John B"
export const HIGHLIGHTAUTHOR = 'John B'
```
## Customize metadata for individual pages
@ -159,38 +178,35 @@ export const HIGHLIGHTAUTHOR = "John B"
// src/consts.ts
export const HOME: Metadata = {
TITLE: "Home",
DESCRIPTION: "Astro Micro is an accessible theme for Astro.",
};
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.",
};
TITLE: 'Blog',
DESCRIPTION: 'A collection of articles on topics I am passionate about.',
}
export const RESEARCH: Metadata = {
TITLE: "Publications",
TITLE: 'Publications',
DESCRIPTION:
"A collection of my publications with links to paper, repositories and live demos.",
};
'A collection of my publications with links to paper, repositories and live demos.',
}
export const CV: Metadata = {
TITLE: "CV",
DESCRIPTION:
"your cv",
};
TITLE: 'CV',
DESCRIPTION: 'your cv',
}
export const TAGS: Metadata = {
TITLE: "TAGS",
DESCRIPTION:
"blog tag filter",
};
TITLE: 'TAGS',
DESCRIPTION: 'blog tag filter',
}
export const ABOUT: Metadata = {
TITLE: "ABOUT",
DESCRIPTION:
"A self-intro",
};
TITLE: 'ABOUT',
DESCRIPTION: 'A self-intro',
}
```
| Field | Req | Description |

View file

@ -1,25 +0,0 @@
import tailwind from "@astrojs/tailwind";
import { defineConfig } from "astro/config";
import { rehypeHeadingIds } from "@astrojs/markdown-remark";
import remarkToc from "remark-toc";
import { rehypeAccessibleEmojis } from "rehype-accessible-emojis";
import rehypeKatex from "rehype-katex";
import remarkMath from "remark-math";
import remarkEmoji from 'remark-emoji';
import mdx from "@astrojs/mdx";
import sitemap from "@astrojs/sitemap";
import pagefind from "astro-pagefind";
// https://astro.build/config
export default defineConfig({
site: "https://astro-micro-academic.vercel.app",
integrations: [tailwind(), sitemap(), mdx(), pagefind()],
markdown: {
shikiConfig: {
theme: "css-variables",
},
rehypePlugins: [rehypeHeadingIds, rehypeAccessibleEmojis, rehypeKatex],
remarkPlugins: [remarkToc, remarkMath, remarkEmoji],
},
server: { port: 1234, host: true}
});

23
astro.config.ts Normal file
View file

@ -0,0 +1,23 @@
import { rehypeHeadingIds } from '@astrojs/markdown-remark'
import mdx from '@astrojs/mdx'
import sitemap from '@astrojs/sitemap'
import tailwind from '@astrojs/tailwind'
import { defineConfig } from 'astro/config'
import rehypeKatex from 'rehype-katex'
import remarkEmoji from 'remark-emoji'
import remarkMath from 'remark-math'
import remarkToc from 'remark-toc'
// https://astro.build/config
export default defineConfig({
site: 'https://astro-micro-academic.vercel.app',
integrations: [tailwind(), sitemap(), mdx()],
markdown: {
shikiConfig: {
theme: 'css-variables',
},
rehypePlugins: [rehypeHeadingIds, rehypeKatex],
remarkPlugins: [remarkToc, remarkMath, remarkEmoji],
},
server: { port: 1234, host: true },
})

168
package-lock.json generated
View file

@ -17,10 +17,8 @@
"@fontsource/geist-mono": "^5.0.3",
"@fontsource/geist-sans": "^5.0.3",
"astro": "^4.11.3",
"astro-pagefind": "^1.5.0",
"bootstrap-icons": "^1.11.3",
"clsx": "^2.1.1",
"rehype-accessible-emojis": "^0.3.2",
"rehype-katex": "^7.0.0",
"remark-emoji": "^5.0.1",
"remark-math": "^6.0.0",
@ -31,7 +29,6 @@
},
"devDependencies": {
"@tailwindcss/typography": "^0.5.13",
"pagefind": "^1.1.0",
"prettier": "^3.2.5",
"prettier-plugin-astro": "^0.13.0",
"prettier-plugin-organize-imports": "^3.2.4",
@ -1698,77 +1695,6 @@
"node": ">= 8"
}
},
"node_modules/@pagefind/darwin-arm64": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@pagefind/darwin-arm64/-/darwin-arm64-1.1.0.tgz",
"integrity": "sha512-SLsXNLtSilGZjvqis8sX42fBWsWAVkcDh1oerxwqbac84HbiwxpxOC2jm8hRwcR0Z55HPZPWO77XeRix/8GwTg==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"darwin"
]
},
"node_modules/@pagefind/darwin-x64": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@pagefind/darwin-x64/-/darwin-x64-1.1.0.tgz",
"integrity": "sha512-QjQSE/L5oS1C8N8GdljGaWtjCBMgMtfrPAoiCmINTu9Y9dp0ggAyXvF8K7Qg3VyIMYJ6v8vg2PN7Z3b+AaAqUA==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"darwin"
]
},
"node_modules/@pagefind/default-ui": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@pagefind/default-ui/-/default-ui-1.1.0.tgz",
"integrity": "sha512-+XiAJAK++C64nQcD7s3Prdmd5S92lT05fwjOxm0L1jj80jbL+tmvcqkkFnPpoqhnicIPgcAX/Y5W0HRZnBt35w==",
"license": "MIT"
},
"node_modules/@pagefind/linux-arm64": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@pagefind/linux-arm64/-/linux-arm64-1.1.0.tgz",
"integrity": "sha512-8zjYCa2BtNEL7KnXtysPtBELCyv5DSQ4yHeK/nsEq6w4ToAMTBl0K06khqxdSGgjMSwwrxvLzq3so0LC5Q14dA==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@pagefind/linux-x64": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@pagefind/linux-x64/-/linux-x64-1.1.0.tgz",
"integrity": "sha512-4lsg6VB7A6PWTwaP8oSmXV4O9H0IHX7AlwTDcfyT+YJo/sPXOVjqycD5cdBgqNLfUk8B9bkWcTDCRmJbHrKeCw==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@pagefind/windows-x64": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@pagefind/windows-x64/-/windows-x64-1.1.0.tgz",
"integrity": "sha512-OboCM76BcMKT9IoSfZuFhiqMRgTde8x4qDDvKulFmycgiJrlL5WnIqBHJLQxZq+o2KyZpoHF97iwsGAm8c32sQ==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"win32"
]
},
"node_modules/@pkgjs/parseargs": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
@ -1779,12 +1705,6 @@
"node": ">=14"
}
},
"node_modules/@polka/url": {
"version": "1.0.0-next.25",
"resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.25.tgz",
"integrity": "sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==",
"license": "MIT"
},
"node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.18.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.1.tgz",
@ -2530,20 +2450,6 @@
"sharp": "^0.33.3"
}
},
"node_modules/astro-pagefind": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/astro-pagefind/-/astro-pagefind-1.5.0.tgz",
"integrity": "sha512-CN7Afe9qW640U1qliCQMXN259Dl6VPUnl8FneLfKE7STV4HLiif4PbNZejylC6yXYyP6uyNVDHNOfJfBBW5h6A==",
"license": "MIT",
"dependencies": {
"@pagefind/default-ui": "^1.0.3",
"pagefind": "^1.0.3",
"sirv": "^2.0.3"
},
"peerDependencies": {
"astro": "^2.0.4 || ^3.0.0 || ^4.0.0"
}
},
"node_modules/astro/node_modules/@astrojs/markdown-remark": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-5.1.1.tgz",
@ -3730,11 +3636,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/gemoji": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/gemoji/-/gemoji-4.2.1.tgz",
"integrity": "sha512-V9lUpRSn+KQGavZx8Pk+6mxG3kaz21ae2kTCXuT36KaRPNgYU8eHtj/RcUCNFVvmwppsYYz3nnNS9lmcP5kTsg=="
},
"node_modules/gensync": {
"version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
@ -6203,22 +6104,6 @@
"integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==",
"license": "BlueOak-1.0.0"
},
"node_modules/pagefind": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/pagefind/-/pagefind-1.1.0.tgz",
"integrity": "sha512-1nmj0/vfYcMxNEQj0YDRp6bTVv9hI7HLdPhK/vBBYlrnwjATndQvHyicj5Y7pUHrpCFZpFnLVQXIF829tpFmaw==",
"license": "MIT",
"bin": {
"pagefind": "lib/runner/bin.cjs"
},
"optionalDependencies": {
"@pagefind/darwin-arm64": "1.1.0",
"@pagefind/darwin-x64": "1.1.0",
"@pagefind/linux-arm64": "1.1.0",
"@pagefind/linux-x64": "1.1.0",
"@pagefind/windows-x64": "1.1.0"
}
},
"node_modules/parse-entities": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz",
@ -6845,31 +6730,6 @@
"url": "https://opencollective.com/unified"
}
},
"node_modules/rehype-accessible-emojis": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/rehype-accessible-emojis/-/rehype-accessible-emojis-0.3.2.tgz",
"integrity": "sha512-kChZo+EZsuFQYHUPu6kOZFjDrG7UtQdGxkrCvHBVo9ariKPL6S68QdPVxLxwcAtZSRZIXZhDuTJHgIM8KW24Qw==",
"dependencies": {
"emoji-regex": "^8.0.0",
"gemoji": "^4.2.1",
"hast-util-is-element": "^1.0.3",
"unist-util-flatmap": "^1.0.0"
}
},
"node_modules/rehype-accessible-emojis/node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
"node_modules/rehype-accessible-emojis/node_modules/hast-util-is-element": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-1.1.0.tgz",
"integrity": "sha512-oUmNua0bFbdrD/ELDSSEadRVtWZOf3iF6Lbv81naqsIV99RnSCieTbWuWCY8BAeEfKJTKl0gRdokv+dELutHGQ==",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/rehype-katex": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/rehype-katex/-/rehype-katex-7.0.0.tgz",
@ -7420,20 +7280,6 @@
"is-arrayish": "^0.3.1"
}
},
"node_modules/sirv": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz",
"integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==",
"license": "MIT",
"dependencies": {
"@polka/url": "^1.0.0-next.24",
"mrmime": "^2.0.0",
"totalist": "^3.0.0"
},
"engines": {
"node": ">= 10"
}
},
"node_modules/sisteransi": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
@ -7862,15 +7708,6 @@
"node": ">=8.0"
}
},
"node_modules/totalist": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz",
"integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/trim-lines": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz",
@ -8011,11 +7848,6 @@
"url": "https://opencollective.com/unified"
}
},
"node_modules/unist-util-flatmap": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unist-util-flatmap/-/unist-util-flatmap-1.0.0.tgz",
"integrity": "sha512-IG32jcKJlhARCYT2LsYPJWdoXYkzz3ESAdl1aa2hn9Auh+cgUmU6wgkII4yCc/1GgeWibRdELdCZh/p3QKQ1dQ=="
},
"node_modules/unist-util-is": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz",

View file

@ -2,12 +2,14 @@
"name": "astro-micro",
"type": "module",
"version": "0.0.1",
"private": true,
"scripts": {
"dev": "astro dev",
"start": "astro dev",
"build": "astro check && astro build",
"preview": "astro preview",
"astro": "astro"
"astro": "astro",
"prettier": "prettier --write ."
},
"dependencies": {
"@astrojs/check": "^0.7.0",
@ -19,10 +21,8 @@
"@fontsource/geist-mono": "^5.0.3",
"@fontsource/geist-sans": "^5.0.3",
"astro": "^4.11.3",
"astro-pagefind": "^1.5.0",
"bootstrap-icons": "^1.11.3",
"clsx": "^2.1.1",
"rehype-accessible-emojis": "^0.3.2",
"rehype-katex": "^7.0.0",
"remark-emoji": "^5.0.1",
"remark-math": "^6.0.0",
@ -33,10 +33,26 @@
},
"devDependencies": {
"@tailwindcss/typography": "^0.5.13",
"pagefind": "^1.1.0",
"prettier": "^3.2.5",
"prettier-plugin-astro": "^0.13.0",
"prettier-plugin-organize-imports": "^3.2.4",
"prettier-plugin-tailwindcss": "^0.5.14"
},
"prettier": {
"semi": false,
"singleQuote": true,
"plugins": [
"prettier-plugin-astro",
"prettier-plugin-organize-imports",
"prettier-plugin-tailwindcss"
],
"overrides": [
{
"files": "*.astro",
"options": {
"parser": "astro"
}
}
]
}
}

View file

@ -1 +0,0 @@
{"version":"1.1.0","languages":{"en":{"hash":"en_45ddb13fe8","wasm":"en","page_count":13}}}

File diff suppressed because it is too large Load diff

View file

@ -1,214 +0,0 @@
:root {
--pagefind-ui-scale: 0.8;
--pagefind-ui-primary: #034AD8;
--pagefind-ui-fade: #707070;
--pagefind-ui-text: #393939;
--pagefind-ui-background: #ffffff;
--pagefind-ui-border: #eeeeee;
--pagefind-ui-tag: #eeeeee;
--pagefind-ui-border-width: 2px;
--pagefind-ui-border-radius: 8px;
--pagefind-ui-image-border-radius: 8px;
--pagefind-ui-image-box-ratio: 3 / 2;
--pagefind-ui-font: system, -apple-system, ".SFNSText-Regular",
"San Francisco", "Roboto", "Segoe UI", "Helvetica Neue",
"Lucida Grande", sans-serif;
}
[data-pfmod-hidden] {
display: none !important;
}
[data-pfmod-suppressed] {
opacity: 0 !important;
pointer-events: none !important;
}
[data-pfmod-sr-hidden] {
-webkit-clip: rect(0 0 0 0) !important;
clip: rect(0 0 0 0) !important;
-webkit-clip-path: inset(100%) !important;
clip-path: inset(100%) !important;
height: 1px !important;
overflow: hidden !important;
overflow: clip !important;
position: absolute !important;
white-space: nowrap !important;
width: 1px !important;
}
[data-pfmod-loading] {
color: var(--pagefind-ui-text);
background-color: var(--pagefind-ui-text);
border-radius: var(--pagefind-ui-border-radius);
opacity: 0.1;
pointer-events: none;
}
/* Input */
.pagefind-modular-input-wrapper {
position: relative;
}
.pagefind-modular-input-wrapper::before {
background-color: var(--pagefind-ui-text);
width: calc(18px * var(--pagefind-ui-scale));
height: calc(18px * var(--pagefind-ui-scale));
top: calc(23px * var(--pagefind-ui-scale));
left: calc(20px * var(--pagefind-ui-scale));
content: "";
position: absolute;
display: block;
opacity: 0.7;
-webkit-mask-image: url("data:image/svg+xml,%3Csvg width='18' height='18' viewBox='0 0 18 18' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12.7549 11.255H11.9649L11.6849 10.985C12.6649 9.845 13.2549 8.365 13.2549 6.755C13.2549 3.165 10.3449 0.255005 6.75488 0.255005C3.16488 0.255005 0.254883 3.165 0.254883 6.755C0.254883 10.345 3.16488 13.255 6.75488 13.255C8.36488 13.255 9.84488 12.665 10.9849 11.685L11.2549 11.965V12.755L16.2549 17.745L17.7449 16.255L12.7549 11.255ZM6.75488 11.255C4.26488 11.255 2.25488 9.245 2.25488 6.755C2.25488 4.26501 4.26488 2.255 6.75488 2.255C9.24488 2.255 11.2549 4.26501 11.2549 6.755C11.2549 9.245 9.24488 11.255 6.75488 11.255Z' fill='%23000000'/%3E%3C/svg%3E%0A");
mask-image: url("data:image/svg+xml,%3Csvg width='18' height='18' viewBox='0 0 18 18' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12.7549 11.255H11.9649L11.6849 10.985C12.6649 9.845 13.2549 8.365 13.2549 6.755C13.2549 3.165 10.3449 0.255005 6.75488 0.255005C3.16488 0.255005 0.254883 3.165 0.254883 6.755C0.254883 10.345 3.16488 13.255 6.75488 13.255C8.36488 13.255 9.84488 12.665 10.9849 11.685L11.2549 11.965V12.755L16.2549 17.745L17.7449 16.255L12.7549 11.255ZM6.75488 11.255C4.26488 11.255 2.25488 9.245 2.25488 6.755C2.25488 4.26501 4.26488 2.255 6.75488 2.255C9.24488 2.255 11.2549 4.26501 11.2549 6.755C11.2549 9.245 9.24488 11.255 6.75488 11.255Z' fill='%23000000'/%3E%3C/svg%3E%0A");
-webkit-mask-size: 100%;
mask-size: 100%;
z-index: 9;
pointer-events: none;
}
.pagefind-modular-input {
height: calc(64px * var(--pagefind-ui-scale));
padding: 0 calc(70px * var(--pagefind-ui-scale)) 0 calc(54px * var(--pagefind-ui-scale));
background-color: var(--pagefind-ui-background);
border: var(--pagefind-ui-border-width) solid var(--pagefind-ui-border);
border-radius: var(--pagefind-ui-border-radius);
font-size: calc(21px * var(--pagefind-ui-scale));
position: relative;
appearance: none;
-webkit-appearance: none;
display: flex;
width: 100%;
box-sizing: border-box;
font-weight: 700;
}
.pagefind-modular-input::placeholder {
opacity: 0.2;
}
.pagefind-modular-input-clear {
position: absolute;
top: calc(2px * var(--pagefind-ui-scale));
right: calc(2px * var(--pagefind-ui-scale));
height: calc(60px * var(--pagefind-ui-scale));
border-radius: var(--pagefind-ui-border-radius);
padding: 0 calc(15px * var(--pagefind-ui-scale)) 0 calc(2px * var(--pagefind-ui-scale));
color: var(--pagefind-ui-text);
font-size: calc(14px * var(--pagefind-ui-scale));
cursor: pointer;
background-color: var(--pagefind-ui-background);
border: none;
appearance: none;
}
/* ResultList */
.pagefind-modular-list-result {
list-style-type: none;
display: flex;
align-items: flex-start;
gap: min(calc(40px * var(--pagefind-ui-scale)), 3%);
padding: calc(30px * var(--pagefind-ui-scale)) 0 calc(40px * var(--pagefind-ui-scale));
border-top: solid var(--pagefind-ui-border-width) var(--pagefind-ui-border);
}
.pagefind-modular-list-result:last-of-type {
border-bottom: solid var(--pagefind-ui-border-width) var(--pagefind-ui-border);
}
.pagefind-modular-list-thumb {
width: min(30%,
calc((30% - (100px * var(--pagefind-ui-scale))) * 100000));
max-width: calc(120px * var(--pagefind-ui-scale));
margin-top: calc(10px * var(--pagefind-ui-scale));
aspect-ratio: var(--pagefind-ui-image-box-ratio);
position: relative;
}
.pagefind-modular-list-image {
display: block;
position: absolute;
left: 50%;
transform: translateX(-50%);
font-size: 0;
width: auto;
height: auto;
max-width: 100%;
max-height: 100%;
border-radius: var(--pagefind-ui-image-border-radius);
}
.pagefind-modular-list-inner {
flex: 1;
display: flex;
flex-direction: column;
align-items: flex-start;
margin-top: calc(10px * var(--pagefind-ui-scale));
}
.pagefind-modular-list-title {
display: inline-block;
font-weight: 700;
font-size: calc(21px * var(--pagefind-ui-scale));
margin-top: 0;
margin-bottom: 0;
}
.pagefind-modular-list-link {
color: var(--pagefind-ui-text);
text-decoration: none;
}
.pagefind-modular-list-link:hover {
text-decoration: underline;
}
.pagefind-modular-list-excerpt {
display: inline-block;
font-weight: 400;
font-size: calc(16px * var(--pagefind-ui-scale));
margin-top: calc(4px * var(--pagefind-ui-scale));
margin-bottom: 0;
min-width: calc(250px * var(--pagefind-ui-scale));
}
/* FilterPills */
.pagefind-modular-filter-pills-wrapper {
overflow-x: scroll;
padding: 15px 0;
}
.pagefind-modular-filter-pills {
display: flex;
gap: 6px;
}
.pagefind-modular-filter-pill {
display: flex;
justify-content: center;
align-items: center;
border: none;
appearance: none;
padding: 0 calc(24px * var(--pagefind-ui-scale));
background-color: var(--pagefind-ui-background);
color: var(--pagefind-ui-fade);
border: var(--pagefind-ui-border-width) solid var(--pagefind-ui-border);
border-radius: calc(25px * var(--pagefind-ui-scale));
font-size: calc(18px * var(--pagefind-ui-scale));
height: calc(50px * var(--pagefind-ui-scale));
cursor: pointer;
white-space: nowrap;
}
.pagefind-modular-filter-pill:hover {
border-color: var(--pagefind-ui-primary);
}
.pagefind-modular-filter-pill[aria-pressed="true"] {
border-color: var(--pagefind-ui-primary);
color: var(--pagefind-ui-primary);
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

View file

@ -1,13 +1,13 @@
---
import type { CollectionEntry } from "astro:content";
import type { CollectionEntry } from 'astro:content'
type Props = {
entry: CollectionEntry<"blog">;
};
entry: CollectionEntry<'blog'>
}
const { entry } = Astro.props as {
entry: CollectionEntry<"blog">;
};
entry: CollectionEntry<'blog'>
}
---
<a

View file

@ -1,9 +1,9 @@
---
type Props = {
href: string;
};
href: string
}
const { href } = Astro.props;
const { href } = Astro.props
---
<a

View file

@ -1,23 +1,23 @@
---
export interface Props {
institution: string;
time: string;
job_title: string;
location: string;
description: string
}
const { institution, time, job_title, location, description } = Astro.props;
institution: string
time: string
job_title: string
location: string
description: string
}
const { institution, time, job_title, location, description } = Astro.props
---
<div class="py-5 px-8">
<div class="flex justify-between text-sm font-bold md:text-lg">
<div>{institution}</div>
<div>{location}</div>
</div>
<div class="flex justify-between text-xs md:text-base">
<div class="italic">{job_title}</div>
<div>{time}</div>
</div>
<p class="text-xs mt-2">{description}</p>
</div>
<div class="px-8 py-5">
<div class="flex justify-between text-sm font-bold md:text-lg">
<div>{institution}</div>
<div>{location}</div>
</div>
<div class="flex justify-between text-xs md:text-base">
<div class="italic">{job_title}</div>
<div>{time}</div>
</div>
<p class="mt-2 text-xs">{description}</p>
</div>

View file

@ -1,18 +1,18 @@
---
interface Component {
type: "default" | "info" | "warning" | "error";
type: 'default' | 'info' | 'warning' | 'error'
}
const { type = "default" } = Astro.props;
const { type = 'default' } = Astro.props
let emoji = "💡";
let emoji = '💡'
if (type === "info") {
emoji = "";
} else if (type === "warning") {
emoji = "⚠️";
} else if (type === "error") {
emoji = "🚨";
if (type === 'info') {
emoji = ''
} else if (type === 'warning') {
emoji = '⚠️'
} else if (type === 'error') {
emoji = '🚨'
}
---

View file

@ -1,19 +1,20 @@
---
import Container from "@components/Container.astro";
import { SITE } from "@consts";
import BackToTop from "@components/BackToTop.astro";
import SocialIcons from "./SocialIcons.astro";
import Container from '@components/Container.astro'
import { SITE } from '@consts'
import BackToTop from '@components/BackToTop.astro'
import SocialIcons from './SocialIcons.astro'
---
<footer class="animate">
<Container>
<div class="flex justify-between my-2">
<div class="my-2 flex justify-between">
<SocialIcons icon_size={'text-xl'} />
<BackToTop />
</div>
<div class="flex items-center justify-between">
<div>&copy; {new Date().getFullYear()} • {SITE.TITLE} 👀<br>
Built with Astro
<div>
&copy; {new Date().getFullYear()} • {SITE.TITLE} 👀<br />
Built with Astro
</div>
<div class="flex flex-wrap items-center gap-1.5">
<button

View file

@ -1,17 +1,17 @@
---
interface Props {
date: Date;
date: Date
}
const { date } = Astro.props;
const { date } = Astro.props
---
<time datetime={date.toISOString()}>
{
date.toLocaleDateString("en-US", {
month: "long",
day: "2-digit",
year: "numeric",
date.toLocaleDateString('en-US', {
month: 'long',
day: '2-digit',
year: 'numeric',
})
}
</time>

View file

@ -1,19 +1,19 @@
---
import "../styles/global.css";
import { ViewTransitions } from "astro:transitions";
import '../styles/global.css'
import { ViewTransitions } from 'astro:transitions'
import "@fontsource/geist-sans";
import "@fontsource/geist-mono";
import '@fontsource/geist-sans'
import '@fontsource/geist-mono'
interface Props {
title: string;
description: string;
image?: string;
title: string
description: string
image?: string
}
const canonicalURL = new URL(Astro.url.pathname, Astro.site);
const canonicalURL = new URL(Astro.url.pathname, Astro.site)
const { title, description, image = "/blog-placeholder-1.jpg" } = Astro.props;
const { title, description, image = '/blog-placeholder-1.jpg' } = Astro.props
---
<!-- Global Metadata -->
@ -48,116 +48,112 @@ const { title, description, image = "/blog-placeholder-1.jpg" } = Astro.props;
<meta property="twitter:description" content={description} />
<meta property="twitter:image" content={new URL(image, Astro.url)} />
<!-- PageFind -->
<link href="/pagefind/pagefind-ui.css" rel="stylesheet" />
<script is:inline src="/pagefind/pagefind-ui.js"></script>
<ViewTransitions />
<script is:inline>
function init() {
preloadTheme();
onScroll();
animate();
updateThemeButtons();
addCopyCodeButtons();
setGiscusTheme();
preloadTheme()
onScroll()
animate()
updateThemeButtons()
addCopyCodeButtons()
setGiscusTheme()
const backToTop = document.getElementById("back-to-top");
backToTop?.addEventListener("click", (event) => scrollToTop(event));
const backToTop = document.getElementById('back-to-top')
backToTop?.addEventListener('click', (event) => scrollToTop(event))
const backToPrev = document.getElementById("back-to-prev");
backToPrev?.addEventListener("click", () => window.history.back());
const backToPrev = document.getElementById('back-to-prev')
backToPrev?.addEventListener('click', () => window.history.back())
const lightThemeButton = document.getElementById("light-theme-button");
lightThemeButton?.addEventListener("click", () => {
localStorage.setItem("theme", "light");
toggleTheme(false);
updateThemeButtons();
});
const lightThemeButton = document.getElementById('light-theme-button')
lightThemeButton?.addEventListener('click', () => {
localStorage.setItem('theme', 'light')
toggleTheme(false)
updateThemeButtons()
})
const darkThemeButton = document.getElementById("dark-theme-button");
darkThemeButton?.addEventListener("click", () => {
localStorage.setItem("theme", "dark");
toggleTheme(true);
updateThemeButtons();
});
const darkThemeButton = document.getElementById('dark-theme-button')
darkThemeButton?.addEventListener('click', () => {
localStorage.setItem('theme', 'dark')
toggleTheme(true)
updateThemeButtons()
})
const systemThemeButton = document.getElementById("system-theme-button");
systemThemeButton?.addEventListener("click", () => {
localStorage.setItem("theme", "system");
toggleTheme(window.matchMedia("(prefers-color-scheme: dark)").matches);
updateThemeButtons();
});
const systemThemeButton = document.getElementById('system-theme-button')
systemThemeButton?.addEventListener('click', () => {
localStorage.setItem('theme', 'system')
toggleTheme(window.matchMedia('(prefers-color-scheme: dark)').matches)
updateThemeButtons()
})
window
.matchMedia("(prefers-color-scheme: dark)")
.addEventListener("change", (event) => {
if (localStorage.theme === "system") {
toggleTheme(event.matches);
.matchMedia('(prefers-color-scheme: dark)')
.addEventListener('change', (event) => {
if (localStorage.theme === 'system') {
toggleTheme(event.matches)
}
});
})
document.addEventListener("scroll", onScroll);
document.addEventListener('scroll', onScroll)
}
function updateThemeButtons() {
const theme = localStorage.getItem("theme");
const lightThemeButton = document.getElementById("light-theme-button");
const darkThemeButton = document.getElementById("dark-theme-button");
const systemThemeButton = document.getElementById("system-theme-button");
const theme = localStorage.getItem('theme')
const lightThemeButton = document.getElementById('light-theme-button')
const darkThemeButton = document.getElementById('dark-theme-button')
const systemThemeButton = document.getElementById('system-theme-button')
function removeActiveButtonTheme(button) {
button?.classList.remove("bg-black/5");
button?.classList.remove("dark:bg-white/5");
button?.classList.remove('bg-black/5')
button?.classList.remove('dark:bg-white/5')
}
function addActiveButtonTheme(button) {
button?.classList.add("bg-black/5");
button?.classList.add("dark:bg-white/5");
button?.classList.add('bg-black/5')
button?.classList.add('dark:bg-white/5')
}
removeActiveButtonTheme(lightThemeButton);
removeActiveButtonTheme(darkThemeButton);
removeActiveButtonTheme(systemThemeButton);
removeActiveButtonTheme(lightThemeButton)
removeActiveButtonTheme(darkThemeButton)
removeActiveButtonTheme(systemThemeButton)
if (theme === "light") {
addActiveButtonTheme(lightThemeButton);
} else if (theme === "dark") {
addActiveButtonTheme(darkThemeButton);
if (theme === 'light') {
addActiveButtonTheme(lightThemeButton)
} else if (theme === 'dark') {
addActiveButtonTheme(darkThemeButton)
} else {
addActiveButtonTheme(systemThemeButton);
addActiveButtonTheme(systemThemeButton)
}
}
function animate() {
const animateElements = document.querySelectorAll(".animate");
const animateElements = document.querySelectorAll('.animate')
animateElements.forEach((element, index) => {
setTimeout(() => {
element.classList.add("show");
}, index * 100);
});
element.classList.add('show')
}, index * 100)
})
}
function onScroll() {
if (window.scrollY > 0) {
document.documentElement.classList.add("scrolled");
document.documentElement.classList.add('scrolled')
} else {
document.documentElement.classList.remove("scrolled");
document.documentElement.classList.remove('scrolled')
}
}
function scrollToTop(event) {
event.preventDefault();
event.preventDefault()
window.scrollTo({
top: 0,
behavior: "smooth",
});
behavior: 'smooth',
})
}
function toggleTheme(dark) {
const css = document.createElement("style");
const css = document.createElement('style')
css.appendChild(
document.createTextNode(
@ -168,84 +164,84 @@ const { title, description, image = "/blog-placeholder-1.jpg" } = Astro.props;
-ms-transition: none !important;
transition: none !important;
}
`
)
);
`,
),
)
document.head.appendChild(css);
document.head.appendChild(css)
if (dark) {
document.documentElement.classList.add("dark");
document.documentElement.classList.add('dark')
} else {
document.documentElement.classList.remove("dark");
document.documentElement.classList.remove('dark')
}
window.getComputedStyle(css).opacity;
document.head.removeChild(css);
window.getComputedStyle(css).opacity
document.head.removeChild(css)
setGiscusTheme();
setGiscusTheme()
}
function preloadTheme() {
const userTheme = localStorage.theme;
const userTheme = localStorage.theme
if (userTheme === "light" || userTheme === "dark") {
toggleTheme(true); // set default to dark theme
if (userTheme === 'light' || userTheme === 'dark') {
toggleTheme(true) // set default to dark theme
} else {
toggleTheme(window.matchMedia("(prefers-color-scheme: dark)").matches);
toggleTheme(window.matchMedia('(prefers-color-scheme: dark)').matches)
}
}
function addCopyCodeButtons() {
let copyButtonLabel = "📋";
let codeBlocks = Array.from(document.querySelectorAll("pre"));
let copyButtonLabel = '📋'
let codeBlocks = Array.from(document.querySelectorAll('pre'))
async function copyCode(codeBlock, copyButton) {
const codeText = codeBlock.innerText;
const buttonText = copyButton.innerText;
const textToCopy = codeText.replace(buttonText, "");
const codeText = codeBlock.innerText
const buttonText = copyButton.innerText
const textToCopy = codeText.replace(buttonText, '')
await navigator.clipboard.writeText(textToCopy);
copyButton.innerText = "✅";
await navigator.clipboard.writeText(textToCopy)
copyButton.innerText = '✅'
setTimeout(() => {
copyButton.innerText = copyButtonLabel;
}, 2000);
copyButton.innerText = copyButtonLabel
}, 2000)
}
for (let codeBlock of codeBlocks) {
const wrapper = document.createElement("div");
wrapper.style.position = "relative";
const wrapper = document.createElement('div')
wrapper.style.position = 'relative'
const copyButton = document.createElement("button");
copyButton.innerText = copyButtonLabel;
copyButton.classList = "copy-code";
const copyButton = document.createElement('button')
copyButton.innerText = copyButtonLabel
copyButton.classList = 'copy-code'
codeBlock.setAttribute("tabindex", "0");
codeBlock.appendChild(copyButton);
codeBlock.setAttribute('tabindex', '0')
codeBlock.appendChild(copyButton)
codeBlock.parentNode.insertBefore(wrapper, codeBlock);
wrapper.appendChild(codeBlock);
codeBlock.parentNode.insertBefore(wrapper, codeBlock)
wrapper.appendChild(codeBlock)
copyButton?.addEventListener("click", async () => {
await copyCode(codeBlock, copyButton);
});
copyButton?.addEventListener('click', async () => {
await copyCode(codeBlock, copyButton)
})
}
}
const setGiscusTheme = () => {
const giscus = document.querySelector(".giscus-frame");
const giscus = document.querySelector('.giscus-frame')
const isDark = document.documentElement.classList.contains("dark");
const isDark = document.documentElement.classList.contains('dark')
if (giscus) {
const url = new URL(giscus.src);
url.searchParams.set("theme", isDark ? "dark" : "light");
giscus.src = url.toString();
const url = new URL(giscus.src)
url.searchParams.set('theme', isDark ? 'dark' : 'light')
giscus.src = url.toString()
}
};
}
document.addEventListener("DOMContentLoaded", () => init());
document.addEventListener("astro:after-swap", () => init());
preloadTheme();
document.addEventListener('DOMContentLoaded', () => init())
document.addEventListener('astro:after-swap', () => init())
preloadTheme()
</script>

View file

@ -1,8 +1,8 @@
---
import Container from "@components/Container.astro";
import Link from "@components/Link.astro";
import { SITE } from "@consts";
import ProgressBar from "./ProgressBar.astro";
import Container from '@components/Container.astro'
import Link from '@components/Link.astro'
import { SITE } from '@consts'
import ProgressBar from './ProgressBar.astro'
---
<header transition:persist>

View file

@ -1,29 +1,23 @@
---
import { cn } from "@lib/utils";
import { cn } from '@lib/utils'
type Props = {
href: string;
external?: boolean;
underline?: boolean;
group?: boolean;
};
href: string
external?: boolean
underline?: boolean
group?: boolean
}
const {
href,
external,
underline = true,
group = false,
...rest
} = Astro.props;
const { href, external, underline = true, group = false, ...rest } = Astro.props
---
<a
href={href}
target={external ? "_blank" : "_self"}
target={external ? '_blank' : '_self'}
class={cn(
"inline-block decoration-black/30 hover:decoration-black/50 focus-visible:decoration-black/50 dark:decoration-white/30 dark:hover:decoration-white/50 dark:focus-visible:decoration-white/50 hover:text-cyan-500 focus-visible:text-black dark:hover:text-orange-500 dark:focus-visible:text-white transition-colors duration-300 ease-in-out",
underline && "underline underline-offset-[3px]",
group && "group"
'inline-block decoration-black/30 hover:decoration-black/50 focus-visible:decoration-black/50 dark:decoration-white/30 dark:hover:decoration-white/50 dark:focus-visible:decoration-white/50 hover:text-cyan-500 focus-visible:text-black dark:hover:text-orange-500 dark:focus-visible:text-white transition-colors duration-300 ease-in-out',
underline && 'underline underline-offset-[3px]',
group && 'group',
)}
{...rest}
>

View file

@ -1,132 +0,0 @@
---
import Search from "astro-pagefind/components/Search";
---
<aside data-pagefind-ignore>
<div
transition:persist
id="backdrop"
class="bg-[rgba(0, 0, 0, 0.5] invisible fixed left-0 top-0 z-50 flex h-screen w-full justify-center p-6 backdrop-blur-sm"
>
<div
id="pagefind-container"
class="m-0 flex h-fit max-h-[80%] w-full max-w-screen-sm flex-col overflow-auto rounded border border-black/15 bg-neutral-100 p-2 px-4 py-3 shadow-lg dark:border-white/20 dark:bg-neutral-900"
>
<Search
id="search"
className="pagefind-ui"
uiOptions={{
showImages: false,
excerptLength: 15,
resetStyles: false,
}}
/>
<div class="mr-2 pb-1 pt-4 text-right text-xs dark:prose-invert">
Press <span class="prose text-xs dark:prose-invert"
><kbd class="">Esc</kbd></span
> or click anywhere to close
</div>
</div>
</div>
</aside>
<script is:inline>
const magnifyingGlass = document.getElementById("magnifying-glass");
const backdrop = document.getElementById("backdrop");
function openPagefind() {
const searchDiv = document.getElementById("search");
const search = searchDiv.querySelector("input");
setTimeout(() => {
search.focus();
}, 0);
backdrop?.classList.remove("invisible");
backdrop?.classList.add("visible");
}
function closePagefind() {
const search = document.getElementById("search");
search.value = "";
backdrop?.classList.remove("visible");
backdrop?.classList.add("invisible");
}
// open pagefind
magnifyingGlass?.addEventListener("click", () => {
openPagefind();
});
document.addEventListener("keydown", (e) => {
if (e.key === "/") {
e.preventDefault();
openPagefind();
} else if ((e.metaKey || e.ctrlKey) && e.key === "k") {
e.preventDefault();
openPagefind();
}
});
// close pagefind
document.addEventListener("keydown", (e) => {
if (e.key === "Escape" || e.keyCode === 27) {
closePagefind();
}
});
// close pagefind when searched result(link) clicked
document.addEventListener("click", (event) => {
if (event.target.classList.contains("pagefind-ui__result-link")) {
closePagefind();
}
});
backdrop?.addEventListener("click", (event) => {
if (!event.target.closest("#pagefind-container")) {
closePagefind();
}
});
// prevent form submission
const form = document.getElementById("form");
form?.addEventListener("submit", (event) => {
event.preventDefault();
});
</script>
<style is:global>
:root {
--pagefind-ui-scale: 0.75;
--pagefind-ui-border-width: 1px;
--pagefind-ui-border-radius: 3px;
--pagefind-ui-font: "Geist", sans-serif;
--pagefind-ui-primary: #3d3d3d;
--pagefind-ui-text: #3d3d3d;
--pagefind-ui-background: #ffffff;
--pagefind-ui-border: #d0d0d0;
--pagefind-ui-tag: #f5f5f5;
}
.dark {
--pagefind-ui-primary: #d4d4d4;
--pagefind-ui-text: #d4d4d4;
--pagefind-ui-background: #171717;
--pagefind-ui-border: #404040;
}
#search input {
font-weight: normal;
}
#search p {
font-weight: normal;
}
#search .pagefind-ui__result-title {
font-weight: 600;
}
#search .pagefind-ui__message {
padding: 0;
padding-bottom: 0.75rem;
}
</style>

View file

@ -1,5 +1,5 @@
---
const { prevPost, nextPost } = Astro.props;
const { prevPost, nextPost } = Astro.props
---
<div class="grid grid-cols-2 gap-1.5 sm:gap-3">

View file

@ -1,9 +1,8 @@
<div class="fixed w-full h-[2px] bg-neutral-300 dark:bg-slate-900 z-50">
<div class="bg-cyan-500 dark:bg-orange-500 h-full"></div>
<div class="fixed z-50 h-[2px] w-full bg-neutral-300 dark:bg-slate-900">
<div class="h-full bg-cyan-500 dark:bg-orange-500"></div>
</div>
<script>
import { initializeProgressBar } from '../scripts/progress-bar.js';
initializeProgressBar();
import { initializeProgressBar } from '../scripts/progress-bar.js'
initializeProgressBar()
</script>

View file

@ -1,74 +1,118 @@
---
import type { CollectionEntry } from "astro:content";
import { Image } from "astro:assets";
import { HIGHLIGHTAUTHOR } from "@consts";
import type { CollectionEntry } from 'astro:content'
import { Image } from 'astro:assets'
import { HIGHLIGHTAUTHOR } from '@consts'
type Props = {
entry: CollectionEntry<"publications">;
};
entry: CollectionEntry<'publications'>
}
const { entry } = Astro.props as {
entry: CollectionEntry<"publications">;
};
entry: CollectionEntry<'publications'>
}
const splitStr = (authors: string | undefined, targetAuthor: string) => {
if (!authors) return [];
const parts = authors.split(new RegExp(`(${targetAuthor})`, 'g'));
return parts;
};
if (!authors) return []
const parts = authors.split(new RegExp(`(${targetAuthor})`, 'g'))
return parts
}
const decomposeURL = (URL: string | undefined) => {
if (!URL) return { text: '', url: '' };
const parts = URL.split(": ");
return { text: parts[0], url: parts[1] };
};
const dataLink = decomposeURL(entry.data.dataURL);
const paperLink = decomposeURL(entry.data.paperURL);
const codeLink = decomposeURL(entry.data.codeURL);
const webLink = decomposeURL(entry.data.webURL);
const authorsParts = splitStr(entry.data.authors, HIGHLIGHTAUTHOR);
if (!URL) return { text: '', url: '' }
const parts = URL.split(': ')
return { text: parts[0], url: parts[1] }
}
const dataLink = decomposeURL(entry.data.dataURL)
const paperLink = decomposeURL(entry.data.paperURL)
const codeLink = decomposeURL(entry.data.codeURL)
const webLink = decomposeURL(entry.data.webURL)
const authorsParts = splitStr(entry.data.authors, HIGHLIGHTAUTHOR)
---
<div
class="w-full not-prose group relative grid grid-cols-auto md:grid-cols-[204px_auto] gap-4 rounded-lg items-center border border-black/15 px-4 py-3 transition-colors duration-300 ease-in-out hover:bg-black/5 hover:text-black focus-visible:bg-black/5 focus-visible:text-black dark:border-white/20 dark:hover:bg-white/5 dark:hover:text-white dark:focus-visible:bg-white/5 dark:focus-visible:text-white"
class="not-prose grid-cols-auto group relative grid w-full items-center gap-4 rounded-lg border border-black/15 px-4 py-3 transition-colors duration-300 ease-in-out hover:bg-black/5 hover:text-black focus-visible:bg-black/5 focus-visible:text-black dark:border-white/20 dark:hover:bg-white/5 dark:hover:text-white dark:focus-visible:bg-white/5 dark:focus-visible:text-white md:grid-cols-[204px_auto]"
>
<Image
src={entry.data.img ?? ''}
alt={entry.data.imgAlt ?? ''}
width={640}
height={480}
class="sm:w-[240px] sm:h-[135px] shadow-sm rounded-md sm:mr-6 hover:opacity-80 transition hidden md:flex"
loading="eager"
src={entry.data.img ?? ''}
alt={entry.data.imgAlt ?? ''}
width={640}
height={480}
class="hidden rounded-md shadow-sm transition hover:opacity-80 sm:mr-6 sm:h-[135px] sm:w-[240px] md:flex"
loading="eager"
/>
<div class="flex items-center h-full">
<div class="flex h-full items-center">
<div class="flex flex-col">
<div class="w-full">
<div class="text-md font-semibold w-full">
<div class="text-md w-full font-semibold">
{entry.data.title}
</div>
<div class="text-sm w-full">
{authorsParts.map((part:any) =>
part === HIGHLIGHTAUTHOR ? <u><strong>{part}</strong></u> : part
)}
<div class="w-full text-sm">
{
authorsParts.map((part: any) =>
part === HIGHLIGHTAUTHOR ? (
<u>
<strong>{part}</strong>
</u>
) : (
part
),
)
}
</div>
<div class="text-sm w-full">
{paperLink.url!="" && <a class="underline hover:text-cyan-500 text-orange-500 dark:hover:text-cyan-500 transition-colors duration-300 ease-in-out visited:text-indigo-400" target="_blank" href={paperLink.url}>{paperLink.text}</a>}
{codeLink.url!="" && <a class="underline hover:text-cyan-500 text-orange-500 dark:hover:text-cyan-500 transition-colors duration-300 ease-in-out visited:text-indigo-400" target="_blank" href={codeLink.url}>{codeLink.text}</a>}
{webLink.url!="" && <a class="underline hover:text-cyan-500 text-orange-500 dark:hover:text-cyan-500 transition-colors duration-300 ease-in-out visited:text-indigo-400" target="_blank" href={webLink.url}>{webLink.text}</a>}
{dataLink.url!="" && <a class="underline hover:text-cyan-500 text-orange-500 dark:hover:text-cyan-500 transition-colors duration-300 ease-in-out visited:text-indigo-400" target="_blank" href={dataLink.url}>{dataLink.text}</a>}
<div class="w-full text-sm">
{
paperLink.url != '' && (
<a
class="text-orange-500 underline transition-colors duration-300 ease-in-out visited:text-indigo-400 hover:text-cyan-500 dark:hover:text-cyan-500"
target="_blank"
href={paperLink.url}
>
{paperLink.text}
</a>
)
}
{
codeLink.url != '' && (
<a
class="text-orange-500 underline transition-colors duration-300 ease-in-out visited:text-indigo-400 hover:text-cyan-500 dark:hover:text-cyan-500"
target="_blank"
href={codeLink.url}
>
{codeLink.text}
</a>
)
}
{
webLink.url != '' && (
<a
class="text-orange-500 underline transition-colors duration-300 ease-in-out visited:text-indigo-400 hover:text-cyan-500 dark:hover:text-cyan-500"
target="_blank"
href={webLink.url}
>
{webLink.text}
</a>
)
}
{
dataLink.url != '' && (
<a
class="text-orange-500 underline transition-colors duration-300 ease-in-out visited:text-indigo-400 hover:text-cyan-500 dark:hover:text-cyan-500"
target="_blank"
href={dataLink.url}
>
{dataLink.text}
</a>
)
}
</div>
<div class="text-sm">
In <div class="inline italic">{entry.data.pub}</div>
</div>
</div>
<p class="text-sm mt-2 break-words">
<p class="mt-2 break-words text-sm">
{entry.data.description}
</p>
</div>
</div>
</div>

View file

@ -1,18 +1,19 @@
---
import 'bootstrap-icons/font/bootstrap-icons.css';
import 'bootstrap-icons/font/bootstrap-icons.css'
export interface Props {
URL: string;
icon: string;
icon_size: string
URL: string
icon: string
icon_size: string
}
const { URL, icon, icon_size } = Astro.props;
const { URL, icon, icon_size } = Astro.props
---
<a
href={URL}
target={"_blank"}
class={
`inline-block ${icon_size} decoration-black/30 dark:decoration-white/30 hover:decoration-black/50 focus-visible:decoration-black/50 dark:hover:decoration-white/50 dark:focus-visible:decoration-white/50 text-current hover:text-cyan-500 focus-visible:text-black dark:hover:text-orange-500 dark:focus-visible:text-white transition-colors duration-300 ease-in-out`}>
<i class={`bi bi-${icon}`}></i>
</a>
href={URL}
target={'_blank'}
class={`inline-block ${icon_size} decoration-black/30 dark:decoration-white/30 hover:decoration-black/50 focus-visible:decoration-black/50 dark:hover:decoration-white/50 dark:focus-visible:decoration-white/50 text-current hover:text-cyan-500 focus-visible:text-black dark:hover:text-orange-500 dark:focus-visible:text-white transition-colors duration-300 ease-in-out`}
>
<i class={`bi bi-${icon}`}></i>
</a>

View file

@ -1,18 +1,23 @@
---
import SocialIcon from "@components/SocialIcon.astro";
import { SITE } from "@consts";
import SocialIcon from '@components/SocialIcon.astro'
import { SITE } from '@consts'
export interface Props {
icon_size: string
icon_size: string
}
const { icon_size } = Astro.props;
const { icon_size } = Astro.props
---
<ul class="not-prose flex flex-wrap gap-2">
<SocialIcon icon_size={icon_size} URL="#" icon="twitter-x"/>
<SocialIcon icon_size={icon_size} URL="#" icon="github"/>
<SocialIcon icon_size={icon_size} URL="#" icon="linkedin"/>
<SocialIcon icon_size={icon_size} URL="#" icon="envelope-fill"/>
<SocialIcon icon_size={icon_size} URL="#" icon="mortarboard-fill"/>
<SocialIcon icon_size={icon_size} URL={`${SITE.SITEURL}/rss.xml`} icon="rss-fill"/>
</ul>
<SocialIcon icon_size={icon_size} URL="#" icon="twitter-x" />
<SocialIcon icon_size={icon_size} URL="#" icon="github" />
<SocialIcon icon_size={icon_size} URL="#" icon="linkedin" />
<SocialIcon icon_size={icon_size} URL="#" icon="envelope-fill" />
<SocialIcon icon_size={icon_size} URL="#" icon="mortarboard-fill" />
<SocialIcon
icon_size={icon_size}
URL={`${SITE.SITEURL}/rss.xml`}
icon="rss-fill"
/>
</ul>

View file

@ -1,29 +1,29 @@
---
import TableOfContentsHeading from "./TableOfContentsHeading.astro";
import TableOfContentsHeading from './TableOfContentsHeading.astro'
// https://kld.dev/building-table-of-contents/
const { headings } = Astro.props;
const toc = buildToc(headings);
const { headings } = Astro.props
const toc = buildToc(headings)
export interface Heading {
depth: number;
slug: string;
text: string;
depth: number
slug: string
text: string
}
function buildToc(headings: Heading[]) {
const toc: Heading[] = [];
const parentHeadings = new Map();
const toc: Heading[] = []
const parentHeadings = new Map()
headings.forEach((h) => {
const heading = { ...h, subheadings: [] };
parentHeadings.set(heading.depth, heading);
const heading = { ...h, subheadings: [] }
parentHeadings.set(heading.depth, heading)
if (heading.depth === 2) {
toc.push(heading);
toc.push(heading)
} else {
parentHeadings.get(heading.depth - 1).subheadings.push(heading);
parentHeadings.get(heading.depth - 1).subheadings.push(heading)
}
});
return toc;
})
return toc
}
---

View file

@ -1,14 +1,14 @@
---
import type { Heading } from "./TableOfContents.astro";
import Link from "./Link.astro";
import type { Heading } from './TableOfContents.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">
<Link href={"#" + heading.slug} underline>
<Link href={'#' + heading.slug} underline>
{heading.text}
</Link>
{

View file

@ -1,46 +1,43 @@
import type { Metadata, Site } from "@types";
import type { Metadata, Site } from '@types'
export const SITE: Site = {
TITLE: "Astro Micro Academics",
DESCRIPTION: "Astro Micro Academics is for academic user.",
EMAIL: "youremial@gmail.com",
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
};
SITEURL: 'https://astro-micro-academic.vercel.app', // Update here to link the RSS icon to your website rss
}
export const HIGHLIGHTAUTHOR = "John B"
export const HIGHLIGHTAUTHOR = 'John B'
export const HOME: Metadata = {
TITLE: "Home",
DESCRIPTION: "Astro Micro is an accessible theme for Astro.",
};
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.",
};
TITLE: 'Blog',
DESCRIPTION: 'A collection of articles on topics I am passionate about.',
}
export const RESEARCH: Metadata = {
TITLE: "Publications",
TITLE: 'Publications',
DESCRIPTION:
"A collection of my publications with links to paper, repositories and live demos.",
};
'A collection of my publications with links to paper, repositories and live demos.',
}
export const CV: Metadata = {
TITLE: "CV",
DESCRIPTION:
"your cv",
};
TITLE: 'CV',
DESCRIPTION: 'your cv',
}
export const TAGS: Metadata = {
TITLE: "TAGS",
DESCRIPTION:
"blog tag filter",
};
TITLE: 'TAGS',
DESCRIPTION: 'blog tag filter',
}
export const ABOUT: Metadata = {
TITLE: "ABOUT",
DESCRIPTION:
"A self-intro",
};
TITLE: 'ABOUT',
DESCRIPTION: 'A self-intro',
}

View file

@ -1,11 +1,11 @@
---
title: "[Logs] What is new in Astro Micro Academic"
description: "Features, enhancements, and changes."
date: "2024-07-25"
title: '[Logs] What is new in Astro Micro Academic'
description: 'Features, enhancements, and changes.'
date: '2024-07-25'
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.
:exclamation: Also refer to [Old] posts to see examples and changes. Some changes are removed in this version, which are marked.
## What is New
@ -13,18 +13,18 @@ tags: ['log', 'rss-feed']
- Add News, Research, Publication, CV sections
- add icon to connect section
- Add tag function to the blog
- add RSS Feed icon
- 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
- 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
- Clear and rearrange all the posts
- [x] rewrite astro-micro-academics
- [x] astro micro
- [x] get started with astro micro
- [x] blog collection example
---
@ -32,9 +32,9 @@ tags: ['log', 'rss-feed']
- Add Group Page
- Add Opening Section
- Add Award Page
- Write a complete personal website setup guide
- screenshot and submit theme to astro
- 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
@ -48,4 +48,5 @@ a = \sum_{n=1}^{22} \sqrt{a+b_n}
$$
## 中文测试
这里是中文测试
这里是中文测试

View file

@ -1,13 +1,13 @@
---
title: "[Tutorial] Getting started with Astro-Micro-Academics"
description: "Hit the ground running."
date: "2024-07-26"
title: '[Tutorial] Getting started with Astro-Micro-Academics'
description: 'Hit the ground running.'
date: '2024-07-26'
tags: ['guide', 'tutorial']
---
:exclamation: Also refer to [Old] posts to see examples and changes. Some changes are removed in this version, which are marked.
:exclamation: Also refer to [Old] posts to see examples and changes. Some changes are removed in this version, which are marked.
## Install Astro-Micro-Academics
## Install Astro-Micro-Academics
Clone the [repository](https://github.com/jingwu2121/astro-micro-academic).
@ -24,6 +24,7 @@ npm i
```
Run local server
```sh
npm run dev
```
@ -32,55 +33,72 @@ npm run dev
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"},
{
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"},
{
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`.
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.
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"
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 |
| 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
@ -88,11 +106,11 @@ Metadata is required for each post.
```astro
---
title: "Blog Collection";
description: "How to add posts to the blog.";
date: "2024-03-21";
title: 'Blog Collection'
description: 'How to add posts to the blog.'
date: '2024-03-21'
tags: ['guide', 'tutorial']
draft: false;
draft: false
---
```
@ -101,10 +119,10 @@ draft: false;
| 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 |
| 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
## Customize the website metadata and set up RSS
To change the website metadata, edit `src/consts.ts`.
@ -112,27 +130,27 @@ To change the website metadata, edit `src/consts.ts`.
// src/consts.ts
export const SITE: Site = {
TITLE: "Astro Micro Academics",
DESCRIPTION: "Astro Micro Academics is for academic user.",
EMAIL: "youremial@gmail.com",
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
};
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. |
| 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 |
| 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.
Please tag the post of RSS feed with tag `"rss-feed"`, other posts are not included in the RSS.
---
@ -141,7 +159,7 @@ Please tag the post of RSS feed with tag `"rss-feed"`, other posts are not inclu
```ts
// src/consts.ts
export const HIGHLIGHTAUTHOR = "John B"
export const HIGHLIGHTAUTHOR = 'John B'
```
## Customize metadata for individual pages
@ -150,38 +168,35 @@ export const HIGHLIGHTAUTHOR = "John B"
// src/consts.ts
export const HOME: Metadata = {
TITLE: "Home",
DESCRIPTION: "Astro Micro is an accessible theme for Astro.",
};
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.",
};
TITLE: 'Blog',
DESCRIPTION: 'A collection of articles on topics I am passionate about.',
}
export const RESEARCH: Metadata = {
TITLE: "Publications",
TITLE: 'Publications',
DESCRIPTION:
"A collection of my publications with links to paper, repositories and live demos.",
};
'A collection of my publications with links to paper, repositories and live demos.',
}
export const CV: Metadata = {
TITLE: "CV",
DESCRIPTION:
"your cv",
};
TITLE: 'CV',
DESCRIPTION: 'your cv',
}
export const TAGS: Metadata = {
TITLE: "TAGS",
DESCRIPTION:
"blog tag filter",
};
TITLE: 'TAGS',
DESCRIPTION: 'blog tag filter',
}
export const ABOUT: Metadata = {
TITLE: "ABOUT",
DESCRIPTION:
"A self-intro",
};
TITLE: 'ABOUT',
DESCRIPTION: 'A self-intro',
}
```
| Field | Req | Description |
@ -206,12 +221,11 @@ To set up RSS and Giscus, it's easier if the site is deployed and has a URL for
To deploy manually see [Astro's docs](https://docs.astro.build/en/guides/deploy/).
To deploy to Github, see [here](https://docs.astro.build/en/guides/deploy/github/).
To deploy to Github, see [here](https://docs.astro.build/en/guides/deploy/github/).
## Set up Giscus (from Astro Micro)
Follow the steps at [giscus.app](https://giscus.app). Once you get your custom Giscus script from that site, go to `Giscus.astro` and replace that script with your own.
Follow the steps at [giscus.app](https://giscus.app). Once you get your custom Giscus script from that site, go to `Giscus.astro` and replace that script with your own.
```js
// src/components/Giscus.astro
@ -232,8 +246,8 @@ Follow the steps at [giscus.app](https://giscus.app). Once you get your custom
data-lang="en"
data-loading="lazy"
crossorigin="anonymous"
async></script>
async
></script>
```
To change the Giscus themes used, edit the `setGiscusTheme` function in `Head.astro`.
@ -242,15 +256,15 @@ To change the Giscus themes used, edit the `setGiscusTheme` function in `Head.as
// src/components/Head.astro
const setGiscusTheme = () => {
const giscus = document.querySelector(".giscus-frame");
const giscus = document.querySelector('.giscus-frame')
const isDark = document.documentElement.classList.contains("dark");
const isDark = document.documentElement.classList.contains('dark')
if (giscus) {
const url = new URL(giscus.src);
const url = new URL(giscus.src)
// Change "dark" and "light" to other Giscus themes
url.searchParams.set("theme", isDark ? "dark" : "light");
giscus.src = url.toString();
url.searchParams.set('theme', isDark ? 'dark' : 'light')
giscus.src = url.toString()
}
};
}
```

View file

@ -1,11 +1,11 @@
---
title: "[Old] Everything new in Astro Micro"
description: "Features, enhancements, and changes."
date: "2024-05-09"
title: '[Old] Everything new in Astro Micro'
description: 'Features, enhancements, and changes.'
date: '2024-05-09'
tags: ['astro-micro']
---
import Callout from "@/components/Callout.astro";
import Callout from '@/components/Callout.astro'
---

View file

@ -1,7 +1,7 @@
---
title: "[Old] Getting started with Astro-Micro"
description: "Hit the ground running."
date: "2024-03-22"
title: '[Old] Getting started with Astro-Micro'
description: 'Hit the ground running.'
date: '2024-03-22'
tags: ['guide', 'start']
---
@ -39,20 +39,20 @@ To change the website metadata, edit `src/consts.ts`.
// src/consts.ts
export const SITE: Site = {
NAME: "Astro Micro",
DESCRIPTION: "Astro Micro is an accessible theme for Astro.",
EMAIL: "trevortylerlee@gmail.com",
NAME: 'Astro Micro',
DESCRIPTION: 'Astro Micro is an accessible theme for Astro.',
EMAIL: 'trevortylerlee@gmail.com',
NUM_POSTS_ON_HOMEPAGE: 3,
NUM_PUBLICATIONS_ON_HOMEPAGE: 3,
};
}
```
| 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. |
| 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. |
---
@ -63,9 +63,9 @@ export const SITE: Site = {
// src/consts.ts
export const ABOUT: Metadata = {
TITLE: "About",
DESCRIPTION: "Astro Micro is a fork of Astro Nano.",
};
TITLE: 'About',
DESCRIPTION: 'Astro Micro is a fork of Astro Nano.',
}
```
| Field | Req | Description |
@ -82,18 +82,18 @@ export const ABOUT: Metadata = {
export const SOCIALS: Socials = [
{
NAME: "twitter-x",
HREF: "https://twitter.com/boogerbuttcheeks",
NAME: 'twitter-x',
HREF: 'https://twitter.com/boogerbuttcheeks',
},
{
NAME: "github",
HREF: "https://github.com/trevortylerlee",
NAME: 'github',
HREF: 'https://github.com/trevortylerlee',
},
{
NAME: "linkedin",
HREF: "https://www.linkedin.com/in/trevortylerlee",
NAME: 'linkedin',
HREF: 'https://www.linkedin.com/in/trevortylerlee',
},
];
]
```
| Field | Req | Description |
@ -124,19 +124,19 @@ Change the `site` option to the deployed site's URL.
// astro.config.mjs
export default defineConfig({
site: "https://astro-micro.vercel.app",
site: 'https://astro-micro.vercel.app',
integrations: [tailwind(), sitemap(), mdx(), pagefind()],
markdown: {
shikiConfig: {
theme: "css-variables",
theme: 'css-variables',
},
},
});
})
```
## Set up Giscus
Follow the steps at [giscus.app](https://giscus.app). Once you get your custom Giscus script from that site, go to `Giscus.astro` and replace that script with your own.
Follow the steps at [giscus.app](https://giscus.app). Once you get your custom Giscus script from that site, go to `Giscus.astro` and replace that script with your own.
```js
// src/components/Giscus.astro
@ -157,8 +157,8 @@ Follow the steps at [giscus.app](https://giscus.app). Once you get your custom
data-lang="en"
data-loading="lazy"
crossorigin="anonymous"
async></script>
async
></script>
```
To change the Giscus themes used, edit the `setGiscusTheme` function in `Head.astro`.
@ -167,15 +167,15 @@ To change the Giscus themes used, edit the `setGiscusTheme` function in `Head.as
// src/components/Head.astro
const setGiscusTheme = () => {
const giscus = document.querySelector(".giscus-frame");
const giscus = document.querySelector('.giscus-frame')
const isDark = document.documentElement.classList.contains("dark");
const isDark = document.documentElement.classList.contains('dark')
if (giscus) {
const url = new URL(giscus.src);
const url = new URL(giscus.src)
// Change "dark" and "light" to other Giscus themes
url.searchParams.set("theme", isDark ? "dark" : "light");
giscus.src = url.toString();
url.searchParams.set('theme', isDark ? 'dark' : 'light')
giscus.src = url.toString()
}
};
}
```

View file

@ -1,7 +1,7 @@
---
title: "[Old] Blog Collection"
description: "How to add posts to the blog."
date: "2024-03-21"
title: '[Old] Blog Collection'
description: 'How to add posts to the blog.'
date: '2024-03-21'
tags: ['aa']
---
@ -32,10 +32,10 @@ Metadata is required for each post.
```astro
---
title: "Blog Collection";
description: "How to add posts to the blog.";
date: "2024-03-21";
draft: false;
title: 'Blog Collection'
description: 'How to add posts to the blog.'
date: '2024-03-21'
draft: false
---
```
@ -52,10 +52,10 @@ All that's left to do is write the content under the metadata.
```astro
---
title: "Blog Collection";
description: "How to add posts to the blog.";
date: "2024-03-21";
draft: false;
title: 'Blog Collection'
description: 'How to add posts to the blog.'
date: '2024-03-21'
draft: false
---
## Working with the blog collection

View file

@ -1,10 +1,10 @@
---
title: "[Old] Markdown syntax guide"
description: "Get started writing content in Markdown."
date: "2024-03-17"
title: '[Old] Markdown syntax guide'
description: 'Get started writing content in Markdown.'
date: '2024-03-17'
---
import Callout from "@/components/Callout.astro";
import Callout from '@/components/Callout.astro'
---
@ -385,7 +385,7 @@ Denote a code block by wrapping a section of valid code in triple backticks (`).
```js
function hello() {
console.log("hello world");
console.log('hello world')
}
```

View file

@ -1,10 +1,10 @@
---
title: "[Old] MDX syntax guide"
description: "Use interactive components in Markdown."
date: "2024-03-16"
title: '[Old] MDX syntax guide'
description: 'Use interactive components in Markdown.'
date: '2024-03-16'
---
import Callout from "@/components/Callout.astro";
import Callout from '@/components/Callout.astro'
---
@ -25,7 +25,7 @@ import DateComp from "../../../components/FormattedDate.astro";
<DateComp date={new Date()} />
```
import FormattedDate from "../../../components/FormattedDate.astro";
import FormattedDate from '../../../components/FormattedDate.astro'
<FormattedDate date={new Date()} />
@ -43,7 +43,7 @@ import RelativeComponent from "./component.astro";
<RelativeComponent />
```
import RelativeComponent from "./component.astro";
import RelativeComponent from './component.astro'
<RelativeComponent />

View file

@ -1,7 +1,7 @@
---
title: "[Old] Year sorting example"
description: "Nano groups posts by year."
date: "2023-12-31"
title: '[Old] Year sorting example'
description: 'Nano groups posts by year.'
date: '2023-12-31'
---
This post is to demonstrate the year sorting capabilities.

View file

@ -1,7 +1,7 @@
---
title: "[Old] Draft example"
description: "Setting draft flag to true to hide this post."
date: "2022-12-31"
title: '[Old] Draft example'
description: 'Setting draft flag to true to hide this post.'
date: '2022-12-31'
draft: false
---

View file

@ -1,7 +1,7 @@
---
title: "[Old] Chronological pagination example"
description: "Pagination works regardless of folder name."
date: "2024-03-21"
title: '[Old] Chronological pagination example'
description: 'Pagination works regardless of folder name.'
date: '2024-03-21'
draft: false
---

View file

@ -1,7 +1,7 @@
import { defineCollection, z } from "astro:content";
import { defineCollection, z } from 'astro:content'
const blog = defineCollection({
type: "content",
type: 'content',
schema: z.object({
title: z.string(),
description: z.string(),
@ -10,10 +10,10 @@ const blog = defineCollection({
tags: z.array(z.string()).optional(),
}),
});
})
const publications = defineCollection({
type: "content",
type: 'content',
schema: z.object({
title: z.string(),
description: z.string(),
@ -27,6 +27,6 @@ const publications = defineCollection({
imgAlt: z.string().optional(),
pub: z.string().optional(),
}),
});
})
export const collections = { blog, publications };
export const collections = { blog, publications }

View file

@ -1,14 +1,13 @@
---
title: "Paper Title1"
description: "Your Paper Abstract"
date: "2024-03-26"
authors: "John B*, Jon A*, Frank C, "
paperURL: "Paper: https://astro-sphere-demo.vercel.app"
codeURL: "Code: https://astro-sphere-demo.vercel.app"
webURL: "Web: https://github.com/markhorn-dev/astro-sphere"
img: "/rupert-cat.gif"
imgAlt: "Paper Teaser"
pub: "ECCV2024"
dataURL: "Data: "
title: 'Paper Title1'
description: 'Your Paper Abstract'
date: '2024-03-26'
authors: 'John B*, Jon A*, Frank C, '
paperURL: 'Paper: https://astro-sphere-demo.vercel.app'
codeURL: 'Code: https://astro-sphere-demo.vercel.app'
webURL: 'Web: https://github.com/markhorn-dev/astro-sphere'
img: '/rupert-cat.gif'
imgAlt: 'Paper Teaser'
pub: 'ECCV2024'
dataURL: 'Data: '
---

View file

@ -1,14 +1,13 @@
---
title: "Paper Title1"
description: "Lorem ipsum dolor sit amet consectetur adipisicing elit. "
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: https://astro-sphere-demo.vercel.app"
webURL: "Web: https://github.com/markhorn-dev/astro-sphere"
img: "/rupert-cat.gif"
imgAlt: "Paper Teaser"
pub: "ECCV2024"
dataURL: "Data: https://github.com/markhorn-dev/astro-sphere"
title: 'Paper Title1'
description: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. '
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: https://astro-sphere-demo.vercel.app'
webURL: 'Web: https://github.com/markhorn-dev/astro-sphere'
img: '/rupert-cat.gif'
imgAlt: 'Paper Teaser'
pub: 'ECCV2024'
dataURL: 'Data: https://github.com/markhorn-dev/astro-sphere'
---

View file

@ -1,14 +1,13 @@
---
title: "Paper Title1"
description: "Your Paper Abstract"
date: "2024-03-26"
authors: "John B*, Jon A*, Frank C, "
paperURL: "Paper: https://astro-sphere-demo.vercel.app"
codeURL: "Code: https://astro-sphere-demo.vercel.app"
webURL: "Web: https://github.com/markhorn-dev/astro-sphere"
img: "/rupert-cat.gif"
imgAlt: "Paper Teaser"
pub: "ECCV2024"
dataURL: "Data: "
title: 'Paper Title1'
description: 'Your Paper Abstract'
date: '2024-03-26'
authors: 'John B*, Jon A*, Frank C, '
paperURL: 'Paper: https://astro-sphere-demo.vercel.app'
codeURL: 'Code: https://astro-sphere-demo.vercel.app'
webURL: 'Web: https://github.com/markhorn-dev/astro-sphere'
img: '/rupert-cat.gif'
imgAlt: 'Paper Teaser'
pub: 'ECCV2024'
dataURL: 'Data: '
---

View file

@ -1,33 +1,29 @@
---
import Head from "@components/Head.astro";
import Header from "@components/Header.astro";
import Footer from "@components/Footer.astro";
import PageFind from "@components/PageFind.astro";
import { SITE } from "@consts";
import '../styles/katex.css';
import ProgressBar from "@components/ProgressBar.astro";
import Head from '@components/Head.astro'
import Header from '@components/Header.astro'
import Footer from '@components/Footer.astro'
import { SITE } from '@consts'
import '../styles/katex.css'
type Props = {
title: string;
description: string;
};
title: string
description: string
}
const { title, description } = Astro.props;
const { title, description } = Astro.props
---
<!doctype html>
<html lang="en">
<head>
<Head title={`${title} | ${SITE.TITLE}`} description={description} />
<link rel="stylesheet" href="/path/to/your/global.css">
<link rel="stylesheet" href="/path/to/your/global.css" />
</head>
<body>
<Header />
<!-- <ProgressBar /> -->
<main>
<slot />
</main>
<Footer />
<PageFind />
</body>
</html>

View file

@ -1,21 +1,21 @@
import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";
import { clsx, type ClassValue } from 'clsx'
import { twMerge } from 'tailwind-merge'
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
return twMerge(clsx(inputs))
}
export function formatDate(date: Date) {
return Intl.DateTimeFormat("en-US", {
year: "numeric",
month: "2-digit",
day: "2-digit",
}).format(date);
return Intl.DateTimeFormat('en-US', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
}).format(date)
}
export function readingTime(html: string) {
const textOnly = html.replace(/<[^>]+>/g, "");
const wordCount = textOnly.split(/\s+/).length;
const readingTimeMinutes = (wordCount / 200 + 1).toFixed();
return `${readingTimeMinutes} min read`;
const textOnly = html.replace(/<[^>]+>/g, '')
const wordCount = textOnly.split(/\s+/).length
const readingTimeMinutes = (wordCount / 200 + 1).toFixed()
return `${readingTimeMinutes} min read`
}

View file

@ -1,9 +1,9 @@
---
import Layout from "@layouts/Layout.astro";
import Container from "@components/Container.astro";
import Link from "@components/Link.astro";
import BackToPrevious from "@components/BackToPrevious.astro";
import { SITE } from "@consts";
import Layout from '@layouts/Layout.astro'
import Container from '@components/Container.astro'
import Link from '@components/Link.astro'
import BackToPrevious from '@components/BackToPrevious.astro'
import { SITE } from '@consts'
---
<Layout title="404" description={SITE.DESCRIPTION}>

View file

@ -1,9 +1,9 @@
---
import { getCollection } from "astro:content";
import Layout from "@layouts/Layout.astro";
import Container from "@components/Container.astro";
import { ABOUT } from "@consts";
import Image from "astro/components/Image.astro";
import { getCollection } from 'astro:content'
import Layout from '@layouts/Layout.astro'
import Container from '@components/Container.astro'
import { ABOUT } from '@consts'
import { Image } from 'astro:assets'
---
<Layout title={ABOUT.TITLE} description={ABOUT.DESCRIPTION}>
@ -14,37 +14,51 @@ import Image from "astro/components/Image.astro";
About
</div>
<section class="animate not-prose flex flex-col gap-4 text-justify">
<p class="text-justify">Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolores porro hic minima incidunt explicabo obcaecati consectetur consequuntur at quisquam commodi.
</p>
<p class="text-justify">Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolores porro hic minima incidunt explicabo obcaecati consectetur consequuntur at quisquam commodi.
<p class="text-justify">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolores
porro hic minima incidunt explicabo obcaecati consectetur
consequuntur at quisquam commodi.
</p>
<p class="text-justify">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolores
porro hic minima incidunt explicabo obcaecati consectetur
consequuntur at quisquam commodi.
</p>
</section>
<div class="flex flex-col md:flex-row justify-center">
<div class="flex flex-col justify-center md:flex-row">
<div class="my-10 text-center">
<div class="bg-neutral-300 w-[350px] h-[250px] object-cover rounded-xl -rotate-6 overflow-hidden">
<div
class="h-[250px] w-[350px] -rotate-6 overflow-hidden rounded-xl bg-neutral-300 object-cover"
>
<Image
src={'/astro-nano.png'}
alt={'life2'}
width={350}
height={250}
class="w-[350px] h-[250px] object-cover rounded-xl overflow-hidden"
class="h-[250px] w-[350px] overflow-hidden rounded-xl object-cover"
/>
</div>
<p class="mt-4 text-sm">Lorem ipsum dolor sit amet, consectetur adipisicing elit. </p>
<p class="mt-4 text-sm">
Lorem ipsum dolor sit amet, consectetur adipisicing elit.
</p>
</div>
<div class="mx-10 my-10 text-center">
<div class="bg-neutral-300 w-[150px] h-[250px] object-cover rounded-xl rotate-6 mx-auto sm:ml-auto">
<div
class="mx-auto h-[250px] w-[150px] rotate-6 rounded-xl bg-neutral-300 object-cover sm:ml-auto"
>
<Image
src={'/astro-micro.jpg'}
alt={'life2'}
width={150}
height={250}
class="w-[150px] h-[250px] object-cover rounded-xl "
class="h-[250px] w-[150px] rounded-xl object-cover"
/>
</div>
<p class="mt-4 text-sm">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
<p class="mt-4 text-sm">
Lorem ipsum dolor sit amet, consectetur adipisicing elit.
</p>
</div>
</div>
</div>

View file

@ -1,49 +1,51 @@
---
import { type CollectionEntry, getCollection } from "astro:content";
import Layout from "@layouts/Layout.astro";
import Container from "@components/Container.astro";
import FormattedDate from "@components/FormattedDate.astro";
import { readingTime } from "@lib/utils";
import BackToPrevious from "@components/BackToPrevious.astro";
import PostNavigation from "@components/PostNavigation.astro";
import TableOfContents from "@components/TableOfContents.astro";
import Giscus from "@components/Giscus.astro";
import { type CollectionEntry, getCollection } from 'astro:content'
import Layout from '@layouts/Layout.astro'
import Container from '@components/Container.astro'
import FormattedDate from '@components/FormattedDate.astro'
import { readingTime } from '@lib/utils'
import BackToPrevious from '@components/BackToPrevious.astro'
import PostNavigation from '@components/PostNavigation.astro'
import TableOfContents from '@components/TableOfContents.astro'
import Giscus from '@components/Giscus.astro'
export async function getStaticPaths() {
const posts = (await getCollection("blog"))
const posts = (await getCollection('blog'))
.filter((post) => !post.data.draft)
.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf());
.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf())
return posts.map((post) => ({
params: { slug: post.slug },
props: post,
}));
}))
}
type Props = CollectionEntry<"blog">;
type Props = CollectionEntry<'blog'>
const posts = (await getCollection("blog"))
const posts = (await getCollection('blog'))
.filter((post) => !post.data.draft)
.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf());
.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf())
function getPostIndex(slug: string): number {
return posts.findIndex((post) => post.slug === slug);
return posts.findIndex((post) => post.slug === slug)
}
function getNextPost(slug: string): Props | null {
const postIndex = getPostIndex(slug);
return postIndex !== -1 && postIndex < posts.length - 1 ? posts[postIndex + 1] : null;
const postIndex = getPostIndex(slug)
return postIndex !== -1 && postIndex < posts.length - 1
? posts[postIndex + 1]
: null
}
function getPrevPost(slug: string): Props | null {
const postIndex = getPostIndex(slug);
return postIndex > 0 ? posts[postIndex - 1] : null;
const postIndex = getPostIndex(slug)
return postIndex > 0 ? posts[postIndex - 1] : null
}
const currentPostSlug = Astro.params.slug;
const nextPost = getNextPost(currentPostSlug);
const prevPost = getPrevPost(currentPostSlug);
const currentPostSlug = Astro.params.slug
const nextPost = getNextPost(currentPostSlug)
const prevPost = getPrevPost(currentPostSlug)
const post = Astro.props;
const { Content, headings } = await post.render();
const post = Astro.props
const { Content, headings } = await post.render()
---
<Layout title={post.data.title} description={post.data.description}>
@ -64,21 +66,23 @@ const { Content, headings } = await post.render();
<h1 class="animate text-4xl font-semibold text-black dark:text-white">
{post.data.title}
</h1>
<div class="font-base text-sm ">
{post.data.tags && post.data.tags.length > 0 ? (
post.data.tags.map((tag) => (
<div class="inline-block my-1">
<a
href={`/tags/${tag}`}
class="mx-1 rounded-full px-2 py-1 bg-orange-300 hover:bg-cyan-200 dark:bg-orange-500 dark:hover:bg-cyan-500 transition-colors duration-300 ease-in-out"
>
#{tag}
</a>
</div>
))
) : (
<span>No tags available</span>
)}
<div class="font-base text-sm">
{
post.data.tags && post.data.tags.length > 0 ? (
post.data.tags.map((tag) => (
<div class="my-1 inline-block">
<a
href={`/tags/${tag}`}
class="mx-1 rounded-full bg-orange-300 px-2 py-1 transition-colors duration-300 ease-in-out hover:bg-cyan-200 dark:bg-orange-500 dark:hover:bg-cyan-500"
>
#{tag}
</a>
</div>
))
) : (
<span>No tags available</span>
)
}
</div>
</div>
{headings.length > 0 && <TableOfContents headings={headings} />}

View file

@ -1,28 +1,28 @@
---
import { type CollectionEntry, getCollection } from "astro:content";
import Layout from "@layouts/Layout.astro";
import Container from "@components/Container.astro";
import ArrowCard from "@components/ArrowCard.astro";
import { BLOG } from "@consts";
import { type CollectionEntry, getCollection } from 'astro:content'
import Layout from '@layouts/Layout.astro'
import Container from '@components/Container.astro'
import ArrowCard from '@components/ArrowCard.astro'
import { BLOG } from '@consts'
const data = (await getCollection("blog"))
const data = (await getCollection('blog'))
.filter((post) => !post.data.draft)
.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf());
.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf())
type Acc = {
[year: string]: CollectionEntry<"blog">[];
};
[year: string]: CollectionEntry<'blog'>[]
}
const posts = data.reduce((acc: Acc, post) => {
const year = post.data.date.getFullYear().toString();
const year = post.data.date.getFullYear().toString()
if (!acc[year]) {
acc[year] = [];
acc[year] = []
}
acc[year].push(post);
return acc;
}, {});
acc[year].push(post)
return acc
}, {})
const years = Object.keys(posts).sort((a, b) => parseInt(b) - parseInt(a));
const years = Object.keys(posts).sort((a, b) => parseInt(b) - parseInt(a))
---
<Layout title={BLOG.TITLE} description={BLOG.DESCRIPTION}>

View file

@ -1,17 +1,35 @@
---
import { getCollection } from "astro:content";
import Layout from "@layouts/Layout.astro";
import Container from "@components/Container.astro";
import { CV } from "@consts";
import CVCard from "@components/CVCard.astro";
import { getCollection } from 'astro:content'
import Layout from '@layouts/Layout.astro'
import Container from '@components/Container.astro'
import { CV } from '@consts'
import CVCard from '@components/CVCard.astro'
// TO Modify
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"},
{
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"},
{
school: 'University 1',
time: '2022-Present',
job_title: 'BEng in Electronic Information Engineering',
location: 'London, UK',
description: 'Your Notes about the study',
},
]
---
@ -23,17 +41,33 @@ const educations = [
Work Experience
</div>
<ul class="animate not-prose flex flex-col gap-4">
{works.map((work) => (
<CVCard institution={work.company} time={work.time} job_title={work.job_title} location={work.location} description={work.description} />)
)}
{
works.map((work) => (
<CVCard
institution={work.company}
time={work.time}
job_title={work.job_title}
location={work.location}
description={work.description}
/>
))
}
</ul>
<div class="animate font-semibold text-black dark:text-white">
Education
</div>
<ul class="animate not-prose flex flex-col gap-4">
{educations.map((education) => (
<CVCard institution={education.school} time={education.time} job_title={education.job_title} location={education.location} description={education.description} />)
)}
{
educations.map((education) => (
<CVCard
institution={education.school}
time={education.time}
job_title={education.job_title}
location={education.location}
description={education.description}
/>
))
}
</ul>
</div>
</aside>

View file

@ -1,24 +1,24 @@
---
import Layout from "@layouts/Layout.astro";
import Container from "@components/Container.astro";
import { SITE, HOME } from "@consts";
import ArrowCard from "@components/ArrowCard.astro";
import Link from "@components/Link.astro";
import { getCollection } from "astro:content";
import type { CollectionEntry } from "astro:content";
import PublicationCard from "@components/PublicationCard.astro";
import SocialIcons from "@components/SocialIcons.astro";
import Layout from '@layouts/Layout.astro'
import Container from '@components/Container.astro'
import { SITE, HOME } from '@consts'
import ArrowCard from '@components/ArrowCard.astro'
import Link from '@components/Link.astro'
import { getCollection } from 'astro:content'
import type { CollectionEntry } from 'astro:content'
import PublicationCard from '@components/PublicationCard.astro'
import SocialIcons from '@components/SocialIcons.astro'
const blog = (await getCollection("blog"))
const blog = (await getCollection('blog'))
.filter((post) => !post.data.draft)
.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf())
.slice(0, SITE.NUM_POSTS_ON_HOMEPAGE);
.slice(0, SITE.NUM_POSTS_ON_HOMEPAGE)
const publications: CollectionEntry<"publications">[] = (
await getCollection("publications")
const publications: CollectionEntry<'publications'>[] = (
await getCollection('publications')
)
.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf())
.slice(0, SITE.NUM_PUBLICATIONS_ON_HOMEPAGE);
.slice(0, SITE.NUM_PUBLICATIONS_ON_HOMEPAGE)
---
<Layout title={HOME.TITLE} description={HOME.DESCRIPTION}>
@ -34,16 +34,21 @@ const publications: CollectionEntry<"publications">[] = (
<p>
Astro Micro Academics is a theme for <Link
href="https://astro.build/">Astro</Link
> and tailored for academic users and researchers. It's built on <Link href="https://astro.build/themes/details/astro-micro/">Astro Micro</Link> and
> and tailored for academic users and researchers. It's built on
<Link href="https://astro.build/themes/details/astro-micro/"
>Astro Micro</Link
> and
<Link href="https://github.com/markhorn-dev">
Mark Horn's
</Link> popular theme <Link
href="https://astro.build/themes/details/astronano/"
>Astro Nano</Link
>.
>.
</p>
<p>
Micro Academics adds features like <span class="text-red-500">tags, and blog math support</span> and also inherits <Link href="https://pagefind.app/"
Micro Academics adds features like <span class="text-red-500"
>tags, and blog math support</span
> and also inherits <Link href="https://pagefind.app/"
>Pagefind</Link
> for search, <Link href="https://giscus.app">Giscus</Link> for comments,
from Astro Micro. See full changes this <Link
@ -53,10 +58,10 @@ const publications: CollectionEntry<"publications">[] = (
</span>
<span class="animate">
<p>
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.
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.
</p>
<p>
Visit
@ -66,11 +71,12 @@ const publications: CollectionEntry<"publications">[] = (
to fork the repository to get started.
</p>
</span>
</article>
</section>
<section class="animate space-y-2 border-2 border-red-800 text-red-800 dark:border-red-400 border-dashed p-2 dark:text-red-400">
<section
class="animate space-y-2 border-2 border-dashed border-red-800 p-2 text-red-800 dark:border-red-400 dark:text-red-400"
>
📢📢 Your important Information (Open for job/Recruiting students)
</section>
@ -81,8 +87,8 @@ const publications: CollectionEntry<"publications">[] = (
</h4>
<article>
<p>
If you want to get in touch with me about something or just to say
hi, reach out on social media or send me an email.
If you want to get in touch with me about something or just to
say hi, reach out on social media or send me an email.
</p>
</article>
<SocialIcons icon_size={'text-3xl'} />
@ -100,14 +106,14 @@ const publications: CollectionEntry<"publications">[] = (
<li>AIGC</li>
</ul>
</section>
<section class="animate space-y-6">
<div class="flex flex-wrap items-center justify-between gap-y-2">
<h2 class="font-semibold text-black dark:text-white">
News
</h2>
<h2 class="font-semibold text-black dark:text-white">News</h2>
</div>
<ul class="not-prose flex flex-col gap-4 overflow-y-auto max-h-[150px] scroll_bar">
<ul
class="not-prose scroll_bar flex max-h-[150px] flex-col gap-4 overflow-y-auto"
>
<li>[06/2024]: Your News1</li>
<li>[06/2024]: Your <span class="text-red-600">News2</span></li>
<li>[06/2024]: Your <span class="text-red-600">News2</span></li>
@ -151,7 +157,6 @@ const publications: CollectionEntry<"publications">[] = (
}
</ul>
</section>
</div>
</aside>
</Container>

View file

@ -1,13 +1,14 @@
---
import { getCollection } from "astro:content";
import Layout from "@layouts/Layout.astro";
import Container from "@components/Container.astro";
import { RESEARCH } from "@consts";
import PublicationCard from "@components/PublicationCard.astro";
import { getCollection } from 'astro:content'
import Layout from '@layouts/Layout.astro'
import Container from '@components/Container.astro'
import { RESEARCH } from '@consts'
import PublicationCard from '@components/PublicationCard.astro'
// import PublicationCard from "@components/PublicationCard";
const publications = (await getCollection("publications"))
.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf());
const publications = (await getCollection('publications')).sort(
(a, b) => b.data.date.valueOf() - a.data.date.valueOf(),
)
---
<Layout title={RESEARCH.TITLE} description={RESEARCH.DESCRIPTION}>

View file

@ -1,6 +1,6 @@
import rss from "@astrojs/rss";
import { SITE } from "@consts";
import { getCollection } from "astro:content";
import rss from '@astrojs/rss'
import { SITE } from '@consts'
import { getCollection } from 'astro:content'
export async function GET(context) {
// const publications = (await getCollection("publications")).filter(
@ -11,15 +11,20 @@ export async function GET(context) {
// (a, b) => new Date(b.data.date).valueOf() - new Date(a.data.date).valueOf(),
// );
try {
const blog = (await getCollection("blog")).filter((post) => !post.data.draft);
const blog = (await getCollection('blog')).filter(
(post) => !post.data.draft,
)
// Filter posts by tag 'rss-feed'
const filteredBlogs = blog.filter(post => post.data.tags && post.data.tags.includes('rss-feed'));
const filteredBlogs = blog.filter(
(post) => post.data.tags && post.data.tags.includes('rss-feed'),
)
// Sort posts by date
const items = [...filteredBlogs].sort(
(a, b) => new Date(b.data.date).valueOf() - new Date(a.data.date).valueOf()
);
(a, b) =>
new Date(b.data.date).valueOf() - new Date(a.data.date).valueOf(),
)
// Return RSS feed
return rss({
@ -32,9 +37,9 @@ export async function GET(context) {
pubDate: item.data.date,
link: `/${item.collection}/${item.slug}/`,
})),
});
})
} catch (error) {
console.error('Error generating RSS feed:', error);
return new Response('Error generating RSS feed', { status: 500 });
console.error('Error generating RSS feed:', error)
return new Response('Error generating RSS feed', { status: 500 })
}
}

View file

@ -1,37 +1,48 @@
---
import { type CollectionEntry, getCollection } from "astro:content";
import Layout from "@layouts/Layout.astro";
import Container from "@components/Container.astro";
import ArrowCard from "@components/ArrowCard.astro";
import { TAGS } from "@consts";
import { type CollectionEntry, getCollection } from 'astro:content'
import Layout from '@layouts/Layout.astro'
import Container from '@components/Container.astro'
import ArrowCard from '@components/ArrowCard.astro'
import { TAGS } from '@consts'
type BlogPost = CollectionEntry<'blog'>;
type BlogPost = CollectionEntry<'blog'>
type Props = {
tag: string;
posts: BlogPost[];
};
tag: string
posts: BlogPost[]
}
const { tag, posts } = Astro.props;
const { tag, posts } = Astro.props
export async function getStaticPaths() {
const posts = await getCollection('blog');
const tags = posts.flatMap((post) => post.data.tags || []);
const uniqueTags = Array.from(new Set(tags.filter((tag): tag is string => typeof tag === 'string')));
const posts = await getCollection('blog')
const tags = posts.flatMap((post) => post.data.tags || [])
const uniqueTags = Array.from(
new Set(tags.filter((tag): tag is string => typeof tag === 'string')),
)
return uniqueTags.map((tag) => ({
params: { slug: tag },
props: { tag, posts: posts.filter((post) => post.data.tags?.includes(tag)) },
}));
props: {
tag,
posts: posts.filter((post) => post.data.tags?.includes(tag)),
},
}))
}
---
<Layout title={`Posts tagged with "${tag}"`} description={`A collection of posts tagged with ${tag}.`}>
<Layout
title={`Posts tagged with "${tag}"`}
description={`A collection of posts tagged with ${tag}.`}
>
<Container>
<aside data-pagefind-ignore>
<div class="space-y-10">
<div class="animate font-semibold text-black dark:text-white">
Tag: <span class="px-3 py-2 rounded-full mx-2 bg-orange-300 hover:bg-cyan-200 dark:bg-orange-500 dark:hover:bg-cyan-500 transition-colors duration-300 ease-in-out">#{tag}</span>
Tag: <span
class="mx-2 rounded-full bg-orange-300 px-3 py-2 transition-colors duration-300 ease-in-out hover:bg-cyan-200 dark:bg-orange-500 dark:hover:bg-cyan-500"
>#{tag}</span
>
</div>
<div class="space-y-4">
{
@ -39,9 +50,9 @@ export async function getStaticPaths() {
<section class="animate space-y-4">
<div>
<ul class="not-prose flex flex-col gap-4">
<li>
<ArrowCard entry={post} />
</li>
<li>
<ArrowCard entry={post} />
</li>
</ul>
</div>
</section>

View file

@ -1,31 +1,35 @@
---
import { getCollection } from "astro:content";
import Layout from "@layouts/Layout.astro";
import Container from "@components/Container.astro";
import { TAGS } from "@consts";
import Image from "astro/components/Image.astro";
import { getCollection } from 'astro:content'
import Layout from '@layouts/Layout.astro'
import Container from '@components/Container.astro'
import { TAGS } from '@consts'
import Image from 'astro/components/Image.astro'
const blog = (await getCollection("blog"))
.filter((post) => !post.data.draft);
const blog = (await getCollection('blog')).filter((post) => !post.data.draft)
const tags = blog.flatMap(post => post.data.tags).filter((tag, index, self) => self.indexOf(tag) === index);
const tags = blog
.flatMap((post) => post.data.tags)
.filter((tag, index, self) => self.indexOf(tag) === index)
---
<Layout title={TAGS.TITLE} description={TAGS.DESCRIPTION}>
<Container>
<aside data-pagefind-ignore>
<div class="space-y-10">
<div class="animate font-semibold text-black dark:text-white">
Tags
</div>
<ul class="flex flex-wrap ">
{tags.map(tag => (
<div class="animate font-semibold text-black dark:text-white">Tags</div>
<ul class="flex flex-wrap">
{
tags.map((tag) => (
<li class="my-3">
<a href={`/tags/${tag}`} class="px-3 py-2 rounded-full mx-2 bg-orange-300 hover:bg-cyan-200 dark:bg-orange-500 dark:hover:bg-cyan-500 transition-colors duration-300 ease-in-out">
#{tag}
<a
href={`/tags/${tag}`}
class="mx-2 rounded-full bg-orange-300 px-3 py-2 transition-colors duration-300 ease-in-out hover:bg-cyan-200 dark:bg-orange-500 dark:hover:bg-cyan-500"
>
#{tag}
</a>
</li>
))}
))
}
</ul>
</div>
</aside>

View file

@ -1,18 +0,0 @@
// src/scripts/progress-bar.js
export function initializeProgressBar() {
function updateProgressBar() {
const scrollTop = window.scrollY;
const docHeight = document.documentElement.scrollHeight;
const winHeight = window.innerHeight;
const scrollPercent = (scrollTop / (docHeight - winHeight)) * 100;
document.getElementById('progress-bar').style.width = `${scrollPercent}%`;
}
window.addEventListener('scroll', updateProgressBar);
window.addEventListener('resize', updateProgressBar);
// Initialize the progress bar on page load
updateProgressBar();
}

View file

@ -57,8 +57,8 @@ article {
}
.scroll_bar {
scrollbar-width: thin;
scrollbar-color: #1e293b #0f172a ;
scrollbar-width: thin;
scrollbar-color: #1e293b #0f172a;
}
.animate {

View file

@ -1 +1 @@
@import 'https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css';
@import 'https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css';

View file

@ -1,13 +1,13 @@
export type Site = {
TITLE: string;
DESCRIPTION: string;
EMAIL: string;
NUM_POSTS_ON_HOMEPAGE: number;
NUM_PUBLICATIONS_ON_HOMEPAGE: number;
SITEURL: string,
};
TITLE: string
DESCRIPTION: string
EMAIL: string
NUM_POSTS_ON_HOMEPAGE: number
NUM_PUBLICATIONS_ON_HOMEPAGE: number
SITEURL: string
}
export type Metadata = {
TITLE: string;
DESCRIPTION: string;
};
TITLE: string
DESCRIPTION: string
}

View file

@ -1,15 +0,0 @@
import defaultTheme from "tailwindcss/defaultTheme";
/** @type {import('tailwindcss').Config} */
export default {
darkMode: "class",
content: ["./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}"],
theme: {
extend: {
fontFamily: {
sans: ["Geist Sans", ...defaultTheme.fontFamily.sans],
mono: ["Geist Mono", ...defaultTheme.fontFamily.mono],
},
},
},
plugins: [require("@tailwindcss/typography")],
};

18
tailwind.config.ts Normal file
View file

@ -0,0 +1,18 @@
import type { Config } from 'tailwindcss'
import defaultTheme from 'tailwindcss/defaultTheme'
const config: Config = {
darkMode: 'class',
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
theme: {
extend: {
fontFamily: {
sans: ['Geist Sans', ...defaultTheme.fontFamily.sans],
mono: ['Geist Mono', ...defaultTheme.fontFamily.mono],
},
},
},
plugins: [require('@tailwindcss/typography')],
}
export default config