diff --git a/Cargo.lock b/Cargo.lock index a0dab6b..5c90018 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -476,9 +476,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "aws-lc-rs" -version = "1.15.1" +version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b5ce75405893cd713f9ab8e297d8e438f624dde7d706108285f7e17a25a180f" +checksum = "6a88aab2464f1f25453baa7a07c84c5b7684e274054ba06817f382357f77a288" dependencies = [ "aws-lc-sys", "zeroize", @@ -486,9 +486,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.34.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "179c3777a8b5e70e90ea426114ffc565b2c1a9f82f6c4a0c5a34aa6ef5e781b6" +checksum = "b45afffdee1e7c9126814751f88dddc747f41d91da16c9551a0f1e8a11e788a1" dependencies = [ "cc", "cmake", @@ -900,9 +900,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.19.0" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" dependencies = [ "allocator-api2", ] @@ -1234,9 +1234,9 @@ dependencies = [ [[package]] name = "cmake" -version = "0.1.56" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b042e5d8a74ae91bb0961acd039822472ec99f8ab0948cbf6d1369588f8be586" +checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d" dependencies = [ "cc", ] @@ -2805,7 +2805,7 @@ dependencies = [ [[package]] name = "dioxus-primitives" version = "0.0.1" -source = "git+https://github.com/DioxusLabs/components#7e5862e574aeceb3a3a021d042c165a839f1860b" +source = "git+https://github.com/DioxusLabs/components#3564270718866d2e886f879973afc77d7c3a1689" dependencies = [ "dioxus 0.7.2", "dioxus-sdk-time", @@ -3992,16 +3992,17 @@ dependencies = [ [[package]] name = "generator" -version = "0.8.7" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "605183a538e3e2a9c1038635cc5c2d194e2ee8fd0d1b66b8349fad7dbacce5a2" +checksum = "52f04ae4152da20c76fe800fa48659201d5cf627c5149ca0b707b69d7eef6cf9" dependencies = [ "cc", "cfg-if", "libc", "log", "rustversion", - "windows 0.61.3", + "windows-link 0.2.1", + "windows-result 0.4.1", ] [[package]] @@ -5149,14 +5150,15 @@ dependencies = [ [[package]] name = "insta" -version = "1.44.3" +version = "1.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5c943d4415edd8153251b6f197de5eb1640e56d84e8d9159bea190421c73698" +checksum = "b76866be74d68b1595eb8060cb9191dca9c021db2316558e52ddc5d55d41b66c" dependencies = [ "console", "once_cell", "serde", "similar", + "tempfile", ] [[package]] @@ -6067,13 +6069,13 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "libredox" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" +checksum = "df15f6eac291ed1cf25865b1ee60399f57e7c227e7f51bdbd4c5270396a9ed50" dependencies = [ "bitflags 2.10.0", "libc", - "redox_syscall", + "redox_syscall 0.6.0", ] [[package]] @@ -6480,7 +6482,7 @@ dependencies = [ [[package]] name = "markdown-weaver" version = "0.13.0" -source = "git+https://github.com/rsform/markdown-weaver#52075e20a194375f1bd4a0c78201ce3b3a52c82d" +source = "git+https://github.com/rsform/markdown-weaver?branch=para-end-context#d1d3e3188bc0c52a060eb194a311f66c08e54377" dependencies = [ "bitflags 2.10.0", "getopts", @@ -6493,7 +6495,7 @@ dependencies = [ [[package]] name = "markdown-weaver-escape" version = "0.11.0" -source = "git+https://github.com/rsform/markdown-weaver#52075e20a194375f1bd4a0c78201ce3b3a52c82d" +source = "git+https://github.com/rsform/markdown-weaver?branch=para-end-context#d1d3e3188bc0c52a060eb194a311f66c08e54377" [[package]] name = "markup5ever" @@ -7635,7 +7637,7 @@ checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.18", "smallvec", "windows-link 0.2.1", ] @@ -8172,7 +8174,7 @@ version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" dependencies = [ - "toml_edit 0.23.9", + "toml_edit 0.23.10+spec-1.0.0", ] [[package]] @@ -8585,6 +8587,15 @@ dependencies = [ "bitflags 2.10.0", ] +[[package]] +name = "redox_syscall" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec96166dafa0886eb81fe1c0a388bece180fbef2135f97c1e2cf8302e74b43b5" +dependencies = [ + "bitflags 2.10.0", +] + [[package]] name = "redox_users" version = "0.5.2" @@ -8926,9 +8937,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "708c0f9d5f54ba0272468c1d306a52c495b31fa155e91bc25371e6df7996908c" +checksum = "21e6f2ab2928ca4291b86736a8bd920a277a399bba1589409d72154ff87c1282" dependencies = [ "web-time", "zeroize", @@ -9989,9 +10000,9 @@ dependencies = [ [[package]] name = "supports-hyperlinks" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "804f44ed3c63152de6a9f90acbea1a110441de43006ea51bcce8f436196a288b" +checksum = "e396b6523b11ccb83120b115a0b7366de372751aa6edf19844dfb13a6af97e91" [[package]] name = "supports-unicode" @@ -10734,9 +10745,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.7.3" +version = "0.7.5+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" dependencies = [ "serde_core", ] @@ -10767,21 +10778,21 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.23.9" +version = "0.23.10+spec-1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d7cbc3b4b49633d57a0509303158ca50de80ae32c265093b24c414705807832" +checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" dependencies = [ "indexmap 2.12.1", - "toml_datetime 0.7.3", + "toml_datetime 0.7.5+spec-1.1.0", "toml_parser", "winnow 0.7.14", ] [[package]] name = "toml_parser" -version = "1.0.4" +version = "1.0.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" +checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" dependencies = [ "winnow 0.7.14", ] @@ -10845,9 +10856,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.43" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "log", "pin-project-lite", @@ -10868,9 +10879,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.35" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", "valuable", diff --git a/Cargo.toml b/Cargo.toml index c63aea5..24c1b4f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,8 +28,8 @@ thiserror = "2.0" syntect = { version = "5.2.0", default-features = false } n0-future = "=0.1.3" tracing = { version = "0.1.41", default-features = false, features = ["std"] } -markdown-weaver = { git = "https://github.com/rsform/markdown-weaver" } -markdown-weaver-escape = { git = "https://github.com/rsform/markdown-weaver" } +markdown-weaver = { git = "https://github.com/rsform/markdown-weaver", branch = "para-end-context" } +markdown-weaver-escape = { git = "https://github.com/rsform/markdown-weaver", branch = "para-end-context" } # markdown-weaver = { path = "../markdown-weaver/markdown-weaver" } # markdown-weaver-escape = { path = "../markdown-weaver/markdown-weaver-escape" } diff --git a/crates/weaver-app/assets/styling/entry.css b/crates/weaver-app/assets/styling/entry.css index d818260..65ea6c5 100644 --- a/crates/weaver-app/assets/styling/entry.css +++ b/crates/weaver-app/assets/styling/entry.css @@ -1,104 +1,140 @@ -/* Entry page layout with gutter navigation */ -.entry-page-layout { - display: grid; - grid-template-columns: minmax(200px, 1fr) minmax(0, 95ch) minmax(200px, 1fr); - gap: 2rem; - width: 100%; +/* Entry page layout - centered content with sidenote margin */ +.entry-page { + --content-width: 65ch; + --sidenote-width: 14rem; + --sidenote-gap: 1.5rem; + + display: flex; + flex-direction: column; min-height: 100vh; background: var(--color-base); - max-width: calc(95ch + 400px + 4rem); /* content + gutters + gaps */ +} + +/* Header with inline nav + metadata */ +.entry-header { + display: flex; + align-items: baseline; + justify-content: center; + gap: 1rem; + padding: 1.5rem 1rem; + max-width: calc(var(--content-width) + var(--sidenote-width) + var(--sidenote-gap) + 10rem); margin: 0 auto; - padding: 0 1rem 0 0; + width: 100%; box-sizing: border-box; } -/* Main content area */ -.entry-content-main { - grid-column: 2; - background: var(--color-base); +/* Nav links in header - minimal style */ +.nav-button { + display: flex; + align-items: center; + gap: 0.5rem; + color: var(--color-subtle); + text-decoration: none; + font-size: 0.9rem; + white-space: nowrap; + transition: color 0.2s ease; } -/* Navigation gutters */ -.nav-gutter { - position: sticky; - top: auto; - bottom: 2rem; - height: fit-content; - align-self: end; +.entry-header .nav-button:hover { + color: var(--color-primary); } -.nav-prev { - grid-column: 1; +.entry-header .nav-button-prev { + flex-shrink: 1; + min-width: 0; } -.nav-next { - grid-column: 3; +.entry-header .nav-button-next { + flex-shrink: 1; + min-width: 0; } -/* Navigation buttons */ -.nav-button { +.entry-header .nav-arrow { + font-weight: 600; + color: var(--color-primary); + flex-shrink: 0; +} + +.entry-header .nav-title { + overflow: hidden; + text-overflow: ellipsis; +} + +/* Metadata takes center, flexes to fill */ +.entry-header .entry-metadata { + flex: 1; + max-width: var(--content-width); + margin: 0; + padding: 0; + border: none; +} + +/* Main content area */ +.entry-content-wrapper { + flex: 1; display: flex; - flex-direction: column; - gap: 0.5rem; - padding: 1rem; - background: var(--color-surface); - box-shadow: 0 1px 3px color-mix(in srgb, var(--color-text) 8%, transparent); - text-decoration: none; - color: var(--color-text); - transition: - box-shadow 0.2s ease, - border-color 0.2s ease; + justify-content: center; + padding: 0 1rem; } -.nav-button:hover { - box-shadow: 0 2px 6px color-mix(in srgb, var(--color-text) 12%, transparent); +.entry-content-main { + width: var(--content-width); + max-width: 100%; + position: relative; } -/* Dark mode: borders instead of shadows */ -@media (prefers-color-scheme: dark) { - .nav-button { - box-shadow: none; - border: 1px dashed var(--color-border); - } +/* When sidenotes exist, shift content left to make room */ +.entry-content-main:has(.sidenote) { + margin-right: calc(var(--sidenote-width) + var(--sidenote-gap)); +} - .nav-button:hover { - box-shadow: none; - border-color: var(--color-primary); - } +/* Footer navigation */ +.entry-footer-nav { + display: flex; + justify-content: space-between; + align-items: stretch; + gap: 2rem; + max-width: calc(var(--content-width) + 20rem); + margin: 4rem auto 2rem; + padding: 0 1rem; + width: 100%; + box-sizing: border-box; } -.nav-button-prev { +.entry-footer-nav .nav-button-prev { align-items: flex-start; text-align: left; } -.nav-button-next { +.entry-footer-nav .nav-button-next { align-items: flex-end; text-align: right; + margin-left: auto; } -.nav-arrow { - font-size: 1.5rem; +.entry-footer-nav .nav-arrow { + font-size: 1.25rem; font-weight: bold; color: var(--color-primary); - transition: color 0.2s ease; } -.nav-button:hover .nav-arrow { - color: var(--color-emphasis); +.entry-footer-nav .nav-title { + font-size: 0.95rem; + font-weight: 500; + line-height: 1.4; } -.nav-button:hover .nav-label { - color: var(--color-secondary); +/* Entry metadata in header context */ +.entry-header .entry-metadata .entry-title { + font-size: 1.75rem; + margin: 0 0 0.5rem 0; } -.nav-title { - font-size: 0.95rem; - font-weight: 500; - line-height: 1.4; +.entry-header .entry-metadata .entry-header-row { + flex-wrap: wrap; } -/* Entry metadata header */ +/* Standalone entry metadata (when not in header) */ .entry-metadata { margin-bottom: calc(1rem * var(--spacing-scale, 1.5)); padding-bottom: calc(0.5rem * var(--spacing-scale, 1.5)); @@ -235,60 +271,73 @@ background: var(--color-surface); } -/* Responsive layout - Tablet/small desktop */ -@media (max-width: 1400px) { - .entry-page-layout { - grid-template-columns: 1fr; - gap: 0; - } +/* TODO: footnote ordering needs non-flex solution for aside reflow to work */ - .entry-content-main { - grid-column: 1; - padding: 2rem 1rem; +/* Responsive: tablet */ +@media (max-width: 1200px) { + .entry-header { + flex-wrap: wrap; } - .nav-gutter { - position: relative; - bottom: auto; - grid-column: 1; - padding: 0 1rem; + .entry-header .entry-metadata { + order: -1; + flex-basis: 100%; + max-width: none; } - .nav-prev { - order: 2; - margin-top: 2rem; + .entry-header .nav-button-prev { + order: 0; } - .nav-next { - order: 3; - margin-top: 1rem; + .entry-header .nav-button-next { + order: 1; + margin-left: auto; } +} - .entry-content-main { - order: 1; +/* Responsive: when sidenotes need to squeeze */ +@media (max-width: 1000px) { + .entry-content-main:has(.sidenote) { + margin-right: calc(var(--sidenote-width) + 0.5rem); + margin-left: -3rem; } } -/* Tablet and smaller */ +/* Responsive: narrower - compress left margin more */ @media (max-width: 900px) { - .entry-page-layout { - max-width: 100%; - grid-template-columns: minmax(0, 1fr); + .entry-header .nav-title { + max-width: 8rem; + } + + .entry-content-main:has(.sidenote) { + margin-left: -5rem; } } -/* Small mobile phones */ -@media (max-width: 480px) { - .entry-content-main { - padding: 1rem 0.75rem; +/* Responsive: mobile - sidenotes go inline */ +@media (max-width: 768px) { + .entry-header { + flex-direction: column; + align-items: stretch; + gap: 0.5rem; } - .nav-gutter { - padding: 0 0.75rem; + .entry-content-main:has(.sidenote) { + margin-left: 0; + margin-right: 0; } - .nav-button { - padding: 0.75rem; + .entry-footer-nav { + flex-direction: column; + gap: 1rem; + margin-top: 2rem; + } +} + +/* Small mobile */ +@media (max-width: 480px) { + .entry-content-main { + padding: 0 0.75rem; } .entry-metadata { diff --git a/crates/weaver-app/src/components/editor/actions.rs b/crates/weaver-app/src/components/editor/actions.rs index 82487a3..3758e99 100644 --- a/crates/weaver-app/src/components/editor/actions.rs +++ b/crates/weaver-app/src/components/editor/actions.rs @@ -43,6 +43,7 @@ impl Range { self.end.saturating_sub(self.start) } + #[allow(dead_code)] pub fn is_empty(&self) -> bool { self.len() == 0 } @@ -65,6 +66,7 @@ impl Range { /// These represent semantic operations on the document, decoupled from /// how they're triggered (keyboard, mouse, touch, voice, etc.). #[derive(Debug, Clone, PartialEq)] +#[allow(dead_code)] pub enum EditorAction { // === Text Insertion === /// Insert text at the given range (replacing any selected content). @@ -178,6 +180,7 @@ impl EditorAction { /// SmolStr to efficiently handle both single characters and composed sequences /// (from dead keys, IME, etc.). #[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[allow(dead_code)] pub enum Key { /// A character key. The string corresponds to the character typed, /// taking into account locale, modifiers, and keyboard mapping. @@ -460,6 +463,7 @@ pub struct Modifiers { pub super_: bool, // `super` is a keyword } +#[allow(dead_code)] impl Modifiers { pub const NONE: Self = Self { ctrl: false, diff --git a/crates/weaver-app/src/components/editor/beforeinput.rs b/crates/weaver-app/src/components/editor/beforeinput.rs index a94104e..5649c57 100644 --- a/crates/weaver-app/src/components/editor/beforeinput.rs +++ b/crates/weaver-app/src/components/editor/beforeinput.rs @@ -57,6 +57,7 @@ pub use static_range::StaticRange; /// /// See: https://w3c.github.io/input-events/#interface-InputEvent-Attributes #[derive(Debug, Clone, PartialEq, Eq)] +#[allow(dead_code)] pub enum InputType { // === Insertion === /// Insert typed text. @@ -131,6 +132,7 @@ pub enum InputType { Unknown(String), } +#[allow(dead_code)] impl InputType { /// Parse from the browser's inputType string. pub fn from_str(s: &str) -> Self { @@ -220,6 +222,7 @@ impl InputType { /// Result of handling a beforeinput event. #[derive(Debug, Clone)] +#[allow(dead_code)] pub enum BeforeInputResult { /// Event was handled, prevent default browser behavior. Handled, @@ -235,6 +238,7 @@ pub enum BeforeInputResult { } /// Context for beforeinput handling. +#[allow(dead_code)] pub struct BeforeInputContext<'a> { /// The input type. pub input_type: InputType, @@ -253,6 +257,7 @@ pub struct BeforeInputContext<'a> { /// /// This is the main entry point for beforeinput-based input handling. /// Returns whether the event was handled and default should be prevented. +#[allow(dead_code)] pub fn handle_beforeinput( doc: &mut EditorDocument, ctx: BeforeInputContext<'_>, @@ -557,10 +562,12 @@ pub fn get_target_range_from_event( let end_text = end_container.text_content().unwrap_or_default(); // Check if containers are the editor element itself - let start_is_editor = start_container.dyn_ref::() + let start_is_editor = start_container + .dyn_ref::() .map(|e| e == &editor_element) .unwrap_or(false); - let end_is_editor = end_container.dyn_ref::() + let end_is_editor = end_container + .dyn_ref::() .map(|e| e == &editor_element) .unwrap_or(false); diff --git a/crates/weaver-app/src/components/editor/component.rs b/crates/weaver-app/src/components/editor/component.rs index 1ace9f7..e1bc286 100644 --- a/crates/weaver-app/src/components/editor/component.rs +++ b/crates/weaver-app/src/components/editor/component.rs @@ -1,44 +1,48 @@ //! The main MarkdownEditor component. -use dioxus::prelude::*; -use jacquard::IntoStatic; -use jacquard::cowstr::ToCowStr; -use jacquard::identity::resolver::IdentityResolver; -use jacquard::smol_str::{SmolStr, ToSmolStr}; -use jacquard::types::aturi::AtUri; -use jacquard::types::blob::BlobRef; -use jacquard::types::ident::AtIdentifier; -use weaver_api::sh_weaver::embed::images::Image; -use weaver_common::WeaverExt; - +#[allow(unused_imports)] use super::actions::{ EditorAction, Key, KeyCombo, KeybindingConfig, KeydownResult, Range, execute_action, handle_keydown_with_bindings, }; +#[allow(unused_imports)] use super::beforeinput::{BeforeInputContext, BeforeInputResult, InputType, handle_beforeinput}; #[cfg(all(target_arch = "wasm32", target_os = "unknown"))] use super::beforeinput::{get_data_from_event, get_target_range_from_event}; use super::document::{CompositionState, EditorDocument, LoadedDocState}; -use super::dom_sync::{ - sync_cursor_from_dom, sync_cursor_from_dom_with_direction, update_paragraph_dom, -}; +#[cfg(all(target_arch = "wasm32", target_os = "unknown"))] +use super::dom_sync::update_paragraph_dom; +use super::dom_sync::{sync_cursor_from_dom, sync_cursor_from_dom_with_direction}; use super::formatting; use super::input::{get_char_at, handle_copy, handle_cut, handle_paste}; use super::offset_map::SnapDirection; use super::paragraph::ParagraphRender; use super::platform; +#[allow(unused_imports)] use super::publish::{LoadedEntry, PublishButton, load_entry_for_editing}; use super::render; use super::storage; use super::sync::{SyncStatus, load_and_merge_document}; use super::toolbar::EditorToolbar; use super::visibility::update_syntax_visibility; +#[allow(unused_imports)] use super::writer::{EditorImageResolver, SyntaxSpanInfo}; use crate::auth::AuthState; use crate::components::collab::CollaboratorAvatars; use crate::components::editor::ReportButton; use crate::components::editor::collab::CollabCoordinator; use crate::fetch::Fetcher; +use dioxus::prelude::*; +use jacquard::IntoStatic; +use jacquard::cowstr::ToCowStr; +use jacquard::identity::resolver::IdentityResolver; +use jacquard::smol_str::{SmolStr, ToSmolStr}; +use jacquard::types::aturi::AtUri; +#[cfg(all(target_arch = "wasm32", target_os = "unknown"))] +use jacquard::types::blob::BlobRef; +use jacquard::types::ident::AtIdentifier; +use weaver_api::sh_weaver::embed::images::Image; +use weaver_common::WeaverExt; /// Result of loading document state. enum LoadResult { @@ -47,6 +51,7 @@ enum LoadResult { /// Loading failed Failed(String), /// Still loading + #[allow(dead_code)] Loading, } @@ -412,6 +417,7 @@ fn MarkdownEditorInner( let fetcher = use_context::(); let auth_state = use_context::>(); + #[allow(unused_mut)] let mut document = use_hook(|| { let mut doc = EditorDocument::from_loaded_state(loaded_state.clone()); @@ -459,6 +465,7 @@ fn MarkdownEditorInner( let doc_for_memo = document.clone(); let doc_for_refs = document.clone(); let entry_index_for_memo = entry_index.clone(); + #[allow(unused_mut)] let mut paragraphs = use_memo(move || { let edit = doc_for_memo.last_edit(); let cache = render_cache.peek(); @@ -627,6 +634,7 @@ fn MarkdownEditorInner( let mut new_tag = use_signal(String::new); + #[allow(unused)] let offset_map = use_memo(move || { paragraphs() .iter() @@ -639,6 +647,7 @@ fn MarkdownEditorInner( .flat_map(|p| p.syntax_spans.iter().cloned()) .collect::>() }); + #[allow(unused_mut)] let mut cached_paragraphs = use_signal(|| Vec::::new()); #[cfg(all(target_arch = "wasm32", target_os = "unknown"))] @@ -710,6 +719,7 @@ fn MarkdownEditorInner( }); // Track last saved frontiers to detect changes (peek-only, no subscriptions) + #[allow(unused_mut, unused)] let mut last_saved_frontiers: Signal> = use_signal(|| None); // Store interval handle so it's dropped when component unmounts (prevents panic) @@ -1153,7 +1163,7 @@ fn MarkdownEditorInner( // Refresh callback: fetch and merge collaborator changes (incremental) let on_refresh = if is_published { let fetcher_for_refresh = fetcher.clone(); - let mut doc_for_refresh = document.clone(); + let doc_for_refresh = document.clone(); let entry_uri = document.entry_ref().map(|r| r.uri.clone().into_static()); Some(EventHandler::new(move |_| { @@ -1398,6 +1408,8 @@ fn MarkdownEditorInner( move |evt| { tracing::debug!("onclick fired - syncing cursor from DOM"); let paras = cached_paragraphs(); + #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] + let _ = evt; // Check if click target is a math-clickable element #[cfg(all(target_arch = "wasm32", target_os = "unknown"))] diff --git a/crates/weaver-app/src/components/editor/cursor.rs b/crates/weaver-app/src/components/editor/cursor.rs index 2ed0a41..3ea6207 100644 --- a/crates/weaver-app/src/components/editor/cursor.rs +++ b/crates/weaver-app/src/components/editor/cursor.rs @@ -7,7 +7,9 @@ //! 3. Walking text nodes to find the UTF-16 offset within the element //! 4. Setting cursor with web_sys Selection API -use super::offset_map::{OffsetMapping, SnapDirection, find_mapping_for_char, find_nearest_valid_position}; +use super::offset_map::OffsetMapping; +#[cfg(all(target_family = "wasm", target_os = "unknown"))] +use super::offset_map::{SnapDirection, find_mapping_for_char, find_nearest_valid_position}; #[cfg(all(target_family = "wasm", target_os = "unknown"))] use wasm_bindgen::JsCast; @@ -46,7 +48,9 @@ pub fn restore_cursor_position( Some((m, false)) => (m, char_offset), // Valid position, use as-is Some((m, true)) => { // Position is on invisible content, snap to nearest valid - if let Some(snapped) = find_nearest_valid_position(offset_map, char_offset, snap_direction) { + if let Some(snapped) = + find_nearest_valid_position(offset_map, char_offset, snap_direction) + { tracing::trace!( target: "weaver::cursor", original_offset = char_offset, @@ -190,17 +194,6 @@ fn find_text_node_at_offset( Err("no text node found in container".into()) } -/// Non-WASM stub for testing -#[cfg(not(all(target_family = "wasm", target_os = "unknown")))] -pub fn restore_cursor_position( - _char_offset: usize, - _offset_map: &[OffsetMapping], - _editor_id: &str, - _snap_direction: Option, -) -> Result<(), String> { - Ok(()) -} - /// Screen coordinates for a cursor position. #[derive(Debug, Clone, Copy)] pub struct CursorRect { @@ -232,12 +225,10 @@ pub fn get_cursor_rect( let document = window.document()?; // Get container element - let container = document - .get_element_by_id(&mapping.node_id) - .or_else(|| { - let selector = format!("[data-node-id='{}']", mapping.node_id); - document.query_selector(&selector).ok().flatten() - })?; + let container = document.get_element_by_id(&mapping.node_id).or_else(|| { + let selector = format!("[data-node-id='{}']", mapping.node_id); + document.query_selector(&selector).ok().flatten() + })?; let range = document.create_range().ok()?; @@ -290,15 +281,6 @@ pub fn get_cursor_rect_relative( }) } -#[cfg(not(all(target_family = "wasm", target_os = "unknown")))] -pub fn get_cursor_rect( - _char_offset: usize, - _offset_map: &[OffsetMapping], - _editor_id: &str, -) -> Option { - None -} - #[cfg(not(all(target_family = "wasm", target_os = "unknown")))] pub fn get_cursor_rect_relative( _char_offset: usize, @@ -378,10 +360,13 @@ pub fn get_selection_rects_relative( // Set start if let Some(child_index) = start_mapping.child_index { let _ = range.set_start(&start_container, child_index as u32); - } else if let Ok(container_element) = start_container.clone().dyn_into::() { + } else if let Ok(container_element) = start_container.clone().dyn_into::() + { let offset_in_range = start - start_mapping.char_range.start; let target_utf16_offset = start_mapping.char_offset_in_node + offset_in_range; - if let Ok((text_node, node_offset)) = find_text_node_at_offset(&container_element, target_utf16_offset) { + if let Ok((text_node, node_offset)) = + find_text_node_at_offset(&container_element, target_utf16_offset) + { let _ = range.set_start(&text_node, node_offset as u32); } } @@ -392,7 +377,9 @@ pub fn get_selection_rects_relative( } else if let Ok(container_element) = end_container.dyn_into::() { let offset_in_range = end - end_mapping.char_range.start; let target_utf16_offset = end_mapping.char_offset_in_node + offset_in_range; - if let Ok((text_node, node_offset)) = find_text_node_at_offset(&container_element, target_utf16_offset) { + if let Ok((text_node, node_offset)) = + find_text_node_at_offset(&container_element, target_utf16_offset) + { let _ = range.set_end(&text_node, node_offset as u32); } } diff --git a/crates/weaver-app/src/components/editor/dom_sync.rs b/crates/weaver-app/src/components/editor/dom_sync.rs index 8110047..4f635ab 100644 --- a/crates/weaver-app/src/components/editor/dom_sync.rs +++ b/crates/weaver-app/src/components/editor/dom_sync.rs @@ -3,12 +3,15 @@ //! Handles syncing cursor/selection state between the browser DOM and our //! internal document model, and updating paragraph DOM elements. -use dioxus::prelude::*; - +#[cfg(all(target_arch = "wasm32", target_os = "unknown"))] use super::cursor::restore_cursor_position; +#[allow(unused_imports)] use super::document::{EditorDocument, Selection}; +#[allow(unused_imports)] use super::offset_map::{SnapDirection, find_nearest_valid_position, is_valid_cursor_position}; use super::paragraph::ParagraphRender; +#[allow(unused_imports)] +use dioxus::prelude::*; /// Sync internal cursor and selection state from browser DOM selection. /// @@ -93,7 +96,11 @@ pub fn sync_cursor_from_dom_with_direction( (Some(anchor), Some(focus)) => { let old_offset = doc.cursor.read().offset; // Warn if cursor is jumping a large distance - likely a bug - let jump = if focus > old_offset { focus - old_offset } else { old_offset - focus }; + let jump = if focus > old_offset { + focus - old_offset + } else { + old_offset - focus + }; if jump > 100 { tracing::warn!( old_offset, @@ -179,7 +186,9 @@ pub fn dom_position_to_text_offset( } } // Couldn't find containing paragraph, fall through - tracing::warn!("dom_position_to_text_offset: walked up to editor but couldn't find containing paragraph"); + tracing::warn!( + "dom_position_to_text_offset: walked up to editor but couldn't find containing paragraph" + ); break None; } @@ -432,10 +441,8 @@ pub fn update_paragraph_dom( let mut cursor_para_updated = false; // Build lookup for old paragraphs by ID (for syntax span comparison) - let old_para_map: HashMap<&str, &ParagraphRender> = old_paragraphs - .iter() - .map(|p| (p.id.as_str(), p)) - .collect(); + let old_para_map: HashMap<&str, &ParagraphRender> = + old_paragraphs.iter().map(|p| (p.id.as_str(), p)).collect(); // Build pool of existing DOM elements by ID let mut old_elements: HashMap = HashMap::new(); @@ -452,8 +459,7 @@ pub fn update_paragraph_dom( // Track position for insertBefore - starts at first element child // (use first_element_child to skip any stray text nodes) - let mut cursor_node: Option = - editor.first_element_child().map(|e| e.into()); + let mut cursor_node: Option = editor.first_element_child().map(|e| e.into()); // Single pass through new paragraphs for new_para in new_paragraphs.iter() { @@ -499,40 +505,41 @@ pub fn update_paragraph_dom( // // HOWEVER: we must verify browser actually updated the DOM. // PassThrough assumes browser handles edit, but sometimes it doesn't. - let should_skip_cursor_update = !FORCE_INNERHTML_UPDATE && is_cursor_para && !force && { - let old_para = old_para_map.get(para_id.as_str()); - let syntax_unchanged = old_para - .map(|old| old.syntax_spans == new_para.syntax_spans) - .unwrap_or(false); - - // Verify DOM content length matches expected - if not, browser didn't handle it - // NOTE: Get inner element (the

) not outer div, to avoid counting - // the newline from

