diff --git a/README.md b/README.md index b5b2950..63c7a44 100644 --- a/README.md +++ b/README.md @@ -36,3 +36,17 @@ npm run build You can preview the production build with `npm run preview`. > To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment. + +# Create Blog Posts + +To create a new post, all you must do is create a new markdown file in the `./src/blog/` directory. +However, before you begin writing, you must first add the following two lines at the top of the +new markdown file: + +```markdown +Date: YYYY-MM-DD +Desc: Some short description to post on the index page of the blogs. +``` + +Below this, you can write your blog post in the markdown format. The metadata above is used for +displaying and parsing the post. diff --git a/package.json b/package.json index 4dea8ff..8d16a73 100644 --- a/package.json +++ b/package.json @@ -1,46 +1,46 @@ { - "name": "personalsite", - "private": true, - "version": "0.0.1", - "type": "module", - "scripts": { - "dev": "vite dev", - "build": "vite build", - "preview": "vite preview", - "prepare": "svelte-kit sync || echo ''", - "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", - "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", - "format": "prettier --write .", - "lint": "prettier --check . && eslint ." - }, - "devDependencies": { - "@eslint/compat": "^1.2.5", - "@eslint/js": "^9.18.0", - "@sveltejs/adapter-auto": "^4.0.0", - "@sveltejs/adapter-node": "^5.2.12", - "@sveltejs/kit": "^2.16.0", - "@sveltejs/vite-plugin-svelte": "^5.0.0", - "@tailwindcss/vite": "^4.0.0", - "eslint": "^9.18.0", - "eslint-config-prettier": "^10.0.1", - "eslint-plugin-svelte": "^2.46.1", - "globals": "^15.14.0", - "prettier": "^3.4.2", - "prettier-plugin-svelte": "^3.3.3", - "prettier-plugin-tailwindcss": "^0.6.11", - "svelte": "^5.0.0", - "svelte-check": "^4.0.0", - "tailwindcss": "^4.0.0", - "typescript": "^5.0.0", - "typescript-eslint": "^8.20.0", - "vite": "^6.0.0" - }, - "dependencies": { - "@types/node": "^22.13.5", - "dompurify": "^3.2.4", - "highlight.js": "^11.11.1", - "marked": "^15.0.7", - "marked-highlight": "^2.2.1", - "path": "^0.12.7" - } + "name": "personalsite", + "private": true, + "version": "0.0.1", + "type": "module", + "scripts": { + "dev": "vite dev", + "build": "vite build", + "preview": "vite preview", + "prepare": "svelte-kit sync || echo ''", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", + "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", + "format": "prettier --write .", + "lint": "prettier --check . && eslint ." + }, + "devDependencies": { + "@eslint/compat": "^1.2.5", + "@eslint/js": "^9.18.0", + "@sveltejs/adapter-auto": "^4.0.0", + "@sveltejs/adapter-node": "^5.2.12", + "@sveltejs/kit": "^2.16.0", + "@sveltejs/vite-plugin-svelte": "^5.0.0", + "@tailwindcss/vite": "^4.0.0", + "eslint": "^9.18.0", + "eslint-config-prettier": "^10.0.1", + "eslint-plugin-svelte": "^2.46.1", + "globals": "^15.14.0", + "prettier": "^3.4.2", + "prettier-plugin-svelte": "^3.3.3", + "prettier-plugin-tailwindcss": "^0.6.11", + "svelte": "^5.0.0", + "svelte-check": "^4.0.0", + "tailwindcss": "^4.0.0", + "typescript": "^5.0.0", + "typescript-eslint": "^8.20.0", + "vite": "^6.0.0" + }, + "dependencies": { + "@types/node": "^22.13.5", + "dompurify": "^3.2.4", + "highlight.js": "^11.11.1", + "marked": "^15.0.7", + "marked-highlight": "^2.2.1", + "path": "^0.12.7" + } } diff --git a/src/blog/postOne.md b/src/blog/Markdown Parser Edge Cases.md similarity index 99% rename from src/blog/postOne.md rename to src/blog/Markdown Parser Edge Cases.md index ce41449..a8313cf 100644 --- a/src/blog/postOne.md +++ b/src/blog/Markdown Parser Edge Cases.md @@ -1,4 +1,5 @@ Date: 2025-02-23 +Desc: Testing the markdown parser with various elements and edge cases. # H1 Tag ## H2 Tag ### H3 Tag diff --git a/src/blog/Neovim: A Robust Alternative to Visual Studio Code.md b/src/blog/Neovim: A Robust Alternative to Visual Studio Code.md index ca67001..da30878 100644 --- a/src/blog/Neovim: A Robust Alternative to Visual Studio Code.md +++ b/src/blog/Neovim: A Robust Alternative to Visual Studio Code.md @@ -1,4 +1,5 @@ Date: 2025-02-24 +Desc: A comparison of performance, extensibility, modal editing, community, and popularity. # Neovim: A Robust Alternative to Visual Studio Code ###### Author: Hayden Hargreaves diff --git a/src/blog/gemini.md b/src/blog/Programming: From Gemini.md similarity index 99% rename from src/blog/gemini.md rename to src/blog/Programming: From Gemini.md index 618031b..af234c1 100644 --- a/src/blog/gemini.md +++ b/src/blog/Programming: From Gemini.md @@ -1,4 +1,5 @@ Date: 2025-02-24 +Desc: A silly article from Gemini. # Diving Deep into the World of Programming: A Journey of Logic and Creativity Programming, in its essence, is the art and science of communicating with computers. It's about crafting a precise sequence of instructions, a "program," that dictates every step a machine should take. From the sleek applications on your smartphone to the intricate systems that manage global infrastructure, programming is the invisible hand shaping the technological world we inhabit. It's more than just lines of code; it's the engine of innovation. diff --git a/src/blog/README.md b/src/blog/README.md new file mode 100644 index 0000000..63c7a44 --- /dev/null +++ b/src/blog/README.md @@ -0,0 +1,52 @@ +# sv + +Everything you need to build a Svelte project, powered by [`sv`](https://github.com/sveltejs/cli). + +## Creating a project + +If you're seeing this, you've probably already done this step. Congrats! + +```bash +# create a new project in the current directory +npx sv create + +# create a new project in my-app +npx sv create my-app +``` + +## Developing + +Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: + +```bash +npm run dev + +# or start the server and open the app in a new browser tab +npm run dev -- --open +``` + +## Building + +To create a production version of your app: + +```bash +npm run build +``` + +You can preview the production build with `npm run preview`. + +> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment. + +# Create Blog Posts + +To create a new post, all you must do is create a new markdown file in the `./src/blog/` directory. +However, before you begin writing, you must first add the following two lines at the top of the +new markdown file: + +```markdown +Date: YYYY-MM-DD +Desc: Some short description to post on the index page of the blogs. +``` + +Below this, you can write your blog post in the markdown format. The metadata above is used for +displaying and parsing the post. diff --git a/src/routes/blog/+page.server.ts b/src/routes/blog/+page.server.ts new file mode 100644 index 0000000..b9108ca --- /dev/null +++ b/src/routes/blog/+page.server.ts @@ -0,0 +1,53 @@ +import { readdirSync, readFileSync } from 'fs'; + +// Location of the blogs, all md files should be placed here +const blog_path = process.cwd().concat('/src', '/blog'); + +/** + * The post object for use in the page. + * @property {string} title - The title of the post. + * @property {string} description - The description of the post. + * @property {string} path - The path to the post for the URL. + * @property {Date} date - The date the post was created. +*/ +type Post = { + title: string; + description: string; + path: string; + date: Date; +}; + +// For this use, we do not need the RequestEvent object +export const load = async () => { + const posts: Post[] = []; + + // Read all the files names in the blog directory. + readdirSync(blog_path).forEach(file => { + const content: string = readFileSync(blog_path.concat('/', file), 'utf-8'); + + // Date: 2025-02-24 -> date object + // Desc: ... -> description + const lines: string[] = content.split("\n"); + let date: Date = new Date(); + let description: string = ""; + + // Ensure the meta data is provided + if (lines[0].slice(0, 5) == "Date:" || lines[1].slice(0, 5) == "Desc:") { + date = new Date(lines[0].split("Date:")[1].trim()); + description = lines[1].split("Desc:")[1].trim(); + } + + // Create the post + const post: Post = { + title: file.split('.')[0], + path: '/blog'.concat('/', file.split('.')[0]), + date, + description + } + posts.push(post); + }); + + return { + posts: posts, + }; +}; diff --git a/src/routes/blog/+page.svelte b/src/routes/blog/+page.svelte new file mode 100644 index 0000000..0f6f8e3 --- /dev/null +++ b/src/routes/blog/+page.svelte @@ -0,0 +1,38 @@ + + +
+ +
+

