Skip to main content

markdown/
lib.rs

1//! A Notion-style block document model, with markdown as the wire form.
2//!
3//! ```
4//! let doc = markdown::parse("# Title\n\n- a\n- b");
5//! assert_eq!(doc.blocks.len(), 3);
6//! assert_eq!(markdown::serialize(&doc), "# Title\n\n- a\n- b");
7//! ```
8//!
9//! The model is a flat list of blocks with an indent level ([`Doc`]), not a
10//! nested tree — Notion's shape rather than CommonMark's, chosen because
11//! editing a flat list is list operations while editing a tree is restructuring.
12//! [`parse`] and [`serialize`] are inverses up to a fixed point: parsing,
13//! serializing and parsing again always lands on the same document, so an
14//! edit/save cycle cannot drift.
15//!
16//! [`doc`], [`parse`], [`serialize`], [`select`] and [`edit`] are pure — no
17//! gpui, no painting — and [`render`] is the gpui layer over them, caret and
18//! selection included for a caller that owns them. The editing *surface* is the
19//! `editor` crate.
20//!
21//! Everything that paints is behind the `gpui` feature, on by default. Without
22//! it the crate is the document model alone and builds for
23//! `wasm32-unknown-unknown`.
24//!
25//! An image at an `http` URL — a picture, a favicon, a bookmark's cover —
26//! needs an http client on the app, which `gpui_platform::application` installs
27//! and a hand-built [`gpui::Application`] does not. gpui's own default is a
28//! `NullHttpClient`, and the failure is silent: the element paints the same
29//! fallback it would show while a fetch was still in flight.
30
31#[cfg(feature = "gpui")]
32pub mod app;
33pub mod doc;
34pub mod edit;
35#[cfg(feature = "gpui")]
36pub mod fence;
37pub mod html;
38pub mod marks;
39#[cfg(feature = "gpui")]
40pub mod paint;
41pub mod parse;
42pub mod quote;
43#[cfg(feature = "gpui")]
44pub mod render;
45pub mod select;
46pub mod serialize;
47#[cfg(feature = "gpui")]
48pub mod source;
49pub mod synced;
50
51#[cfg(feature = "gpui")]
52pub use app::{
53    AppExt,
54    layout::Layout,
55    link::{Link, Links},
56    picture::PictureMenu,
57    preview::Preview,
58    typography::Typography,
59};
60pub use doc::{Align, Block, BlockKind, Doc, Form, Mark, MarkSpan, Part, QuoteKind, Quoted, Text};
61pub use edit::{Shortcut, Splice, shortcut};
62#[cfg(feature = "gpui")]
63pub use fence::{BlockRenderer, Fence, Rewrite, highlight::Highlighter};
64pub use html::{Html, html};
65pub use marks::Marks;
66#[cfg(feature = "gpui")]
67pub use paint::{
68    comment::{CommentPaint, CommentWashes, default_comment},
69    find::{FindPaint, default_find, find_washes},
70    marks::{
71        HighlightColor, HighlightPaint, MarkPaint, default_highlight, highlight_solid,
72        highlight_wash,
73    },
74};
75pub use parse::{
76    ParsedDoc, is_image, is_link, is_url, parse, parse_at, parse_at_many, parse_ranges,
77    parse_ranges_with, parse_with,
78};
79pub use quote::Quote;
80#[cfg(feature = "gpui")]
81pub use render::{
82    Annotation, BlockLayouts, Caption, CopyButton, Editing, FenceHost, ImageOverlay,
83    ImageOverlayCorner, LeaveBlock, OnImage, OnImageMenu, OnJump, OnLeave, OnResize, OnRewrite,
84    OnToggle, PAINTED_CONTEXT, RevealMode, SourceText, SpanJob, Spans, Toggle, image_source,
85    markdown, render, render_source, render_with,
86};
87pub use select::{Affinity, Cursor, Selection};
88pub use serialize::{serialize, serialize_at, serialize_at_many, serialize_with};
89#[cfg(feature = "gpui")]
90pub use source::{spans as source_spans, style::SourceStyle};
91pub use synced::Synced;