\n in the HTML - let dom_matches_expected = if syntax_unchanged { - let inner_elem = existing_elem.first_element_child(); - let dom_text = inner_elem - .as_ref() - .and_then(|e| e.text_content()) - .unwrap_or_default(); - let expected_len = new_para.byte_range.end - new_para.byte_range.start; - let dom_len = dom_text.len(); - let matches = dom_len == expected_len; - // Always log for debugging - tracing::debug!( - para_id = %para_id, - dom_len, - expected_len, - matches, - dom_text = %dom_text, - "DOM sync check" - ); - matches - } else { - false - }; + let should_skip_cursor_update = + !FORCE_INNERHTML_UPDATE && is_cursor_para && !force && { + let old_para = old_para_map.get(para_id.as_str()); + let syntax_unchanged = old_para + .map(|old| old.syntax_spans == new_para.syntax_spans) + .unwrap_or(false); + + // Verify DOM content length matches expected - if not, browser didn't handle it + // NOTE: Get inner element (the

) not outer div, to avoid counting + // the newline from

\n in the HTML + let dom_matches_expected = if syntax_unchanged { + let inner_elem = existing_elem.first_element_child(); + let dom_text = inner_elem + .as_ref() + .and_then(|e| e.text_content()) + .unwrap_or_default(); + let expected_len = new_para.byte_range.end - new_para.byte_range.start; + let dom_len = dom_text.len(); + let matches = dom_len == expected_len; + // Always log for debugging + tracing::debug!( + para_id = %para_id, + dom_len, + expected_len, + matches, + dom_text = %dom_text, + "DOM sync check" + ); + matches + } else { + false + }; - syntax_unchanged && dom_matches_expected - }; + syntax_unchanged && dom_matches_expected + }; if should_skip_cursor_update { tracing::trace!( @@ -607,14 +614,3 @@ pub fn update_paragraph_dom( cursor_para_updated } - -#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] -pub fn update_paragraph_dom( - _editor_id: &str, - _old_paragraphs: &[ParagraphRender], - _new_paragraphs: &[ParagraphRender], - _cursor_offset: usize, - _force: bool, -) -> bool { - false -} diff --git a/crates/weaver-app/src/components/editor/formatting.rs b/crates/weaver-app/src/components/editor/formatting.rs index 985d67d..cb6d976 100644 --- a/crates/weaver-app/src/components/editor/formatting.rs +++ b/crates/weaver-app/src/components/editor/formatting.rs @@ -1,6 +1,7 @@ //! Formatting actions and utilities for applying markdown formatting. use super::document::EditorDocument; +#[allow(unused_imports)] use super::input::{ListContext, detect_list_context, find_line_end}; use dioxus::prelude::*; diff --git a/crates/weaver-app/src/components/editor/input.rs b/crates/weaver-app/src/components/editor/input.rs index 476a048..e9dc866 100644 --- a/crates/weaver-app/src/components/editor/input.rs +++ b/crates/weaver-app/src/components/editor/input.rs @@ -10,6 +10,7 @@ use super::offset_map::SnapDirection; /// Check if we need to intercept this key event. /// Returns true for content-modifying operations, false for navigation. +#[allow(unused)] pub fn should_intercept_key(evt: &Event) -> bool { use dioxus::prelude::keyboard_types::Key; @@ -42,6 +43,7 @@ pub fn should_intercept_key(evt: &Event) -> bool { } /// Handle keyboard events and update document state. +#[allow(unused)] pub fn handle_keydown(evt: Event, doc: &mut EditorDocument) { use dioxus::prelude::keyboard_types::Key; @@ -329,6 +331,8 @@ pub fn handle_keydown(evt: Event, doc: &mut EditorDocument) { /// Handle paste events and insert text at cursor. pub fn handle_paste(evt: Event, doc: &mut EditorDocument) { evt.prevent_default(); + #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] + let _ = doc; #[cfg(all(target_arch = "wasm32", target_os = "unknown"))] { @@ -369,6 +373,8 @@ pub fn handle_paste(evt: Event, doc: &mut EditorDocument) { /// Handle cut events - extract text, write to clipboard, then delete. pub fn handle_cut(evt: Event, doc: &mut EditorDocument) { evt.prevent_default(); + #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] + let _ = doc; #[cfg(all(target_arch = "wasm32", target_os = "unknown"))] { diff --git a/crates/weaver-app/src/components/editor/log_buffer.rs b/crates/weaver-app/src/components/editor/log_buffer.rs index 5927f81..1078710 100644 --- a/crates/weaver-app/src/components/editor/log_buffer.rs +++ b/crates/weaver-app/src/components/editor/log_buffer.rs @@ -98,6 +98,7 @@ fn level_str(level: &Level) -> &'static str { } /// Get all captured log entries as a single string. +#[allow(dead_code)] pub fn get_logs() -> String { LOG_BUFFER.with(|buf| { let buf = buf.borrow(); diff --git a/crates/weaver-app/src/components/editor/offset_map.rs b/crates/weaver-app/src/components/editor/offset_map.rs index 9df5498..41636c8 100644 --- a/crates/weaver-app/src/components/editor/offset_map.rs +++ b/crates/weaver-app/src/components/editor/offset_map.rs @@ -114,6 +114,7 @@ pub fn find_mapping_for_byte( /// /// Returns the mapping and whether the cursor should snap to the next /// visible position (for invisible content). +#[allow(dead_code)] pub fn find_mapping_for_char( offset_map: &[OffsetMapping], char_offset: usize, @@ -162,12 +163,14 @@ pub enum SnapDirection { /// Result of finding a valid cursor position. #[derive(Debug, Clone)] +#[allow(dead_code)] pub struct SnappedPosition<'a> { pub mapping: &'a OffsetMapping, pub offset_in_mapping: usize, pub snapped: Option, } +#[allow(dead_code)] impl SnappedPosition<'_> { /// Get the absolute char offset for this position. pub fn char_offset(&self) -> usize { @@ -181,6 +184,7 @@ impl SnappedPosition<'_> { /// If the position is already valid, returns it directly. Otherwise, /// searches in the preferred direction first, falling back to the other /// direction if needed. +#[allow(dead_code)] pub fn find_nearest_valid_position( offset_map: &[OffsetMapping], char_offset: usize, @@ -219,6 +223,7 @@ pub fn find_nearest_valid_position( } /// Search for a valid position in a specific direction. +#[allow(dead_code)] fn find_valid_in_direction( offset_map: &[OffsetMapping], char_offset: usize, @@ -275,6 +280,7 @@ fn find_valid_in_direction( } /// Check if a char offset is at a valid (non-invisible) cursor position. +#[allow(dead_code)] pub fn is_valid_cursor_position(offset_map: &[OffsetMapping], char_offset: usize) -> bool { find_mapping_for_char(offset_map, char_offset) .map(|(m, should_snap)| !should_snap && m.utf16_len > 0) @@ -473,7 +479,8 @@ mod tests { let mappings = make_test_mappings(); // Position 10 is invisible (in 5..15), prefer backward to end of "alt" (position 5) - let pos = find_nearest_valid_position(&mappings, 10, Some(SnapDirection::Backward)).unwrap(); + let pos = + find_nearest_valid_position(&mappings, 10, Some(SnapDirection::Backward)).unwrap(); assert_eq!(pos.char_offset(), 5); // end of "alt" mapping assert_eq!(pos.snapped, Some(SnapDirection::Backward)); } diff --git a/crates/weaver-app/src/components/editor/platform.rs b/crates/weaver-app/src/components/editor/platform.rs index ee697c9..03d4094 100644 --- a/crates/weaver-app/src/components/editor/platform.rs +++ b/crates/weaver-app/src/components/editor/platform.rs @@ -6,6 +6,7 @@ use std::sync::OnceLock; /// Cached platform detection results. #[derive(Debug, Clone)] +#[allow(dead_code)] pub struct Platform { pub ios: bool, pub mac: bool, diff --git a/crates/weaver-app/src/components/editor/publish.rs b/crates/weaver-app/src/components/editor/publish.rs index 9d6d5f7..ca25019 100644 --- a/crates/weaver-app/src/components/editor/publish.rs +++ b/crates/weaver-app/src/components/editor/publish.rs @@ -8,6 +8,7 @@ use jacquard::smol_str::ToSmolStr; use jacquard::types::collection::Collection; use jacquard::types::ident::AtIdentifier; use jacquard::types::recordkey::RecordKey; +#[allow(unused_imports)] use jacquard::types::string::{AtUri, Datetime, Nsid, Rkey}; use jacquard::types::tid::Ticker; use jacquard::{IntoStatic, from_data, prelude::*, to_data}; diff --git a/crates/weaver-app/src/components/editor/render.rs b/crates/weaver-app/src/components/editor/render.rs index e6280e2..85f86b5 100644 --- a/crates/weaver-app/src/components/editor/render.rs +++ b/crates/weaver-app/src/components/editor/render.rs @@ -5,12 +5,13 @@ //! Uses EditorWriter which tracks gaps in offset_iter to preserve formatting characters. use super::document::EditInfo; +#[allow(unused_imports)] use super::offset_map::{OffsetMapping, RenderResult}; use super::paragraph::{ParagraphRender, hash_source, make_paragraph_id, text_slice_to_string}; +#[allow(unused_imports)] use super::writer::{EditorImageResolver, EditorWriter, ImageResolver, SyntaxSpanInfo}; use loro::LoroText; use markdown_weaver::Parser; -use std::collections::HashMap; use std::ops::Range; use weaver_common::{EntryIndex, ResolvedContent}; @@ -94,7 +95,6 @@ fn add_gap_paragraphs( if gap_size > MIN_PARAGRAPH_BREAK_INCR { let gap_start_char = prev_end_char + MIN_PARAGRAPH_BREAK_INCR; let gap_end_char = para.char_range.start; - let gap_start_byte = prev_end_byte + MIN_PARAGRAPH_BREAK_INCR; let gap_end_byte = para.byte_range.start; let gap_node_id = format!("gap-{}-{}", gap_start_char, gap_end_char); @@ -724,7 +724,7 @@ pub fn render_paragraphs_incremental( let mut new_cached = Vec::with_capacity(paragraph_ranges.len()); let mut all_refs: Vec = Vec::new(); // next_para_id must account for all IDs allocated by the writer - let mut next_para_id = parsed_para_id_start + parsed_para_count; + let next_para_id = parsed_para_id_start + parsed_para_count; let reused_count = reused_paragraphs.len(); // Find which paragraph contains cursor (for stable ID assignment) @@ -741,11 +741,6 @@ pub fn render_paragraphs_incremental( "ID assignment: cursor and edit info" ); - // Build hash->cached_para lookup for non-cursor matching - let cached_by_hash: HashMap = cache - .map(|c| c.paragraphs.iter().map(|p| (p.source_hash, p)).collect()) - .unwrap_or_default(); - for (idx, (byte_range, char_range)) in paragraph_ranges.iter().enumerate() { let para_source = text_slice_to_string(text, char_range.clone()); let source_hash = hash_source(¶_source); diff --git a/crates/weaver-app/src/components/editor/report.rs b/crates/weaver-app/src/components/editor/report.rs index 8db3440..2d74f3c 100644 --- a/crates/weaver-app/src/components/editor/report.rs +++ b/crates/weaver-app/src/components/editor/report.rs @@ -5,7 +5,9 @@ use dioxus::prelude::*; +#[allow(unused_imports)] use super::log_buffer; +#[allow(unused_imports)] use super::storage::load_from_storage; /// Captured report data. @@ -112,6 +114,7 @@ pub fn ReportButton(props: ReportButtonProps) -> Element { let email = props.email.clone(); let submit_report = move |_| { let data = report_data(); + #[allow(unused_variables)] let mailto_url = data.to_mailto(&email, &comment()); #[cfg(all(target_arch = "wasm32", target_os = "unknown"))] diff --git a/crates/weaver-app/src/components/editor/storage.rs b/crates/weaver-app/src/components/editor/storage.rs index bb3ed6c..bf5080e 100644 --- a/crates/weaver-app/src/components/editor/storage.rs +++ b/crates/weaver-app/src/components/editor/storage.rs @@ -19,8 +19,11 @@ use base64::{Engine, engine::general_purpose::STANDARD as BASE64}; use dioxus::prelude::*; #[cfg(all(target_family = "wasm", target_os = "unknown"))] use gloo_storage::{LocalStorage, Storage}; +#[allow(unused_imports)] use jacquard::IntoStatic; +#[allow(unused_imports)] use jacquard::smol_str::{SmolStr, ToSmolStr}; +#[allow(unused_imports)] use jacquard::types::string::{AtUri, Cid}; use loro::cursor::Cursor; use serde::{Deserialize, Serialize}; @@ -78,6 +81,7 @@ pub struct EditorSnapshot { } /// Build the full storage key from a draft key. +#[allow(dead_code)] fn storage_key(key: &str) -> String { format!("{}{}", DRAFT_KEY_PREFIX, key) } diff --git a/crates/weaver-app/src/components/editor/sync.rs b/crates/weaver-app/src/components/editor/sync.rs index 09c5bbb..03bebad 100644 --- a/crates/weaver-app/src/components/editor/sync.rs +++ b/crates/weaver-app/src/components/editor/sync.rs @@ -25,6 +25,7 @@ use jacquard::cowstr::ToCowStr; use jacquard::prelude::*; use jacquard::smol_str::format_smolstr; use jacquard::types::blob::MimeType; +#[allow(unused_imports)] use jacquard::types::collection::Collection; use jacquard::types::ident::AtIdentifier; use jacquard::types::recordkey::RecordKey; @@ -43,6 +44,7 @@ use weaver_api::sh_weaver::edit::draft::Draft; use weaver_api::sh_weaver::edit::root::Root; use weaver_api::sh_weaver::edit::{DocRef, DocRefValue, DraftRef, EntryRef}; use weaver_common::constellation::{GetBacklinksQuery, RecordId}; +#[allow(unused_imports)] use weaver_common::{WeaverError, WeaverExt}; const ROOT_NSID: &str = "sh.weaver.edit.root"; diff --git a/crates/weaver-app/src/components/editor/visibility.rs b/crates/weaver-app/src/components/editor/visibility.rs index dae324f..1b13f40 100644 --- a/crates/weaver-app/src/components/editor/visibility.rs +++ b/crates/weaver-app/src/components/editor/visibility.rs @@ -124,6 +124,7 @@ fn selection_overlaps(selection: Option<&Selection>, range: &Range) -> bo } /// Check if cursor is in the same paragraph as a syntax span. +#[allow(dead_code)] fn cursor_in_same_paragraph( cursor_offset: usize, syntax_range: &Range, diff --git a/crates/weaver-app/src/components/editor/writer.rs b/crates/weaver-app/src/components/editor/writer.rs index d4caece..e35382a 100644 --- a/crates/weaver-app/src/components/editor/writer.rs +++ b/crates/weaver-app/src/components/editor/writer.rs @@ -5,12 +5,13 @@ //! //! Uses Parser::into_offset_iter() to track gaps between events, which //! represent consumed formatting characters. - +#[allow(unused_imports)] use super::offset_map::{OffsetMapping, RenderResult}; use jacquard::types::{ident::AtIdentifier, string::Rkey}; use loro::LoroText; use markdown_weaver::{ Alignment, BlockQuoteKind, CodeBlockKind, CowStr, EmbedType, Event, LinkType, Tag, + WeaverAttributes, }; use markdown_weaver_escape::{ StrWrite, escape_href, escape_html, escape_html_body_text, @@ -30,6 +31,7 @@ pub struct SegmentedWriter { segments: Vec, } +#[allow(dead_code)] impl SegmentedWriter { pub fn new() -> Self { Self { @@ -375,6 +377,13 @@ impl ImageResolver for &EditorImageResolver { } } +/// Tracks the type of wrapper element emitted for WeaverBlock prefix +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum WrapperElement { + Aside, + Div, +} + /// HTML writer that preserves markdown formatting characters. /// /// This writer processes offset-iter events to detect gaps (consumed formatting) @@ -416,10 +425,10 @@ pub struct EditorWriter<'a, I: Iterator, Range)>, E = ( // Offset mapping tracking - current paragraph offset_maps: Vec, - node_id_prefix: Option, // paragraph ID prefix for stable node IDs - auto_increment_prefix: Option, // if set, auto-increment prefix per paragraph from this value + node_id_prefix: Option, // paragraph ID prefix for stable node IDs + auto_increment_prefix: Option, // if set, auto-increment prefix per paragraph from this value static_prefix_override: Option<(usize, String)>, // (index, prefix) - override auto-increment at this index - current_paragraph_index: usize, // which paragraph we're currently building (0-indexed) + current_paragraph_index: usize, // which paragraph we're currently building (0-indexed) next_node_id: usize, current_node_id: Option, // node ID for current text container current_node_char_offset: usize, // UTF-16 offset within current node @@ -450,6 +459,22 @@ pub struct EditorWriter<'a, I: Iterator, Range)>, E = ( syntax_spans_by_para: Vec>, refs_by_para: Vec>, + // WeaverBlock prefix system + /// Pending WeaverBlock attrs to apply to the next block element + pending_block_attrs: Option>, + /// Type of wrapper element currently open (needs closing on block end) + active_wrapper: Option, + /// Buffer for WeaverBlock text content (to parse for attrs) + weaver_block_buffer: String, + /// Start char offset of current WeaverBlock (for syntax span) + weaver_block_char_start: Option, + + // Footnote syntax linking (ref ↔ definition visibility) + /// Maps footnote name → (syntax_span_index, char_start) for linking ref and def + footnote_ref_spans: HashMap, + /// Current footnote definition being processed (name, syntax_span_index, char_start) + current_footnote_def: Option<(String, usize, usize)>, + _phantom: std::marker::PhantomData<&'a ()>, } @@ -519,6 +544,12 @@ impl<'a, I: Iterator, Range)>, E: EmbedContentProvider, offset_maps_by_para: Vec::new(), syntax_spans_by_para: Vec::new(), refs_by_para: Vec::new(), + pending_block_attrs: None, + active_wrapper: None, + weaver_block_buffer: String::new(), + weaver_block_char_start: None, + footnote_ref_spans: HashMap::new(), + current_footnote_def: None, _phantom: std::marker::PhantomData, } } @@ -578,6 +609,12 @@ impl<'a, I: Iterator, Range)>, E: EmbedContentProvider, offset_maps_by_para: self.offset_maps_by_para, syntax_spans_by_para: self.syntax_spans_by_para, refs_by_para: self.refs_by_para, + pending_block_attrs: self.pending_block_attrs, + active_wrapper: self.active_wrapper, + weaver_block_buffer: self.weaver_block_buffer, + weaver_block_char_start: self.weaver_block_char_start, + footnote_ref_spans: self.footnote_ref_spans, + current_footnote_def: self.current_footnote_def, _phantom: std::marker::PhantomData, } } @@ -608,6 +645,7 @@ impl<'a, I: Iterator, Range)>, E: EmbedContentProvider, } /// Get the next paragraph ID that would be assigned (for tracking allocations). + #[allow(dead_code)] pub fn next_paragraph_id(&self) -> Option { self.auto_increment_prefix } @@ -1106,6 +1144,7 @@ impl<'a, I: Iterator, Range)>, E: EmbedContentProvider, } // Consume raw text events until end tag, for alt attributes + #[allow(dead_code)] fn raw_text(&mut self) -> Result<(), fmt::Error> { use Event::*; let mut nest = 0; @@ -1170,6 +1209,104 @@ impl<'a, I: Iterator, Range)>, E: EmbedContentProvider, } } + /// Parse WeaverBlock text content into attributes. + /// Format: comma-separated, colon for key:value, otherwise class. + /// Example: ".aside, width: 300px" -> classes: ["aside"], attrs: [("width", "300px")] + fn parse_weaver_attrs(text: &str) -> WeaverAttributes<'static> { + let mut classes = Vec::new(); + let mut attrs = Vec::new(); + + for part in text.split(',') { + let part = part.trim(); + if part.is_empty() { + continue; + } + + if let Some((key, value)) = part.split_once(':') { + let key = key.trim(); + let value = value.trim(); + if !key.is_empty() && !value.is_empty() { + attrs.push((CowStr::from(key.to_string()), CowStr::from(value.to_string()))); + } + } else { + // No colon - treat as class, strip leading dot if present + let class = part.strip_prefix('.').unwrap_or(part); + if !class.is_empty() { + classes.push(CowStr::from(class.to_string())); + } + } + } + + WeaverAttributes { classes, attrs } + } + + /// Emit wrapper element start based on pending block attrs. + /// Returns true if a wrapper was emitted. + fn emit_wrapper_start(&mut self) -> Result { + if let Some(attrs) = self.pending_block_attrs.take() { + let is_aside = attrs.classes.iter().any(|c| c.as_ref() == "aside"); + + if !self.end_newline { + self.write("\n")?; + } + + if is_aside { + self.write(" element) + let classes: Vec<_> = if is_aside { + attrs + .classes + .iter() + .filter(|c| c.as_ref() != "aside") + .collect() + } else { + attrs.classes.iter().collect() + }; + + if !classes.is_empty() { + self.write(" class=\"")?; + for (i, class) in classes.iter().enumerate() { + if i > 0 { + self.write(" ")?; + } + escape_html(&mut self.writer, class)?; + } + self.write("\"")?; + } + + // Write other attrs + for (attr, value) in &attrs.attrs { + self.write(" ")?; + escape_html(&mut self.writer, attr)?; + self.write("=\"")?; + escape_html(&mut self.writer, value)?; + self.write("\"")?; + } + + self.write(">\n")?; + Ok(true) + } else { + Ok(false) + } + } + + /// Close active wrapper element if one is open + fn close_wrapper(&mut self) -> Result<(), fmt::Error> { + if let Some(wrapper) = self.active_wrapper.take() { + match wrapper { + WrapperElement::Aside => self.write("\n")?, + WrapperElement::Div => self.write("\n")?, + } + } + Ok(()) + } + fn process_event(&mut self, event: Event<'_>, range: Range) -> Result<(), fmt::Error> { use Event::*; @@ -1546,14 +1683,6 @@ impl<'a, I: Iterator, Range)>, E: EmbedContentProvider, escape_html(&mut self.writer, spaces)?; self.write("")?; - // Record syntax span info - // self.syntax_spans.push(SyntaxSpanInfo { - // syn_id, - // char_range: char_start..char_end, - // syntax_type: SyntaxType::Inline, - // formatted_range: None, - // }); - // Count this span as a child self.current_node_child_count += 1; @@ -1570,7 +1699,6 @@ impl<'a, I: Iterator, Range)>, E: EmbedContentProvider, // After
, emit plain zero-width space for cursor positioning self.write(" ")?; - //self.write("\u{200B}")?; // Count the zero-width space text node as a child self.current_node_child_count += 1; @@ -1636,13 +1764,52 @@ impl<'a, I: Iterator, Range)>, E: EmbedContentProvider, self.write("

\n")?; } FootnoteReference(name) => { + // Get/create footnote number let len = self.numbers.len() + 1; - self.write("")?; let number = *self.numbers.entry(name.to_string()).or_insert(len); - write!(&mut self.writer, "{}", number)?; - self.write("")?; + + // Emit the [^name] syntax as a hideable syntax span + let raw_text = &self.source[range.clone()]; + let char_start = self.last_char_offset; + let syntax_char_len = raw_text.chars().count(); + let char_end = char_start + syntax_char_len; + let syn_id = self.gen_syn_id(); + + write!( + &mut self.writer, + "", + syn_id, char_start, char_end + )?; + escape_html(&mut self.writer, raw_text)?; + self.write("")?; + + // Track this span for linking with the footnote definition later + let span_index = self.syntax_spans.len(); + self.syntax_spans.push(SyntaxSpanInfo { + syn_id, + char_range: char_start..char_end, + syntax_type: SyntaxType::Inline, + formatted_range: None, // Set when we see the definition + }); + self.footnote_ref_spans + .insert(name.to_string(), (span_index, char_start)); + + // Record offset mapping for the syntax span content + self.record_mapping(range.clone(), char_start..char_end); + + // Count as child + self.current_node_child_count += 1; + + // Emit the visible footnote reference (superscript number) + write!( + &mut self.writer, + "{}", + name, number + )?; + + // Update tracking + self.last_char_offset = char_end; + self.last_byte_offset = range.end; } TaskListMarker(checked) => { // Emit the [ ] or [x] syntax @@ -1680,7 +1847,10 @@ impl<'a, I: Iterator, Range)>, E: EmbedContentProvider, self.write("\n")?; } } - WeaverBlock(_) => {} + WeaverBlock(text) => { + // Buffer WeaverBlock content for parsing on End + self.weaver_block_buffer.push_str(&text); + } } Ok(()) } @@ -1830,7 +2000,10 @@ impl<'a, I: Iterator, Range)>, E: EmbedContentProvider, Ok(()) } - Tag::Paragraph => { + Tag::Paragraph(_) => { + // Handle wrapper before block + self.emit_wrapper_start()?; + // Record paragraph start for boundary tracking // BUT skip if inside a list - list owns the paragraph boundary if self.list_depth == 0 { @@ -1892,6 +2065,9 @@ impl<'a, I: Iterator, Range)>, E: EmbedContentProvider, classes, attrs, } => { + // Emit wrapper if pending (but don't close on heading end - wraps following block too) + self.emit_wrapper_start()?; + // Record paragraph start for boundary tracking // Treat headings as paragraph-level blocks self.current_paragraph_start = Some((self.last_byte_offset, self.last_char_offset)); @@ -1980,6 +2156,7 @@ impl<'a, I: Iterator, Range)>, E: EmbedContentProvider, self.in_non_writing_block = true; // Suppress content output Ok(()) } else { + self.emit_wrapper_start()?; self.table_alignments = alignments; self.write("") } @@ -2018,6 +2195,8 @@ impl<'a, I: Iterator, Range)>, E: EmbedContentProvider, } } Tag::BlockQuote(kind) => { + self.emit_wrapper_start()?; + let class_str = match kind { None => "", Some(BlockQuoteKind::Note) => " class=\"markdown-alert-note\"", @@ -2037,6 +2216,8 @@ impl<'a, I: Iterator, Range)>, E: EmbedContentProvider, Ok(()) } Tag::CodeBlock(info) => { + self.emit_wrapper_start()?; + // Track code block as paragraph-level block self.current_paragraph_start = Some((self.last_byte_offset, self.last_char_offset)); @@ -2110,6 +2291,7 @@ impl<'a, I: Iterator, Range)>, E: EmbedContentProvider, } } Tag::List(Some(1)) => { + self.emit_wrapper_start()?; // Track list as paragraph-level block self.current_paragraph_start = Some((self.last_byte_offset, self.last_char_offset)); self.list_depth += 1; @@ -2120,6 +2302,7 @@ impl<'a, I: Iterator, Range)>, E: EmbedContentProvider, } } Tag::List(Some(start)) => { + self.emit_wrapper_start()?; // Track list as paragraph-level block self.current_paragraph_start = Some((self.last_byte_offset, self.last_char_offset)); self.list_depth += 1; @@ -2132,6 +2315,7 @@ impl<'a, I: Iterator, Range)>, E: EmbedContentProvider, self.write("\">\n") } Tag::List(None) => { + self.emit_wrapper_start()?; // Track list as paragraph-level block self.current_paragraph_start = Some((self.last_byte_offset, self.last_char_offset)); self.list_depth += 1; @@ -2239,6 +2423,7 @@ impl<'a, I: Iterator, Range)>, E: EmbedContentProvider, Ok(()) } Tag::DefinitionList => { + self.emit_wrapper_start()?; if self.end_newline { self.write("
\n") } else { @@ -2507,22 +2692,73 @@ impl<'a, I: Iterator, Range)>, E: EmbedContentProvider, id, attrs, } => self.write_embed(range, embed_type, dest_url, title, id, attrs), - Tag::WeaverBlock(_, _) => { + Tag::WeaverBlock(_, attrs) => { self.in_non_writing_block = true; + self.weaver_block_buffer.clear(); + self.weaver_block_char_start = Some(self.last_char_offset); + // Store attrs from Start tag, will merge with parsed text on End + if !attrs.classes.is_empty() || !attrs.attrs.is_empty() { + self.pending_block_attrs = Some(attrs.into_static()); + } Ok(()) } Tag::FootnoteDefinition(name) => { - if self.end_newline { - self.write("
")?; + + write!( + &mut self.writer, + "", + syn_id, char_start, char_end + )?; + escape_html(&mut self.writer, &prefix)?; + self.write("")?; + + // Track this span for linking with the footnote reference + let def_span_index = self.syntax_spans.len(); + self.syntax_spans.push(SyntaxSpanInfo { + syn_id, + char_range: char_start..char_end, + syntax_type: SyntaxType::Block, + formatted_range: None, // Set at FootnoteDefinition end + }); + + // Store the definition info for linking at end + self.current_footnote_def = Some((name.to_string(), def_span_index, char_start)); + + // Record offset mapping for the syntax span + self.record_mapping(range.start..range.start + prefix.len(), char_start..char_end); + + // Update tracking for the prefix + self.last_char_offset = char_end; + self.last_byte_offset = range.start + prefix.len(); + + // Emit the definition container + write!( + &mut self.writer, + "
", + name + )?; + + // Get/create footnote number for the label let len = self.numbers.len() + 1; let number = *self.numbers.entry(name.to_string()).or_insert(len); - write!(&mut self.writer, "{}", number)?; - self.write("") + write!( + &mut self.writer, + "{}", + number + )?; + + Ok(()) } Tag::MetadataBlock(_) => { self.in_non_writing_block = true; @@ -2566,7 +2802,7 @@ impl<'a, I: Iterator, Range)>, E: EmbedContentProvider, } Ok(()) } - TagEnd::Paragraph => { + TagEnd::Paragraph(_) => { // Capture paragraph boundary info BEFORE writing closing HTML // Skip if inside a list - list owns the paragraph boundary let para_boundary = if self.list_depth == 0 { @@ -2585,6 +2821,7 @@ impl<'a, I: Iterator, Range)>, E: EmbedContentProvider, // Write closing HTML to current segment self.end_node(); self.write("

\n")?; + self.close_wrapper()?; // Now finalize paragraph (starts new segment) if let Some((byte_range, char_range)) = para_boundary { @@ -2609,6 +2846,7 @@ impl<'a, I: Iterator, Range)>, E: EmbedContentProvider, self.write("\n")?; + // Note: Don't close wrapper here - headings typically go with following block // Now finalize paragraph (starts new segment) if let Some((byte_range, char_range)) = para_boundary { @@ -2701,6 +2939,7 @@ impl<'a, I: Iterator, Range)>, E: EmbedContentProvider, } } self.write("\n")?; + self.close_wrapper()?; // Now finalize paragraph if we had one if let Some((byte_range, char_range)) = para_boundary { @@ -2857,6 +3096,7 @@ impl<'a, I: Iterator, Range)>, E: EmbedContentProvider, }); self.write("\n")?; + self.close_wrapper()?; // Finalize paragraph after closing HTML if let Some((byte_range, char_range)) = para_boundary { @@ -2878,6 +3118,7 @@ impl<'a, I: Iterator, Range)>, E: EmbedContentProvider, }); self.write("\n")?; + self.close_wrapper()?; // Finalize paragraph after closing HTML if let Some((byte_range, char_range)) = para_boundary { @@ -2889,7 +3130,10 @@ impl<'a, I: Iterator, Range)>, E: EmbedContentProvider, self.end_node(); self.write("\n") } - TagEnd::DefinitionList => self.write("
\n"), + TagEnd::DefinitionList => { + self.write("\n")?; + self.close_wrapper() + } TagEnd::DefinitionListTitle => { self.end_node(); self.write("\n") @@ -2956,9 +3200,84 @@ impl<'a, I: Iterator, Range)>, E: EmbedContentProvider, TagEnd::Embed => Ok(()), TagEnd::WeaverBlock(_) => { self.in_non_writing_block = false; + + // Emit the { content } as a hideable syntax span + if let Some(char_start) = self.weaver_block_char_start.take() { + // Build the full syntax text: { buffered_content } + let syntax_text = format!("{{{}}}", self.weaver_block_buffer); + let syntax_char_len = syntax_text.chars().count(); + let char_end = char_start + syntax_char_len; + + let syn_id = self.gen_syn_id(); + + write!( + &mut self.writer, + "", + syn_id, char_start, char_end + )?; + escape_html(&mut self.writer, &syntax_text)?; + self.write("")?; + + // Track the syntax span + self.syntax_spans.push(SyntaxSpanInfo { + syn_id, + char_range: char_start..char_end, + syntax_type: SyntaxType::Block, + formatted_range: None, + }); + + // Record offset mapping for the syntax span + self.record_mapping(range.clone(), char_start..char_end); + + // Update tracking + self.last_char_offset = char_end; + self.last_byte_offset = range.end; + } + + // Parse the buffered text for attrs and store for next block + if !self.weaver_block_buffer.is_empty() { + let parsed = Self::parse_weaver_attrs(&self.weaver_block_buffer); + self.weaver_block_buffer.clear(); + // Merge with any existing pending attrs or set new + if let Some(ref mut existing) = self.pending_block_attrs { + existing.classes.extend(parsed.classes); + existing.attrs.extend(parsed.attrs); + } else { + self.pending_block_attrs = Some(parsed); + } + } + + Ok(()) + } + TagEnd::FootnoteDefinition => { + self.write("\n")?; + + // Link the footnote definition span with its reference span + if let Some((name, def_span_index, _def_char_start)) = + self.current_footnote_def.take() + { + let def_char_end = self.last_char_offset; + + // Look up the reference span + if let Some(&(ref_span_index, ref_char_start)) = + self.footnote_ref_spans.get(&name) + { + // Create formatted_range spanning from ref start to def end + let formatted_range = ref_char_start..def_char_end; + + // Update both spans with the same formatted_range + // so they show/hide together based on cursor proximity + if let Some(ref_span) = self.syntax_spans.get_mut(ref_span_index) { + ref_span.formatted_range = Some(formatted_range.clone()); + } + if let Some(def_span) = self.syntax_spans.get_mut(def_span_index) { + def_span.formatted_range = Some(formatted_range); + } + } + } + Ok(()) } - TagEnd::FootnoteDefinition => self.write("\n"), TagEnd::MetadataBlock(_) => { self.in_non_writing_block = false; Ok(()) diff --git a/crates/weaver-app/src/components/entry.rs b/crates/weaver-app/src/components/entry.rs index 9b68975..9ef4517 100644 --- a/crates/weaver-app/src/components/entry.rs +++ b/crates/weaver-app/src/components/entry.rs @@ -212,6 +212,9 @@ fn EntryPageView( tracing::info!("Entry: {book_title} - {title}"); + let prev_entry = book_entry_view().prev.clone(); + let next_entry = book_entry_view().next.clone(); + rsx! { EntryOgMeta { title: title.to_string(), @@ -223,10 +226,10 @@ fn EntryPageView( } document::Link { rel: "stylesheet", href: ENTRY_CSS } - div { class: "entry-page-layout", - // Left gutter with prev button - if let Some(ref prev) = book_entry_view().prev { - div { class: "nav-gutter nav-prev", + div { class: "entry-page", + // Header: nav prev + metadata + nav next + header { class: "entry-header", + if let Some(ref prev) = prev_entry { NavButton { direction: "prev", entry: prev.entry.clone(), @@ -234,11 +237,7 @@ fn EntryPageView( book_title: book_title() } } - } - // Main content area - div { class: "entry-content-main notebook-content", - // Metadata header { let (word_count, reading_time_mins) = calculate_reading_stats(&entry_record().content); rsx! { @@ -254,16 +253,38 @@ fn EntryPageView( } } - // Rendered markdown - EntryMarkdown { - content: entry_record, - ident + if let Some(ref next) = next_entry { + NavButton { + direction: "next", + entry: next.entry.clone(), + ident: ident(), + book_title: book_title() + } + } + } + + // Main content area + div { class: "entry-content-wrapper", + div { class: "entry-content-main notebook-content", + EntryMarkdown { + content: entry_record, + ident + } } } - // Right gutter with next button - if let Some(ref next) = book_entry_view().next { - div { class: "nav-gutter nav-next", + // Footer navigation + footer { class: "entry-footer-nav", + if let Some(ref prev) = prev_entry { + NavButton { + direction: "prev", + entry: prev.entry.clone(), + ident: ident(), + book_title: book_title() + } + } + + if let Some(ref next) = next_entry { NavButton { direction: "next", entry: next.entry.clone(), @@ -648,7 +669,7 @@ pub fn EntryMetadata( } } -/// Navigation button for prev/next entries +/// Navigation link for prev/next entries (minimal: arrow + title) #[component] pub fn NavButton( direction: &'static str, @@ -662,14 +683,17 @@ pub fn NavButton( .map(|t| t.as_ref()) .unwrap_or("Untitled"); - // Get path from view for URL, fallback to title let entry_path = entry .path .as_ref() .map(|p| p.as_ref().to_string()) .unwrap_or_else(|| entry_title.to_string()); - let arrow = if direction == "prev" { "←" } else { "→" }; + let (arrow, title_first) = if direction == "prev" { + ("←", false) + } else { + ("→", true) + }; rsx! { Link { @@ -679,8 +703,13 @@ pub fn NavButton( title: entry_path.into() }, class: "nav-button nav-button-{direction}", - div { class: "nav-arrow", "{arrow}" } - div { class: "nav-title", "{entry_title}" } + if title_first { + span { class: "nav-title", "{entry_title}" } + span { class: "nav-arrow", "{arrow}" } + } else { + span { class: "nav-arrow", "{arrow}" } + span { class: "nav-title", "{entry_title}" } + } } } } diff --git a/crates/weaver-renderer/src/atproto.rs b/crates/weaver-renderer/src/atproto.rs index 3505491..c7ce034 100644 --- a/crates/weaver-renderer/src/atproto.rs +++ b/crates/weaver-renderer/src/atproto.rs @@ -22,3 +22,6 @@ pub use markdown_writer::MarkdownWriter; pub use preprocess::AtProtoPreprocessContext; pub use types::{BlobInfo, BlobName}; pub use writer::{ClientWriter, EmbedContentProvider}; + +#[cfg(test)] +mod tests; diff --git a/crates/weaver-renderer/src/atproto/markdown_writer.rs b/crates/weaver-renderer/src/atproto/markdown_writer.rs index 2bb516d..f4cde2b 100644 --- a/crates/weaver-renderer/src/atproto/markdown_writer.rs +++ b/crates/weaver-renderer/src/atproto/markdown_writer.rs @@ -48,7 +48,7 @@ impl MarkdownWriter { fn start_tag(&mut self, tag: Tag<'_>) -> Result<(), W::Error> { match tag { - Tag::Paragraph => Ok(()), + Tag::Paragraph(_) => Ok(()), Tag::Heading { level, .. } => { write!(self.writer, "{} ", "#".repeat(level as usize)) } @@ -109,7 +109,7 @@ impl MarkdownWriter { fn end_tag(&mut self, tag: TagEnd) -> Result<(), W::Error> { match tag { - TagEnd::Paragraph => write!(self.writer, "\n\n"), + TagEnd::Paragraph(_) => write!(self.writer, "\n\n"), TagEnd::Heading(_) => write!(self.writer, "\n\n"), TagEnd::BlockQuote(_) => write!(self.writer, "\n\n"), TagEnd::CodeBlock => write!(self.writer, "```\n\n"), @@ -158,7 +158,7 @@ impl MarkdownWriter { #[cfg(test)] mod tests { use super::*; - use markdown_weaver::{Event, Tag, CowStr}; + use markdown_weaver::{Event, Tag, CowStr, ParagraphContext}; use markdown_weaver_escape::FmtWriter; #[test] @@ -166,9 +166,9 @@ mod tests { let mut output = String::new(); let mut writer = MarkdownWriter::new(FmtWriter(&mut output)); - writer.write_event(Event::Start(Tag::Paragraph)).unwrap(); + writer.write_event(Event::Start(Tag::Paragraph(ParagraphContext::Complete))).unwrap(); writer.write_event(Event::Text(CowStr::Borrowed("Hello"))).unwrap(); - writer.write_event(Event::End(markdown_weaver::TagEnd::Paragraph)).unwrap(); + writer.write_event(Event::End(markdown_weaver::TagEnd::Paragraph(ParagraphContext::Complete))).unwrap(); assert_eq!(output, "Hello\n\n"); } diff --git a/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__blockquote_rendering.snap b/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__blockquote_rendering.snap new file mode 100644 index 0000000..0a1cc16 --- /dev/null +++ b/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__blockquote_rendering.snap @@ -0,0 +1,8 @@ +--- +source: crates/weaver-renderer/src/atproto/tests.rs +expression: output +--- +
+

This is a quote

+

With multiple lines

+
diff --git a/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__code_block_rendering.snap b/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__code_block_rendering.snap new file mode 100644 index 0000000..c885084 --- /dev/null +++ b/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__code_block_rendering.snap @@ -0,0 +1,8 @@ +--- +source: crates/weaver-renderer/src/atproto/tests.rs +expression: output +--- +
fn main() {
+    println!("Hello");
+}
+
diff --git a/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__footnote_in_blockquote.snap b/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__footnote_in_blockquote.snap new file mode 100644 index 0000000..2dcdbc3 --- /dev/null +++ b/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__footnote_in_blockquote.snap @@ -0,0 +1,10 @@ +--- +source: crates/weaver-renderer/src/atproto/tests.rs +expression: output +--- +
+

Quote with footnote1.

+
+
1 +

Footnote for quote.

+
diff --git a/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__footnote_multiple.snap b/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__footnote_multiple.snap new file mode 100644 index 0000000..53fbfde --- /dev/null +++ b/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__footnote_multiple.snap @@ -0,0 +1,11 @@ +--- +source: crates/weaver-renderer/src/atproto/tests.rs +expression: output +--- +

First1 and second2 footnotes.

+
1 +

First note.

+
+
2 +

Second note.

+
diff --git a/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__footnote_named.snap b/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__footnote_named.snap new file mode 100644 index 0000000..ef52693 --- /dev/null +++ b/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__footnote_named.snap @@ -0,0 +1,5 @@ +--- +source: crates/weaver-renderer/src/atproto/tests.rs +expression: output +--- +

ReferenceNamed footnote content..

diff --git a/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__footnote_sidenote_inline.snap b/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__footnote_sidenote_inline.snap new file mode 100644 index 0000000..31a6c38 --- /dev/null +++ b/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__footnote_sidenote_inline.snap @@ -0,0 +1,5 @@ +--- +source: crates/weaver-renderer/src/atproto/tests.rs +expression: output +--- +

Here is textSidenote content.

diff --git a/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__footnote_traditional.snap b/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__footnote_traditional.snap new file mode 100644 index 0000000..065ecd0 --- /dev/null +++ b/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__footnote_traditional.snap @@ -0,0 +1,5 @@ +--- +source: crates/weaver-renderer/src/atproto/tests.rs +expression: output +--- +

Here is some textThis is the footnote definition..

diff --git a/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__footnote_with_inline_formatting.snap b/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__footnote_with_inline_formatting.snap new file mode 100644 index 0000000..8927fdd --- /dev/null +++ b/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__footnote_with_inline_formatting.snap @@ -0,0 +1,5 @@ +--- +source: crates/weaver-renderer/src/atproto/tests.rs +expression: output +--- +

Text with footnoteNote with bold and italic..

diff --git a/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__heading_rendering.snap b/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__heading_rendering.snap new file mode 100644 index 0000000..571d8e5 --- /dev/null +++ b/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__heading_rendering.snap @@ -0,0 +1,7 @@ +--- +source: crates/weaver-renderer/src/atproto/tests.rs +expression: output +--- +

Heading 1

+

Heading 2

+

Heading 3

diff --git a/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__list_rendering.snap b/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__list_rendering.snap new file mode 100644 index 0000000..cf21f9e --- /dev/null +++ b/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__list_rendering.snap @@ -0,0 +1,16 @@ +--- +source: crates/weaver-renderer/src/atproto/tests.rs +expression: output +--- +
    +
  • Item 1
  • +
  • Item 2 +
      +
    • Nested
    • +
    +
  • +
+
    +
  1. Ordered 1
  2. +
  3. Ordered 2
  4. +
diff --git a/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__math_rendering.snap b/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__math_rendering.snap new file mode 100644 index 0000000..197b391 --- /dev/null +++ b/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__math_rendering.snap @@ -0,0 +1,6 @@ +--- +source: crates/weaver-renderer/src/atproto/tests.rs +expression: output +--- +

Inline x2 and display:

+

y=mx+b

diff --git a/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__paragraph_rendering.snap b/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__paragraph_rendering.snap new file mode 100644 index 0000000..8456f79 --- /dev/null +++ b/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__paragraph_rendering.snap @@ -0,0 +1,6 @@ +--- +source: crates/weaver-renderer/src/atproto/tests.rs +expression: output +--- +

This is a paragraph.

+

This is another paragraph.

diff --git a/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__table_rendering.snap b/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__table_rendering.snap new file mode 100644 index 0000000..c0b576b --- /dev/null +++ b/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__table_rendering.snap @@ -0,0 +1,7 @@ +--- +source: crates/weaver-renderer/src/atproto/tests.rs +expression: output +--- +
+ +
LeftCenterRight
ABC
diff --git a/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__weaver_block_aside_class.snap b/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__weaver_block_aside_class.snap new file mode 100644 index 0000000..8cf8940 --- /dev/null +++ b/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__weaver_block_aside_class.snap @@ -0,0 +1,7 @@ +--- +source: crates/weaver-renderer/src/atproto/tests.rs +expression: output +--- + diff --git a/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__weaver_block_before_blockquote.snap b/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__weaver_block_before_blockquote.snap new file mode 100644 index 0000000..67fef45 --- /dev/null +++ b/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__weaver_block_before_blockquote.snap @@ -0,0 +1,9 @@ +--- +source: crates/weaver-renderer/src/atproto/tests.rs +expression: output +--- + + diff --git a/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__weaver_block_before_code_block.snap b/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__weaver_block_before_code_block.snap new file mode 100644 index 0000000..6304c29 --- /dev/null +++ b/crates/weaver-renderer/src/atproto/snapshots/weaver_renderer__atproto__tests__weaver_block_before_code_block.snap @@ -0,0 +1,7 @@ +--- +source: crates/weaver-renderer/src/atproto/tests.rs +expression: output +--- +\n")?, + WrapperElement::Div => self.write("\n")?, + } + } + Ok(()) + } + #[inline] fn write_newline(&mut self) -> Result<(), W::Error> { self.end_newline = true; @@ -139,9 +302,23 @@ impl<'a, I: Iterator>, W: StrWrite, E: EmbedContentProvider> while let Some(event) = self.events.next() { self.process_event(event)?; } + self.finalize()?; Ok(self.writer) } + /// Finalize output, closing any deferred state + fn finalize(&mut self) -> Result<(), W::Error> { + // Flush any pending footnote as traditional + self.flush_pending_footnote()?; + // Close deferred paragraph if any + if self.defer_paragraph_close { + self.write("

\n")?; + self.close_wrapper()?; + self.defer_paragraph_close = false; + } + Ok(()) + } + /// Consume events until End tag without writing anything. /// Used when we've already rendered content and just need to advance the iterator. fn consume_until_end(&mut self) { @@ -216,6 +393,9 @@ impl<'a, I: Iterator>, W: StrWrite, E: EmbedContentProvider> // If buffering code, append to buffer instead of writing if let Some((_, ref mut buffer)) = self.code_buffer { buffer.push_str(&text); + } else if self.pending_footnote.is_some() { + // Buffer text while waiting to see if footnote def follows + self.pending_footnote_content.push_str(&text); } else if !self.in_non_writing_block { escape_html_body_text(&mut self.writer, &text)?; self.end_newline = text.ends_with('\n'); @@ -254,8 +434,20 @@ impl<'a, I: Iterator>, W: StrWrite, E: EmbedContentProvider> self.write(&html)?; self.write("")?; } - SoftBreak => self.write_newline()?, - HardBreak => self.write("
\n")?, + SoftBreak => { + if self.pending_footnote.is_some() { + self.pending_footnote_content.push('\n'); + } else { + self.write_newline()?; + } + } + HardBreak => { + if self.pending_footnote.is_some() { + self.pending_footnote_content.push_str("
\n"); + } else { + self.write("
\n")?; + } + } Rule => { if self.end_newline { self.write("
\n")?; @@ -264,13 +456,13 @@ impl<'a, I: Iterator>, W: StrWrite, E: EmbedContentProvider> } } FootnoteReference(name) => { + // Flush any existing pending footnote as traditional + self.flush_pending_footnote()?; + // Get/create footnote number let len = self.numbers.len() + 1; - self.write("")?; let number = *self.numbers.entry(name.to_string()).or_insert(len); - write!(&mut self.writer, "{}", number)?; - self.write("")?; + // Buffer this reference to see if definition follows immediately + self.pending_footnote = Some((name.to_string(), number)); } TaskListMarker(checked) => { if checked { @@ -279,7 +471,10 @@ impl<'a, I: Iterator>, W: StrWrite, E: EmbedContentProvider> self.write("\n")?; } } - WeaverBlock(_) => {} + WeaverBlock(text) => { + // Buffer WeaverBlock content for parsing on End + self.weaver_block_buffer.push_str(&text); + } } Ok(()) } @@ -287,11 +482,24 @@ impl<'a, I: Iterator>, W: StrWrite, E: EmbedContentProvider> fn start_tag(&mut self, tag: Tag<'_>) -> Result<(), W::Error> { match tag { Tag::HtmlBlock => self.write(r#""#), - Tag::Paragraph => { - if self.end_newline { - self.write("

") + Tag::Paragraph(_) => { + if self.in_sidenote { + // Inside sidenote span - don't emit paragraph tags + Ok(()) + } else if self.defer_paragraph_close { + // We're continuing a virtual paragraph after a sidenote + // Don't emit

(already open) + // Clear defer flag - we'll set it again at end if another sidenote follows + self.defer_paragraph_close = false; + Ok(()) } else { - self.write("\n

") + self.flush_pending_footnote()?; + self.emit_wrapper_start()?; + if self.end_newline { + self.write("

") + } else { + self.write("\n

") + } } } Tag::Heading { @@ -300,6 +508,8 @@ impl<'a, I: Iterator>, W: StrWrite, E: EmbedContentProvider> classes, attrs, } => { + self.close_deferred_paragraph()?; + self.emit_wrapper_start()?; if !self.end_newline { self.write("\n")?; } @@ -334,6 +544,8 @@ impl<'a, I: Iterator>, W: StrWrite, E: EmbedContentProvider> self.write(">") } Tag::Table(alignments) => { + self.close_deferred_paragraph()?; + self.emit_wrapper_start()?; self.table_alignments = alignments; self.write("") } @@ -359,6 +571,8 @@ impl<'a, I: Iterator>, W: StrWrite, E: EmbedContentProvider> } } Tag::BlockQuote(kind) => { + self.close_deferred_paragraph()?; + self.emit_wrapper_start()?; let class_str = match kind { None => "", Some(BlockQuoteKind::Note) => " class=\"markdown-alert-note\"", @@ -375,6 +589,8 @@ impl<'a, I: Iterator>, W: StrWrite, E: EmbedContentProvider> Ok(()) } Tag::CodeBlock(info) => { + self.close_deferred_paragraph()?; + self.emit_wrapper_start()?; if !self.end_newline { self.write_newline()?; } @@ -398,6 +614,8 @@ impl<'a, I: Iterator>, W: StrWrite, E: EmbedContentProvider> } } Tag::List(Some(1)) => { + self.close_deferred_paragraph()?; + self.emit_wrapper_start()?; if self.end_newline { self.write("
    \n") } else { @@ -405,6 +623,8 @@ impl<'a, I: Iterator>, W: StrWrite, E: EmbedContentProvider> } } Tag::List(Some(start)) => { + self.close_deferred_paragraph()?; + self.emit_wrapper_start()?; if self.end_newline { self.write("
      >, W: StrWrite, E: EmbedContentProvider> self.write("\">\n") } Tag::List(None) => { + self.close_deferred_paragraph()?; + self.emit_wrapper_start()?; if self.end_newline { self.write("
        \n") } else { @@ -428,6 +650,8 @@ impl<'a, I: Iterator>, W: StrWrite, E: EmbedContentProvider> } } Tag::DefinitionList => { + self.close_deferred_paragraph()?; + self.emit_wrapper_start()?; if self.end_newline { self.write("
        \n") } else { @@ -556,22 +780,55 @@ impl<'a, I: Iterator>, W: StrWrite, E: EmbedContentProvider> id, attrs, } => self.write_embed(embed_type, dest_url, title, id, attrs), - Tag::WeaverBlock(_, _) => { + Tag::WeaverBlock(_, attrs) => { self.in_non_writing_block = true; + self.weaver_block_buffer.clear(); + // Store attrs from Start tag, will merge with parsed text on End + if !attrs.classes.is_empty() || !attrs.attrs.is_empty() { + self.pending_block_attrs = Some(attrs.into_static()); + } Ok(()) } Tag::FootnoteDefinition(name) => { - if self.end_newline { - self.write("
        + self.write("")?; + self.write("")?; + self.write("")?; + + self.in_sidenote = true; } else { - self.write("\n
        ")?; + let len = self.numbers.len() + 1; + let number = *self.numbers.entry(name.to_string()).or_insert(len); + write!(&mut self.writer, "{}", number)?; + self.write("")?; } - escape_html(&mut self.writer, &name)?; - self.write("\">")?; - let len = self.numbers.len() + 1; - let number = *self.numbers.entry(name.to_string()).or_insert(len); - write!(&mut self.writer, "{}", number)?; - self.write("") + Ok(()) } Tag::MetadataBlock(_) => { self.in_non_writing_block = true; @@ -584,10 +841,30 @@ impl<'a, I: Iterator>, W: StrWrite, E: EmbedContentProvider> use markdown_weaver::TagEnd; match tag { TagEnd::HtmlBlock => self.write("\n"), - TagEnd::Paragraph => self.write("

        \n"), + TagEnd::Paragraph(ctx) => { + if self.in_sidenote { + // Inside sidenote span - don't emit paragraph tags + Ok(()) + } else if ctx == ParagraphContext::Interrupted && self.pending_footnote.is_some() { + // Paragraph was interrupted AND we have a pending footnote, + // defer the

        close - the sidenote will be rendered inline + self.defer_paragraph_close = true; + Ok(()) + } else if self.defer_paragraph_close { + // We were deferring but now closing for real + self.write("

        \n")?; + self.close_wrapper()?; + self.defer_paragraph_close = false; + Ok(()) + } else { + self.write("

        \n")?; + self.close_wrapper() + } + } TagEnd::Heading(level) => { self.write("\n") } TagEnd::Table => self.write("
\n"), @@ -605,7 +882,13 @@ impl<'a, I: Iterator>, W: StrWrite, E: EmbedContentProvider> self.table_cell_index += 1; Ok(()) } - TagEnd::BlockQuote(_) => self.write("\n"), + TagEnd::BlockQuote(_) => { + // Close any deferred paragraph before closing blockquote + // (footnotes inside blockquotes can't be sidenotes since def is outside) + self.close_deferred_paragraph()?; + self.write("\n")?; + self.close_wrapper() + } TagEnd::CodeBlock => { use std::sync::LazyLock; use syntect::parsing::SyntaxSet; @@ -644,10 +927,19 @@ impl<'a, I: Iterator>, W: StrWrite, E: EmbedContentProvider> } Ok(()) } - TagEnd::List(true) => self.write("\n"), - TagEnd::List(false) => self.write("\n"), + TagEnd::List(true) => { + self.write("\n")?; + self.close_wrapper() + } + TagEnd::List(false) => { + self.write("\n")?; + self.close_wrapper() + } TagEnd::Item => self.write("\n"), - TagEnd::DefinitionList => self.write("\n"), + TagEnd::DefinitionList => { + self.write("\n")?; + self.close_wrapper() + } TagEnd::DefinitionListTitle => self.write("\n"), TagEnd::DefinitionListDefinition => self.write("\n"), TagEnd::Emphasis => self.write(""), @@ -660,9 +952,35 @@ impl<'a, I: Iterator>, W: StrWrite, E: EmbedContentProvider> TagEnd::Embed => Ok(()), TagEnd::WeaverBlock(_) => { self.in_non_writing_block = false; + // Parse the buffered text for attrs and store for next block + if !self.weaver_block_buffer.is_empty() { + let parsed = Self::parse_weaver_attrs(&self.weaver_block_buffer); + self.weaver_block_buffer.clear(); + // Merge with any existing pending attrs or set new + if let Some(ref mut existing) = self.pending_block_attrs { + existing.classes.extend(parsed.classes); + existing.attrs.extend(parsed.attrs); + } else { + self.pending_block_attrs = Some(parsed); + } + } + Ok(()) + } + TagEnd::FootnoteDefinition => { + if self.in_sidenote { + self.write("")?; + self.in_sidenote = false; + // Write any buffered content that came after the ref + if !self.pending_footnote_content.is_empty() { + let content = std::mem::take(&mut self.pending_footnote_content); + escape_html_body_text(&mut self.writer, &content)?; + self.end_newline = content.ends_with('\n'); + } + } else { + self.write("\n")?; + } Ok(()) } - TagEnd::FootnoteDefinition => self.write("\n"), TagEnd::MetadataBlock(_) => { self.in_non_writing_block = false; Ok(()) diff --git a/crates/weaver-renderer/src/base_html.rs b/crates/weaver-renderer/src/base_html.rs index 816f694..cd69d53 100644 --- a/crates/weaver-renderer/src/base_html.rs +++ b/crates/weaver-renderer/src/base_html.rs @@ -96,30 +96,26 @@ where escape_html_body_text(&mut self.writer, &text)?; self.write("")?; } - InlineMath(text) => { - match crate::math::render_math(&text, false) { - crate::math::MathResult::Success(mathml) => { - self.write(r#""#)?; - self.write(&mathml)?; - self.write("")?; - } - crate::math::MathResult::Error { html, .. } => { - self.write(&html)?; - } + InlineMath(text) => match crate::math::render_math(&text, false) { + crate::math::MathResult::Success(mathml) => { + self.write(r#""#)?; + self.write(&mathml)?; + self.write("")?; } - } - DisplayMath(text) => { - match crate::math::render_math(&text, true) { - crate::math::MathResult::Success(mathml) => { - self.write(r#""#)?; - self.write(&mathml)?; - self.write("")?; - } - crate::math::MathResult::Error { html, .. } => { - self.write(&html)?; - } + crate::math::MathResult::Error { html, .. } => { + self.write(&html)?; } - } + }, + DisplayMath(text) => match crate::math::render_math(&text, true) { + crate::math::MathResult::Success(mathml) => { + self.write(r#""#)?; + self.write(&mathml)?; + self.write("")?; + } + crate::math::MathResult::Error { html, .. } => { + self.write(&html)?; + } + }, Html(html) | InlineHtml(html) => { self.write(&html)?; } @@ -161,7 +157,7 @@ where fn start_tag(&mut self, tag: Tag<'a>) -> Result<(), W::Error> { match tag { Tag::HtmlBlock => Ok(()), - Tag::Paragraph => { + Tag::Paragraph(_) => { if self.end_newline { self.write("

") } else { @@ -461,7 +457,7 @@ where fn end_tag(&mut self, tag: TagEnd) -> Result<(), W::Error> { match tag { TagEnd::HtmlBlock => {} - TagEnd::Paragraph => { + TagEnd::Paragraph(_) => { self.write("

\n")?; } TagEnd::Heading(level) => { diff --git a/crates/weaver-renderer/src/css.rs b/crates/weaver-renderer/src/css.rs index 3ccced4..d41ae9c 100644 --- a/crates/weaver-renderer/src/css.rs +++ b/crates/weaver-renderer/src/css.rs @@ -125,6 +125,15 @@ html {{ padding: 1rem 0rem; word-wrap: break-word; overflow-wrap: break-word; + counter-reset: sidenote-counter; + max-width: 95ch; +}} + +/* When sidenotes exist, body padding creates the gutter */ +/* Left padding shrinks first as viewport narrows, right stays for sidenotes */ +body:has(.sidenote) {{ + padding-left: clamp(0rem, calc((100vw - 95ch - 15.5rem - 2rem) / 2), 15.5rem); + padding-right: 15.5rem; }} /* Typography */ @@ -286,18 +295,144 @@ tr:hover {{ }} .footnote-definition {{ - margin-top: 2rem; - padding-top: 0.5rem; - border-top: 1px solid var(--color-border); + order: 9999; + margin: 0; + padding: 0.5rem 0; font-size: 0.9em; }} +.footnote-definition:first-of-type {{ + margin-top: 2rem; + padding-top: 1rem; + border-top: 2px solid var(--color-border); +}} + +.footnote-definition:first-of-type::before {{ + content: "Footnotes"; + display: block; + font-weight: 600; + font-size: 1.1em; + color: var(--color-subtle); + margin-bottom: 0.75rem; +}} + .footnote-definition-label {{ font-weight: 600; margin-right: 0.5rem; color: var(--color-primary); }} +/* Aside blocks (via WeaverBlock prefix) */ +aside, .aside {{ + float: left; + width: 40%; + margin: 0 1.5rem 1rem 0; + padding: 1rem; + background: var(--color-surface); + border-right: 3px solid var(--color-primary); + font-size: 0.9em; + clear: left; +}} + +aside > *:first-child, +.aside > *:first-child {{ + margin-top: 0; +}} + +aside > *:last-child, +.aside > *:last-child {{ + margin-bottom: 0; +}} + +/* Reset blockquote styling inside asides */ +aside > blockquote, +.aside > blockquote {{ + border-left: none; + background: transparent; + padding: 0; + margin: 0; + font-size: inherit; +}} + +/* Indent utilities */ +.indent-1 {{ margin-left: 1em; }} +.indent-2 {{ margin-left: 2em; }} +.indent-3 {{ margin-left: 3em; }} + +/* Tufte-style Sidenotes */ +/* Hide checkbox for sidenote toggle */ +.margin-toggle {{ + display: none; +}} + +/* Sidenote number marker (inline superscript) */ +.sidenote-number {{ + counter-increment: sidenote-counter; +}} + +.sidenote-number::after {{ + content: counter(sidenote-counter); + font-size: 0.7em; + position: relative; + top: -0.5em; + color: var(--color-primary); + padding-left: 0.1em; +}} + +/* Sidenote content (margin notes on wide screens) */ +.sidenote {{ + float: right; + clear: right; + margin-right: -15.5rem; + width: 14rem; + margin-top: 0.3rem; + margin-bottom: 1rem; + font-size: 0.85em; + line-height: 1.4; + color: var(--color-subtle); +}} + +.sidenote::before {{ + content: counter(sidenote-counter) ". "; + color: var(--color-primary); +}} + +/* Mobile sidenotes: toggle behavior */ +@media (max-width: 900px) {{ + /* Reset sidenote gutter on mobile */ + body:has(.sidenote) {{ + padding-right: 0; + }} + + aside, .aside {{ + float: none; + width: 100%; + margin: 1rem 0; + }} + + .sidenote {{ + display: none; + }} + + .margin-toggle:checked + .sidenote {{ + display: block; + float: none; + width: 95%; + margin: 0.5rem 2.5%; + padding: 0.5rem; + background: var(--color-surface); + border-left: 2px solid var(--color-primary); + }} + + label.sidenote-number {{ + cursor: pointer; + }} + + label.sidenote-number::after {{ + text-decoration: underline; + }} +}} + /* Images */ img {{ max-width: 100%; diff --git a/crates/weaver-renderer/src/lib.rs b/crates/weaver-renderer/src/lib.rs index ff378dc..1b0f653 100644 --- a/crates/weaver-renderer/src/lib.rs +++ b/crates/weaver-renderer/src/lib.rs @@ -365,7 +365,7 @@ impl EventContext { pub fn get_context<'a>(event: &Event<'a>, prev: Option<&Self>) -> Self { match event { Event::Start(tag) => match tag { - Tag::Paragraph => Self::Text, + Tag::Paragraph(_) => Self::Text, Tag::Heading { .. } => Self::Heading, Tag::BlockQuote(_block_quote_kind) => Self::Text, Tag::CodeBlock(_code_block_kind) => Self::CodeBlock, diff --git a/crates/weaver-renderer/src/static_site/document.rs b/crates/weaver-renderer/src/static_site/document.rs index 06f0d98..39f2381 100644 --- a/crates/weaver-renderer/src/static_site/document.rs +++ b/crates/weaver-renderer/src/static_site/document.rs @@ -154,7 +154,10 @@ pub async fn write_document_head( } writer.write_all(b"\n").await.into_diagnostic()?; - writer.write_all(b"\n").await.into_diagnostic()?; + writer + .write_all(b"\n") + .await + .into_diagnostic()?; writer .write_all(b"
\n") .await diff --git a/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__footnote_in_blockquote.snap b/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__footnote_in_blockquote.snap new file mode 100644 index 0000000..96cda3a --- /dev/null +++ b/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__footnote_in_blockquote.snap @@ -0,0 +1,10 @@ +--- +source: crates/weaver-renderer/src/static_site/tests.rs +expression: output +--- +
+

Quote with footnote1.

+
+
1 +

Footnote for quote.

+
diff --git a/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__footnote_multiple.snap b/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__footnote_multiple.snap new file mode 100644 index 0000000..6b03363 --- /dev/null +++ b/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__footnote_multiple.snap @@ -0,0 +1,11 @@ +--- +source: crates/weaver-renderer/src/static_site/tests.rs +expression: output +--- +

First1 and second2 footnotes.

+
1 +

First note.

+
+
2 +

Second note.

+
diff --git a/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__footnote_named.snap b/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__footnote_named.snap new file mode 100644 index 0000000..f67c188 --- /dev/null +++ b/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__footnote_named.snap @@ -0,0 +1,5 @@ +--- +source: crates/weaver-renderer/src/static_site/tests.rs +expression: output +--- +

ReferenceNamed footnote content..

diff --git a/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__footnote_sidenote_inline.snap b/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__footnote_sidenote_inline.snap new file mode 100644 index 0000000..380ccc3 --- /dev/null +++ b/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__footnote_sidenote_inline.snap @@ -0,0 +1,5 @@ +--- +source: crates/weaver-renderer/src/static_site/tests.rs +expression: output +--- +

Here is textSidenote content.

diff --git a/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__footnote_traditional.snap b/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__footnote_traditional.snap new file mode 100644 index 0000000..d532ab7 --- /dev/null +++ b/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__footnote_traditional.snap @@ -0,0 +1,5 @@ +--- +source: crates/weaver-renderer/src/static_site/tests.rs +expression: output +--- +

Here is some textThis is the footnote definition..

diff --git a/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__footnote_with_inline_formatting.snap b/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__footnote_with_inline_formatting.snap new file mode 100644 index 0000000..364221e --- /dev/null +++ b/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__footnote_with_inline_formatting.snap @@ -0,0 +1,5 @@ +--- +source: crates/weaver-renderer/src/static_site/tests.rs +expression: output +--- +

Text with footnoteNote with bold and italic..

diff --git a/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__weaver_block_aside_class.snap b/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__weaver_block_aside_class.snap new file mode 100644 index 0000000..8ee3c60 --- /dev/null +++ b/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__weaver_block_aside_class.snap @@ -0,0 +1,7 @@ +--- +source: crates/weaver-renderer/src/static_site/tests.rs +expression: output +--- + diff --git a/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__weaver_block_before_blockquote.snap b/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__weaver_block_before_blockquote.snap new file mode 100644 index 0000000..b90b0e0 --- /dev/null +++ b/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__weaver_block_before_blockquote.snap @@ -0,0 +1,9 @@ +--- +source: crates/weaver-renderer/src/static_site/tests.rs +expression: output +--- + diff --git a/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__weaver_block_before_code_block.snap b/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__weaver_block_before_code_block.snap new file mode 100644 index 0000000..1941b6b --- /dev/null +++ b/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__weaver_block_before_code_block.snap @@ -0,0 +1,7 @@ +--- +source: crates/weaver-renderer/src/static_site/tests.rs +expression: output +--- + diff --git a/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__weaver_block_before_heading.snap b/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__weaver_block_before_heading.snap new file mode 100644 index 0000000..b54b571 --- /dev/null +++ b/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__weaver_block_before_heading.snap @@ -0,0 +1,8 @@ +--- +source: crates/weaver-renderer/src/static_site/tests.rs +expression: output +--- + diff --git a/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__weaver_block_before_list.snap b/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__weaver_block_before_list.snap new file mode 100644 index 0000000..1fbf0f4 --- /dev/null +++ b/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__weaver_block_before_list.snap @@ -0,0 +1,10 @@ +--- +source: crates/weaver-renderer/src/static_site/tests.rs +expression: output +--- + diff --git a/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__weaver_block_custom_attributes.snap b/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__weaver_block_custom_attributes.snap new file mode 100644 index 0000000..eadfe47 --- /dev/null +++ b/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__weaver_block_custom_attributes.snap @@ -0,0 +1,7 @@ +--- +source: crates/weaver-renderer/src/static_site/tests.rs +expression: output +--- +
+

Paragraph with class and attributes.

+
diff --git a/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__weaver_block_custom_class.snap b/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__weaver_block_custom_class.snap new file mode 100644 index 0000000..bbfa8bf --- /dev/null +++ b/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__weaver_block_custom_class.snap @@ -0,0 +1,7 @@ +--- +source: crates/weaver-renderer/src/static_site/tests.rs +expression: output +--- +
+

This paragraph has a custom class.

+
diff --git a/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__weaver_block_multiple_classes.snap b/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__weaver_block_multiple_classes.snap new file mode 100644 index 0000000..458374e --- /dev/null +++ b/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__weaver_block_multiple_classes.snap @@ -0,0 +1,7 @@ +--- +source: crates/weaver-renderer/src/static_site/tests.rs +expression: output +--- + diff --git a/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__weaver_block_no_effect_on_following.snap b/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__weaver_block_no_effect_on_following.snap new file mode 100644 index 0000000..f1a8845 --- /dev/null +++ b/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__weaver_block_no_effect_on_following.snap @@ -0,0 +1,8 @@ +--- +source: crates/weaver-renderer/src/static_site/tests.rs +expression: output +--- + +

Second paragraph NOT in aside.

diff --git a/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__weaver_block_with_footnote.snap b/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__weaver_block_with_footnote.snap new file mode 100644 index 0000000..baf3937 --- /dev/null +++ b/crates/weaver-renderer/src/static_site/snapshots/weaver_renderer__static_site__tests__weaver_block_with_footnote.snap @@ -0,0 +1,7 @@ +--- +source: crates/weaver-renderer/src/static_site/tests.rs +expression: output +--- + diff --git a/crates/weaver-renderer/src/static_site/tests.rs b/crates/weaver-renderer/src/static_site/tests.rs index 48985a9..f73b926 100644 --- a/crates/weaver-renderer/src/static_site/tests.rs +++ b/crates/weaver-renderer/src/static_site/tests.rs @@ -210,3 +210,128 @@ async fn test_unicode_content() { assert!(output.contains("🎉")); assert!(output.contains("café")); } + +// ============================================================================= +// WeaverBlock Prefix Tests +// ============================================================================= + +#[tokio::test] +async fn test_weaver_block_aside_class() { + let input = "\n\n{.aside}\nThis paragraph should be in an aside."; + let output = render_markdown(input).await; + insta::assert_snapshot!(output); +} + +#[tokio::test] +async fn test_weaver_block_custom_class() { + let input = "\n\n{.highlight}\nThis paragraph has a custom class."; + let output = render_markdown(input).await; + insta::assert_snapshot!(output); +} + +#[tokio::test] +async fn test_weaver_block_custom_attributes() { + let input = "\n\n{.foo, width: 300px, data-test: value}\nParagraph with class and attributes."; + let output = render_markdown(input).await; + insta::assert_snapshot!(output); +} + +#[tokio::test] +async fn test_weaver_block_before_heading() { + let input = "\n\n{.aside}\n## Heading in aside\n\nParagraph also in aside."; + let output = render_markdown(input).await; + insta::assert_snapshot!(output); +} + +#[tokio::test] +async fn test_weaver_block_before_blockquote() { + let input = "\n\n{.aside}\n\n> This blockquote is in an aside."; + let output = render_markdown(input).await; + insta::assert_snapshot!(output); +} + +#[tokio::test] +async fn test_weaver_block_before_list() { + let input = "\n\n{.aside}\n\n- Item 1\n- Item 2"; + let output = render_markdown(input).await; + insta::assert_snapshot!(output); +} + +#[tokio::test] +async fn test_weaver_block_before_code_block() { + let input = "\n\n{.aside}\n\n```rust\nfn main() {}\n```"; + let output = render_markdown(input).await; + insta::assert_snapshot!(output); +} + +#[tokio::test] +async fn test_weaver_block_multiple_classes() { + let input = "\n\n{.aside, .highlight, .important}\nMultiple classes applied."; + let output = render_markdown(input).await; + insta::assert_snapshot!(output); +} + +#[tokio::test] +async fn test_weaver_block_no_effect_on_following() { + let input = "\n\n{.aside}\nFirst paragraph in aside.\n\nSecond paragraph NOT in aside."; + let output = render_markdown(input).await; + insta::assert_snapshot!(output); +} + +// ============================================================================= +// Footnote / Sidenote Tests +// ============================================================================= + +#[tokio::test] +async fn test_footnote_traditional() { + let input = "Here is some text[^1].\n[^1]: This is the footnote definition."; + let output = render_markdown(input).await; + insta::assert_snapshot!(output); +} + +#[tokio::test] +async fn test_footnote_sidenote_inline() { + // When definition immediately follows reference in the same paragraph flow + let input = "Here is text[^note]\n[^note]: Sidenote content."; + let output = render_markdown(input).await; + insta::assert_snapshot!(output); +} + +#[tokio::test] +async fn test_footnote_multiple() { + let input = "First[^1] and second[^2] footnotes.\n[^1]: First note.\n[^2]: Second note."; + let output = render_markdown(input).await; + insta::assert_snapshot!(output); +} + +#[tokio::test] +async fn test_footnote_with_inline_formatting() { + let input = "Text with footnote[^fmt].\n[^fmt]: Note with **bold** and *italic*."; + let output = render_markdown(input).await; + insta::assert_snapshot!(output); +} + +#[tokio::test] +async fn test_footnote_named() { + let input = "Reference[^my-note].\n[^my-note]: Named footnote content."; + let output = render_markdown(input).await; + insta::assert_snapshot!(output); +} + +#[tokio::test] +async fn test_footnote_in_blockquote() { + let input = "> Quote with footnote[^q].\n[^q]: Footnote for quote."; + let output = render_markdown(input).await; + insta::assert_snapshot!(output); +} + +// ============================================================================= +// Combined WeaverBlock + Footnote Tests +// ============================================================================= + +#[tokio::test] +async fn test_weaver_block_with_footnote() { + let input = "{.aside}\nAside with a footnote[^aside].\n\n[^aside]: Footnote in aside context."; + let output = render_markdown(input).await; + insta::assert_snapshot!(output); +} diff --git a/crates/weaver-renderer/src/static_site/writer.rs b/crates/weaver-renderer/src/static_site/writer.rs index 26fb4aa..bedd2d4 100644 --- a/crates/weaver-renderer/src/static_site/writer.rs +++ b/crates/weaver-renderer/src/static_site/writer.rs @@ -1,12 +1,20 @@ use crate::{NotebookProcessor, base_html::TableState, static_site::context::StaticSiteContext}; use dashmap::DashMap; use markdown_weaver::{ - Alignment, BlockQuoteKind, CodeBlockKind, CowStr, EmbedType, Event, LinkType, Tag, + Alignment, BlockQuoteKind, CodeBlockKind, CowStr, EmbedType, Event, LinkType, + ParagraphContext, Tag, WeaverAttributes, }; use markdown_weaver_escape::{StrWrite, escape_href, escape_html, escape_html_body_text}; use n0_future::StreamExt; use weaver_common::jacquard::{client::AgentSession, prelude::*}; +/// Tracks the type of wrapper element emitted for WeaverBlock prefix +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum WrapperElement { + Aside, + Div, +} + pub struct StaticPageWriter<'input, I: Iterator>, A: AgentSession, W: StrWrite> { context: NotebookProcessor<'input, I, StaticSiteContext>, @@ -23,6 +31,23 @@ pub struct StaticPageWriter<'input, I: Iterator>, A: AgentS numbers: DashMap, usize>, code_buffer: Option<(Option, String)>, // (lang, content) + + /// Pending WeaverBlock attrs to apply to the next block element + pending_block_attrs: Option>, + /// Type of wrapper element currently open, and the block depth at which it was opened + active_wrapper: Option<(WrapperElement, usize)>, + /// Current block nesting depth (for wrapper close tracking) + block_depth: usize, + /// Buffer for WeaverBlock text content (to parse for attrs) + weaver_block_buffer: String, + /// Pending footnote reference waiting to see if definition follows immediately + pending_footnote: Option<(CowStr<'static>, usize)>, + /// Buffer for content between footnote ref and resolution + pending_footnote_content: String, + /// Whether current footnote definition is being rendered as a sidenote + in_sidenote: bool, + /// Whether we're deferring paragraph close for sidenote handling + defer_paragraph_close: bool, } impl<'input, I: Iterator>, A: AgentSession, W: StrWrite> @@ -39,9 +64,51 @@ impl<'input, I: Iterator>, A: AgentSession, W: StrWrite> table_cell_index: 0, numbers: DashMap::new(), code_buffer: None, + pending_block_attrs: None, + active_wrapper: None, + block_depth: 0, + weaver_block_buffer: String::new(), + pending_footnote: None, + pending_footnote_content: String::new(), + in_sidenote: false, + defer_paragraph_close: false, } } + /// Parse WeaverBlock text content into attributes. + /// Format: comma-separated, colon for key:value, otherwise class. + /// Example: ".aside, width: 300px" -> classes: ["aside"], attrs: [("width", "300px")] + fn parse_weaver_attrs(text: &str) -> WeaverAttributes<'static> { + let mut classes = Vec::new(); + let mut attrs = Vec::new(); + + for part in text.split(',') { + let part = part.trim(); + if part.is_empty() { + continue; + } + + if let Some((key, value)) = part.split_once(':') { + let key = key.trim(); + let value = value.trim(); + if !key.is_empty() && !value.is_empty() { + attrs.push(( + CowStr::from(key.to_string()), + CowStr::from(value.to_string()), + )); + } + } else { + // No colon - treat as class, strip leading dot if present + let class = part.strip_prefix('.').unwrap_or(part); + if !class.is_empty() { + classes.push(CowStr::from(class.to_string())); + } + } + } + + WeaverAttributes { classes, attrs } + } + /// Writes a new line. #[inline] fn write_newline(&mut self) -> Result<(), W::Error> { @@ -60,20 +127,147 @@ impl<'input, I: Iterator>, A: AgentSession, W: StrWrite> Ok(()) } + /// Close deferred paragraph if we're in that state. + /// Called when a non-paragraph block element starts. + fn close_deferred_paragraph(&mut self) -> Result<(), W::Error> { + if self.defer_paragraph_close { + // Flush pending footnote as traditional before closing + self.flush_pending_footnote()?; + self.write("

\n")?; + self.block_depth -= 1; + self.close_wrapper()?; + self.defer_paragraph_close = false; + } + Ok(()) + } + + /// Flush any pending footnote reference as a traditional footnote, + /// then write any buffered content that came after the reference. + fn flush_pending_footnote(&mut self) -> Result<(), W::Error> { + if let Some((name, number)) = self.pending_footnote.take() { + // Emit traditional footnote reference + self.write("
")?; + write!(&mut self.writer, "{}", number)?; + self.write("")?; + // Write any buffered content + if !self.pending_footnote_content.is_empty() { + let content = std::mem::take(&mut self.pending_footnote_content); + escape_html_body_text(&mut self.writer, &content)?; + self.end_newline = content.ends_with('\n'); + } + } + Ok(()) + } + + /// Emit wrapper element start based on pending block attrs + /// Returns true if a wrapper was emitted + fn emit_wrapper_start(&mut self) -> Result { + if let Some(attrs) = self.pending_block_attrs.take() { + let is_aside = attrs.classes.iter().any(|c| c.as_ref() == "aside"); + + if !self.end_newline { + self.write("\n")?; + } + + if is_aside { + self.write(" element) + let classes: Vec<_> = if is_aside { + attrs + .classes + .iter() + .filter(|c| c.as_ref() != "aside") + .collect() + } else { + attrs.classes.iter().collect() + }; + + if !classes.is_empty() { + self.write(" class=\"")?; + for (i, class) in classes.iter().enumerate() { + if i > 0 { + self.write(" ")?; + } + escape_html(&mut self.writer, class)?; + } + self.write("\"")?; + } + + // Write other attrs + for (attr, value) in &attrs.attrs { + self.write(" ")?; + escape_html(&mut self.writer, attr)?; + self.write("=\"")?; + escape_html(&mut self.writer, value)?; + self.write("\"")?; + } + + self.write(">\n")?; + Ok(true) + } else { + Ok(false) + } + } + + /// Close active wrapper element if one is open and we're at the right depth + fn close_wrapper(&mut self) -> Result<(), W::Error> { + if let Some((wrapper, open_depth)) = self.active_wrapper.take() { + if self.block_depth == open_depth { + match wrapper { + WrapperElement::Aside => self.write("\n")?, + WrapperElement::Div => self.write("
\n")?, + } + } else { + // Not at the right depth yet, put it back + self.active_wrapper = Some((wrapper, open_depth)); + } + } + Ok(()) + } + fn end_tag(&mut self, tag: markdown_weaver::TagEnd) -> Result<(), W::Error> { use markdown_weaver::TagEnd; match tag { TagEnd::HtmlBlock => {} - TagEnd::Paragraph => { - self.write("

\n")?; + TagEnd::Paragraph(ctx) => { + if self.in_sidenote { + // Inside sidenote span - don't emit paragraph tags + } else if ctx == ParagraphContext::Interrupted && self.pending_footnote.is_some() { + // Paragraph was interrupted AND we have a pending footnote, + // defer the

close - the sidenote will be rendered inline + self.defer_paragraph_close = true; + // Don't decrement block_depth yet - we're continuing the virtual paragraph + } else if self.defer_paragraph_close { + // We were deferring but now closing for real + self.write("

\n")?; + self.block_depth -= 1; + self.close_wrapper()?; + self.defer_paragraph_close = false; + } else { + self.write("

\n")?; + self.block_depth -= 1; + self.close_wrapper()?; + } } TagEnd::Heading(level) => { self.write("\n")?; } TagEnd::Table => { self.write("\n")?; + self.block_depth -= 1; + self.close_wrapper()?; } TagEnd::TableHead => { self.write("\n")?; @@ -94,7 +288,12 @@ impl<'input, I: Iterator>, A: AgentSession, W: StrWrite> self.table_cell_index += 1; } TagEnd::BlockQuote(_) => { + // Close any deferred paragraph before closing blockquote + // (footnotes inside blockquotes can't be sidenotes since def is outside) + self.close_deferred_paragraph()?; self.write("\n")?; + self.block_depth -= 1; + self.close_wrapper()?; } TagEnd::CodeBlock => { if let Some((lang, buffer)) = self.code_buffer.take() { @@ -127,18 +326,26 @@ impl<'input, I: Iterator>, A: AgentSession, W: StrWrite> } else { self.write("\n")?; } + self.block_depth -= 1; + self.close_wrapper()?; } TagEnd::List(true) => { self.write("\n")?; + self.block_depth -= 1; + self.close_wrapper()?; } TagEnd::List(false) => { self.write("\n")?; + self.block_depth -= 1; + self.close_wrapper()?; } TagEnd::Item => { self.write("\n")?; } TagEnd::DefinitionList => { self.write("\n")?; + self.block_depth -= 1; + self.close_wrapper()?; } TagEnd::DefinitionListTitle => { self.write("\n")?; @@ -168,9 +375,41 @@ impl<'input, I: Iterator>, A: AgentSession, W: StrWrite> TagEnd::Embed => (), // shouldn't happen, handled in start TagEnd::WeaverBlock(_) => { self.in_non_writing_block = false; + eprintln!( + "[TagEnd::WeaverBlock] buffer: {:?}", + self.weaver_block_buffer + ); + // Parse the buffered text for attrs and store for next block + if !self.weaver_block_buffer.is_empty() { + let parsed = Self::parse_weaver_attrs(&self.weaver_block_buffer); + eprintln!("[TagEnd::WeaverBlock] parsed: {:?}", parsed); + self.weaver_block_buffer.clear(); + // Merge with any existing pending attrs or set new + if let Some(ref mut existing) = self.pending_block_attrs { + existing.classes.extend(parsed.classes); + existing.attrs.extend(parsed.attrs); + } else { + self.pending_block_attrs = Some(parsed); + } + eprintln!( + "[TagEnd::WeaverBlock] pending_block_attrs now: {:?}", + self.pending_block_attrs + ); + } } TagEnd::FootnoteDefinition => { - self.write("\n")?; + if self.in_sidenote { + self.write("
")?; + self.in_sidenote = false; + // Write any buffered content that came after the ref + if !self.pending_footnote_content.is_empty() { + let content = std::mem::take(&mut self.pending_footnote_content); + escape_html_body_text(&mut self.writer, &content)?; + self.end_newline = content.ends_with('\n'); + } + } else { + self.write("\n")?; + } } TagEnd::MetadataBlock(_) => { self.in_non_writing_block = false; @@ -191,6 +430,20 @@ impl< while let Some(event) = self.context.next().await { self.process_event(event).await? } + self.finalize() + } + + /// Finalize output, closing any deferred state + fn finalize(&mut self) -> Result<(), W::Error> { + // Flush any pending footnote as traditional + self.flush_pending_footnote()?; + // Close deferred paragraph if any + if self.defer_paragraph_close { + self.write("

\n")?; + self.block_depth -= 1; + self.close_wrapper()?; + self.defer_paragraph_close = false; + } Ok(()) } @@ -198,6 +451,7 @@ impl< use markdown_weaver::Event::*; match event { Start(tag) => { + println!("Start tag: {:?}", tag); self.start_tag(tag).await?; } End(tag) => { @@ -207,6 +461,9 @@ impl< // If buffering code, append to buffer instead of writing if let Some((_, ref mut buffer)) = self.code_buffer { buffer.push_str(&text); + } else if self.pending_footnote.is_some() { + // Buffer text while waiting to see if footnote def follows + self.pending_footnote_content.push_str(&text); } else if !self.in_non_writing_block { escape_html_body_text(&mut self.writer, &text)?; self.end_newline = text.ends_with('\n'); @@ -231,10 +488,18 @@ impl< self.write(&html)?; } SoftBreak => { - self.write_newline()?; + if self.pending_footnote.is_some() { + self.pending_footnote_content.push('\n'); + } else { + self.write_newline()?; + } } HardBreak => { - self.write("
\n")?; + if self.pending_footnote.is_some() { + self.pending_footnote_content.push_str("
\n"); + } else { + self.write("
\n")?; + } } Rule => { if self.end_newline { @@ -244,13 +509,16 @@ impl< } } FootnoteReference(name) => { + // Flush any existing pending footnote as traditional + self.flush_pending_footnote()?; + // Get/create footnote number let len = self.numbers.len() + 1; - self.write("")?; - let number = *self.numbers.entry(name.into_static()).or_insert(len); - write!(&mut self.writer, "{}", number)?; - self.write("")?; + let number = *self + .numbers + .entry(name.clone().into_static()) + .or_insert(len); + // Buffer this reference to see if definition follows immediately + self.pending_footnote = Some((name.into_static(), number)); } TaskListMarker(true) => { self.write("\n")?; @@ -258,7 +526,11 @@ impl< TaskListMarker(false) => { self.write("\n")?; } - WeaverBlock(_text) => {} + WeaverBlock(text) => { + // Buffer WeaverBlock content for parsing on End + eprintln!("[WeaverBlock event] text: {:?}", text); + self.weaver_block_buffer.push_str(&text); + } } Ok(()) } @@ -315,11 +587,25 @@ impl< async fn start_tag(&mut self, tag: Tag<'input>) -> Result<(), W::Error> { match tag { Tag::HtmlBlock => Ok(()), - Tag::Paragraph => { - if self.end_newline { - self.write("

") + Tag::Paragraph(_) => { + if self.in_sidenote { + // Inside sidenote span - don't emit paragraph tags + Ok(()) + } else if self.defer_paragraph_close { + // We're continuing a virtual paragraph after a sidenote + // Don't emit

or increment block_depth (already counted) + // Clear defer flag - we'll set it again at end if another sidenote follows + self.defer_paragraph_close = false; + Ok(()) } else { - self.write("\n

") + self.flush_pending_footnote()?; + self.emit_wrapper_start()?; + self.block_depth += 1; + if self.end_newline { + self.write("

") + } else { + self.write("\n

") + } } } Tag::Heading { @@ -328,6 +614,9 @@ impl< classes, attrs, } => { + self.close_deferred_paragraph()?; + self.emit_wrapper_start()?; + self.block_depth += 1; if self.end_newline { self.write("<")?; } else { @@ -363,6 +652,9 @@ impl< self.write(">") } Tag::Table(alignments) => { + self.close_deferred_paragraph()?; + self.emit_wrapper_start()?; + self.block_depth += 1; self.table_alignments = alignments; self.write("") } @@ -392,6 +684,9 @@ impl< } } Tag::BlockQuote(kind) => { + self.close_deferred_paragraph()?; + self.emit_wrapper_start()?; + self.block_depth += 1; let class_str = match kind { None => "", Some(kind) => match kind { @@ -409,6 +704,9 @@ impl< } } Tag::CodeBlock(info) => { + self.close_deferred_paragraph()?; + self.emit_wrapper_start()?; + self.block_depth += 1; if !self.end_newline { self.write_newline()?; } @@ -432,6 +730,9 @@ impl< } } Tag::List(Some(1)) => { + self.close_deferred_paragraph()?; + self.emit_wrapper_start()?; + self.block_depth += 1; if self.end_newline { self.write("
    \n") } else { @@ -439,6 +740,9 @@ impl< } } Tag::List(Some(start)) => { + self.close_deferred_paragraph()?; + self.emit_wrapper_start()?; + self.block_depth += 1; if self.end_newline { self.write("
      \n") } Tag::List(None) => { + self.close_deferred_paragraph()?; + self.emit_wrapper_start()?; + self.block_depth += 1; if self.end_newline { self.write("
        \n") } else { @@ -462,6 +769,9 @@ impl< } } Tag::DefinitionList => { + self.close_deferred_paragraph()?; + self.emit_wrapper_start()?; + self.block_depth += 1; if self.end_newline { self.write("
        \n") } else { @@ -632,23 +942,57 @@ impl< } Ok(()) } - Tag::WeaverBlock(_, _attrs) => { - println!("Weaver block"); + Tag::WeaverBlock(_, attrs) => { self.in_non_writing_block = true; + self.weaver_block_buffer.clear(); + // Store attrs from Start tag, will merge with parsed text on End + if !attrs.classes.is_empty() || !attrs.attrs.is_empty() { + self.pending_block_attrs = Some(attrs.into_static()); + } Ok(()) } Tag::FootnoteDefinition(name) => { - if self.end_newline { - self.write("
        + self.write("")?; + self.write("")?; + self.write("")?; + + // Write any buffered content AFTER the sidenote span closes + // (we'll do this in end_tag) + self.in_sidenote = true; } else { - self.write("\n
        ")?; + let len = self.numbers.len() + 1; + let number = *self.numbers.entry(name.into_static()).or_insert(len); + write!(&mut self.writer, "{}", number)?; + self.write("")?; } - escape_html(&mut self.writer, &name)?; - self.write("\">")?; - let len = self.numbers.len() + 1; - let number = *self.numbers.entry(name.into_static()).or_insert(len); - write!(&mut self.writer, "{}", number)?; - self.write("") + Ok(()) } Tag::MetadataBlock(_) => { self.in_non_writing_block = true; diff --git a/lexicons/notebook/searchNotebooks.json b/lexicons/notebook/searchNotebooks.json index f06e4c3..b6de3fa 100644 --- a/lexicons/notebook/searchNotebooks.json +++ b/lexicons/notebook/searchNotebooks.json @@ -9,7 +9,11 @@ "type": "params", "required": ["q"], "properties": { - "q": { "type": "string", "minLength": 1, "maxLength": 500 }, + "q": { + "type": "string", + "minLength": 1, + "maxLength": 500 + }, "author": { "type": "string", "format": "at-identifier", @@ -17,13 +21,18 @@ }, "tags": { "type": "array", - "items": { "type": "string" }, + "items": { + "type": "string" + }, "maxLength": 10, "description": "Filter by tags (all must match)." }, "rating": { "type": "array", - "items": { "type": "ref", "ref": "sh.weaver.notebook.defs#contentRating" }, + "items": { + "type": "string", + "knownValues": ["general", "teen", "mature", "explicit"] + }, "description": "Filter by content rating (any of these)." }, "sort": { @@ -31,8 +40,15 @@ "knownValues": ["relevance", "recent", "popular"], "default": "relevance" }, - "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 25 }, - "cursor": { "type": "string" } + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 25 + }, + "cursor": { + "type": "string" + } } }, "output": { @@ -43,9 +59,14 @@ "properties": { "notebooks": { "type": "array", - "items": { "type": "ref", "ref": "sh.weaver.notebook.defs#notebookView" } + "items": { + "type": "ref", + "ref": "sh.weaver.notebook.defs#notebookView" + } }, - "cursor": { "type": "string" } + "cursor": { + "type": "string" + } } } } diff --git a/lexicons/notification/listNotifications.json b/lexicons/notification/listNotifications.json index a310c07..c6335b8 100644 --- a/lexicons/notification/listNotifications.json +++ b/lexicons/notification/listNotifications.json @@ -10,7 +10,24 @@ "properties": { "reasons": { "type": "array", - "items": { "type": "ref", "ref": "sh.weaver.notification.defs#notificationReason" }, + "items": { + "type": "string", + "knownValues": [ + "like", + "bookmark", + "follow", + "followAccept", + "subscribe", + "subscribeAccept", + "collaborationInvite", + "collaborationAccept", + "newEntry", + "entryUpdate", + "mention", + "tag", + "comment" + ] + }, "description": "Filter by notification reasons." }, "seenAt": { diff --git a/test-output/test-sidenotes.html b/test-output/test-sidenotes.html new file mode 100644 index 0000000..42516b2 --- /dev/null +++ b/test-output/test-sidenotes.html @@ -0,0 +1,1278 @@ + + + + + + test-sidenotes + + + + +
        +

        Weaver: Long-form Writing on AT Protocol

        +

        Or: "Get in kid, we're rebuilding the blogosphere!"

        +

        I grew up, like a lot of people on Bluesky, in the era of the internet where most of your online social interactions took place via text. I had a MySpace account, MSN messenger and Google Chat, I first got on Facebook back when they required a school email to sign up, I had a Tumblr, though not a LiveJournal.Hi Rahaeli. Sorry I was the wrong kind of nerd.

        +
        +

        weaver_photo_med.jpgThe namesake of what I'm building

        +
        +

        Social media in the conventional sense has been in a lot of ways a small part of the story of my time on the internet. The broader independent blogosphere of my teens and early adulthood shaped my worldview, and I was an avid reader and sometime participant there.

        +

        The Blogosphere

        +

        I am an atheist in large part because of a blog called Common Sense Atheism.The author, Luke Muehlhauser, was criticising both Richard Dawkins and some Christian apologetics I was familiar with. Luke's blog was part of a cluster of blogs out of which grew the rationalists, one of, for better or for worse, the most influential intellectual movements of the 21st century.I also read blogs like boingboing.net, was a big fan of Cory Doctorow. I figured out I am trans in part because of Thing of Things,Specifically their piece on the cluster structure of genderspace. a blog by Ozy Frantz, a transmasc person in the broader rationalist and Effective Altruist blogosphere.One thing these all have in common is length. Part of the reason I only really got onto Twitter in 2020 or so was because the concept of microblogging, of having to fit your thoughts into such a small package, baffled me for ages.Amusingly I now think that being on Twitter and now Bluesky made me a better writer. Restrictions breed creativity, after all.

        + +

        But at the same time, Substack's success proves that there is very much a desire for long-form writing, enough that people will pay for it, and that investors will back it. There are thoughts and forms of writing that you simply cannot fit into a post or even a thread of posts.

        +

        Plus, I'm loathe to enable a centralised platform like Substack where the owners are unfortunately friendly to fascists.I am very much a fan of freedom of expression. I'm not so much a fan of paying money to Nazis.That's where the at:// protocol and Weaver comes in.

        +

        The Pitch

        +

        Weaver is designed to be a highly flexible platform for medium and long-form writing on atproto.The weaver bird builds intricate, self-contained homes—seemed fitting for a platform about owning your writing. I was inspired by how weaver birds build their own homes, and by the notebooks, physical and virtual, that I create in the course of my work.The initial proof-of-concept is essentially a static site generator, able to turn a Markdown text file or a folder of Markdown files into a static "notebook" site. The intermediate goal is an elegant and intuitive writing platform with collaborative editing and straightforward, immediate publishing via a web-app.

        + +

        How It Works

        +

        Weaver works on a concept of notebooks with entries, which can be grouped into pages or chapters. They can have multiple attributed authors. You can tear out a metaphorical page and stick it in another notebook.

        +

        You own what you write.Technically you can include entries you don't control in your notebooks, although this isn't a supported mode—it's about your ownership of your words. And once collaborative editing is in, collaborative work will be resilient against deletion by one author. They can delete their notebook or even their account, but what you write will be safe.Entries are Markdown text—specifically, an extension on the Obsidian flavour of Markdown.I forked the popular rust markdown processing library pulldown-cmark because it had limited extensibility along the axes I wanted—custom syntax extensions to support Obsidian's Markdown flavour and additional useful features, like some of the ones on show here! They support additional embed types, including atproto record embeds and other markdown documents, as well as resizable images.

        +

        Why Rust?

        +

        As to why I'm writing it in Rust (and currently zero Typescript) as opposed to Go and Typescript? Well it comes down to familiarity. Rust isn't necessarily anyone's first choice in a vacuum for a web-native programming language, but it works quite well as one. I can share the vast majority of the protocol code, as well as the markdown rendering engine, between front and back end, with few if any compromises on performance, save a larger bundle size due to the nature of WebAssembly.

        + +

        Evolution

        +

        Weaver is therefore very much an evolving thing. It will always have and support the proof-of-concept workflow as a first-class citizen. That's part of the benefit of building this on atproto.

        +

        If I screw this up, not too hard for someone else to pick up the torch and continue.This is the traditional footnote, at the end, because sometimes you want your citations at the bottom of the page rather than in the margins.

        +
        + + diff --git a/test-output/weaver_photo_med.jpg b/test-output/weaver_photo_med.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1d66d62500ae545abae5492b4c820b17e0c64915 GIT binary patch literal 216984 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 ![[weaver_photo_med.jpg]]*The namesake of what I'm building* + +Social media in the conventional sense has been in a lot of ways a small part of the story of my time on the internet. The broader independent blogosphere of my teens and early adulthood shaped my worldview, and I was an avid reader and sometime participant there. + +## The Blogosphere + +I am an atheist in large part because of a blog called Common Sense Atheism.[^csa] Luke's blog was part of a cluster of blogs out of which grew the rationalists, one of, for better or for worse, the most influential intellectual movements of the 21st century. +[^csa]: The author, Luke Muehlhauser, was criticising both Richard Dawkins *and* some Christian apologetics I was familiar with. + +I also read blogs like boingboing.net, was a big fan of Cory Doctorow. I figured out I am trans in part because of Thing of Things,[^ozy] a blog by Ozy Frantz, a transmasc person in the broader rationalist and Effective Altruist blogosphere. +[^ozy]: Specifically their piece on the [cluster structure of genderspace](https://thingofthings.wordpress.com/2017/05/05/the-cluster-structure-of-genderspace/). + +One thing these all have in common is length. Part of the reason I only really got onto Twitter in 2020 or so was because the concept of microblogging, of having to fit your thoughts into such a small package, baffled me for ages.[^irony] +[^irony]: Amusingly I now think that being on Twitter and now Bluesky made me a better writer. Restrictions breed creativity, after all. + +{.aside} +> **On Platform Decay** +> +> Through all of this I was never really satisfied with the options that were out there for long-form writing. Wordpress required too much setup. Tumblr's system for comments remains insane. Hosting my own seemed like too much money to burn on something nobody might read. + +But at the same time, Substack's success proves that there is very much a desire for long-form writing, enough that people will pay for it, and that investors will back it. There are thoughts and forms of writing that you simply cannot fit into a post or even a thread of posts. + +Plus, I'm loathe to enable a centralised platform like Substack where the owners are unfortunately friendly to fascists.[^substack] +[^substack]: I am very much a fan of freedom of expression. I'm not so much a fan of paying money to Nazis. + +That's where the `at://` protocol and Weaver comes in. + +## The Pitch + +Weaver is designed to be a highly flexible platform for medium and long-form writing on atproto.[^namesake] I was inspired by how weaver birds build their own homes, and by the notebooks, physical and virtual, that I create in the course of my work. +[^namesake]: The weaver bird builds intricate, self-contained homes—seemed fitting for a platform about owning your writing. + +The initial proof-of-concept is essentially a static site generator, able to turn a Markdown text file or a folder of Markdown files into a static "notebook" site. The intermediate goal is an elegant and intuitive writing platform with collaborative editing and straightforward, immediate publishing via a web-app. + +{.aside} +> **The Ultimate Goal** +> +> Build a platform suitable for professional writers and journalists, an open alternative to platforms like Substack, with ways for readers to support writers, all on the `at://` protocol. + +## How It Works + +Weaver works on a concept of notebooks with entries, which can be grouped into pages or chapters. They can have multiple attributed authors. You can tear out a metaphorical page and stick it in another notebook. + +You own what you write.[^ownership] And once collaborative editing is in, collaborative work will be resilient against deletion by one author. They can delete their notebook or even their account, but what you write will be safe. +[^ownership]: Technically you can include entries you don't control in your notebooks, although this isn't a supported mode—it's about *your* ownership of *your* words. + +Entries are Markdown text—specifically, an extension on the Obsidian flavour of Markdown.[^markdown] They support additional embed types, including atproto record embeds and other markdown documents, as well as resizable images. +[^markdown]: I forked the popular rust markdown processing library `pulldown-cmark` because it had limited extensibility along the axes I wanted—custom syntax extensions to support Obsidian's Markdown flavour and additional useful features, like some of the ones on show here! + +## Why Rust? + +As to why I'm writing it in Rust (and currently zero Typescript) as opposed to Go and Typescript? Well it comes down to familiarity. Rust isn't necessarily anyone's first choice in a vacuum for a web-native programming language, but it works quite well as one. I can share the vast majority of the protocol code, as well as the markdown rendering engine, between front and back end, with few if any compromises on performance, save a larger bundle size due to the nature of WebAssembly. + +{.aside} +> **On Interoperability** +> +> The `at://` protocol, while it was developed in concert with a microblogging app, is actually pretty damn good for "macroblogging" too. Weaver's app server can display Whitewind posts. With effort, it can faithfully render Leaflet posts. It doesn't care what app your profile is on. + +## Evolution + +Weaver is therefore very much an evolving thing. It will always have and support the proof-of-concept workflow as a first-class citizen. That's part of the benefit of building this on atproto. + +If I screw this up, not too hard for someone else to pick up the torch and continue.[^open] +[^open]: This is the traditional footnote, at the end, because sometimes you want your citations at the bottom of the page rather than in the margins.