2020//! edition: Edition::Edition2015,
2121//! playground: &None,
2222//! heading_offset: HeadingOffset::H2,
23+ //! custom_code_classes_in_docs: true,
2324//! };
2425//! let html = md.into_string();
2526//! // ... something using html
@@ -95,6 +96,8 @@ pub struct Markdown<'a> {
9596 /// Offset at which we render headings.
9697 /// E.g. if `heading_offset: HeadingOffset::H2`, then `# something` renders an `<h2>`.
9798 pub heading_offset : HeadingOffset ,
99+ /// `true` if the `custom_code_classes_in_docs` feature is enabled.
100+ pub custom_code_classes_in_docs : bool ,
98101}
99102/// A struct like `Markdown` that renders the markdown with a table of contents.
100103pub ( crate ) struct MarkdownWithToc < ' a > {
@@ -103,6 +106,8 @@ pub(crate) struct MarkdownWithToc<'a> {
103106 pub ( crate ) error_codes : ErrorCodes ,
104107 pub ( crate ) edition : Edition ,
105108 pub ( crate ) playground : & ' a Option < Playground > ,
109+ /// `true` if the `custom_code_classes_in_docs` feature is enabled.
110+ pub ( crate ) custom_code_classes_in_docs : bool ,
106111}
107112/// A tuple struct like `Markdown` that renders the markdown escaping HTML tags
108113/// and includes no paragraph tags.
@@ -203,6 +208,7 @@ struct CodeBlocks<'p, 'a, I: Iterator<Item = Event<'a>>> {
203208 // Information about the playground if a URL has been specified, containing an
204209 // optional crate name and the URL.
205210 playground : & ' p Option < Playground > ,
211+ custom_code_classes_in_docs : bool ,
206212}
207213
208214impl < ' p , ' a , I : Iterator < Item = Event < ' a > > > CodeBlocks < ' p , ' a , I > {
@@ -211,8 +217,15 @@ impl<'p, 'a, I: Iterator<Item = Event<'a>>> CodeBlocks<'p, 'a, I> {
211217 error_codes : ErrorCodes ,
212218 edition : Edition ,
213219 playground : & ' p Option < Playground > ,
220+ custom_code_classes_in_docs : bool ,
214221 ) -> Self {
215- CodeBlocks { inner : iter, check_error_codes : error_codes, edition, playground }
222+ CodeBlocks {
223+ inner : iter,
224+ check_error_codes : error_codes,
225+ edition,
226+ playground,
227+ custom_code_classes_in_docs,
228+ }
216229 }
217230}
218231
@@ -242,8 +255,12 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
242255
243256 let parse_result = match kind {
244257 CodeBlockKind :: Fenced ( ref lang) => {
245- let parse_result =
246- LangString :: parse_without_check ( lang, self . check_error_codes , false ) ;
258+ let parse_result = LangString :: parse_without_check (
259+ lang,
260+ self . check_error_codes ,
261+ false ,
262+ self . custom_code_classes_in_docs ,
263+ ) ;
247264 if !parse_result. rust {
248265 let added_classes = parse_result. added_classes ;
249266 let lang_string = if let Some ( lang) = parse_result. unknown . first ( ) {
@@ -725,8 +742,17 @@ pub(crate) fn find_testable_code<T: doctest::Tester>(
725742 error_codes : ErrorCodes ,
726743 enable_per_target_ignores : bool ,
727744 extra_info : Option < & ExtraInfo < ' _ > > ,
745+ custom_code_classes_in_docs : bool ,
728746) {
729- find_codes ( doc, tests, error_codes, enable_per_target_ignores, extra_info, false )
747+ find_codes (
748+ doc,
749+ tests,
750+ error_codes,
751+ enable_per_target_ignores,
752+ extra_info,
753+ false ,
754+ custom_code_classes_in_docs,
755+ )
730756}
731757
732758pub ( crate ) fn find_codes < T : doctest:: Tester > (
@@ -736,6 +762,7 @@ pub(crate) fn find_codes<T: doctest::Tester>(
736762 enable_per_target_ignores : bool ,
737763 extra_info : Option < & ExtraInfo < ' _ > > ,
738764 include_non_rust : bool ,
765+ custom_code_classes_in_docs : bool ,
739766) {
740767 let mut parser = Parser :: new ( doc) . into_offset_iter ( ) ;
741768 let mut prev_offset = 0 ;
@@ -754,6 +781,7 @@ pub(crate) fn find_codes<T: doctest::Tester>(
754781 error_codes,
755782 enable_per_target_ignores,
756783 extra_info,
784+ custom_code_classes_in_docs,
757785 )
758786 }
759787 }
@@ -1153,15 +1181,23 @@ impl LangString {
11531181 string : & str ,
11541182 allow_error_code_check : ErrorCodes ,
11551183 enable_per_target_ignores : bool ,
1184+ custom_code_classes_in_docs : bool ,
11561185 ) -> Self {
1157- Self :: parse ( string, allow_error_code_check, enable_per_target_ignores, None )
1186+ Self :: parse (
1187+ string,
1188+ allow_error_code_check,
1189+ enable_per_target_ignores,
1190+ None ,
1191+ custom_code_classes_in_docs,
1192+ )
11581193 }
11591194
11601195 fn parse (
11611196 string : & str ,
11621197 allow_error_code_check : ErrorCodes ,
11631198 enable_per_target_ignores : bool ,
11641199 extra : Option < & ExtraInfo < ' _ > > ,
1200+ custom_code_classes_in_docs : bool ,
11651201 ) -> Self {
11661202 let allow_error_code_check = allow_error_code_check. as_bool ( ) ;
11671203 let mut seen_rust_tags = false ;
@@ -1197,7 +1233,11 @@ impl LangString {
11971233 seen_rust_tags = true ;
11981234 }
11991235 LangStringToken :: LangToken ( "custom" ) => {
1200- seen_custom_tag = true ;
1236+ if custom_code_classes_in_docs {
1237+ seen_custom_tag = true ;
1238+ } else {
1239+ seen_other_tags = true ;
1240+ }
12011241 }
12021242 LangStringToken :: LangToken ( "test_harness" ) => {
12031243 data. test_harness = true ;
@@ -1268,11 +1308,16 @@ impl LangString {
12681308 data. unknown . push ( x. to_owned ( ) ) ;
12691309 }
12701310 LangStringToken :: KeyValueAttribute ( key, value) => {
1271- if key == "class" {
1272- data. added_classes . push ( value. to_owned ( ) ) ;
1273- } else if let Some ( extra) = extra {
1274- extra
1275- . error_invalid_codeblock_attr ( format ! ( "unsupported attribute `{key}`" ) ) ;
1311+ if custom_code_classes_in_docs {
1312+ if key == "class" {
1313+ data. added_classes . push ( value. to_owned ( ) ) ;
1314+ } else if let Some ( extra) = extra {
1315+ extra. error_invalid_codeblock_attr ( format ! (
1316+ "unsupported attribute `{key}`"
1317+ ) ) ;
1318+ }
1319+ } else {
1320+ seen_other_tags = true ;
12761321 }
12771322 }
12781323 LangStringToken :: ClassAttribute ( class) => {
@@ -1302,6 +1347,7 @@ impl Markdown<'_> {
13021347 edition,
13031348 playground,
13041349 heading_offset,
1350+ custom_code_classes_in_docs,
13051351 } = self ;
13061352
13071353 // This is actually common enough to special-case
@@ -1324,7 +1370,7 @@ impl Markdown<'_> {
13241370 let p = Footnotes :: new ( p) ;
13251371 let p = LinkReplacer :: new ( p. map ( |( ev, _) | ev) , links) ;
13261372 let p = TableWrapper :: new ( p) ;
1327- let p = CodeBlocks :: new ( p, codes, edition, playground) ;
1373+ let p = CodeBlocks :: new ( p, codes, edition, playground, custom_code_classes_in_docs ) ;
13281374 html:: push_html ( & mut s, p) ;
13291375
13301376 s
@@ -1333,7 +1379,14 @@ impl Markdown<'_> {
13331379
13341380impl MarkdownWithToc < ' _ > {
13351381 pub ( crate ) fn into_string ( self ) -> String {
1336- let MarkdownWithToc { content : md, ids, error_codes : codes, edition, playground } = self ;
1382+ let MarkdownWithToc {
1383+ content : md,
1384+ ids,
1385+ error_codes : codes,
1386+ edition,
1387+ playground,
1388+ custom_code_classes_in_docs,
1389+ } = self ;
13371390
13381391 let p = Parser :: new_ext ( md, main_body_opts ( ) ) . into_offset_iter ( ) ;
13391392
@@ -1345,7 +1398,7 @@ impl MarkdownWithToc<'_> {
13451398 let p = HeadingLinks :: new ( p, Some ( & mut toc) , ids, HeadingOffset :: H1 ) ;
13461399 let p = Footnotes :: new ( p) ;
13471400 let p = TableWrapper :: new ( p. map ( |( ev, _) | ev) ) ;
1348- let p = CodeBlocks :: new ( p, codes, edition, playground) ;
1401+ let p = CodeBlocks :: new ( p, codes, edition, playground, custom_code_classes_in_docs ) ;
13491402 html:: push_html ( & mut s, p) ;
13501403 }
13511404
@@ -1786,7 +1839,11 @@ pub(crate) struct RustCodeBlock {
17861839
17871840/// Returns a range of bytes for each code block in the markdown that is tagged as `rust` or
17881841/// untagged (and assumed to be rust).
1789- pub ( crate ) fn rust_code_blocks ( md : & str , extra_info : & ExtraInfo < ' _ > ) -> Vec < RustCodeBlock > {
1842+ pub ( crate ) fn rust_code_blocks (
1843+ md : & str ,
1844+ extra_info : & ExtraInfo < ' _ > ,
1845+ custom_code_classes_in_docs : bool ,
1846+ ) -> Vec < RustCodeBlock > {
17901847 let mut code_blocks = vec ! [ ] ;
17911848
17921849 if md. is_empty ( ) {
@@ -1803,7 +1860,13 @@ pub(crate) fn rust_code_blocks(md: &str, extra_info: &ExtraInfo<'_>) -> Vec<Rust
18031860 let lang_string = if syntax. is_empty ( ) {
18041861 Default :: default ( )
18051862 } else {
1806- LangString :: parse ( & * syntax, ErrorCodes :: Yes , false , Some ( extra_info) )
1863+ LangString :: parse (
1864+ & * syntax,
1865+ ErrorCodes :: Yes ,
1866+ false ,
1867+ Some ( extra_info) ,
1868+ custom_code_classes_in_docs,
1869+ )
18071870 } ;
18081871 if !lang_string. rust {
18091872 continue ;
0 commit comments