Skip to content

Commit 89da870

Browse files
rustdoc: Add --highlight-foreign-code unstable flag
Gate the arborium-based syntax highlighting behind an unstable flag (-Z unstable-options --highlight-foreign-code) so it can be tested before becoming the default behavior. The flag is threaded through: - RenderOptions in config.rs - SharedContext in context.rs - Markdown/MarkdownWithToc structs in markdown.rs - CodeBlocks iterator for actual highlighting
1 parent 258a8ef commit 89da870

File tree

9 files changed

+60
-9
lines changed

9 files changed

+60
-9
lines changed

src/librustdoc/config.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,8 @@ pub(crate) struct RenderOptions {
312312
pub(crate) disable_minification: bool,
313313
/// If `true`, HTML source pages will generate the possibility to expand macros.
314314
pub(crate) generate_macro_expansion: bool,
315+
/// If `true`, non-Rust code blocks will be syntax-highlighted using tree-sitter.
316+
pub(crate) highlight_foreign_code: bool,
315317
}
316318

317319
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
@@ -805,6 +807,7 @@ impl Options {
805807
let no_capture = matches.opt_present("no-capture");
806808
let generate_link_to_definition = matches.opt_present("generate-link-to-definition");
807809
let generate_macro_expansion = matches.opt_present("generate-macro-expansion");
810+
let highlight_foreign_code = matches.opt_present("highlight-foreign-code");
808811
let extern_html_root_takes_precedence =
809812
matches.opt_present("extern-html-root-takes-precedence");
810813
let html_no_source = matches.opt_present("html-no-source");
@@ -916,6 +919,7 @@ impl Options {
916919
include_parts_dir,
917920
parts_out_dir,
918921
disable_minification,
922+
highlight_foreign_code,
919923
};
920924
Some((input, options, render_options, loaded_paths))
921925
}

src/librustdoc/externalfiles.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ impl ExternalHtml {
4747
edition,
4848
playground,
4949
heading_offset: HeadingOffset::H2,
50+
highlight_foreign_code: false,
5051
}
5152
.write_into(&mut bc)
5253
.unwrap();
@@ -63,6 +64,7 @@ impl ExternalHtml {
6364
edition,
6465
playground,
6566
heading_offset: HeadingOffset::H2,
67+
highlight_foreign_code: false,
6668
}
6769
.write_into(&mut ac)
6870
.unwrap();

src/librustdoc/html/markdown.rs

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
//! edition: Edition::Edition2015,
2121
//! playground: &None,
2222
//! heading_offset: HeadingOffset::H2,
23+
//! highlight_foreign_code: false,
2324
//! };
2425
//! let mut html = String::new();
2526
//! md.write_into(&mut html).unwrap();
@@ -99,6 +100,8 @@ pub struct Markdown<'a> {
99100
/// Offset at which we render headings.
100101
/// E.g. if `heading_offset: HeadingOffset::H2`, then `# something` renders an `<h2>`.
101102
pub heading_offset: HeadingOffset,
103+
/// Whether to syntax-highlight non-Rust code blocks using tree-sitter.
104+
pub highlight_foreign_code: bool,
102105
}
103106
/// A struct like `Markdown` that renders the markdown with a table of contents.
104107
pub(crate) struct MarkdownWithToc<'a> {
@@ -108,6 +111,7 @@ pub(crate) struct MarkdownWithToc<'a> {
108111
pub(crate) error_codes: ErrorCodes,
109112
pub(crate) edition: Edition,
110113
pub(crate) playground: &'a Option<Playground>,
114+
pub(crate) highlight_foreign_code: bool,
111115
}
112116
/// A tuple struct like `Markdown` that renders the markdown escaping HTML tags
113117
/// and includes no paragraph tags.
@@ -210,6 +214,8 @@ struct CodeBlocks<'p, 'a, I: Iterator<Item = Event<'a>>> {
210214
// Information about the playground if a URL has been specified, containing an
211215
// optional crate name and the URL.
212216
playground: &'p Option<Playground>,
217+
// Whether to use tree-sitter highlighting for non-Rust code blocks.
218+
highlight_foreign_code: bool,
213219
}
214220

