Skip to content

Commit 1a4563b

Browse files
committed
DRAFT: rustdoc: math-core LaTeX MathML test
This is intended for crater to see how many crates error if we just enable math-core. This isn't an exhaustive test, because some crates will render worse without actually producing an error, but it should gives us some bug reports to open against the math-core repo.
1 parent 78865ca commit 1a4563b

7 files changed

Lines changed: 195 additions & 10 deletions

File tree

Cargo.lock

Lines changed: 119 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,7 @@ dependencies = [
643643
"declare_clippy_lint",
644644
"filetime",
645645
"itertools",
646-
"pulldown-cmark",
646+
"pulldown-cmark 0.11.3",
647647
"regex",
648648
"rustc_tools_util 0.4.2",
649649
"serde",
@@ -1275,6 +1275,12 @@ version = "1.0.10"
12751275
source = "registry+https://github.com/rust-lang/crates.io-index"
12761276
checksum = "8975ffdaa0ef3661bfe02dbdcc06c9f829dfafe6a3c474de366a8d5e44276921"
12771277

1278+
[[package]]
1279+
name = "dtoa"
1280+
version = "1.0.11"
1281+
source = "registry+https://github.com/rust-lang/crates.io-index"
1282+
checksum = "4c3cf4824e2d5f025c7b531afcb2325364084a16806f6d47fbc1f5fbd9960590"
1283+
12781284
[[package]]
12791285
name = "dyn-clone"
12801286
version = "1.0.20"
@@ -2392,6 +2398,33 @@ dependencies = [
23922398
"regex-automata",
23932399
]
23942400

2401+
[[package]]
2402+
name = "math-core"
2403+
version = "0.2.2"
2404+
source = "registry+https://github.com/rust-lang/crates.io-index"
2405+
checksum = "2226363d63d9c12367ca74c261a198ba979f98b4311fded39239a9a904835e40"
2406+
dependencies = [
2407+
"math-core-renderer-internal",
2408+
"memchr",
2409+
"phf 0.13.1",
2410+
"rustc-hash 2.1.1",
2411+
"strum 0.27.2",
2412+
"strum_macros 0.27.2",
2413+
]
2414+
2415+
[[package]]
2416+
name = "math-core-renderer-internal"
2417+
version = "0.2.2"
2418+
source = "registry+https://github.com/rust-lang/crates.io-index"
2419+
checksum = "fd17e13ea5087c4df7aeccf184eff5352546913e72cac8f4a64841980733913c"
2420+
dependencies = [
2421+
"bitflags",
2422+
"dtoa",
2423+
"stable-arena",
2424+
"strum 0.27.2",
2425+
"strum_macros 0.27.2",
2426+
]
2427+
23952428
[[package]]
23962429
name = "md-5"
23972430
version = "0.10.6"
@@ -2915,13 +2948,24 @@ dependencies = [
29152948
"phf_shared 0.12.1",
29162949
]
29172950

2951+
[[package]]
2952+
name = "phf"
2953+
version = "0.13.1"
2954+
source = "registry+https://github.com/rust-lang/crates.io-index"
2955+
checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf"
2956+
dependencies = [
2957+
"phf_macros",
2958+
"phf_shared 0.13.1",
2959+
"serde",
2960+
]
2961+
29182962
[[package]]
29192963
name = "phf_codegen"
29202964
version = "0.11.3"
29212965
source = "registry+https://github.com/rust-lang/crates.io-index"
29222966
checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a"
29232967
dependencies = [
2924-
"phf_generator",
2968+
"phf_generator 0.11.3",
29252969
"phf_shared 0.11.3",
29262970
]
29272971

@@ -2935,6 +2979,29 @@ dependencies = [
29352979
"rand 0.8.5",
29362980
]
29372981

2982+
[[package]]
2983+
name = "phf_generator"
2984+
version = "0.13.1"
2985+
source = "registry+https://github.com/rust-lang/crates.io-index"
2986+
checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737"
2987+
dependencies = [
2988+
"fastrand",
2989+
"phf_shared 0.13.1",
2990+
]
2991+
2992+
[[package]]
2993+
name = "phf_macros"
2994+
version = "0.13.1"
2995+
source = "registry+https://github.com/rust-lang/crates.io-index"
2996+
checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef"
2997+
dependencies = [
2998+
"phf_generator 0.13.1",
2999+
"phf_shared 0.13.1",
3000+
"proc-macro2",
3001+
"quote",
3002+
"syn 2.0.110",
3003+
]
3004+
29383005
[[package]]
29393006
name = "phf_shared"
29403007
version = "0.11.3"
@@ -2953,6 +3020,15 @@ dependencies = [
29533020
"siphasher",
29543021
]
29553022

3023+
[[package]]
3024+
name = "phf_shared"
3025+
version = "0.13.1"
3026+
source = "registry+https://github.com/rust-lang/crates.io-index"
3027+
checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266"
3028+
dependencies = [
3029+
"siphasher",
3030+
]
3031+
29563032
[[package]]
29573033
name = "pin-project-lite"
29583034
version = "0.2.16"
@@ -3089,6 +3165,18 @@ dependencies = [
30893165
"unicase",
30903166
]
30913167

3168+
[[package]]
3169+
name = "pulldown-cmark"
3170+
version = "0.13.0"
3171+
source = "registry+https://github.com/rust-lang/crates.io-index"
3172+
checksum = "1e8bbe1a966bd2f362681a44f6edce3c2310ac21e4d5067a6e7ec396297a6ea0"
3173+
dependencies = [
3174+
"bitflags",
3175+
"memchr",
3176+
"pulldown-cmark-escape",
3177+
"unicase",
3178+
]
3179+
30923180
[[package]]
30933181
name = "pulldown-cmark-escape"
30943182
version = "0.11.0"
@@ -4591,7 +4679,7 @@ version = "0.0.0"
45914679
dependencies = [
45924680
"indexmap",
45934681
"itertools",
4594-
"pulldown-cmark",
4682+
"pulldown-cmark 0.13.0",
45954683
"rustc_arena",
45964684
"rustc_ast",
45974685
"rustc_ast_pretty",
@@ -4883,6 +4971,7 @@ dependencies = [
48834971
"expect-test",
48844972
"indexmap",
48854973
"itertools",
4974+
"math-core",
48864975
"minifier",
48874976
"proc-macro2",
48884977
"pulldown-cmark-escape",
@@ -5314,12 +5403,18 @@ dependencies = [
53145403
"nom",
53155404
"serde",
53165405
"spdx-expression",
5317-
"strum",
5318-
"strum_macros",
5406+
"strum 0.24.1",
5407+
"strum_macros 0.24.3",
53195408
"thiserror 1.0.69",
53205409
"uuid",
53215410
]
53225411

5412+
[[package]]
5413+
name = "stable-arena"
5414+
version = "0.2.0"
5415+
source = "registry+https://github.com/rust-lang/crates.io-index"
5416+
checksum = "2a6572b16faf73db61fab0b1d848ce108e20d026dc20dcb043a3f83c73ad1c09"
5417+
53235418
[[package]]
53245419
name = "stable_deref_trait"
53255420
version = "1.2.1"
@@ -5364,7 +5459,7 @@ version = "0.5.4"
53645459
source = "registry+https://github.com/rust-lang/crates.io-index"
53655460
checksum = "c711928715f1fe0fe509c53b43e993a9a557babc2d0a3567d0a3006f1ac931a0"
53665461
dependencies = [
5367-
"phf_generator",
5462+
"phf_generator 0.11.3",
53685463
"phf_shared 0.11.3",
53695464
"proc-macro2",
53705465
"quote",
@@ -5391,6 +5486,12 @@ version = "0.24.1"
53915486
source = "registry+https://github.com/rust-lang/crates.io-index"
53925487
checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f"
53935488

5489+
[[package]]
5490+
name = "strum"
5491+
version = "0.27.2"
5492+
source = "registry+https://github.com/rust-lang/crates.io-index"
5493+
checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf"
5494+
53945495
[[package]]
53955496
name = "strum_macros"
53965497
version = "0.24.3"
@@ -5404,6 +5505,18 @@ dependencies = [
54045505
"syn 1.0.109",
54055506
]
54065507

5508+
[[package]]
5509+
name = "strum_macros"
5510+
version = "0.27.2"
5511+
source = "registry+https://github.com/rust-lang/crates.io-index"
5512+
checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7"
5513+
dependencies = [
5514+
"heck 0.5.0",
5515+
"proc-macro2",
5516+
"quote",
5517+
"syn 2.0.110",
5518+
]
5519+
54075520
[[package]]
54085521
name = "syn"
54095522
version = "1.0.109"

compiler/rustc_resolve/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ edition = "2024"
77
# tidy-alphabetical-start
88
indexmap = "2.4.0"
99
itertools = "0.12"
10-
pulldown-cmark = { version = "0.11", features = ["html"], default-features = false }
10+
pulldown-cmark = { version = "0.13", features = ["html"], default-features = false }
1111
rustc_arena = { path = "../rustc_arena" }
1212
rustc_ast = { path = "../rustc_ast" }
1313
rustc_ast_pretty = { path = "../rustc_ast_pretty" }

compiler/rustc_resolve/src/rustdoc.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ pub fn main_body_opts() -> Options {
254254
| Options::ENABLE_STRIKETHROUGH
255255
| Options::ENABLE_TASKLISTS
256256
| Options::ENABLE_SMART_PUNCTUATION
257+
| Options::ENABLE_MATH
257258
}
258259

259260
fn strip_generics_from_path_segment(segment: Vec<char>) -> Result<Symbol, MalformedGenerics> {
@@ -403,7 +404,7 @@ pub fn may_be_doc_link(link_type: LinkType) -> bool {
403404
| LinkType::CollapsedUnknown
404405
| LinkType::Shortcut
405406
| LinkType::ShortcutUnknown => true,
406-
LinkType::Autolink | LinkType::Email => false,
407+
LinkType::Autolink | LinkType::Email | LinkType::WikiLink { .. } => false,
407408
}
408409
}
409410

src/bootstrap/src/utils/proc_macro_deps.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pub static CRATES: &[&str] = &[
1818
"derive_builder_core",
1919
"digest",
2020
"equivalent",
21+
"fastrand",
2122
"fluent-bundle",
2223
"fluent-langneg",
2324
"fluent-syntax",
@@ -37,6 +38,8 @@ pub static CRATES: &[&str] = &[
3738
"pest",
3839
"pest_generator",
3940
"pest_meta",
41+
"phf_generator",
42+
"phf_shared",
4043
"proc-macro2",
4144
"quote",
4245
"rustc-hash",
@@ -45,6 +48,7 @@ pub static CRATES: &[&str] = &[
4548
"serde_core",
4649
"serde_derive_internals",
4750
"sha2",
51+
"siphasher",
4852
"smallvec",
4953
"stable_deref_trait",
5054
"strsim",

src/librustdoc/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ askama = { version = "0.15.4", default-features = false, features = ["alloc", "c
1414
base64 = "0.21.7"
1515
indexmap = { version = "2", features = ["serde"] }
1616
itertools = "0.12"
17+
math-core = "0.2.2"
1718
minifier = { version = "0.3.5", default-features = false }
1819
proc-macro2 = "1.0.103"
1920
pulldown-cmark-escape = { version = "0.11.0", features = ["simd"] }

src/librustdoc/html/markdown.rs

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ use std::str::{self, CharIndices};
3636
use std::sync::atomic::AtomicUsize;
3737
use std::sync::{Arc, Weak};
3838

39+
use math_core::{LatexToMathML, MathCoreConfig, MathDisplay};
3940
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
4041
use rustc_errors::{Diag, DiagMessage};
4142
use rustc_hir::def_id::LocalDefId;
@@ -71,6 +72,7 @@ pub(crate) fn summary_opts() -> Options {
7172
| Options::ENABLE_STRIKETHROUGH
7273
| Options::ENABLE_TASKLISTS
7374
| Options::ENABLE_SMART_PUNCTUATION
75+
| Options::ENABLE_MATH
7476
}
7577

7678
#[derive(Debug, Clone, Copy)]
@@ -500,6 +502,51 @@ impl<'a, I: Iterator<Item = SpannedEvent<'a>>> Iterator for SpannedLinkReplacer<
500502
}
501503
}
502504

505+
/// Convert $\LaTeX$ math markup into MathML Core
506+
struct Math<'a, I: Iterator<Item = Event<'a>>> {
507+
inner: I,
508+
converter: LatexToMathML,
509+
}
510+
511+
impl<'a, I: Iterator<Item = Event<'a>>> Math<'a, I> {
512+
fn new(iter: I) -> Self {
513+
Self {
514+
inner: iter,
515+
converter: LatexToMathML::new(MathCoreConfig {
516+
pretty_print: math_core::PrettyPrint::Never,
517+
xml_namespace: false,
518+
..MathCoreConfig::default()
519+
})
520+
.expect("no custom macros are specified, so error should be impossible"),
521+
}
522+
}
523+
}
524+
525+
impl<'a, I: Iterator<Item = Event<'a>>> Iterator for Math<'a, I> {
526+
type Item = Event<'a>;
527+
528+
fn next(&mut self) -> Option<Self::Item> {
529+
match self.inner.next() {
530+
Some(Event::InlineMath(latex)) => {
531+
let mathml = self
532+
.converter
533+
.convert_with_local_counter(&latex, MathDisplay::Inline)
534+
.expect("a production-ready version of this should handle the error somehow");
535+
Some(Event::InlineHtml(mathml.into()))
536+
}
537+
Some(Event::DisplayMath(latex)) => {
538+
let mathml = self
539+
.converter
540+
.convert_with_local_counter(&latex, MathDisplay::Block)
541+
.expect("a production-ready version of this should handle the error somehow");
542+
// as counterintuitive as it might seem, block equations are still parsed as inline
543+
Some(Event::InlineHtml(mathml.into()))
544+
}
545+
event => event,
546+
}
547+
}
548+
}
549+
503550
/// Wrap HTML tables into `<div>` to prevent having the doc blocks width being too big.
504551
struct TableWrapper<'a, I: Iterator<Item = Event<'a>>> {
505552
inner: I,
@@ -624,7 +671,7 @@ fn check_if_allowed_tag(t: &TagEnd) -> bool {
624671
| TagEnd::Strong
625672
| TagEnd::Strikethrough
626673
| TagEnd::Link
627-
| TagEnd::BlockQuote
674+
| TagEnd::BlockQuote(..)
628675
)
629676
}
630677

@@ -1369,6 +1416,7 @@ impl<'a> Markdown<'a> {
13691416
let p = SpannedLinkReplacer::new(p, links);
13701417
let p = footnotes::Footnotes::new(p, existing_footnotes);
13711418
let p = TableWrapper::new(p.map(|(ev, _)| ev));
1419+
let p = Math::new(p);
13721420
CodeBlocks::new(p, codes, edition, playground)
13731421
})
13741422
}
@@ -1451,6 +1499,7 @@ impl MarkdownWithToc<'_> {
14511499
let p = footnotes::Footnotes::new(p, existing_footnotes);
14521500
let p = TableWrapper::new(p.map(|(ev, _)| ev));
14531501
let p = CodeBlocks::new(p, codes, edition, playground);
1502+
let p = Math::new(p);
14541503
html::push_html(&mut s, p);
14551504
});
14561505

@@ -1500,6 +1549,7 @@ impl<'a> MarkdownItemInfo<'a> {
15001549
let p = p.filter(|event| {
15011550
!matches!(event, Event::Start(Tag::Paragraph) | Event::End(TagEnd::Paragraph))
15021551
});
1552+
let p = Math::new(p);
15031553
html::write_html_fmt(&mut f, p)
15041554
})
15051555
}
@@ -1914,7 +1964,9 @@ pub(crate) fn markdown_links<'md, R>(
19141964
span_for_link(&dest_url, span)
19151965
}
19161966
}
1917-
LinkType::Autolink | LinkType::Email => unreachable!(),
1967+
LinkType::Autolink | LinkType::Email | LinkType::WikiLink { .. } => {
1968+
unreachable!()
1969+
}
19181970
};
19191971

19201972
if let Some(link) = preprocess_link(MarkdownLink {

0 commit comments

Comments
 (0)