From 20c108a28347252f29b07077ef273ddf1152b276 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0lker=20SI=C4=9EIRCI?= <39417966+ilkersigirci@users.noreply.github.com> Date: Sun, 3 Nov 2024 22:01:35 +0300 Subject: [PATCH] Migrate to shadcn-svelte, complete redesign (#11) --- .eslintrc.cjs | 30 - .github/workflows/deploy.yml | 66 +- .gitignore | 21 +- .prettierrc | 9 +- README.md | 15 +- components.json | 14 + docker-compose.yml | 8 +- eslint.config.js | 33 + journey/2020/1.md | 6 + journey/2020/2.md | 6 + journey/2021/1.md | 6 + journey/2023/1.md | 8 + journey/2024/1.md | 5 + mdsvex.config.js | 393 +++++ package.json | 124 +- playwright.config.ts | 12 - postcss.config.js | 6 + .../blog-development/page.md | 22 +- posts/logo.jpg | Bin 0 -> 47530 bytes .../markdown-compatibility/page.md | 71 +- .../My.Thesis.md => posts/my-thesis/page.md | 15 +- series/guide-markdown-blog/create-new-blog.md | 286 +++ series/guide-markdown-blog/page.md | 10 + series/guide-markdown-blog/setup.md | 198 +++ src/app.css | 375 ++-- src/app.d.ts | 3 +- src/app.html | 32 +- src/content/Code.Test.md | 54 - src/content/counter.svelte | 9 - src/lib/components/markdown/a.svelte | 27 + src/lib/components/markdown/blockquote.svelte | 25 + src/lib/components/markdown/blueprint.svelte | 39 + src/lib/components/markdown/h1.svelte | 18 + src/lib/components/markdown/h2.svelte | 33 + src/lib/components/markdown/h3.svelte | 30 + src/lib/components/markdown/h4.svelte | 18 + src/lib/components/markdown/h5.svelte | 18 + src/lib/components/markdown/h6.svelte | 18 + src/lib/components/markdown/hr.svelte | 10 + src/lib/components/markdown/icons/index.ts | 58 + src/lib/components/markdown/img.svelte | 59 + src/lib/components/markdown/index.ts | 15 + src/lib/components/markdown/li.svelte | 18 + src/lib/components/markdown/markdown.pcss | 177 ++ src/lib/components/markdown/ol.svelte | 21 + src/lib/components/markdown/p.svelte | 18 + src/lib/components/markdown/pre.svelte | 111 ++ .../markdown/toast-code-title.svelte | 15 + src/lib/components/markdown/ul.svelte | 18 + .../components/search/PageFindSearch.svelte | 85 - src/lib/components/search/SearchModal.svelte | 62 - src/lib/components/search/index.ts | 4 - src/lib/components/site/card.svelte | 99 ++ src/lib/components/site/index.ts | 10 + src/lib/components/site/masonry.svelte | 132 ++ src/lib/components/site/md-list.svelte | 20 + src/lib/components/site/menucontent.svelte | 63 + src/lib/components/site/metatags.svelte | 107 ++ src/lib/components/site/navbar.svelte | 70 + .../components/site/navigation-link.svelte | 57 + src/lib/components/site/pagetitle.svelte | 17 + src/lib/components/site/postslist.svelte | 146 ++ src/lib/components/site/scrollarea.svelte | 22 + src/lib/components/site/worklist.svelte | 49 + .../ui/accordion/accordion-content.svelte | 37 + .../ui/accordion/accordion-item.svelte | 20 + .../ui/accordion/accordion-trigger.svelte | 32 + src/lib/components/ui/accordion/index.ts | 17 + src/lib/components/ui/badge/badge.svelte | 24 + src/lib/components/ui/badge/index.ts | 21 + src/lib/components/ui/button/button.svelte | 38 + src/lib/components/ui/button/index.ts | 49 + .../ui/drawer/drawer-content.svelte | 30 + .../ui/drawer/drawer-description.svelte | 24 + .../components/ui/drawer/drawer-footer.svelte | 22 + .../components/ui/drawer/drawer-header.svelte | 25 + .../components/ui/drawer/drawer-nested.svelte | 24 + .../ui/drawer/drawer-overlay.svelte | 24 + .../components/ui/drawer/drawer-title.svelte | 24 + src/lib/components/ui/drawer/drawer.svelte | 24 + src/lib/components/ui/drawer/index.ts | 41 + .../ui/hover-card/hover-card-content.svelte | 41 + src/lib/components/ui/hover-card/index.ts | 14 + src/lib/components/ui/scroll-area/index.ts | 10 + .../scroll-area/scroll-area-scrollbar.svelte | 32 + .../ui/scroll-area/scroll-area.svelte | 45 + src/lib/components/ui/skeleton/index.ts | 7 + .../components/ui/skeleton/skeleton.svelte | 16 + src/lib/components/ui/sonner/index.ts | 1 + src/lib/components/ui/sonner/sonner.svelte | 25 + src/lib/components/ui/tabs/index.ts | 18 + .../components/ui/tabs/tabs-content.svelte | 27 + src/lib/components/ui/tabs/tabs-list.svelte | 25 + .../components/ui/tabs/tabs-trigger.svelte | 29 + src/lib/config.ts | 64 +- src/lib/icons/index.ts | 1 + src/lib/icons/x.svelte | 16 + src/lib/index.ts | 1 + src/lib/posts.ts | 230 +++ src/lib/stores.svelte.ts | 34 + src/lib/styles/themes/tokyo-night-light.json | 1552 +++++++++++++++++ src/lib/styles/themes/tokyo-night-storm.json | 1523 ++++++++++++++++ src/lib/theme.ts | 23 - src/lib/types.ts | 64 +- src/lib/utils.ts | 71 +- src/mdsvex.svelte | 6 - src/routes/+error.svelte | 15 - src/routes/+layout.svelte | 73 +- src/routes/+layout.ts | 7 - src/routes/+page.server.ts | 9 + src/routes/+page.svelte | 44 +- src/routes/+page.ts | 6 - src/routes/[dynamic_page]/+page.svelte | 67 - src/routes/[dynamic_page]/+page.ts | 37 - src/routes/about/+page.svelte | 2 - src/routes/api/posts/+server.ts | 49 +- src/routes/api/posts_pagination/+server.ts | 41 - src/routes/contact/+page.svelte | 2 - src/routes/footer.svelte | 18 - src/routes/header.svelte | 103 -- src/routes/journey/+page.svelte | 95 + src/routes/journey/+page.ts | 38 + src/routes/post/+page.svelte | 52 - src/routes/post/+page.ts | 7 - src/routes/post/[slug]/+page.svelte | 57 - src/routes/post/[slug]/+page.ts | 14 - src/routes/rss.xml/+server.ts | 37 - src/routes/social.png/+server.ts | 48 + src/routes/social.png/Satoshi-Bold.ttf | Bin 0 -> 73368 bytes src/routes/social.png/comp.svelte | 86 + src/routes/toggle.svelte | 35 - src/routes/transition.svelte | 17 - src/routes/work/+page.svelte | 120 ++ src/routes/work/+page.ts | 36 + src/routes/writing/+layout.server.ts | 13 + src/routes/writing/+layout.svelte | 19 + src/routes/writing/+page.svelte | 45 + .../.nojekyll => src/routes/writing/+page.ts | 0 src/routes/writing/[slug]/+page.svelte | 60 + src/routes/writing/[slug]/+page.ts | 49 + src/routes/writing/social.png/+server.ts | 51 + .../writing/social.png/Satoshi-Bold.ttf | Bin 0 -> 73368 bytes src/routes/writing/social.png/comp.svelte | 103 ++ static/SF Pro Display Regular.otf | Bin 0 -> 2230364 bytes .../assets/images => static}/ThesisMethod.png | Bin static/fallback.avif | Bin 0 -> 1339 bytes {src/assets/images => static}/favicon.png | Bin static/havelsan_logo.svg | 20 + static/icons/copy-success.svg | 6 - static/icons/copy.svg | 5 - static/logo.jpg | Bin 0 -> 47530 bytes static/metu_logo.svg | 7 + static/profile_picture.jpg | Bin 0 -> 47530 bytes static/robots.txt | 3 - svelte.config.js | 56 +- tailwind.config.ts | 96 + tests/test.ts | 6 - vite.config.ts | 24 +- works/bert-score-api.md | 13 + .../python-template.md | 29 +- 160 files changed, 8282 insertions(+), 1315 deletions(-) delete mode 100644 .eslintrc.cjs create mode 100644 components.json create mode 100644 eslint.config.js create mode 100644 journey/2020/1.md create mode 100644 journey/2020/2.md create mode 100644 journey/2021/1.md create mode 100644 journey/2023/1.md create mode 100644 journey/2024/1.md create mode 100644 mdsvex.config.js delete mode 100644 playwright.config.ts create mode 100644 postcss.config.js rename src/content/How.This.Blog.Developed.md => posts/blog-development/page.md (70%) create mode 100644 posts/logo.jpg rename src/content/MD.Compatibility.md => posts/markdown-compatibility/page.md (85%) rename src/content/My.Thesis.md => posts/my-thesis/page.md (86%) create mode 100644 series/guide-markdown-blog/create-new-blog.md create mode 100644 series/guide-markdown-blog/page.md create mode 100644 series/guide-markdown-blog/setup.md delete mode 100644 src/content/Code.Test.md delete mode 100644 src/content/counter.svelte create mode 100644 src/lib/components/markdown/a.svelte create mode 100644 src/lib/components/markdown/blockquote.svelte create mode 100644 src/lib/components/markdown/blueprint.svelte create mode 100644 src/lib/components/markdown/h1.svelte create mode 100644 src/lib/components/markdown/h2.svelte create mode 100644 src/lib/components/markdown/h3.svelte create mode 100644 src/lib/components/markdown/h4.svelte create mode 100644 src/lib/components/markdown/h5.svelte create mode 100644 src/lib/components/markdown/h6.svelte create mode 100644 src/lib/components/markdown/hr.svelte create mode 100644 src/lib/components/markdown/icons/index.ts create mode 100644 src/lib/components/markdown/img.svelte create mode 100644 src/lib/components/markdown/index.ts create mode 100644 src/lib/components/markdown/li.svelte create mode 100644 src/lib/components/markdown/markdown.pcss create mode 100644 src/lib/components/markdown/ol.svelte create mode 100644 src/lib/components/markdown/p.svelte create mode 100644 src/lib/components/markdown/pre.svelte create mode 100644 src/lib/components/markdown/toast-code-title.svelte create mode 100644 src/lib/components/markdown/ul.svelte delete mode 100644 src/lib/components/search/PageFindSearch.svelte delete mode 100644 src/lib/components/search/SearchModal.svelte delete mode 100644 src/lib/components/search/index.ts create mode 100644 src/lib/components/site/card.svelte create mode 100644 src/lib/components/site/index.ts create mode 100644 src/lib/components/site/masonry.svelte create mode 100644 src/lib/components/site/md-list.svelte create mode 100644 src/lib/components/site/menucontent.svelte create mode 100644 src/lib/components/site/metatags.svelte create mode 100644 src/lib/components/site/navbar.svelte create mode 100644 src/lib/components/site/navigation-link.svelte create mode 100644 src/lib/components/site/pagetitle.svelte create mode 100644 src/lib/components/site/postslist.svelte create mode 100644 src/lib/components/site/scrollarea.svelte create mode 100644 src/lib/components/site/worklist.svelte create mode 100644 src/lib/components/ui/accordion/accordion-content.svelte create mode 100644 src/lib/components/ui/accordion/accordion-item.svelte create mode 100644 src/lib/components/ui/accordion/accordion-trigger.svelte create mode 100644 src/lib/components/ui/accordion/index.ts create mode 100644 src/lib/components/ui/badge/badge.svelte create mode 100644 src/lib/components/ui/badge/index.ts create mode 100644 src/lib/components/ui/button/button.svelte create mode 100644 src/lib/components/ui/button/index.ts create mode 100644 src/lib/components/ui/drawer/drawer-content.svelte create mode 100644 src/lib/components/ui/drawer/drawer-description.svelte create mode 100644 src/lib/components/ui/drawer/drawer-footer.svelte create mode 100644 src/lib/components/ui/drawer/drawer-header.svelte create mode 100644 src/lib/components/ui/drawer/drawer-nested.svelte create mode 100644 src/lib/components/ui/drawer/drawer-overlay.svelte create mode 100644 src/lib/components/ui/drawer/drawer-title.svelte create mode 100644 src/lib/components/ui/drawer/drawer.svelte create mode 100644 src/lib/components/ui/drawer/index.ts create mode 100644 src/lib/components/ui/hover-card/hover-card-content.svelte create mode 100644 src/lib/components/ui/hover-card/index.ts create mode 100644 src/lib/components/ui/scroll-area/index.ts create mode 100644 src/lib/components/ui/scroll-area/scroll-area-scrollbar.svelte create mode 100644 src/lib/components/ui/scroll-area/scroll-area.svelte create mode 100644 src/lib/components/ui/skeleton/index.ts create mode 100644 src/lib/components/ui/skeleton/skeleton.svelte create mode 100644 src/lib/components/ui/sonner/index.ts create mode 100644 src/lib/components/ui/sonner/sonner.svelte create mode 100644 src/lib/components/ui/tabs/index.ts create mode 100644 src/lib/components/ui/tabs/tabs-content.svelte create mode 100644 src/lib/components/ui/tabs/tabs-list.svelte create mode 100644 src/lib/components/ui/tabs/tabs-trigger.svelte create mode 100644 src/lib/icons/index.ts create mode 100644 src/lib/icons/x.svelte create mode 100644 src/lib/index.ts create mode 100644 src/lib/posts.ts create mode 100644 src/lib/stores.svelte.ts create mode 100644 src/lib/styles/themes/tokyo-night-light.json create mode 100644 src/lib/styles/themes/tokyo-night-storm.json delete mode 100644 src/lib/theme.ts delete mode 100644 src/mdsvex.svelte delete mode 100644 src/routes/+error.svelte delete mode 100644 src/routes/+layout.ts create mode 100644 src/routes/+page.server.ts delete mode 100644 src/routes/+page.ts delete mode 100644 src/routes/[dynamic_page]/+page.svelte delete mode 100644 src/routes/[dynamic_page]/+page.ts delete mode 100644 src/routes/about/+page.svelte delete mode 100644 src/routes/api/posts_pagination/+server.ts delete mode 100644 src/routes/contact/+page.svelte delete mode 100644 src/routes/footer.svelte delete mode 100644 src/routes/header.svelte create mode 100644 src/routes/journey/+page.svelte create mode 100644 src/routes/journey/+page.ts delete mode 100644 src/routes/post/+page.svelte delete mode 100644 src/routes/post/+page.ts delete mode 100644 src/routes/post/[slug]/+page.svelte delete mode 100644 src/routes/post/[slug]/+page.ts delete mode 100644 src/routes/rss.xml/+server.ts create mode 100644 src/routes/social.png/+server.ts create mode 100644 src/routes/social.png/Satoshi-Bold.ttf create mode 100644 src/routes/social.png/comp.svelte delete mode 100644 src/routes/toggle.svelte delete mode 100644 src/routes/transition.svelte create mode 100644 src/routes/work/+page.svelte create mode 100644 src/routes/work/+page.ts create mode 100644 src/routes/writing/+layout.server.ts create mode 100644 src/routes/writing/+layout.svelte create mode 100644 src/routes/writing/+page.svelte rename static/.nojekyll => src/routes/writing/+page.ts (100%) create mode 100644 src/routes/writing/[slug]/+page.svelte create mode 100644 src/routes/writing/[slug]/+page.ts create mode 100644 src/routes/writing/social.png/+server.ts create mode 100644 src/routes/writing/social.png/Satoshi-Bold.ttf create mode 100644 src/routes/writing/social.png/comp.svelte create mode 100644 static/SF Pro Display Regular.otf rename {src/assets/images => static}/ThesisMethod.png (100%) create mode 100644 static/fallback.avif rename {src/assets/images => static}/favicon.png (100%) create mode 100644 static/havelsan_logo.svg delete mode 100644 static/icons/copy-success.svg delete mode 100644 static/icons/copy.svg create mode 100644 static/logo.jpg create mode 100644 static/metu_logo.svg create mode 100644 static/profile_picture.jpg delete mode 100644 static/robots.txt create mode 100644 tailwind.config.ts delete mode 100644 tests/test.ts create mode 100644 works/bert-score-api.md rename src/content/Python.Template.md => works/python-template.md (87%) diff --git a/.eslintrc.cjs b/.eslintrc.cjs deleted file mode 100644 index de77eaf..0000000 --- a/.eslintrc.cjs +++ /dev/null @@ -1,30 +0,0 @@ -module.exports = { - root: true, - extends: [ - 'eslint:recommended', - 'plugin:@typescript-eslint/recommended', - 'plugin:svelte/recommended', - 'prettier' - ], - parser: '@typescript-eslint/parser', - plugins: ['@typescript-eslint'], - parserOptions: { - sourceType: 'module', - ecmaVersion: 2020, - extraFileExtensions: ['.svelte'] - }, - env: { - browser: true, - es2017: true, - node: true - }, - overrides: [ - { - files: ['*.svelte'], - parser: 'svelte-eslint-parser', - parserOptions: { - parser: '@typescript-eslint/parser' - } - } - ] -} diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 92501f7..ab83ed1 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,40 +1,40 @@ -name: Deploy to GitHub Pages +# name: Deploy to GitHub Pages -on: - push: - branches: [main] - pull_request: - branches: [main] +# on: +# push: +# branches: [main] +# pull_request: +# branches: [main] -jobs: - deploy: - permissions: - pages: write - contents: write +# jobs: +# deploy: +# permissions: +# pages: write +# contents: write - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 +# runs-on: ubuntu-latest +# steps: +# - name: Checkout +# uses: actions/checkout@v4 - - name: Setup bun - uses: oven-sh/setup-bun@v2 - with: - bun-version: latest +# - name: Setup bun +# uses: oven-sh/setup-bun@v2 +# with: +# bun-version: latest - - name: Install dependencies - run: bun install +# - name: Install dependencies +# run: bun install - - name: build - env: - BASE_PATH: '/${{ github.event.repository.name }}' - PUBLIC_URL: "https://ilkersigirci.github.io" - run: | - bun run build +# - name: build +# env: +# BASE_PATH: '/${{ github.event.repository.name }}' +# PUBLIC_URL: "https://ilkersigirci.github.io" +# run: | +# bun run build - - name: Deploy - uses: peaceiris/actions-gh-pages@v4 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./build - publish_branch: gh-pages \ No newline at end of file +# - name: Deploy +# uses: peaceiris/actions-gh-pages@v4 +# with: +# github_token: ${{ secrets.GITHUB_TOKEN }} +# publish_dir: ./build +# publish_branch: gh-pages \ No newline at end of file diff --git a/.gitignore b/.gitignore index ee2c5a8..88dcff6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,13 +1,24 @@ -.DS_Store node_modules -/build + +# Output +.output +.vercel /.svelte-kit -/package +/build + +# OS +.DS_Store +Thumbs.db + +# Env .env .env.* !.env.example -.vercel -.output +!.env.test + +# Vite vite.config.js.timestamp-* vite.config.ts.timestamp-* + +# Custom static/pagefind \ No newline at end of file diff --git a/.prettierrc b/.prettierrc index 15d5607..9023878 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,11 +1,12 @@ { - "semi": false, "useTabs": true, "singleQuote": true, "trailingComma": "none", "printWidth": 100, - "plugins": ["prettier-plugin-svelte"], - "pluginSearchDirs": ["."], + "plugins": [ + "prettier-plugin-svelte", + "prettier-plugin-tailwindcss" + ], "overrides": [ { "files": "*.svelte", @@ -14,4 +15,4 @@ } } ] -} +} \ No newline at end of file diff --git a/README.md b/README.md index 3c7e1ab..af33c3e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Blog-Markdown +# my-blog ## Install && Run the App @@ -22,6 +22,12 @@ bun run build #preview your app bun run preview + +## With pagefind in package.json +vite build && pagefind + +## Without pagefind in package.json +vite build ``` ## Vercel Project Settings @@ -39,4 +45,9 @@ bun run preview - For custom Ignored Build Step - Go to Settings -> Git -> Ignored Build Step -> Project Settings - Custom -> if [ "$VERCEL_GIT_COMMIT_REF" == "gh-pages" ]; then exit 0; else exit 1; fi - - (Alternative) Run my bash script -> bash scripts/vercel_ignored_build_step.sh \ No newline at end of file + - (Alternative) Run my bash script -> bash scripts/vercel_ignored_build_step.s + + +## TODO + +- Using [official mdsvex](https://github.com/pngwn/MDsveX) package instead of [@huntabyte/mdsvex](https://github.com/huntabyte/MDsveX) breaks the code highlighting. Need to fix it. \ No newline at end of file diff --git a/components.json b/components.json new file mode 100644 index 0000000..e6f140c --- /dev/null +++ b/components.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://shadcn-svelte.com/schema.json", + "style": "default", + "tailwind": { + "config": "tailwind.config.ts", + "css": "src/app.css", + "baseColor": "zinc" + }, + "aliases": { + "components": "$lib/components", + "utils": "$lib/utils" + }, + "typescript": true +} \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index af1ce88..961f634 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,15 +1,15 @@ version: '3.9' -name: blog-markdown +name: my-blog networks: bun_network: driver: bridge services: - blog-markdown: - container_name: blog-markdown + my-blog: + container_name: my-blog # The name of the image that will be created when building this container - image: blog-markdown:latest + image: my-blog:latest build: context: . dockerfile: Dockerfile diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..62dbd03 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,33 @@ +import js from '@eslint/js'; +import ts from 'typescript-eslint'; +import svelte from 'eslint-plugin-svelte'; +import prettier from 'eslint-config-prettier'; +import globals from 'globals'; + +/** @type {import('eslint').Linter.Config[]} */ +export default [ + js.configs.recommended, + ...ts.configs.recommended, + ...svelte.configs['flat/recommended'], + prettier, + ...svelte.configs['flat/prettier'], + { + languageOptions: { + globals: { + ...globals.browser, + ...globals.node + } + } + }, + { + files: ['**/*.svelte'], + languageOptions: { + parserOptions: { + parser: ts.parser + } + } + }, + { + ignores: ['build/', '.svelte-kit/', 'dist/'] + } +]; diff --git a/journey/2020/1.md b/journey/2020/1.md new file mode 100644 index 0000000..c2308e6 --- /dev/null +++ b/journey/2020/1.md @@ -0,0 +1,6 @@ +--- +title: Bachelor's degree, Computer Engineering 🎓 +month: 'June' +image: '/metu_logo.svg' +--- +Graduated from Middle East Technical University, Computer Engineering Department. diff --git a/journey/2020/2.md b/journey/2020/2.md new file mode 100644 index 0000000..31d1506 --- /dev/null +++ b/journey/2020/2.md @@ -0,0 +1,6 @@ +--- +title: Started working at HAVELSAN +month: 'October' +image: '/havelsan_logo.svg' +--- +I have started as Software Engineer at HAVELSAN Simulation Department. \ No newline at end of file diff --git a/journey/2021/1.md b/journey/2021/1.md new file mode 100644 index 0000000..8356c92 --- /dev/null +++ b/journey/2021/1.md @@ -0,0 +1,6 @@ +--- +title: Started working at Databoss +month: 'June' +image: './cg-logo.png' +--- +I have started as Machine Learning Engineer at Databoss Machine Learning Team. \ No newline at end of file diff --git a/journey/2023/1.md b/journey/2023/1.md new file mode 100644 index 0000000..90b6331 --- /dev/null +++ b/journey/2023/1.md @@ -0,0 +1,8 @@ +--- +title: Master of Science, Computer Engineering 🎓 +month: 'September' +image: '/metu_logo.svg' +--- +Graduated from Middle East Technical University, Computer Engineering Department. + +[Thesis](/pdfs/Thesis.pdf): **On The Use of Large Language Model for Virtual Screening** \ No newline at end of file diff --git a/journey/2024/1.md b/journey/2024/1.md new file mode 100644 index 0000000..3e25f13 --- /dev/null +++ b/journey/2024/1.md @@ -0,0 +1,5 @@ +--- +title: Created my personal website +month: 'May' +--- +I have created my personal website using SvelteKit and mdsveX. I have also added a blog section to share my journey and thoughts. \ No newline at end of file diff --git a/mdsvex.config.js b/mdsvex.config.js new file mode 100644 index 0000000..fe798ef --- /dev/null +++ b/mdsvex.config.js @@ -0,0 +1,393 @@ +/** + * Source: https://github.com/melt-ui/melt-ui/blob/develop/mdsvex.config.js + */ + +import { join, resolve } from 'path'; +import { readFileSync } from 'fs'; +import { fileURLToPath } from 'url'; +import { visit } from 'unist-util-visit'; +import { toHtml } from 'hast-util-to-html'; +import rehypePrettyCode from 'rehype-pretty-code'; +// import { escapeSvelte } from 'mdsvex'; +import { escapeSvelte } from '@huntabyte/mdsvex'; +import rehypeUnwrapImages from 'rehype-unwrap-images'; +import rehypeSlug from 'rehype-slug'; +import math from 'remark-math'; +import rehype_katex from 'rehype-katex'; +import remarkGfm from 'remark-gfm'; +import katex from 'katex'; +import { getSingletonHighlighter } from 'shiki'; +import { enhancedImages, defaultResolverFactory } from 'mdsvex-enhanced-images'; + +const __dirname = fileURLToPath(new URL('.', import.meta.url)); + +const correct_hast_tree = () => (tree) => { + visit(tree, 'text', (node) => { + if (node.value.trim().startsWith('<')) { + node.type = 'raw'; + } + }); +}; + +const katex_blocks = () => (tree) => { + visit(tree, 'code', (node) => { + if (node.lang === 'math') { + const str = katex.renderToString(node.value, { + displayMode: true, + leqno: false, + fleqn: false, + throwOnError: true, + errorColor: '#cc0000', + strict: 'warn', + output: 'htmlAndMathml', + trust: false, + macros: { '\\f': '#1f(#2)' } + }); + + node.type = 'raw'; + node.value = '{@html `' + str + '`}'; + } + }); +}; + +const inlineKatexUsingInlineCode = () => (tree) => { + visit(tree, 'inlineCode', (node) => { + if (node.value.endsWith('{:eq}')) { + node.value = node.value.replace('{:eq}', ''); + const str = katex.renderToString(node.value, { + displayMode: false, + leqno: false, + fleqn: false, + throwOnError: true, + errorColor: '#cc0000', + strict: 'warn', + output: 'htmlAndMathml', + trust: false, + macros: { '\\f': '#1f(#2)' } + }); + + node.type = 'raw'; + node.value = '{@html `' + str + '`}'; + } + }); +}; + +const katex_inline = () => (tree) => { + // using $$ $$ for inline math + // + visit(tree, 'text', (node, index, parent) => { + const regex = /\$\$(.*?)\$\$/g; + let replacedText = node.value; + + replacedText = replacedText.replace(regex, (match, equation) => { + // Replace double backslashes with single backslashes + const cleanedEquation = equation.replace(/\\\\/g, '\\'); + + const str = katex.renderToString(cleanedEquation, { + throwOnError: true, + errorColor: '#cc0000', + strict: 'warn', + output: 'htmlAndMathml', + trust: false, + macros: { '\\f': '#1f(#2)' } + }); + + // Escape the HTML for Svelte + const escapedHTML = escapeSvelte(str); + + // Wrap the rendered equation in a span + return `{@html \`${escapedHTML}\`}`; + }); + + // Replace the original text node with the modified text + parent.children[index] = { type: 'text', value: replacedText }; + }); +}; + +const prettyCodeOptions = { + // theme: 'github-dark', + theme: { + // for dark, class name will be Moonlight II, use that class name in pre.svelte to adjust + // any changes here, you need to change in pre.svelte as well with the same class name + dark: JSON.parse( + readFileSync(resolve(__dirname, './src/lib/styles/themes/tokyo-night-storm.json'), 'utf-8') + ), + // for light, class name will be min-light, use that class name in pre.svelte to adjust + // any changes here, you need to change in pre.svelte as well with the same class name + // light: JSON.parse( + // readFileSync(resolve(__dirname, './src/lib/styles/themes/tokyo-night-light.json'), 'utf-8') + // ) + light: 'min-light' + }, + keepBackground: false, // to use our own background color + onVisitLine(node) { + if (node.children.length === 0) { + node.children = { type: 'text', value: ' ' }; + } + }, + // onVisitTitle(node) { + // // console.log('title:', node); + // }, + getHighlighter: (options) => { + return getSingletonHighlighter({ + ...options, + langs: [ + 'bash', + 'css', + 'html', + 'javascript', + 'json', + 'markdown', + 'plaintext', + 'python', + 'svelte', + 'typescript', + 'yaml' + ] + }); + } +}; + +// replaces “ and ” with " and ". useful to render {} curly braces +const replaceQuotes = () => (tree) => { + visit(tree, 'text', (node) => { + node.value = node.value + .replace(/”/g, '"') // Replace curly double quotes with straight double quotes + .replace(/“/g, '"') // Replace straight double quotes with straight double quotes + .replace(/’/g, "'") // Replace curly single quotes with straight single quotes + .replace(/‘/g, "'"); // Replace straight single quotes with straight single quotes + }); +}; + +/** @type {import('mdsvex').MdsvexOptions} */ +export const mdsvexOptions = { + extensions: ['.md', '.svx'], + layout: { + _: resolve('./src/lib/components/markdown/blueprint.svelte') // default or fallback layout + // about: resolve('./src/lib/components/markdown/about-layout.svelte') // named layout + }, + // comment if not working + // highlight: { + // highlighter: highlightCode + // }, + remarkPlugins: [ + math, + katex_blocks, + katex_inline, + replaceQuotes, + remarkGfm, + inlineKatexUsingInlineCode, + [ + enhancedImages, + { + // resolve: defaultResolverFactory((path) => join('$img', path)) + resolve: (path) => path + } + ] + ], + rehypePlugins: [ + rehypeUnwrapImages, + rehypeCustomComponents, + rehypeComponentPreToPre, + [rehypePrettyCode, prettyCodeOptions], + rehypeHandleMetadata, + rehypeRenderCode, + rehypePreToComponentPre, + rehypeSlug, + correct_hast_tree, + rehype_katex + ] +}; + +function rehypeCustomComponents() { + return async (tree) => { + const hTags = [ + 'Components.h1', + 'Components.h2', + 'Components.h3', + 'Components.h4', + 'Components.h5', + 'Components.h6' + ]; + + visit(tree, (node) => { + // Check h tags, and pass some extra parameters to the custom components. + if (node?.type === 'element' && hTags.includes(node?.tagName)) { + node.properties['id'] = node.children[0].value.split(' ').join('-').toLowerCase(); + node.properties['headerTag'] = node.tagName.split('.')[1]; + } + }); + }; +} + +function rehypeComponentPreToPre() { + return async (tree) => { + // Replace `Component.pre` tags with regular `pre` tags. + // This enables us to use rehype-pretty-code with our custom `pre` component. + visit(tree, (node) => { + // if (node?.data && 'meta' in node?.data) { + // console.log('node:', node, '\n'); + // console.log('data:', node?.data, '\n-------------------------'); + // } + + if (node?.type === 'element' && node?.tagName === 'Components.pre') { + node.tagName = 'pre'; + } + }); + }; +} + +/** + * Escapes the html string of code blocks so we can pass + * it on to our custom `Component.pre` element. + */ +// function escapeHtml(html) { +// return html +// .replaceAll('&', '&') +// .replaceAll('<', '<') +// .replaceAll('>', '>') +// .replaceAll('"', '"') +// .replaceAll("'", '''); +// } + +function rehypePreToComponentPre() { + return async (tree) => { + /** + * Replace `pre` tags with our custom `Component.pre` tags. + * This enables us to use rehype-pretty-code with our custom `pre` component. + * We also add the raw html string as a parameter for the copy button. + */ + visit(tree, (node) => { + if (node?.type === 'element' && node?.tagName === 'pre') { + node.tagName = 'Components.pre'; + + // if (node?.children.length > 0) { + // console.log('\n\nnode:', node); + // console.log('\n\nnode.children[0]:', node?.children[0], '\n------------------------'); + // } + // const value = node.children[0].value.trim(); + // const rawHTMLString = value.substring(8, value.length - 2); + // node.properties['rawHTMLString'] = escapeHtml(rawHTMLString); + } + }); + }; +} + +function rehypeHandleMetadata() { + return async (tree) => { + visit(tree, (node) => { + if (node?.type === 'element' && node?.tagName === 'figure') { + if (!('data-rehype-pretty-code-figure' in node.properties)) { + return; + } + + const titleElement = node.children[0]; + const preElement = node.children.at(-1); + + if ( + preElement.tagName !== 'pre' || + !('data-rehype-pretty-code-title' in titleElement.properties) + ) { + return; + } + + // const codeElement = preElement.children.find((child) => child.tagName === 'code'); + + // if (codeElement) { + // processCustomCodeBlockHighlights(codeElement.children); + // } + + if (titleElement.children.length > 0 && 'value' in titleElement.children[0]) { + preElement.properties['title'] = titleElement.children[0].value; + preElement.properties['language'] = node.children[0].properties['data-language']; + node.children.shift(); + } + } + }); + }; +} + +function processCustomCodeBlockHighlights(children) { + children.forEach((child) => { + if (child.type === 'element' && child.tagName === 'span' && 'data-line' in child.properties) { + let shouldAddHighlight = false; + let shouldRemoveHighlight = false; + + child.children.forEach((innerChild) => { + if (innerChild.type === 'element' && innerChild.tagName === 'span') { + const textNode = innerChild.children.find((c) => c.type === 'text'); + if (textNode && textNode.value) { + const addHighlightPatterns = ['# ++add', '// ++add', '#++add', '//++add']; + const removeHighlightPatterns = ['# --del', '// --del', '#--del', '//--del']; + + addHighlightPatterns.forEach((pattern) => { + if (textNode.value.includes(pattern)) { + shouldAddHighlight = true; + textNode.value = textNode.value.replace(pattern, '').trim(); + } + }); + + removeHighlightPatterns.forEach((pattern) => { + if (textNode.value.includes(pattern)) { + shouldRemoveHighlight = true; + textNode.value = textNode.value.replace(pattern, '').trim(); + } + }); + } + } + }); + + if (shouldAddHighlight) { + child.properties['data-highlighted-line-id'] = 'add'; + child.properties['data-highlighted-line'] = ''; + } else if (shouldRemoveHighlight) { + child.properties['data-highlighted-line-id'] = 'remove'; + child.properties['data-highlighted-line'] = ''; + } + } + + // Recursively traverse inner children + if (child.children && child.children.length > 0) { + processCustomCodeBlockHighlights(child.children); + } + }); +} + +function rehypeRenderCode() { + return async (tree) => { + visit(tree, (node) => { + if ( + node?.type === 'element' && + (node?.tagName === 'Components.pre' || node?.tagName === 'pre') + ) { + const codeEl = node.children[0]; + if (codeEl.tagName !== 'code') { + return; + } + + if (codeEl && node.properties['data-language'] !== 'md') { + processCustomCodeBlockHighlights(codeEl.children); + } + + const codeString = tabsToSpaces( + toHtml(codeEl, { + allowDangerousCharacters: true, + allowDangerousHtml: true + }) + ); + + codeEl.type = 'raw'; + codeEl.value = `{@html \`${escapeSvelte(codeString)}\`}`; + } + }); + }; +} + +/** + * + * @param {string} code + * @returns {string} + */ +function tabsToSpaces(code) { + return code.replaceAll(' ', ' ').replaceAll('\t', ' '); +} diff --git a/package.json b/package.json index fe7936e..6215526 100644 --- a/package.json +++ b/package.json @@ -1,57 +1,71 @@ { - "name": "blog-markdown", - "version": "0.0.1", - "type": "module", - "scripts": { - "dev": "vite dev --port 5173", - "build": "vite build && pagefind", - "preview": "vite preview", - "test": "npm run test:integration && npm run test:unit", - "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", - "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", - "lint": "prettier --plugin-search-dir . --check . && eslint .", - "format": "prettier --plugin-search-dir . --write .", - "test:integration": "playwright test", - "test:unit": "vitest" - }, - "devDependencies": { - "@neoconfetti/svelte": "^2.2.1", - "@playwright/test": "^1.46.1", - "@sveltejs/adapter-static": "^3.0.4", - "@sveltejs/adapter-vercel": "^5.4.3", - "@sveltejs/enhanced-img": "^0.3.3", - "@sveltejs/kit": "^2.5.24", - "@sveltejs/vite-plugin-svelte": "^3.1.2", - "@types/eslint": "9.6.0", - "@typescript-eslint/eslint-plugin": "^7.18.0", - "@typescript-eslint/parser": "^7.18.0", - "eslint": "^9.9.1", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-svelte": "^2.43.0", - "mdsvex": "^0.11.2", - "prettier": "^3.3.3", - "prettier-plugin-svelte": "^3.2.6", - "shiki-transformer-copy-button": "^0.0.3", - "svelte": "^4.2.19", - "svelte-check": "^3.8.6", - "tslib": "^2.7.0", - "typescript": "^5.5.4", - "vite": "^5.4.2", - "vite-plugin-pagefind": "^0.2.10", - "vitest": "^2.0.5" - }, - "dependencies": { - "@fontsource/fira-mono": "^5.0.14", - "@fontsource/jetbrains-mono": "^5.0.21", - "@fontsource/manrope": "^5.0.21", - "@pagefind/default-ui": "^1.1.0", - "lucide-svelte": "^0.414.0", - "open-props": "^1.7.5", - "pagefind": "^1.1.0", - "rehype-slug": "^6.0.0", - "remark-toc": "^9.0.0", - "remark-unwrap-images": "^4.0.0", - "shiki": "^1.14.1", - "svelte-zoo": "^0.4.11" - } + "name": "my-blog", + "version": "0.0.1", + "private": true, + "type": "module", + "scripts": { + "dev": "vite dev --port 5173", + "build": "vite build", + "preview": "vite preview", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", + "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", + "lint": "prettier --check . && eslint .", + "format": "prettier --write ." + }, + "devDependencies": { + "@sveltejs/adapter-auto": "^3.3.1", + "@sveltejs/adapter-static": "^3.0.6", + "@sveltejs/enhanced-img": "^0.3.10", + "@sveltejs/kit": "^2.7.3", + "@sveltejs/vite-plugin-svelte": "4.0.0", + "@tailwindcss/typography": "^0.5.15", + "@types/eslint": "^9.6.1", + "autoprefixer": "^10.4.20", + "eslint": "^9.13.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-svelte": "^2.46.0", + "globals": "^15.11.0", + "mdsvex-enhanced-images": "^0.2.3", + "pagefind": "^1.1.1", + "prettier": "^3.3.3", + "prettier-plugin-svelte": "^3.2.7", + "prettier-plugin-tailwindcss": "^0.6.8", + "rehype-unwrap-images": "^1.0.0", + "svelte": "5.1.6", + "svelte-check": "^4.0.5", + "tailwindcss": "^3.4.14", + "typescript": "^5.6.3", + "typescript-eslint": "^8.12.2", + "vite": "^5.4.10", + "vite-plugin-pagefind": "^0.2.10" + }, + "dependencies": { + "@huntabyte/mdsvex": "^0.16.8", + "@resvg/resvg-js": "^2.6.2", + "@sveltejs/adapter-vercel": "^5.4.6", + "@tailwindcss/container-queries": "^0.1.1", + "bits-ui": "^0.21.16", + "clsx": "^2.1.1", + "hast-util-to-html": "^9.0.3", + "katex": "^0.16.11", + "lucide-svelte": "^0.454.0", + "mdsvex": "^0.12.3", + "mode-watcher": "^0.4.1", + "rehype-katex": "^7.0.1", + "rehype-pretty-code": "^0.14.0", + "rehype-slug": "^6.0.0", + "remark-gfm": "^4.0.0", + "remark-math": "^6.0.0", + "satori": "^0.11.2", + "satori-html": "^0.3.2", + "shiki": "^1.22.2", + "svelte-action-balancer": "^1.0.4", + "svelte-meta-tags": "^4.0.4", + "svelte-sonner": "^0.3.28", + "tailwind-merge": "^2.5.4", + "tailwind-variants": "^0.2.1", + "tailwindcss-animate": "^1.0.7", + "unist-util-visit": "^5.0.0", + "vaul-svelte": "^0.3.2" + } } \ No newline at end of file diff --git a/playwright.config.ts b/playwright.config.ts deleted file mode 100644 index 967c1bc..0000000 --- a/playwright.config.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { PlaywrightTestConfig } from '@playwright/test' - -const config: PlaywrightTestConfig = { - webServer: { - command: 'npm run build && npm run preview', - port: 4173 - }, - testDir: 'tests', - testMatch: /(.+\.)?(test|spec)\.[jt]s/ -} - -export default config diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..0f77216 --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {} + } +}; diff --git a/src/content/How.This.Blog.Developed.md b/posts/blog-development/page.md similarity index 70% rename from src/content/How.This.Blog.Developed.md rename to posts/blog-development/page.md index 66ffb65..8f7b1da 100644 --- a/src/content/How.This.Blog.Developed.md +++ b/posts/blog-development/page.md @@ -1,18 +1,20 @@ --- -title: How.This.Blog.Developed -description: How.This.Blog.Developed -date: '2024-7-22' -categories: - - sveltekit - - optimization -published: true +title: How This Blog is Built +description: Understanding the optimizations and technologies used in building this blog +date: '2024-7-26' +image: https://blog.ronin.cloud/content/images/size/w2000/2022/02/markdown.png +icon: '/posts/logo.jpg' +# Not working on vercel +useIconInHome: false +tags: + - SvelteKit +draft: false --- ## Contents ## General - -- + - Built using SvelteKit ## Optimizations @@ -20,7 +22,7 @@ published: true - Enable pre-render - Unlike other SSGs, prerendered SvelteKit still allows for client-side hydration, so I can still use smooth client-side routing and transitions. - Use static adapter -- For images, use AVIF / WebP instead of PNG / JPEG +- For images, use AVIF / WebP instead of PNG / jpg - Use Sveltekit [enhanced:img](https://kit.svelte.dev/docs/images#sveltejs-enhanced-img-srcset-and-sizes) - Optimize fonts by reducing their size - Only import the necessary weights and subsets for each font diff --git a/posts/logo.jpg b/posts/logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..cca04947e2b7a39462da4ba4793546b21ce046b8 GIT binary patch literal 47530 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
6( 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 KJR9D>x&H@ - import Counter from './counter.svelte' - - - ## Contents ## Overview @@ -105,7 +102,7 @@ and code blocks: Any decent text editor should make email-style quoting easy. For example, with BBEdit, you can make a selection and choose Increase Quote Level from the Text menu. - + + ## Span Elements @@ -298,9 +298,50 @@ function greet(name: string) { - But if you arrange routes in `src/routes/post/[slug]` form, the static media will be served from `../`. - If one uses `enhanced:img` instead of default `img`, images must be located inside `src/assets/images` and they can be referenced only by their file name. - [ ] Research this - - ![Svelte](favicon.png) + - ![Svelte](/favicon.png) + +## Long Code Block -## Svelte Component inside Markdown +```ts +import * as config from '$lib/config' +import type { Post } from '$lib/types' + +export async function GET({ fetch }) { + const response = await fetch('api/posts') + const posts: Post[] = await response.json() + + const headers = { 'Content-Type': 'application/xml' } + + const xml = ` + + + ${config.title} + ${config.description} + ${config.url} + + ${posts + .map( + (post) => ` + + ${post.title} + ${post.description} + ${config.url}/${post.slug} + ${config.url}/${post.slug} + ${new Date(post.date).toUTCString()} + + ` + ) + .join('')} + + + `.trim() + + return new Response(xml, { headers }) +} +``` - \ No newline at end of file +```python +# Long variable scroll test +longvariablename = "longvariablename_longvariablename_longvariablename_longvariablename_longvariablename_longvariablename_longvariablename_longvariablename_longvariablename_longvariablename" +``` \ No newline at end of file diff --git a/src/content/My.Thesis.md b/posts/my-thesis/page.md similarity index 86% rename from src/content/My.Thesis.md rename to posts/my-thesis/page.md index e9cf319..bfb4757 100644 --- a/src/content/My.Thesis.md +++ b/posts/my-thesis/page.md @@ -1,11 +1,14 @@ --- title: My Thesis description: ON THE USE OF LARGE LANGUAGE MODEL FOR VIRTUAL SCREENING -date: '2024-7-16' -categories: - - programming - - thesis -published: true +date: '2024-7-27' +image: https://blog.ronin.cloud/content/images/size/w2000/2022/02/markdown.png +# Not working on vercel +icon: '/posts/logo.jpg' +useIconInHome: false +tags: + - Programming +draft: false --- ## Contents @@ -29,4 +32,4 @@ natural language processing, clustering - We use 3 main compound SMILES datasets, with 3 different descriptors. - We also use dimensionality reduction techniques before clustering. - We use 4 main clustering algorithm and evaluate their performance with 3 different metrics. -- ![Thesis.Method](ThesisMethod.png) +- ![Thesis.Method](/ThesisMethod.png) \ No newline at end of file diff --git a/series/guide-markdown-blog/create-new-blog.md b/series/guide-markdown-blog/create-new-blog.md new file mode 100644 index 0000000..0c7d121 --- /dev/null +++ b/series/guide-markdown-blog/create-new-blog.md @@ -0,0 +1,286 @@ +--- +title: Creating a new Blog +description: Let's look at how to create a new Blog (Indivdual & Series) +date: '2023-12-20' +order: 2 +image: https://blog.ronin.cloud/content/images/size/w2000/2022/02/markdown.png +draft: false +--- + +Welcome to the Part II of the series, Creating a new blog post (individual & series) + +## Individual Blogs + +to create a new blog, create a folder with the slug you want and create a `page.md` file. the slug will act as the blog url which will be `/blog/[slug]` + +here's the tree view of the folder structure + +```md /authjs-sveltekit-prisma/#rb /dimensionality-reduction-using-auto-encoders/#yb /getting-started/#rb {2-10} /page.md/#hi +├── about +├── posts +│ ├── authjs-sveltekit-prisma +│ │ └── page.md +│ ├── dimensionality-reduction-using-auto-encoders +│ │ ├── banner.png +│ │ └── page.md +│ └── getting-started +│ ├── PDF_Assistant.png +│ └── page.md +├── series +├── src +├── static +├── svelte.config.js +├── tailwind.config.js +├── biome.json +├── components.json +├── mdsvex.config.js +├── package.json +├── pnpm-lock.yaml +├── postcss.config.cjs +├── tsconfig.json +├── README.md +└── vite.config.ts +``` + +> **Note**: Do not add any spaces, separate the name using `-` + + +## Frontmatter + +Frontmatter allows you to specify metadata and options. Included in frontmatter are things like the document or project title, what thumbnail to use for site or content previews, authors that contributed to the work etc, + +for this template the frontmatter is + +```md +--- +title: +description: +date: '2023-11-26' +tags: + - SvelteKit + - MDsveX +image: url or a pathname +draft: false +--- +``` + +`tags` is an array so if you want to declare multiple tags just add a new tag below it. + +## Writing Series Blogs + +To understand Series Blogs, you need to understand the folder structure first. + +```md /guide-markdown-blog/#hi {3-8} /config.md/#rb /setup.md/#rb /create-new-blog.md/#rb /page.md/#hi +├── about +├── posts +├── series +│ └── guide-markdown-blog +│ ├── config.md +│ ├── create-new-blog.md +│ ├── page.md +│ └── setup.md +├── src +├── static +├── svelte.config.js +├── tailwind.config.js +├── biome.json +├── components.json +├── mdsvex.config.js +├── package.json +├── pnpm-lock.yaml +├── postcss.config.cjs +├── tsconfig.json +├── README.md +└── vite.config.ts +``` + +## Frontmatter (for series) + +for `page.md` + +```md +--- +title: Guide on how to use this blog template +description: A guide on how to use this sveltekit + markdown blog. +date: '2023-12-20' +tags: + - SvelteKit + - MDsveX +image: https://blog.ronin.cloud/content/images/size/w2000/2022/02/markdown.png +draft: false +--- +``` +this is same as the one for individual blog posts and for actual posts in the series, the frontmatter is little different. + +```md +--- +title: Creating a new Blog +description: Let's look at how to create a new Blog (Indivdual & Series) +date: '2023-12-20' +order: 2 +image: https://blog.ronin.cloud/content/images/size/w2000/2022/02/markdown.png +draft: false +--- +``` + +We have a new property called `order`, which indicates the order of the particular post in that series. Additionally, `image` and `tags` are completely optional. If you do not specify them, the values from the cover folder (`page.md`) are used. However, if you do specify them, the specified values are used instead. When it comes to tags, if you specify them, the tags from the specific post are combined with the tags declared in `page.md`. This is particularly useful when you're writing a long series and each post is on a different topic. For example, if you're writing a Machine Learning Series, at some point, you're writing a post on Clustering algorithms, so that specific post should have its own tag. + +for series blogs, the slug will be `cover folder` + `a unique identifier` + `name of the .md file` + +## Code Blocks + +This blog uses [rehype-pretty-code](https://rehype-pretty-code.netlify.app/) and [shiki](https://shiki.matsu.io/) for syntax highlighting with two different themes for light and dark mode. To configure code blocks to your style, take a look at `mdsvex.config.js`, `pre.svelte` and `markdown.postcss` files. + +You can create fenced code blocks by placing triple backticks ``` before and after the code block. Place a blank line before and after code blocks to make the raw formatting easier to read. + +```js +console.log("Hello") +``` + +To display triple backticks in a fenced code block, wrap them inside quadruple backticks. +````py +```py +print("Hello from Python 🐍") +``` +```` + +### Adding Title + +if you provide a title with an extension, the code block will look like + +```ts title="hello.ts" +console.log("Hello from TS") +``` +for rendering icons, it grabs the extension and maps it to the icon for that language. Again, you can totally change this behaviour in `pre.svelte` which is a custom component. + +### Inline Syntax Highlighting + +you can also do inline syntax highlighting. To use that + +```java +System.out.println("This is a example of Inline Syntax Highlighting"){:java} +``` + +this will become + +`System.out.println("This is a example of Inline Syntax Highlighting"){:java}` + +### Word Highlighting + +you can highlight individual words in your code with different colors. + +````md +```py /fibonacci/1-2#rb {2-3} +def fibonacci(n): + if n <= 1: # base case + return n + else: + return fibonacci(n - 2) + fibonacci(n - 3) # --del + return fibonacci(n - 1) + fibonacci(n - 2) # ++add +``` +```` + +this will become + +```py {2-3} /fibonacci/1-2#rb +def fibonacci(n): + if n <= 1: + return n + else: + return fibonacci(n - 2) + fibonacci(n - 3) # --del + return fibonacci(n - 1) + fibonacci(n - 2) # ++add +``` + +for other languages, like js or ts + +````md +```js title="code-diff.js" +export function foo() { + console.log('hewwo') // --del // this should be hello + console.log('hello') // ++add +} +``` +```` + +this will become + +```js title="code-diff.js" +export function foo() { + console.log('hewwo') // --del // this should be hello + console.log('hello') // ++add +} +``` + +## Math Blocks + +for rendering math equations, i gave a detailed explanation [here](/blog/getting-started#math-blocks). Earlier it wasn't possible to add inline equations without using an external component but I created a plugin that allows you to insert inline math equations. + +here's the plugin +```js showLineNumbers {3} +const katex_inline = () => (tree) => { + visit(tree, 'text', (node, index, parent) => { + const regex = /\$\$(.*?)\$\$/g; + let match; + + while ((match = regex.exec(node.value)) !== null) { + const equation = match[1].trim(); + + // Replace double backslashes with single backslashes + const cleanedEquation = equation.replace(/\\\\/g, '\\'); + + const str = katex.renderToString(cleanedEquation, { + throwOnError: true, + errorColor: '#cc0000', + strict: 'warn', + output: 'htmlAndMathml', + trust: false, + macros: { '\\f': '#1f(#2)' } + }); + + // Escape the HTML for Svelte + const escapedHTML = escapeSvelte(str); + + // Replace the matched portion with the escaped HTML + const before = node.value.slice(0, match.index); + const after = node.value.slice(match.index + match[0].length); + const renderedEquation = '{@html `' + escapedHTML + '`}'; + + // Create a new 'raw' node with the rendered equation + const rawNode = { + type: 'raw', + value: renderedEquation + }; + + // Insert the 'raw' node into the parent's children array + parent.children.splice( + index, + 1, + ...[{ type: 'text', value: before }, rawNode, { type: 'text', value: after }] + ); + } + }); +}; +``` + +to write inline equations use `$$ $$` and wrap your KaTeX inside. + +```md +$$(a+b)^2 = a^2 + b^2 + 2ab$$ +``` +this becomes $$(a+b)^2 = a^2 + b^2 + 2ab$$ + +for block equations + ````md /math/1#rb title="math.md" +```math +\\nabla \\times \\mathbf{B} = \\mu_0 \\left(\\mathbf{J} + \\varepsilon_0 \\frac{\\partial \\mathbf{E}}{\\partial t}\\right) +``` +```` + +this becomes + +```math +\nabla \times \mathbf{B} = \mu_0 \left(\mathbf{J} + \varepsilon_0 \frac{\partial \mathbf{E}}{\partial t}\right) +``` + +--- + diff --git a/series/guide-markdown-blog/page.md b/series/guide-markdown-blog/page.md new file mode 100644 index 0000000..3c7afcc --- /dev/null +++ b/series/guide-markdown-blog/page.md @@ -0,0 +1,10 @@ +--- +title: Guide on how to use this blog template +description: A guide on how to use this sveltekit + markdown blog. +date: '2023-12-16' +tags: + - SvelteKit + - MDsveX +image: https://blog.ronin.cloud/content/images/size/w2000/2022/02/markdown.png +draft: false +--- \ No newline at end of file diff --git a/series/guide-markdown-blog/setup.md b/series/guide-markdown-blog/setup.md new file mode 100644 index 0000000..f3837af --- /dev/null +++ b/series/guide-markdown-blog/setup.md @@ -0,0 +1,198 @@ +--- +title: Getting Started +description: Setting up the Portfolio + Blog. +date: '2023-12-20' +order: 1 +draft: false +--- + + + +## Introduction + +Welcome, this will guide you through this template and how to use it. This is a SvelteKit + MDsveX Personal website and a blog completely designed with [Shadcn-Svelte](https://shadcn-svelte.com/), it has everything you need get started and you can fully customise it. +[repo link](https://github.com/ilkersigirci/my-blog.git) + + +## Features + +it's got ton of features that you don't wanna miss out. + +- Tailwind CSS for styling +- SvelteKit as meta framework + - with shallow routing when clicking on tags to instantly see the posts based on tags. Click on the tag to see. + + +- [Shadcn-Svelte](https://shadcn-svelte.com/) for UI Components ([@huntabyte](https://x.com/huntabyte)) +- Light and Dark mode +- different themes for code blocks based on color scheme. +- Individual blog posts and series blog posts (you're reading a series) +- Syntax Highlighting + - with toast notifications for copy feedback + - individual words highlighting + ```py {2} showLineNumbers title="fib.py" /fibonacci/#yb /return/#hi + def fibonacci(n): + if n <= 1: # base case + return n + else: + return fibonacci(n - 1) + fibonacci(n - 2) + ``` + - inline syntax highlighting example: `console.log("Hey there"){:js}` + - render language icon if title with an extension is provided. + ````md /title/#rb /example.js/#ul /.js/#yb + ```js title="example.js" + console.log('Hello from JS'); + ``` + ```` + this will become + ```js title="example.js" + console.log('Hello from JS'); + ``` + - while icons are available for few languages like JS/TS, Py, Svelte, you can add for more languages if you want. + - [MDsveX](https://mdsvex.pngwn.io/) preprocessor to support markdown files + - Custom Components + - use svelte components inside markdown + - example +
+ try changing the theme 👉 +
+ - Table of Contents + - Giscus Comments (based on Github Discussions) + - Projects Page + - Math support using KaTeX + - examples: `Inline`: $$\nabla \times \mathbf{B} = \mu_0 \left(\mathbf{J} + \varepsilon_0 \frac{\partial \mathbf{E}}{\partial t}\right)$$ + - Block equations (here are my favourite [Maxwells's Equations](https://en.wikipedia.org/wiki/Maxwell%27s_equations#:~:text=Maxwell's%20equations%2C%20or%20Maxwell%E2%80%93Heaviside,classical%20optics%2C%20and%20electric%20circuits.)) + ```math + \nabla \cdot \mathbf{E} = \frac{\rho}{\varepsilon_0} + ``` + ```math + \nabla \cdot \mathbf{B} = 0 + ``` + ```math + \nabla \times \mathbf{E} = -\frac{\partial \mathbf{B}}{\partial t} + ``` + ```math + \nabla \times \mathbf{B} = \mu_0 \left(\mathbf{J} + \varepsilon_0 \frac{\partial \mathbf{E}}{\partial t}\right) + ``` + - Mobile friendly interface + + +## How to Use? + +In this section we'll dicsuss about how to setup quicky and get started. + +### Installation + +To install, clone the repo using + +```bash +git clone https://github.com/ilker-sigirci/my-blog.git +``` +install the node modules + +```bash +cd my-blog && pnpm i +``` +and start editing the following files + - `$lib/config.ts` which has all the links + - `about/about.md` to change the about page + - `$lib/assets` for favicon and image + - `$lib/components/site/hero.svelte` to change the home page + - `$lib/projects.ts` to change your projects. + +let's have a look at `$lib/config.ts` + +```ts title="lib/config.ts" +import { LinkedIn, X } from '$lib/components/site/icons'; +import { FileText, Github, Mail } from 'lucide-svelte'; + +type routesType = { + name: string; + link: string; +}; + +type socialsType = { + href: string; + icon: typeof Github; + display: string; + class?: string; +}; + +// nav routes +export const routes: routesType[] = [ + { + name: 'Blog', + link: '/blog' + }, + { + name: 'Tags', + link: '/tags' + }, + { + name: 'Projects', + link: '/projects' + }, + { + name: 'About', + link: '/about' + } +]; + +// social icons with links +const socials: socialsType[] = [ + { + href: 'https://github.com/ilkersigirci', + icon: Github, + display: 'GitHub' + }, + { + href: 'https://linkedin.com/in/ilkersigirci', + icon: LinkedIn, + display: 'LinkedIn' + }, + { + href: 'https://x.com/ilkersigirci', + icon: X, + display: 'Twitter', + class: 'h-4 w-4' + }, + { + href: 'mailto:sigirci.ilker@gmail.com', + icon: Mail, + display: 'Mail', + class: 'h-4 w-4' + }, + { + href: '/Ilker-Sigirci-Resume.pdf', + icon: FileText, + display: 'Resume' + } +]; + +export const getSocials = ({ exclude }: { exclude?: string } = {}): socialsType[] => { + if (exclude) { + return socials.filter((social) => social.display !== exclude); + } + return socials; +}; + +export const githubConfig = { + username: 'ilkersigirci', + repo: 'my-blog', + branch: 'main' +}; +``` + +To ensure that your local images, located in the `posts/[slug]` folder, can be converted to GitHub URLs, it's essential to include your `githubConfig` in the `config.ts` file. This is particularly useful when you want to include images in your blog posts and prefer to store them in the same folder as your post for better organization. + +However, there's a caveat – assets in other than public folder (static), won't be processed by Vite. As a result, these images won't have a definite URL. To obtain the URL, you'll need to incorporate your `githubConfig`, which transforms your local images into GitHub raw URL format. This ensures that when you deploy your application, the images will correctly point to your GitHub repository. + +Alternatively, you can place your images directly in the static folder and access them using `/` which points to static folder. example: `/image.png` and you also get Vite Image Optimisation. + +> Always use a CDN for better performance. + +see the next part on How to write blogs + +--- \ No newline at end of file diff --git a/src/app.css b/src/app.css index 1e33d8e..f17f7b3 100644 --- a/src/app.css +++ b/src/app.css @@ -1,218 +1,223 @@ -@import '@fontsource/manrope'; -@import '@fontsource/jetbrains-mono'; - -html { - /* font */ - --font-sans: 'Manrope', sans-serif; - --font-mono: 'JetBrains Mono', monospace; - - /* dark */ - --brand-dark: var(--orange-3); - --text-1-dark: var(--gray-3); - --text-2-dark: var(--gray-5); - --surface-1-dark: var(--gray-12); - --surface-2-dark: var(--gray-11); - --surface-3-dark: var(--gray-10); - --surface-4-dark: var(--gray-9); - --background-dark: var(--gradient-8); - --border-dark: var(--gray-9); - - /* light */ - --brand-light: var(--orange-10); - --text-1-light: var(--gray-8); - --text-2-light: var(--gray-7); - --surface-1-light: var(--gray-0); - --surface-2-light: var(--gray-1); - --surface-3-light: var(--gray-2); - --surface-4-light: var(--gray-3); - --background-light: none; - --border-light: var(--gray-4); -} - -:root { - color-scheme: dark; - - --brand: var(--brand-dark); - --text-1: var(--text-1-dark); - --text-2: var(--text-2-dark); - --surface-1: var(--surface-1-dark); - --surface-2: var(--surface-2-dark); - --surface-3: var(--surface-3-dark); - --surface-4: var(--surface-4-dark); - --background: var(--background-dark); - --border: var(--border-dark); -} +@tailwind base; +@tailwind components; +@tailwind utilities; -@media (prefers-color-scheme: light) { +@layer base { :root { - color-scheme: light; - - --brand: var(--brand-light); - --text-1: var(--text-1-light); - --text-2: var(--text-2-light); - --surface-1: var(--surface-1-light); - --surface-2: var(--surface-2-light); - --surface-3: var(--surface-3-light); - --surface-4: var(--surface-4-light); - --background: var(--background-light); - --border: var(--border-light); + --background: 0 0% 100%; + --foreground: 240 10% 3.9%; + + --muted: 240 4.8% 95.9%; + --muted-foreground: 240 3.8% 46.1%; + + --popover: 0 0% 100%; + --popover-foreground: 240 10% 3.9%; + + --card: 0 0% 100%; + --card-foreground: 240 10% 3.9%; + + --border: 240 5.9% 90%; + --input: 240 5.9% 90%; + + --primary: 240 5.9% 10%; + --primary-foreground: 0 0% 98%; + + --secondary: 240 4.8% 95.9%; + --secondary-foreground: 240 5.9% 10%; + + --accent: 240 4.8% 95.9%; + --accent-foreground: 240 5.9% 10%; + + --destructive: 0 72.2% 50.6%; + --destructive-foreground: 0 0% 98%; + + --ring: 240 10% 3.9%; + + --radius: 0.5rem; } -} -[color-scheme='dark'] { - color-scheme: dark; - - --brand: var(--brand-dark); - --text-1: var(--text-1-dark); - --text-2: var(--text-2-dark); - --surface-1: var(--surface-1-dark); - --surface-2: var(--surface-2-dark); - --surface-3: var(--surface-3-dark); - --surface-4: var(--surface-4-dark); - --background: var(--background-dark); - --border: var(--border-dark); -} + /* .dark { + --background: 240 10% 3.9%; + --foreground: 0 0% 98%; -[color-scheme='light'] { - color-scheme: light; - - --brand: var(--brand-light); - --text-1: var(--text-1-light); - --text-2: var(--text-2-light); - --surface-1: var(--surface-1-light); - --surface-2: var(--surface-2-light); - --surface-3: var(--surface-3-light); - --surface-4: var(--surface-4-light); - --background: var(--background-light); - --border: var(--border-light); -} + --muted: 240 3.7% 15.9%; + --muted-foreground: 240 5% 64.9%; -html, -body { - height: 100%; -} + --popover: 240 10% 3.9%; + --popover-foreground: 0 0% 98%; -html { - color: var(--text-1); - accent-color: var(--link); - background-image: var(--background); - background-attachment: fixed; -} + --card: 240 10% 3.9%; + --card-foreground: 0 0% 98%; -img { - border-radius: var(--radius-3); -} + --border: 240 3.7% 15.9%; + --input: 240 3.7% 15.9%; -ul, -ol { - list-style: none; - padding: 0; -} + --primary: 0 0% 98%; + --primary-foreground: 240 5.9% 10%; -li { - padding-inline-start: 0; - /* max-width: 100%; */ -} + --secondary: 240 3.7% 15.9%; + --secondary-foreground: 0 0% 98%; -.surface-1 { - background-color: var(--surface-1); - color: var(--text-2); -} + --accent: 240 3.7% 15.9%; + --accent-foreground: 0 0% 98%; -.surface-2 { - background-color: var(--surface-2); - color: var(--text-2); -} + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 0 0% 98%; -.surface-3 { - background-color: var(--surface-3); - color: var(--text-1); -} + --ring: 240 4.9% 83.9%; + } */ -.surface-4 { - background-color: var(--surface-4); - color: var(--text-1); -} + ::selection { + @apply bg-black text-white; + } -.prose :is(h2, h3, h4, h5, h6) { - margin-top: var(--size-8); - margin-bottom: var(--size-3); -} + body { + @apply font-sans text-base text-gray-900; + } -.prose p:not(:is(h2, h3, h4, h5, h6) + p) { - margin-top: var(--size-7); -} + html { + @apply overflow-hidden scroll-smooth antialiased; + text-size-adjust: 100%; + text-rendering: optimizeLegibility; + } -.prose :is(ul, ol) { - list-style-type: '🔘'; - padding-left: var(--size-5); -} + article { + @apply flex flex-col; + } -.prose :is(ul, ol) li { - margin-block: var(--size-2); - padding-inline-start: var(--size-2); -} + span > p { + @apply my-0; + } -.prose pre { - max-inline-size: 100%; - padding: var(--size-3); - border-radius: 8px; - tab-size: 2; + p { + @apply mb-6 leading-slacker; + } + + a, + button { + @apply cursor-pointer outline-none; + } + + a { + @apply transition-colors duration-300; + } + + h1, + h2, + h3 { + @apply scroll-mt-16 font-semibold slashed-zero tracking-tighter text-black lg:scroll-mt-8; + } + + h1 { + @apply text-2xl md:text-3xl; + } + + h2 { + @apply text-lg md:text-xl; + } + + h3 { + @apply md:text-lg; + } + + h2 + h3 { + @apply !mt-0; + } + + ol > li::marker { + @apply font-semibold; + } + + ul > li { + @apply pl-2; + } + + ul > li::marker { + @apply text-gray-400; + } + + /* li div { + @apply inline; + } */ + + li p, + li div, + li h1, + li h2 { + @apply my-0; + } + + hr { + @apply my-6 border-gray-200; + } + + img, + object { + @apply rounded-xl border; + } } -/* button { - color: white; - cursor: pointer; - border: none; - border-radius: 3pt; - background-color: rgb(26, 158, 185); - padding: 2pt 4pt; - font-size: 12pt; - line-height: initial; - transition: background-color 0.2s; - } */ - -/*************** CODE COPY BUTTON ***************/ - -pre:has(code) { - position: relative; - overflow-x: auto; +@layer base { + * { + @apply border-border; + } + body { + @apply h-screen bg-background text-foreground; + } } -pre button.copy { - position: absolute; - right: 16px; - top: 16px; - height: 28px; - width: 28px; - padding: 0; - display: flex; +@layer components { + .content-wrapper { + @apply z-[1] w-full px-6 pb-8 pt-8 lg:px-8 lg:pb-16 lg:pt-24; + } - & span { - width: 100%; - aspect-ratio: 1 / 1; - background-repeat: no-repeat; - background-position: center; - background-size: cover; + .content { + @apply mx-auto w-full lg:mb-0 lg:max-w-[52rem]; } - & .ready { - background-image: url(/icons/copy.svg); + .thumbnail-shadow { + box-shadow: + 0 0 0 0.5px #e2e8f0, + 0 0 0 1px rgba(226, 232, 240, 0.5), + 0 0 0 3px #f8fafc, + 0 0 0 3.5px #f1f5f9, + 0 10px 15px -3px rgb(59 130 246/5%), + 0 4px 6px -4px rgb(59 130 246/5%); } - & .success { - display: none; - background-image: url(/icons/copy-success.svg); + .scrollable-area { + @apply h-full max-h-dynamic-screen min-h-dynamic-screen overflow-y-auto overflow-x-hidden; } - &.copied { - & .success { - display: block; - } + .bg-dots { + @apply bg-white bg-[radial-gradient(#e5e7eb_1px,transparent_1px)] [background-size:16px_16px]; + } + + .bg-grid { + @apply bg-white bg-[linear-gradient(to_right,#80808012_1px,transparent_1px),linear-gradient(to_bottom,#80808012_1px,transparent_1px)] bg-[size:24px_24px]; + } - & .ready { - display: none; - } + .word-break-word { + word-break: break-word; } + + .gradientBg3 { + @apply absolute inset-0 z-0 h-screen w-screen bg-white bg-[radial-gradient(100%_50%_at_50%_0%,rgba(0,163,255,0.13)_0,rgba(0,163,255,0)_50%,rgba(0,163,255,0)_100%)]; + } +} + +::-webkit-scrollbar { + @apply w-0; + @apply h-0; +} + +::-webkit-scrollbar-track { + @apply hidden !bg-transparent; +} +::-webkit-scrollbar-thumb { + @apply hidden rounded-xl !bg-border; +} + +::-webkit-scrollbar-corner { + background: rgba(0, 0, 0, 0); } -/*************** CODE COPY BUTTON ***************/ \ No newline at end of file diff --git a/src/app.d.ts b/src/app.d.ts index bf6daa3..743f07b 100644 --- a/src/app.d.ts +++ b/src/app.d.ts @@ -5,8 +5,9 @@ declare global { // interface Error {} // interface Locals {} // interface PageData {} + // interface PageState {} // interface Platform {} } } -export {} +export {}; diff --git a/src/app.html b/src/app.html index eba8503..e58c00c 100644 --- a/src/app.html +++ b/src/app.html @@ -1,21 +1,15 @@ - + - - - - - - - - %sveltekit.head% - - -
%sveltekit.body%
- - + + + + + %sveltekit.head% + + + +
%sveltekit.body%
+ + + \ No newline at end of file diff --git a/src/content/Code.Test.md b/src/content/Code.Test.md deleted file mode 100644 index 25da9b9..0000000 --- a/src/content/Code.Test.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: Code Test -description: Code Test -date: '2024-7-25' -categories: - - programming -published: true ---- - -Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum -- Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum - -```ts -import * as config from '$lib/config' -import type { Post } from '$lib/types' - -export async function GET({ fetch }) { - const response = await fetch('api/posts') - const posts: Post[] = await response.json() - - const headers = { 'Content-Type': 'application/xml' } - - const xml = ` - - - ${config.title} - ${config.description} - ${config.url} - - ${posts - .map( - (post) => ` - - ${post.title} - ${post.description} - ${config.url}/${post.slug} - ${config.url}/${post.slug} - ${new Date(post.date).toUTCString()} - - ` - ) - .join('')} - - - `.trim() - - return new Response(xml, { headers }) -} -``` - -```python -# Long variable scroll test -longvariablename = "longvariablename_longvariablename_longvariablename_longvariablename_longvariablename_longvariablename_longvariablename_longvariablename_longvariablename_longvariablename" -``` \ No newline at end of file diff --git a/src/content/counter.svelte b/src/content/counter.svelte deleted file mode 100644 index e8310bd..0000000 --- a/src/content/counter.svelte +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/src/lib/components/markdown/a.svelte b/src/lib/components/markdown/a.svelte new file mode 100644 index 0000000..f16d12e --- /dev/null +++ b/src/lib/components/markdown/a.svelte @@ -0,0 +1,27 @@ + + + + {@render children()} + + {#if !internal} + + {/if} + diff --git a/src/lib/components/markdown/blockquote.svelte b/src/lib/components/markdown/blockquote.svelte new file mode 100644 index 0000000..58e2cda --- /dev/null +++ b/src/lib/components/markdown/blockquote.svelte @@ -0,0 +1,25 @@ + + +
+
+ + {@render children()} +
+
diff --git a/src/lib/components/markdown/blueprint.svelte b/src/lib/components/markdown/blueprint.svelte new file mode 100644 index 0000000..ee96f26 --- /dev/null +++ b/src/lib/components/markdown/blueprint.svelte @@ -0,0 +1,39 @@ + + + + + + + + + + +{@render children()} diff --git a/src/lib/components/markdown/h1.svelte b/src/lib/components/markdown/h1.svelte new file mode 100644 index 0000000..afba1b3 --- /dev/null +++ b/src/lib/components/markdown/h1.svelte @@ -0,0 +1,18 @@ + + +

+ {@render children()} +

diff --git a/src/lib/components/markdown/h2.svelte b/src/lib/components/markdown/h2.svelte new file mode 100644 index 0000000..aad8420 --- /dev/null +++ b/src/lib/components/markdown/h2.svelte @@ -0,0 +1,33 @@ + + + +

{ + if (window.location.hash !== `#${restprops.id}`) { + window.location.hash = `#${restprops.id}`; + } + }} +> + {@render children()} +

diff --git a/src/lib/components/markdown/h3.svelte b/src/lib/components/markdown/h3.svelte new file mode 100644 index 0000000..3fbf692 --- /dev/null +++ b/src/lib/components/markdown/h3.svelte @@ -0,0 +1,30 @@ + + + +

{ + if (window.location.hash !== `#${restprops}.id}`) { + window.location.hash = `#${restprops}.id}`; + } + }} +> + {@render children()} +

diff --git a/src/lib/components/markdown/h4.svelte b/src/lib/components/markdown/h4.svelte new file mode 100644 index 0000000..df583d0 --- /dev/null +++ b/src/lib/components/markdown/h4.svelte @@ -0,0 +1,18 @@ + + +

+ {@render children()} +

diff --git a/src/lib/components/markdown/h5.svelte b/src/lib/components/markdown/h5.svelte new file mode 100644 index 0000000..0256af8 --- /dev/null +++ b/src/lib/components/markdown/h5.svelte @@ -0,0 +1,18 @@ + + +
+ {@render children()} +
diff --git a/src/lib/components/markdown/h6.svelte b/src/lib/components/markdown/h6.svelte new file mode 100644 index 0000000..6c7ec1c --- /dev/null +++ b/src/lib/components/markdown/h6.svelte @@ -0,0 +1,18 @@ + + +
+ {@render children()} +
diff --git a/src/lib/components/markdown/hr.svelte b/src/lib/components/markdown/hr.svelte new file mode 100644 index 0000000..5b33f14 --- /dev/null +++ b/src/lib/components/markdown/hr.svelte @@ -0,0 +1,10 @@ + + +
diff --git a/src/lib/components/markdown/icons/index.ts b/src/lib/components/markdown/icons/index.ts new file mode 100644 index 0000000..1755818 --- /dev/null +++ b/src/lib/components/markdown/icons/index.ts @@ -0,0 +1,58 @@ +export const langIcons: { + [key: string]: { + src: string; + class?: string; + }; +} = { + bash: { + src: 'https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/bash/bash-original.svg' + }, + + shell: { + src: 'https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/bash/bash-original.svg' + }, + + py: { + src: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/python/python-original.svg' + }, + + python: { + src: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/python/python-original.svg' + }, + + docker: { + src: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/docker/docker-original.svg' + }, + + prisma: { + src: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/prisma/prisma-original.svg' + }, + + svelte: { + src: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/svelte/svelte-original.svg' + }, + + sveltekit: { + src: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/svelte/svelte-original.svg' + }, + + ts: { + src: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/typescript/typescript-original.svg' + }, + + typescript: { + src: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/typescript/typescript-original.svg' + }, + + js: { + src: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/javascript/javascript-original.svg' + }, + + javascript: { + src: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/javascript/javascript-original.svg' + }, + + md: { + src: 'https://cdn.jsdelivr.net/gh/devicons/devicon/icons/markdown/markdown-original.svg' + } +}; diff --git a/src/lib/components/markdown/img.svelte b/src/lib/components/markdown/img.svelte new file mode 100644 index 0000000..5a4bbee --- /dev/null +++ b/src/lib/components/markdown/img.svelte @@ -0,0 +1,59 @@ + + + + +
+
+
+ { + const target = e.target; + if (target instanceof HTMLImageElement) { + target.onerror = null; + target.src = '/fallback.avif'; + } + }} + /> +
+
+ {#if alt} +

{alt ? alt : ''}

+ {/if} +
diff --git a/src/lib/components/markdown/index.ts b/src/lib/components/markdown/index.ts new file mode 100644 index 0000000..bc9e636 --- /dev/null +++ b/src/lib/components/markdown/index.ts @@ -0,0 +1,15 @@ +export { default as a } from './a.svelte'; +export { default as h1 } from './h1.svelte'; +export { default as h2 } from './h2.svelte'; +export { default as h3 } from './h3.svelte'; +export { default as h4 } from './h4.svelte'; +export { default as h5 } from './h5.svelte'; +export { default as blockquote } from './blockquote.svelte'; +export { default as pre } from './pre.svelte'; +export { default as p } from './p.svelte'; +export { default as li } from './li.svelte'; +export { default as ul } from './ul.svelte'; +export { default as ol } from './ol.svelte'; +export { default as hr } from './hr.svelte'; +export { default as img } from './img.svelte'; +export { default as ToastCodeTitle } from './toast-code-title.svelte'; diff --git a/src/lib/components/markdown/li.svelte b/src/lib/components/markdown/li.svelte new file mode 100644 index 0000000..38657ee --- /dev/null +++ b/src/lib/components/markdown/li.svelte @@ -0,0 +1,18 @@ + + +
  • + {@render children()} +
  • diff --git a/src/lib/components/markdown/markdown.pcss b/src/lib/components/markdown/markdown.pcss new file mode 100644 index 0000000..2e5c73e --- /dev/null +++ b/src/lib/components/markdown/markdown.pcss @@ -0,0 +1,177 @@ +[data-theme] { + display: flex; + flex-direction: column; +} + +code[data-theme*=' '], +code[data-theme*=' '] span { + color: var(--shiki-light); + background-color: var(--shiki-light-bg); +} + +.journey p { + @apply text-sm md:text-base; +} + +[data-rehype-pretty-code-figure] [data-line-numbers] > [data-line]::before { + @apply text-xs text-black; + counter-increment: line; + content: counter(line); + display: inline-block; + width: 1rem; + margin-right: 1rem; + text-align: right; +} + +.mdsvex span[data-rehype-pretty-code-figure] { + @apply inline-flex w-fit; +} + +.mdsvex span[data-line] { + @apply inline-block w-full; +} + +.mdsvex span[data-rehype-pretty-code-figure] code { + @apply inline-flex w-full border-none bg-background text-base; + + & span[data-line] { + @apply inline-block px-0; + } +} + +/* +p > code { + @apply bg-slate-200 dark:bg-zinc-700/70 px-1 rounded-md mx-1 border border-primary font-mono tracking-wide text-base; +} */ + +.mdsvex code:not(pre code) { + white-space: pre-wrap; + word-break: break-all; + overflow-wrap: break-word; + @apply h-5 rounded-md border border-primary bg-zinc-100 font-mono; +} + +code:not(code[data-language]) { + @apply h-5 rounded-md border border-primary bg-zinc-100 font-mono px-1 mx-1; +} + +[data-metadata] [data-code-copy] { + @apply top-16 !important; +} + +.mdsvex .code-add { + @apply border-l-green-600 bg-green-100; +} + +.mdsvex .code-delete { + @apply border-l-red-600 bg-red-100; +} + +[data-rehype-pretty-code-figure] { + @apply relative; + + & pre { + @apply max-h-[450px] min-h-0 overflow-x-auto bg-zinc-50 py-2 text-base font-medium; + display: flex; + flex-direction: column; + } + + & code { + @apply grid min-w-full break-words rounded-none border-0 bg-transparent p-0; + counter-reset: line; + box-decoration-break: clone; + } + + & [data-line] { + @apply inline-block w-full basis-4 border-l-[3px] border-l-transparent py-0.5 pl-2 pr-5; + } + + & [data-highlighted-line] { + @apply border-l-orange-500 bg-orange-500/[0.1]; + } + + /* + & [data-highlighted-line-id='add'] { + @apply border-none bg-green-500/[0.1]; + } + + + & [data-highlighted-line-id='add']::before { + content: '+'; + margin-left: -6px; + margin-right: 2px; + @apply text-xs text-green-700; + } + + + & [data-highlighted-line-id='delete'] { + @apply border-none bg-red-500/[0.1]; + } + + & [data-highlighted-line-id='delete']::before { + content: '-'; + margin-left: -6px; + margin-right: 2px; + @apply text-xs text-red-700; + } + + */ + + & [data-highlighted-line][data-highlighted-line-id='add'] { + @apply border-l-green-600 data-[highlighted-line-id="add"]:bg-green-100; + } + + & [data-highlighted-line][data-highlighted-line-id='remove'] { + @apply border-l-red-600 data-[highlighted-line-id="remove"]:bg-red-100; + } + + & [data-chars-id] { + @apply pb-0.5 shadow-none; + } +} + +[data-comp-preview] [data-rehype-pretty-code-figure] { + & pre { + @apply mt-0 rounded-b-lg rounded-t-none; + } +} + +[data-chars-id='ul'] { + @apply border-b border-b-green-500 font-bold !important; +} + +[data-chars-id='hi'] { + @apply rounded bg-teal-700/60 p-1 font-bold !important; +} + +[data-chars-id='rb'] { + @apply rounded border border-red-600 p-[2px] font-bold !important; +} + +[data-chars-id='yb'] { + @apply rounded border border-yellow-600 p-[2px] font-bold !important; +} + +/* [data-rehype-pretty-code-title] { + @apply mt-2 px-4 pt-6 text-sm font-medium; +} */ + +[data-rehype-pretty-code-title] { + @apply hidden; +} + +[data-rehype-pretty-code-title] + pre { + @apply mt-2; +} + +/* [data-callout] > p:last-child { + @apply mb-0 !important; +} + +[data-comp-preview] + p { + @apply mt-6; +} + +[data-metadata]:not(:has(pre)) { + display: none; +} */ diff --git a/src/lib/components/markdown/ol.svelte b/src/lib/components/markdown/ol.svelte new file mode 100644 index 0000000..9f5b83e --- /dev/null +++ b/src/lib/components/markdown/ol.svelte @@ -0,0 +1,21 @@ + + +
      + {@render children()} +
    diff --git a/src/lib/components/markdown/p.svelte b/src/lib/components/markdown/p.svelte new file mode 100644 index 0000000..4f583f0 --- /dev/null +++ b/src/lib/components/markdown/p.svelte @@ -0,0 +1,18 @@ + + +

    + {@render children()} +

    diff --git a/src/lib/components/markdown/pre.svelte b/src/lib/components/markdown/pre.svelte new file mode 100644 index 0000000..f657136 --- /dev/null +++ b/src/lib/components/markdown/pre.svelte @@ -0,0 +1,111 @@ + + +{#snippet iconImage({ langIcons, extension }: IconImageType)} + Language +{/snippet} + +
    +
    + + + + + +

    + {#if title} + {title} + {@const extension = title.split('.').pop()} + {#if extension && langIcons[extension]} + {@render iconImage({ langIcons, extension })} + {/if} + {:else if lang && langIcons[lang]} + {@render iconImage({ langIcons, extension: lang })} + {/if} +

    +
    +
    + +
    +
    +
    +
    +		{@render children()}
    +    
    +
    diff --git a/src/lib/components/markdown/toast-code-title.svelte b/src/lib/components/markdown/toast-code-title.svelte new file mode 100644 index 0000000..49284f4 --- /dev/null +++ b/src/lib/components/markdown/toast-code-title.svelte @@ -0,0 +1,15 @@ + + +
    +
    + + {title} +
    +
    + Copied to clipboard +
    +
    diff --git a/src/lib/components/markdown/ul.svelte b/src/lib/components/markdown/ul.svelte new file mode 100644 index 0000000..4109b47 --- /dev/null +++ b/src/lib/components/markdown/ul.svelte @@ -0,0 +1,18 @@ + + +
      + {@render children()} +
    diff --git a/src/lib/components/search/PageFindSearch.svelte b/src/lib/components/search/PageFindSearch.svelte deleted file mode 100644 index 65ddcf1..0000000 --- a/src/lib/components/search/PageFindSearch.svelte +++ /dev/null @@ -1,85 +0,0 @@ - - - - Search {title} - - -