215221
impl<'p, 'a, I: Iterator<Item = Event<'a>>> CodeBlocks<'p, 'a, I> {
@@ -218,8 +224,15 @@ impl<'p, 'a, I: Iterator<Item = Event<'a>>> CodeBlocks<'p, 'a, I> {
218224
error_codes: ErrorCodes,
219225
edition: Edition,
220226
playground: &'p Option<Playground>,
227+
highlight_foreign_code: bool,
221228
) -> Self {
222-
CodeBlocks { inner: iter, check_error_codes: error_codes, edition, playground }
229+
CodeBlocks {
230+
inner: iter,
231+
check_error_codes: error_codes,
232+
edition,
233+
playground,
234+
highlight_foreign_code,
235+
}
223236
}
224237
}
225238

@@ -254,14 +267,17 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
254267
let lang_string = lang.map(|l| format!("language-{l}")).unwrap_or_default();
255268
let whitespace = if added_classes.is_empty() { "" } else { " " };
256269

257-
// Try to highlight with arborium if we have a language
258-
let code_html = lang
259-
.and_then(|l| {
270+
// Try to highlight with arborium if enabled and we have a language
271+
let code_html = if self.highlight_foreign_code {
272+
lang.and_then(|l| {
260273
highlight::highlight_foreign_code(l, original_text.trim_suffix('\n'))
261274
})
262275
.unwrap_or_else(|| {
263276
Escape(original_text.trim_suffix('\n')).to_string()
264-
});
277+
})
278+
} else {
279+
Escape(original_text.trim_suffix('\n')).to_string()
280+
};
265281

