diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..12fc788 --- /dev/null +++ b/.env.example @@ -0,0 +1,6 @@ +# Hostname +PUBLIC_HOSTNAME = 'moris.day' + +# Post +POST_DIR = '/home/user/BlogPosts' +PUBLIC_POST_REPO = 'https://github.com/moris/Posts' \ No newline at end of file diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..b6f27f1 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +engine-strict=true diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..4b69478 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "npm.packageManager": "bun", +} \ No newline at end of file diff --git a/Caddyfile b/Caddyfile new file mode 100644 index 0000000..33e1efc --- /dev/null +++ b/Caddyfile @@ -0,0 +1,7 @@ +localhost:80, macbookair.local:80 { + file_server + + handle_path /blog/* { + root build + } +} diff --git a/bun.lockb b/bun.lockb new file mode 100755 index 0000000..b44a5fc Binary files /dev/null and b/bun.lockb differ diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..d7375b6 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,735 @@ +{ + "name": "day.moris.blog", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "day.moris.blog", + "version": "0.0.1", + "devDependencies": { + "@sveltejs/adapter-auto": "^3.0.0", + "@sveltejs/adapter-static": "^3.0.8", + "@sveltejs/kit": "^2.0.0", + "@sveltejs/vite-plugin-svelte": "^4.0.0", + "svelte": "^5.0.0", + "svelte-check": "^4.0.0", + "typescript": "^5.0.0", + "vite": "^5.4.11" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.28", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.29.1", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@sveltejs/adapter-auto": { + "version": "3.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "import-meta-resolve": "^4.1.0" + }, + "peerDependencies": { + "@sveltejs/kit": "^2.0.0" + } + }, + "node_modules/@sveltejs/adapter-static": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.8.tgz", + "integrity": "sha512-YaDrquRpZwfcXbnlDsSrBQNCChVOT9MGuSg+dMAyfsAa1SmiAhrA5jUYUiIMC59G92kIbY/AaQOWcBdq+lh+zg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@sveltejs/kit": "^2.0.0" + } + }, + "node_modules/@sveltejs/kit": { + "version": "2.15.1", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@types/cookie": "^0.6.0", + "cookie": "^0.6.0", + "devalue": "^5.1.0", + "esm-env": "^1.2.1", + "import-meta-resolve": "^4.1.0", + "kleur": "^4.1.5", + "magic-string": "^0.30.5", + "mrmime": "^2.0.0", + "sade": "^1.8.1", + "set-cookie-parser": "^2.6.0", + "sirv": "^3.0.0", + "tiny-glob": "^0.2.9" + }, + "bin": { + "svelte-kit": "svelte-kit.js" + }, + "engines": { + "node": ">=18.13" + }, + "peerDependencies": { + "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0", + "svelte": "^4.0.0 || ^5.0.0-next.0", + "vite": "^5.0.3 || ^6.0.0" + } + }, + "node_modules/@sveltejs/vite-plugin-svelte": { + "version": "4.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@sveltejs/vite-plugin-svelte-inspector": "^3.0.0-next.0||^3.0.0", + "debug": "^4.3.7", + "deepmerge": "^4.3.1", + "kleur": "^4.1.5", + "magic-string": "^0.30.12", + "vitefu": "^1.0.3" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22" + }, + "peerDependencies": { + "svelte": "^5.0.0-next.96 || ^5.0.0", + "vite": "^5.0.0" + } + }, + "node_modules/@sveltejs/vite-plugin-svelte-inspector": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.7" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22" + }, + "peerDependencies": { + "@sveltejs/vite-plugin-svelte": "^4.0.0-next.0||^4.0.0", + "svelte": "^5.0.0-next.96 || ^5.0.0", + "vite": "^5.0.0" + } + }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.14.0", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-typescript": { + "version": "1.4.13", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": ">=8.9.0" + } + }, + "node_modules/aria-query": { + "version": "5.3.2", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cookie": { + "version": "0.6.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/debug": { + "version": "4.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/devalue": { + "version": "5.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.21.5", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/esm-env": { + "version": "1.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/esrap": { + "version": "1.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, + "node_modules/fdir": { + "version": "6.4.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/globalyzer": { + "version": "0.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/globrex": { + "version": "0.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/import-meta-resolve": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-reference": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.6" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/locate-character": { + "version": "3.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/magic-string": { + "version": "0.30.17", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/mri": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/mrmime": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.8", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "dev": true, + "license": "ISC" + }, + "node_modules/postcss": { + "version": "8.4.49", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/readdirp": { + "version": "4.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/rollup": { + "version": "4.29.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.29.1", + "@rollup/rollup-android-arm64": "4.29.1", + "@rollup/rollup-darwin-arm64": "4.29.1", + "@rollup/rollup-darwin-x64": "4.29.1", + "@rollup/rollup-freebsd-arm64": "4.29.1", + "@rollup/rollup-freebsd-x64": "4.29.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.29.1", + "@rollup/rollup-linux-arm-musleabihf": "4.29.1", + "@rollup/rollup-linux-arm64-gnu": "4.29.1", + "@rollup/rollup-linux-arm64-musl": "4.29.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.29.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.29.1", + "@rollup/rollup-linux-riscv64-gnu": "4.29.1", + "@rollup/rollup-linux-s390x-gnu": "4.29.1", + "@rollup/rollup-linux-x64-gnu": "4.29.1", + "@rollup/rollup-linux-x64-musl": "4.29.1", + "@rollup/rollup-win32-arm64-msvc": "4.29.1", + "@rollup/rollup-win32-ia32-msvc": "4.29.1", + "@rollup/rollup-win32-x64-msvc": "4.29.1", + "fsevents": "~2.3.2" + } + }, + "node_modules/sade": { + "version": "1.8.1", + "dev": true, + "license": "MIT", + "dependencies": { + "mri": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/set-cookie-parser": { + "version": "2.7.1", + "dev": true, + "license": "MIT" + }, + "node_modules/sirv": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/svelte": { + "version": "5.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.3.0", + "@jridgewell/sourcemap-codec": "^1.5.0", + "@types/estree": "^1.0.5", + "acorn": "^8.12.1", + "acorn-typescript": "^1.4.13", + "aria-query": "^5.3.1", + "axobject-query": "^4.1.0", + "clsx": "^2.1.1", + "esm-env": "^1.2.1", + "esrap": "^1.3.2", + "is-reference": "^3.0.3", + "locate-character": "^3.0.0", + "magic-string": "^0.30.11", + "zimmerframe": "^1.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/svelte-check": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "chokidar": "^4.0.1", + "fdir": "^6.2.0", + "picocolors": "^1.0.0", + "sade": "^1.7.4" + }, + "bin": { + "svelte-check": "bin/svelte-check" + }, + "engines": { + "node": ">= 18.0.0" + }, + "peerDependencies": { + "svelte": "^4.0.0 || ^5.0.0-next.0", + "typescript": ">=5.0.0" + } + }, + "node_modules/tiny-glob": { + "version": "0.2.9", + "dev": true, + "license": "MIT", + "dependencies": { + "globalyzer": "0.1.0", + "globrex": "^0.1.2" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/typescript": { + "version": "5.7.2", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/vite": { + "version": "5.4.11", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vitefu": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "workspaces": [ + "tests/deps/*", + "tests/projects/*" + ], + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/zimmerframe": { + "version": "1.1.2", + "dev": true, + "license": "MIT" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..67e2b3a --- /dev/null +++ b/package.json @@ -0,0 +1,39 @@ +{ + "name": "day.moris.blog", + "private": true, + "version": "0.0.1", + "type": "module", + "scripts": { + "dev": "vite dev", + "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" + }, + "devDependencies": { + "@sveltejs/adapter-static": "^3.0.8", + "@sveltejs/kit": "^2.0.0", + "@sveltejs/vite-plugin-svelte": "^4.0.0", + "svelte": "^5.0.0", + "svelte-check": "^4.0.0", + "typescript": "^5.0.0", + "vite": "^5.4.11", + "@types/bun": "latest" + }, + "dependencies": { + "@twemoji/parser": "^15.1.1", + "github-slugger": "^2.0.0", + "rehype-external-links": "^3.0.0", + "rehype-highlight": "^7.0.1", + "rehype-katex": "^7.0.1", + "rehype-slug": "^6.0.0", + "rehype-stringify": "^10.0.1", + "remark": "^15.0.1", + "remark-breaks": "^4.0.0", + "remark-gfm": "^4.0.0", + "remark-math": "^6.0.0", + "remark-rehype": "^11.1.1", + "yaml": "^2.6.1" + }, + "module": "index.ts" +} \ No newline at end of file diff --git a/src/app.css b/src/app.css new file mode 100644 index 0000000..ff5e16f --- /dev/null +++ b/src/app.css @@ -0,0 +1,99 @@ +@property --theme-color { + syntax: ""; + inherits: true; +} +@property --back-color { + syntax: ""; + inherits: true; +} +@property --grid-color { + syntax: ""; + inherits: true; +} + +/* theme color */ +body, body.light { + --color-scheme: light; + --white-black: white; + --black-white: black; + --theme-color: hsl(85, 50%, 60%); + --back-color: hsl(60, 100%, 98%); + --font-color: #222; + --grid-color: #fff; + --code-color: #ddd; + --code-block: #30303a; + --frame-shadow: #999; +} + +body.dark { + --color-scheme: dark; + --white-black: black; + --black-white: white; + --theme-color: teal; + --back-color: hsl(210, 7%, 18%); + --font-color: #f5f5f5; + --grid-color: #333; + --code-color: #445; + --code-block: #23232a; + --frame-shadow: #111; +} + +@media(prefers-color-scheme: dark){ + body { + --color-scheme: dark; + --white-black: black; + --black-white: white; + --theme-color: teal; + --back-color: hsl(210, 7%, 18%); + --font-color: #fafafa; + --grid-color: #333; + --code-color: #445; + --code-block: #23232a; + --frame-shadow: #111; + } +} + +/* general */ +body { + margin: 0; + color: var(--font-color); +} + +img { + -webkit-user-drag: none; + user-select: none; +} + +@media (scripting: none) { + .js {display: none !important;} +} + + + +/* font */ +body { + font-family: "-apple-system", "BlinkMacSystemFont", "Hiragino Kaku Gothic ProN", "Noto Sans CJK JP", "Segoe UI", "BIZ UDPGothic", sans-serif; + /* Apple | Linux | win-en win-jp */ +} +code { + font-family: "Source Code Pro", "Monaco", "Consolas", "BIZ UDGothic", monospace; + /* Linux | Apple | windows | 和文 */ +} +em { + font-family: serif; +} + + + +/* link style */ +a { + text-decoration: none; + color: var(--theme-color); + + &:hover { + text-decoration: underline; + } + &:visited { + color: hsl(290, 40%, 50%); + } +} \ No newline at end of file diff --git a/src/app.d.ts b/src/app.d.ts new file mode 100644 index 0000000..da08e6d --- /dev/null +++ b/src/app.d.ts @@ -0,0 +1,13 @@ +// See https://svelte.dev/docs/kit/types#app.d.ts +// for information about these interfaces +declare global { + namespace App { + // interface Error {} + // interface Locals {} + // interface PageData {} + // interface PageState {} + // interface Platform {} + } +} + +export {}; diff --git a/src/app.html b/src/app.html new file mode 100644 index 0000000..94b5e5b --- /dev/null +++ b/src/app.html @@ -0,0 +1,12 @@ + + + + + + + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/src/lib/components/Markdown.css b/src/lib/components/Markdown.css new file mode 100644 index 0000000..edc0bda --- /dev/null +++ b/src/lib/components/Markdown.css @@ -0,0 +1,193 @@ +.markdown { + width: 100%; + overflow-wrap: anywhere; + + @media (width>480px) { + font-size: 1.125em; + } + + & h1, h2 { + font-weight: 600; + padding-top: 25px; + @media(width>999px){padding-top:50px; margin-top:0;} + + &::before { + display: inline-block; + content: '§'; + margin-right: 4px; + width: 4px; + color: #0000; + background-color: var(--theme-color); + } + } + + & p { + margin: 0 0.5em; + line-height: 2em; + @media (width>480px) { + margin: 1em 2em; + } + } + + & a[target="_blank"]:after { + content: '■'; + font-size: 1em; + line-height: 1em; + width: 1em; + height: 1em; + display: inline-block; + mask-image: url('data:image/svg+xml;utf-8,'); + vertical-align: top; + } + + & li { + line-height: 1.5em; + } + + & img { + display: block; + margin: 1em auto; + max-width: 100%; + max-height: 60vh; + } + + & code { + font-size: 1rem; + margin: 0 3px; + padding: 0 3px; + border-radius: 3px; + background-color: var(--code-color); + } + & details { + margin: 0 0.5em; + padding: 0 .5em; + border: dashed #8888 2px; + border-radius: 6px; + line-height: 2em; + @media (width>480px) { + margin: 1em 2em; + } + } + & pre { + position: relative; + margin: 1em; + padding: 1em; + box-sizing: border-box; + border-radius: 8px; + background-color: var(--code-block); + color: #d1d9e1; + overflow: auto; + scrollbar-width: thin; + scrollbar-color: #aaa #444; + + @media (width<480px) { + margin: 1em 0; + } + & code { + margin: 0; + padding: 0; + border-radius: 0; + background-color: #fff0; + } + /* + issue: 擬似要素は { イベントリスナを設置できない, アニメーション不可, スクロールに巻き込まれる } + &::after { + content: ''; + background-image: url('data:image/svg+xml;utf-8,'); + width: 1.5em; + height: 1.5em; + position: absolute; + top: 1em; + right: 1em; + } */ + } + & table { + margin: 1rem auto; + font-size: 1.2rem; + border-collapse: collapse; + + & thead tr { + border-bottom: solid 1px var(--black-white); + } + & tbody tr { + border-top: solid color-mix(in srgb, var(--black-white) 20%, var(--back-color)) 1px; + /* background-color: color-mix(in srgb, var(--black-white) 10%, var(--back-color)); */ + } + & td,th { + border-width: 0px; + padding: .5em; + } + } + & blockquote { + position: relative; + font-style: italic; + width: fit-content; + max-width: 100%; + margin: 1em auto; + border-top: 1px solid var(--font-color); + border-bottom: 1px solid var(--font-color); + + & p::before { + content: ''; + mask-image: url('data:image/svg+xml;utf-8,'); + width: 1em; + height: 1em; + position: absolute; + background-color: var(--font-color); + top: -.4em; + left: -1em; + } + & p::after { + content: ''; + mask-image: url('data:image/svg+xml;utf-8,'); + width: 1em; + height: 1em; + position: absolute; + background-color: var(--font-color); + bottom: -.4em; + right: -1em; + } + } + & iframe { + display: block; + margin: 30px auto; + border: none; + width: 80%; + aspect-ratio: 16/9; + border-radius: 12px; + box-shadow: 0px 6px 30px var(--frame-shadow); + max-height: 75vh; + transition: max-height .3s ease-in-out; + &.hide { + max-height: 30px; + } + @media(width<480px) { + width: 100%; + aspect-ratio: 4/3; + box-shadow: 0px 4px 16px var(--frame-shadow); + } + @media(width>1280px) { + width: 60%; + } + &[src*="youtube.com"]{ + aspect-ratio: 16/9; + } + } + & video { + display: block; + margin: 30px auto; + width: 80%; + border-radius: 15px; + box-shadow: 0px 6px 30px var(--frame-shadow); + @media(width<480px) { + width: 100%; + } + @media(width>1280px) { + width: 60%; + } + } + & math[display="block"] { + margin: 1rem; + font-size: 1.5rem; + } +} \ No newline at end of file diff --git a/src/lib/components/Markdown.ts b/src/lib/components/Markdown.ts new file mode 100644 index 0000000..a67c526 --- /dev/null +++ b/src/lib/components/Markdown.ts @@ -0,0 +1,30 @@ +export default Perser; + +import { remark } from 'remark' +import remarkgfm from 'remark-gfm' +import remarkBreaks from "remark-breaks" +import remarkmath from 'remark-math' +import remarkRehype from 'remark-rehype' +import rehypeslug from 'rehype-slug' +import rehypeKatex from 'rehype-katex' +import rehypeHighlight from 'rehype-highlight' +import rehypeExternalLinks from 'rehype-external-links' +import rehypeStringify from 'rehype-stringify' + + +function Perser(mdtext: string): string { + let md = remark() + .use(remarkgfm) // Github Markdown + .use(remarkBreaks) // 改行 + .use(remarkmath) // 数式 + .use(remarkRehype, {allowDangerousHtml: true}) + .use(rehypeslug) // headingにidを設定 + .use(rehypeKatex, {output:'mathml'}) // 数式 + .use(rehypeHighlight) // Syntax highlight + .use(rehypeExternalLinks, {target:'_blank', rel:['noreferrer','noopener']}) // 外部サイトを新規タブで開く + .use(rehypeStringify, {allowDangerousHtml: true}) + .processSync(mdtext) + .toString() + + return md +} \ No newline at end of file diff --git a/src/lib/components/rainbow.css b/src/lib/components/rainbow.css new file mode 100644 index 0000000..dc8452f --- /dev/null +++ b/src/lib/components/rainbow.css @@ -0,0 +1,120 @@ +/* + +BSD 3-Clause License + +Copyright (c) 2006, Ivan Sagalaev. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + + +/* + +Style with support for rainbow parens + +*/ + +.hljs { + background: #474949; + color: #d1d9e1; +} + + +.hljs-comment, +.hljs-quote { + color: #969896; + font-style: italic; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-literal, +.hljs-type { + color: #cc99cc; +} + +.hljs-number, +.hljs-selector-attr, +.hljs-selector-pseudo { + color: #f99157; +} + +.hljs-string, +.hljs-doctag, +.hljs-regexp { + color: #8abeb7; +} + +.hljs-title, +.hljs-name, +.hljs-section, +.hljs-built_in { + color: #b5bd68; +} + +.hljs-variable, +.hljs-template-variable, +.hljs-selector-id, +.hljs-title.class_, +.hljs-class .hljs-title { + color: #ffcc66; +} + +.hljs-section, +.hljs-strong { + font-weight: bold; +} + +.hljs-symbol, +.hljs-bullet, +.hljs-subst, +.hljs-meta, +.hljs-link { + color: #f99157; +} + +.hljs-deletion { + color: #dc322f; +} + +.hljs-addition { + color: #68dc2e +} + +.hljs-formula { + background: #eee8d5; +} + +.hljs-attr, +.hljs-attribute { + color: #81a2be; +} + +.hljs-emphasis { + font-style: italic; +} diff --git a/src/lib/server/LoadPost.ts b/src/lib/server/LoadPost.ts new file mode 100644 index 0000000..7bd26d8 --- /dev/null +++ b/src/lib/server/LoadPost.ts @@ -0,0 +1,26 @@ +export default getpost; + +import { POST_DIR } from '$env/static/private'; +import Parser from './MetaParser'; +import fs from 'node:fs'; + + +async function getpost(id:string) { + const md = fs.readFileSync(`${POST_DIR}/Posts/${id}.md`, 'utf8'); + + let fm_line = md.split('\n'); + + let line_no:number[] = [] + fm_line.forEach((i,n)=>{ + if(i=='---'){line_no.push(n)} + }) + + let a = line_no[0] + + let md_text = fm_line.slice(line_no[1]+1).join('\n'); + let fm_text = fm_line.slice(line_no[0]+1, line_no[1]).join('\n'); + + let metadata = Parser(fm_text); + + return {metadata: metadata, post: md_text} +} \ No newline at end of file diff --git a/src/lib/server/MetaParser.ts b/src/lib/server/MetaParser.ts new file mode 100644 index 0000000..9b37a75 --- /dev/null +++ b/src/lib/server/MetaParser.ts @@ -0,0 +1,34 @@ +export default parser; + +import yaml from "yaml" +import { parse } from '@twemoji/parser'; +import { error } from '@sveltejs/kit'; + +function parser(fm_text:string) { + + let persed = yaml.parse(fm_text); + + let fms = (fm:unknown) => { + if (typeof fm === 'object' && fm !== null){ + let title = 'title' in fm && typeof fm.title === 'string' ? fm.title : '' + let description = 'description' in fm && typeof fm.description === 'string'? fm.description : '' + let thumbnail = 'thumbnail' in fm && typeof fm.thumbnail === 'string' ? fm.thumbnail : '' + let emoji = 'emoji' in fm && typeof fm.emoji === 'string' ? fm.emoji : '' + let date_str = 'date' in fm && typeof fm.date === 'string' ? fm.date : '' + let category = 'category' in fm && typeof fm.category === 'string' ? fm.category : 'other' + let tags = 'tags' in fm && Array.isArray(fm.tags) ? fm.tags : [] + let index = 'index' in fm && typeof fm.index === 'boolean' ? fm.index : true + let published = 'published' in fm && typeof fm.published === 'boolean' ? fm.published : false + + emoji = emoji? parse(emoji)[0].url:'' + + let date:Date = new Date(date_str) + + return {title, description,thumbnail,emoji,date,category,tags,index,published} + } else { + error(500,{message:'Invalid frontmatter'}) + } + } + + return fms(persed) +} \ No newline at end of file diff --git a/src/lib/server/Metadatas.ts b/src/lib/server/Metadatas.ts new file mode 100644 index 0000000..3280d5b --- /dev/null +++ b/src/lib/server/Metadatas.ts @@ -0,0 +1,68 @@ +export default Metadatas; + +import fs from 'node:fs'; +import path from 'node:path'; +import Posts from './PostList'; +import Load from './LoadPost'; + +import { dev } from '$app/environment'; + +async function Metadatas() { + + const cache_dir = '/tmp/day.moris.blog/'; + const cache_file = `${cache_dir}metadata.json`; + + async function build() { + const posts = await Posts(); + + const metadataList = await Promise.all(posts.map(async (file)=>{ + const postId = path.basename(file, '.md') + const metadata = (await Load(postId)).metadata + return {postId, metadata} + })) + + const sorted = metadataList + .sort((a,b)=>{ + return b.metadata.date.getTime() - a.metadata.date.getTime() + }) + .filter((m)=> dev||m.metadata.published) + + return sorted + } + + async function makeCache() { + let data = await build() + let cache_data = { + cached_time: Date.now(), + dev, + data + } + + if (!fs.existsSync(cache_dir)) { + fs.mkdirSync(cache_dir), {recursive: true} + } + + fs.writeFileSync(cache_file, JSON.stringify(cache_data, null, 2), 'utf8') + return data + } + + + if (fs.existsSync(cache_file)) { + const cache = JSON.parse(fs.readFileSync(cache_file, 'utf8'), (key,value)=>{ + if(key=='date'){ + return (new Date(value)); + } + return value + }) + + if (Boolean(cache.dev)!=dev || Date.now()-cache.cached_time>5*60000) { + const data = await makeCache() + return data + } else { + return cache.data + } + } else { + const data = await makeCache() + return data + } +} \ No newline at end of file diff --git a/src/lib/server/PostList.ts b/src/lib/server/PostList.ts new file mode 100644 index 0000000..c5eb622 --- /dev/null +++ b/src/lib/server/PostList.ts @@ -0,0 +1,15 @@ +export default postList; + +import fs from 'node:fs'; +import Path from 'node:path'; + +import { POST_DIR } from '$env/static/private'; + +async function postList() { + + const files = fs.readdirSync(`${POST_DIR}/Posts`); + + const posts = files.filter((content)=> Path.extname(content)=='.md' && content!='README.md') + + return posts +} \ No newline at end of file diff --git a/src/routes/(DefaultStyle)/+layout.svelte b/src/routes/(DefaultStyle)/+layout.svelte new file mode 100644 index 0000000..f74b54c --- /dev/null +++ b/src/routes/(DefaultStyle)/+layout.svelte @@ -0,0 +1,121 @@ + + + + + + + +
+
+ {#if dev} +
DEV DUILD
+ {/if} + +
+
+
+
+
+ +
+
+ {@render children()} +
+ +
+
+ +
+
+ + \ No newline at end of file diff --git a/src/routes/(DefaultStyle)/+page.svelte b/src/routes/(DefaultStyle)/+page.svelte new file mode 100644 index 0000000..3112aa7 --- /dev/null +++ b/src/routes/(DefaultStyle)/+page.svelte @@ -0,0 +1,11 @@ + + +To show posts, click here \ No newline at end of file diff --git a/src/routes/(DefaultStyle)/[slug]/+page.server.ts b/src/routes/(DefaultStyle)/[slug]/+page.server.ts new file mode 100644 index 0000000..56b705b --- /dev/null +++ b/src/routes/(DefaultStyle)/[slug]/+page.server.ts @@ -0,0 +1,11 @@ +import Metas from '$lib/server/Metadatas'; + +export async function load({params}){ + const pageNo = Number(params.slug) + const postList = await Metas() + + const posts = postList.slice(pageNo*12, (pageNo+1)*12); + const lastPage = Math.ceil(postList.length/12)-1; + + return {posts, pageNo, lastPage} +} \ No newline at end of file diff --git a/src/routes/(DefaultStyle)/[slug]/+page.svelte b/src/routes/(DefaultStyle)/[slug]/+page.svelte new file mode 100644 index 0000000..4ce3cf6 --- /dev/null +++ b/src/routes/(DefaultStyle)/[slug]/+page.svelte @@ -0,0 +1,74 @@ + + + + 記事一覧 | moris.day Blog + + + + +
+
+ {#each data.posts as post} +
+ + + +
+ {/each} + {#if data.posts.length%4} + {#each Array(4-data.posts.length%4) as i} +
+ {/each} + {/if} +
+ +
+ + {data.pageNo}/{data.lastPage} + +
+
+ + + \ No newline at end of file diff --git a/src/routes/(DefaultStyle)/[slug]/grid.svelte b/src/routes/(DefaultStyle)/[slug]/grid.svelte new file mode 100644 index 0000000..c82c992 --- /dev/null +++ b/src/routes/(DefaultStyle)/[slug]/grid.svelte @@ -0,0 +1,117 @@ + + +
+
+ {#if thumbnail } + thumbnail + {:else if emoji} + {#await twemoji(emoji)} +
+ {:then emojisvg} +
+ {@html emojisvg} +
+ {/await} + + {:else} + ')}' alt="fallback"/> + {/if} + +
{date.toLocaleDateString('sv-SE')}
+
{category}
+
+
+
{title}
+
{description}
+
+
+ + \ No newline at end of file diff --git a/src/routes/(DefaultStyle)/about/+page.server.ts b/src/routes/(DefaultStyle)/about/+page.server.ts new file mode 100644 index 0000000..f6eb26e --- /dev/null +++ b/src/routes/(DefaultStyle)/about/+page.server.ts @@ -0,0 +1,10 @@ +import fs from 'node:fs'; +import Perser from '$lib/components/Markdown' + +export async function load(){ + const profile_md = fs.readFileSync(`${process.cwd()}/src/routes/(DefaultStyle)/about/profile.md`, 'utf-8') + + let persed = Perser(profile_md) + + return {md: persed} +} \ No newline at end of file diff --git a/src/routes/(DefaultStyle)/about/+page.svelte b/src/routes/(DefaultStyle)/about/+page.svelte new file mode 100644 index 0000000..2423a85 --- /dev/null +++ b/src/routes/(DefaultStyle)/about/+page.svelte @@ -0,0 +1,26 @@ + + + + + About | moris.day Blog + + +
+
+ {@html data.md} +
+
+ + + \ No newline at end of file diff --git a/src/routes/(DefaultStyle)/about/profile.md b/src/routes/(DefaultStyle)/about/profile.md new file mode 100644 index 0000000..0fd77bc --- /dev/null +++ b/src/routes/(DefaultStyle)/about/profile.md @@ -0,0 +1,9 @@ +## プロフィール +![morisのアイコン](https://moris.day/blog/icon_192.webp) +moris + + +## ライセンス +このブログのコンテンツは全てCC-BY-4.0の下で提供されます。 + +このブログのソースコードは[Gitea](https://git.moris.day/moris/moris-blog)で公開されており、MITライセンスの下で使用、改変、再頒布などを行うことができます。 \ No newline at end of file diff --git a/src/routes/(DefaultStyle)/category/+page.server.ts b/src/routes/(DefaultStyle)/category/+page.server.ts new file mode 100644 index 0000000..4628088 --- /dev/null +++ b/src/routes/(DefaultStyle)/category/+page.server.ts @@ -0,0 +1,17 @@ +import Metadatas from "$lib/server/Metadatas"; + +export async function load() { + let metalist = await Metadatas() + + let cats: string[] = [] + + for (let meta of metalist){ + let cat = meta.metadata.category; + + if (!cats.includes(cat)) { + cats.push(cat) + } + } + + return {cats} +} \ No newline at end of file diff --git a/src/routes/(DefaultStyle)/category/+page.svelte b/src/routes/(DefaultStyle)/category/+page.svelte new file mode 100644 index 0000000..2aba39c --- /dev/null +++ b/src/routes/(DefaultStyle)/category/+page.svelte @@ -0,0 +1,9 @@ + + +{#each data.cats as cat} +
+ {cat} +
+{/each} \ No newline at end of file diff --git a/src/routes/(DefaultStyle)/category/[slug]/+page.server.ts b/src/routes/(DefaultStyle)/category/[slug]/+page.server.ts new file mode 100644 index 0000000..ea36a87 --- /dev/null +++ b/src/routes/(DefaultStyle)/category/[slug]/+page.server.ts @@ -0,0 +1,11 @@ +import Metadatas from "$lib/server/Metadatas"; + +export async function load({params}) { + const cat = params.slug + + const metalist = await Metadatas() + + const result = metalist.filter((meta)=>meta.metadata.category == cat).map((meta)=>meta.postId) + + return {posts: result} +} \ No newline at end of file diff --git a/src/routes/(DefaultStyle)/category/[slug]/+page.svelte b/src/routes/(DefaultStyle)/category/[slug]/+page.svelte new file mode 100644 index 0000000..7afe2e5 --- /dev/null +++ b/src/routes/(DefaultStyle)/category/[slug]/+page.svelte @@ -0,0 +1,8 @@ + + +{#each data.posts as post} +
{post}
+{/each} \ No newline at end of file diff --git a/src/routes/(DefaultStyle)/footer.svelte b/src/routes/(DefaultStyle)/footer.svelte new file mode 100644 index 0000000..a7d67ca --- /dev/null +++ b/src/routes/(DefaultStyle)/footer.svelte @@ -0,0 +1,77 @@ + + +
+
+
+ +
+ +
+
+ Copyright 2024 moris. +
+
+ + \ No newline at end of file diff --git a/src/routes/(DefaultStyle)/header.svelte b/src/routes/(DefaultStyle)/header.svelte new file mode 100644 index 0000000..d7d0728 --- /dev/null +++ b/src/routes/(DefaultStyle)/header.svelte @@ -0,0 +1,27 @@ + + + + + + \ No newline at end of file diff --git a/src/routes/(DefaultStyle)/post/+page.server.ts b/src/routes/(DefaultStyle)/post/+page.server.ts new file mode 100644 index 0000000..990ac9b --- /dev/null +++ b/src/routes/(DefaultStyle)/post/+page.server.ts @@ -0,0 +1,9 @@ +import Metas from '$lib/server/Metadatas'; + +export async function load(){ + const postList = await Metas() + + let id = postList[0].postId + + return {id} +} \ No newline at end of file diff --git a/src/routes/(DefaultStyle)/post/+page.svelte b/src/routes/(DefaultStyle)/post/+page.svelte new file mode 100644 index 0000000..ad839a0 --- /dev/null +++ b/src/routes/(DefaultStyle)/post/+page.svelte @@ -0,0 +1,15 @@ + + + + + \ No newline at end of file diff --git a/src/routes/(DefaultStyle)/post/[slug]/+page.server.ts b/src/routes/(DefaultStyle)/post/[slug]/+page.server.ts new file mode 100644 index 0000000..03f6382 --- /dev/null +++ b/src/routes/(DefaultStyle)/post/[slug]/+page.server.ts @@ -0,0 +1,28 @@ +import Post from '$lib/server/LoadPost'; +import { remark } from 'remark' +import Perser from '$lib/components/Markdown' +import GithubSlugger from 'github-slugger'; + +export async function load({params}) { + + const md = await Post(params.slug); + + let persed = Perser(md.post) + + let mdast = remark().parse(md.post) + let headers = mdast.children.filter((i) => i.type=='heading').map((i)=>{ + let title = i.children[0].value + return {"depth": i.depth, "title": title} + }) + + const slugs = new GithubSlugger() + + let slugged = headers.map((x)=>x.depth ?slugs.slug(x.title):'').filter((x)=>x!='') + + return { + id: params.slug, + metadata: md.metadata, + post: persed, + heading: slugged, + } +} \ No newline at end of file diff --git a/src/routes/(DefaultStyle)/post/[slug]/+page.svelte b/src/routes/(DefaultStyle)/post/[slug]/+page.svelte new file mode 100644 index 0000000..d8d4f89 --- /dev/null +++ b/src/routes/(DefaultStyle)/post/[slug]/+page.svelte @@ -0,0 +1,311 @@ + + + + + {data.metadata.title} | moris.day Blog + + + + + + {#if data.metadata.thumbnail} + + {/if} + + {#if !data.metadata.index} + + {/if} + + + +
+
+

{data.metadata.title}

+ +
+
+ Category: + {data.metadata.category} +
+ + {#if data.metadata.tags.length } +
+ +
+ Tags: + {#each data.metadata.tags as tag} + {tag} + {/each} +
+ {/if} + +
+ + {data.metadata.date.toLocaleDateString('sv-SE')} +
+
+ + {#if data.metadata.thumbnail} + thumbnail + {:else if data.metadata.emoji} +
thumbnail
+ {/if} + +
+ {@html data.post} +
+ +
+ {#if PUBLIC_POST_REPO} + +
+ {/if} + +
+
+ + +
+ + + \ No newline at end of file diff --git a/src/routes/(DefaultStyle)/post/[slug]/profile.svelte b/src/routes/(DefaultStyle)/post/[slug]/profile.svelte new file mode 100644 index 0000000..258c240 --- /dev/null +++ b/src/routes/(DefaultStyle)/post/[slug]/profile.svelte @@ -0,0 +1,49 @@ +
+
+
+
+ moris icon +
+
+
moristest tube
+
+ +
+ 有機化学好きの大学生
電子工作やプログラムもいじります
誤字 文句 その他連絡→Misskey(Fediverse)
+
+
+ + \ No newline at end of file diff --git a/src/routes/(DefaultStyle)/post/[slug]/raw.md/+server.ts b/src/routes/(DefaultStyle)/post/[slug]/raw.md/+server.ts new file mode 100644 index 0000000..47effb2 --- /dev/null +++ b/src/routes/(DefaultStyle)/post/[slug]/raw.md/+server.ts @@ -0,0 +1,9 @@ +export const prerender = true + +import fs from 'node:fs'; +import { POST_DIR } from '$env/static/private'; + +export async function GET({params}) { + const raw = fs.readFileSync(`${POST_DIR}/Posts/${params.slug}.md`,{encoding:'utf-8'}) + return new Response(raw); +}; diff --git a/src/routes/(DefaultStyle)/post/[slug]/share.svelte b/src/routes/(DefaultStyle)/post/[slug]/share.svelte new file mode 100644 index 0000000..95f1622 --- /dev/null +++ b/src/routes/(DefaultStyle)/post/[slug]/share.svelte @@ -0,0 +1,92 @@ + + +
Share
+
+ +
+ + + +
+
+ + + +
+ +
+ + + +
+
+ + diff --git a/src/routes/(DefaultStyle)/post/[slug]/toc.svelte b/src/routes/(DefaultStyle)/post/[slug]/toc.svelte new file mode 100644 index 0000000..afc158c --- /dev/null +++ b/src/routes/(DefaultStyle)/post/[slug]/toc.svelte @@ -0,0 +1,46 @@ + + + + + + + \ No newline at end of file diff --git a/src/routes/(DefaultStyle)/tag/+page.server.ts b/src/routes/(DefaultStyle)/tag/+page.server.ts new file mode 100644 index 0000000..9e34e7a --- /dev/null +++ b/src/routes/(DefaultStyle)/tag/+page.server.ts @@ -0,0 +1,17 @@ +import Metadatas from "$lib/server/Metadatas"; + +export async function load() { + let metalist = await Metadatas() + + let tags: string[] = [] + + for (let meta of metalist){ + for (let tag of meta.metadata.tags) { + if (!tags.includes(tag)) { + tags.push(tag) + } + } + } + + return {tags} +} \ No newline at end of file diff --git a/src/routes/(DefaultStyle)/tag/+page.svelte b/src/routes/(DefaultStyle)/tag/+page.svelte new file mode 100644 index 0000000..147881b --- /dev/null +++ b/src/routes/(DefaultStyle)/tag/+page.svelte @@ -0,0 +1,9 @@ + + +{#each data.tags as tag} +
+ {tag} +
+{/each} \ No newline at end of file diff --git a/src/routes/(DefaultStyle)/tag/[slug]/+page.server.ts b/src/routes/(DefaultStyle)/tag/[slug]/+page.server.ts new file mode 100644 index 0000000..b227a3f --- /dev/null +++ b/src/routes/(DefaultStyle)/tag/[slug]/+page.server.ts @@ -0,0 +1,11 @@ +import Metadatas from "$lib/server/Metadatas"; + +export async function load({params}) { + const tag = params.slug + + const metalist = await Metadatas() + + const result = metalist.filter((meta)=>meta.metadata.tags.includes(tag)).map((meta)=>meta.postId) + + return {posts: result} +} \ No newline at end of file diff --git a/src/routes/(DefaultStyle)/tag/[slug]/+page.svelte b/src/routes/(DefaultStyle)/tag/[slug]/+page.svelte new file mode 100644 index 0000000..7afe2e5 --- /dev/null +++ b/src/routes/(DefaultStyle)/tag/[slug]/+page.svelte @@ -0,0 +1,8 @@ + + +{#each data.posts as post} +
{post}
+{/each} \ No newline at end of file diff --git a/src/routes/+layout.ts b/src/routes/+layout.ts new file mode 100644 index 0000000..5fd74ce --- /dev/null +++ b/src/routes/+layout.ts @@ -0,0 +1,2 @@ +export const prerender = true; +export const trailingSlash = 'always'; \ No newline at end of file diff --git a/src/routes/code/+layout.ts b/src/routes/code/+layout.ts new file mode 100644 index 0000000..3013ed9 --- /dev/null +++ b/src/routes/code/+layout.ts @@ -0,0 +1 @@ +export const csr = false diff --git a/src/routes/code/+page.server.ts b/src/routes/code/+page.server.ts new file mode 100644 index 0000000..decb8b4 --- /dev/null +++ b/src/routes/code/+page.server.ts @@ -0,0 +1,12 @@ +import { POST_DIR } from '$env/static/private'; +import Path from 'node:path'; +import fs from 'node:fs'; + +export async function load({}) { + + const files = fs.readdirSync(`${POST_DIR}/Codes`); + + const codes = files.filter((content)=> Path.extname(content)=='.html') + + return {codes} +} \ No newline at end of file diff --git a/src/routes/code/+page.svelte b/src/routes/code/+page.svelte new file mode 100644 index 0000000..2c0f44e --- /dev/null +++ b/src/routes/code/+page.svelte @@ -0,0 +1,10 @@ + + +
    +{#each data.codes as code} +
  • {code}
  • +{/each} +
\ No newline at end of file diff --git a/src/routes/code/[slug]/+layout.svelte b/src/routes/code/[slug]/+layout.svelte new file mode 100644 index 0000000..289bd2b --- /dev/null +++ b/src/routes/code/[slug]/+layout.svelte @@ -0,0 +1,75 @@ + + + + + + +
+ +
+ {@render children()} +
+
+ + \ No newline at end of file diff --git a/src/routes/code/[slug]/+page.server.ts b/src/routes/code/[slug]/+page.server.ts new file mode 100644 index 0000000..4e60780 --- /dev/null +++ b/src/routes/code/[slug]/+page.server.ts @@ -0,0 +1,10 @@ +import { POST_DIR } from '$env/static/private'; +import fs from 'node:fs'; + +export async function load({params}) { + const code = params.slug.replace(/\.html$/, ""); + + const html = fs.readFileSync(`${POST_DIR}/Codes/${code}.html`, 'utf-8'); + + return {html} +} \ No newline at end of file diff --git a/src/routes/code/[slug]/+page.svelte b/src/routes/code/[slug]/+page.svelte new file mode 100644 index 0000000..6e46d8e --- /dev/null +++ b/src/routes/code/[slug]/+page.svelte @@ -0,0 +1,5 @@ + + +
{@html data.html}
\ No newline at end of file diff --git a/src/routes/code/[slug]/app.css b/src/routes/code/[slug]/app.css new file mode 100644 index 0000000..abee866 --- /dev/null +++ b/src/routes/code/[slug]/app.css @@ -0,0 +1,35 @@ +:root { + height: 100%; + background-color: var(--white-black); + + --back-color: white; /*rgb(240 238 245)*/ + --head-color: rgb(245, 245, 245); /*rgb(244 243 250)*/ + --divider-color: rgb(220 220 220); + --border-color: #bbb; + --shadow-color: #0009; + --white-black: #fff; + --font-color: #222; + + @media(prefers-color-scheme: dark){ + --back-color: rgb(43 48 55); + --head-color: rgb(58 60 66); + --divider-color: #222; + --border-color: #555; + --shadow-color: #000; + --white-black: #000; + --font-color: #f5f5f5; + } +} + +body { + margin: 0; + height: 100%; + background-color: var(--white-black); + color: var(--font-color); +} + +body:fullscreen { + padding: 10%; + background-image: url(https://moris.day/files/img/BigSur.avif); + background-size: cover; +} \ No newline at end of file diff --git a/src/routes/feed.rss/+server.ts b/src/routes/feed.rss/+server.ts new file mode 100644 index 0000000..3f643ec --- /dev/null +++ b/src/routes/feed.rss/+server.ts @@ -0,0 +1,46 @@ +export const prerender = true + +import path from 'node:path'; + +import Metadatas from '$lib/server/Metadatas'; +import { PUBLIC_HOSTNAME } from '$env/static/public'; + +/** @type {import('./$types').RequestHandler} */ +export async function GET() { + + let items = "" + let i = 0 + + const metalist = await Metadatas() + + for (let post of metalist){ + + let meta = post.metadata + let link = `https://${PUBLIC_HOSTNAME}/blog/post/${path.basename(post.postId, '.md')}` + + i++ + items += ` + + ${meta.title} + ${meta.description} + ${link} + ${meta.date.toUTCString()} + ${link} + ` + + if (i==15) {break} + } + + let rss = ` + + + moris.day blog RSSfeed + 工作とか化学とかプログラミングとか + https://moris.day/blog + ${(new Date()).toUTCString()} + ${items} + +` + + return new Response(rss); +}; diff --git a/svelte.config.js b/svelte.config.js new file mode 100644 index 0000000..f563a9d --- /dev/null +++ b/svelte.config.js @@ -0,0 +1,17 @@ +import adapter from '@sveltejs/adapter-static'; +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; + +/** @type {import('@sveltejs/kit').Config} */ +const config = { + preprocess: vitePreprocess(), + + kit: { + adapter: adapter(), + paths: { + base: "/blog", + relative: false + } + } +}; + +export default config; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..0b2d886 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true, + "moduleResolution": "bundler" + } + // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias + // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files + // + // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes + // from the referenced tsconfig.json - TypeScript does not merge them in +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..5b1c868 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,9 @@ +import { sveltekit } from '@sveltejs/kit/vite'; +import { defineConfig } from 'vite'; + +export default defineConfig({ + plugins: [sveltekit()], + server: { + port: 5273 + } +});