Markdown is standard: docengine is not a feature
The rich feature was default-on, on the reasoning that a consumer with no
rich text should not pay for a markdown parser. Markdown turns out to be
what these apps are mostly made of, so the saving was hypothetical and what
the flag bought was a build in which a described screen draws **bold** at
the reader. A renderer either honours the description or it is not a
renderer for it.
The dependency is unpinned deliberately: docengine is in-tree and moves
with us, and a pinned minor means editing two files to release one.
- Co-Authored-By
- Claude Opus 5 (1M context) <noreply@anthropic.com>
3 files changed,
+28 insertions,
-31 deletions
| 723 |
723 |
|
|
| 724 |
724 |
|
[[package]]
|
| 725 |
725 |
|
name = "docengine"
|
| 726 |
|
- |
version = "0.4.0"
|
|
726 |
+ |
version = "0.5.0"
|
| 727 |
727 |
|
dependencies = [
|
| 728 |
728 |
|
"ammonia",
|
| 729 |
729 |
|
"pulldown-cmark",
|
| 4888 |
4888 |
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
| 4889 |
4889 |
|
checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
|
| 4890 |
4890 |
|
|
| 4891 |
|
- |
[[patch.unused]]
|
| 4892 |
|
- |
name = "synckit-client"
|
| 4893 |
|
- |
version = "0.8.0"
|
| 4894 |
|
- |
|
| 4895 |
|
- |
[[patch.unused]]
|
| 4896 |
|
- |
name = "synckit-config"
|
| 4897 |
|
- |
version = "0.2.0"
|
| 4898 |
|
- |
|
| 4899 |
4891 |
|
[[patch.unused]]
|
| 4900 |
4892 |
|
name = "kberg"
|
| 4901 |
4893 |
|
version = "0.1.0"
|
| 4907 |
4899 |
|
[[patch.unused]]
|
| 4908 |
4900 |
|
name = "tagtree"
|
| 4909 |
4901 |
|
version = "0.4.0"
|
|
4902 |
+ |
|
|
4903 |
+ |
[[patch.unused]]
|
|
4904 |
+ |
name = "synckit-client"
|
|
4905 |
+ |
version = "0.8.0"
|
|
4906 |
+ |
|
|
4907 |
+ |
[[patch.unused]]
|
|
4908 |
+ |
name = "synckit-config"
|
|
4909 |
+ |
version = "0.2.0"
|
| 18 |
18 |
|
makeover-layout = "0.12.0"
|
| 19 |
19 |
|
makeover-webview = "0.22.1"
|
| 20 |
20 |
|
# `Node::Rich` carries markdown source and this is what turns it into markup.
|
| 21 |
|
- |
# Optional and default-on: a renderer that cannot render the member makes the
|
| 22 |
|
- |
# member do nothing, and a consumer with no rich text should not pay for a
|
| 23 |
|
- |
# markdown parser. Sanitising comes with it, which is why the node can carry
|
| 24 |
|
- |
# what a user typed.
|
| 25 |
|
- |
docengine = { git = "https://makenot.work/git/max/docengine.git", version = "0.4.0", optional = true }
|
| 26 |
|
- |
|
| 27 |
|
- |
[features]
|
| 28 |
|
- |
default = ["rich"]
|
| 29 |
|
- |
# Render `Node::Rich`. Without it the node emits its source as text, which is
|
| 30 |
|
- |
# what every renderer did before the member existed.
|
| 31 |
|
- |
rich = ["dep:docengine"]
|
|
21 |
+ |
# Sanitising comes with it, which is why the node can carry what a user typed.
|
|
22 |
+ |
#
|
|
23 |
+ |
# Not optional. It was, default-on, on the reasoning that a consumer with no
|
|
24 |
+ |
# rich text should not pay for a markdown parser; markdown turns out to be what
|
|
25 |
+ |
# these apps are mostly made of (every task, project and event description, and
|
|
26 |
+ |
# every mail body an HTML message produced), so the saving was hypothetical and
|
|
27 |
+ |
# what the flag really bought was a build in which a described screen silently
|
|
28 |
+ |
# renders its prose as syntax. A renderer either honours the description or it
|
|
29 |
+ |
# is not a renderer for it.
|
|
30 |
+ |
#
|
|
31 |
+ |
# Unpinned deliberately: docengine is in-tree and moves with us, and a pinned
|
|
32 |
+ |
# minor here means editing two files to release one.
|
|
33 |
+ |
docengine = { git = "https://makenot.work/git/max/docengine.git" }
|
| 127 |
127 |
|
/// rendering as text rather than as markup, which is the outcome
|
| 128 |
128 |
|
/// [`Node::Text`] would have given anyway.
|
| 129 |
129 |
|
///
|
| 130 |
|
- |
/// Without the `rich` feature the source is escaped and emitted as it was
|
| 131 |
|
- |
/// written. That is lossy and visible rather than silent, and it is what the
|
| 132 |
|
- |
/// node did before it could be rendered at all.
|
|
130 |
+ |
/// Unconditional. This sat behind a default-on `rich` feature until markdown
|
|
131 |
+ |
/// was made standard, and turning the feature off did not remove a cost so much
|
|
132 |
+ |
/// as produce a renderer that draws `**bold**` at the user. Markdown is what
|
|
133 |
+ |
/// these descriptions are made of, so rendering it is part of being a renderer
|
|
134 |
+ |
/// rather than an extra somebody opts into.
|
| 133 |
135 |
|
fn rich_html(source: &str) -> String {
|
| 134 |
|
- |
#[cfg(feature = "rich")]
|
| 135 |
|
- |
{
|
| 136 |
|
- |
docengine::render_strict(source)
|
| 137 |
|
- |
}
|
| 138 |
|
- |
#[cfg(not(feature = "rich"))]
|
| 139 |
|
- |
{
|
| 140 |
|
- |
escape(source)
|
| 141 |
|
- |
}
|
|
136 |
+ |
docengine::render_strict(source)
|
| 142 |
137 |
|
}
|
| 143 |
138 |
|
|
| 144 |
139 |
|
/// JSON-encode a string, for an `hx-vals` payload.
|