setting and importing blog scripts and imgs

This commit is contained in:
matthieu42morin 2023-11-02 00:42:12 +01:00
parent 66ba7d2378
commit e519c6e385
27 changed files with 383 additions and 0 deletions

View File

@ -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.

View File

@ -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.

16
src/content/types.d.ts vendored Normal file
View File

@ -0,0 +1,16 @@
export interface MarkdownHeading {
title: string;
slug: string;
level: number;
children: MarkdownHeading[];
}
export interface MarkdownMetadata {
headings: MarkdownHeading[];
}
export interface MdsvexImport<T extends MarkdownMetadata = MarkdownMetadata> {
// Technically not correct but needed to make language-tools happy
default: ConstructorOfATypedSvelteComponent;
metadata: T;
}

10
src/lib/config.ts Normal file
View File

@ -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';

View File

@ -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;

16
src/lib/contents/types.d.ts vendored Normal file
View File

@ -0,0 +1,16 @@
export interface MarkdownHeading {
title: string;
slug: string;
level: number;
children: MarkdownHeading[];
}
export interface MarkdownMetadata {
headings: MarkdownHeading[];
}
export interface MdsvexImport<T extends MarkdownMetadata = MarkdownMetadata> {
// Technically not correct but needed to make language-tools happy
default: ConstructorOfATypedSvelteComponent;
metadata: T;
}

15
src/lib/types/blog.d.ts vendored Normal file
View File

@ -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;
}

1
src/lib/types/categories.d.ts vendored Normal file
View File

@ -0,0 +1 @@
export type categories = 'sveltekit' | 'svelte';

View File

@ -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;
};

View File

@ -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 `<CodeFence code={${JSON.stringify(highlighted)}}
rawCode={${JSON.stringify(code)}}
lang={"${_lang}"}
${title ? `title={"${title}"}` : ''}
/>`;
}

View File

@ -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 = /^<script context="module">/.test(markup);
const isModulePass = attributes?.context === 'module';
if (!isModulePass || !hasModuleContext) {
return { code: content };
}
const isValidPass =
(hasModuleContext && isModulePass) || !hasModuleContext;
if (!isValidPass) {
return { code: content };
}
return { code: `${imports}\n${content}` };
},
};
return preprocessor;
};

View File

@ -0,0 +1,30 @@
import { visit } from 'unist-util-visit';
const youtubeEmbedRegex = new RegExp(`\(youtube\):\(\.\*\)`, 'i');
const embedVideoHtml = (videoId, options) => `
<span class="relative mt-medium not-prose block overflow-hidden max-w-full after:block after:pt-[56.26%]"><iframe
title="${options.title ? options.title : 'Youtube Video'}"
width="${options.width}"
height="${options.height}"
src="https://www.youtube-nocookie.com/embed/${videoId}?rel=0"
class="absolute top-0 left-0 w-full h-full"
${options.noIframeBorder ? 'style="border:0"' : ''}
allowfullscreen
sandbox="allow-same-origin allow-scripts allow-popups">
</iframe></span>`;
const visitor = (options) => (node) => {
if (node.type === 'inlineCode') {
const regexResult = node.value.match(youtubeEmbedRegex);
if (regexResult) {
node.type = 'html';
node.value = embedVideoHtml(regexResult[2].trim(), options);
}
}
};
export default (options) => (tree) => {
visit(tree, visitor(options));
return tree;
};

View File

@ -0,0 +1,34 @@
import { visit } from 'unist-util-visit';
import regexCreator from 'emoji-regex';
const emojiRegex = regexCreator();
const nonAlphanumericsAtTheBeginningRegex = /^\W+/g;
const nonAlphanumericsAtTheEndRegex = /\W+$/g;
const beautifyFragment = (str = '') =>
str
.replace(emojiRegex, '')
.replace(nonAlphanumericsAtTheBeginningRegex, '')
.replace(nonAlphanumericsAtTheEndRegex, '');
const visitor = (node) => {
node.data = node.data || {};
node.data.hProperties = node.data.hProperties || {};
if (node.type === 'heading') {
let fragment = node.data.id;
fragment = beautifyFragment(fragment);
const lastChildrenIdx = node.children.length - 1;
const headingPermalink = node.children[lastChildrenIdx];
headingPermalink.url = `#${fragment}`;
node.data.hProperties.id = fragment;
node.data.id = fragment;
}
};
export default () => async (tree) => {
visit(tree, visitor);
return tree;
};

View File

@ -0,0 +1,22 @@
import { visit } from 'unist-util-visit';
const visitor = (node) => {
node.data = node.data || {};
node.data.hProperties = node.data.hProperties || {};
if (node.type === 'link') {
if (
node.children &&
node.children.length &&
node.children.length === 1
) {
if (node.children[0].type === 'image') {
node.data.hProperties.class = 'after:hidden';
}
}
}
};
export default () => async (tree) => {
visit(tree, visitor);
return tree;
};

View File

@ -0,0 +1,26 @@
import { visit } from 'unist-util-visit';
const imagesRelativeUrlPattern = '/images/';
const visitor = (node) => {
if (
node.type === 'image' &&
node.url.indexOf(imagesRelativeUrlPattern) > 0
) {
node.url = node.url.substring(
node.url.indexOf(imagesRelativeUrlPattern) + ''.length,
);
}
};
export default () => async (tree, vFile) => {
if (
vFile.filename.indexOf('src/routes/docs/') > 0 ||
vFile.filename.indexOf('src/routes/blog/') > 0 ||
vFile.filename.indexOf('src/routes/guides/') > 0 ||
vFile.filename.indexOf('src/routes/customers/') > 0
) {
visit(tree, visitor);
}
return tree;
};

BIN
static/images/Logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 555 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 950 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 712 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
static/logos/LI-In-Bug.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

BIN
static/logos/LI-Logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

@ -0,0 +1 @@
<svg width="98" height="96" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z" fill="#fff"/></svg>

After

Width:  |  Height:  |  Size: 980 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@ -0,0 +1 @@
<svg width="98" height="96" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z" fill="#24292f"/></svg>

After

Width:  |  Height:  |  Size: 963 B