Compare commits
4 Commits
6d2d486866
...
c11e552d0a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c11e552d0a | ||
|
|
6308ac279e | ||
|
|
ddb837be56 | ||
|
|
8f0b59775e |
16
Cargo.lock
generated
16
Cargo.lock
generated
@@ -1502,6 +1502,15 @@ version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154"
|
||||
|
||||
[[package]]
|
||||
name = "markdown"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5cab8f2cadc416a82d2e783a1946388b31654d391d1c7d92cc1f03e295b1deb"
|
||||
dependencies = [
|
||||
"unicode-id",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matchers"
|
||||
version = "0.1.0"
|
||||
@@ -3259,6 +3268,12 @@ version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-id"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70ba288e709927c043cbe476718d37be306be53fb1fafecd0dbe36d072be2580"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.18"
|
||||
@@ -3851,6 +3866,7 @@ dependencies = [
|
||||
"config",
|
||||
"fake",
|
||||
"linkify",
|
||||
"markdown",
|
||||
"once_cell",
|
||||
"quickcheck",
|
||||
"quickcheck_macros",
|
||||
|
||||
@@ -20,6 +20,7 @@ axum-server = { version = "0.7.2", features = ["tls-rustls-no-provider"] }
|
||||
base64 = "0.22.1"
|
||||
chrono = { version = "0.4.41", default-features = false, features = ["clock"] }
|
||||
config = "0.15.14"
|
||||
markdown = "1.0.0"
|
||||
rand = { version = "0.9.2", features = ["std_rng"] }
|
||||
reqwest = { version = "0.12.23", default-features = false, features = [
|
||||
"rustls-tls",
|
||||
|
||||
File diff suppressed because one or more lines are too long
50
package-lock.json
generated
50
package-lock.json
generated
@@ -7,6 +7,9 @@
|
||||
"dependencies": {
|
||||
"@tailwindcss/cli": "^4.1.13",
|
||||
"tailwindcss": "^4.1.13"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/typography": "^0.5.18"
|
||||
}
|
||||
},
|
||||
"node_modules/@isaacs/fs-minipass": {
|
||||
@@ -636,6 +639,19 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/typography": {
|
||||
"version": "0.5.18",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.18.tgz",
|
||||
"integrity": "sha512-dDIgwZOlf+tVkZ7A029VvQ1+ngKATENDjMEx2N35s2yPjfTS05RWSM8ilhEWSa5DMJ6ci2Ha9WNZEd2GQjrdQg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"postcss-selector-parser": "6.0.10"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1"
|
||||
}
|
||||
},
|
||||
"node_modules/braces": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||
@@ -657,6 +673,19 @@
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/cssesc": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
|
||||
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"cssesc": "bin/cssesc"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/detect-libc": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
|
||||
@@ -1067,6 +1096,20 @@
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-selector-parser": {
|
||||
"version": "6.0.10",
|
||||
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz",
|
||||
"integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cssesc": "^3.0.0",
|
||||
"util-deprecate": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map-js": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||
@@ -1124,6 +1167,13 @@
|
||||
"node": ">=8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/yallist": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz",
|
||||
|
||||
@@ -5,5 +5,8 @@
|
||||
"dependencies": {
|
||||
"@tailwindcss/cli": "^4.1.13",
|
||||
"tailwindcss": "^4.1.13"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/typography": "^0.5.18"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,4 +14,11 @@ impl PostEntry {
|
||||
pub fn formatted_date(&self) -> String {
|
||||
self.published_at.format("%B %d, %Y").to_string()
|
||||
}
|
||||
|
||||
pub fn to_html(self) -> Self {
|
||||
Self {
|
||||
content: markdown::to_html(&self.content),
|
||||
..self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,8 @@ pub async fn see_post(
|
||||
let post = get_post(&connection_pool, post_id)
|
||||
.await
|
||||
.context(format!("Failed to fetch post #{}", post_id))
|
||||
.map_err(AppError::unexpected_page)?;
|
||||
.map_err(AppError::unexpected_page)?
|
||||
.to_html();
|
||||
let template = PostTemplate { post };
|
||||
Ok(Html(template.render().unwrap()).into_response())
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="mobile-menu"
|
||||
class="hidden md:hidden pb-4 border-t border-gray-100 mt-4">
|
||||
class="hidden md:hidden border-t border-gray-100 pb-4 pt-4">
|
||||
<nav class="flex flex-col space-y-2">
|
||||
<a href="/"
|
||||
class="text-gray-700 hover:text-blue-600 hover:bg-blue-50 px-4 py-2 rounded-lg text-sm font-medium transition-colors duration-200">
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
</div>
|
||||
<div>
|
||||
<label for="post-content"
|
||||
class="block text-sm font-medium text-gray-700 mb-2">HTML content</label>
|
||||
class="block text-sm font-medium text-gray-700 mb-2">Markdown content</label>
|
||||
<textarea id="post-content"
|
||||
name="content"
|
||||
rows="6"
|
||||
|
||||
@@ -1,13 +1,91 @@
|
||||
@import "tailwindcss";
|
||||
@plugin "@tailwindcss/typography";
|
||||
@import "tailwindcss";
|
||||
@plugin "@tailwindcss/typography";
|
||||
|
||||
@layer utilities {
|
||||
.font-inter {
|
||||
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
}
|
||||
@import "tailwindcss";
|
||||
@plugin "@tailwindcss/typography";
|
||||
|
||||
@layer components {
|
||||
.prose-compact {
|
||||
@apply prose prose-slate max-w-none;
|
||||
|
||||
--tw-prose-body: theme(colors.gray.700);
|
||||
--tw-prose-headings: theme(colors.gray.900);
|
||||
--tw-prose-links: theme(colors.blue.600);
|
||||
--tw-prose-code: theme(colors.gray.800);
|
||||
}
|
||||
|
||||
@layer base {
|
||||
body {
|
||||
font-feature-settings: 'cv02', 'cv03', 'cv04', 'cv11';
|
||||
.prose-compact p {
|
||||
@apply mb-2 mt-0;
|
||||
}
|
||||
|
||||
.prose-compact h1 {
|
||||
@apply pb-2 mb-3 border-b-2 border-gray-100;
|
||||
}
|
||||
|
||||
.prose-compact h2 {
|
||||
@apply mt-4 pb-2 mb-3 border-b-2 border-gray-100 font-semibold;
|
||||
}
|
||||
|
||||
.prose-compact h3 {
|
||||
@apply mt-3 mb-1;
|
||||
}
|
||||
|
||||
.prose-compact h4,
|
||||
.prose-compact h5,
|
||||
.prose-compact h6 {
|
||||
@apply mt-2 mb-1;
|
||||
}
|
||||
|
||||
.prose-compact ul,
|
||||
.prose-compact ol {
|
||||
@apply my-2 space-y-0;
|
||||
}
|
||||
|
||||
.prose-compact li {
|
||||
@apply my-0;
|
||||
}
|
||||
|
||||
.prose-compact blockquote {
|
||||
@apply my-3 py-2;
|
||||
}
|
||||
|
||||
.prose-compact img {
|
||||
@apply m-0 align-top;
|
||||
}
|
||||
|
||||
.prose-compact a:has(img) {
|
||||
@apply no-underline border-0 inline-block align-top;
|
||||
}
|
||||
|
||||
.prose-compact a img {
|
||||
@apply inline-block align-top;
|
||||
}
|
||||
|
||||
.prose-compact :not(pre) > code {
|
||||
@apply bg-gray-100 text-gray-800 px-1.5 py-0.5 rounded text-sm font-mono font-normal;
|
||||
}
|
||||
|
||||
.prose-compact :not(pre) > code::before,
|
||||
.prose-compact :not(pre) > code::after {
|
||||
content: none !important;
|
||||
}
|
||||
|
||||
.prose-compact pre {
|
||||
@apply my-3 p-4 bg-gray-100 text-gray-800 rounded-sm overflow-x-auto border border-gray-200;
|
||||
overflow-x: auto;
|
||||
max-width: 100%;
|
||||
width: 0;
|
||||
min-width: 100%;
|
||||
}
|
||||
|
||||
.prose-compact pre code {
|
||||
@apply bg-transparent text-gray-800 p-0 rounded-none;
|
||||
}
|
||||
|
||||
.prose-compact pre code::before,
|
||||
.prose-compact pre code::after {
|
||||
content: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,9 +32,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="px-8 py-8">
|
||||
<div class="prose prose-lg prose-blue max-w-none">{{ post.content | safe }}</div>
|
||||
</div>
|
||||
<div class="px-8 py-8 prose-compact">{{ post.content | safe }}</div>
|
||||
</article>
|
||||
<div class="mt-8 bg-gradient-to-r from-blue-600 to-indigo-700 rounded-lg shadow-lg text-white p-8 text-center">
|
||||
<h3 class="text-2xl font-bold mb-2">Enjoyed this post?</h3>
|
||||
|
||||
Reference in New Issue
Block a user