]> git.lizzy.rs Git - rust.git/commitdiff
[rustdoc] Wrap code blocks in <code> tag
authorJakub Beránek <berykubik@gmail.com>
Mon, 16 Aug 2021 21:19:00 +0000 (23:19 +0200)
committerJakub Beránek <berykubik@gmail.com>
Thu, 19 Aug 2021 08:30:08 +0000 (10:30 +0200)
src/librustdoc/html/highlight.rs
src/librustdoc/html/markdown.rs
src/librustdoc/html/render/print_item.rs
src/librustdoc/html/static/css/rustdoc.css
src/test/rustdoc-gui/code-tags.goml [new file with mode: 0644]
src/test/rustdoc-gui/source-code-page.goml

index 3cdb1352bef956045502b1d557e4d49ffe2c7209..f8fc9243e14b95891549e9dd1b835f2e42cded95 100644 (file)
@@ -65,10 +65,11 @@ fn write_header(out: &mut Buffer, class: Option<&str>, extra_content: Option<Buf
         out.push_buffer(extra);
     }
     if let Some(class) = class {
-        writeln!(out, "<pre class=\"rust {}\">", class);
+        write!(out, "<pre class=\"rust {}\">", class);
     } else {
-        writeln!(out, "<pre class=\"rust\">");
+        write!(out, "<pre class=\"rust\">");
     }
+    write!(out, "<code>");
 }
 
 /// Convert the given `src` source code into HTML by adding classes for highlighting.
@@ -101,7 +102,7 @@ fn write_code(
 }
 
 fn write_footer(out: &mut Buffer, playground_button: Option<&str>) {
-    writeln!(out, "</pre>{}</div>", playground_button.unwrap_or_default());
+    writeln!(out, "</code></pre>{}</div>", playground_button.unwrap_or_default());
 }
 
 /// How a span of text is classified. Mostly corresponds to token kinds.
