chore: init
27
.gitignore
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
# build output
|
||||
dist/
|
||||
# generated types
|
||||
.astro/
|
||||
|
||||
# dependencies
|
||||
node_modules/
|
||||
|
||||
# logs
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
|
||||
# environment variables
|
||||
.env
|
||||
.env.production
|
||||
|
||||
# macOS-specific files
|
||||
.DS_Store
|
||||
|
||||
# jetbrains setting folder
|
||||
.idea/
|
||||
|
||||
teaser.pptx
|
||||
~$teaser.pptx
|
17
.prettierrc.mjs
Normal file
|
@ -0,0 +1,17 @@
|
|||
// .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",
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
21
LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2024 Trevor Lee
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
199
README.md
Normal file
|
@ -0,0 +1,199 @@
|
|||
# Astro-Micro-Academics
|
||||
|
||||
[
|
||||
](https://astro.build/themes/details/astro-micro-academics)
|
||||
[](https://astro-micro-academic.vercel.app/)
|
||||
|
||||
Astro Micro Academic is an academic version of [Astro-Micro](https://github.com/trevortylerlee/astro-micro) and [Nano](https://astro-nano-demo.vercel.app/).
|
||||
It is tailored for researchers.
|
||||
|
||||
Micro Academics adds features like tags, and blog math support and also inherits [Pagefind](https://pagefind.app/) for search, [Giscus](https://giscus.app/) for comments, from Astro Micro.
|
||||
|
||||
Micro Academics still comes with everything great about Micro and Nano — full type safety, a sitemap, an RSS feed, and Markdown + MDX support. Styled with TailwindCSS and preconfigured with system, light, and dark themes.
|
||||
|
||||

|
||||
|
||||
## News
|
||||
✨ I've got a detailed blog about building and deploying your website using this template! Check it out [here](https://jingwu2121.github.io/blog/01-build-deploy-website/)
|
||||
|
||||
## Install Astro-Micro-Academics
|
||||
|
||||
Clone the [repository](https://github.com/jingwu2121/astro-micro-academic).
|
||||
|
||||
```sh
|
||||
git clone https://github.com/jingwu2121/astro-micro-academic.git
|
||||
```
|
||||
|
||||
```sh
|
||||
cd astro-micro-academic
|
||||
```
|
||||
|
||||
```sh
|
||||
npm i
|
||||
```
|
||||
|
||||
Run local server
|
||||
```sh
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## Update the Homepage
|
||||
|
||||
Update your home page in `src/pages/index.astro`.
|
||||
|
||||
|
||||
## CV & About
|
||||
|
||||
Update your CV and About page in `src/pages/cv.astro` and `src/pages/about.astro`.
|
||||
|
||||
```ts
|
||||
const works = [
|
||||
{company:"Company A", time: "2022-Present", job_title: "Research Scientist", location: "London, UK", description: "Your Notes about the job"},
|
||||
{company:"Company A", time: "2022-Present", job_title: "Research Scientist", location: "London, UK", description: "Your Notes about the job"},
|
||||
]
|
||||
const educations = [
|
||||
{school:"University 1", time: "2022-Present", job_title: "BEng in Electronic Information Engineering", location: "London, UK", description: "Your Notes about the study"},
|
||||
]
|
||||
```
|
||||
|
||||
## Social Links
|
||||
|
||||
Update the social links in `src/components/SocialIcons.astro`, simply replace the `URL`.
|
||||
|
||||
## Publications metadata
|
||||
|
||||
Metadata is required for each post. Add a new `publication.md` to automartically add a publication on the website. Publications are sorted by date.
|
||||
|
||||
```astro
|
||||
---
|
||||
title: "Diffusion Models Beat GANs on Image Synthesis"
|
||||
description: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestias earum quod quo repellat blanditiis est iste eos dolorem! Voluptatibus corporis totam sed unde est iusto neque iure natus adipisci omnis."
|
||||
date: "2024-07-26"
|
||||
authors: "John B*, Jon A*, Frank C, John B, Jon A, Frank C"
|
||||
paperURL: "Paper: https://astro-sphere-demo.vercel.app"
|
||||
codeURL: "Code: "
|
||||
webURL: "Web: https://github.com/markhorn-dev/astro-sphere"
|
||||
dataURL: "Data: https://github.com/markhorn-dev/astro-sphere"
|
||||
img: "/rupert-cat.gif"
|
||||
imgAlt: "Paper Teaser"
|
||||
pub: "ECCV2024"
|
||||
---
|
||||
```
|
||||
|
||||
| Field | Req | Type | Remarks |
|
||||
| :---------- | :-- | :------ | :----------------------------------------------- |
|
||||
| title | Yes | string | Title of the content. Used in SEO and RSS. |
|
||||
| description | Yes | string | Description of the content. Used in SEO and RSS. |
|
||||
| date | Yes | string | Must be a valid date string (able to be parsed). |
|
||||
| authors | Yes | string | A string seperated by comma. |
|
||||
| paperURL, codeURL, webURL, dataURL | Yes | string | A string seperated by ": ". If you don't have a link to add, leave the link part blank, e.g. `codeURL: "Code: "` |
|
||||
| img | Yes | string | Path to teaser image. |
|
||||
| imgAlt | Yes | string | Description of the image. |
|
||||
| pub | Yes | string | The conference or journal |
|
||||
|
||||
## Blog metadata
|
||||
|
||||
Metadata is required for each post.
|
||||
|
||||
```astro
|
||||
---
|
||||
title: "Blog Collection";
|
||||
description: "How to add posts to the blog.";
|
||||
date: "2024-03-21";
|
||||
tags: ['guide', 'tutorial']
|
||||
draft: false;
|
||||
---
|
||||
```
|
||||
|
||||
| Field | Req | Type | Remarks |
|
||||
| :---------- | :-- | :------ | :----------------------------------------------- |
|
||||
| title | Yes | string | Title of the content. Used in SEO and RSS. |
|
||||
| description | Yes | string | Description of the content. Used in SEO and RSS. |
|
||||
| date | Yes | string | Must be a valid date string (able to be parsed). |
|
||||
| tags | Yes | list | A list of strings |
|
||||
| draft | No | boolean | If draft: true, content will not be published. |
|
||||
|
||||
## Customize the website metadata and set up RSS
|
||||
|
||||
To change the website metadata, edit `src/consts.ts`.
|
||||
|
||||
```ts
|
||||
// src/consts.ts
|
||||
|
||||
export const SITE: Site = {
|
||||
TITLE: "Astro Micro Academics",
|
||||
DESCRIPTION: "Astro Micro Academics is for academic user.",
|
||||
EMAIL: "youremial@gmail.com",
|
||||
NUM_POSTS_ON_HOMEPAGE: 2,
|
||||
NUM_PUBLICATIONS_ON_HOMEPAGE: 3,
|
||||
SITEURL: 'https://astro-micro-academic.vercel.app' // Update here to link the RSS icon to your website RSS
|
||||
};
|
||||
```
|
||||
|
||||
| Field | Req | Description |
|
||||
| :----------- | :-- | :--------------------------------------------------- |
|
||||
| TITLE | Yes | Displayed in header and footer. Used in SEO and RSS. |
|
||||
| DESCRIPTION | Yes | Used in SEO and RSS. |
|
||||
| EMAIL | Yes | Displayed in contact section. |
|
||||
| NUM_POSTS | Yes | Limit number of posts on home page. |
|
||||
| NUM_PUBLICATIONS | Yes | Limit number of research on home page. |
|
||||
| SITEURL | Yes | Your website URL |
|
||||
|
||||
### RSS Post
|
||||
|
||||
Please tag the post of RSS feed with tag `"rss-feed"`, other posts are not included in the RSS.
|
||||
|
||||
---
|
||||
|
||||
## Custom metadata for highlighted author in your paper
|
||||
|
||||
```ts
|
||||
// src/consts.ts
|
||||
|
||||
export const HIGHLIGHTAUTHOR = "John B"
|
||||
```
|
||||
|
||||
## Customize metadata for individual pages
|
||||
|
||||
```ts
|
||||
// src/consts.ts
|
||||
|
||||
export const HOME: Metadata = {
|
||||
TITLE: "Home",
|
||||
DESCRIPTION: "Astro Micro is an accessible theme for Astro.",
|
||||
};
|
||||
|
||||
export const BLOG: Metadata = {
|
||||
TITLE: "Blog",
|
||||
DESCRIPTION: "A collection of articles on topics I am passionate about.",
|
||||
};
|
||||
|
||||
export const RESEARCH: Metadata = {
|
||||
TITLE: "Publications",
|
||||
DESCRIPTION:
|
||||
"A collection of my publications with links to paper, repositories and live demos.",
|
||||
};
|
||||
|
||||
export const CV: Metadata = {
|
||||
TITLE: "CV",
|
||||
DESCRIPTION:
|
||||
"your cv",
|
||||
};
|
||||
|
||||
export const TAGS: Metadata = {
|
||||
TITLE: "TAGS",
|
||||
DESCRIPTION:
|
||||
"blog tag filter",
|
||||
};
|
||||
|
||||
export const ABOUT: Metadata = {
|
||||
TITLE: "ABOUT",
|
||||
DESCRIPTION:
|
||||
"A self-intro",
|
||||
};
|
||||
```
|
||||
|
||||
| Field | Req | Description |
|
||||
| :---------- | :-- | :--------------------------------------------- |
|
||||
| TITLE | Yes | Displayed in browser tab. Used in SEO and RSS. |
|
||||
| DESCRIPTION | Yes | Used in SEO and RSS. |
|
BIN
assets/teaser-1.png
Normal file
After Width: | Height: | Size: 415 KiB |
25
astro.config.mjs
Normal file
|
@ -0,0 +1,25 @@
|
|||
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}
|
||||
});
|
8850
package-lock.json
generated
Normal file
42
package.json
Normal file
|
@ -0,0 +1,42 @@
|
|||
{
|
||||
"name": "astro-micro",
|
||||
"type": "module",
|
||||
"version": "0.0.1",
|
||||
"scripts": {
|
||||
"dev": "astro dev",
|
||||
"start": "astro dev",
|
||||
"build": "astro check && astro build",
|
||||
"preview": "astro preview",
|
||||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/check": "^0.7.0",
|
||||
"@astrojs/markdown-remark": "^5.2.0",
|
||||
"@astrojs/mdx": "^3.1.2",
|
||||
"@astrojs/rss": "^4.0.7",
|
||||
"@astrojs/sitemap": "^3.1.6",
|
||||
"@astrojs/tailwind": "^5.1.0",
|
||||
"@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",
|
||||
"remark-toc": "^9.0.0",
|
||||
"tailwind-merge": "^2.3.0",
|
||||
"tailwindcss": "^3.4.3",
|
||||
"typescript": "^5.4.5"
|
||||
},
|
||||
"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"
|
||||
}
|
||||
}
|
BIN
public/astro-micro-lighthouse.jpg
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
public/astro-micro.jpg
Normal file
After Width: | Height: | Size: 155 KiB |
BIN
public/astro-nano-lighthouse.jpg
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
public/astro-nano.png
Normal file
After Width: | Height: | Size: 241 KiB |
BIN
public/astro-sphere-lighthouse.jpg
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
public/astro-sphere.jpg
Normal file
After Width: | Height: | Size: 68 KiB |
BIN
public/blog-placeholder-1.jpg
Normal file
After Width: | Height: | Size: 31 KiB |
17
public/deploy_netlify.svg
Normal file
|
@ -0,0 +1,17 @@
|
|||
<svg width="179" height="32" viewBox="0 0 179 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_8_30)">
|
||||
<path d="M173 0H6C2.68629 0 0 2.68629 0 6V26C0 29.3137 2.68629 32 6 32H173C176.314 32 179 29.3137 179 26V6C179 2.68629 176.314 0 173 0Z" fill="#2E51ED"/>
|
||||
<path d="M15.027 23.227H14.781L13.556 22.049V21.813L15.429 20.011H16.727L16.9 20.178V21.426L15.027 23.227ZM13.556 9.89999V9.66399L14.781 8.48499H15.027L16.9 10.287V11.535L16.727 11.701H15.429L13.556 9.89999ZM24.343 19.429H22.561L22.411 19.286V15.273C22.411 14.559 22.12 14.005 21.224 13.986C20.764 13.975 20.236 13.986 19.673 14.007L19.588 14.091V19.284L19.439 19.427H17.657L17.507 19.284V12.429L17.657 12.285H21.669C23.229 12.285 24.492 13.5 24.492 15V19.286L24.343 19.429ZM15.28 16.86H8.15L8 16.716V14.998L8.149 14.855H15.28L15.43 14.998V16.716L15.28 16.859V16.86ZM33.853 16.86H26.722L26.572 16.716V14.998L26.722 14.855H33.853L34.002 14.998V16.716L33.853 16.859V16.86ZM19.973 10.143V4.99999L20.122 4.85699H21.909L22.057 4.99999V10.143L21.909 10.287H20.122L19.973 10.143ZM19.973 26.714V21.571L20.122 21.428H21.909L22.057 21.571V26.714L21.909 26.857H20.122L19.973 26.714ZM155.15 10.64C154.72 11.06 154.51 11.64 154.51 12.39V13.43H153.28V15.1H154.51V21.19H156.47V15.1H158.11V13.43H156.47V12.38C156.47 11.85 156.75 11.58 157.3 11.58H158.34V9.99999H156.94C156.18 9.99999 155.59 10.21 155.16 10.64H155.15ZM150.93 10.13C150.57 10.13 150.27 10.25 150.05 10.48C149.84 10.7 149.73 10.98 149.73 11.32C149.73 11.66 149.84 11.95 150.05 12.19C150.27 12.42 150.57 12.54 150.93 12.54C151.29 12.54 151.57 12.42 151.78 12.19C152 11.96 152.12 11.67 152.12 11.32C152.12 10.97 152.01 10.7 151.78 10.48C151.56 10.25 151.28 10.13 150.93 10.13ZM73.23 10.14H75.19V21.19H73.23V10.14Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M47.32 10.63C48.49 10.63 49.49 10.84 50.33 11.27C51.17 11.69 51.81 12.3 52.25 13.09C52.7 13.88 52.92 14.83 52.92 15.92C52.92 17.01 52.7 17.96 52.25 18.75C51.81 19.54 51.17 20.14 50.33 20.56C49.49 20.98 48.49 21.19 47.32 21.19H44V10.63H47.32ZM47.23 19.22C48.31 19.22 49.16 18.93 49.78 18.35V18.36C50.41 17.77 50.72 16.97 50.72 15.92C50.72 14.87 50.41 14.05 49.78 13.47C49.16 12.89 48.31 12.6 47.23 12.6H46.11V19.22H47.23ZM58.16 13.29C58.96 13.29 59.65 13.45 60.25 13.79L60.24 13.78C60.85 14.11 61.31 14.57 61.64 15.17C61.97 15.77 62.13 16.47 62.13 17.26V17.92H56.28C56.31 18.18 56.36 18.44 56.47 18.66C56.63 18.96 56.85 19.19 57.14 19.36C57.43 19.53 57.78 19.61 58.19 19.61C58.6 19.61 58.95 19.54 59.23 19.41C59.51 19.28 59.72 19.09 59.86 18.86H61.96C61.8 19.33 61.54 19.76 61.19 20.13C60.85 20.51 60.41 20.79 59.89 21C59.38 21.21 58.8 21.31 58.17 21.31C57.38 21.31 56.68 21.15 56.07 20.82C55.47 20.49 55.01 20.02 54.67 19.41C54.34 18.81 54.18 18.1 54.18 17.3C54.18 16.5 54.34 15.8 54.67 15.2C55 14.6 55.46 14.13 56.06 13.79C56.67 13.46 57.36 13.29 58.16 13.29ZM58.16 14.99C57.8 14.99 57.47 15.08 57.18 15.26C56.89 15.42 56.66 15.66 56.49 15.97C56.41 16.14 56.35 16.31 56.31 16.49H60.05C60.0095 16.2241 59.9069 15.9714 59.7505 15.7525C59.5941 15.5336 59.3884 15.3546 59.15 15.23C58.86 15.07 58.52 14.99 58.16 14.99ZM70.16 13.74C69.64 13.42 69.04 13.26 68.35 13.26C67.66 13.26 67.06 13.42 66.57 13.74C66.28 13.93 66.05 14.19 65.86 14.47V13.43H63.9V23.85H65.86V20.16C66.06 20.45 66.29 20.7 66.57 20.9C67.06 21.23 67.65 21.39 68.35 21.39C69.05 21.39 69.63 21.23 70.16 20.91C70.68 20.58 71.09 20.12 71.38 19.51C71.67 18.89 71.81 18.17 71.81 17.33C71.81 16.49 71.67 15.75 71.38 15.15C71.09 14.53 70.68 14.07 70.16 13.75V13.74ZM69.5 18.6C69.33 18.95 69.1 19.22 68.8 19.41C68.51 19.6 68.18 19.69 67.81 19.69C67.22 19.69 66.75 19.48 66.4 19.07C66.05 18.65 65.87 18.08 65.87 17.35C65.87 16.62 66.05 16.07 66.4 15.66C66.75 15.25 67.23 15.04 67.81 15.04C68.18 15.04 68.51 15.14 68.8 15.33C69.1 15.52 69.33 15.79 69.5 16.14C69.67 16.49 69.75 16.89 69.75 17.34C69.75 17.79 69.67 18.23 69.5 18.59V18.6ZM82.85 13.79C82.23 13.44 81.51 13.26 80.68 13.26C79.85 13.26 79.13 13.44 78.51 13.79C77.9 14.14 77.44 14.62 77.11 15.23C76.78 15.85 76.62 16.54 76.62 17.32C76.62 18.1 76.78 18.79 77.11 19.41C77.44 20.02 77.9 20.5 78.51 20.85C79.13 21.2 79.85 21.38 80.68 21.38C81.51 21.38 82.23 21.2 82.85 20.85C83.47 20.5 83.93 20.01 84.25 19.39C84.58 18.77 84.74 18.08 84.74 17.32C84.74 16.56 84.58 15.85 84.25 15.23C83.93 14.61 83.47 14.13 82.85 13.79ZM82.43 18.49C82.27 18.83 82.04 19.09 81.73 19.27C81.43 19.46 81.08 19.55 80.68 19.55C80.28 19.55 79.91 19.46 79.62 19.27C79.32 19.08 79.09 18.82 78.92 18.49C78.76 18.15 78.68 17.76 78.68 17.31C78.68 16.86 78.76 16.46 78.92 16.12C79.09 15.78 79.32 15.53 79.62 15.35C79.92 15.16 80.27 15.07 80.68 15.07C81.09 15.07 81.43 15.16 81.73 15.35C82.04 15.53 82.27 15.79 82.43 16.13C82.6 16.47 82.68 16.86 82.68 17.31C82.68 17.76 82.6 18.15 82.43 18.49Z" fill="white"/>
|
||||
<path d="M87.11 13.43L89.15 18.5L91.26 13.43H93.15L88.84 23.75H86.95L88.14 20.9L85.13 13.43H87.11ZM102.71 10.98H100.75V13.43H99.26V15.1H100.75V21.19H102.71V15.1H104.39V13.43H102.71V10.98Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M109.18 13.26C110.01 13.26 110.73 13.44 111.35 13.79C111.97 14.13 112.43 14.61 112.75 15.23C113.08 15.85 113.24 16.56 113.24 17.32C113.24 18.08 113.08 18.77 112.75 19.39C112.43 20.01 111.97 20.5 111.35 20.85C110.73 21.2 110.01 21.38 109.18 21.38C108.35 21.38 107.63 21.2 107.01 20.85C106.4 20.5 105.94 20.02 105.61 19.41C105.28 18.79 105.12 18.1 105.12 17.32C105.12 16.54 105.28 15.85 105.61 15.23C105.94 14.62 106.4 14.14 107.01 13.79C107.63 13.44 108.35 13.26 109.18 13.26ZM110.23 19.27C110.54 19.09 110.77 18.83 110.93 18.49C111.1 18.15 111.18 17.76 111.18 17.31C111.18 16.86 111.1 16.47 110.93 16.13C110.77 15.79 110.54 15.53 110.23 15.35C109.93 15.16 109.59 15.07 109.18 15.07C108.77 15.07 108.42 15.16 108.12 15.35C107.82 15.53 107.59 15.78 107.42 16.12C107.26 16.46 107.18 16.86 107.18 17.31C107.18 17.76 107.26 18.15 107.42 18.49C107.59 18.82 107.82 19.08 108.12 19.27C108.41 19.46 108.78 19.55 109.18 19.55C109.58 19.55 109.93 19.46 110.23 19.27Z" fill="white"/>
|
||||
<path d="M126.91 16.02L122.22 10.63H120.41V21.19H122.52V14.26L126.91 19.31V21.19H129.02V10.63H126.91V16.02Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M134.5 13.29C135.3 13.29 135.99 13.45 136.59 13.79L136.58 13.78C137.19 14.11 137.65 14.57 137.98 15.17C138.31 15.77 138.47 16.47 138.47 17.26V17.92H132.62C132.65 18.18 132.7 18.44 132.81 18.66C132.97 18.96 133.19 19.19 133.48 19.36C133.77 19.53 134.12 19.61 134.53 19.61C134.94 19.61 135.29 19.54 135.57 19.41C135.85 19.28 136.06 19.09 136.2 18.86H138.3C138.14 19.33 137.88 19.76 137.53 20.13C137.19 20.51 136.75 20.79 136.23 21C135.72 21.21 135.14 21.31 134.51 21.31C133.72 21.31 133.02 21.15 132.41 20.82C131.81 20.49 131.35 20.02 131.01 19.41C130.68 18.81 130.52 18.1 130.52 17.3C130.52 16.5 130.68 15.8 131.01 15.2C131.34 14.6 131.8 14.13 132.4 13.79C133.01 13.46 133.7 13.29 134.5 13.29ZM134.5 14.99C134.14 14.99 133.81 15.08 133.52 15.26C133.23 15.42 133 15.66 132.83 15.97C132.75 16.14 132.69 16.31 132.65 16.49H136.39C136.349 16.224 136.247 15.9714 136.09 15.7525C135.934 15.5336 135.728 15.3546 135.49 15.23C135.2 15.07 134.86 14.99 134.5 14.99Z" fill="white"/>
|
||||
<path d="M142.58 10.98H140.62V13.43H139.14V15.1H140.62V21.19H142.58V15.1H144.26V13.43H142.58V10.98ZM145.92 10.14H147.88V21.19H145.92V10.14ZM149.95 21.18V13.26C150.21 13.45 150.53 13.55 150.93 13.55C151.33 13.55 151.66 13.46 151.91 13.26V21.18H149.95ZM163.14 18.5L165.26 13.43H167.15L162.84 23.75H160.95L162.14 20.9L159.13 13.43H161.1L163.14 18.5Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_8_30">
|
||||
<rect width="179" height="32" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 7.5 KiB |
5
public/deploy_vercel.svg
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
public/lighthouse-nano.jpg
Normal file
After Width: | Height: | Size: 52 KiB |
BIN
public/lighthouse-sphere.jpg
Normal file
After Width: | Height: | Size: 53 KiB |
BIN
public/pagefind/fragment/en_26435e5.pf_fragment
Normal file
BIN
public/pagefind/fragment/en_2a5e6b1.pf_fragment
Normal file
BIN
public/pagefind/fragment/en_2fed8eb.pf_fragment
Normal file
BIN
public/pagefind/fragment/en_3131981.pf_fragment
Normal file
BIN
public/pagefind/fragment/en_3923b3d.pf_fragment
Normal file
BIN
public/pagefind/fragment/en_3ccfc4e.pf_fragment
Normal file
BIN
public/pagefind/fragment/en_3ec1c2b.pf_fragment
Normal file
BIN
public/pagefind/fragment/en_42f73b1.pf_fragment
Normal file
BIN
public/pagefind/fragment/en_4885cf2.pf_fragment
Normal file
BIN
public/pagefind/fragment/en_4cc991a.pf_fragment
Normal file
BIN
public/pagefind/fragment/en_4f7e69c.pf_fragment
Normal file
BIN
public/pagefind/fragment/en_51fdb47.pf_fragment
Normal file
BIN
public/pagefind/fragment/en_54fba64.pf_fragment
Normal file
BIN
public/pagefind/fragment/en_6935ba6.pf_fragment
Normal file
BIN
public/pagefind/fragment/en_6ee846f.pf_fragment
Normal file
BIN
public/pagefind/fragment/en_7a47df9.pf_fragment
Normal file
BIN
public/pagefind/fragment/en_7cbffcd.pf_fragment
Normal file
BIN
public/pagefind/fragment/en_8826d47.pf_fragment
Normal file
BIN
public/pagefind/fragment/en_a1fb37a.pf_fragment
Normal file
BIN
public/pagefind/fragment/en_a3eb135.pf_fragment
Normal file
BIN
public/pagefind/fragment/en_ad42bb6.pf_fragment
Normal file
BIN
public/pagefind/fragment/en_bbc53aa.pf_fragment
Normal file
BIN
public/pagefind/fragment/en_cf248be.pf_fragment
Normal file
BIN
public/pagefind/fragment/en_cf8ecb3.pf_fragment
Normal file
BIN
public/pagefind/fragment/en_fbe187d.pf_fragment
Normal file
BIN
public/pagefind/fragment/en_fefcc58.pf_fragment
Normal file
BIN
public/pagefind/index/en_8739159.pf_index
Normal file
BIN
public/pagefind/index/en_d0dad81.pf_index
Normal file
1
public/pagefind/pagefind-entry.json
Normal file
|
@ -0,0 +1 @@
|
|||
{"version":"1.1.0","languages":{"en":{"hash":"en_45ddb13fe8","wasm":"en","page_count":13}}}
|
1069
public/pagefind/pagefind-highlight.js
Normal file
214
public/pagefind/pagefind-modular-ui.css
Normal file
|
@ -0,0 +1,214 @@
|
|||
: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);
|
||||
}
|
8
public/pagefind/pagefind-modular-ui.js
Normal file
1
public/pagefind/pagefind-ui.css
Normal file
2
public/pagefind/pagefind-ui.js
Normal file
BIN
public/pagefind/pagefind.en_2e70f624f4.pf_meta
Normal file
BIN
public/pagefind/pagefind.en_3fd8bd6252.pf_meta
Normal file
BIN
public/pagefind/pagefind.en_45ddb13fe8.pf_meta
Normal file
9
public/pagefind/pagefind.js
Normal file
BIN
public/pagefind/wasm.en.pagefind
Normal file
BIN
public/pagefind/wasm.unknown.pagefind
Normal file
BIN
public/paper-teaser.jpg
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
public/rupert-cat.gif
Normal file
After Width: | Height: | Size: 354 KiB |
BIN
public/y-wing.jpeg
Normal file
After Width: | Height: | Size: 218 KiB |
42
src/components/ArrowCard.astro
Normal file
|
@ -0,0 +1,42 @@
|
|||
---
|
||||
import type { CollectionEntry } from "astro:content";
|
||||
|
||||
type Props = {
|
||||
entry: CollectionEntry<"blog">;
|
||||
};
|
||||
|
||||
const { entry } = Astro.props as {
|
||||
entry: CollectionEntry<"blog">;
|
||||
};
|
||||
---
|
||||
|
||||
<a
|
||||
href={`/${entry.collection}/${entry.slug}`}
|
||||
class="not-prose group relative flex flex-nowrap rounded-lg border border-black/15 px-4 py-3 pr-10 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"
|
||||
>
|
||||
<div class="flex flex-1 flex-col truncate">
|
||||
<div class="font-semibold">
|
||||
{entry.data.title}
|
||||
</div>
|
||||
<div class="text-sm">
|
||||
{entry.data.description}
|
||||
</div>
|
||||
</div>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
class="absolute right-2 top-1/2 size-5 -translate-y-1/2 fill-none stroke-current stroke-2"
|
||||
>
|
||||
<line
|
||||
x1="5"
|
||||
y1="12"
|
||||
x2="19"
|
||||
y2="12"
|
||||
class="translate-x-3 scale-x-0 transition-transform duration-300 ease-in-out group-hover:translate-x-0 group-hover:scale-x-100 group-focus-visible:translate-x-0 group-focus-visible:scale-x-100"
|
||||
></line>
|
||||
<polyline
|
||||
points="12 5 19 12 12 19"
|
||||
class="-translate-x-1 transition-transform duration-300 ease-in-out group-hover:translate-x-0 group-focus-visible:translate-x-0"
|
||||
></polyline>
|
||||
</svg>
|
||||
</a>
|
33
src/components/BackToPrevious.astro
Normal file
|
@ -0,0 +1,33 @@
|
|||
---
|
||||
type Props = {
|
||||
href: string;
|
||||
};
|
||||
|
||||
const { href } = Astro.props;
|
||||
---
|
||||
|
||||
<a
|
||||
href={href}
|
||||
class="not-prose group relative flex w-fit flex-nowrap rounded border border-black/15 py-1.5 pl-7 pr-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"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
class="absolute left-2 top-1/2 size-4 -translate-y-1/2 fill-none stroke-current stroke-2"
|
||||
>
|
||||
<line
|
||||
x1="5"
|
||||
y1="12"
|
||||
x2="19"
|
||||
y2="12"
|
||||
class="translate-x-2 scale-x-0 transition-transform duration-300 ease-in-out group-hover:translate-x-0 group-hover:scale-x-100 group-focus-visible:translate-x-0 group-focus-visible:scale-x-100"
|
||||
></line>
|
||||
<polyline
|
||||
points="12 5 5 12 12 19"
|
||||
class="translate-x-1 transition-transform duration-300 ease-in-out group-hover:translate-x-0 group-focus-visible:translate-x-0"
|
||||
></polyline>
|
||||
</svg>
|
||||
<div class="text-sm">
|
||||
<slot />
|
||||
</div>
|
||||
</a>
|
27
src/components/BackToTop.astro
Normal file
|
@ -0,0 +1,27 @@
|
|||
---
|
||||
|
||||
---
|
||||
|
||||
<button
|
||||
id="back-to-top"
|
||||
class="group relative flex w-fit flex-nowrap rounded border border-black/15 py-1.5 pl-8 pr-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"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
class="absolute left-2 top-1/2 size-4 -translate-y-1/2 rotate-90 fill-none stroke-current stroke-2"
|
||||
>
|
||||
<line
|
||||
x1="5"
|
||||
y1="12"
|
||||
x2="19"
|
||||
y2="12"
|
||||
class="translate-x-2 scale-x-0 transition-transform duration-300 ease-in-out group-hover:translate-x-0 group-hover:scale-x-100 group-focus-visible:translate-x-0 group-focus-visible:scale-x-100"
|
||||
></line>
|
||||
<polyline
|
||||
points="12 5 5 12 12 19"
|
||||
class="translate-x-1 transition-transform duration-300 ease-in-out group-hover:translate-x-0 group-focus-visible:translate-x-0"
|
||||
></polyline>
|
||||
</svg>
|
||||
<div class="text-sm">Back to top</div>
|
||||
</button>
|
23
src/components/CVCard.astro
Normal file
|
@ -0,0 +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;
|
||||
---
|
||||
|
||||
<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>
|
44
src/components/Callout.astro
Normal file
|
@ -0,0 +1,44 @@
|
|||
---
|
||||
interface Component {
|
||||
type: "default" | "info" | "warning" | "error";
|
||||
}
|
||||
|
||||
const { type = "default" } = Astro.props;
|
||||
|
||||
let emoji = "💡";
|
||||
|
||||
if (type === "info") {
|
||||
emoji = "ℹ️";
|
||||
} else if (type === "warning") {
|
||||
emoji = "⚠️";
|
||||
} else if (type === "error") {
|
||||
emoji = "🚨";
|
||||
}
|
||||
---
|
||||
|
||||
<div class={`not-prose callout callout-${type}`}>
|
||||
<span class="emoji pointer-events-none select-none">{emoji}</span>
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.callout {
|
||||
@apply relative my-4 flex rounded border border-orange-800 bg-orange-100 p-3 text-orange-950 dark:border-orange-200/20 dark:bg-orange-950/20 dark:text-orange-200;
|
||||
}
|
||||
|
||||
.emoji {
|
||||
@apply pr-3 text-xl;
|
||||
}
|
||||
|
||||
.callout-info {
|
||||
@apply border-blue-800 bg-blue-100 text-blue-950 dark:border-blue-200/20 dark:bg-blue-950/20 dark:text-blue-200;
|
||||
}
|
||||
|
||||
.callout-warning {
|
||||
@apply border-yellow-800 bg-yellow-100 text-yellow-950 dark:border-yellow-200/20 dark:bg-yellow-950/20 dark:text-yellow-200;
|
||||
}
|
||||
|
||||
.callout-error {
|
||||
@apply border-red-800 bg-red-100 text-red-950 dark:border-red-200/20 dark:bg-red-950/20 dark:text-red-200;
|
||||
}
|
||||
</style>
|
5
src/components/Container.astro
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
|
||||
---
|
||||
|
||||
<div class="mx-auto max-w-screen-md px-3"><slot /></div>
|
92
src/components/Footer.astro
Normal file
|
@ -0,0 +1,92 @@
|
|||
---
|
||||
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">
|
||||
<SocialIcons icon_size={'text-xl'} />
|
||||
<BackToTop />
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<div>© {new Date().getFullYear()} • {SITE.TITLE} 👀<br>
|
||||
Built with Astro
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center gap-1.5">
|
||||
<button
|
||||
id="light-theme-button"
|
||||
aria-label="Light theme"
|
||||
class="group flex size-9 items-center justify-center rounded border border-black/15 hover:bg-black/5 focus-visible:bg-black/5 dark:border-white/20 dark:hover:bg-white/5 dark:focus-visible:bg-white/5"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="transition-colors duration-300 ease-in-out group-hover:animate-pulse group-hover:stroke-black group-focus-visible:animate-pulse group-focus-visible:stroke-black group-hover:dark:stroke-white dark:group-focus-visible:stroke-white"
|
||||
>
|
||||
<circle cx="12" cy="12" r="5"></circle>
|
||||
<line x1="12" y1="1" x2="12" y2="3"></line>
|
||||
<line x1="12" y1="21" x2="12" y2="23"></line>
|
||||
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
|
||||
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
|
||||
<line x1="1" y1="12" x2="3" y2="12"></line>
|
||||
<line x1="21" y1="12" x2="23" y2="12"></line>
|
||||
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
|
||||
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
id="dark-theme-button"
|
||||
aria-label="Dark theme"
|
||||
class="group flex size-9 items-center justify-center rounded border border-black/15 hover:bg-black/5 focus-visible:bg-black/5 dark:border-white/20 dark:hover:bg-white/5 dark:focus-visible:bg-white/5"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="transition-colors duration-300 ease-in-out group-hover:animate-pulse group-hover:stroke-black group-focus-visible:animate-pulse group-focus-visible:stroke-black group-hover:dark:stroke-white dark:group-focus-visible:stroke-white"
|
||||
>
|
||||
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
id="system-theme-button"
|
||||
aria-label="System theme"
|
||||
class="group flex size-9 items-center justify-center rounded border border-black/15 hover:bg-black/5 focus-visible:bg-black/5 dark:border-white/20 dark:hover:bg-white/5 dark:focus-visible:bg-white/5"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.5"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="transition-colors duration-300 ease-in-out group-hover:animate-pulse group-hover:stroke-black group-focus-visible:animate-pulse group-focus-visible:stroke-black group-hover:dark:stroke-white dark:group-focus-visible:stroke-white"
|
||||
>
|
||||
<rect x="2" y="3" width="20" height="14" rx="2" ry="2"></rect>
|
||||
<line x1="8" y1="21" x2="16" y2="21"></line>
|
||||
<line x1="12" y1="17" x2="12" y2="21"></line>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</Container>
|
||||
</footer>
|
17
src/components/FormattedDate.astro
Normal file
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
interface Props {
|
||||
date: Date;
|
||||
}
|
||||
|
||||
const { date } = Astro.props;
|
||||
---
|
||||
|
||||
<time datetime={date.toISOString()}>
|
||||
{
|
||||
date.toLocaleDateString("en-US", {
|
||||
month: "long",
|
||||
day: "2-digit",
|
||||
year: "numeric",
|
||||
})
|
||||
}
|
||||
</time>
|
20
src/components/Giscus.astro
Normal file
|
@ -0,0 +1,20 @@
|
|||
<div class="giscus"></div>
|
||||
|
||||
<script
|
||||
is:inline
|
||||
data-astro-rerun
|
||||
src="https://giscus.app/client.js"
|
||||
data-repo="trevortylerlee/astro-micro"
|
||||
data-repo-id="R_kgDOL_6l9Q"
|
||||
data-category="Announcements"
|
||||
data-category-id="DIC_kwDOL_6l9c4Cfk55"
|
||||
data-mapping="pathname"
|
||||
data-strict="0"
|
||||
data-reactions-enabled="1"
|
||||
data-emit-metadata="0"
|
||||
data-input-position="top"
|
||||
data-theme="preferred_color_scheme"
|
||||
data-lang="en"
|
||||
data-loading="lazy"
|
||||
crossorigin="anonymous"
|
||||
async></script>
|
251
src/components/Head.astro
Normal file
|
@ -0,0 +1,251 @@
|
|||
---
|
||||
import "../styles/global.css";
|
||||
import { ViewTransitions } from "astro:transitions";
|
||||
|
||||
import "@fontsource/geist-sans";
|
||||
import "@fontsource/geist-mono";
|
||||
|
||||
interface Props {
|
||||
title: string;
|
||||
description: string;
|
||||
image?: string;
|
||||
}
|
||||
|
||||
const canonicalURL = new URL(Astro.url.pathname, Astro.site);
|
||||
|
||||
const { title, description, image = "/blog-placeholder-1.jpg" } = Astro.props;
|
||||
---
|
||||
|
||||
<!-- Global Metadata -->
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<link
|
||||
rel="icon"
|
||||
href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🍄</text></svg>"
|
||||
/>
|
||||
<meta name="generator" content={Astro.generator} />
|
||||
|
||||
<!-- Canonical URL -->
|
||||
<link rel="canonical" href={canonicalURL} />
|
||||
|
||||
<!-- Primary Meta Tags -->
|
||||
<title>{title}</title>
|
||||
<meta name="title" content={title} />
|
||||
<meta name="description" content={description} />
|
||||
|
||||
<!-- Open Graph / Facebook -->
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content={Astro.url} />
|
||||
<meta property="og:title" content={title} />
|
||||
<meta property="og:description" content={description} />
|
||||
<meta property="og:image" content={new URL(image, Astro.url)} />
|
||||
|
||||
<!-- Twitter -->
|
||||
<meta property="twitter:card" content="summary_large_image" />
|
||||
<meta property="twitter:url" content={Astro.url} />
|
||||
<meta property="twitter:title" content={title} />
|
||||
<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();
|
||||
|
||||
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 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 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);
|
||||
}
|
||||
});
|
||||
|
||||
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");
|
||||
|
||||
function removeActiveButtonTheme(button) {
|
||||
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");
|
||||
}
|
||||
|
||||
removeActiveButtonTheme(lightThemeButton);
|
||||
removeActiveButtonTheme(darkThemeButton);
|
||||
removeActiveButtonTheme(systemThemeButton);
|
||||
|
||||
if (theme === "light") {
|
||||
addActiveButtonTheme(lightThemeButton);
|
||||
} else if (theme === "dark") {
|
||||
addActiveButtonTheme(darkThemeButton);
|
||||
} else {
|
||||
addActiveButtonTheme(systemThemeButton);
|
||||
}
|
||||
}
|
||||
|
||||
function animate() {
|
||||
const animateElements = document.querySelectorAll(".animate");
|
||||
|
||||
animateElements.forEach((element, index) => {
|
||||
setTimeout(() => {
|
||||
element.classList.add("show");
|
||||
}, index * 100);
|
||||
});
|
||||
}
|
||||
|
||||
function onScroll() {
|
||||
if (window.scrollY > 0) {
|
||||
document.documentElement.classList.add("scrolled");
|
||||
} else {
|
||||
document.documentElement.classList.remove("scrolled");
|
||||
}
|
||||
}
|
||||
|
||||
function scrollToTop(event) {
|
||||
event.preventDefault();
|
||||
window.scrollTo({
|
||||
top: 0,
|
||||
behavior: "smooth",
|
||||
});
|
||||
}
|
||||
|
||||
function toggleTheme(dark) {
|
||||
const css = document.createElement("style");
|
||||
|
||||
css.appendChild(
|
||||
document.createTextNode(
|
||||
`* {
|
||||
-webkit-transition: none !important;
|
||||
-moz-transition: none !important;
|
||||
-o-transition: none !important;
|
||||
-ms-transition: none !important;
|
||||
transition: none !important;
|
||||
}
|
||||
`
|
||||
)
|
||||
);
|
||||
|
||||
document.head.appendChild(css);
|
||||
|
||||
if (dark) {
|
||||
document.documentElement.classList.add("dark");
|
||||
} else {
|
||||
document.documentElement.classList.remove("dark");
|
||||
}
|
||||
|
||||
window.getComputedStyle(css).opacity;
|
||||
document.head.removeChild(css);
|
||||
|
||||
setGiscusTheme();
|
||||
}
|
||||
|
||||
function preloadTheme() {
|
||||
const userTheme = localStorage.theme;
|
||||
|
||||
if (userTheme === "light" || userTheme === "dark") {
|
||||
toggleTheme(true); // set default to dark theme
|
||||
} else {
|
||||
toggleTheme(window.matchMedia("(prefers-color-scheme: dark)").matches);
|
||||
}
|
||||
}
|
||||
|
||||
function addCopyCodeButtons() {
|
||||
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, "");
|
||||
|
||||
await navigator.clipboard.writeText(textToCopy);
|
||||
copyButton.innerText = "✅";
|
||||
|
||||
setTimeout(() => {
|
||||
copyButton.innerText = copyButtonLabel;
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
for (let codeBlock of codeBlocks) {
|
||||
const wrapper = document.createElement("div");
|
||||
wrapper.style.position = "relative";
|
||||
|
||||
const copyButton = document.createElement("button");
|
||||
copyButton.innerText = copyButtonLabel;
|
||||
copyButton.classList = "copy-code";
|
||||
|
||||
codeBlock.setAttribute("tabindex", "0");
|
||||
codeBlock.appendChild(copyButton);
|
||||
|
||||
codeBlock.parentNode.insertBefore(wrapper, codeBlock);
|
||||
wrapper.appendChild(codeBlock);
|
||||
|
||||
copyButton?.addEventListener("click", async () => {
|
||||
await copyCode(codeBlock, copyButton);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const setGiscusTheme = () => {
|
||||
const giscus = document.querySelector(".giscus-frame");
|
||||
|
||||
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();
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => init());
|
||||
document.addEventListener("astro:after-swap", () => init());
|
||||
preloadTheme();
|
||||
</script>
|
59
src/components/Header.astro
Normal file
|
@ -0,0 +1,59 @@
|
|||
---
|
||||
import Container from "@components/Container.astro";
|
||||
import Link from "@components/Link.astro";
|
||||
import { SITE } from "@consts";
|
||||
import ProgressBar from "./ProgressBar.astro";
|
||||
---
|
||||
|
||||
<header transition:persist>
|
||||
<Container>
|
||||
<div class="flex flex-wrap justify-between gap-y-2">
|
||||
<Link href="/" underline={false}>
|
||||
<div class="font-semibold">
|
||||
{SITE.TITLE} 🍄
|
||||
</div>
|
||||
</Link>
|
||||
<nav class="flex items-center gap-1 text-sm">
|
||||
<Link href="/blog">blog</Link>
|
||||
<span>
|
||||
{`/`}
|
||||
</span>
|
||||
<Link href="/publications">research</Link>
|
||||
<span>
|
||||
{`/`}
|
||||
</span>
|
||||
<Link href="/cv">cv</Link>
|
||||
<span>
|
||||
{`/`}
|
||||
</span>
|
||||
<Link href="/about">about</Link>
|
||||
<span>
|
||||
{`/`}
|
||||
</span>
|
||||
<Link href="/tags">tags</Link>
|
||||
<span>
|
||||
{`/`}
|
||||
</span>
|
||||
<button
|
||||
id="magnifying-glass"
|
||||
aria-label="Search"
|
||||
class="flex items-center rounded border border-black/15 bg-neutral-100 px-2 py-1 text-xs 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:bg-neutral-900 dark:hover:bg-white/5 dark:hover:text-white dark:focus-visible:bg-white/5 dark:focus-visible:text-white"
|
||||
>
|
||||
<svg
|
||||
height="16"
|
||||
stroke-linejoin="round"
|
||||
viewBox="0 0 16 16"
|
||||
width="16"
|
||||
style="color: currentcolor;"
|
||||
><path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M3.5 7C3.5 5.067 5.067 3.5 7 3.5C8.933 3.5 10.5 5.067 10.5 7C10.5 7.88461 10.1718 8.69256 9.63058 9.30876L9.30876 9.63058C8.69256 10.1718 7.88461 10.5 7 10.5C5.067 10.5 3.5 8.933 3.5 7ZM9.96544 11.0261C9.13578 11.6382 8.11014 12 7 12C4.23858 12 2 9.76142 2 7C2 4.23858 4.23858 2 7 2C9.76142 2 12 4.23858 12 7C12 8.11014 11.6382 9.13578 11.0261 9.96544L14.0303 12.9697L14.5607 13.5L13.5 14.5607L12.9697 14.0303L9.96544 11.0261Z"
|
||||
fill="currentColor"></path></svg
|
||||
>
|
||||
Search
|
||||
</button>
|
||||
</nav>
|
||||
</div>
|
||||
</Container>
|
||||
</header>
|
31
src/components/Link.astro
Normal file
|
@ -0,0 +1,31 @@
|
|||
---
|
||||
import { cn } from "@lib/utils";
|
||||
|
||||
type Props = {
|
||||
href: string;
|
||||
external?: boolean;
|
||||
underline?: boolean;
|
||||
group?: boolean;
|
||||
};
|
||||
|
||||
const {
|
||||
href,
|
||||
external,
|
||||
underline = true,
|
||||
group = false,
|
||||
...rest
|
||||
} = Astro.props;
|
||||
---
|
||||
|
||||
<a
|
||||
href={href}
|
||||
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"
|
||||
)}
|
||||
{...rest}
|
||||
>
|
||||
<slot />
|
||||
</a>
|
132
src/components/PageFind.astro
Normal file
|
@ -0,0 +1,132 @@
|
|||
---
|
||||
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>
|
65
src/components/PostNavigation.astro
Normal file
|
@ -0,0 +1,65 @@
|
|||
---
|
||||
const { prevPost, nextPost } = Astro.props;
|
||||
---
|
||||
|
||||
<div class="grid grid-cols-2 gap-1.5 sm:gap-3">
|
||||
{
|
||||
prevPost?.slug ? (
|
||||
<a
|
||||
href={`/blog/${prevPost?.slug}`}
|
||||
class="group relative flex flex-nowrap rounded-lg border border-black/15 px-4 py-3 pl-10 no-underline 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"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
class="absolute left-2 top-1/2 size-5 -translate-y-1/2 fill-none stroke-current stroke-2"
|
||||
>
|
||||
<line
|
||||
x1="5"
|
||||
y1="12"
|
||||
x2="19"
|
||||
y2="12"
|
||||
class="translate-x-3 scale-x-0 transition-transform duration-300 ease-in-out group-hover:translate-x-0 group-hover:scale-x-100 group-focus-visible:translate-x-0 group-focus-visible:scale-x-100"
|
||||
/>
|
||||
<polyline
|
||||
points="12 5 5 12 12 19"
|
||||
class="translate-x-1 transition-transform duration-300 ease-in-out group-hover:translate-x-0 group-focus-visible:translate-x-0"
|
||||
/>
|
||||
</svg>
|
||||
<div class="flex items-center text-sm">{prevPost?.data.title}</div>
|
||||
</a>
|
||||
) : (
|
||||
<div class="invisible" />
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
nextPost?.slug ? (
|
||||
<a
|
||||
href={`/blog/${nextPost?.slug}`}
|
||||
class="group relative flex flex-grow flex-row-reverse flex-nowrap rounded-lg border border-black/15 px-4 py-4 pr-10 no-underline 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"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
class="absolute right-2 top-1/2 size-5 -translate-y-1/2 fill-none stroke-current stroke-2"
|
||||
>
|
||||
<line
|
||||
x1="5"
|
||||
y1="12"
|
||||
x2="19"
|
||||
y2="12"
|
||||
class="translate-x-3 scale-x-0 transition-transform duration-300 ease-in-out group-hover:translate-x-0 group-hover:scale-x-100 group-focus-visible:translate-x-0 group-focus-visible:scale-x-100"
|
||||
/>
|
||||
<polyline
|
||||
points="12 5 19 12 12 19"
|
||||
class="-translate-x-1 transition-transform duration-300 ease-in-out group-hover:translate-x-0 group-focus-visible:translate-x-0"
|
||||
/>
|
||||
</svg>
|
||||
<div class="flex items-center text-sm">{nextPost?.data.title}</div>
|
||||
</a>
|
||||
) : (
|
||||
<div class="invisible" />
|
||||
)
|
||||
}
|
||||
</div>
|
9
src/components/ProgressBar.astro
Normal file
|
@ -0,0 +1,9 @@
|
|||
<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>
|
||||
|
||||
<script>
|
||||
import { initializeProgressBar } from '../scripts/progress-bar.js';
|
||||
initializeProgressBar();
|
||||
</script>
|
||||
|
74
src/components/PublicationCard.astro
Normal file
|
@ -0,0 +1,74 @@
|
|||
---
|
||||
import type { CollectionEntry } from "astro:content";
|
||||
import { Image } from "astro:assets";
|
||||
import { HIGHLIGHTAUTHOR } from "@consts";
|
||||
|
||||
type Props = {
|
||||
entry: CollectionEntry<"publications">;
|
||||
};
|
||||
|
||||
const { entry } = Astro.props as {
|
||||
entry: CollectionEntry<"publications">;
|
||||
};
|
||||
|
||||
const splitStr = (authors: string | undefined, targetAuthor: string) => {
|
||||
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);
|
||||
|
||||
---
|
||||
|
||||
<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"
|
||||
>
|
||||
<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"
|
||||
/>
|
||||
|
||||
|
||||
<div class="flex items-center h-full">
|
||||
<div class="flex flex-col">
|
||||
<div class="w-full">
|
||||
<div class="text-md font-semibold w-full">
|
||||
{entry.data.title}
|
||||
</div>
|
||||
<div class="text-sm w-full">
|
||||
{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>
|
||||
<div class="text-sm">
|
||||
In <div class="inline italic">{entry.data.pub}</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-sm mt-2 break-words">
|
||||
{entry.data.description}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
18
src/components/SocialIcon.astro
Normal file
|
@ -0,0 +1,18 @@
|
|||
---
|
||||
import 'bootstrap-icons/font/bootstrap-icons.css';
|
||||
|
||||
export interface Props {
|
||||
URL: string;
|
||||
icon: string;
|
||||
icon_size: string
|
||||
}
|
||||
|
||||
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>
|
18
src/components/SocialIcons.astro
Normal file
|
@ -0,0 +1,18 @@
|
|||
---
|
||||
import SocialIcon from "@components/SocialIcon.astro";
|
||||
import { SITE } from "@consts";
|
||||
|
||||
export interface Props {
|
||||
icon_size: string
|
||||
}
|
||||
|
||||
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>
|
54
src/components/TableOfContents.astro
Normal file
|
@ -0,0 +1,54 @@
|
|||
---
|
||||
import TableOfContentsHeading from "./TableOfContentsHeading.astro";
|
||||
|
||||
// https://kld.dev/building-table-of-contents/
|
||||
const { headings } = Astro.props;
|
||||
const toc = buildToc(headings);
|
||||
|
||||
export interface Heading {
|
||||
depth: number;
|
||||
slug: string;
|
||||
text: string;
|
||||
}
|
||||
|
||||
function buildToc(headings: Heading[]) {
|
||||
const toc: Heading[] = [];
|
||||
const parentHeadings = new Map();
|
||||
headings.forEach((h) => {
|
||||
const heading = { ...h, subheadings: [] };
|
||||
parentHeadings.set(heading.depth, heading);
|
||||
if (heading.depth === 2) {
|
||||
toc.push(heading);
|
||||
} else {
|
||||
parentHeadings.get(heading.depth - 1).subheadings.push(heading);
|
||||
}
|
||||
});
|
||||
return toc;
|
||||
}
|
||||
---
|
||||
|
||||
<details
|
||||
open
|
||||
class="animate rounded-lg border border-black/15 dark:border-white/20"
|
||||
>
|
||||
<summary>Table of Contents</summary>
|
||||
<nav class="">
|
||||
<ul class="py-3">
|
||||
{toc.map((heading) => <TableOfContentsHeading heading={heading} />)}
|
||||
</ul>
|
||||
</nav>
|
||||
</details>
|
||||
|
||||
<style>
|
||||
summary {
|
||||
@apply cursor-pointer rounded-t-lg px-3 py-1.5 font-medium transition-colors;
|
||||
}
|
||||
|
||||
summary:hover {
|
||||
@apply bg-black/5 dark:bg-white/5;
|
||||
}
|
||||
|
||||
details[open] summary {
|
||||
@apply bg-black/5 dark:bg-white/5;
|
||||
}
|
||||
</style>
|
23
src/components/TableOfContentsHeading.astro
Normal file
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
import type { Heading } from "./TableOfContents.astro";
|
||||
import Link from "./Link.astro";
|
||||
|
||||
// https://kld.dev/building-table-of-contents/
|
||||
|
||||
const { heading } = Astro.props;
|
||||
---
|
||||
|
||||
<li class="list-inside list-disc px-6 py-1.5 text-sm">
|
||||
<Link href={"#" + heading.slug} underline>
|
||||
{heading.text}
|
||||
</Link>
|
||||
{
|
||||
heading.subheadings.length > 0 && (
|
||||
<ul class="translate-x-3">
|
||||
{heading.subheadings.map((subheading: Heading) => (
|
||||
<Astro.self heading={subheading} />
|
||||
))}
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
</li>
|
46
src/consts.ts
Normal file
|
@ -0,0 +1,46 @@
|
|||
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",
|
||||
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
|
||||
};
|
||||
|
||||
export const HIGHLIGHTAUTHOR = "John B"
|
||||
|
||||
export const HOME: Metadata = {
|
||||
TITLE: "Home",
|
||||
DESCRIPTION: "Astro Micro is an accessible theme for Astro.",
|
||||
};
|
||||
|
||||
export const BLOG: Metadata = {
|
||||
TITLE: "Blog",
|
||||
DESCRIPTION: "A collection of articles on topics I am passionate about.",
|
||||
};
|
||||
|
||||
export const RESEARCH: Metadata = {
|
||||
TITLE: "Publications",
|
||||
DESCRIPTION:
|
||||
"A collection of my publications with links to paper, repositories and live demos.",
|
||||
};
|
||||
|
||||
export const CV: Metadata = {
|
||||
TITLE: "CV",
|
||||
DESCRIPTION:
|
||||
"your cv",
|
||||
};
|
||||
|
||||
export const TAGS: Metadata = {
|
||||
TITLE: "TAGS",
|
||||
DESCRIPTION:
|
||||
"blog tag filter",
|
||||
};
|
||||
|
||||
export const ABOUT: Metadata = {
|
||||
TITLE: "ABOUT",
|
||||
DESCRIPTION:
|
||||
"A self-intro",
|
||||
};
|
51
src/content/blog/00-academic-astro.mdx
Normal file
|
@ -0,0 +1,51 @@
|
|||
---
|
||||
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.
|
||||
|
||||
## What is New
|
||||
|
||||
- Add Math support to the blog
|
||||
- Add News, Research, Publication, CV sections
|
||||
- add icon to connect section
|
||||
- Add tag function to the blog
|
||||
- add RSS Feed icon
|
||||
- add tags to post slug and enable tag based search
|
||||
- add function to RSS feed only posts with rss-feed tags
|
||||
- Change SOCIALS
|
||||
- add highlight author
|
||||
- redo the news section height
|
||||
- support markdown emoji :blush: :exclamation:
|
||||
- Clear and rearrange all the posts
|
||||
- [x] rewrite astro-micro-academics
|
||||
- [x] astro micro
|
||||
- [x] get started with astro micro
|
||||
- [x] blog collection example
|
||||
|
||||
---
|
||||
|
||||
## TODO
|
||||
|
||||
- Add Group Page
|
||||
- Add Opening Section
|
||||
- Add Award Page
|
||||
- Write a complete personal website setup guide
|
||||
- screenshot and submit theme to astro
|
||||
- add progress bar on the top
|
||||
- show tags on allowcard
|
||||
- fix news section scroll bar
|
||||
|
||||
## Math test
|
||||
|
||||
This is an inline formula: $a = b+1$, $a = \frac{1}{x_1}$
|
||||
|
||||
$$
|
||||
a = \sum_{n=1}^{22} \sqrt{a+b_n}
|
||||
$$
|
||||
|
||||
## 中文测试
|
||||
这里是中文测试
|
256
src/content/blog/00-academics-getting-started.md
Normal file
|
@ -0,0 +1,256 @@
|
|||
---
|
||||
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.
|
||||
|
||||
## Install Astro-Micro-Academics
|
||||
|
||||
Clone the [repository](https://github.com/jingwu2121/astro-micro-academic).
|
||||
|
||||
```sh
|
||||
git clone https://github.com/jingwu2121/astro-micro-academic.git
|
||||
```
|
||||
|
||||
```sh
|
||||
cd astro-micro-academic
|
||||
```
|
||||
|
||||
```sh
|
||||
npm i
|
||||
```
|
||||
|
||||
Run local server
|
||||
```sh
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## Update the Homepage
|
||||
|
||||
Update your home page in `src/pages/index.astro`.
|
||||
|
||||
|
||||
## CV & About
|
||||
|
||||
Update your CV and About page in `src/pages/cv.astro` and `src/pages/about.astro`.
|
||||
|
||||
```ts
|
||||
const works = [
|
||||
{company:"Company A", time: "2022-Present", job_title: "Research Scientist", location: "London, UK", description: "Your Notes about the job"},
|
||||
{company:"Company A", time: "2022-Present", job_title: "Research Scientist", location: "London, UK", description: "Your Notes about the job"},
|
||||
]
|
||||
const educations = [
|
||||
{school:"University 1", time: "2022-Present", job_title: "BEng in Electronic Information Engineering", location: "London, UK", description: "Your Notes about the study"},
|
||||
]
|
||||
```
|
||||
|
||||
## Social Links
|
||||
|
||||
Update the social links in `src/components/SocialIcons.astro`, simply replace the `URL`.
|
||||
|
||||
## Publications metadata
|
||||
|
||||
Metadata is required for each post. Add a new `publication.md` to automartically add a publication on the website. Publications are sorted by date.
|
||||
|
||||
```astro
|
||||
---
|
||||
title: "Diffusion Models Beat GANs on Image Synthesis"
|
||||
description: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestias earum quod quo repellat blanditiis est iste eos dolorem! Voluptatibus corporis totam sed unde est iusto neque iure natus adipisci omnis."
|
||||
date: "2024-07-26"
|
||||
authors: "John B*, Jon A*, Frank C, John B, Jon A, Frank C"
|
||||
paperURL: "Paper: https://astro-sphere-demo.vercel.app"
|
||||
codeURL: "Code: "
|
||||
webURL: "Web: https://github.com/markhorn-dev/astro-sphere"
|
||||
dataURL: "Data: https://github.com/markhorn-dev/astro-sphere"
|
||||
img: "/rupert-cat.gif"
|
||||
imgAlt: "Paper Teaser"
|
||||
pub: "ECCV2024"
|
||||
---
|
||||
```
|
||||
|
||||
| Field | Req | Type | Remarks |
|
||||
| :---------- | :-- | :------ | :----------------------------------------------- |
|
||||
| title | Yes | string | Title of the content. Used in SEO and RSS. |
|
||||
| description | Yes | string | Description of the content. Used in SEO and RSS. |
|
||||
| date | Yes | string | Must be a valid date string (able to be parsed). |
|
||||
| authors | Yes | string | A string seperated by comma. |
|
||||
| paperURL, codeURL, webURL, dataURL | Yes | string | A string seperated by ": ". If you don't have a link to add, leave the link part blank, e.g. `codeURL: "Code: "` |
|
||||
| img | Yes | string | Path to teaser image. |
|
||||
| imgAlt | Yes | string | Description of the image. |
|
||||
| pub | Yes | string | The conference or journal |
|
||||
|
||||
## Blog metadata
|
||||
|
||||
Metadata is required for each post.
|
||||
|
||||
```astro
|
||||
---
|
||||
title: "Blog Collection";
|
||||
description: "How to add posts to the blog.";
|
||||
date: "2024-03-21";
|
||||
tags: ['guide', 'tutorial']
|
||||
draft: false;
|
||||
---
|
||||
```
|
||||
|
||||
| Field | Req | Type | Remarks |
|
||||
| :---------- | :-- | :------ | :----------------------------------------------- |
|
||||
| title | Yes | string | Title of the content. Used in SEO and RSS. |
|
||||
| description | Yes | string | Description of the content. Used in SEO and RSS. |
|
||||
| date | Yes | string | Must be a valid date string (able to be parsed). |
|
||||
| tags | Yes | list | A list of strings |
|
||||
| draft | No | boolean | If draft: true, content will not be published. |
|
||||
|
||||
## Customize the website metadata and set up RSS
|
||||
|
||||
To change the website metadata, edit `src/consts.ts`.
|
||||
|
||||
```ts
|
||||
// src/consts.ts
|
||||
|
||||
export const SITE: Site = {
|
||||
TITLE: "Astro Micro Academics",
|
||||
DESCRIPTION: "Astro Micro Academics is for academic user.",
|
||||
EMAIL: "youremial@gmail.com",
|
||||
NUM_POSTS_ON_HOMEPAGE: 2,
|
||||
NUM_PUBLICATIONS_ON_HOMEPAGE: 3,
|
||||
SITEURL: 'https://astro-micro-academic.vercel.app' // Update here to link the RSS icon to your website RSS
|
||||
};
|
||||
```
|
||||
|
||||
| Field | Req | Description |
|
||||
| :----------- | :-- | :--------------------------------------------------- |
|
||||
| TITLE | Yes | Displayed in header and footer. Used in SEO and RSS. |
|
||||
| DESCRIPTION | Yes | Used in SEO and RSS. |
|
||||
| EMAIL | Yes | Displayed in contact section. |
|
||||
| NUM_POSTS | Yes | Limit number of posts on home page. |
|
||||
| NUM_PUBLICATIONS | Yes | Limit number of research on home page. |
|
||||
| SITEURL | Yes | Your website URL |
|
||||
|
||||
### RSS Post
|
||||
|
||||
Please tag the post of RSS feed with tag `"rss-feed"`, other posts are not included in the RSS.
|
||||
|
||||
---
|
||||
|
||||
## Custom metadata for highlighted author in your paper
|
||||
|
||||
```ts
|
||||
// src/consts.ts
|
||||
|
||||
export const HIGHLIGHTAUTHOR = "John B"
|
||||
```
|
||||
|
||||
## Customize metadata for individual pages
|
||||
|
||||
```ts
|
||||
// src/consts.ts
|
||||
|
||||
export const HOME: Metadata = {
|
||||
TITLE: "Home",
|
||||
DESCRIPTION: "Astro Micro is an accessible theme for Astro.",
|
||||
};
|
||||
|
||||
export const BLOG: Metadata = {
|
||||
TITLE: "Blog",
|
||||
DESCRIPTION: "A collection of articles on topics I am passionate about.",
|
||||
};
|
||||
|
||||
export const RESEARCH: Metadata = {
|
||||
TITLE: "Publications",
|
||||
DESCRIPTION:
|
||||
"A collection of my publications with links to paper, repositories and live demos.",
|
||||
};
|
||||
|
||||
export const CV: Metadata = {
|
||||
TITLE: "CV",
|
||||
DESCRIPTION:
|
||||
"your cv",
|
||||
};
|
||||
|
||||
export const TAGS: Metadata = {
|
||||
TITLE: "TAGS",
|
||||
DESCRIPTION:
|
||||
"blog tag filter",
|
||||
};
|
||||
|
||||
export const ABOUT: Metadata = {
|
||||
TITLE: "ABOUT",
|
||||
DESCRIPTION:
|
||||
"A self-intro",
|
||||
};
|
||||
```
|
||||
|
||||
| Field | Req | Description |
|
||||
| :---------- | :-- | :--------------------------------------------- |
|
||||
| TITLE | Yes | Displayed in browser tab. Used in SEO and RSS. |
|
||||
| DESCRIPTION | Yes | Used in SEO and RSS. |
|
||||
|
||||
---
|
||||
|
||||
## Deploy the site
|
||||
|
||||
To set up RSS and Giscus, it's easier if the site is deployed and has a URL for you to use. Instantly deploy to Vercel or Netlify by clicking the buttons below.
|
||||
|
||||
<div class="flex gap-2">
|
||||
<a target="_blank" aria-label="Deploy with Vercel" href="https://vercel.com/new/clone?repository-url=https://github.com/trevortylerlee/astro-micro">
|
||||
<img src="/deploy_vercel.svg" />
|
||||
</a>
|
||||
<a target="_blank" aria-label="Deploy with Netlify" href="https://app.netlify.com/start/deploy?repository=https://github.com/trevortylerlee/astro-micro">
|
||||
<img src="/deploy_netlify.svg" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
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/).
|
||||
|
||||
|
||||
## 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.
|
||||
|
||||
```js
|
||||
// src/components/Giscus.astro
|
||||
|
||||
<script
|
||||
is:inline
|
||||
src="https://giscus.app/client.js"
|
||||
data-repo="trevortylerlee/astro-micro"
|
||||
data-repo-id="R_kgDOL_6l9Q"
|
||||
data-category="Announcements"
|
||||
data-category-id="DIC_kwDOL_6l9c4Cfk55"
|
||||
data-mapping="pathname"
|
||||
data-strict="0"
|
||||
data-reactions-enabled="1"
|
||||
data-emit-metadata="0"
|
||||
data-input-position="top"
|
||||
data-theme="preferred_color_scheme"
|
||||
data-lang="en"
|
||||
data-loading="lazy"
|
||||
crossorigin="anonymous"
|
||||
async></script>
|
||||
|
||||
```
|
||||
|
||||
To change the Giscus themes used, edit the `setGiscusTheme` function in `Head.astro`.
|
||||
|
||||
```js
|
||||
// src/components/Head.astro
|
||||
|
||||
const setGiscusTheme = () => {
|
||||
const giscus = document.querySelector(".giscus-frame");
|
||||
|
||||
const isDark = document.documentElement.classList.contains("dark");
|
||||
|
||||
if (giscus) {
|
||||
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();
|
||||
}
|
||||
};
|
||||
```
|
105
src/content/blog/00-astro-micro-changelog/index.mdx
Normal file
|
@ -0,0 +1,105 @@
|
|||
---
|
||||
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";
|
||||
|
||||
---
|
||||
|
||||
## Pagefind search 🔎
|
||||
|
||||
[Pagefind](https://pagefind.app) is a search library for static websites. Micro uses [Sergey Shishkin's](https://github.com/shishkin) [astro-pagefind](https://github.com/shishkin/astro-pagefind) integration. This integration simplifies development and does not require any changes to the default build script.
|
||||
|
||||
Press <kbd>/</kbd> or <kbd>CTRL</kbd> + <kbd>K</kbd> to open the search dialog. For Mac users, <kbd>⌘</kbd> + <kbd>K</kbd> can also be used. To dismiss the search dialog, press <kbd>Esc</kbd> or click on an area outside the component.
|
||||
|
||||
### Build and develop
|
||||
|
||||
<Callout type="error">
|
||||
The site **must** be built at least once so Pagefind can index the content.
|
||||
</Callout>
|
||||
|
||||
```bash
|
||||
# Pagefind must index the site to function
|
||||
npm run build
|
||||
```
|
||||
|
||||
When developing you can continue to use `npm run dev` and Pagefind will use the index from the last available build.
|
||||
|
||||
---
|
||||
|
||||
## Giscus comments 💬
|
||||
|
||||
[Giscus](https://giscus.app) leverages Github discussions to act as a comments system. To get Giscus working on your own website, see [here](/blog/01-getting-started#deploy-the-site).
|
||||
|
||||
---
|
||||
|
||||
## Callout component 🆕
|
||||
|
||||
<Callout>
|
||||
Adipisicing et officia reprehenderit fugiat occaecat cupidatat exercitation
|
||||
labore consequat ullamco nostrud non.
|
||||
</Callout>
|
||||
|
||||
<Callout type="info">
|
||||
Adipisicing et officia reprehenderit fugiat occaecat cupidatat exercitation
|
||||
labore consequat ullamco nostrud non.
|
||||
</Callout>
|
||||
|
||||
<Callout type="warning">
|
||||
Adipisicing et officia reprehenderit fugiat occaecat cupidatat exercitation
|
||||
labore consequat ullamco nostrud non.
|
||||
</Callout>
|
||||
|
||||
<Callout type="error">
|
||||
Adipisicing et officia reprehenderit fugiat occaecat cupidatat exercitation
|
||||
labore consequat ullamco nostrud non.
|
||||
</Callout>
|
||||
|
||||
---
|
||||
|
||||
## UI enhancements 🎨
|
||||
|
||||
- Elements are styled and animate on focus
|
||||
- Increased contrast in light mode
|
||||
- Active theme is indicated by theme buttons
|
||||
- Separate syntax highlight themes for light and dark mode
|
||||
- Code blocks have a copy button
|
||||
- Add pagination to the bottom of blog posts
|
||||
- Create 404 page
|
||||
- Add ToC component to posts
|
||||
|
||||
---
|
||||
|
||||
## Other changes
|
||||
|
||||
- Change fonts to Geist Sans and Geist Mono
|
||||
- Switch base color from "stone" to "neutral"
|
||||
- Change formatted date to use "long" option for month
|
||||
- Minor spacing changes throughout
|
||||
- Remove "work" collection and components
|
||||
- If desired, you can get the code from [Astro Nano](https://github.com/markhorn-dev/astro-nano)
|
||||
- Slightly increased link decoration offset
|
||||
- Slightly sped-up animations
|
||||
- Reversed animation
|
||||
- Ensure posts use an h1 tag for post titles
|
||||
- Tweaked typography
|
||||
|
||||
---
|
||||
|
||||
## Issues ⚠️
|
||||
|
||||
### Active issues
|
||||
|
||||
- [PostNavigation.astro is broken when deployed with Cloudflare Pages](https://github.com/trevortylerlee/astro-micro/issues/39)
|
||||
|
||||
### Closed issues
|
||||
|
||||
- Fixed by [blopker](https://github.com/blopker): [Pagefind requires a refresh to function when ViewTransitions is enabled](https://github.com/trevortylerlee/astro-micro/issues/7)
|
||||
- Fixed by [blopker](https://github.com/blopker): [ToC links are obscured by Header when scrolled to](https://github.com/trevortylerlee/astro-micro/issues/4)
|
||||
- Fixed by [cgranier](https://github.com/cgranier): [Pagination links advance by slug/folder](https://github.com/trevortylerlee/astro-micro/issues/26)
|
||||
- Fixed by [cgranier](https://github.com/cgranier): [Hides Table of Contents when there are no headings](https://github.com/trevortylerlee/astro-micro/pull/30)
|
||||
- Fixed by [arastoonet](https://github.com/arastoonet): [Fix typo in README](https://github.com/trevortylerlee/astro-micro/pull/19)
|
||||
- Fixed by [luciancah](https://github.com/luciancah): [Prevent Pagefind from double-indexing results](https://github.com/trevortylerlee/astro-micro/issues/40)
|
181
src/content/blog/01-getting-started.md
Normal file
|
@ -0,0 +1,181 @@
|
|||
---
|
||||
title: "[Old] Getting started with Astro-Micro"
|
||||
description: "Hit the ground running."
|
||||
date: "2024-03-22"
|
||||
tags: ['guide', 'start']
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
## Install astro-micro
|
||||
|
||||
Clone the [Astro Micro repository](https://github.com/trevortylerlee/astro-micro.git).
|
||||
|
||||
```sh
|
||||
git clone https://github.com/trevortylerlee/astro-micro.git my-astro-micro
|
||||
```
|
||||
|
||||
```sh
|
||||
cd my-astro-micro
|
||||
```
|
||||
|
||||
```sh
|
||||
npm i
|
||||
```
|
||||
|
||||
```sh
|
||||
npm run build
|
||||
```
|
||||
|
||||
```sh
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## Customize the website metadata
|
||||
|
||||
To change the website metadata, edit `src/consts.ts`.
|
||||
|
||||
```ts
|
||||
// src/consts.ts
|
||||
|
||||
export const SITE: Site = {
|
||||
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. |
|
||||
| NUM_PUBLICATIONS | Yes | Limit number of research on home page. |
|
||||
|
||||
---
|
||||
|
||||
## Customize metadata for individual pages
|
||||
|
||||
```ts
|
||||
// src/consts.ts
|
||||
|
||||
export const ABOUT: Metadata = {
|
||||
TITLE: "About",
|
||||
DESCRIPTION: "Astro Micro is a fork of Astro Nano.",
|
||||
};
|
||||
```
|
||||
|
||||
| Field | Req | Description |
|
||||
| :---------- | :-- | :--------------------------------------------- |
|
||||
| TITLE | Yes | Displayed in browser tab. Used in SEO and RSS. |
|
||||
| DESCRIPTION | Yes | Used in SEO and RSS. |
|
||||
|
||||
---
|
||||
|
||||
## ~~Add your social media links~~ Removed in Micro Academics
|
||||
|
||||
```ts
|
||||
// src/consts.ts
|
||||
|
||||
export const SOCIALS: Socials = [
|
||||
{
|
||||
NAME: "twitter-x",
|
||||
HREF: "https://twitter.com/boogerbuttcheeks",
|
||||
},
|
||||
{
|
||||
NAME: "github",
|
||||
HREF: "https://github.com/trevortylerlee",
|
||||
},
|
||||
{
|
||||
NAME: "linkedin",
|
||||
HREF: "https://www.linkedin.com/in/trevortylerlee",
|
||||
},
|
||||
];
|
||||
```
|
||||
|
||||
| Field | Req | Description |
|
||||
| :---- | :-- | :-------------------------------------- |
|
||||
| NAME | Yes | Displayed in contact section as a link. |
|
||||
| HREF | Yes | External url to social media profile. |
|
||||
|
||||
## Deploy the site
|
||||
|
||||
To set up RSS and Giscus, it's easier if the site is deployed and has a URL for you to use. Instantly deploy to Vercel or Netlify by clicking the buttons below.
|
||||
|
||||
<div class="flex gap-2">
|
||||
<a target="_blank" aria-label="Deploy with Vercel" href="https://vercel.com/new/clone?repository-url=https://github.com/trevortylerlee/astro-micro">
|
||||
<img src="/deploy_vercel.svg" />
|
||||
</a>
|
||||
<a target="_blank" aria-label="Deploy with Netlify" href="https://app.netlify.com/start/deploy?repository=https://github.com/trevortylerlee/astro-micro">
|
||||
<img src="/deploy_netlify.svg" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
To deploy manually see [Astro's docs](https://docs.astro.build/en/guides/deploy/).
|
||||
|
||||
## ~~Set up RSS~~ New config in Astro Micro Academics
|
||||
|
||||
Change the `site` option to the deployed site's URL.
|
||||
|
||||
```js
|
||||
// astro.config.mjs
|
||||
|
||||
export default defineConfig({
|
||||
site: "https://astro-micro.vercel.app",
|
||||
integrations: [tailwind(), sitemap(), mdx(), pagefind()],
|
||||
markdown: {
|
||||
shikiConfig: {
|
||||
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.
|
||||
|
||||
```js
|
||||
// src/components/Giscus.astro
|
||||
|
||||
<script
|
||||
is:inline
|
||||
src="https://giscus.app/client.js"
|
||||
data-repo="trevortylerlee/astro-micro"
|
||||
data-repo-id="R_kgDOL_6l9Q"
|
||||
data-category="Announcements"
|
||||
data-category-id="DIC_kwDOL_6l9c4Cfk55"
|
||||
data-mapping="pathname"
|
||||
data-strict="0"
|
||||
data-reactions-enabled="1"
|
||||
data-emit-metadata="0"
|
||||
data-input-position="top"
|
||||
data-theme="preferred_color_scheme"
|
||||
data-lang="en"
|
||||
data-loading="lazy"
|
||||
crossorigin="anonymous"
|
||||
async></script>
|
||||
|
||||
```
|
||||
|
||||
To change the Giscus themes used, edit the `setGiscusTheme` function in `Head.astro`.
|
||||
|
||||
```js
|
||||
// src/components/Head.astro
|
||||
|
||||
const setGiscusTheme = () => {
|
||||
const giscus = document.querySelector(".giscus-frame");
|
||||
|
||||
const isDark = document.documentElement.classList.contains("dark");
|
||||
|
||||
if (giscus) {
|
||||
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();
|
||||
}
|
||||
};
|
||||
```
|
63
src/content/blog/02-blog-collection/index.md
Normal file
|
@ -0,0 +1,63 @@
|
|||
---
|
||||
title: "[Old] Blog Collection"
|
||||
description: "How to add posts to the blog."
|
||||
date: "2024-03-21"
|
||||
tags: ['aa']
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
## Working with the `blog` collection:
|
||||
|
||||
The `blog` collection is found in `src/content/blog`.
|
||||
|
||||
```
|
||||
📁 /src/content/blog
|
||||
└── 📁 post-1
|
||||
└── 📄 index.md
|
||||
└── 📁 post-2
|
||||
└── 📄 index.mdx
|
||||
```
|
||||
|
||||
In the above example, two blog posts will be generated with the folder name representing the slug.
|
||||
|
||||
- `https://example.com/blog/post-1`
|
||||
- `https://example.com/blog/post-2`
|
||||
|
||||
---
|
||||
|
||||
## Provide metadata
|
||||
|
||||
Metadata is required for each post.
|
||||
|
||||
```astro
|
||||
---
|
||||
title: "Blog Collection";
|
||||
description: "How to add posts to the blog.";
|
||||
date: "2024-03-21";
|
||||
draft: false;
|
||||
---
|
||||
```
|
||||
|
||||
| Field | Req | Type | Remarks |
|
||||
| :---------- | :-- | :------ | :----------------------------------------------- |
|
||||
| title | Yes | string | Title of the content. Used in SEO and RSS. |
|
||||
| description | Yes | string | Description of the content. Used in SEO and RSS. |
|
||||
| date | Yes | string | Must be a valid date string (able to be parsed). |
|
||||
| draft | No | boolean | If draft: true, content will not be published. |
|
||||
|
||||
---
|
||||
|
||||
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;
|
||||
---
|
||||
|
||||
## Working with the blog collection
|
||||
<!-- content -->
|
||||
```
|
398
src/content/blog/04-markdown-syntax/index.mdx
Normal file
|
@ -0,0 +1,398 @@
|
|||
---
|
||||
title: "[Old] Markdown syntax guide"
|
||||
description: "Get started writing content in Markdown."
|
||||
date: "2024-03-17"
|
||||
---
|
||||
|
||||
import Callout from "@/components/Callout.astro";
|
||||
|
||||
---
|
||||
|
||||
## Headings
|
||||
|
||||
To create headings, use hash symbols (#) followed by a space. The number of hash symbols indicates the heading level.
|
||||
|
||||
<Callout>
|
||||
Use `h2` tags instead of `h1` tags in the post. Too many `h1` tags on a single
|
||||
page can impact SEO. The post title serves as the `h1`.
|
||||
</Callout>
|
||||
|
||||
```md
|
||||
# Heading 1
|
||||
|
||||
## Heading 2
|
||||
|
||||
### Heading 3
|
||||
|
||||
#### Heading 4
|
||||
|
||||
##### Heading 5
|
||||
|
||||
###### Heading 6
|
||||
```
|
||||
|
||||
<h1>Heading 1</h1>
|
||||
<h2>Heading 2</h2>
|
||||
<h3>Heading 3</h3>
|
||||
<h4>Heading 4</h4>
|
||||
<h5>Heading 5</h5>
|
||||
<h6>Heading 6</h6>
|
||||
|
||||
---
|
||||
|
||||
## Paragraphs
|
||||
|
||||
To create paragraphs, use a blank line to separate one or more lines of text.
|
||||
|
||||
{/* prettier-ignore */}
|
||||
```md
|
||||
<!-- empty line -->
|
||||
I love Star Wars.
|
||||
<!-- empty line -->
|
||||
My favourite is Episode III – Revenge of the Sith.
|
||||
<!-- empty line -->
|
||||
```
|
||||
|
||||
I love Star Wars.
|
||||
|
||||
My favourite is Episode III – Revenge of the Sith.
|
||||
|
||||
---
|
||||
|
||||
## Italic
|
||||
|
||||
Use one asterisk \(\*\) or underscore \(\_\) to italicize text.
|
||||
|
||||
{/* prettier-ignore */}
|
||||
```md
|
||||
I *love* Star Wars.
|
||||
My _favourite_ is Episode III – Revenge of the Sith.
|
||||
```
|
||||
|
||||
I _love_ Star Wars.
|
||||
My _favourite_ is Episode III – Revenge of the Sith.
|
||||
|
||||
---
|
||||
|
||||
## Bold
|
||||
|
||||
Use two asterisks \(\*\) or underscores \(\_\) to bold text.
|
||||
|
||||
{/* prettier-ignore */}
|
||||
```md
|
||||
I **love** Star Wars.
|
||||
My __favourite__ is Episode III – Revenge of the Sith.
|
||||
```
|
||||
|
||||
I **love** Star Wars.
|
||||
My **favourite** is Episode III – Revenge of the Sith.
|
||||
|
||||
---
|
||||
|
||||
## Italic and Bold
|
||||
|
||||
Use three asterisks \(\*\) or underscores \(\_\) to both bold and italicize text.
|
||||
|
||||
{/* prettier-ignore */}
|
||||
```md
|
||||
I ***love*** Star Wars.
|
||||
My ___favourite___ is Episode III – Revenge of the Sith.
|
||||
```
|
||||
|
||||
I **_love_** Star Wars.
|
||||
My **_favourite_** is Episode III – Revenge of the Sith.
|
||||
|
||||
---
|
||||
|
||||
## Horizontal Rule
|
||||
|
||||
Use three hyphens \(\-\), asterisks \(\*\), or underscores \(\_\) to create a horizontal rule.
|
||||
|
||||
{/* prettier-ignore */}
|
||||
```md
|
||||
<!-- empty line -->
|
||||
---
|
||||
<!-- empty line -->
|
||||
***
|
||||
<!-- empty line -->
|
||||
___
|
||||
<!-- empty line -->
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
## Links
|
||||
|
||||
To create a link, the link text in brackets \(\[\]\) and then follow it immediately with the URL in parentheses \(\(\)\).
|
||||
|
||||
```md
|
||||
Micro is a fork of [astro-nano](https://github.com/markhorn-dev/astro-nano).
|
||||
```
|
||||
|
||||
Micro is a fork of [astro-nano](https://github.com/markhorn-dev/astro-nano).
|
||||
|
||||
---
|
||||
|
||||
## Ordered Lists
|
||||
|
||||
To create an ordered list, add line items with numbers followed by periods. Use an indent to create a nested list.
|
||||
|
||||
```md
|
||||
1. Item 1
|
||||
2. Item 2
|
||||
1. Sub item 1
|
||||
2. Sub item 2
|
||||
3. Item 3
|
||||
```
|
||||
|
||||
1. Item 1
|
||||
2. Item 2
|
||||
1. Sub item 1
|
||||
2. Sub item 2
|
||||
3. Item 3
|
||||
|
||||
---
|
||||
|
||||
## Unordered List
|
||||
|
||||
To create an unordered list, add a hyphen \(\-\), an asterisk \(\*\), or a plus sign \(\+\) in front of line items. Don't mix. Use an indent to create a nested list.
|
||||
|
||||
```md
|
||||
- Item 1
|
||||
- Item 2
|
||||
- Sub item 1
|
||||
- Sub item 2
|
||||
- Item 3
|
||||
```
|
||||
|
||||
- Item 1
|
||||
- Item 2
|
||||
- Sub item 1
|
||||
- Sub item 2
|
||||
- Item 3
|
||||
|
||||
---
|
||||
|
||||
## Images
|
||||
|
||||
To add an image, add an exclamation mark (!), followed by alt text in brackets ([]), and the path or URL to the image asset in parentheses.
|
||||
|
||||
```md
|
||||

|
||||
```
|
||||
|
||||
### Relative
|
||||
|
||||
Use the `` pattern relative to the same folder as the markdown file. Notice the period.
|
||||
|
||||
```md
|
||||

|
||||
```
|
||||
|
||||

|
||||
|
||||
### Public Image
|
||||
|
||||
Use the `` pattern relative to the public folder. No period.
|
||||
|
||||
```md
|
||||

|
||||
```
|
||||
|
||||

|
||||
|
||||
### External Image
|
||||
|
||||
Use the `` pattern.
|
||||
|
||||
```md
|
||||

|
||||
```
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## Blockquotes
|
||||
|
||||
To add a blockquote add the greater-than character \(\>\) before a paragraph. For multi-line blockquotes, add additional greater-than character for each line and include an empty spacer line.
|
||||
|
||||
```md
|
||||
> So this is how liberty dies...
|
||||
>
|
||||
> with thunderous applause.
|
||||
```
|
||||
|
||||
> So this is how liberty dies...
|
||||
>
|
||||
> with thunderous applause.
|
||||
|
||||
---
|
||||
|
||||
## Strikethrough
|
||||
|
||||
Use a tilde \(\~\) symbol to strikethrough text.
|
||||
|
||||
```md
|
||||
~I don't like sand.~ It's coarse and rough and irritating.
|
||||
```
|
||||
|
||||
~I don't like sand.~ It's coarse and rough and irritating.
|
||||
|
||||
---
|
||||
|
||||
## Subscript
|
||||
|
||||
Use the `<sub>` tag to denote subscript.
|
||||
|
||||
```md
|
||||
H<sub>2</sub>O
|
||||
```
|
||||
|
||||
H<sub>2</sub>O
|
||||
|
||||
---
|
||||
|
||||
## Superscript
|
||||
|
||||
Use the `<sup>` tag to denote superscript.
|
||||
|
||||
```md
|
||||
E=mc<sup>2</sup>
|
||||
```
|
||||
|
||||
E=mc<sup>2</sup>
|
||||
|
||||
---
|
||||
|
||||
## Keyboard
|
||||
|
||||
Use the `<kbd>` tag to denote keys on the keyboard.
|
||||
|
||||
```md
|
||||
<kbd>CTRL</kbd> + <kbd>ALT</kbd> + <kbd>Delete</kbd>
|
||||
```
|
||||
|
||||
<kbd>CTRL</kbd> + <kbd>ALT</kbd> + <kbd>Delete</kbd>
|
||||
|
||||
---
|
||||
|
||||
## Abbreviate
|
||||
|
||||
Use the `<abbr>` tag to denote abbreviation.
|
||||
|
||||
```md
|
||||
<abbr title="Graphics Interchange Format">GIF</abbr>
|
||||
```
|
||||
|
||||
<abbr title="Graphics Interchange Format">GIF</abbr>
|
||||
|
||||
---
|
||||
|
||||
### Highlight
|
||||
|
||||
Use the `<mark>` tag to denote highlighted text.
|
||||
|
||||
```md
|
||||
Do or do not. <mark>There is no try.</mark>
|
||||
```
|
||||
|
||||
Do or do not. <mark>There is no try.</mark>
|
||||
|
||||
---
|
||||
|
||||
## Task Lists
|
||||
|
||||
Combine a list with square brackets ([]) representing a checkbox. Typing `x` inside the brackets marks the task as complete.
|
||||
|
||||
```md
|
||||
- [x] Build a lightsaber
|
||||
- [ ] Pass the Jedi Trials
|
||||
- [ ] Train a padawan
|
||||
```
|
||||
|
||||
- [x] Build a lightsaber
|
||||
- [ ] Pass the Jedi Trials
|
||||
- [ ] Train a padawan
|
||||
|
||||
---
|
||||
|
||||
## Tables
|
||||
|
||||
Use three or more hyphens (-) for the column headers and use pipes (|) to separate each column. You can align text in the columns to the left, right, or center by adding a colon (:) to the left, right, or on both side of the hyphens.
|
||||
|
||||
```md
|
||||
| Item | Count |
|
||||
| :----- | ----: |
|
||||
| X-Wing | 1 |
|
||||
| Y-Wing | 2 |
|
||||
| A-Wing | 3 |
|
||||
```
|
||||
|
||||
| Item | Count |
|
||||
| :----- | ----: |
|
||||
| X-Wing | 1 |
|
||||
| Y-Wing | 2 |
|
||||
| A-Wing | 3 |
|
||||
|
||||
---
|
||||
|
||||
## Footnotes
|
||||
|
||||
Add a caret (^) and an identifier inside brackets \(\[\^1\]\). Identifiers can be numbers or words but can't contain spaces or tabs.
|
||||
|
||||
```md
|
||||
Here's a footnote, [^1] and here's another one. [^2]
|
||||
[^1]: This is the first footnote.
|
||||
[^2]: This is the second footnote.
|
||||
```
|
||||
|
||||
Here's a footnote, [^1] and here's another one. [^2]
|
||||
[^1]: This is the first footnote.
|
||||
[^2]: This is the second footnote.
|
||||
|
||||
See the bottom of this page to view the footnotes.
|
||||
|
||||
---
|
||||
|
||||
## Code
|
||||
|
||||
To denote a word or phrase as code, enclose it in backticks (`).
|
||||
|
||||
```md
|
||||
`package.json`
|
||||
```
|
||||
|
||||
`package.json`
|
||||
|
||||
---
|
||||
|
||||
## Code Blocks
|
||||
|
||||
Denote a code block by wrapping a section of valid code in triple backticks (`). To enable syntax highlighting, type the shorthand symbol for the language after the first three backticks. [Reference for shorthand symbols](https://shiki.style/languages).
|
||||
|
||||
````
|
||||
```js
|
||||
function hello() {
|
||||
console.log("hello world");
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
```js
|
||||
function hello() {
|
||||
console.log("hello world");
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Conclusion
|
||||
|
||||
Refer to [markdownguide.org](https://www.markdownguide.org/) for best practices as well as extended syntax.
|
||||
|
||||
---
|
BIN
src/content/blog/04-markdown-syntax/x-wing.jpeg
Normal file
After Width: | Height: | Size: 203 KiB |
10
src/content/blog/05-mdx-syntax/component.astro
Normal file
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
|
||||
---
|
||||
|
||||
<button
|
||||
onclick="alert(`You clicked the button!`)"
|
||||
class="border border-black/10 p-2 transition-colors duration-300 ease-in-out hover:bg-black/5 dark:border-white/10 dark:hover:bg-white/10"
|
||||
>
|
||||
Relative Button
|
||||
</button>
|
71
src/content/blog/05-mdx-syntax/index.mdx
Normal file
|
@ -0,0 +1,71 @@
|
|||
---
|
||||
title: "[Old] MDX syntax guide"
|
||||
description: "Use interactive components in Markdown."
|
||||
date: "2024-03-16"
|
||||
---
|
||||
|
||||
import Callout from "@/components/Callout.astro";
|
||||
|
||||
---
|
||||
|
||||
MDX is an extension of Markdown with the ability to import `.astro`,
|
||||
`.jsx`, `.tsx` and other framework components you have integrated.
|
||||
|
||||
This guide covers the basics of MDX syntax and how to use it, as well as a few examples.
|
||||
|
||||
## Example 1
|
||||
|
||||
Importing a component from the `/components` directory.
|
||||
|
||||
This component accepts a Javascript date object and format it as a string.
|
||||
|
||||
```astro
|
||||
import DateComp from "../../../components/FormattedDate.astro";
|
||||
|
||||
<DateComp date={new Date()} />
|
||||
```
|
||||
|
||||
import FormattedDate from "../../../components/FormattedDate.astro";
|
||||
|
||||
<FormattedDate date={new Date()} />
|
||||
|
||||
---
|
||||
|
||||
## Example 2
|
||||
|
||||
Importing a component from a relative path to your content.
|
||||
|
||||
This component displays an alert when the button is clicked.
|
||||
|
||||
```astro
|
||||
import RelativeComponent from "./component.astro";
|
||||
|
||||
<RelativeComponent />
|
||||
```
|
||||
|
||||
import RelativeComponent from "./component.astro";
|
||||
|
||||
<RelativeComponent />
|
||||
|
||||
---
|
||||
|
||||
By default Micro has zero frameworks installed. If you install a framework, components of that framework can be used in MDX files.
|
||||
|
||||
<Callout>
|
||||
Don't forget to use [client
|
||||
directives](https://docs.astro.build/en/reference/directives-reference/#client-directives)
|
||||
to make framework components interactive.
|
||||
</Callout>
|
||||
|
||||
```astro
|
||||
<ReactComponent client:load />
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## More Links
|
||||
|
||||
- [MDX Syntax Documentation](https://mdxjs.com/docs/what-is-mdx)
|
||||
- [Astro Framework Integrations](https://docs.astro.build/en/guides/integrations-guide)
|
||||
- [Astro Usage Documentation](https://docs.astro.build/en/guides/markdown-content/#markdown-and-mdx-pages)
|
||||
- [Client Directives](https://docs.astro.build/en/reference/directives-reference/#client-directives)
|
7
src/content/blog/06-year-sorting-example.md
Normal file
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
title: "[Old] Year sorting example"
|
||||
description: "Nano groups posts by year."
|
||||
date: "2023-12-31"
|
||||
---
|
||||
|
||||
This post is to demonstrate the year sorting capabilities.
|
10
src/content/blog/07-draft-example.md
Normal file
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
title: "[Old] Draft example"
|
||||
description: "Setting draft flag to true to hide this post."
|
||||
date: "2022-12-31"
|
||||
draft: false
|
||||
---
|
||||
|
||||
This post also demonstrates the year sorting capabilities.
|
||||
|
||||
Try setting this file's metadata to `draft: true`.
|
10
src/content/blog/08-prev-next-order-example.md
Normal file
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
title: "[Old] Chronological pagination example"
|
||||
description: "Pagination works regardless of folder name."
|
||||
date: "2024-03-21"
|
||||
draft: false
|
||||
---
|
||||
|
||||
This post should show up in proper chronological order even though its folder comes last in the `content/blog` directory.
|
||||
|
||||
The `Previous Post` and `Next Post` buttons under each blog post should also keep the proper chronological order, based on the frontmatter `date` field.
|
32
src/content/config.ts
Normal file
|
@ -0,0 +1,32 @@
|
|||
import { defineCollection, z } from "astro:content";
|
||||
|
||||
const blog = defineCollection({
|
||||
type: "content",
|
||||
schema: z.object({
|
||||
title: z.string(),
|
||||
description: z.string(),
|
||||
date: z.coerce.date(),
|
||||
draft: z.boolean().optional(),
|
||||
|
||||
tags: z.array(z.string()).optional(),
|
||||
}),
|
||||
});
|
||||
|
||||
const publications = defineCollection({
|
||||
type: "content",
|
||||
schema: z.object({
|
||||
title: z.string(),
|
||||
description: z.string(),
|
||||
date: z.coerce.date(),
|
||||
paperURL: z.string().optional(),
|
||||
authors: z.string().optional(),
|
||||
codeURL: z.string().optional(),
|
||||
webURL: z.string().optional(),
|
||||
dataURL: z.string().optional(),
|
||||
img: z.string().optional(),
|
||||
imgAlt: z.string().optional(),
|
||||
pub: z.string().optional(),
|
||||
}),
|
||||
});
|
||||
|
||||
export const collections = { blog, publications };
|
14
src/content/publications/papertitle1.md
Normal file
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
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: "
|
||||
---
|
||||
|
14
src/content/publications/papertitle2.md
Normal file
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
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"
|
||||
---
|
||||
|
14
src/content/publications/papertitle3.md
Normal file
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
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: "
|
||||
---
|
||||
|
2
src/env.d.ts
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
/// <reference path="../.astro/types.d.ts" />
|
||||
/// <reference types="astro/client" />
|