commits dce5094 roots: render Markdown and AsciiDoc blobs
Ports pre-redo:crates/git-ents-server/src/markdown.rs and asciidoc.rs
into ents-web, adapted to this crate own Result/Error and maud::Markup
shapes. acdc-converters-core and acdc-converters-html are not on
crates.io, so they are git dependencies on github.com/nlopes/acdc
pinned to the same rev pre-redo used (6ae19bc2e6f0fa4254a3e9ebd1c3d2f6c7caafde);
acdc-converters-terminal is not taken, since this crate has no
terminal-recording rendering. pulldown-cmark stays on the 0.13 line
pre-redo pinned.
Carries over the one non-obvious gotcha from the pre-redo port: acdc
embedded render mode drops the visible doctitle (Title heading) and
subtitle, so to_html reconstructs an h1/doc-subtitle from the parsed
doc.header and prepends it to the embedded body.
Neither renderer output is sanitized beyond what the renderer itself
guarantees (pulldown-cmark well-formed HTML from the parsed tree, acdc
own HTML converter) — matching the pre-redo version stance, which
emitted both unescaped via PreEscaped.
Both modules are unused until the next commit wires them into the file
browser blob view.
Assisted-by: Claude:claude-sonnet-5
Joseph D. Carpinelli · 1 month ago
Reviews No reviews of this commit yet — record a verdict below.
Start a review verdict
approve request-changes comment
Body Start a Review Cargo.lock
@@ -2,6 +2,77 @@
# It is not intended for manual editing.
version = 4
+[[package]]
+name = "acdc-converters-core"
+version = "0.1.0"
+source = "git+https://github.com/nlopes/acdc?rev=6ae19bc2e6f0fa4254a3e9ebd1c3d2f6c7caafde#6ae19bc2e6f0fa4254a3e9ebd1c3d2f6c7caafde"
+dependencies = [
+ "acdc-parser",
+ "bitflags 2.13.0",
+ "thiserror 2.0.18",
+ "tracing",
+]
+
+[[package]]
+name = "acdc-converters-html"
+version = "0.1.0"
+source = "git+https://github.com/nlopes/acdc?rev=6ae19bc2e6f0fa4254a3e9ebd1c3d2f6c7caafde#6ae19bc2e6f0fa4254a3e9ebd1c3d2f6c7caafde"
+dependencies = [
+ "acdc-converters-core",
+ "acdc-converters-terminal",
+ "acdc-parser",
+ "base64",
+ "chrono",
+ "sha2 0.11.0",
+ "thiserror 2.0.18",
+ "tracing",
+]
+
+[[package]]
+name = "acdc-converters-terminal"
+version = "0.1.0"
+source = "git+https://github.com/nlopes/acdc?rev=6ae19bc2e6f0fa4254a3e9ebd1c3d2f6c7caafde#6ae19bc2e6f0fa4254a3e9ebd1c3d2f6c7caafde"
+dependencies = [
+ "acdc-converters-core",
+ "acdc-parser",
+ "asciicast-rs",
+ "comfy-table",
+ "crossterm",
+ "libghostty-vt",
+ "serde",
+ "serde_json",
+ "syntect",
+ "thiserror 2.0.18",
+ "tracing",
+ "unicode-width",
+]
+
+[[package]]
+name = "acdc-parser"
+version = "0.9.0"
+source = "git+https://github.com/nlopes/acdc?rev=6ae19bc2e6f0fa4254a3e9ebd1c3d2f6c7caafde#6ae19bc2e6f0fa4254a3e9ebd1c3d2f6c7caafde"
+dependencies = [
+ "bitflags 2.13.0",
+ "bumpalo",
+ "csv",
+ "encoding_rs",
+ "evalexpr",
+ "peg",
+ "rustc-hash",
+ "self_cell",
+ "serde",
+ "serde_json",
+ "thiserror 2.0.18",
+ "tracing",
+ "url",
+]
+
+[[package]]
+name = "adler2"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
+
[[package]]
name = "aho-corasick"
version = "1.1.4"
@@ -17,6 +88,34 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
+[[package]]
+name = "android_system_properties"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "ansi-str"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "060de1453b69f46304b28274f382132f4e72c55637cf362920926a70d090890d"
+dependencies = [
+ "ansitok",
+]
+
+[[package]]
+name = "ansitok"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0a8acea8c2f1c60f0a92a8cd26bf96ca97db56f10bbcab238bbe0cceba659ee"
+dependencies = [
+ "nom",
+ "vte",
+]
+
[[package]]
name = "arc-swap"
version = "1.9.2"
@@ -42,6 +141,19 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56"
+[[package]]
+name = "asciicast-rs"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc0ba000776cf478263576bca61217ca5557749c55a8a2d2daf973047188be03"
+dependencies = [
+ "rgb",
+ "ruzstd",
+ "serde",
+ "serde_json",
+ "thiserror 2.0.18",
+]
+
[[package]]
name = "atomic-waker"
version = "1.1.2"
@@ -112,12 +224,27 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf"
+[[package]]
+name = "base64"
+version = "0.22.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
+
[[package]]
name = "base64ct"
version = "1.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06"
+[[package]]
+name = "bincode"
+version = "1.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
+dependencies = [
+ "serde",
+]
+
[[package]]
name = "bit-set"
version = "0.8.0"
@@ -154,6 +281,15 @@
"generic-array",
]
+[[package]]
+name = "block-buffer"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa"
+dependencies = [
+ "hybrid-array",
+]
+
[[package]]
name = "bstr"
version = "1.12.3"
@@ -222,6 +358,16 @@
"thiserror 2.0.18",
]
+[[package]]
+name = "cc"
+version = "1.2.67"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e17dd265a7d0f31ef544e1b20e03add05d3b45b491b633b10d67145d2acc1a38"
+dependencies = [
+ "find-msvc-tools",
+ "shlex",
+]
+
[[package]]
name = "cfg-if"
version = "1.0.4"
@@ -234,13 +380,26 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
+[[package]]
+name = "chrono"
+version = "0.4.45"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327"
+dependencies = [
+ "iana-time-zone",
+ "js-sys",
+ "num-traits",
+ "wasm-bindgen",
+ "windows-link",
+]
+
[[package]]
name = "cipher"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
dependencies = [
- "crypto-common",
+ "crypto-common 0.1.7",
"inout",
]
@@ -253,6 +412,31 @@
"hashbrown 0.16.1",
]
+[[package]]
+name = "comfy-table"
+version = "7.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "958c5d6ecf1f214b4c2bbbbf6ab9523a864bd136dcf71a7e8904799acfe1ad47"
+dependencies = [
+ "ansi-str",
+ "console",
+ "crossterm",
+ "unicode-segmentation",
+ "unicode-width",
+]
+
+[[package]]
+name = "console"
+version = "0.16.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4fe5f465a4f6fee88fad41b85d990f84c835335e85b5d9e6e63e0d06d28cba7c"
+dependencies = [
+ "encode_unicode",
+ "libc",
+ "unicode-width",
+ "windows-sys 0.61.2",
+]
+
[[package]]
name = "const-fnv1a-hash"
version = "1.1.0"
@@ -265,6 +449,12 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
+[[package]]
+name = "const-oid"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c"
+
[[package]]
name = "convert_case"
version = "0.10.0"
@@ -280,6 +470,12 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "980c2afde4af43d6a05c5be738f9eae595cff86dce1f38f88b95058a98c027f3"
+[[package]]
+name = "core-foundation-sys"
+version = "0.8.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
+
[[package]]
name = "cpufeatures"
version = "0.2.17"
@@ -289,6 +485,15 @@
"libc",
]
+[[package]]
+name = "cpufeatures"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201"
+dependencies = [
+ "libc",
+]
+
[[package]]
name = "crc32fast"
version = "1.5.0"
@@ -362,6 +567,36 @@
"typenum",
]
+[[package]]
+name = "crypto-common"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453"
+dependencies = [
+ "hybrid-array",
+]
+
+[[package]]
+name = "csv"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "52cd9d68cf7efc6ddfaaee42e7288d3a99d613d4b50f76ce9827ae0c6e14f938"
+dependencies = [
+ "csv-core",
+ "itoa",
+ "ryu",
+ "serde_core",
+]
+
+[[package]]
+name = "csv-core"
+version = "0.1.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "704a3c26996a80471189265814dbc2c257598b96b8a7feae2d31ace646bb9782"
+dependencies = [
+ "memchr",
+]
+
[[package]]
name = "curve25519-dalek"
version = "4.1.3"
@@ -369,9 +604,9 @@
checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be"
dependencies = [
"cfg-if",
- "cpufeatures",
+ "cpufeatures 0.2.17",
"curve25519-dalek-derive",
- "digest",
+ "digest 0.10.7",
"fiat-crypto",
"rustc_version",
"subtle",
@@ -439,10 +674,16 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb"
dependencies = [
- "const-oid",
+ "const-oid 0.9.6",
"zeroize",
]
+[[package]]
+name = "deranged"
+version = "0.5.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c"
+
[[package]]
name = "derive_more"
version = "2.1.1"
@@ -471,12 +712,34 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
- "block-buffer",
- "const-oid",
- "crypto-common",
+ "block-buffer 0.10.4",
+ "const-oid 0.9.6",
+ "crypto-common 0.1.7",
"subtle",
]
+[[package]]
+name = "digest"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2"
+dependencies = [
+ "block-buffer 0.12.1",
+ "const-oid 0.10.2",
+ "crypto-common 0.2.2",
+]
+
+[[package]]
+name = "displaydoc"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
[[package]]
name = "document-features"
version = "0.2.12"
@@ -499,7 +762,7 @@
checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca"
dependencies = [
"der",
- "digest",
+ "digest 0.10.7",
"elliptic-curve",
"rfc6979",
"signature",
@@ -523,7 +786,7 @@
dependencies = [
"curve25519-dalek",
"ed25519",
- "sha2",
+ "sha2 0.10.9",
"subtle",
]
@@ -535,7 +798,7 @@
dependencies = [
"base16ct",
"crypto-bigint",
- "digest",
+ "digest 0.10.7",
"ff",
"generic-array",
"group",
@@ -546,6 +809,12 @@
"zeroize",
]
+[[package]]
+name = "encode_unicode"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0"
+
[[package]]
name = "encoding_rs"
version = "0.8.35"
@@ -730,6 +999,9 @@
name = "ents-web"
version = "0.0.0"
dependencies = [
+ "acdc-converters-core",
+ "acdc-converters-html",
+ "acdc-parser",
"axum",
"ents-anchor",
"ents-effect",
@@ -750,6 +1022,7 @@
"gix-ref-store",
"http-body-util",
"maud",
+ "pulldown-cmark",
"rstest",
"serde",
"tempfile",
@@ -774,6 +1047,12 @@
"windows-sys 0.61.2",
]
+[[package]]
+name = "evalexpr"
+version = "13.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "25929004897f2bbab309121a60400d36992f6d911d09baa6c172f6cc55706601"
+
[[package]]
name = "facet"
version = "0.50.0-rc.5"
@@ -1023,6 +1302,22 @@
"libc",
]
+[[package]]
+name = "find-msvc-tools"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
+
+[[package]]
+name = "flate2"
+version = "1.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c"
+dependencies = [
+ "crc32fast",
+ "miniz_oxide",
+]
+
[[package]]
name = "fnv"
version = "1.0.7"
@@ -2163,7 +2458,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
dependencies = [
- "digest",
+ "digest 0.10.7",
]
[[package]]
@@ -2217,6 +2512,15 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eaec953f16e5bcf6b8a3cb3aa959b17e5577dbd2693e94554c462c08be22624b"
+[[package]]
+name = "hybrid-array"
+version = "0.4.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "818356c5132c1fede50f837ca96afbe78ff42413047f4abb886217845e1b6c8c"
+dependencies = [
+ "typenum",
+]
+
[[package]]
name = "hyper"
version = "1.10.1"
@@ -2252,6 +2556,112 @@
"tower-service",
]
+[[package]]
+name = "iana-time-zone"
+version = "0.1.65"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470"
+dependencies = [
+ "android_system_properties",
+ "core-foundation-sys",
+ "iana-time-zone-haiku",
+ "js-sys",
+ "log",
+ "wasm-bindgen",
+ "windows-core",
+]
+
+[[package]]
+name = "iana-time-zone-haiku"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "icu_collections"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c"
+dependencies = [
+ "displaydoc",
+ "potential_utf",
+ "utf8_iter",
+ "yoke",
+ "zerofrom",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_locale_core"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29"
+dependencies = [
+ "displaydoc",
+ "litemap",
+ "tinystr",
+ "writeable",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_normalizer"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4"
+dependencies = [
+ "icu_collections",
+ "icu_normalizer_data",
+ "icu_properties",
+ "icu_provider",
+ "smallvec 1.15.2",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_normalizer_data"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38"
+
+[[package]]
+name = "icu_properties"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de"
+dependencies = [
+ "icu_collections",
+ "icu_locale_core",
+ "icu_properties_data",
+ "icu_provider",
+ "zerotrie",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_properties_data"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14"
+
+[[package]]
+name = "icu_provider"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421"
+dependencies = [
+ "displaydoc",
+ "icu_locale_core",
+ "writeable",
+ "yoke",
+ "zerofrom",
+ "zerotrie",
+ "zerovec",
+]
+
[[package]]
name = "iddqd"
version = "0.4.5"
@@ -2264,6 +2674,27 @@
"hashbrown 0.16.1",
]
+[[package]]
+name = "idna"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de"
+dependencies = [
+ "idna_adapter",
+ "smallvec 1.15.2",
+ "utf8_iter",
+]
+
+[[package]]
+name = "idna_adapter"
+version = "1.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714"
+dependencies = [
+ "icu_normalizer",
+ "icu_properties",
+]
+
[[package]]
name = "impls"
version = "1.0.3"
@@ -2289,6 +2720,18 @@
"generic-array",
]
+[[package]]
+name = "int-enum"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e366a1634cccc76b4cfd3e7580de9b605e4d93f1edac48d786c1f867c0def495"
+dependencies = [
+ "proc-macro2",
+ "proc-macro2-diagnostics",
+ "quote",
+ "syn",
+]
+
[[package]]
name = "io-close"
version = "0.3.7"
@@ -2399,18 +2842,47 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
+[[package]]
+name = "libghostty-vt"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "04c77176dd05b2b5718046d807e786473f463ea6d478d56f8c0105e2fe6f71f5"
+dependencies = [
+ "bitflags 2.13.0",
+ "int-enum",
+ "libghostty-vt-sys",
+]
+
+[[package]]
+name = "libghostty-vt-sys"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "404671567c0ac43389a69ae424eefc89390a25d3a5386a54249cdaf13e01b411"
+
[[package]]
name = "libm"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
+[[package]]
+name = "linked-hash-map"
+version = "0.5.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
+
[[package]]
name = "linux-raw-sys"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
+[[package]]
+name = "litemap"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0"
+
[[package]]
name = "litrs"
version = "1.0.0"
@@ -2494,6 +2966,22 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
+[[package]]
+name = "minimal-lexical"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
+
+[[package]]
+name = "miniz_oxide"
+version = "0.8.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
+dependencies = [
+ "adler2",
+ "simd-adler32",
+]
+
[[package]]
name = "mio"
version = "1.2.1"
@@ -2524,6 +3012,16 @@
"libc",
]
+[[package]]
+name = "nom"
+version = "7.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
+dependencies = [
+ "memchr",
+ "minimal-lexical",
+]
+
[[package]]
name = "nonempty"
version = "0.12.0"
@@ -2546,6 +3044,12 @@
"zeroize",
]
+[[package]]
+name = "num-conv"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441"
+
[[package]]
name = "num-integer"
version = "0.1.46"
@@ -2581,6 +3085,28 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
+[[package]]
+name = "onig"
+version = "6.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0cc3cbf698f9438986c11a880c90a6d04b9de27575afd28bbf45b154b6c709e2"
+dependencies = [
+ "bitflags 2.13.0",
+ "libc",
+ "once_cell",
+ "onig_sys",
+]
+
+[[package]]
+name = "onig_sys"
+version = "69.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e68317604e77e53b85896388e1a803c1d21b74c899ec9e5e1112db90735edd7"
+dependencies = [
+ "cc",
+ "pkg-config",
+]
+
[[package]]
name = "owo-colors"
version = "4.3.0"
@@ -2600,7 +3126,7 @@
"ecdsa",
"elliptic-curve",
"primeorder",
- "sha2",
+ "sha2 0.10.9",
]
[[package]]
@@ -2612,7 +3138,7 @@
"ecdsa",
"elliptic-curve",
"primeorder",
- "sha2",
+ "sha2 0.10.9",
]
[[package]]
@@ -2626,7 +3152,7 @@
"elliptic-curve",
"primeorder",
"rand_core 0.6.4",
- "sha2",
+ "sha2 0.10.9",
]
[[package]]
@@ -2652,6 +3178,33 @@
"windows-link",
]
+[[package]]
+name = "peg"
+version = "0.8.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0aad070be5b63aa72103f2fcdd70a83adbd5e90112ce5b574171ff1c65501773"
+dependencies = [
+ "peg-macros",
+ "peg-runtime",
+]
+
+[[package]]
+name = "peg-macros"
+version = "0.8.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ddd8ef6825cae95355031ae26a99b616a2a21f22ba2de0197c43dfb05acbe7ee"
+dependencies = [
+ "peg-runtime",
+ "proc-macro2",
+ "quote",
+]
+
+[[package]]
+name = "peg-runtime"
+version = "0.8.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7011d97b484a5ebdc4b1fdb3b12d5e4bbbea56e9d22b688f2e79e04b65a7d8a6"
+
[[package]]
name = "pem-rfc7468"
version = "0.7.0"
@@ -2694,6 +3247,25 @@
"spki",
]
+[[package]]
+name = "pkg-config"
+version = "0.3.33"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e"
+
+[[package]]
+name = "plist"
+version = "1.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7da1d65da6dd5d1e44199ac0f58712d241c0f439f80adea8924d832384087f85"
+dependencies = [
+ "base64",
+ "indexmap",
+ "quick-xml",
+ "serde",
+ "time",
+]
+
[[package]]
name = "portable-atomic"
version = "1.13.1"
@@ -2709,6 +3281,21 @@
"portable-atomic",
]
+[[package]]
+name = "potential_utf"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564"
+dependencies = [
+ "zerovec",
+]
+
+[[package]]
+name = "powerfmt"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
+
[[package]]
name = "ppv-lite86"
version = "0.2.21"
@@ -2787,12 +3374,39 @@
"unarray",
]
+[[package]]
+name = "pulldown-cmark"
+version = "0.13.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e9f068eba8e7071c5f9511831b44f32c740d5adf574e990f946ddb53db2f314e"
+dependencies = [
+ "bitflags 2.13.0",
+ "memchr",
+ "pulldown-cmark-escape",
+ "unicase",
+]
+
+[[package]]
+name = "pulldown-cmark-escape"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "007d8adb5ddab6f8e3f491ac63566a7d5002cc7ed73901f72057943fa71ae1ae"
+
[[package]]
name = "quick-error"
version = "1.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
+[[package]]
+name = "quick-xml"
+version = "0.41.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e660451e55124f798a69a5af3f49ccfbefbd41910eefd25caf2393e1f3473ec1"
+dependencies = [
+ "memchr",
+]
+
[[package]]
name = "quote"
version = "1.0.46"
@@ -2935,21 +3549,27 @@
"subtle",
]
+[[package]]
+name = "rgb"
+version = "0.8.53"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47b34b781b31e5d73e9fbc8689c70551fd1ade9a19e3e28cfec8580a79290cc4"
+
[[package]]
name = "rsa"
version = "0.9.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d"
dependencies = [
- "const-oid",
- "digest",
+ "const-oid 0.9.6",
+ "digest 0.10.7",
"num-bigint-dig",
"num-integer",
"num-traits",
"pkcs1",
"pkcs8",
"rand_core 0.6.4",
- "sha2",
+ "sha2 0.10.9",
"signature",
"spki",
"subtle",
@@ -3031,6 +3651,12 @@
"wait-timeout",
]
+[[package]]
+name = "ruzstd"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a7c1c839d570d835527c9a5e4db7cb2198683a988cb9d7293fc8674e6bd58fc8"
+
[[package]]
name = "ryu"
version = "1.0.23"
@@ -3066,6 +3692,12 @@
"zeroize",
]
+[[package]]
+name = "self_cell"
+version = "1.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b12e76d157a900eb52e81bc6e9f3069344290341720e9178cde2407113ac8d89"
+
[[package]]
name = "semver"
version = "1.0.28"
@@ -3149,8 +3781,8 @@
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
dependencies = [
"cfg-if",
- "cpufeatures",
- "digest",
+ "cpufeatures 0.2.17",
+ "digest 0.10.7",
]
[[package]]
@@ -3159,7 +3791,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89f599ac0c323ebb1c6082821a54962b839832b03984598375bff3975b804423"
dependencies = [
- "digest",
+ "digest 0.10.7",
"sha1",
]
@@ -3170,8 +3802,19 @@
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
dependencies = [
"cfg-if",
- "cpufeatures",
- "digest",
+ "cpufeatures 0.2.17",
+ "digest 0.10.7",
+]
+
+[[package]]
+name = "sha2"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4"
+dependencies = [
+ "cfg-if",
+ "cpufeatures 0.3.0",
+ "digest 0.11.3",
]
[[package]]
@@ -3180,6 +3823,12 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc6fe69c597f9c37bfeeeeeb33da3530379845f10be461a66d16d03eca2ded77"
+[[package]]
+name = "shlex"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
+
[[package]]
name = "signal-hook"
version = "0.3.18"
@@ -3227,10 +3876,16 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
dependencies = [
- "digest",
+ "digest 0.10.7",
"rand_core 0.6.4",
]
+[[package]]
+name = "simd-adler32"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214"
+
[[package]]
name = "slab"
version = "0.4.12"
@@ -3293,7 +3948,7 @@
dependencies = [
"base64ct",
"pem-rfc7468",
- "sha2",
+ "sha2 0.10.9",
]
[[package]]
@@ -3309,7 +3964,7 @@
"rand_core 0.6.4",
"rsa",
"sec1",
- "sha2",
+ "sha2 0.10.9",
"signature",
"ssh-cipher",
"ssh-encoding",
@@ -3386,6 +4041,38 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
+[[package]]
+name = "synstructure"
+version = "0.13.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "syntect"
+version = "5.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "656b45c05d95a5704399aeef6bd0ddec7b2b3531b7c9e900abbf7c4d2190c925"
+dependencies = [
+ "bincode",
+ "flate2",
+ "fnv",
+ "once_cell",
+ "onig",
+ "plist",
+ "regex-syntax",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "thiserror 2.0.18",
+ "walkdir",
+ "yaml-rust",
+]
+
[[package]]
name = "tempfile"
version = "3.27.0"
@@ -3451,6 +4138,46 @@
"syn",
]
+[[package]]
+name = "time"
+version = "0.3.53"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "18dfaaeddcb932337b5e7866ee7d0ce9b76d2fd092997146f187ec09b4558a50"
+dependencies = [
+ "deranged",
+ "num-conv",
+ "powerfmt",
+ "serde_core",
+ "time-core",
+ "time-macros",
+]
+
+[[package]]
+name = "time-core"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109"
+
+[[package]]
+name = "time-macros"
+version = "0.2.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c431b87111666e491a90baa837f914fb45cd5dc3c268591b0220ff5057f2085f"
+dependencies = [
+ "num-conv",
+ "time-core",
+]
+
+[[package]]
+name = "tinystr"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d"
+dependencies = [
+ "displaydoc",
+ "zerovec",
+]
+
[[package]]
name = "tinyvec"
version = "1.11.0"
@@ -3604,6 +4331,12 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94"
+[[package]]
+name = "unicase"
+version = "2.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142"
+
[[package]]
name = "unicode-bom"
version = "2.0.3"
@@ -3648,6 +4381,24 @@
"rustc-hash",
]
+[[package]]
+name = "url"
+version = "2.5.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed"
+dependencies = [
+ "form_urlencoded",
+ "idna",
+ "percent-encoding",
+ "serde",
+]
+
+[[package]]
+name = "utf8_iter"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
+
[[package]]
name = "uuid"
version = "1.23.4"
@@ -3671,6 +4422,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "231fdcd7ef3037e8330d8e17e61011a2c244126acc0a982f4040ac3f9f0bc077"
dependencies = [
+ "arrayvec",
"memchr",
]
@@ -3790,12 +4542,65 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+[[package]]
+name = "windows-core"
+version = "0.62.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
+dependencies = [
+ "windows-implement",
+ "windows-interface",
+ "windows-link",
+ "windows-result",
+ "windows-strings",
+]
+
+[[package]]
+name = "windows-implement"
+version = "0.60.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "windows-interface"
+version = "0.59.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
[[package]]
name = "windows-link"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
+[[package]]
+name = "windows-result"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
+dependencies = [
+ "windows-link",
+]
+
+[[package]]
+name = "windows-strings"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
+dependencies = [
+ "windows-link",
+]
+
[[package]]
name = "windows-sys"
version = "0.59.0"
@@ -3893,6 +4698,12 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e"
+[[package]]
+name = "writeable"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4"
+
[[package]]
name = "xterm-query"
version = "0.6.0"
@@ -3904,12 +4715,44 @@
"windows-sys 0.59.0",
]
+[[package]]
+name = "yaml-rust"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
+dependencies = [
+ "linked-hash-map",
+]
+
[[package]]
name = "yansi"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
+[[package]]
+name = "yoke"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5"
+dependencies = [
+ "stable_deref_trait",
+ "yoke-derive",
+ "zerofrom",
+]
+
+[[package]]
+name = "yoke-derive"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "synstructure",
+]
+
[[package]]
name = "zerocopy"
version = "0.8.54"
@@ -3930,12 +4773,66 @@
"syn",
]
+[[package]]
+name = "zerofrom"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272"
+dependencies = [
+ "zerofrom-derive",
+]
+
+[[package]]
+name = "zerofrom-derive"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "synstructure",
+]
+
[[package]]
name = "zeroize"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e"
+[[package]]
+name = "zerotrie"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf"
+dependencies = [
+ "displaydoc",
+ "yoke",
+ "zerofrom",
+]
+
+[[package]]
+name = "zerovec"
+version = "0.11.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239"
+dependencies = [
+ "yoke",
+ "zerofrom",
+ "zerovec-derive",
+]
+
+[[package]]
+name = "zerovec-derive"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
[[package]]
name = "zlib-rs"
version = "0.6.6"
crates/cli/ents-web/Cargo.toml
@@ -6,6 +6,9 @@
license.workspace = true
[dependencies]
+acdc-converters-core = { workspace = true }
+acdc-converters-html = { workspace = true }
+acdc-parser = { workspace = true }
ents-anchor = { workspace = true }
ents-effect = { workspace = true }
ents-forge = { workspace = true }
@@ -24,6 +27,7 @@
gix-ref-store = { workspace = true }
axum = { workspace = true }
maud = { workspace = true }
+pulldown-cmark = { workspace = true }
serde = { version = "1", features = ["derive"] }
thiserror = { workspace = true }
tokio = { workspace = true }
crates/cli/ents-web/src/error.rs
@@ -83,6 +83,12 @@
/// outcome. Boxed; see [`Error::Forge`]'s own doc.
#[error(transparent)]
Receive(Box<ents_receive::Error>),
+
+ /// `crate::asciidoc::to_html` could not parse or convert an AsciiDoc
+ /// blob (`acdc` reported no more specific error than "could not
+ /// convert").
+ #[error("could not render asciidoc: {0}")]
+ Asciidoc(String),
}
impl From<ents_forge::Error> for Error {
crates/cli/ents-web/src/lib.rs
@@ -106,9 +106,11 @@
//! # });
//! ```
+pub(crate) mod asciidoc;
pub(crate) mod assets;
pub mod error;
pub mod identity;
+pub(crate) mod markdown;
pub mod pages;
pub mod render;
pub mod router;
crates/cli/ents-web/src/asciidoc.rs
@@ -1,0 +1,127 @@
+//! AsciiDoc rendering via the [`acdc`](https://github.com/nlopes/acdc) library.
+//!
+//! AsciiDoc gets the same treatment Markdown does (`crate::markdown`): an
+//! `.adoc`/`.asciidoc` blob in [`crate::pages::files`] renders as a
+//! formatted document rather than a plain-text listing. Output is the
+//! *embedded* fragment (no `<!DOCTYPE>`/`<html>` frame) so it can drop
+//! straight into a `.doc-body`-styled card
+//! (`crate::assets::OVERRIDES`).
+//!
+//! `acdc-converters-core` and `acdc-converters-html` are not on crates.io
+//! yet, so they are pinned as git dependencies on the same revision
+//! `pre-redo:Cargo.toml` pinned (see this crate's own `Cargo.toml`).
+#![cfg_attr(
+ not(test),
+ expect(
+ dead_code,
+ reason = "wired into crate::pages::files's blob view in the next commit"
+ )
+)]
+
+use acdc_converters_core::{Converter, Options as ConvertOptions, inlines_to_string};
+use acdc_converters_html::{Processor, RenderOptions};
+use acdc_parser::Options as ParseOptions;
+use maud::{Markup, PreEscaped, html};
+
+use crate::error::{Error, Result};
+
+/// File extensions that name an AsciiDoc document.
+const EXTENSIONS: [&str; 4] = ["adoc", "asciidoc", "asc", "adc"];
+
+/// Whether `name` looks like an AsciiDoc file by its extension.
+#[must_use]
+pub(crate) fn is_asciidoc(name: &str) -> bool {
+ name.rsplit_once('.')
+ .is_some_and(|(_, ext)| EXTENSIONS.iter().any(|e| ext.eq_ignore_ascii_case(e)))
+}
+
+/// Render AsciiDoc `source` to an embedded HTML fragment. The fragment
+/// carries no document frame, so callers place it inside their own
+/// container (`.doc-body`).
+///
+/// `acdc`'s embedded render mode omits both the document frame *and* the
+/// visible doctitle/subtitle, so this reconstructs them from the parsed
+/// header and prepends them to the embedded body -- carried over from
+/// `pre-redo:crates/git-ents-server/src/asciidoc.rs`'s own `to_html`,
+/// which hit the same gap: without this, a README's own `= Title` line
+/// would silently vanish from the rendered page.
+///
+/// No sanitization is applied beyond what `acdc`'s HTML converter itself
+/// guarantees -- the pre-redo version did the same, emitting the
+/// converter's output unescaped via `maud::PreEscaped`.
+///
+/// # Errors
+///
+/// [`Error::Asciidoc`] if `source` cannot be parsed or converted.
+pub(crate) fn to_html(source: &str) -> Result<Markup> {
+ let parsed = acdc_parser::parse(source, &ParseOptions::default())
+ .map_err(|err| Error::Asciidoc(err.to_string()))?;
+ let doc = parsed.document();
+
+ let heading = doc
+ .header
+ .as_ref()
+ .filter(|h| !h.title.is_empty())
+ .map(|h| {
+ let title = inlines_to_string(&h.title);
+ let subtitle = h.subtitle.as_ref().map(|s| inlines_to_string(s));
+ html! {
+ h1 { (title) }
+ @if let Some(subtitle) = subtitle {
+ p.doc-subtitle { (subtitle) }
+ }
+ }
+ });
+
+ let processor = Processor::new(ConvertOptions::default(), doc.attributes.clone());
+ let options = RenderOptions {
+ embedded: true,
+ ..RenderOptions::default()
+ };
+ let body = processor
+ .convert_to_string(doc, &options)
+ .map_err(|err| Error::Asciidoc(err.to_string()))?;
+ Ok(match heading {
+ Some(heading) => html! { (heading) (PreEscaped(body)) },
+ None => PreEscaped(body),
+ })
+}
+
+#[cfg(test)]
+mod tests {
+ #![allow(clippy::expect_used, reason = "unit test")]
+
+ use rstest::rstest;
+
+ use super::*;
+
+ #[rstest]
+ #[case::adoc("readme.adoc", true)]
+ #[case::asciidoc("readme.asciidoc", true)]
+ #[case::asc("notes.asc", true)]
+ #[case::upper("README.ADOC", true)]
+ #[case::md("readme.md", false)]
+ #[case::no_ext("readme", false)]
+ fn is_asciidoc_matches_by_extension(#[case] name: &str, #[case] expected: bool) {
+ assert_eq!(is_asciidoc(name), expected);
+ }
+
+ #[test]
+ fn to_html_reconstructs_the_doctitle_and_renders_a_paragraph() {
+ let rendered = to_html("= Title\n\nA paragraph.\n")
+ .expect("valid asciidoc")
+ .into_string();
+ assert!(rendered.contains("<h1>Title</h1>"));
+ assert!(rendered.contains("A paragraph."));
+ }
+
+ #[test]
+ fn to_html_reconstructs_a_subtitle() {
+ let rendered = to_html("= Title: Subtitle\n\nBody.\n")
+ .expect("valid asciidoc")
+ .into_string();
+ assert!(rendered.contains("<h1>Title</h1>"));
+ assert!(rendered.contains(r#"class="doc-subtitle""#));
+ assert!(rendered.contains("Subtitle"));
+ }
+}
crates/cli/ents-web/src/markdown.rs
@@ -1,0 +1,72 @@
+//! Markdown rendering via [`pulldown_cmark`].
+//!
+//! Markdown gets the same treatment AsciiDoc does (`crate::asciidoc`): a
+//! `.md` blob in [`crate::pages::files`] renders as a formatted document
+//! rather than a plain-text listing. Output is an embedded fragment (no
+//! document frame) styled by [`crate::assets::OVERRIDES`]'s own
+//! `.doc-body` rules.
+#![cfg_attr(
+ not(test),
+ expect(
+ dead_code,
+ reason = "wired into crate::pages::files's blob view in the next commit"
+ )
+)]
+
+use maud::{Markup, PreEscaped};
+use pulldown_cmark::{Options, Parser, html};
+
+/// File extensions that name a Markdown document.
+const EXTENSIONS: [&str; 4] = ["md", "markdown", "mdown", "mkd"];
+
+/// Whether `name` looks like a Markdown file by its extension.
+#[must_use]
+pub(crate) fn is_markdown(name: &str) -> bool {
+ name.rsplit_once('.')
+ .is_some_and(|(_, ext)| EXTENSIONS.iter().any(|e| ext.eq_ignore_ascii_case(e)))
+}
+
+/// Render Markdown `source` to an embedded HTML fragment, with the tables,
+/// footnotes, strikethrough, and task-list extensions people expect from
+/// forge-flavored Markdown.
+///
+/// No additional sanitization is applied beyond what `pulldown_cmark`
+/// itself guarantees (well-formed HTML output from the parsed Markdown
+/// tree, not sanitized against embedded raw HTML in the source) --
+/// `pre-redo:crates/git-ents-server/src/markdown.rs`'s own `to_html` did
+/// the same: it emitted `pulldown_cmark::html::push_html`'s output
+/// unescaped, straight into the page.
+#[must_use]
+pub(crate) fn to_html(source: &str) -> Markup {
+ let options = Options::ENABLE_TABLES
+ | Options::ENABLE_FOOTNOTES
+ | Options::ENABLE_STRIKETHROUGH
+ | Options::ENABLE_TASKLISTS;
+ let mut out = String::new();
+ html::push_html(&mut out, Parser::new_ext(source, options));
+ PreEscaped(out)
+}
+
+#[cfg(test)]
+mod tests {
+ use rstest::rstest;
+
+ use super::*;
+
+ #[rstest]
+ #[case::md("readme.md", true)]
+ #[case::markdown("readme.markdown", true)]
+ #[case::upper("README.MD", true)]
+ #[case::adoc("readme.adoc", false)]
+ #[case::no_ext("readme", false)]
+ fn is_markdown_matches_by_extension(#[case] name: &str, #[case] expected: bool) {
+ assert_eq!(is_markdown(name), expected);
+ }
+
+ #[test]
+ fn to_html_renders_a_heading_and_a_table() {
+ let rendered = to_html("# Title\n\n| a | b |\n|---|---|\n| 1 | 2 |\n").into_string();
+ assert!(rendered.contains("<h1>Title</h1>"));
+ assert!(rendered.contains("<table>"));
+ }
+}