index 472323daf3017ae594eebe2a42b091a0cd505f98..7c6d7dff816d539ed77a69521fca2df775dbfa36 100644 (file)
@@ -234,7 +234,7 @@ fn next(&mut self) -> Option<Self::Item> {
                     return Some(Event::Html(
                         format!(
                             "<div class=\"example-wrap\">\
-                                 <pre class=\"language-{}\">{}</pre>\
+                                 <pre class=\"language-{}\"><code>{}</code></pre>\
                              </div>",
                             lang,
                             Escape(&text),
index f31305c76e642582b3306cdd3d07f1b02d5ba526..c1d95c8c252ade1f306351e4ecd1790321d829ed 100644 (file)
@@ -455,24 +455,25 @@ fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean::
         + name.as_str().len()
         + generics_len;
 
-    w.write_str("<pre class=\"rust fn\">");
-    render_attributes_in_pre(w, it, "");
-    w.reserve(header_len);
-    write!(
-        w,
-        "{vis}{constness}{asyncness}{unsafety}{abi}fn \
-         {name}{generics}{decl}{notable_traits}{where_clause}</pre>",
-        vis = vis,
-        constness = constness,
-        asyncness = asyncness,
-        unsafety = unsafety,
-        abi = abi,
-        name = name,
-        generics = f.generics.print(cx),
-        where_clause = print_where_clause(&f.generics, cx, 0, true),
-        decl = f.decl.full_print(header_len, 0, f.header.asyncness, cx),
-        notable_traits = notable_traits_decl(&f.decl, cx),
-    );
+    wrap_item(w, "fn", |w| {
+        render_attributes_in_pre(w, it, "");
+        w.reserve(header_len);
+        write!(
+            w,
+            "{vis}{constness}{asyncness}{unsafety}{abi}fn \
+             {name}{generics}{decl}{notable_traits}{where_clause}",
+            vis = vis,
+            constness = constness,
+            asyncness = asyncness,
+            unsafety = unsafety,
+            abi = abi,
+            name = name,
+            generics = f.generics.print(cx),
+            where_clause = print_where_clause(&f.generics, cx, 0, true),
+            decl = f.decl.full_print(header_len, 0, f.header.asyncness, cx),
+            notable_traits = notable_traits_decl(&f.decl, cx),
+        );
+    });
     document(w, cx, it, None)
 }
 
@@ -488,108 +489,111 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
 
     // Output the trait definition
     wrap_into_docblock(w, |w| {
-        w.write_str("<pre class=\"rust trait\">");
-        render_attributes_in_pre(w, it, "");
-        write!(
-            w,
-            "{}{}{}trait {}{}{}",
-            it.visibility.print_with_space(it.def_id, cx),
-            t.unsafety.print_with_space(),
-            if t.is_auto { "auto " } else { "" },
-            it.name.as_ref().unwrap(),
-            t.generics.print(cx),
-            bounds
-        );
-
-        if !t.generics.where_predicates.is_empty() {
-            write!(w, "{}", print_where_clause(&t.generics, cx, 0, true));
-        } else {
-            w.write_str(" ");
-        }
+        wrap_item(w, "trait", |w| {
+            render_attributes_in_pre(w, it, "");
+            write!(
+                w,
+                "{}{}{}trait {}{}{}",
+                it.visibility.print_with_space(it.def_id, cx),
+                t.unsafety.print_with_space(),
+                if t.is_auto { "auto " } else { "" },
+                it.name.as_ref().unwrap(),
+                t.generics.print(cx),
+                bounds
+            );
 
-        if t.items.is_empty() {
-            w.write_str("{ }");
-        } else {
-            // FIXME: we should be using a derived_id for the Anchors here
-            w.write_str("{\n");
-            let mut toggle = false;
-
-            // If there are too many associated types, hide _everything_
-            if should_hide_fields(count_types) {
-                toggle = true;
-                toggle_open(
-                    w,
-                    format_args!("{} associated items", count_types + count_consts + count_methods),
-                );
-            }
-            for t in &types {
-                render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait, cx);
-                w.write_str(";\n");
-            }
-            // If there are too many associated constants, hide everything after them
-            // We also do this if the types + consts is large because otherwise we could
-            // render a bunch of types and _then_ a bunch of consts just because both were
-            // _just_ under the limit
-            if !toggle && should_hide_fields(count_types + count_consts) {
-                toggle = true;
-                toggle_open(
-                    w,
-                    format_args!(
-                        "{} associated constant{} and {} method{}",
-                        count_consts,
-                        pluralize(count_consts),
-                        count_methods,
-                        pluralize(count_methods),
-                    ),
-                );
-            }
-            if !types.is_empty() && !consts.is_empty() {
-                w.write_str("\n");
-            }
-            for t in &consts {
-                render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait, cx);
-                w.write_str(";\n");
-            }
-            if !toggle && should_hide_fields(count_methods) {
-                toggle = true;
-                toggle_open(w, format_args!("{} methods", count_methods));
-            }
-            if !consts.is_empty() && !required.is_empty() {
-                w.write_str("\n");
+            if !t.generics.where_predicates.is_empty() {
+                write!(w, "{}", print_where_clause(&t.generics, cx, 0, true));
+            } else {
+                w.write_str(" ");
             }
-            for (pos, m) in required.iter().enumerate() {
-                render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait, cx);
-                w.write_str(";\n");
 
-                if pos < required.len() - 1 {
-                    w.write_str("<div class=\"item-spacer\"></div>");
+            if t.items.is_empty() {
+                w.write_str("{ }");
+            } else {
+                // FIXME: we should be using a derived_id for the Anchors here
+                w.write_str("{\n");
+                let mut toggle = false;
+
+                // If there are too many associated types, hide _everything_
+                if should_hide_fields(count_types) {
+                    toggle = true;
+                    toggle_open(
+                        w,
+                        format_args!(
+                            "{} associated items",
+                            count_types + count_consts + count_methods
+                        ),
+                    );
                 }
-            }
-            if !required.is_empty() && !provided.is_empty() {
-                w.write_str("\n");
-            }
-            for (pos, m) in provided.iter().enumerate() {
-                render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait, cx);
-                match *m.kind {
-                    clean::MethodItem(ref inner, _)
-                        if !inner.generics.where_predicates.is_empty() =>
-                    {
-                        w.write_str(",\n    { ... }\n");
+                for t in &types {
+                    render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait, cx);
+                    w.write_str(";\n");
+                }
+                // If there are too many associated constants, hide everything after them
+                // We also do this if the types + consts is large because otherwise we could
+                // render a bunch of types and _then_ a bunch of consts just because both were
+                // _just_ under the limit
+                if !toggle && should_hide_fields(count_types + count_consts) {
+                    toggle = true;
+                    toggle_open(
+                        w,
+                        format_args!(
+                            "{} associated constant{} and {} method{}",
+                            count_consts,
+                            pluralize(count_consts),
+                            count_methods,
+                            pluralize(count_methods),
+                        ),
+                    );
+                }
+                if !types.is_empty() && !consts.is_empty() {
+                    w.write_str("\n");
+                }
+                for t in &consts {
+                    render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait, cx);
+                    w.write_str(";\n");
+                }
+                if !toggle && should_hide_fields(count_methods) {
+                    toggle = true;
+                    toggle_open(w, format_args!("{} methods", count_methods));
+                }
+                if !consts.is_empty() && !required.is_empty() {
+                    w.write_str("\n");
+                }
+                for (pos, m) in required.iter().enumerate() {
+                    render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait, cx);
+                    w.write_str(";\n");
+
+                    if pos < required.len() - 1 {
+                        w.write_str("<div class=\"item-spacer\"></div>");
                     }
-                    _ => {
-                        w.write_str(" { ... }\n");
+                }
+                if !required.is_empty() && !provided.is_empty() {
+                    w.write_str("\n");
+                }
+                for (pos, m) in provided.iter().enumerate() {
+                    render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait, cx);
+                    match *m.kind {
+                        clean::MethodItem(ref inner, _)
+                            if !inner.generics.where_predicates.is_empty() =>
+                        {
+                            w.write_str(",\n    { ... }\n");
+                        }
+                        _ => {
+                            w.write_str(" { ... }\n");
+                        }
+                    }
+                    if pos < provided.len() - 1 {
+                        w.write_str("<div class=\"item-spacer\"></div>");
                     }
                 }
-                if pos < provided.len() - 1 {
-                    w.write_str("<div class=\"item-spacer\"></div>");
+                if toggle {
+                    toggle_close(w);
                 }
+                w.write_str("}");
             }
-            if toggle {
-                toggle_close(w);
-            }
-            w.write_str("}");
-        }
-        w.write_str("</pre>")
+        });
     });
 
     // Trait documentation
@@ -812,16 +816,17 @@ fn trait_item(w: &mut Buffer, cx: &Context<'_>, m: &clean::Item, t: &clean::Item
 }
 
 fn item_trait_alias(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::TraitAlias) {
-    w.write_str("<pre class=\"rust trait-alias\">");
-    render_attributes_in_pre(w, it, "");
-    write!(
-        w,
-        "trait {}{}{} = {};</pre>",
-        it.name.as_ref().unwrap(),
-        t.generics.print(cx),
-        print_where_clause(&t.generics, cx, 0, true),
-        bounds(&t.bounds, true, cx)
-    );
+    wrap_item(w, "trait-alias", |w| {
+        render_attributes_in_pre(w, it, "");
+        write!(
+            w,
+            "trait {}{}{} = {};",
+            it.name.as_ref().unwrap(),
+            t.generics.print(cx),
+            print_where_clause(&t.generics, cx, 0, true),
+            bounds(&t.bounds, true, cx)
+        );
+    });
 
     document(w, cx, it, None);
 
@@ -833,16 +838,17 @@ fn item_trait_alias(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clea
 }
 
 fn item_opaque_ty(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::OpaqueTy) {
-    w.write_str("<pre class=\"rust opaque\">");
-    render_attributes_in_pre(w, it, "");
-    write!(
-        w,
-        "type {}{}{where_clause} = impl {bounds};</pre>",
-        it.name.as_ref().unwrap(),
-        t.generics.print(cx),
-        where_clause = print_where_clause(&t.generics, cx, 0, true),
-        bounds = bounds(&t.bounds, false, cx),
-    );
+    wrap_item(w, "opaque", |w| {
+        render_attributes_in_pre(w, it, "");
+        write!(
+            w,
+            "type {}{}{where_clause} = impl {bounds};",
+            it.name.as_ref().unwrap(),
+            t.generics.print(cx),
+            where_clause = print_where_clause(&t.generics, cx, 0, true),
+            bounds = bounds(&t.bounds, false, cx),
+        );
+    });
 
     document(w, cx, it, None);
 
@@ -860,19 +866,20 @@ fn item_typedef(
     t: &clean::Typedef,
     is_associated: bool,
 ) {
-    w.write_str("<pre class=\"rust typedef\">");
-    render_attributes_in_pre(w, it, "");
-    if !is_associated {
-        write!(w, "{}", it.visibility.print_with_space(it.def_id, cx));
-    }
-    write!(
-        w,
-        "type {}{}{where_clause} = {type_};</pre>",
-        it.name.as_ref().unwrap(),
-        t.generics.print(cx),
-        where_clause = print_where_clause(&t.generics, cx, 0, true),
-        type_ = t.type_.print(cx),
-    );
+    wrap_item(w, "typedef", |w| {
+        render_attributes_in_pre(w, it, "");
+        if !is_associated {
+            write!(w, "{}", it.visibility.print_with_space(it.def_id, cx));
+        }
+        write!(
+            w,
+            "type {}{}{where_clause} = {type_};",
+            it.name.as_ref().unwrap(),
+            t.generics.print(cx),
+            where_clause = print_where_clause(&t.generics, cx, 0, true),
+            type_ = t.type_.print(cx),
+        );
+    });
 
     document(w, cx, it, None);
 
@@ -886,10 +893,10 @@ fn item_typedef(
 
 fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Union) {
     wrap_into_docblock(w, |w| {
-        w.write_str("<pre class=\"rust union\">");
-        render_attributes_in_pre(w, it, "");
-        render_union(w, it, Some(&s.generics), &s.fields, "", cx);
-        w.write_str("</pre>")
+        wrap_item(w, "union", |w| {
+            render_attributes_in_pre(w, it, "");
+            render_union(w, it, Some(&s.generics), &s.fields, "", cx);
+        });
     });
 
     document(w, cx, it, None);
@@ -935,59 +942,68 @@ fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Uni
 
 fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum) {
     wrap_into_docblock(w, |w| {
-        w.write_str("<pre class=\"rust enum\">");
-        render_attributes_in_pre(w, it, "");
-        write!(
-            w,
-            "{}enum {}{}{}",
-            it.visibility.print_with_space(it.def_id, cx),
-            it.name.as_ref().unwrap(),
-            e.generics.print(cx),
-            print_where_clause(&e.generics, cx, 0, true),
-        );
-        if e.variants.is_empty() && !e.variants_stripped {
-            w.write_str(" {}");
-        } else {
-            w.write_str(" {\n");
-            let count_variants = e.variants.len();
-            let toggle = should_hide_fields(count_variants);
-            if toggle {
-                toggle_open(w, format_args!("{} variants", count_variants));
-            }
-            for v in &e.variants {
-                w.write_str("    ");
-                let name = v.name.as_ref().unwrap();
-                match *v.kind {
-                    clean::VariantItem(ref var) => match var {
-                        clean::Variant::CLike => write!(w, "{}", name),
-                        clean::Variant::Tuple(ref tys) => {
-                            write!(w, "{}(", name);
-                            for (i, ty) in tys.iter().enumerate() {
-                                if i > 0 {
-                                    w.write_str(",&nbsp;")
+        wrap_item(w, "enum", |w| {
+            render_attributes_in_pre(w, it, "");
+            write!(
+                w,
+                "{}enum {}{}{}",
+                it.visibility.print_with_space(it.def_id, cx),
+                it.name.as_ref().unwrap(),
+                e.generics.print(cx),
+                print_where_clause(&e.generics, cx, 0, true),
+            );
+            if e.variants.is_empty() && !e.variants_stripped {
+                w.write_str(" {}");
+            } else {
+                w.write_str(" {\n");
+                let count_variants = e.variants.len();
+                let toggle = should_hide_fields(count_variants);
+                if toggle {
+                    toggle_open(w, format_args!("{} variants", count_variants));
+                }
+                for v in &e.variants {
+                    w.write_str("    ");
+                    let name = v.name.as_ref().unwrap();
+                    match *v.kind {
+                        clean::VariantItem(ref var) => match var {
+                            clean::Variant::CLike => write!(w, "{}", name),
+                            clean::Variant::Tuple(ref tys) => {
+                                write!(w, "{}(", name);
+                                for (i, ty) in tys.iter().enumerate() {
+                                    if i > 0 {
+                                        w.write_str(",&nbsp;")
+                                    }
+                                    write!(w, "{}", ty.print(cx));
                                 }
-                                write!(w, "{}", ty.print(cx));
+                                w.write_str(")");
                             }
-                            w.write_str(")");
-                        }
-                        clean::Variant::Struct(ref s) => {
-                            render_struct(w, v, None, s.struct_type, &s.fields, "    ", false, cx);
-                        }
-                    },
-                    _ => unreachable!(),
+                            clean::Variant::Struct(ref s) => {
+                                render_struct(
+                                    w,
+                                    v,
+                                    None,
+                                    s.struct_type,
+                                    &s.fields,
+                                    "    ",
+                                    false,
+                                    cx,
+                                );
+                            }
+                        },
+                        _ => unreachable!(),
+                    }
+                    w.write_str(",\n");
                 }
-                w.write_str(",\n");
-            }
 
-            if e.variants_stripped {
-                w.write_str("    // some variants omitted\n");
-            }
-            if toggle {
-                toggle_close(w);
+                if e.variants_stripped {
+                    w.write_str("    // some variants omitted\n");
+                }
+                if toggle {
+                    toggle_close(w);
+                }
+                w.write_str("}");
             }
-            w.write_str("}");
-        }
-        w.write_str("</pre>")
+        });
     });
 
     document(w, cx, it, None);
@@ -1091,27 +1107,27 @@ fn item_proc_macro(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, m: &clean
     let name = it.name.as_ref().expect("proc-macros always have names");
     match m.kind {
         MacroKind::Bang => {
-            w.push_str("<pre class=\"rust macro\">");
-            write!(w, "{}!() {{ /* proc-macro */ }}", name);
-            w.push_str("</pre>");
+            wrap_item(w, "macro", |w| {
+                write!(w, "{}!() {{ /* proc-macro */ }}", name);
+            });
         }
         MacroKind::Attr => {
-            w.push_str("<pre class=\"rust attr\">");
-            write!(w, "#[{}]", name);
-            w.push_str("</pre>");
+            wrap_item(w, "attr", |w| {
+                write!(w, "#[{}]", name);
+            });
         }
         MacroKind::Derive => {
-            w.push_str("<pre class=\"rust derive\">");
-            write!(w, "#[derive({})]", name);
-            if !m.helpers.is_empty() {
-                w.push_str("\n{\n");
-                w.push_str("    // Attributes available to this derive:\n");
-                for attr in &m.helpers {
-                    writeln!(w, "    #[{}]", attr);
+            wrap_item(w, "derive", |w| {
+                write!(w, "#[derive({})]", name);
+                if !m.helpers.is_empty() {
+                    w.push_str("\n{\n");
+                    w.push_str("    // Attributes available to this derive:\n");
+                    for attr in &m.helpers {
+                        writeln!(w, "    #[{}]", attr);
+                    }
+                    w.push_str("}\n");
                 }
-                w.push_str("}\n");
-            }
-            w.push_str("</pre>");
+            });
         }
     }
     document(w, cx, it, None)
@@ -1123,49 +1139,49 @@ fn item_primitive(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) {
 }
 
 fn item_constant(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, c: &clean::Constant) {
-    w.write_str("<pre class=\"rust const\">");
-    render_attributes_in_code(w, it);
+    wrap_item(w, "const", |w| {
+        render_attributes_in_code(w, it);
 
-    write!(
-        w,
-        "{vis}const {name}: {typ}",
-        vis = it.visibility.print_with_space(it.def_id, cx),
-        name = it.name.as_ref().unwrap(),
-        typ = c.type_.print(cx),
-    );
+        write!(
+            w,
+            "{vis}const {name}: {typ}",
+            vis = it.visibility.print_with_space(it.def_id, cx),
+            name = it.name.as_ref().unwrap(),
+            typ = c.type_.print(cx),
+        );
 
-    let value = c.value(cx.tcx());
-    let is_literal = c.is_literal(cx.tcx());
-    let expr = c.expr(cx.tcx());
-    if value.is_some() || is_literal {
-        write!(w, " = {expr};", expr = Escape(&expr));
-    } else {
-        w.write_str(";");
-    }
+        let value = c.value(cx.tcx());
+        let is_literal = c.is_literal(cx.tcx());
+        let expr = c.expr(cx.tcx());
+        if value.is_some() || is_literal {
+            write!(w, " = {expr};", expr = Escape(&expr));
+        } else {
+            w.write_str(";");
+        }
 
-    if !is_literal {
-        if let Some(value) = &value {
-            let value_lowercase = value.to_lowercase();
-            let expr_lowercase = expr.to_lowercase();
+        if !is_literal {
+            if let Some(value) = &value {
+                let value_lowercase = value.to_lowercase();
+                let expr_lowercase = expr.to_lowercase();
 
-            if value_lowercase != expr_lowercase
-                && value_lowercase.trim_end_matches("i32") != expr_lowercase
-            {
-                write!(w, " // {value}", value = Escape(value));
+                if value_lowercase != expr_lowercase
+                    && value_lowercase.trim_end_matches("i32") != expr_lowercase
+                {
+                    write!(w, " // {value}", value = Escape(value));
+                }
             }
         }
-    }
+    });
 
-    w.write_str("</pre>");
     document(w, cx, it, None)
 }
 
 fn item_struct(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Struct) {
     wrap_into_docblock(w, |w| {
-        w.write_str("<pre class=\"rust struct\">");
-        render_attributes_in_code(w, it);
-        render_struct(w, it, Some(&s.generics), s.struct_type, &s.fields, "", true, cx);
-        w.write_str("</pre>")
+        wrap_item(w, "struct", |w| {
+            render_attributes_in_code(w, it);
+            render_struct(w, it, Some(&s.generics), s.struct_type, &s.fields, "", true, cx);
+        });
     });
 
     document(w, cx, it, None);
@@ -1214,28 +1230,31 @@ fn item_struct(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St
 }
 
 fn item_static(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Static) {
-    w.write_str("<pre class=\"rust static\">");
-    render_attributes_in_code(w, it);
-    write!(
-        w,
-        "{vis}static {mutability}{name}: {typ}</pre>",
-        vis = it.visibility.print_with_space(it.def_id, cx),
-        mutability = s.mutability.print_with_space(),
-        name = it.name.as_ref().unwrap(),
-        typ = s.type_.print(cx)
-    );
+    wrap_item(w, "static", |w| {
+        render_attributes_in_code(w, it);
+        write!(
+            w,
+            "{vis}static {mutability}{name}: {typ}",
+            vis = it.visibility.print_with_space(it.def_id, cx),
+            mutability = s.mutability.print_with_space(),
+            name = it.name.as_ref().unwrap(),
+            typ = s.type_.print(cx)
+        );
+    });
     document(w, cx, it, None)
 }
 
 fn item_foreign_type(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) {
-    w.write_str("<pre class=\"rust foreigntype\">extern {\n");
-    render_attributes_in_code(w, it);
-    write!(
-        w,
-        "    {}type {};\n}}</pre>",
-        it.visibility.print_with_space(it.def_id, cx),
-        it.name.as_ref().unwrap(),
-    );
+    wrap_item(w, "foreigntype", |w| {
+        w.write_str("extern {\n");
+        render_attributes_in_code(w, it);
+        write!(
+            w,
+            "    {}type {};\n}}",
+            it.visibility.print_with_space(it.def_id, cx),
+            it.name.as_ref().unwrap(),
+        );
+    });
 
     document(w, cx, it, None);
 
@@ -1322,6 +1341,15 @@ fn wrap_into_docblock<F>(w: &mut Buffer, f: F)
     w.write_str("</div>")
 }
 
+fn wrap_item<F>(w: &mut Buffer, item_name: &str, f: F)
+where
+    F: FnOnce(&mut Buffer),
+{
+    w.write_fmt(format_args!("<pre class=\"rust {}\"><code>", item_name));
+    f(w);
+    w.write_str("</code></pre>");
+}
+
 fn render_stability_since(
     w: &mut Buffer,
     item: &clean::Item,
index bbc48f49e63e184d98b6438af0213a627d81b5f4..0f95b6aaa898d93b3bf5572482314cd836ed7362 100644 (file)
@@ -249,7 +249,6 @@ code, pre, a.test-arrow, .code-header {
 }
 .docblock pre code, .docblock-short pre code {
        padding: 0;
-       padding-right: 1ex;
 }
 pre {
        padding: 14px;
diff --git a/src/test/rustdoc-gui/code-tags.goml b/src/test/rustdoc-gui/code-tags.goml
new file mode 100644 (file)
index 0000000..200569a
--- /dev/null
@@ -0,0 +1,20 @@
+// This test ensures that items and documentation code blocks are wrapped in <pre><code>
+goto: file://|DOC_PATH|/test_docs/fn.foo.html
+size: (1080, 600)
+// There should be three doc codeblocks
+// Check that their content is inside <pre><code>
+assert-count: (".example-wrap pre > code", 3)
+// Check that function signature is inside <pre><code>
+assert: "pre.rust.fn > code"
+
+goto: file://|DOC_PATH|/test_docs/struct.Foo.html
+assert: "pre.rust.struct > code"
+
+goto: file://|DOC_PATH|/test_docs/enum.AnEnum.html
+assert: "pre.rust.enum > code"
+
+goto: file://|DOC_PATH|/test_docs/trait.AnotherOne.html
+assert: "pre.rust.trait > code"
+
+goto: file://|DOC_PATH|/test_docs/type.SomeType.html
+assert: "pre.rust.typedef > code"
index d7bae93c211a19b058833c653109aae5c7cdc2e6..5a49807e180b27d06fe1b15b157fb8dd14cff7b9 100644 (file)
@@ -12,4 +12,4 @@ assert-attribute: (".line-numbers > span:nth-child(5)", {"class": "line-highligh
 assert-attribute: (".line-numbers > span:nth-child(6)", {"class": "line-highlighted"})
 assert-attribute-false: (".line-numbers > span:nth-child(7)", {"class": "line-highlighted"})
 // This is to ensure that the content is correctly align with the line numbers.
-compare-elements-position: ("//*[@id='1']", ".rust > span", ("y"))
+compare-elements-position: ("//*[@id='1']", ".rust > code > span", ("y"))