266282
return Some(Event::Html(
267283
format!(
@@ -1354,6 +1370,7 @@ impl<'a> Markdown<'a> {
13541370
edition,
13551371
playground,
13561372
heading_offset,
1373+
highlight_foreign_code,
13571374
} = self;
13581375

13591376
let replacer = move |broken_link: BrokenLink<'_>| {
@@ -1371,7 +1388,7 @@ impl<'a> Markdown<'a> {
13711388
let p = SpannedLinkReplacer::new(p, links);
13721389
let p = footnotes::Footnotes::new(p, existing_footnotes);
13731390
let p = TableWrapper::new(p.map(|(ev, _)| ev));
1374-
CodeBlocks::new(p, codes, edition, playground)
1391+
CodeBlocks::new(p, codes, edition, playground, highlight_foreign_code)
13751392
})
13761393
}
13771394

@@ -1427,8 +1444,15 @@ impl<'a> Markdown<'a> {
14271444

14281445
impl MarkdownWithToc<'_> {
14291446
pub(crate) fn into_parts(self) -> (Toc, String) {
1430-
let MarkdownWithToc { content: md, links, ids, error_codes: codes, edition, playground } =
1431-
self;
1447+
let MarkdownWithToc {
1448+
content: md,
1449+
links,
1450+
ids,
1451+
error_codes: codes,
1452+
edition,
1453+
playground,
1454+
highlight_foreign_code,
1455+
} = self;
14321456

14331457
// This is actually common enough to special-case
14341458
if md.is_empty() {
@@ -1452,7 +1476,7 @@ impl MarkdownWithToc<'_> {
14521476
let p = HeadingLinks::new(p, Some(&mut toc), ids, HeadingOffset::H1);
14531477
let p = footnotes::Footnotes::new(p, existing_footnotes);
14541478
let p = TableWrapper::new(p.map(|(ev, _)| ev));
1455-
let p = CodeBlocks::new(p, codes, edition, playground);
1479+
let p = CodeBlocks::new(p, codes, edition, playground, highlight_foreign_code);
14561480
html::push_html(&mut s, p);
14571481
});
14581482

src/librustdoc/html/markdown/tests.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ fn test_header() {
306306
edition: DEFAULT_EDITION,
307307
playground: &None,
308308
heading_offset: HeadingOffset::H2,
309+
highlight_foreign_code: false,
309310
}
310311
.write_into(&mut output)
311312
.unwrap();
@@ -359,6 +360,7 @@ fn test_header_ids_multiple_blocks() {
359360
edition: DEFAULT_EDITION,
360361
playground: &None,
361362
heading_offset: HeadingOffset::H2,
363+
highlight_foreign_code: false,
362364
}
363365
.write_into(&mut output)
364366
.unwrap();
@@ -510,6 +512,7 @@ fn test_ascii_with_prepending_hashtag() {
510512
edition: DEFAULT_EDITION,
511513
playground: &None,
512514
heading_offset: HeadingOffset::H2,
515+
highlight_foreign_code: false,
513516
}
514517
.write_into(&mut output)
515518
.unwrap();

src/librustdoc/html/render/context.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ pub(crate) struct SharedContext<'tcx> {
150150
/// Controls whether we read / write to cci files in the doc root. Defaults read=true,
151151
/// write=true
152152
should_merge: ShouldMerge,
153+
/// Whether to syntax-highlight non-Rust code blocks using tree-sitter.
154+
pub(super) highlight_foreign_code: bool,
153155
}
154156

155157
impl SharedContext<'_> {
@@ -495,6 +497,7 @@ impl<'tcx> Context<'tcx> {
495497
call_locations,
496498
no_emit_shared,
497499
html_no_source,
500+
highlight_foreign_code,
498501
..
499502
} = options;
500503

@@ -580,6 +583,7 @@ impl<'tcx> Context<'tcx> {
580583
call_locations,
581584
should_merge: options.should_merge,
582585
expanded_codes,
586+
highlight_foreign_code,
583587
};
584588

585589
let dst = output;

src/librustdoc/html/render/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,7 @@ fn scrape_examples_help(shared: &SharedContext<'_>) -> String {
651651
edition: shared.edition(),
652652
playground: &shared.playground,
653653
heading_offset: HeadingOffset::H1,
654+
highlight_foreign_code: shared.highlight_foreign_code,
654655
}
655656
.write_into(f))
656657
)
@@ -693,6 +694,7 @@ fn render_markdown(
693694
edition: cx.shared.edition(),
694695
playground: &cx.shared.playground,
695696
heading_offset,
697+
highlight_foreign_code: cx.shared.highlight_foreign_code,
696698
}
697699
.write_into(&mut *f)?;
698700
f.write_str("</div>")
@@ -2164,6 +2166,7 @@ fn render_impl(
21642166
edition: cx.shared.edition(),
21652167
playground: &cx.shared.playground,
21662168
heading_offset: HeadingOffset::H4,
2169+
highlight_foreign_code: cx.shared.highlight_foreign_code,
21672170
}
21682171
.split_summary_and_content()
21692172
})

src/librustdoc/html/render/sidebar.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ fn docblock_toc<'a>(
229229
error_codes: cx.shared.codes,
230230
edition: cx.shared.edition(),
231231
playground: &cx.shared.playground,
232+
highlight_foreign_code: cx.shared.highlight_foreign_code,
232233
}
233234
.into_parts();
234235
let links: Vec<Link<'_>> = toc

src/librustdoc/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,14 @@ fn opts() -> Vec<RustcOptGroup> {
654654
"Add possibility to expand macros in the HTML source code pages",
655655
"",
656656
),
657+
opt(
658+
Unstable,
659+
Flag,
660+
"",
661+
"highlight-foreign-code",
662+
"Syntax-highlight non-Rust code blocks using tree-sitter (arborium)",
663+
"",
664+
),
657665
// deprecated / removed options
658666
opt(
659667
Stable,

src/librustdoc/markdown.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ pub(crate) fn render_and_write<P: AsRef<Path>>(
8787
error_codes,
8888
edition,
8989
playground: &playground,
90+
highlight_foreign_code: options.highlight_foreign_code,
9091
}
9192
.write_into(f)
9293
} else {
@@ -98,6 +99,7 @@ pub(crate) fn render_and_write<P: AsRef<Path>>(
9899
edition,
99100
playground: &playground,
100101
heading_offset: HeadingOffset::H1,
102+
highlight_foreign_code: options.highlight_foreign_code,
101103
}
102104
.write_into(f)
103105
}

0 commit comments

Comments
 (0)