Blog Posts.

+

+ Here you can find a list of all the blog posts I have written. Some of them are about my + projects, some are about my thoughts, and some are about my experiences. I hope you enjoy! +

+
+ +
+ {#each data.posts as post} +
+

+ + {post.title} + + +

+

{post.description}

+
+ {/each} +
+
diff --git a/src/routes/blog/[title]/+page.server.ts b/src/routes/blog/[title]/+page.server.ts index 2233f49..40c2939 100644 --- a/src/routes/blog/[title]/+page.server.ts +++ b/src/routes/blog/[title]/+page.server.ts @@ -18,9 +18,9 @@ export const load = async ({ url }: RequestEvent) => { const cleanPath = blogPath.replaceAll("%20", " "); // Read the file and get the data - let data: string = ""; + let content: string = ""; try { - data = readFileSync(cleanPath, 'utf-8'); + content = readFileSync(cleanPath, 'utf-8'); } catch { // Catch and return any errors return { @@ -33,7 +33,19 @@ export const load = async ({ url }: RequestEvent) => { } // Date: 2025-02-24 -> date object - const date: Date = new Date(data.split("\n")[0].split(":")[1].trim()); + // Desc: ... -> description + let lines: string[] = content.split("\n"); + let date: Date = new Date(); + let description: string = ""; + + // Ensure the meta data is provided + if (lines[0].slice(0, 5) == "Date:" || lines[1].slice(0, 5) == "Desc:") { + date = new Date(lines[0].split("Date:")[1].trim()); + description = lines[1].split("Desc:")[1].trim(); + + // Remove meta data from final content + lines = lines.slice(2); + } // Create a marked object that can parse the data const marked = new Marked( @@ -50,8 +62,9 @@ export const load = async ({ url }: RequestEvent) => { return { post: { // Convert the markdown to HTML. Slice off the first line which is the date of publication. + // The second line is the description of the post. // Any other meta data that needs to be cut can be removed by increasing the '1' in the slice. - content: marked.parse(data.split("\n").slice(1).join("\n")), + content: marked.parse(lines.join("\n")), date: date, error: null, } diff --git a/src/routes/blog/[title]/+page.svelte b/src/routes/blog/[title]/+page.svelte index 4ff6704..d08776a 100644 --- a/src/routes/blog/[title]/+page.svelte +++ b/src/routes/blog/[title]/+page.svelte @@ -1,8 +1,6 @@ {#if data.post.error}