diff --git a/src/content/blog/first-post.md b/src/content/blog/first-post.md new file mode 100644 index 0000000..47a7172 --- /dev/null +++ b/src/content/blog/first-post.md @@ -0,0 +1,15 @@ +--- +title: First post +excerpt: First post +date: 2021-01-01 +tags: + - first + - post +published: true +image: Feature.jpg + +--- + +## Svelte + +Media inside the **Svelte** folder is served from the `static` folder. diff --git a/src/content/blog/second-post.md b/src/content/blog/second-post.md new file mode 100644 index 0000000..e871a84 --- /dev/null +++ b/src/content/blog/second-post.md @@ -0,0 +1,15 @@ +--- +title: Second post +excerpt: Second post +date: 2023-01-01 +tags: + - first + - post +published: true +image: Feature.jpg + +--- + +## Svelte + +Media inside the **Svelte** folder is server from the `static` folder. diff --git a/src/content/types.d.ts b/src/content/types.d.ts new file mode 100644 index 0000000..9655b9f --- /dev/null +++ b/src/content/types.d.ts @@ -0,0 +1,16 @@ +export interface MarkdownHeading { + title: string; + slug: string; + level: number; + children: MarkdownHeading[]; +} + +export interface MarkdownMetadata { + headings: MarkdownHeading[]; +} + +export interface MdsvexImport { + // Technically not correct but needed to make language-tools happy + default: ConstructorOfATypedSvelteComponent; + metadata: T; +} diff --git a/src/lib/config.ts b/src/lib/config.ts new file mode 100644 index 0000000..c124799 --- /dev/null +++ b/src/lib/config.ts @@ -0,0 +1,10 @@ +import { dev } from '$app/environment'; + +export const title = "Matt's Matrix"; +export const description = 'A blog about SvelteKit, Svelte, and other things.'; +export const url = dev ? 'http://localhost:5174' : 'https://mattmor.in'; +export const author = 'Matt Morin'; + +export const email = 'mailto:matt.b.morin@pm.me'; +export const LinkedIn = 'https://www.linkedin.com/in/matthieu-morin/'; +export const github = 'https://github.com/matthieu42morin'; diff --git a/src/lib/contents/skills.ts b/src/lib/contents/skills.ts new file mode 100644 index 0000000..8fd457f --- /dev/null +++ b/src/lib/contents/skills.ts @@ -0,0 +1,12 @@ +const skills = { + programming: ['Svelte', 'TypeScript', 'React.js', 'Svelte.js', 'Go', 'Electron'], + Devops: [], + Linux: ['', ''], + IoT: ['Raspberry Pi', 'Arduino', 'ESP32', 'ESP8266', 'lots of sensors','MQTT', 'LoRa', 'BLE', 'NFC', 'RFID', 'WiFi', ], + databases: ['MongoDB', 'PostgreSQL'], + Tools: [], + languages: ['Italian', 'English'], + other: ['Figma', 'UI design'] +}; + +export default skills; \ No newline at end of file diff --git a/src/lib/contents/types.d.ts b/src/lib/contents/types.d.ts new file mode 100644 index 0000000..9655b9f --- /dev/null +++ b/src/lib/contents/types.d.ts @@ -0,0 +1,16 @@ +export interface MarkdownHeading { + title: string; + slug: string; + level: number; + children: MarkdownHeading[]; +} + +export interface MarkdownMetadata { + headings: MarkdownHeading[]; +} + +export interface MdsvexImport { + // Technically not correct but needed to make language-tools happy + default: ConstructorOfATypedSvelteComponent; + metadata: T; +} diff --git a/src/lib/types/blog.d.ts b/src/lib/types/blog.d.ts new file mode 100644 index 0000000..21c8377 --- /dev/null +++ b/src/lib/types/blog.d.ts @@ -0,0 +1,15 @@ +import type { MarkdownMetadata } from '$lib/contents/types'; + +export type BlogTag = 'Projects' | 'Ideas' | 'Updates' | ''; + +export interface BlogPost extends MarkdownMetadata { + date?: string; + excerpt: string; + image: string; + slug?: string; + href?: string; + tags?: BlogTag[]; + subtitle?: string; + title: string; + published: boolean; +} diff --git a/src/lib/types/categories.d.ts b/src/lib/types/categories.d.ts new file mode 100644 index 0000000..69bb702 --- /dev/null +++ b/src/lib/types/categories.d.ts @@ -0,0 +1 @@ +export type categories = 'sveltekit' | 'svelte'; diff --git a/src/lib/utils/get-headings.js b/src/lib/utils/get-headings.js new file mode 100644 index 0000000..420dad0 --- /dev/null +++ b/src/lib/utils/get-headings.js @@ -0,0 +1,51 @@ +import { toString } from 'mdast-util-to-string'; +import { visit } from 'unist-util-visit'; + +export default () => (tree, vFile) => { + let headers = []; + visit(tree, (node) => { + if (node.type === 'heading') { + if (node.depth !== 1) { + const sanitizedString = toString(node).replace( + /{(.*?)}/, + (_, token) => { + return vFile.data.fm[token] || token; + }, + ); + headers.push({ + title: sanitizedString, + level: node.depth, + slug: node.data.id, + children: [], + }); + } + } + }); + + const stack = []; + const sortedHeaders = []; + + //const sort Header to tree + const sortHeader = (header) => { + while (stack.length !== 0 && header.level <= stack[0].level) { + stack.shift(); + } + + if (stack.length === 0) { + sortedHeaders.push(header); + stack.push(header); + } else { + (stack[0].children ??= []).push(header); + stack.unshift(header); + } + }; + + headers.forEach((_, index) => { + const header = headers[index]; + sortHeader(header); + }); + + if (!vFile.data.fm) vFile.data.fm = {}; + vFile.data.fm.headings = sortedHeaders; + return tree; +}; diff --git a/src/lib/utils/highlight.js b/src/lib/utils/highlight.js new file mode 100644 index 0000000..e0d867b --- /dev/null +++ b/src/lib/utils/highlight.js @@ -0,0 +1,45 @@ +import Prism from 'prismjs'; +import 'prismjs/components/prism-docker.min.js'; +import 'prismjs/components/prism-bash.min.js'; +import 'prismjs/components/prism-yaml.min.js'; +import 'prismjs/components/prism-javascript.min.js'; +import 'prismjs/components/prism-json.min.js'; +import 'prismjs/components/prism-markdown.min.js'; +import 'prismjs/components/prism-sql.min.js'; +import 'prismjs/components/prism-toml.min.js'; +import 'prismjs/components/prism-promql.min.js'; +import 'prismjs/components/prism-go.min.js'; +import 'prismjs/components/prism-typescript.min.js'; +import 'prismjs/components/prism-python.min.js'; +import { escapeSvelte } from 'mdsvex'; + +const langMap = { + sh: 'bash', + Dockerfile: 'dockerfile', + YAML: 'yaml', +}; + +/** + * + * @param {string} code the code that gets parsed + * @param {string} lang the language the code is written in + * @param {string} meta meta information for the code fence + * @returns {string} + */ +export function highlightCode(code, lang, meta) { + let title = null; + const _lang = langMap[lang] || lang || ''; + + if (meta) { + title = meta.match(/title="?(.*?)"/)?.[1]; + } + + const highlighted = _lang + ? escapeSvelte(Prism.highlight(code, Prism.languages[_lang], _lang)) + : code; + return ``; +} diff --git a/src/lib/utils/mdsvex-global-components.js b/src/lib/utils/mdsvex-global-components.js new file mode 100644 index 0000000..58c684a --- /dev/null +++ b/src/lib/utils/mdsvex-global-components.js @@ -0,0 +1,73 @@ +/** + * Credit goes to @Xananax for providing this solution within the gist https://gist.github.com/Xananax/5dca3a1dd7070e4fdebe2927e4aeb55b + */ +import { join, basename, extname } from 'path'; + +export const defaults = { + extensions: ['.svelte.md', '.md', '.svx'], + dir: `$lib`, + list: [], +}; + +/** + * Injects global imports in all your mdsvex files + * Specify: + * - the root dir (defaults to `src/lib`) + * - the array list of components (with extension), like `['Component.svelte']` + * - the valid extensions list as an array (defaults to `['.svelte.md', '.md', '.svx']`) + * + * If you want the component name to be different from the file name, you can specify an array + * of arrays: `['Component.svelte', ['Another', 'AnotherComp.svelte'], 'ThirdComp.svelte']` + * + * @param {Object} options options described above + * @returns a preprocessor suitable to plug into the `preprocess` key of the svelte config + */ +export const mdsvexGlobalComponents = (options = {}) => { + const { extensions, dir, list } = { ...defaults, ...options }; + const extensionsRegex = new RegExp( + '(' + extensions.join('|').replace(/\./g, '\\.') + ')$', + 'i', + ); + + if (!list || !list.length || !Array.isArray(list)) { + throw new Error( + `"list" option must be an array and contain at least one element`, + ); + } + + const imports = list + .map((entry) => { + let name = ''; + if (Array.isArray(entry)) { + name = entry[0]; + entry = entry[1]; + } + const ext = extname(entry); + const path = join(dir, entry); + name = name || basename(entry, ext); + return `\nimport ${name} from "${path}"`; + }) + .join('\n'); + + const preprocessor = { + script(thing) { + const { content, filename, attributes, markup } = thing; + if (!filename.match(extensionsRegex)) { + return { code: content }; + } + const hasModuleContext = /^